Skip to content

Commit 3d6a871

Browse files
authored
Rename executePrompt to runSubagent (#1420)
1 parent 7cb8330 commit 3d6a871

File tree

9 files changed

+45
-46
lines changed

9 files changed

+45
-46
lines changed

assets/chatmodes/Plan.chatmode.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
description: Researches a task to create multi-step plans
3-
tools: ['search', 'github/github-mcp-server/get_issue', 'github/github-mcp-server/get_issue_comments', 'executePrompt', 'usages', 'problems', 'changes', 'testFailure', 'fetch', 'githubRepo', 'github.vscode-pull-request-github/issue_fetch', 'github.vscode-pull-request-github/activePullRequest', 'todos']
3+
tools: ['search', 'github/github-mcp-server/get_issue', 'github/github-mcp-server/get_issue_comments', 'runSubagent', 'usages', 'problems', 'changes', 'testFailure', 'fetch', 'githubRepo', 'github.vscode-pull-request-github/issue_fetch', 'github.vscode-pull-request-github/activePullRequest', 'todos']
44
handoffs:
55
- label: Start Implementation
66
agent: agent
@@ -17,11 +17,11 @@ Comprehensive context gathering for planning following <plan_research>:
1717

1818
## 1. Context gathering and research:
1919

20-
MANDATORY: Run #executePrompt tool, instructing the agent to work autonomously without pausing for user feedback, following <plan_research> to gather context to return to you.
20+
MANDATORY: Run #runSubagent tool, instructing the agent to work autonomously without pausing for user feedback, following <plan_research> to gather context to return to you.
2121

22-
DO NOT do any other tool calls after #executePrompt returns!
22+
DO NOT do any other tool calls after #runSubagent returns!
2323

24-
If #executePrompt tool is NOT available, run <plan_research> via tools yourself.
24+
If #runSubagent tool is NOT available, run <plan_research> via tools yourself.
2525

2626
## 2. Present a concise plan to the user for iteration:
2727

docs/tools.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ First, consider whether a new built-in tool is needed. Tools should be built-in
1515
### Static part
1616

1717
First, add an entry in vscode-copilot's package.json under `contributes.languageModelTools`:
18-
- Give it a name that starts with `copilot_`- this pattern is protected for our use only
18+
- ~~Give it a name that starts with `copilot_`- this pattern is protected for our use only~~
19+
- This is obsolete- new tools can use any name, I think matching `toolReferenceName` might be a good idea.
20+
- The existing `copilot_` tools will be renamed later.
1921
- Give it a reasonable `toolReferenceName` and a localized `userDescription`.
2022
- `toolReferenceName` is the name used in the tool picker, and to reference the tool with `#`, and to add the tool to a mode or toolset.
2123
- Consider whether the tool should be available on its own or part of a toolset. Add it to a toolset in `contributes.languageModelToolSets` if needed.

package.json

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@
165165
}
166166
},
167167
{
168-
"name": "execute_prompt",
169-
"toolReferenceName": "executePrompt",
170-
"displayName": "Execute Prompt",
171-
"when": "config.github.copilot.chat.executePrompt.enabled",
168+
"name": "runSubagent",
169+
"toolReferenceName": "runSubagent",
170+
"displayName": "%copilot.tools.runSubagent.name%",
172171
"canBeReferencedInPrompt": true,
173-
"modelDescription": "Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use this agent to perform the search for you.\n\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n - Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n - The agent's outputs should generally be trusted\n - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent",
172+
"userDescription": "%copilot.tools.runSubagent.description%",
173+
"modelDescription": "Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use this agent to perform the search for you.\n\n- Agents do not run async or in the background, you will wait for the agent's result.\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n - Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n - The agent's outputs should generally be trusted\n - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent",
174174
"tags": [],
175175
"inputSchema": {
176176
"type": "object",
@@ -3121,14 +3121,6 @@
31213121
"detailed"
31223122
]
31233123
},
3124-
"github.copilot.chat.executePrompt.enabled": {
3125-
"type": "boolean",
3126-
"default": true,
3127-
"markdownDescription": "%github.copilot.config.executePrompt.enabled%",
3128-
"tags": [
3129-
"experimental"
3130-
]
3131-
},
31323124
"github.copilot.chat.completionsFetcher": {
31333125
"type": [
31343126
"string",
@@ -4388,4 +4380,4 @@
43884380
"string_decoder": "npm:string_decoder@1.2.0",
43894381
"node-gyp": "npm:node-gyp@10.3.1"
43904382
}
4391-
}
4383+
}

