Add automode.routerModelSelection telemetry with actualModel#310238
Add automode.routerModelSelection telemetry with actualModel#310238
Conversation
Screenshot ChangesBase: Changed (1)blocks-ci screenshots changedReplace the contents of Updated blocks-ci-screenshots.md<!-- auto-generated by CI — do not edit manually -->
#### editor/codeEditor/CodeEditor/Dark

#### editor/codeEditor/CodeEditor/Light
 |
f829091 to
c72380d
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new telemetry event to capture the router’s recommended model vs the final model actually used in Auto Mode, after client-side selection adjustments.
Changes:
- Emits
automode.routerModelSelectiontelemetry after model selection is finalized. - Extends
_tryRouterSelectionto return the router’s top candidate model (candidateModel) for correlation.
Show a summary per file
| File | Description |
|---|---|
| extensions/copilot/src/platform/endpoint/node/automodeService.ts | Emits new model-selection telemetry and propagates router candidate model out of router selection. |
Copilot's findings
Comments suppressed due to low confidence (2)
extensions/copilot/src/platform/endpoint/node/automodeService.ts:235
overrideReasonincludes adefaultFallbackbranch, butrouterResult.candidateModelis only set in_tryRouterSelectionwhen the router also produced a matchingselectedModel(success path). In the router-fallback/default-selection paths (emptyCandidateList,noMatchingEndpoint,routerFallback, etc.)candidateModelis currently omitted, so this event never fires anddefaultFallbackis effectively unreachable. Consider propagatingcandidateModelwhenever the router returnscandidate_models[0](even if you later fall back to_selectDefaultModel), and emitting this event whenever a router recommendation exists socandidateModelvsactualModelcan be compared for default-selection fallbacks as described in the PR.
if (!skipRouter && routerResult.candidateModel) {
/* __GDPR__
"automode.routerModelSelection" : {
"owner": "aashnagarg",
"comment": "Reports the router's recommended model vs the actual model used after all client-side overrides (same-provider, vision fallback, default selection)",
"conversationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The conversation ID" },
"candidateModel": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The router's top candidate model (candidate_models[0])" },
"actualModel": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The model actually selected after all client-side overrides" },
"overrideReason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Why the actual model differs from the candidate: none, visionFallback, defaultFallback, or sameProvider" }
}
*/
const candidateModel = routerResult.candidateModel;
const overrideReason = candidateModel === selectedModel.model ? 'none'
: routerFallbackReason ? 'defaultFallback'
: 'clientOverride';
this._telemetryService.sendMSFTTelemetryEvent('automode.routerModelSelection', {
extensions/copilot/src/platform/endpoint/node/automodeService.ts:229
- The GDPR metadata/comment for
overrideReasonlists valuesnone, visionFallback, defaultFallback, or sameProvider, but the implementation only ever emitsnone,defaultFallback, orclientOverride. Please align the schema description with the actual emitted values (or update the code to emit the documented values) so downstream telemetry consumers and compliance metadata are accurate.
/* __GDPR__
"automode.routerModelSelection" : {
"owner": "aashnagarg",
"comment": "Reports the router's recommended model vs the actual model used after all client-side overrides (same-provider, vision fallback, default selection)",
"conversationId": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The conversation ID" },
"candidateModel": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The router's top candidate model (candidate_models[0])" },
"actualModel": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The model actually selected after all client-side overrides" },
"overrideReason": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Why the actual model differs from the candidate: none, visionFallback, defaultFallback, or sameProvider" }
}
- Files reviewed: 1/1 changed files
- Comments generated: 1
Emits a new telemetry event after all client-side model overrides (same-provider, vision fallback, default selection) are applied. Properties: - candidateModel: the router's top pick (candidate_models[0]) - actualModel: the model actually used after all overrides - overrideReason: none, defaultFallback, or clientOverride - conversationId: for correlation This enables accurate switch attribution without fragile cross-event joins. The existing automode.routerDecision event captures the router's recommendation, but doesn't know what model was ultimately selected because vision fallback and default selection happen afterward. Analysts can now query automode.routerModelSelection directly: | where candidateModel != actualModel | summarize count() by candidateModel, actualModel
c72380d to
ff47e16
Compare
| const overrideReason = candidateModel === selectedModel.model ? 'none' | ||
| : routerFallbackReason ? 'defaultFallback' | ||
| : 'clientOverride'; | ||
| this._telemetryService.sendMSFTTelemetryEvent('automode.routerModelSelection', { |
There was a problem hiding this comment.
I'll also try and check the feasibility of my comment when I have the time, but is it not possible to just pipe actualModel to the github.copilot-chat/automode.routerdecision event?
There was a problem hiding this comment.
Maybe we need Logan's input on this, but I think moving the emission of github.copilot-chat/automode.routerdecision out of the fetcher object and into here may just be cleanest.
If we have two separate events for basically the same thing, that might get confusing as well.
Emits a new telemetry event after all client-side model overrides (same-provider, vision fallback, default selection) are applied.
Properties:
This enables accurate switch attribution without fragile cross-event joins. The existing automode.routerDecision event captures the router's recommendation, but doesn't know what model was ultimately selected because vision fallback and default selection happen afterward.
Analysts can now query automode.routerModelSelection directly:
| where candidateModel != actualModel
| summarize count() by candidateModel, actualModel