agentHostTelemetryReporter.ts ×13

Frontier kind: Code frontier

unlabeled · c_b08cbb07b617

922 tests · 15237 LOC · 54 files · introduces 0 tests · 345 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
13 ranges345 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1005 ranges15237 lines · 54 files · Browse complete extent
All tests (intent)
922 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 345 introduced LOC across 13 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/agentHostTelemetryReporter.ts 345 introduced LOC · 13 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- agentHostTelemetryReporter.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import type { LanguageModelToolInvokedClassification, LanguageModelToolInvokedEvent } from '../../telemetry/common/languageModelToolTelemetry.js';
7 > import type { ITelemetryService } from '../../telemetry/common/telemetry.js';
8 > import { TelemetryTrustedValue } from '../../telemetry/common/telemetryUtils.js';
9 > import { hash } from '../../../base/common/hash.js';
10 > import { AgentSession } from '../common/agentService.js';
11 > import type { ErrorInfo, MessageAttachment, SessionInputRequestKind, ToolDefinition } from '../common/state/protocol/state.js';
12 > import { isAhpChatChannel, isSubagentChatUri, isSubagentSession, parseRequiredSessionUriFromChatUri, type ISessionWithDefaultChat } from '../common/state/sessionState.js';
13 > import type { ToolInvokedResult } from './agentHostToolCallTracker.js';
14 > import { multiplexProperties, type IAgentHostRestrictedTelemetry, type IAgentHostRestrictedTelemetryContext } from './agentHostRestrictedTelemetry.js';
15 >
16 > export type AgentHostUserMessageSentSource = 'direct' | 'queued';
17 >
18 > export interface IAgentHostUserMessageSentEvent {
19 > provider: string;
20 > agentSessionId: string;
21 > source: AgentHostUserMessageSentSource;
22 > isSubagentSession: boolean;
23 > turnCount: number;
24 > activeClientId?: string;
25 > activeClientToolCount?: number;
26 > activeClientCustomizationCount?: number;
27 > attachmentCount: number;
28 > }
29 >
30 > export type IAgentHostUserMessageSentClassification = {
31 > provider: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The provider handling the agent host session.' };
32 > agentSessionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The agent host session identifier.' };
33 > source: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether the user message was sent directly or from the queued-message flow.' };
34 > isSubagentSession: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Whether the message was sent to a subagent session.' };
35 > turnCount: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The number of completed turns in the session when the message was sent.' };
36 > activeClientId?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifier of the first active client for the session, if any.' };
37 > activeClientToolCount?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The total number of tools provided by the active clients, if any.' };
38 > activeClientCustomizationCount?: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The total number of customizations provided by the active clients, if any.' };
39 > attachmentCount: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'The number of attachments included with the user message.' };
40 > owner: 'roblourens';
41 > comment: 'Tracks user messages sent from the agent host process to an agent provider.';
42 > };
43 >
44 > export type AgentHostTurnResult = 'success' | 'error' | 'cancelled';
45 > export type AgentHostModelTelemetryKind = 'trusted' | 'byok' | 'unknown';
46 > type AgentHostModelSelectionKind = 'default' | 'auto' | 'explicit';
47 > export type AgentHostTurnFailureStage = 'validation' | 'workingDirectory' | 'modelSelection' | 'sendMessage' | 'provider';
48 >
49 > export interface IAgentHostTurnCompletedEvent {
50 > provider: string;
51 > agentSessionId: string;
52 > turnId: string;
53 > timeToFirstProgress: number | undefined;
54 > totalTime: number;
55 > result: AgentHostTurnResult;
56 > model: string | TelemetryTrustedValue<string> | undefined;
57 > modelSelectionKind: AgentHostModelSelectionKind;
58 > permissionLevel: string | undefined;
59 > errorType: string | undefined;
60 > failureStage: AgentHostTurnFailureStage | undefined;
61 > }
62 >
63 > export type IAgentHostTurnCompletedClassification = {
64 > provider: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The provider handling the agent host session.' };
65 > agentSessionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The agent host session identifier.' };
66 > turnId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifier of the turn within the agent host session.' };
67 > timeToFirstProgress: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Time in milliseconds from turn start to the first visible progress (text delta, response part, tool call start, or reasoning).' };
68 > totalTime: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Total time in milliseconds from turn start to turn completion.' };
69 > result: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether the turn completed successfully, with an error, or was cancelled.' };
70 > model: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The trusted provider model identifier selected at turn start, or a generic value for BYOK and unknown models.' };
71 > modelSelectionKind: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether the client used the provider default, Auto, or an explicit model.' };
72 > permissionLevel: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The tool auto-approval level configured for the session at turn start (e.g. default, autoApprove, autopilot).' };
73 > errorType: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The structured agent host or provider error type when the turn fails.' };
74 > failureStage: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The bounded stage at which the agent host turn failed.' };
75 > owner: 'roblourens';
76 > comment: 'Tracks agent host turn performance including time to first visible progress and total turn duration.';
77 > };
78 >
79 > export interface IAgentHostTurnFailedEvent {
80 > provider: string;
81 > agentSessionId: string;
82 > turnId: string;
83 > failureStage: AgentHostTurnFailureStage;
84 > errorType: string;
85 > errorName: string | undefined;
86 > errorCode: string | undefined;
87 > msg: string;
88 > callstack: string | undefined;
89 > }
90 >
91 > export type IAgentHostTurnFailedClassification = {
92 > provider: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The provider handling the failed agent host turn.' };
93 > agentSessionId: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The agent host session identifier.' };
94 > turnId: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The identifier of the failed turn within the agent host session.' };
95 > failureStage: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The bounded stage at which the agent host turn failed.' };
96 > errorType: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The structured agent host or provider error type.' };
97 > errorName: { classification: 'CallstackOrException'; purpose: 'PerformanceAndHealth'; comment: 'The name of the exception, when available.' };
98 > errorCode: { classification: 'CallstackOrException'; purpose: 'PerformanceAndHealth'; comment: 'The exception or protocol error code, when available.' };
99 > msg: { classification: 'CallstackOrException'; purpose: 'PerformanceAndHealth'; comment: 'The error message. VS Code telemetry scrubs file paths and likely secrets before transmission.' };
100 > callstack: { classification: 'CallstackOrException'; purpose: 'PerformanceAndHealth'; comment: 'The error stack. VS Code telemetry scrubs file paths and likely secrets before transmission.' };
101 > owner: 'roblourens';
102 > comment: 'Captures diagnostic details for failed agent host turns.';
103 > };
104 >
105 > export interface IAgentHostTurnFailure {
106 > stage: AgentHostTurnFailureStage;
107 > error: ErrorInfo;
108 > errorName?: string;
109 > errorCode?: string;
110 > errorStack?: string;
111 > }
112 >
113 > export interface IAgentHostTurnCompletedReport {
114 > provider: string;
115 > session: string;
116 > turnId: string;
117 > timeToFirstProgress: number | undefined;
118 > totalTime: number;
119 > result: AgentHostTurnResult;
120 > model: string | undefined;
121 > modelTelemetryKind: AgentHostModelTelemetryKind | undefined;
122 > permissionLevel: string | undefined;
123 > failure: IAgentHostTurnFailure | undefined;
124 > }
125 >
126 > export interface IAgentHostToolInvokedReport {
127 > provider: string;
128 > session: string;
129 > toolId: string;
130 > toolSourceKind: string;
131 > result: ToolInvokedResult;
132 > invocationTimeMs: number;
133 > }
134 >
135 > export interface IAgentHostToolCallDetailsReport {
136 > session: string;
137 > turnId: string;
138 > model: string | undefined;
139 > responseType: string;
140 > /** Count of invocations keyed by tool name, across all rounds in the turn. */
141 > toolCounts: Record<string, number>;
142 > /** Names of the tools offered to the model for this turn. */
143 > availableTools: readonly string[];
144 > /** Number of model-call rounds in the turn, including the final tool-free response round (matches the extension's `toolCallRounds.length`). */
145 > numRequests: number;
146 > totalToolCalls: number;
147 > parallelToolCallRounds: number;
148 > parallelToolCallsTotal: number;
149 > }
150 >
151 > export interface IAgentHostSkillContentReadReport {
152 > /** The skill name. */
153 > name: string;
154 > /** Path to the SKILL.md file. */
155 > path: string;
156 > /** Full skill content; hashed (never sent raw), matching the extension. */
157 > content: string;
158 > /** Where the skill was discovered (project, personal-copilot, plugin, builtin, …). */
159 > source: string | undefined;
160 > /** Name of the plugin the skill came from, when applicable (AH-native analog of the extension's skill extension id). */
161 > pluginName: string | undefined;
162 > /** Version of the plugin the skill came from, when applicable. */
163 > pluginVersion: string | undefined;
164 > }
165 >
166 > export type AgentHostRepoInfoResult = 'success' | 'filesChanged' | 'diffTooLarge' | 'noChanges' | 'tooManyChanges' | 'mergeBaseTooOld' | 'virtualFileSystem' | 'tooManyCommits';
167 >
168 > export interface IAgentHostRepoInfoReport {
169 > telemetryMessageId: string;
170 > location: 'begin' | 'end';
171 > remoteUrl: string;
172 > repoId: string;
173 > repoType: 'github' | 'ado';
174 > headCommitHash: string;
175 > headBranchName: string | undefined;
176 > fileRelativePaths: string | undefined;
177 > diffsJSON: string | undefined;
178 > result: AgentHostRepoInfoResult;
179 > isActiveRepository: 'true';
180 > workspaceFileCount: number;
181 > changedFileCount: number;
182 > diffSizeBytes: number;
183 > }
184 >
185 > export interface IAgentHostToolCallStalledEvent {
186 > provider: string;
187 > agentSessionId: string;
188 > isSubagentSession: boolean;
189 > blockerKind: SessionInputRequestKind.ToolConfirmation | SessionInputRequestKind.ToolClientExecution | SessionInputRequestKind.ToolAuthentication;
190 > toolId: string;
191 > toolSourceKind: string;
192 > stalledTimeMs: number;
193 > }
194 >
195 > export type IAgentHostToolCallStalledClassification = {
196 > provider: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The provider handling the stalled agent host tool call.' };
197 > agentSessionId: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The agent host session identifier.' };
198 > isSubagentSession: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether the stalled tool call belongs to a subagent session.' };
199 > blockerKind: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether the tool call is waiting for confirmation or client execution.' };
200 > toolId: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The identifier of the stalled tool.' };
201 > toolSourceKind: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether the stalled tool is provided by the agent host, an MCP server, or a client.' };
202 > stalledTimeMs: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Time in milliseconds that the tool call has remained blocked.' };
203 > owner: 'roblourens';
204 > comment: 'Tracks agent host tool calls that remain blocked beyond the stall threshold.';
205 > };
206 >
207 > export interface IAgentHostToolCallStalledReport {
208 > provider: string;
209 > session: string;
210 > blockerKind: SessionInputRequestKind.ToolConfirmation | SessionInputRequestKind.ToolClientExecution | SessionInputRequestKind.ToolAuthentication;
211 > toolId: string;
212 > toolSourceKind: string;
213 > stalledTimeMs: number;
214 > }
215 >
216 > export interface IAgentHostStalledToolCallCompletedEvent {
217 > provider: string;
218 > agentSessionId: string;
219 > isSubagentSession: boolean;
220 > blockerKind: SessionInputRequestKind.ToolConfirmation | SessionInputRequestKind.ToolClientExecution | SessionInputRequestKind.ToolAuthentication;
221 > toolId: string;
222 > toolSourceKind: string;
223 > result: ToolInvokedResult;
224 > totalTimeMs: number;
225 > timeAfterStallMs: number;
226 > }
227 >
228 > export type IAgentHostStalledToolCallCompletedClassification = {
229 > provider: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The provider handling the completed agent host tool call.' };
230 > agentSessionId: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The agent host session identifier.' };
231 > isSubagentSession: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether the completed tool call belongs to a subagent session.' };
232 > blockerKind: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether the tool call had stalled waiting for confirmation or client execution.' };
233 > toolId: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'The identifier of the completed tool.' };
234 > toolSourceKind: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether the completed tool is provided by the agent host, an MCP server, or a client.' };
235 > result: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether the stalled tool call eventually completed successfully, with an error, or through user cancellation.' };
236 > totalTimeMs: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Total time in milliseconds from tool call start to completion.' };
237 > timeAfterStallMs: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Time in milliseconds from the stall report to tool call completion.' };
238 > owner: 'roblourens';
239 > comment: 'Tracks agent host tool calls that complete after previously exceeding the stall threshold.';
240 > };
241 >
242 > export interface IAgentHostStalledToolCallCompletedReport {
243 > provider: string;
244 > session: string;
245 > blockerKind: SessionInputRequestKind.ToolConfirmation | SessionInputRequestKind.ToolClientExecution | SessionInputRequestKind.ToolAuthentication;
246 > toolId: string;
247 > toolSourceKind: string;
248 > result: ToolInvokedResult;
249 > totalTimeMs: number;
250 > timeAfterStallMs: number;
251 > }
252 >
253 > export class AgentHostTelemetryReporter {
254 >
255 > constructor(private readonly _telemetryService: ITelemetryService) { }
256 >
257 > /** The restricted GH/MSFT telemetry surface, present when the agent-host telemetry service is wired. */
258 > private get _restricted(): IAgentHostRestrictedTelemetry | undefined {
259 const ts = this._telemetryService as Partial<IAgentHostRestrictedTelemetry>;
260 return typeof ts.sendEnhancedGHTelemetryEvent === 'function' ? ts as IAgentHostRestrictedTelemetry : undefined;
261 }
263 > userMessageSent(provider: string, session: string, sessionState: ISessionWithDefaultChat | undefined, source: AgentHostUserMessageSentSource, attachments: readonly MessageAttachment[] | undefined): void {
264 const attachmentCount = attachments?.length ?? 0;
265 const activeClients = sessionState?.activeClients ?? [];
279 });
280 }
282 > /**
283 > * Mirrors the Copilot extension's enhanced GH `request.options.tools` event for the agent-host
284 > * flow. The extension emits it per LLM request from its model fetcher; the agent host observes
285 > * the equivalent boundary when an `assistant.message` arrives (one per model call). The
286 > * extension populates `headerRequestId` with the client-minted `x-request-id`, which the SDK
287 > * does not surface on success; we keep the same field name (so science queries are undisturbed)
288 > * but fill it with the model call's `x-copilot-service-request-id`, the per-call id the SDK does
289 > * expose. `messagesJson` is the raw tool definitions offered for the call, multiplexed across
290 > * ~8192-char chunks like the extension, so it lands identically downstream.
291 > *
292 > * @param session Session URI string; its id becomes `conversationId`.
293 > * @param serviceRequestId The model call's `x-copilot-service-request-id`, mapped to the extension's `headerRequestId`. No-ops when absent (e.g. providers that don't surface it).
294 > * @param tools The tool definitions offered to the model for this call.
295 > */
296 > assistantMessageReceived(session: string, serviceRequestId: string | undefined, tools: readonly ToolDefinition[]): void {
297 const restricted = this._restricted;
298 if (!restricted || !serviceRequestId || tools.length === 0) {
305 }));
306 }
308 > /**
309 > * Mirrors the Copilot extension's restricted `conversation.messageText` event (the panel-chat
310 > * prefix of `sendConversationalMessageTelemetry`) for the user's prompt. The extension emits it
311 > * for every user and model message, carrying the raw message text to the enhanced GH
312 > * (`copilot_v0_restricted_copilot_event`) and internal MSFT pipelines; the agent host observes
313 > * the same boundary at the SDK `user.message` event. The text is multiplexed across ~8192-char
314 > * chunks (`messageText`, `messageText_02`, …) so long prompts land untruncated, matching the
315 > * extension's `multiplexProperties`.
316 > *
317 > * @param session Session URI string; its id becomes `conversationId`.
318 > * @param content The user's prompt text. No-ops when empty.
319 > * @param turnIndex The 0-based ordinal of the turn this message belongs to, matching the extension's numeric `turnIndex` (`conversation.turns.length`). CTS parses `turn_index` as an integer, so a numeric ordinal is required here (a non-numeric id lands empty).
320 > */
321 > userMessageText(session: string, content: string, turnIndex: number): void {
322 const restricted = this._restricted;
323 if (!restricted || !content) {
334 restricted.sendInternalMSFTTelemetryEvent('conversation.messageText', properties, measurements);
335 }
337 > /**
338 > * The model-message counterpart to {@link userMessageText}. Emitted when an `assistant.message`
339 > * arrives (the agent host's per-model-call boundary), carrying the assistant's response text.
340 > * `headerRequestId` is filled with the model call's `x-copilot-service-request-id` (the id the
341 > * SDK exposes), mirroring the field the extension populates from the client-minted request id.
342 > * VS Code-only enrichment dims (code-block languages/counts) are not reconstructed here.
343 > *
344 > * @param session Session URI string; its id becomes `conversationId`.
345 > * @param content The assistant's response text. No-ops when empty.
346 > * @param turnIndex The 0-based ordinal of the turn this message belongs to, matching the extension's numeric `turnIndex` (`conversation.turns.length`). CTS parses `turn_index` as an integer, so a numeric ordinal is required here.
347 > * @param serviceRequestId The model call's `x-copilot-service-request-id`, mapped to `headerRequestId`.
348 > */
349 > modelMessageText(session: string, content: string, turnIndex: number, serviceRequestId: string | undefined): void {
350 const restricted = this._restricted;
351 if (!restricted || !content) {
363 restricted.sendInternalMSFTTelemetryEvent('conversation.messageText', properties, measurements);
364 }
366 > /**
367 > * Mirrors the Copilot extension's restricted `toolCallDetailsExternal` / `toolCallDetailsInternal`
368 > * events (`chatParticipantTelemetry.ts` -> `sendToolCallingTelemetry`) — the per-turn tool-call
369 > * aggregate. The extension emits it once at the end of a turn's tool-calling loop; the agent host
370 > * accumulates the same counts across the turn's `assistant.message` rounds and emits on turn
371 > * completion. The tool-definition token count, per-round token/char counts, invalid-round count,
372 > * and turn index (the extension emits it only as a non-landing measurement) are not surfaced at the
373 > * AH turn boundary and are omitted. Like the extension, this fires for every turn that had tools
374 > * available — even one that made no tool calls (empty `toolCounts`) — and no-ops only when no tools
375 > * were offered.
376 > *
377 > * @param report The per-turn tool-call aggregate.
378 > */
379 > toolCallDetails(report: IAgentHostToolCallDetailsReport): void {
380 const restricted = this._restricted;
381 if (!restricted || report.availableTools.length === 0) {
402 restricted.sendInternalMSFTTelemetryEvent('toolCallDetailsInternal', properties, measurements);
403 }
405 > /**
406 > * Mirrors the Copilot extension's restricted `skillContentRead` event (`skillTelemetry.ts` ->
407 > * `sendSkillContentReadTelemetry`) — records which skill file was loaded into the conversation.
408 > * The extension emits it from the skill/readFile tools; the agent host observes the equivalent
409 > * boundary at the SDK `skill.invoked` event, whose payload already carries the content (hashed
410 > * here, never sent raw), the discovery `source`, and the plugin identity. The extension's
411 > * `skillExtensionId` / `skillExtensionVersion` encode the contributing *VS Code extension*, which
412 > * does not exist in the agent host; the AH-native provenance is the plugin, so `pluginName` /
413 > * `pluginVersion` fill those columns. No-ops when the skill name is empty.
414 > *
415 > * @param report The invoked skill's metadata (from the SDK `skill.invoked` payload).
416 > */
417 > skillContentRead(report: IAgentHostSkillContentReadReport): void {
418 const restricted = this._restricted;
419 if (!restricted || !report.name) {
443 restricted.sendInternalMSFTTelemetryEvent('skillContentRead', plaintextProps);
444 }
446 > reportRepoInfo(context: IAgentHostRestrictedTelemetryContext, report: IAgentHostRepoInfoReport): void {
447 const restricted = this._restricted;
448 if (!restricted) {
473 restricted.sendInternalMSFTTelemetryEventForContext(context, 'request.repoInfo', multiplexProperties(internalProperties), measurements);
474 }
476 > turnCompleted(report: IAgentHostTurnCompletedReport): void {
477 const session = isAhpChatChannel(report.session) ? parseRequiredSessionUriFromChatUri(report.session) : report.session;
478 const model = report.model === undefined
508 }
509 }
511 > toolInvoked(report: IAgentHostToolInvokedReport): void {
512 // `chatSessionId` is the full session URI string (matching the value
513 // previously emitted by `CopilotAgentSession`). Action signals are keyed
524 });
525 }
527 > toolCallStalled(report: IAgentHostToolCallStalledReport): void {
528 const session = isAhpChatChannel(report.session) ? parseRequiredSessionUriFromChatUri(report.session) : report.session;
529 this._telemetryService.publicLog2<IAgentHostToolCallStalledEvent, IAgentHostToolCallStalledClassification>('agentHost.toolCallStalled', {
537 });
538 }
540 > stalledToolCallCompleted(report: IAgentHostStalledToolCallCompletedReport): void {
541 const session = isAhpChatChannel(report.session) ? parseRequiredSessionUriFromChatUri(report.session) : report.session;
542 this._telemetryService.publicLog2<IAgentHostStalledToolCallCompletedEvent, IAgentHostStalledToolCallCompletedClassification>('agentHost.stalledToolCallCompleted', {