package.nls.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,10 @@
300300
"github.copilot.config.useResponsesApi": "Use the Responses API instead of the Chat Completions API when supported. Enables reasoning and reasoning summaries.\n\n**Note**: This is an experimental feature that is not yet activated for all users.",
301301
"github.copilot.config.responsesApiReasoningEffort": "Sets the reasoning effort used for the Responses API. Requires `#github.copilot.chat.useResponsesApi#`.",
302302
"github.copilot.config.responsesApiReasoningSummary": "Sets the reasoning summary style used for the Responses API. Requires `#github.copilot.chat.useResponsesApi#`.",
303-
"github.copilot.config.executePrompt.enabled": "The executePrompt tool enables the agent to execute tasks in a separate, isolated context.",
304303
"github.copilot.config.completionsFetcher": "Sets the fetcher used for the inline completions.",
305304
"github.copilot.config.nesFetcher": "Sets the fetcher used for the next edit suggestions.",
306305
"github.copilot.command.refreshCopilotAgentSessions": "Refresh Copilot Agent Sessions",
307-
"github.copilot.command.openCopilotAgentSessionsInBrowser": "Open in browser"
306+
"github.copilot.command.openCopilotAgentSessionsInBrowser": "Open in browser",
307+
"copilot.tools.runSubagent.name": "Run Subagent",
308+
"copilot.tools.runSubagent.description": "Runs a task within an isolated subagent context. Enables efficient organization of tasks and context window management."
308309
}

src/extension/prompt/node/executePromptToolCalling.ts renamed to src/extension/prompt/node/subagentLoop.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,23 @@ import { IToolCallingLoopOptions, ToolCallingLoop, ToolCallingLoopFetchOptions }
1818
import { AgentPrompt } from '../../prompts/node/agent/agentPrompt';
1919
import { PromptRenderer } from '../../prompts/node/base/promptRenderer';
2020
import { ToolName } from '../../tools/common/toolNames';
21+
import { normalizeToolSchema } from '../../tools/common/toolSchemaNormalizer';
2122
import { ChatVariablesCollection } from '../common/chatVariablesCollection';
2223
import { IBuildPromptContext } from '../common/intents';
2324
import { IBuildPromptResult } from './intents';
24-
import { normalizeToolSchema } from '../../tools/common/toolSchemaNormalizer';
2525

