Auto mode: use the router's chosen_model instead of candidate_models[0]#324095
Merged
Conversation
Auto mode resolved the pseudo-model by picking candidate_models[0] (the pre-experiment ranked list) and never consumed chosen_model, the router's authoritative pick after server-side re-ranking (e.g. Cost Sorting). Per the auto-intent-service contract (docs/integrators_onboarding.md), clients must "use chosen_model for the upcoming chat call, and use candidate_models as the ordered fallback list". The CLI already does this; VS Code did not, so VS Code was invisible to the Cost Sorting experiment and sent a different model than Auto Intent chose (e.g. router chose GPT 5.4 Mini, VS Code sent GPT 5.3 Codex). Prefer chosen_model (resolved against known endpoints) and fall back to the ordered candidate_models list only when chosen_model is absent or unresolvable. Also report chosen_model as candidateModel in the automode.routerModelSelection telemetry so router-pick vs actual comparisons are meaningful. Existing tests hid the bug because every fixture set chosen_model === candidate_models[0]. Added regression tests that decouple the two fields.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes VS Code Copilot “Auto mode” routing to honor the router’s authoritative chosen_model (including post-ranking/experiment adjustments) instead of incorrectly using candidate_models[0], aligning behavior with the auto-intent-service integrator contract and the Copilot CLI.
Changes:
- Update router selection logic to resolve
chosen_modelagainstknownEndpoints, falling back to the orderedcandidate_modelslist only when needed. - Update routing telemetry (
automode.routerModelSelection) socandidateModelreflects the router’schosen_model. - Add regression tests that decouple
chosen_modelfromcandidate_models[0]and validate both selection and telemetry.
Show a summary per file
| File | Description |
|---|---|
| extensions/copilot/src/platform/endpoint/node/automodeService.ts | Prefer router chosen_model for endpoint resolution; fall back to candidate_models when chosen_model can’t be resolved; emit telemetry using the router’s authoritative pick. |
| extensions/copilot/src/platform/endpoint/node/test/automodeService.spec.ts | Add/adjust tests to ensure selection prefers chosen_model and telemetry reports candidateModel from chosen_model, plus a real fallback-path test. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Low
Add a regression test asserting the routing decision surfaced to the UI (consumeLastRoutingDecision, which drives the 'Routed to <model>' explainability label) resolves to chosen_model, matching the served endpoint shown in the response footer. This locks in that the top label and bottom footer cannot diverge.
aashna
marked this pull request as ready for review
July 2, 2026 18:39
aashna
enabled auto-merge
July 2, 2026 18:48
bhavyaus
approved these changes
Jul 2, 2026
dmitrivMS
approved these changes
Jul 2, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Auto mode was picking the wrong model. When resolving the
autopseudo-model, we tookcandidate_models[0]from the router response and ignoredchosen_modelentirely.chosen_modelis the router's actual pick after any server-side re-ranking (the Cost Sorting experiment being the one that bit us). The integrator contract is explicit about this:— auto-intent-service integrator docs. The Copilot CLI already does this; VS Code was the odd one out.
This showed up as two separate-looking bugs that are really the same root cause:
/models/session/intentreturned GPT-5.4 mini but the chat completion actually went to GPT-5.3 Codex.chosen_model, the label, the request, and the footer all line up.There's a knock-on effect too: because the Cost Sorting experiment only re-ranks
chosen_model, anything readingcandidate_models[0]was effectively invisible to it. That matches what we saw — the experiment moved the CLI but not VS Code.What changed
In
_tryRouterSelection(automodeService.ts):chosen_modelagainst the client's known endpoints first.candidate_modelswhenchosen_modelis missing or we don't have an endpoint for it.chosen_modelascandidateModelin theautomode.routerModelSelectiontelemetry, so the "router pick vs actual model" comparison is actually meaningful.Why the tests didn't catch it
Every mocked router response in the spec set
chosen_model === candidate_models[0], so reading the wrong field gave the right answer by accident. The new tests decouple them:should prefer chosen_model over candidate_models[0]— resolved endpoint followschosen_modelwhen the two differ.should surface chosen_model in the routing decision the UI displays— the decision the "Routed to" label consumes matches the served endpoint (guards bug gulp-symdest does not preserve links on electron #2).should emit candidateModel from chosen_model, not candidate_models[0]— pins the telemetry field.iterate all candidate_modelstest intoshould fall back to candidate_models when chosen_model has no endpointso it actually exercises the fallback path.I confirmed the new tests fail on the pre-fix code (resolving
gpt-5.3-codexinstead ofgpt-5.4-mini) and pass after the fix.Test plan
vitest run automodeService.spec.ts— 37 passing