promptRegistry.ts ×7

Frontier kind: Code frontier

unlabeled · c_988c97c2a1bf

442 tests · 7226 LOC · 41 files · introduces 0 tests · 339 LOC · 4 files

Introduces — evidence that enters the hierarchy at this concept

Code
17 ranges339 lines · 4 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
583 ranges7226 lines · 41 files · Browse complete extent
All tests (intent)
442 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.

4 files ranked by introduced lines: 339 introduced LOC across 17 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/copilot/prompts/promptRegistry.ts 187 introduced LOC · 7 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- promptRegistry.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 { SectionOverride, SystemMessageConfig, SystemMessageSection } from '@github/copilot-sdk';
7 > import { copilotCliConfigSchema } from '../../../common/copilotCliConfig.js';
8 > import type { SchemaValue } from '../../../common/agentHostSchema.js';
9 > import type { ModelSelection } from '../../../common/state/protocol/state.js';
10 > import { appendSystemMessageContent, COPILOT_AGENT_HOST_FILE_LINK_INSTRUCTIONS, COPILOT_AGENT_HOST_WORKSPACELESS_INSTRUCTIONS, COPILOT_AGENT_HOST_SYSTEM_MESSAGE, fullSystemPrompt, sectionOverrides } from './systemMessage.js';
11 > import { resolveToolInstructionsOverride, toolSearchInstructionLines } from './toolInstructions.js';
12 >
13 > type CopilotCliConfigDefinition = typeof copilotCliConfigSchema.definition;
14 >
15 > /**
16 > * Read-time context handed to prompt contributors so they can gate behavior on
17 > * host configuration — the agent-host equivalent of the Copilot extension
18 > * injecting `IConfigurationService` into a resolver.
19 > *
20 > * Scoped to the Copilot CLI config schema so contributors (and tests) read
21 > * settings in a fully-typed way without depending on the whole configuration
22 > * service.
23 > */
24 > export interface IAgentHostPromptContext {
25 > /**
26 > * Returns the host-level value for a Copilot CLI setting, or `undefined`
27 > * when unset. Mirrors `IAgentConfigurationService.getRootValue` bound to
28 > * {@link copilotCliConfigSchema}.
29 > */
30 > getSetting<K extends keyof CopilotCliConfigDefinition & string>(key: K): SchemaValue<CopilotCliConfigDefinition[K]> | undefined;
31 >
32 > /**
33 > * Returns whether a *client* tool is available in the session, addressed by
34 > * the camelCase `toolReferenceName` the agent sees it under (e.g.
35 > * `openBrowserPage`). Used to gate tool-specific instructions on the tool
36 > * being present, the agent-host equivalent of the Copilot extension
37 > * inspecting its tool set.
38 > *
39 > * Scope: client tools only (the forwarded workbench tools). It does NOT see
40 > * shell tools, server-SDK tools, or MCP-provided tools — those aren't in the
41 > * session snapshot at launch (MCP is discovered dynamically). A line that
42 > * gates on one of those names silently resolves to `false`; broadening this
43 > * is the context-enrichment follow-up.
44 > */
45 > hasClientTool(name: string): boolean;
46 >
47 > /** Whether deferred tool search is active for this session. */
48 > toolSearchActive: boolean;
49 >
50 > /**
51 > * Whether this is a workspace-less session. When `true`, the
52 > * resolved system message gets a scratch/repoless section (see
53 > * {@link COPILOT_AGENT_HOST_WORKSPACELESS_INSTRUCTIONS}) telling the agent its
54 > * working directory is a scratch dir, not a code repo. Set by the launcher
55 > * from the session's `workspaceless` marker.
56 > */
57 > workspaceless: boolean;
58 > }
59 >
60 > /**
61 > * Per-model system-prompt contributor for Copilot CLI agent-host sessions.
62 > *
63 > * Mirrors the Copilot extension's `IAgentPrompt`, but — because the agent host
64 > * runs in its own process and cannot use prompt-tsx — a contributor returns
65 > * plain data the SDK accepts directly rather than prompt-tsx elements.
66 > *
67 > * A contributor may provide EITHER a full system-prompt override OR a set of
68 > * section overrides. When it provides a full prompt that wins (`replace` mode);
69 > * otherwise the section overrides are applied (`customize` mode).
70 > */
71 > export interface IAgentHostPrompt {
72 > /**
73 > * Full system-prompt override. Resolved into `{ mode: 'replace' }`, which
74 > * drops the SDK foundation prompt and its guardrails.
75 > */
76 > resolveFullSystemPrompt?(model: ModelSelection, context: IAgentHostPromptContext): string | undefined;
77 >
78 > /**
79 > * Section-level overrides. Resolved into `{ mode: 'customize' }`, keeping the
80 > * SDK foundation prompt and guardrails intact.
81 > */
82 > resolveSectionOverrides?(model: ModelSelection, context: IAgentHostPromptContext): Partial<Record<SystemMessageSection, SectionOverride>> | undefined;
83 > }
84 >
85 > /**
86 > * Constructor/static shape for a registered prompt contributor. Mirrors the
87 > * Copilot extension's `IAgentPromptCtor`: a contributor matches a model either
88 > * by a custom {@link matchesModel} predicate or by a model-id family prefix.
89 > */
90 > export interface IAgentHostPromptCtor {
91 > /** Model-id prefixes this contributor handles (e.g. `'claude'`, `'gpt-5'`). */
92 > readonly familyPrefixes: readonly string[];
93 >
94 > /** Optional custom matcher; takes precedence over {@link familyPrefixes}. */
95 > matchesModel?(model: ModelSelection): boolean;
96 >
97 > new(): IAgentHostPrompt;
98 > }
99 >
100 > type PromptWithMatcher = IAgentHostPromptCtor & { matchesModel: (model: ModelSelection) => boolean };
101 >
102 > /**
103 > * Registry of per-model system-prompt contributors for Copilot CLI agent-host
104 > * sessions. Mirrors the Copilot extension's `PromptRegistry`: contributors
105 > * register a model match (custom predicate or family prefix) and the session
106 > * launcher calls {@link resolveSystemMessageConfig} when building a session.
107 > *
108 > * Exported as a class for isolated unit testing; a shared singleton
109 > * ({@link agentHostPromptRegistry}) is what contributors register into and the
110 > * launcher consumes.
111 > */
112 > export class AgentHostPromptRegistry {
113 > private readonly _promptsWithMatcher: PromptWithMatcher[] = [];
114 > private readonly _familyPrefixList: { readonly prefix: string; readonly ctor: IAgentHostPromptCtor }[] = [];
115 >
116 > registerPrompt(ctor: IAgentHostPromptCtor): void {
117 > if (ctor.matchesModel) {
118 > this._promptsWithMatcher.push(ctor as PromptWithMatcher);
119 > }
120 > for (const prefix of ctor.familyPrefixes) {
121 this._familyPrefixList.push({ prefix, ctor });
122 }
124 >
125 > private _getContributor(model: ModelSelection): IAgentHostPromptCtor | undefined {
126 for (const ctor of this._promptsWithMatcher) {
127 if (ctor.matchesModel(model)) {
136 return undefined;
137 }
139 > /**
140 > * Resolves the {@link SystemMessageConfig} for a session's model: the
141 > * per-model (or default) config from {@link _resolveModelConfig}, with the
142 > * model-agnostic section overrides from {@link _withUniversalSections}
143 > * layered on top.
144 > *
145 > * Lifetime: the SDK accepts a system message only at session create/resume
146 > * (there is no mid-session update), so this is resolved once per (re)launch
147 > * and any tool-gated content reflects the tool set at that moment. A change
148 > * to the session's tools/plugins is part of the launcher's restart-detection
149 > * snapshot, so it re-launches the session and recomputes this; an in-flight
150 > * turn keeps the prompt it launched with.
151 > */
152 > resolveSystemMessageConfig(model: ModelSelection | undefined, context: IAgentHostPromptContext): SystemMessageConfig {
153 const config = this._withUniversalSections(this._resolveModelConfig(model, context), context);
154 const withWorkspacelessScratch = this._withWorkspacelessScratch(config, context);
155 return appendSystemMessageContent(withWorkspacelessScratch, COPILOT_AGENT_HOST_FILE_LINK_INSTRUCTIONS);
156 }
158 > /**
159 > * Resolves the per-model config, before universal sections are layered on.
160 > *
161 > * Falls back to {@link COPILOT_AGENT_HOST_SYSTEM_MESSAGE} when the model is
162 > * unknown (e.g. server-side "Auto" selection where no model is chosen at
163 > * create time), when no contributor matches, or when the matching
164 > * contributor opts out for the current {@link context} (e.g. a setting that
165 > * gates it is disabled).
166 > */
167 > private _resolveModelConfig(model: ModelSelection | undefined, context: IAgentHostPromptContext): SystemMessageConfig {
168 if (!model) {
169 return COPILOT_AGENT_HOST_SYSTEM_MESSAGE;
187 return COPILOT_AGENT_HOST_SYSTEM_MESSAGE;
188 }
190 > /**
191 > * Layers section overrides that apply to EVERY model on top of the per-model
192 > * (or default) config. Currently this is only the `tool_instructions` section
193 > * (see {@link resolveToolInstructionsOverride}), which the agent host wants
194 > * for all models rather than gating per-model like the Opus prompt.
195 > *
196 > * Only `customize`-mode configs carry section overrides, so this is a no-op
197 > * for a contributor's full `replace` prompt (which owns the entire system
198 > * message and intentionally drops the SDK foundation) and for `append` mode.
199 > * A `replace` contributor that wants the universal guidance re-includes it
200 > * itself by rendering `universalToolInstructions` (in `toolInstructions.ts`)
201 > * from its `resolveFullSystemPrompt`, mirroring how the extension's full-prompt
202 > * models inline the same lines.
203 > *
204 > * A per-model `tool_instructions` override is composed with — not overwritten
205 > * by — the universal lines (see {@link resolveToolInstructionsOverride}).
206 > */
207 > private _withUniversalSections(config: SystemMessageConfig, context: IAgentHostPromptContext): SystemMessageConfig {
208 if (config.mode !== 'customize') {
209 return config;
215 return { ...config, sections: { ...config.sections, tool_instructions: toolInstructions } };
216 }
218 > /**
219 > * Appends the scratch/repoless workspace-less guidance (see
220 > * {@link COPILOT_AGENT_HOST_WORKSPACELESS_INSTRUCTIONS}) as customize-mode
221 > * `content` when {@link IAgentHostPromptContext.workspaceless} is set, so it
222 > * composes on top of whatever sections the per-model (or default) config
223 > * carries while keeping the SDK foundation intact.
224 > *
225 > * No-op for workspace-bound sessions and for a full `replace` prompt (which
226 > * owns the entire system message and intentionally drops the SDK foundation).
227 > */
228 > private _withWorkspacelessScratch(config: SystemMessageConfig, context: IAgentHostPromptContext): SystemMessageConfig {
229 if (!context.workspaceless || config.mode !== 'customize') {
230 return config;
233 return { ...config, content };
234 }
236 >
237 > /**
238 > * Shared registry instance. Per-model contributors register here (see
239 > * `allPrompts.ts`) and the session launcher reads from it.
240 > */
241 > export const agentHostPromptRegistry = new AgentHostPromptRegistry();
src/vs/platform/agentHost/node/copilot/prompts/systemMessage.ts 92 introduced LOC · 4 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- systemMessage.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 { SectionOverride, SystemMessageConfig, SystemMessageSection } from '@github/copilot-sdk';
7 >
8 > /**
9 > * Identity section content shared by the default agent-host system message and
10 > * any per-model override that wants to keep the same self-description. Kept as
11 > * a single constant so the identity text is defined in exactly one place.
12 > */
13 > export const COPILOT_AGENT_HOST_IDENTITY = 'You are an AI assistant using Copilot CLI runtime in VS Code. You help users with software engineering tasks. When asked about your identity, you must state that you are an AI assistant using Copilot CLI runtime in VS Code.';
14 >
15 > /** Response-formatting contract for workspace links emitted by Agent Host models. */
16 > export const COPILOT_AGENT_HOST_FILE_LINK_INSTRUCTIONS = [
17 > '<file_folder_and_symbol_links>',
18 > 'Always use Markdown links when referring to existing files, folders, or symbols in the workspace. This is very important for helping the user understand your responses.',
19 > '- File: use the file name as the link text and the absolute filesystem path as the target, for example [foo.ts](/path/to/foo.ts).',
20 > '- Folder: links to folders are also supported, with an absolute path to the folder as the target, for example [src/](/path/to/src).',
21 > '- Symbol: link to symbols by using the containing file path with a 1-based line number as the target, for example [myMethod](/path/to/foo.ts:42).',
22 > '- Use `/` path separators in link targets, including on Windows (`C:/path/to/foo.ts`).',
23 > '- If a file path has spaces, wrap the target in angle brackets: [foo bar.ts](</path/to/foo bar.ts>).',
24 > '- Use absolute filesystem paths rather than `file://` URIs.',
25 > '- Do not provide line ranges.',
26 > '- Use a markdown link format every time you refer to a file, folder, or symbol, not just the first time.',
27 > '</file_folder_and_symbol_links>',
28 > ].join('\n');
29 >
30 > /**
31 > * Default system-message customization applied to every Copilot CLI agent-host
32 > * session that has no per-model override registered in the
33 > * {@link AgentHostPromptRegistry}.
34 > *
35 > * Uses `customize` mode so the CLI/SDK foundation prompt (and its built-in
36 > * guardrails) stay intact — only the `identity` section is replaced.
37 > */
38 > export const COPILOT_AGENT_HOST_SYSTEM_MESSAGE = {
39 > mode: 'customize',
40 > sections: {
41 > identity: {
42 > action: 'replace',
43 > content: COPILOT_AGENT_HOST_IDENTITY,
44 > },
45 > },
46 > } satisfies SystemMessageConfig;
47 >
48 > /**
49 > * Scratch/repoless guidance appended to a workspace-less chat's system message.
50 > * A workspace-less chat's working directory is a throwaway SCRATCH dir, not a
51 > * code repository — so this tells the agent not to treat it like a project, to
52 > * stay read-only on real repos, and to delegate code changes to a dedicated
53 > * session. Modeled on the GitHub app's `build_general_chat_system_message`.
54 > */
55 > export const COPILOT_AGENT_HOST_WORKSPACELESS_INSTRUCTIONS = [
56 > '<workspaceless_chat>',
57 > 'This is a lightweight workspace-less chat, not tied to any project or workspace. The user opens it for quick questions, navigation, and triage.',
58 > '',
59 > '- Your working directory is a SCRATCH directory for running commands and saving throwaway artifacts — it is NOT a code repository. Do not treat it as a project to build, test, or commit.',
60 > '- If the user points you at a real repository, prefer read-only operations: read files, search code, and inspect git metadata (branch, log, diff, status) to answer questions. Avoid modifying files or running builds, tests, linters, or installs in their working copies.',
61 > '- When the user wants code changes, test runs, or any work that modifies or executes against a real project, delegate it to a dedicated session rather than doing it here.',
62 > '</workspaceless_chat>',
63 > ].join('\n');
64 >
65 > /**
66 > * Builds a {@link SystemMessageConfig} that fully replaces the CLI/SDK system
67 > * prompt with `content`.
68 > *
69 > * ⚠️ `replace` mode drops ALL SDK guardrails (including security restrictions);
70 > * prefer {@link sectionOverrides} unless the caller intends to own the entire
71 > * prompt.
72 > */
73 > export function fullSystemPrompt(content: string): SystemMessageConfig {
74 return { mode: 'replace', content };
75 }
77 > /**
78 > * Builds a `customize`-mode {@link SystemMessageConfig} that overrides only the
79 > * given sections, leaving the rest of the CLI/SDK foundation prompt intact.
80 > */
81 > export function sectionOverrides(sections: Partial<Record<SystemMessageSection, SectionOverride>>): SystemMessageConfig {
82 return { mode: 'customize', sections };
83 }
85 > /** Appends universal content without changing a full-prompt replacement. */
86 > export function appendSystemMessageContent(config: SystemMessageConfig, content: string): SystemMessageConfig {
87 if (config.mode === 'replace') {
88 return config;
91 return { ...config, content: existing ? `${existing}\n\n${content}` : content };
92 }
94 > /**
95 > * One-line, log-friendly summary of a resolved {@link SystemMessageConfig} —
96 > * the mode plus, for `customize`, which sections are overridden and with what
97 > * action (e.g. `mode=customize sections=[identity:replace, tool_instructions:append]`).
98 > *
99 > * Keeps prompt observability cheap at `info` level without dumping full prompt
100 > * text on every session launch (log the whole config at `trace` for that).
101 > */
102 > export function describeSystemMessageConfig(config: SystemMessageConfig): string {
103 if (config.mode === 'replace') {
104 return `mode=replace (content length ${config.content.length})`;
src/vs/platform/agentHost/node/copilot/prompts/anthropicPrompt.ts 44 introduced LOC · 5 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- anthropicPrompt.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 { SectionOverride, SystemMessageSection } from '@github/copilot-sdk';
7 > import { CopilotCliConfigKey } from '../../../common/copilotCliConfig.js';
8 > import type { ModelSelection } from '../../../common/state/protocol/state.js';
9 > import { agentHostPromptRegistry, type IAgentHostPrompt, type IAgentHostPromptContext } from './promptRegistry.js';
10 > import { COPILOT_AGENT_HOST_IDENTITY } from './systemMessage.js';
11 >
12 > /**
13 > * `customize`-mode section overrides for Claude Opus 4.8, tuned per Anthropic's
14 > * "Prompting Claude Opus 4.8" guide:
15 > * https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-opus-4-8
16 > *
17 > * Opus 4.8 performs well out of the box, so this stays intentionally minimal:
18 > * it keeps the SDK foundation prompt (and its tool/safety sections) intact and
19 > * only nudges the two behaviors the guide calls out for tuning —
20 > * - verbosity/tone: the model calibrates length to task complexity, so steer
21 > * it toward concision when a consistent style is wanted; and
22 > * - subagents: the model spawns fewer by default, so give explicit fan-out
23 > * guidance.
24 > * The guide warns against forcing interim-progress scaffolding ("summarize
25 > * after every N tool calls"), so none is added here. The identity is re-stated
26 > * to keep the agent-host self-description that the default message applies.
27 > */
28 function opus48SectionOverrides(): Partial<Record<SystemMessageSection, SectionOverride>> {
29 return {
47 };
48 }
50 > /** Whether `model` is Claude Opus 4.8 — matches the SDK dashed id and the CAPI dotted id. */
51 function isOpus48(model: ModelSelection): boolean {
52 return model.id.startsWith('claude-opus-4-8') || model.id.startsWith('claude-opus-4.8');
53 }
55 > /**
56 > * Opus 4.8 agent prompt for Claude Opus 4.8 sessions: matches only Opus 4.8 and
57 > * is opt-in via {@link CopilotCliConfigKey.Opus48Prompt}. Off → falls back to the
58 > * default system message.
59 > */
60 > class Claude48OpusPromptResolver implements IAgentHostPrompt {
61 > static readonly familyPrefixes: readonly string[] = [];
62 >
63 > static matchesModel(model: ModelSelection): boolean {
64 return isOpus48(model);
65 }
67 > resolveSectionOverrides(_model: ModelSelection, context: IAgentHostPromptContext): Partial<Record<SystemMessageSection, SectionOverride>> | undefined {
68 return context.getSetting(CopilotCliConfigKey.Opus48Prompt) === true ? opus48SectionOverrides() : undefined;
69 }
71 >
72 > agentHostPromptRegistry.registerPrompt(Claude48OpusPromptResolver);
src/vs/platform/agentHost/node/copilot/prompts/allPrompts.ts 16 introduced LOC · 1 range

Open complete file

1 > /*--------------------------------------------------------------------------------------------- allPrompts.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 > // Side-effect import hub for per-model Copilot CLI agent-host prompt
7 > // contributors. Importing this module registers every contributor into the
8 > // shared `agentHostPromptRegistry`. Mirrors the Copilot extension's
9 > // `allAgentPrompts.ts`.
10 > //
11 > // Add per-model modules here as they are ported over, e.g.:
12 > //
13 > // import './geminiPrompt.js';
14 > // import './openaiPrompt.js';
15 >
16 > import './anthropicPrompt.js';