Yemohyle/add to telemetry#311837
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR extends Copilot’s telemetry to (1) capture additional token-usage breakdown (cached/reasoning/prediction tokens) and (2) link subagent telemetry back to the parent HTTP request via a propagated parentHeaderRequestId.
Changes:
- Add
cachedTokensand additionalcompletion_tokens_detailsmeasurements to output telemetry for both Responses API and Messages API flows. - Introduce and propagate
parentHeaderRequestIdthrough request telemetry properties and subagent calling loops. - Track the most recent request header ID in
ToolCallingLoopso subagent tools can attach it to their own telemetry.
Show a summary per file
| File | Description |
|---|---|
| extensions/copilot/src/platform/networking/node/chatStream.ts | Adds parentHeaderRequestId to model-call telemetry; also adds debug logging (needs changes). |
| extensions/copilot/src/platform/networking/common/networking.ts | Extends IChatRequestTelemetryProperties with parentHeaderRequestId. |
| extensions/copilot/src/platform/endpoint/node/responsesApi.ts | Adds cached/reasoning/prediction token measurements to output telemetry. |
| extensions/copilot/src/platform/endpoint/node/messagesApi.ts | Adds cached/reasoning/prediction token measurements to output telemetry. |
| extensions/copilot/src/extension/tools/node/searchSubagentTool.ts | Passes parentHeaderRequestId into search subagent loop options. |
| extensions/copilot/src/extension/tools/node/executionSubagentTool.ts | Passes parentHeaderRequestId into execution subagent loop options. |
| extensions/copilot/src/extension/prompt/node/searchSubagentToolCallingLoop.ts | Adds parentHeaderRequestId to subagent telemetryProperties. |
| extensions/copilot/src/extension/prompt/node/executionSubagentToolCallingLoop.ts | Adds parentHeaderRequestId to subagent telemetryProperties (but missing requestKindOptions). |
| extensions/copilot/src/extension/prompt/node/chatMLFetcher.ts | No functional change (whitespace only). |
| extensions/copilot/src/extension/prompt/common/intents.ts | Adds parentHeaderRequestId to IBuildPromptContext. |
| extensions/copilot/src/extension/intents/node/toolCallingLoop.ts | Tracks last successful requestId and exposes it in prompt context for subagent tools. |
Copilot's findings
Comments suppressed due to low confidence (1)
extensions/copilot/src/platform/networking/node/chatStream.ts:415
- The conditional info-level
[DEBUG-TELEMETRY]log formodel.modelCall.inputstringifies and logs the full event payload (including chunked UUID arrays). This is high-volume and can expose telemetry payloads in logs; it should be removed or downgraded/gated behind a dedicated debug setting with redaction.
if (eventName.endsWith('.input')) {
logService?.info(`[DEBUG-TELEMETRY] ${eventName}: ` + JSON.stringify({ properties: modelCallData.properties, measurements: modelCallData.measurements }));
}
- Files reviewed: 11/11 changed files
- Comments generated: 2
| // Create telemetry data for the request | ||
| const requestData = TelemetryData.createAndMarkAsIssued(filteredProperties, telemetryData.measurements); | ||
|
|
||
| logService?.info(`[DEBUG-TELEMETRY] model.request.added: ` + JSON.stringify({ properties: requestData.properties, measurements: requestData.measurements })); |
There was a problem hiding this comment.
The new [DEBUG-TELEMETRY] info-level log prints full telemetry properties/measurements for model.request.added. This can include user/system metadata and will emit on every request, increasing log volume and risking leaking telemetry-only fields into regular logs. Please remove this log, or gate it behind an explicit debug flag and use trace/debug with redaction (e.g., log only the event name + headerRequestId).
This issue also appears on line 413 of the same file.
| logService?.info(`[DEBUG-TELEMETRY] model.request.added: ` + JSON.stringify({ properties: requestData.properties, measurements: requestData.measurements })); |
| telemetryProperties: { | ||
| requestId: this.options.subAgentInvocationId, | ||
| messageId: randomUUID(), | ||
| messageSource: 'chat.editAgent', | ||
| subType: 'subagent/execution', | ||
| conversationId: this.options.conversation.sessionId, | ||
| parentToolCallId: this.options.parentToolCallId, | ||
| parentHeaderRequestId: this.options.parentHeaderRequestId, | ||
| }, | ||
| }, token); |
There was a problem hiding this comment.
SearchSubagentToolCallingLoop sets requestKindOptions: { kind: 'subagent' }, but ExecutionSubagentToolCallingLoop does not. Without this, execution subagent requests will not send the X-Interaction-Type: conversation-subagent header (and may be misclassified operationally/telemetry-wise). Please add requestKindOptions: { kind: 'subagent' } to this makeChatRequest2 call for consistency with the search subagent loop.
There was a problem hiding this comment.
preexistent absense
…hyleyemohyle/vscode into yemohyle/add_to_telemetry
|
🕵️ CodeSherlock Review: 🔴 Critical Issues:
🟡 Improvements:
🟢 Good Practices:
💡 Suggestions:
Risk Level: LOW |
|
🕵️ CodeSherlock Review: 🔴 Critical Issues:
🟡 Improvements:
🟢 Good Practices:
💡 Suggestions:
Risk Level: LOW |
|
🕵️ CodeSherlock Review: 🔴 Critical Issues:
🟡 Improvements:
🟢 Good Practices:
💡 Suggestions:
Risk Level: LOW |
| // (the server's response header value), because requestId is what appears as headerRequestId | ||
| // across all telemetry events. | ||
| if (fetchResult.type === ChatFetchResponseType.Success) { | ||
| this.lastHeaderRequestId = fetchResult.requestId; |
There was a problem hiding this comment.
can we not say "header request id"? This is the clients guid for request id and I think it should just be "requestId"
There was a problem hiding this comment.
Is this ID not the same as this.options.request.id
There was a problem hiding this comment.
This id is telemetryMessageId, may not be the same as this.options.request.id.
This id already appears as headerRequestId in existing msft internal telemetrey events that track agent trajectories:
engine.messages
model.request.added
model.modelCall.input.
The added property parentHeaderRequestId is meant to appear only for subagent calls and to echo main agent headerRequestId from where the subagent tool was called. I kept the name to be consistent with existing telemetry.
* add last asst messages logs * add last asst messages logs ... * add last asst messages logs .... * add last asst messages logs ..... * add assistant messages added logs * ... * add tokens info * add parentHeaderrequestId value to subagent telemetry * remove debug logging * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * suggested change * extra verification * revert suggested change * remove debug logs * add cashed tokens to Legasy SSE path --------- Co-authored-by: Yevhen Mohylevskyy <yevhenmohylevskyy@Yevhens-MacBook-Pro-2.local> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Add cashed tokens info to telemetry and parentHeaderRequestId for subagent generated events.