26-
export interface IExecutePromptToolCallingLoopOptions extends IToolCallingLoopOptions {
26+
export interface ISubagentToolCallingLoopOptions extends IToolCallingLoopOptions {
2727
request: ChatRequest;
2828
location: ChatLocation;
2929
promptText: string;
3030
}
3131

32-
export class ExecutePromptToolCallingLoop extends ToolCallingLoop<IExecutePromptToolCallingLoopOptions> {
32+
export class SubagentToolCallingLoop extends ToolCallingLoop<ISubagentToolCallingLoopOptions> {
3333

34-
public static readonly ID = 'executePromptTool';
34+
public static readonly ID = 'subagent';
3535

3636
constructor(
37-
options: IExecutePromptToolCallingLoopOptions,
37+
options: ISubagentToolCallingLoopOptions,
3838
@IInstantiationService private readonly instantiationService: IInstantiationService,
3939
@ILogService logService: ILogService,
4040
@IRequestLogger requestLogger: IRequestLogger,
@@ -85,7 +85,7 @@ export class ExecutePromptToolCallingLoop extends ToolCallingLoop<IExecutePrompt
8585
}
8686

8787
protected async getAvailableTools(): Promise<LanguageModelToolInformation[]> {
88-
const excludedTools = new Set([ToolName.ExecutePrompt, ToolName.CoreManageTodoList]);
88+
const excludedTools = new Set([ToolName.RunSubagent, ToolName.CoreManageTodoList]);
8989
return (await getAgentTools(this.instantiationService, this.options.request))
9090
.filter(tool => !excludedTools.has(tool.name as ToolName))
9191
// TODO can't do virtual tools at this level
@@ -95,7 +95,7 @@ export class ExecutePromptToolCallingLoop extends ToolCallingLoop<IExecutePrompt
9595
protected async fetch({ messages, finishedCb, requestOptions }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
9696
const endpoint = await this.getEndpoint(this.options.request);
9797
return endpoint.makeChatRequest2({
98-
debugName: ExecutePromptToolCallingLoop.ID,
98+
debugName: SubagentToolCallingLoop.ID,
9999
messages,
100100
finishedCb,
101101
location: this.options.location,
@@ -114,7 +114,7 @@ export class ExecutePromptToolCallingLoop extends ToolCallingLoop<IExecutePrompt
114114
userInitiatedRequest: false,
115115
telemetryProperties: {
116116
messageId: randomUUID(),
117-
messageSource: ExecutePromptToolCallingLoop.ID
117+
messageSource: SubagentToolCallingLoop.ID
118118
},
119119
}, token);
120120
}

src/extension/tools/common/toolNames.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export enum ToolName {
6565
CoreRunTest = 'runTests',
6666
ToolReplay = 'tool_replay',
6767
EditFilesPlaceholder = 'edit_files',
68-
ExecutePrompt = 'execute_prompt',
68+
RunSubagent = 'runSubagent',
6969
CoreConfirmationTool = 'vscode_get_confirmation'
7070
}
7171

@@ -109,7 +109,6 @@ export enum ContributedToolName {
109109
RunVscodeCmd = 'copilot_runVscodeCommand',
110110
ToolReplay = 'copilot_toolReplay',
111111
EditFilesPlaceholder = 'copilot_editFiles',
112-
ExecutePrompt = 'execute_prompt',
113112
}
114113

115114
export const byokEditToolNamesToToolNames = {
@@ -171,6 +170,7 @@ export const toolCategories: Record<ToolName, ToolCategory> = {
171170
[ToolName.FindFiles]: ToolCategory.Core,
172171
[ToolName.CreateDirectory]: ToolCategory.Core,
173172
[ToolName.ReadProjectStructure]: ToolCategory.Core,
173+
[ToolName.RunSubagent]: ToolCategory.Core,
174174

175175
// already enabled only when tasks are enabled
176176
[ToolName.CoreRunTask]: ToolCategory.Core,
@@ -218,7 +218,6 @@ export const toolCategories: Record<ToolName, ToolCategory> = {
218218
// Other tools - categorize appropriately
219219
[ToolName.UpdateUserPreferences]: ToolCategory.VSCodeInteraction,
220220
[ToolName.ToolReplay]: ToolCategory.RedundantButSpecific,
221-
[ToolName.ExecutePrompt]: ToolCategory.RedundantButSpecific,
222221
[ToolName.CoreConfirmationTool]: ToolCategory.VSCodeInteraction,
223222
} as const;
224223

src/extension/tools/node/allTools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import './createDirectoryTool';
99
import './createFileTool';
1010
import './docTool';
1111
import './editNotebookTool';
12-
import './executePromptTool';
12+
import './runSubagentTool';
1313
import './findFilesTool';
1414
import './findTestsFilesTool';
1515
import './findTextInFilesTool';

src/extension/tools/node/executePromptTool.ts renamed to src/extension/tools/node/runSubagentTool.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,27 @@ import { IInstantiationService } from '../../../util/vs/platform/instantiation/c
99
import { ChatPrepareToolInvocationPart, ChatResponseNotebookEditPart, ChatResponseTextEditPart, ExtendedLanguageModelToolResult, LanguageModelTextPart } from '../../../vscodeTypes';
1010
import { Conversation, Turn } from '../../prompt/common/conversation';
1111
import { IBuildPromptContext } from '../../prompt/common/intents';
12-
import { ExecutePromptToolCallingLoop } from '../../prompt/node/executePromptToolCalling';
12+
import { SubagentToolCallingLoop } from '../../prompt/node/subagentLoop';
1313
import { ToolName } from '../common/toolNames';
1414
import { CopilotToolMode, ICopilotTool, ToolRegistry } from '../common/toolsRegistry';
15+
import { ChatFetchResponseType } from '../../../platform/chat/common/commonTypes';
1516

16-
export interface IExecutePromptParams {
17+
export interface IRunSubagentParams {
1718
prompt: string;
1819
description: string;
1920
}
2021

21-
class ExecutePromptTool implements ICopilotTool<IExecutePromptParams> {
22-
public static readonly toolName = ToolName.ExecutePrompt;
22+
class RunSubagentTool implements ICopilotTool<IRunSubagentParams> {
23+
public static readonly toolName = ToolName.RunSubagent;
2324
private _inputContext: IBuildPromptContext | undefined;
2425

2526
constructor(
2627
@IInstantiationService private readonly instantiationService: IInstantiationService,
2728
) { }
2829

29-
async invoke(options: vscode.LanguageModelToolInvocationOptions<IExecutePromptParams>, token: vscode.CancellationToken) {
30+
async invoke(options: vscode.LanguageModelToolInvocationOptions<IRunSubagentParams>, token: vscode.CancellationToken) {
3031

31-
const loop = this.instantiationService.createInstance(ExecutePromptToolCallingLoop, {
32+
const loop = this.instantiationService.createInstance(SubagentToolCallingLoop, {
3233
toolCallLimit: 25,
3334
conversation: new Conversation('', [new Turn('', { type: 'user', message: options.input.prompt })]),
3435
request: this._inputContext!.request!,
@@ -43,13 +44,18 @@ class ExecutePromptTool implements ICopilotTool<IExecutePromptParams> {
4344
);
4445

4546
const loopResult = await loop.run(stream, token);
46-
// Return the text of the last assistant response from the tool calling loop
47-
const lastRoundResponse = loopResult.toolCallRounds.at(-1)?.response ?? loopResult.round.response ?? '';
48-
const result = new ExtendedLanguageModelToolResult([new LanguageModelTextPart(lastRoundResponse)]);
47+
// Return the text of the last assistant response from the tool calling loop, or request error
48+
let subagentSummary = '';
49+
if (loopResult.response.type === ChatFetchResponseType.Success) {
50+
subagentSummary = loopResult.toolCallRounds.at(-1)?.response ?? loopResult.round.response ?? '';
51+
} else {
52+
subagentSummary = `The subagent request failed with this message:\n${loopResult.response.type}: ${loopResult.response.reason}`;
53+
}
54+
const result = new ExtendedLanguageModelToolResult([new LanguageModelTextPart(subagentSummary)]);
4955
return result;
5056
}
5157

52-
prepareInvocation(options: vscode.LanguageModelToolInvocationPrepareOptions<IExecutePromptParams>, token: vscode.CancellationToken): vscode.ProviderResult<vscode.PreparedToolInvocation> {
58+
prepareInvocation(options: vscode.LanguageModelToolInvocationPrepareOptions<IRunSubagentParams>, token: vscode.CancellationToken): vscode.ProviderResult<vscode.PreparedToolInvocation> {
5359
const { input } = options;
5460
try {
5561
return {
@@ -60,10 +66,10 @@ class ExecutePromptTool implements ICopilotTool<IExecutePromptParams> {
6066
}
6167
}
6268

63-
async resolveInput(input: IExecutePromptParams, promptContext: IBuildPromptContext, mode: CopilotToolMode): Promise<IExecutePromptParams> {
69+
async resolveInput(input: IRunSubagentParams, promptContext: IBuildPromptContext, mode: CopilotToolMode): Promise<IRunSubagentParams> {
6470
this._inputContext = promptContext;
6571
return input;
6672
}
6773
}
6874

69-
ToolRegistry.registerTool(ExecutePromptTool);
75+
ToolRegistry.registerTool(RunSubagentTool);

src/platform/configuration/common/configurationService.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,6 @@ export namespace ConfigKey {
811811
export const Gpt5CodexAlternatePrompt = defineExpSetting<'default' | 'codex'>('chat.gpt5CodexAlternatePrompt', 'codex');
812812
export const GrokCodeAlternatePrompt = defineExpSetting<string>('chat.grokCodeAlternatePrompt', 'default');
813813
export const ClaudeSonnet45AlternatePrompt = defineExpSetting<string>('chat.claudeSonnet45AlternatePrompt', 'default');
814-
export const ExecutePromptEnabled = defineSetting<boolean>('chat.executePrompt.enabled', true);
815814

816815
export const CompletionsFetcher = defineExpSetting<FetcherId | undefined>('chat.completionsFetcher', undefined);
817816
export const NextEditSuggestionsFetcher = defineExpSetting<FetcherId | undefined>('chat.nesFetcher', undefined);

0 commit comments

Comments
 (0)