From 0b2fcb84f40c20da3888380a10cca244dce2b839 Mon Sep 17 00:00:00 2001 From: Aishanee Shah Date: Tue, 17 Feb 2026 05:51:32 +0000 Subject: [PATCH] refactor: optimize shell tool description and instructions --- .../tools/__snapshots__/shell.test.ts.snap | 68 ++----------------- .../coreToolsModelSnapshots.test.ts.snap | 6 +- .../core/src/tools/definitions/coreTools.ts | 24 ++++--- packages/core/src/tools/shell.ts | 12 +++- 4 files changed, 34 insertions(+), 76 deletions(-) diff --git a/packages/core/src/tools/__snapshots__/shell.test.ts.snap b/packages/core/src/tools/__snapshots__/shell.test.ts.snap index 471ce45f6e..bae1703e07 100644 --- a/packages/core/src/tools/__snapshots__/shell.test.ts.snap +++ b/packages/core/src/tools/__snapshots__/shell.test.ts.snap @@ -1,69 +1,9 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`ShellTool > getDescription > should return the non-windows description when not on windows 1`] = ` -"This tool executes a given shell command as \`bash -c \`. Command can start background processes using \`&\`. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. +exports[`ShellTool > getDescription > should return the non-windows description when not on windows 1`] = `"This tool executes a given shell command as \`bash -c \`."`; - Efficiency Guidelines: - - Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information. - - Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`). +exports[`ShellTool > getDescription > should return the windows description when on windows 1`] = `"This tool executes a given shell command as \`powershell.exe -NoProfile -Command \`."`; - The following information is returned: +exports[`ShellTool > getSchema > should return the base schema when no modelId is provided 1`] = `"This tool executes a given shell command as \`bash -c \`."`; - Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes. - Exit Code: Only included if non-zero (command failed). - Error: Only included if a process-level error occurred (e.g., spawn failure). - Signal: Only included if process was terminated by a signal. - Background PIDs: Only included if background processes were started. - Process Group PGID: Only included if available." -`; - -exports[`ShellTool > getDescription > should return the windows description when on windows 1`] = ` -"This tool executes a given shell command as \`powershell.exe -NoProfile -Command \`. Command can start background processes using PowerShell constructs such as \`Start-Process -NoNewWindow\` or \`Start-Job\`. - - Efficiency Guidelines: - - Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information. - - Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`). - - The following information is returned: - - Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes. - Exit Code: Only included if non-zero (command failed). - Error: Only included if a process-level error occurred (e.g., spawn failure). - Signal: Only included if process was terminated by a signal. - Background PIDs: Only included if background processes were started. - Process Group PGID: Only included if available." -`; - -exports[`ShellTool > getSchema > should return the base schema when no modelId is provided 1`] = ` -"This tool executes a given shell command as \`bash -c \`. Command can start background processes using \`&\`. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. - - Efficiency Guidelines: - - Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information. - - Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`). - - The following information is returned: - - Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes. - Exit Code: Only included if non-zero (command failed). - Error: Only included if a process-level error occurred (e.g., spawn failure). - Signal: Only included if process was terminated by a signal. - Background PIDs: Only included if background processes were started. - Process Group PGID: Only included if available." -`; - -exports[`ShellTool > getSchema > should return the schema from the resolver when modelId is provided 1`] = ` -"This tool executes a given shell command as \`bash -c \`. Command can start background processes using \`&\`. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. - - Efficiency Guidelines: - - Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information. - - Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`). - - The following information is returned: - - Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes. - Exit Code: Only included if non-zero (command failed). - Error: Only included if a process-level error occurred (e.g., spawn failure). - Signal: Only included if process was terminated by a signal. - Background PIDs: Only included if background processes were started. - Process Group PGID: Only included if available." -`; +exports[`ShellTool > getSchema > should return the schema from the resolver when modelId is provided 1`] = `"This tool executes a given shell command as \`bash -c \`."`; diff --git a/packages/core/src/tools/definitions/__snapshots__/coreToolsModelSnapshots.test.ts.snap b/packages/core/src/tools/definitions/__snapshots__/coreToolsModelSnapshots.test.ts.snap index 5d26aa3e0f..41f780dd39 100644 --- a/packages/core/src/tools/definitions/__snapshots__/coreToolsModelSnapshots.test.ts.snap +++ b/packages/core/src/tools/definitions/__snapshots__/coreToolsModelSnapshots.test.ts.snap @@ -568,7 +568,8 @@ A good instruction should concisely answer: exports[`coreTools snapshots for specific models > Model: gemini-2.5-pro > snapshot for tool: run_shell_command 1`] = ` { - "description": "This tool executes a given shell command as \`bash -c \`. To run a command in the background, set the \`is_background\` parameter to true. Do NOT use \`&\` to background commands. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. + "description": "This tool executes a given shell command as \`bash -c \`.", + "instructions": "To run a command in the background, set the \`is_background\` parameter to true. Do NOT use \`&\` to background commands. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. Efficiency Guidelines: - Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information. @@ -1357,7 +1358,8 @@ A good instruction should concisely answer: exports[`coreTools snapshots for specific models > Model: gemini-3-pro-preview > snapshot for tool: run_shell_command 1`] = ` { - "description": "This tool executes a given shell command as \`bash -c \`. To run a command in the background, set the \`is_background\` parameter to true. Do NOT use \`&\` to background commands. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. + "description": "This tool executes a given shell command as \`bash -c \`.", + "instructions": "To run a command in the background, set the \`is_background\` parameter to true. Do NOT use \`&\` to background commands. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`. Efficiency Guidelines: - Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information. diff --git a/packages/core/src/tools/definitions/coreTools.ts b/packages/core/src/tools/definitions/coreTools.ts index 17d795c683..6d382bf0b9 100644 --- a/packages/core/src/tools/definitions/coreTools.ts +++ b/packages/core/src/tools/definitions/coreTools.ts @@ -420,12 +420,12 @@ export const LS_DEFINITION: ToolDefinition = { // ============================================================================ /** - * Generates the platform-specific description for the shell tool. + * Generates the platform-specific description and instructions for the shell tool. */ export function getShellToolDescription( enableInteractiveShell: boolean, enableEfficiency: boolean, -): string { +): { description: string; instructions: string } { const efficiencyGuidelines = enableEfficiency ? ` @@ -449,12 +449,18 @@ export function getShellToolDescription( const backgroundInstructions = enableInteractiveShell ? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use PowerShell background constructs.' : 'Command can start background processes using PowerShell constructs such as `Start-Process -NoNewWindow` or `Start-Job`.'; - return `This tool executes a given shell command as \`powershell.exe -NoProfile -Command \`. ${backgroundInstructions}${efficiencyGuidelines}${returnedInfo}`; + return { + description: `This tool executes a given shell command as \`powershell.exe -NoProfile -Command \`.`, + instructions: `${backgroundInstructions}${efficiencyGuidelines}${returnedInfo}`, + }; } else { const backgroundInstructions = enableInteractiveShell ? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use `&` to background commands.' : 'Command can start background processes using `&`.'; - return `This tool executes a given shell command as \`bash -c \`. ${backgroundInstructions} Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.${efficiencyGuidelines}${returnedInfo}`; + return { + description: `This tool executes a given shell command as \`bash -c \`.`, + instructions: `${backgroundInstructions} Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.${efficiencyGuidelines}${returnedInfo}`, + }; } } @@ -475,13 +481,15 @@ export function getShellDefinition( enableInteractiveShell: boolean, enableEfficiency: boolean, ): ToolDefinition { + const { description, instructions } = getShellToolDescription( + enableInteractiveShell, + enableEfficiency, + ); return { base: { name: SHELL_TOOL_NAME, - description: getShellToolDescription( - enableInteractiveShell, - enableEfficiency, - ), + description, + instructions, parametersJsonSchema: { type: 'object', properties: { diff --git a/packages/core/src/tools/shell.ts b/packages/core/src/tools/shell.ts index ff20b8a7b2..4b0bcbb2b9 100644 --- a/packages/core/src/tools/shell.ts +++ b/packages/core/src/tools/shell.ts @@ -466,19 +466,27 @@ export class ShellTool extends BaseDeclarativeTool< void initializeShellParsers().catch(() => { // Errors are surfaced when parsing commands. }); + const modelId = + typeof config.getActiveModel === 'function' + ? config.getActiveModel() + : undefined; const definition = getShellDefinition( config.getEnableInteractiveShell(), config.getEnableShellOutputEfficiency(), ); + const resolved = resolveToolDeclaration(definition, modelId); super( ShellTool.Name, 'Shell', - definition.base.description!, + resolved.description!, Kind.Execute, - definition.base.parametersJsonSchema, + resolved.parametersJsonSchema, messageBus, false, // output is not markdown true, // output can be updated + undefined, // extensionName + undefined, // extensionId + resolved.instructions, ); }