You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Azure provider now supports only the modern Foundry OpenAI v1 surface. Classic Azure OpenAI deployment routes, inference routes, API-version/flavor/override fields, and model-name heuristics are removed—not hidden.
New API protocol selector: Auto (default), Chat Completions, or Responses. Explicit selections never fall back. Auto uses one bounded structured-error Chat → Responses fallback.
Validation and Helix share the same model identity and protocol. Embeddings always use the same v1 endpoint with their separately configured deployment name.
Provider key remains azure, preserving credentials and feature-provider identity. Existing configurations without api_protocol migrate previously effective deployment names into visible model fields; obsolete fields are dropped on settings save. Modern configs ignore obsolete overrides.
Resource roots normalize to /openai/v1. Other API paths/query parameters are rejected, not silently rerouted.
Probe budget remains explicit (1,024 tokens / 30 seconds), caller budgets are honored, both operation errors survive, Responses uses store:false and rejects failed/incomplete/refused/empty results.
Responses streaming remains buffered completion-to-chunks, clearly documented in UI and docs; Chat Completions uses native SSE.
… 404
Helix Chat 404 DeploymentNotFound after #118 because every
*.services.ai.azure.com host was routed to /openai/v1/chat/completions
without api-version. Restore flavor deployments URLs unless the path
explicitly contains /openai/v1, and fall back to that classic URL when
v1 chat 404s.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Restores Azure Foundry chat routing by distinguishing v1 URLs from classic endpoints and adding fallback behavior.
Changes:
Restricts v1 detection to /openai/v1 paths.
Adds classic-route fallback for failed v1 chat requests.
Updates routing and fallback regression tests.
File summaries
File
Summary
internal/ai/provider/azure/azure.go
Routing and fallback implementation; response handling, deployment selection, fallback errors, and package documentation require updates.
internal/ai/provider/azure/azure_test.go
Covers host-only routing and fallback behavior.
Review details
Suppressed comments (3)
internal/ai/provider/azure/azure.go:185
resp.Body.Close() is deferred until this Chat call returns, but the fallback starts another request on the same http.Client before that return. With a transport configured with MaxConnsPerHost: 1, the first response keeps the only connection occupied and the fallback can block until the context expires; even without that limit, each in-flight 404 consumes an extra connection. Close the failed response before starting the retry (and keep the defer only for the successful-response path).
if resp.StatusCode == http.StatusNotFound && a.usesOpenAIV1() {
if fallback, ferr := a.withoutOpenAIV1().Chat(ctx, req); ferr == nil {
internal/ai/provider/azure/azure.go:185
This retry does not cover saved v1 configurations where cfg.Deployment is stale: chatEndpoint selects the v1 body model through chatDeployment, which prefers cfg.Deployment over cfg.Model, and this fallback then uses that same deployment in the classic URL. The settings form intentionally merges hidden deployment fields when switching flavors, so both requests can target the old deployment and still return 404. Use a v1-specific identity that prefers req.Model/cfg.Model (with an explicit fallback only when appropriate), while retaining cfg.Deployment for classic OpenAI routing.
if resp.StatusCode == http.StatusNotFound && a.usesOpenAIV1() {
if fallback, ferr := a.withoutOpenAIV1().Chat(ctx, req); ferr == nil {
internal/ai/provider/azure/azure.go:188
When the classic retry also fails, ferr is discarded and the caller receives only the original v1 404. That masks whether the fallback failed because of authentication, API version, or another routing problem; surface the fallback error while retaining the initial error for diagnosis.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Address the two moderate issues in azure.go.
Review details
Suppressed comments (2)
internal/ai/provider/azure/azure.go:429
The package-level documentation above still says that the v1 surface is detected from a services.ai.azure.com hostname, but this change makes the path the only detection signal. That now contradicts the implementation and the new behavior for host-only Foundry URLs; please update the package comment in the same change so future callers do not rely on the removed auto-detection rule.
// OpenAI-compatible v1 surface. Only the path is authoritative —
// hostname *.services.ai.azure.com also hosts classic
// /openai/deployments/{name}/chat/completions?api-version= which
// Helix used successfully before auto-detect (#118) forced v1.
internal/ai/provider/azure/azure.go:187
When the classic retry fails, ferr is discarded and the original v1 404 is returned. That hides the actual fallback failure (for example, a 401 or 500), so validation and callers can misclassify a bad key or upstream outage as not_found; return the fallback error (or otherwise preserve it as the primary error) instead of silently ignoring it.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Install gopls (Go LSP)
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
Helix dispatch leaves MaxTokens unset. Azure gpt-5 then 400s with
'max_tokens or model output limit was reached' because reasoning
tokens consume the tiny default. Send max_completion_tokens=8192
for gpt-5/o-series (and Foundry v1) instead of max_tokens.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
Official Microsoft Foundry docs route gpt-5.6-sol through
POST /openai/v1/responses (not chat/completions). Chat Completions
rejects function tools on gpt-5.6+ unless reasoning_effort=none;
Helix uses tools. Encode input/instructions/max_output_tokens,
omit temperature, and keep classic chat completions for gpt-4o/gpt-5.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Moderate issues remain in model capability detection, validation token limits, and package documentation.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
internal/ai/provider/azure/azure.go:705
The cloud validation path always sends MaxTokens: 1 (see handleValidateCloud), so this branch emits max_completion_tokens: 1 for GPT-5/o-series requests. The new comment explicitly says Azure rejects an omitted or 1-token reasoning cap, which means Validate connection still fails for the models this change targets; omit the probe cap or normalize that specific probe to a valid completion budget before encoding.
// Plural tool_calls — what dispatch.go now copies from
// resp.ToolCalls into the assistant message before
// appending to history. This is the round-trip path that
// makes multi-iteration tool dispatching work.
for _, mc := range m.ToolCalls {
tc := azureWireToolCall{ID: mc.ID, Type: "function"}
tc.Function.Name = mc.Name
tc.Function.Arguments = string(mc.Arguments)
wm.ToolCalls = append(wm.ToolCalls, tc)
}
internal/ai/provider/azure/azure.go:429
The package comment at lines 5-7 still says any services.ai.azure.com hostname auto-selects v1. This function now deliberately ignores the hostname, so the public package documentation contradicts the implementation and can lead future changes back to the removed behavior; update the top-level comment in this change.
}
switch a.cfg.Flavor {
case provider.AzureFlavorFoundry:
return a.buildURL("embeddings")
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
Responses API is used for every Microsoft Foundry flavor and every
/openai/v1 endpoint, regardless of deployment name. Classic Azure
OpenAI flavor without that path stays on chat completions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unresolved critical and moderate findings affect Azure routing, streaming, fallback, token limits, model selection, and completion status.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (3)
internal/ai/provider/azure/azure.go:740
The adjacent comment says Azure rejects max_completion_tokens=1, but this classic GPT-5 branch only defaults when n <= 0. internal/api/aisettingsvalidate/handler.go sends MaxTokens: 1, so host-only classic GPT-5 validation still emits max_completion_tokens: 1 and can return 400 instead of validating. Apply the same lower-bound handling here or change the probe contract.
if n <= 0 {
// gpt-5 / o-series spend hidden reasoning tokens
// against this cap. Azure 400s with "max_tokens or
// model output limit was reached" when the field is
// omitted or set to 1 (the settings probe).
n = defaultMaxCompletionTokens
internal/ai/provider/azure/azure.go:8
The package comment now says a gpt-5.6+/gpt-6 model selects the OpenAI v1/Responses surface, but routing is path-based (and the model only changes the token-cap field). A host-only classic GPT-5 deployment follows chat completions, so this documentation contradicts the path-only detection described by the change and can lead maintainers to configure the wrong endpoint.
// A third URL shape — Azure AI Foundry OpenAI v1 — is used when the
// path contains /openai/v1, or when the model is gpt-5.6+ / gpt-6
// (official Responses API). See:
// https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/responses
internal/ai/provider/azure/azure.go:196
The documented fallback from a v1 404 re-enters classic Chat Completions with the original Helix tool list, but the new Responses implementation explicitly notes that gpt-5.6+ rejects function tools unless reasoning_effort=none; azureChatRequest has no such field or value. For the target gpt-5.6-sol deployment, a failed v1 probe will therefore fail again instead of restoring chat routing. Add the required reasoning setting to this classic fallback or restrict it to models that support the existing Chat Completions payload.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
Use bounded structured-error fallback on explicit v1 endpoints, preserve legacy inference and both failures, align validation with Helix deployment identity, and honor caller token budgets. Disable Responses storage and reject unsuccessful results. Cover HTTP and real dispatch tool roundtrips plus settings persistence.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
Final verification for 6debba4: CI and Frontend quality gates both succeeded. PR checks: 64 passed, 4 skipped by their existing conditions, none failed or pending. All five Docker jobs started after the generated/backend/frontend gates completed; this ordering was checked against job timestamps. Local API/web Docker builds and responsive inline-edit/Helix tests also passed. No merge performed.
Verify 320-2560px layouts in light and dark themes at normal and 135% text scale. Check shortcut text width, action placement and hit targets, category description separation, unclipped overview text and preserved drafts. Capture individual shortcut screenshots for inspection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
Settings readability verified in 82aa2f7. The stacked-card production fix was already present in 31db0e7; this follow-up adds stronger regression coverage rather than changing working layout code.
Tested widths: 320, 390, 768, 1024, 1280, 1440, 1920 and 2560px, each in light/dark themes at 100% and 135% text scale.
Assertions cover all three shortcut descriptions (at least 180px wide), buttons below descriptions with 44px minimum height and unobscured click targets, separate category description/save-hint lines, no overview text spilling outside cards, no horizontal page overflow, and preserved unsaved edits across categories. Individual card screenshots are captured as browser-test artifacts.
TypeScript and scoped ESLint passed. SettingsPage and SettingsActionCard audits each reported zero violations; Settings hook routes matched the backend. No production components, sections, or API behavior were changed in this follow-up. CI is being monitored; no merge or deployment performed.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🔵 Needs a closer look
The served OpenAPI contract is missing the new Alert Packs and AI draft routes, and the PR combines unrelated Alert Packs work with the Foundry refactor.
Allow summary cards to shrink and wrap long values instead of overflowing with Linux system fonts at 135% text scale. Keep the strengthened responsive assertions. Exclude native footer elements from synthetic long-copy mutation, matching the existing contentinfo exclusion, and refresh the two inspected long-content baselines without changing screenshot thresholds.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
Follow-up correction pushed in 7261999 after the stronger CI matrix caught a real platform-specific issue: Linux system-font metrics made the Typography value overflow at 135% text scale. Settings summary cards now permit shrinking and word wrapping; the strict overflow assertions remain unchanged.
The visual diff was isolated to synthetic long-copy mutation of the live native footer. The fixture previously excluded explicit role=contentinfo but missed native footer elements; it now excludes both. Inspected and regenerated the two long-content baselines, then reran comparisons without update mode. Screenshot thresholds remain unchanged.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
Use one property per column and consistently sized editors. Flatten pack-default controls, show effective once/repeat values without a Master option, and keep field-specific overrides with an explicit reset action. Preserve Helix, channel routing, mobile editing, validation and installation behavior. Add measured alignment and row-density regressions across eight viewport widths.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
Reworked the pack preview in f3c43b6 using the flat editable-grid pattern discussed with the user (KendoReact as an interaction reference, no new UI dependency).
One property per column: Operator, Value, Cooldown, Alert behavior, Channels, Notification message, Include title, and Defaults reset. No nested mini-forms or repeated labels inside desktop cells.
Header labels align with their cells; editors use consistent 44px heights. Compact rows remain under the regression's 100px limit.
Five pack-default controls occupy one aligned row. Removed the ambiguous Master: Once option; each rule displays its effective Once per condition / Repeat while active value.
Editing still overrides only that field. Reset delivery / Apply defaults to all preserve messages, operators, thresholds and channels.
Per-row Helix review/apply, mobile cards, pagination, dirty guards and explicit installation remain intact.
TypeScript, full frontend lint, scoped violations audit and hook-route verification passed. Browser coverage now includes 320, 390, 768, 1024, 1280, 1440, 1920 and 2560px in both themes, asserting default-control alignment, cell alignment, flat column structure and compact row height. Fresh desktop/mobile screenshots were inspected.
CI is being monitored. No merge or deployment performed.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
This PR adds the pack catalog, installation/removal, and Helix draft routes in internal/api/router.go, but the public OpenAPI document has no /alerts/packs, /alerts/pack-installations, or /ai/alerts/packs/draft paths (only the bulk-delete/channel field additions are documented here). API consumers and generated clients therefore cannot discover the new feature; add the new operations and their request/response schemas alongside the bulk-delete entry.
Final verification for f3c43b6: CI and Frontend quality gates succeeded, including the Linux responsive grid/alignment cases and all Windows visual shards. No failed or pending PR checks remain. Local frontend lint, 673 notification tests, 22 browser cases and the web Docker build passed. The Settings readability follow-up also remains green. PR is unmerged; no deployment performed.
Inherit pack channels unless a rule explicitly overrides them; reset channels with other delivery fields. Reuse Studio behavior labels and the 15-minute cooldown while preserving responsive aligned controls.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5b104204-65b7-4d04-90a4-e2d5897b8e2e
Added Default channels to Pack defaults; untouched rules inherit, while explicit all/none/fixed-channel overrides survive default changes.
Individual reset and Apply defaults to all rules now reset channels too. The existing API receives resolved per-rule channel IDs, never an unsupported root field.
Shared the Studio cooldown default (15 minutes) and behavior options (Re-alert until resolved, Notify on event). Preserved packs' initial Notify on event selection and the ordinary new-rule editor's explicit-choice placeholder.
Six top controls align in one row on wide desktops and wrap into aligned rows on narrower displays. Updated docs and inspected desktop/tablet/mobile screenshots.
Actual local output:
TypeScript exit: 0 (no diagnostics if exit 0)
Test Files 56 passed (56)
Tests 678 passed (678)
Final pack-only run, including 10 new channel-contract cases:
Test Files 2 passed (2)
Tests 35 passed (35)
22 passed (1.9m)
E2E preview proxy escape check: 0 errors
ALL CHECKS PASSED — 0 total violations
ALL EXTRACTED HOOK PATHS MATCH REGISTERED ROUTES
Pack component lines: 641 -> 641; panels: 3 -> 3
Studio page lines: 2413 -> 2413; panels: 8 -> 8
Image teslasync-web Built
Full frontend lint and final helper lint exited 0. Browser coverage includes 320–2560px, both themes, six-control alignment, per-rule channel overrides, bulk reset, and submitted channel routing. CI is pending; no merge or deployment.
One or more custom setup steps configured for this repository failed during this Copilot code review run:
Verify TypeScript build
Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.
Note
You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.
PR scope mixes Foundry changes with unrelated Alert Packs work
internal/alertpacks/doc.go:1
This PR is described as Microsoft Foundry v1-only, but it also introduces an unrelated Alert Packs domain/API/UI/migration surface (plus settings and CI changes). Please split these changes or update the PR scope/description before approval; reviewing them as one change materially increases the merge risk.
body := `{"version":2,"all_vehicles":true,"rules":[{"template_id":"battery-low","channel_ids":[2,3]},{"template_id":"charge-complete","channel_ids":[2]}]}`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Microsoft Foundry v1 only
The Azure provider now supports only the modern Foundry OpenAI v1 surface. Classic Azure OpenAI deployment routes, inference routes, API-version/flavor/override fields, and model-name heuristics are removed—not hidden.
azure, preserving credentials and feature-provider identity. Existing configurations withoutapi_protocolmigrate previously effective deployment names into visible model fields; obsolete fields are dropped on settings save. Modern configs ignore obsolete overrides./openai/v1. Other API paths/query parameters are rejected, not silently rerouted.store:falseand rejects failed/incomplete/refused/empty results.Verification for e44ebf9
Verified in an isolated worktree because unrelated Alert Packs edits were concurrently in progress in the shared checkout:
-racePASS; targeted golangci-lint PASS.npx tsc --noEmitPASS; 3 frontend test files / 49 tests PASS; targeted ESLint PASS.docker compose -p foundryverify build: all five service images Built.No Azure endpoint credentials were available: this is not live Azure verification. CI is being monitored; no merge requested.
Official references:
https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/responses
https://learn.microsoft.com/en-us/azure/foundry/openai/api-version-lifecycle