Skip to content

Commit a307dcf

Browse files
authored
add switch agent tool (#3144)
1 parent 3bad3bf commit a307dcf

File tree

5 files changed

+84
-2
lines changed

5 files changed

+84
-2
lines changed

package.json

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,6 @@
11481148
"userDescription": "%copilot.tools.askQuestions.description%",
11491149
"modelDescription": "Ask the user questions to clarify intent, validate assumptions, or choose between implementation approaches. Prefer proposing a sensible default so users can confirm quickly.\n\nOnly use this tool when the user's answer provides information you cannot determine or reasonably assume yourself. This tool is for gathering information, not for reporting status or problems. If a question has an obvious best answer, take that action instead of asking.\n\nWhen to use:\n- Clarify ambiguous requirements before proceeding\n- Get user preferences on implementation choices\n- Confirm decisions that meaningfully affect outcome\n\nWhen NOT to use:\n- The answer is determinable from code or context\n- Asking for permission to continue or abort\n- Confirming something you can reasonably decide yourself\n- Reporting a problem (instead, attempt to resolve it)\n\nQuestion guidelines:\n- Batch related questions into a single call (max 4 questions, 2-6 options each; omit options for free text input)\n- Provide brief context explaining what is being decided and why\n- Mark one option as `recommended` with a short justification\n- Keep options mutually exclusive for single-select; use `multiSelect: true` only when choices are additive and phrase the question accordingly\n\nAfter receiving answers:\n- Incorporate decisions and continue without re-asking unless requirements change\n\nAn \"Other\" option is automatically shown to users—do not add your own.",
11501150
"icon": "$(question)",
1151-
"canBeReferencedInPrompt": true,
11521151
"when": "config.github.copilot.chat.askQuestions.enabled",
11531152
"inputSchema": {
11541153
"type": "object",
@@ -1214,6 +1213,29 @@
12141213
]
12151214
}
12161215
},
1216+
{
1217+
"name": "copilot_switchAgent",
1218+
"toolReferenceName": "switchAgent",
1219+
"displayName": "%copilot.tools.switchAgent.name%",
1220+
"userDescription": "%copilot.tools.switchAgent.description%",
1221+
"modelDescription": "Switch to a different agent mode. Use this tool when you determine that the current task would be better handled by a different agent mode.\n\nCurrently supported agents:\n- 'Plan': Switch to Plan mode when the task requires careful planning before implementation. Use Plan mode when:\n - The task is complex and requires multiple steps\n - You need to explore the codebase and design an implementation approach\n - The user would benefit from reviewing and approving a plan before you make changes\n - The task involves architectural decisions or significant code modifications\n\nAfter calling this tool, the conversation will continue in the new agent mode.",
1222+
"icon": "$(arrow-swap)",
1223+
"inputSchema": {
1224+
"type": "object",
1225+
"properties": {
1226+
"agentName": {
1227+
"type": "string",
1228+
"description": "The name of the agent to switch to. Currently only 'Plan' is supported.",
1229+
"enum": [
1230+
"Plan"
1231+
]
1232+
}
1233+
},
1234+
"required": [
1235+
"agentName"
1236+
]
1237+
}
1238+
},
12171239
{
12181240
"name": "copilot_editFiles",
12191241
"modelDescription": "This is a placeholder tool, do not use",
@@ -1282,6 +1304,8 @@
12821304
"newWorkspace",
12831305
"openSimpleBrowser",
12841306
"runCommand",
1307+
"askQuestions",
1308+
"switchAgent",
12851309
"vscodeAPI"
12861310
]
12871311
},

package.nls.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@
292292
"copilot.tools.memory.description": "Manage persistent memory across conversations. Create, view, update, and delete memory files that remember important information between chat sessions. Only available with BYOK Anthropic Claude models.",
293293
"copilot.tools.askQuestions.name": "Ask Questions",
294294
"copilot.tools.askQuestions.description": "Ask questions to clarify requirements before proceeding with a task.",
295+
"copilot.tools.switchAgent.name": "Switch Agent",
296+
"copilot.tools.switchAgent.description": "Switch to a different agent mode. Currently only the Plan agent is supported.",
295297
"copilot.tools.findTestFiles.name": "Find Test Files",
296298
"copilot.tools.getDocInfo.name": "Doc Info",
297299
"copilot.tools.createDirectory.name": "Create Directory",

