src/vs/platform/agentHost/common/meta/agentToolCallMeta.ts

157 LOC · 155 covered · 2 uncovered · 23 ranges · 6287 concepts · 11 introducers · 3170 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

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 related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- sessionState.ts ×57
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 { Mutable } from '../../../../base/common/types.js';
7 >
8 > /** Anything carrying a tool call's `_meta` bag (persisted state or wire actions). */
9 > interface IHasToolCallMeta {
10 > readonly _meta?: Record<string, unknown>;
11 > }
12 >
13 > /**
14 > * Well-known typed view over a tool call's open `_meta` bag. Producers and
15 > * consumers agree on these keys here so the two sides can't drift; always read
16 > * the bag through {@link readToolCallMeta}, which validates each field and drops
17 > * wrong-typed values.
18 > */
19 > export interface IToolCallMeta {
20 > /**
21 > * VS Code rendering hint. `terminal` routes the call to the command/output
22 > * renderer, `subagent` to the subagent UI, `search` to the search renderer;
23 > * everything else falls through to the generic invocation renderer. Set by
24 > * the agent adapter, never matched on raw tool name by the renderer.
25 > */
26 > readonly toolKind?: ToolKind;
27 > /** Shell language for a `terminal` tool call (drives syntax highlighting). */
28 > readonly language?: string;
29 > /** Short task description for a `subagent` tool call (e.g. "Find related files"). */
30 > readonly subagentDescription?: string;
31 > /** Agent name for a `subagent` tool call (e.g. "explore"). */
32 > readonly subagentAgentName?: string;
33 > /** Chat URI of the subagent this tool call spawns, stamped by the host (see {@link buildSubagentChatUri}); the resource may not be registered yet. */
34 > readonly subagentChatUri?: string;
35 > /** Raw, pre-stringified tool arguments captured for display/debugging. */
36 > readonly toolArguments?: unknown;
37 > /** Originating MCP server name, when the call came from an MCP server. */
38 > readonly mcpServerName?: string;
39 > /** Originating MCP tool name, when the call came from an MCP server. */
40 > readonly mcpToolName?: string;
41 > /** MCP App render data, when the call exposes an interactive App surface. */
42 > readonly ui?: IToolCallUiMeta;
43 > /**
44 > * Set by the host's side-effect layer when the call was auto-approved
45 > * because of an `autoApprove` session-config setting (rather than an
46 > * explicit user action), so the client can render it as setting-driven.
47 > */
48 > readonly autoApproveBySetting?: boolean;
49 > /** Transient runtime corpus for the local client tool-search invocation. */
50 > readonly toolSearchCandidates?: readonly IToolSearchCandidate[];
51 > }
52 >
53 > /** Minimal metadata needed to embed and rank a deferred tool. */
54 > export interface IToolSearchCandidate {
55 > readonly name: string;
56 > readonly description: string;
57 > }
58 >
59 > /**
60 > * The set of VS Code-recognized tool-call rendering kinds. Add a new value here
61 > * (and teach the renderer to handle it) rather than matching on tool name.
62 > */
63 > export type ToolKind = 'terminal' | 'subagent' | 'search';
64 >
65 > /**
66 > * MCP App render data carried under {@link IToolCallMeta.ui}. Clients gate
67 > * mounting the App webview on both a `resourceUri` and a `channel` being
68 > * present.
69 > */
70 > export interface IToolCallUiMeta {
71 > /** The MCP App's UI resource URI (an `ui://` resource the App renders). */
72 > readonly resourceUri: string;
73 > /** AHP `mcp://` channel the App's sub-RPCs route back through, when ready. */
74 > readonly channel?: string;
75 > }
76 >
77 > function isToolKind(value: unknown): value is ToolKind { agentToolCallMeta.ts ×6
78 > return value === 'terminal' || value === 'subagent' || value === 'search';
79 > }
81 > function readToolCallUiMeta(value: unknown): IToolCallUiMeta | undefined { agentToolCallMeta.ts ×6
82 > if (!value || typeof value !== 'object' || Array.isArray(value)) {
83 > return undefined; agentToolCallMeta.ts ×1
84 > }
85 > const raw = value as Record<string, unknown>; agentToolCallMeta.ts ×1
86 > if (typeof raw['resourceUri'] !== 'string' || raw['resourceUri'].length === 0) { agentToolCallMeta.ts ×6
87 > return undefined; agentToolCallMeta.ts ×1
88 > }
89 > const result: Mutable<IToolCallUiMeta> = { resourceUri: raw['resourceUri'] }; agentToolCallMeta.ts ×2
90 > if (typeof raw['channel'] === 'string' && raw['channel'].length > 0) { agentToolCallMeta.ts ×6
91 > result.channel = raw['channel']; agentToolCallMeta.ts ×2
92 > }
93 > return result;
94 > }
96 > function readToolSearchCandidates(value: unknown): readonly IToolSearchCandidate[] | undefined { agentToolCallMeta.ts ×6
97 > if (!Array.isArray(value)) {
98 > return undefined;
99 > }
100 > const result: IToolSearchCandidate[] = []; agentToolCallMeta.ts ×2
101 > for (const candidate of value) {
102 > if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
103 return undefined;
104 }
105 > const raw = candidate as Record<string, unknown>; agentToolCallMeta.ts ×2
106 > if (typeof raw['name'] !== 'string' || typeof raw['description'] !== 'string') {
107 > return undefined;
108 > }
109 > result.push({
110 > name: raw['name'],
111 > description: raw['description'],
112 > });
113 > }
114 > return result;
115 > }
117 > /**
118 > * Reads the well-known {@link IToolCallMeta} keys from a tool call's `_meta`
119 > * bag, dropping unknown keys and wrong-typed values.
120 > */
121 > export function readToolCallMeta(source: IHasToolCallMeta): IToolCallMeta {
122 > const meta = source._meta; agentToolCallMeta.ts ×1
123 > if (!meta) {
124 > return {}; agentToolCallMeta.ts ×1
125 > }
126 > const result: Mutable<IToolCallMeta> = {}; agentToolCallMeta.ts ×6
127 > if (isToolKind(meta['toolKind'])) { result.toolKind = meta['toolKind']; }
128 > if (typeof meta['language'] === 'string') { result.language = meta['language']; }
129 > if (typeof meta['subagentDescription'] === 'string') { result.subagentDescription = meta['subagentDescription']; }
130 > if (typeof meta['subagentAgentName'] === 'string') { result.subagentAgentName = meta['subagentAgentName']; }
131 > if (typeof meta['subagentChatUri'] === 'string') { result.subagentChatUri = meta['subagentChatUri']; }
132 > if (meta['toolArguments'] !== undefined) { result.toolArguments = meta['toolArguments']; }
133 > if (typeof meta['mcpServerName'] === 'string') { result.mcpServerName = meta['mcpServerName']; }
134 > if (typeof meta['mcpToolName'] === 'string') { result.mcpToolName = meta['mcpToolName']; }
135 > if (typeof meta['autoApproveBySetting'] === 'boolean') { result.autoApproveBySetting = meta['autoApproveBySetting']; }
136 > const toolSearchCandidates = readToolSearchCandidates(meta['toolSearchCandidates']);
137 > if (toolSearchCandidates) { result.toolSearchCandidates = toolSearchCandidates; }
138 > const ui = readToolCallUiMeta(meta['ui']);
139 > if (ui) { result.ui = ui; }
140 > return result;
141 > }
143 > /**
144 > * Serializes a typed {@link IToolCallMeta} into the `_meta` record, dropping
145 > * `undefined` entries and returning `undefined` when empty. Build a tool call's
146 > * `_meta` through this so producers stay in lock-step with
147 > * {@link readToolCallMeta}.
148 > */
149 > export function toToolCallMeta(meta: IToolCallMeta): Record<string, unknown> | undefined {
150 > const result: Record<string, unknown> = {}; agentToolCallMeta.ts ×2
151 > for (const [key, value] of Object.entries(meta)) {
152 > if (value !== undefined) {
153 > result[key] = value; agentToolCallMeta.ts ×1
154 > }
156 > return Object.keys(result).length > 0 ? result : undefined;
157 > }