agentHostToolCallTracker.ts ×11

Frontier kind: Code frontier

unlabeled · c_7881aead196e

508 tests · 13737 LOC · 48 files · introduces 0 tests · 88 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
11 ranges88 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1152 ranges13737 lines · 48 files · Browse complete extent
All tests (intent)
508 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: 88 introduced LOC across 11 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/agentHostToolCallTracker.ts 88 introduced LOC · 11 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- agentHostToolCallTracker.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 { disposableTimeout } from '../../../base/common/async.js';
7 > import { Disposable, DisposableMap } from '../../../base/common/lifecycle.js';
8 > import { StopWatch } from '../../../base/common/stopwatch.js';
9 > import type { SessionToolAuthenticationRequest, SessionToolClientExecutionRequest, SessionToolConfirmationRequest } from '../common/state/protocol/state.js';
10 > import { ToolCallContributorKind, type ToolCallContributor, type ToolCallResult } from '../common/state/sessionState.js';
11 > import type { AgentHostTelemetryReporter } from './agentHostTelemetryReporter.js';
12 >
13 > export type ToolInvokedResult = 'success' | 'error' | 'userCancelled';
14 >
15 > const TOOL_CALL_STALL_THRESHOLD_MS = 5 * 60 * 1000;
16 >
17 > type ToolCallBlockerRequest = SessionToolConfirmationRequest | SessionToolClientExecutionRequest | SessionToolAuthenticationRequest;
18 >
19 > /**
20 > * Maps a completed tool call's result to the telemetry result bucket. Mirrors
21 > * the derivation previously done inline in `CopilotAgentSession`: a denied,
22 > * rejected, or cancelled tool call counts as `userCancelled`; any other
23 > * failure counts as `error`.
24 > */
25 > export function deriveToolInvokedResult(result: ToolCallResult): ToolInvokedResult {
26 if (result.success) {
27 return 'success';
33 return 'error';
34 }
36 > /**
37 > * Maps a tool call's contributor to the telemetry `toolSourceKind`. A tool with
38 > * no contributor is provided by the agent host itself; an MCP contributor maps
39 > * to `mcp` and a client contributor to `client`.
40 > */
41 > export function toolSourceKindFromContributor(contributor: ToolCallContributor | undefined): string {
42 if (!contributor) {
43 return 'agentHost';
55 }
56 }
58 > /** Per-tool-call timing state, keyed by `session:toolCallId`. */
59 > interface IToolCallTiming {
60 > readonly stopWatch: StopWatch;
61 > readonly provider: string;
62 > readonly session: string;
63 > readonly toolId: string;
64 > readonly toolSourceKind: string;
65 > }
66 >
67 > interface IStalledToolCall {
68 > readonly blockerKind: ToolCallBlockerRequest['kind'];
69 > readonly completionStopWatch: StopWatch;
70 > }
71 >
72 > /**
73 > * Tracks completed and stalled tool calls for agent host sessions.
74 > *
75 > * Lifecycle per tool call:
76 > * 1. {@link toolCallStarted} — begins a stopwatch and records the tool's
77 > * name and source kind (only the start action carries these)
78 > * 2. {@link toolCallCompleted} — emits the telemetry event and clears state
79 > * 3. {@link toolCallBlocked} / {@link toolCallUnblocked} — emits once when a
80 > * confirmation or client execution remains unresolved past the threshold
81 > *
82 > * In-flight tool calls that never complete (e.g. the turn is cancelled mid
83 > * tool call) are dropped via {@link clearSession} / {@link clear} so the
84 > * tracking map cannot leak.
85 > */
86 > export class AgentHostToolCallTracker extends Disposable {
87 >
88 > private readonly _toolCalls = new Map<string, IToolCallTiming>();
89 > private readonly _toolCallStallTimers = this._register(new DisposableMap<string>());
90 > private readonly _stalledToolCalls = new Map<string, IStalledToolCall>();
91 >
92 > constructor(private readonly _reporter: AgentHostTelemetryReporter) {
93 super();
94 }
96 > toolCallStarted(provider: string, session: string, toolCallId: string, toolName: string, contributor: ToolCallContributor | undefined): void {
97 this._toolCalls.set(this._key(session, toolCallId), {
98 stopWatch: StopWatch.create(true),
103 });
104 }
106 > toolCallCompleted(session: string, toolCallId: string, result: ToolCallResult): void {
107 const key = this._key(session, toolCallId);
108 const timing = this._toolCalls.get(key);
141 }
142 }
144 > toolCallBlocked(provider: string, session: string, request: ToolCallBlockerRequest): void {
145 const key = this._key(session, request.id);
146 const toolCallKey = this._key(session, request.toolCall.toolCallId);
163 }, TOOL_CALL_STALL_THRESHOLD_MS));
164 }
166 > toolCallUnblocked(session: string, requestId: string): void {
167 this._toolCallStallTimers.deleteAndDispose(this._key(session, requestId));
168 }
170 > /**
171 > * Drops any in-flight (never-completed) tool calls for a session. Called
172 > * when a turn ends or a session is torn down so the tracking map cannot
173 > * leak. A no-op in the normal case where every tool call completes.
174 > */
175 > clearSession(session: string): void {
176 const prefix = `${session}\0`;
177 for (const key of this._toolCalls.keys()) {