src/extension/tools/common/toolNames.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export enum ToolName {
6969
CoreConfirmationTool = 'vscode_get_confirmation',
7070
CoreTerminalConfirmationTool = 'vscode_get_terminal_confirmation',
7171
SearchSubagent = 'search_subagent',
72-
AskQuestions = 'ask_questions'
72+
AskQuestions = 'ask_questions',
73+
SwitchAgent = 'switch_agent'
7374
}
7475

7576
export enum ContributedToolName {
@@ -114,6 +115,7 @@ export enum ContributedToolName {
114115
ToolReplay = 'copilot_toolReplay',
115116
EditFilesPlaceholder = 'copilot_editFiles',
116117
AskQuestions = 'copilot_askQuestions',
118+
SwitchAgent = 'copilot_switchAgent',
117119
}
118120

119121
export const byokEditToolNamesToToolNames = {
@@ -227,6 +229,7 @@ export const toolCategories: Record<ToolName, ToolCategory> = {
227229
[ToolName.CoreConfirmationTool]: ToolCategory.VSCodeInteraction,
228230
[ToolName.CoreTerminalConfirmationTool]: ToolCategory.VSCodeInteraction,
229231
[ToolName.AskQuestions]: ToolCategory.VSCodeInteraction,
232+
[ToolName.SwitchAgent]: ToolCategory.VSCodeInteraction,
230233
} as const;
231234

232235

src/extension/tools/vscode-node/allTools.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77

88
import './askQuestionsTool';
99
import './fetchWebPageTool';
10+
import './switchAgentTool';
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*---------------------------------------------------------------------------------------------
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 * as vscode from 'vscode';
7+
import { CancellationToken } from '../../../util/vs/base/common/cancellation';
8+
import { LanguageModelTextPart, LanguageModelToolResult, MarkdownString } from '../../../vscodeTypes';
9+
import { ToolName } from '../common/toolNames';
10+
import { ICopilotTool, ToolRegistry } from '../common/toolsRegistry';
11+
12+
interface ISwitchAgentParams {
13+
agentName: string;
14+
}
15+
16+
export class SwitchAgentTool implements ICopilotTool<ISwitchAgentParams> {
17+
public static readonly toolName = ToolName.SwitchAgent;
18+
19+
async invoke(options: vscode.LanguageModelToolInvocationOptions<ISwitchAgentParams>, token: CancellationToken): Promise<vscode.LanguageModelToolResult> {
20+
const { agentName } = options.input;
21+
22+
// Only 'Plan' is supported
23+
if (agentName !== 'Plan') {
24+
throw new Error(vscode.l10n.t('Only "Plan" agent is supported'));
25+
}
26+
27+
// Execute command to switch agent
28+
await vscode.commands.executeCommand('workbench.action.chat.toggleAgentMode', {
29+
modeId: agentName,
30+
sessionResource: options.chatSessionResource ? vscode.Uri.parse(options.chatSessionResource) : undefined
31+
});
32+
33+
return new LanguageModelToolResult([
34+
new LanguageModelTextPart(JSON.stringify({ success: true, agentName }))
35+
]);
36+
}
37+
38+
prepareInvocation(options: vscode.LanguageModelToolInvocationPrepareOptions<ISwitchAgentParams>, token: vscode.CancellationToken): vscode.ProviderResult<vscode.PreparedToolInvocation> {
39+
const { agentName } = options.input;
40+
41+
if (agentName !== 'Plan') {
42+
throw new Error(vscode.l10n.t('Only "Plan" agent is supported. Received: "{0}"', agentName));
43+
}
44+
45+
return {
46+
invocationMessage: new MarkdownString(vscode.l10n.t('Switching to {0} agent', agentName)),
47+
pastTenseMessage: new MarkdownString(vscode.l10n.t('Switched to {0} agent', agentName))
48+
};
49+
}
50+
}
51+
52+
ToolRegistry.registerTool(SwitchAgentTool);

0 commit comments

Comments
 (0)