diff --git a/packages/core/src/prompts/snippets.ts b/packages/core/src/prompts/snippets.ts index b049ddf58e..0fbb6b8872 100644 --- a/packages/core/src/prompts/snippets.ts +++ b/packages/core/src/prompts/snippets.ts @@ -806,8 +806,7 @@ function toolUsageInteractive( function toolUsageAiShell(options: OperationalGuidelinesOptions): string { if (options.interactiveShellMode !== 'ai') return ''; return ` -- **AI-Driven Interactive Shell:** Commands using \`wait_for_output_seconds\` auto-promote to background when they stall. Once promoted, use ${formatToolName(READ_SHELL_TOOL_NAME)} to see the terminal screen, then ${formatToolName(WRITE_TO_SHELL_TOOL_NAME)} to send text input and/or special keys (arrows, Enter, Ctrl-C, etc.). - - Set \`wait_for_output_seconds\` **low (2-5)** for commands that prompt for input (npx, installers, REPLs). Set **high (60+)** for long builds. Omit for instant commands. +- **AI-Driven Interactive Shell:** Commands auto-promote to background if they stall for 3 seconds. Once promoted, use ${formatToolName(READ_SHELL_TOOL_NAME)} to see the terminal screen, then ${formatToolName(WRITE_TO_SHELL_TOOL_NAME)} to send text input and/or special keys (arrows, Enter, Ctrl-C, etc.). - **Always read the screen before writing input.** The screen state tells you what the process is waiting for. - When waiting for a command to finish (e.g. npm install), use ${formatToolName(READ_SHELL_TOOL_NAME)} with \`wait_seconds\` to delay before reading. Do NOT poll in a tight loop. - **Clean up when done:** when your task is complete, kill background processes with ${formatToolName(WRITE_TO_SHELL_TOOL_NAME)} sending Ctrl-C, or note the PID for the user to clean up. diff --git a/packages/core/src/tools/definitions/base-declarations.ts b/packages/core/src/tools/definitions/base-declarations.ts index e1575966af..47e57ec8ab 100644 --- a/packages/core/src/tools/definitions/base-declarations.ts +++ b/packages/core/src/tools/definitions/base-declarations.ts @@ -56,7 +56,6 @@ export const READ_FILE_PARAM_END_LINE = 'end_line'; export const SHELL_TOOL_NAME = 'run_shell_command'; export const SHELL_PARAM_COMMAND = 'command'; export const SHELL_PARAM_IS_BACKGROUND = 'is_background'; -export const SHELL_PARAM_WAIT_SECONDS = 'wait_for_output_seconds'; // -- write_to_shell -- export const WRITE_TO_SHELL_TOOL_NAME = 'write_to_shell'; diff --git a/packages/core/src/tools/definitions/coreTools.ts b/packages/core/src/tools/definitions/coreTools.ts index a70ed1a33c..18ed26ea58 100644 --- a/packages/core/src/tools/definitions/coreTools.ts +++ b/packages/core/src/tools/definitions/coreTools.ts @@ -75,7 +75,6 @@ export { LS_PARAM_IGNORE, SHELL_PARAM_COMMAND, SHELL_PARAM_IS_BACKGROUND, - SHELL_PARAM_WAIT_SECONDS, WRITE_TO_SHELL_PARAM_PID, WRITE_TO_SHELL_PARAM_INPUT, WRITE_TO_SHELL_PARAM_SPECIAL_KEYS, diff --git a/packages/core/src/tools/definitions/dynamic-declaration-helpers.ts b/packages/core/src/tools/definitions/dynamic-declaration-helpers.ts index 6f001c7459..cade647893 100644 --- a/packages/core/src/tools/definitions/dynamic-declaration-helpers.ts +++ b/packages/core/src/tools/definitions/dynamic-declaration-helpers.ts @@ -22,7 +22,6 @@ import { PARAM_DIR_PATH, SHELL_PARAM_IS_BACKGROUND, EXIT_PLAN_PARAM_PLAN_FILENAME, - SHELL_PARAM_WAIT_SECONDS, SKILL_PARAM_NAME, PARAM_ADDITIONAL_PERMISSIONS, UPDATE_TOPIC_TOOL_NAME, @@ -60,7 +59,7 @@ export function getShellToolDescription( Process Group PGID: Only included if available.`; if (isAiMode) { - const autoPromoteInstructions = `Commands that do not complete within \`${SHELL_PARAM_WAIT_SECONDS}\` seconds are automatically promoted to background. Once promoted, use \`write_to_shell\` and \`read_shell\` to interact with the process. Do NOT use \`&\` to background commands.`; + const autoPromoteInstructions = `Commands that do not complete within 3 seconds are automatically promoted to background. Once promoted, use \`write_to_shell\` and \`read_shell\` to interact with the process. Do NOT use \`&\` to background commands.`; return `This tool executes a given shell command as \`bash -c \`. ${autoPromoteInstructions} 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}`; } @@ -98,15 +97,9 @@ export function getShellDeclaration( ): FunctionDeclaration { const isAiMode = interactiveShellMode === 'ai'; - // In AI mode, use wait_for_output_seconds instead of is_background + // In AI mode, auto-promotion is enabled by default, no background param needed const backgroundParam = isAiMode - ? { - [SHELL_PARAM_WAIT_SECONDS]: { - type: 'number' as const, - description: - 'Max seconds to wait for command to complete before auto-promoting to background (default: 5). Set low (2-5) for commands likely to prompt for input (npx, installers, REPLs). Set high (60-300) for long builds or installs. Once promoted, use write_to_shell/read_shell to interact.', - }, - } + ? {} : { [SHELL_PARAM_IS_BACKGROUND]: { type: 'boolean' as const, diff --git a/packages/core/src/tools/shell.ts b/packages/core/src/tools/shell.ts index 053cc4b00d..66e61841f6 100644 --- a/packages/core/src/tools/shell.ts +++ b/packages/core/src/tools/shell.ts @@ -72,7 +72,6 @@ export interface ShellToolParams { is_background?: boolean; delay_ms?: number; [PARAM_ADDITIONAL_PERMISSIONS]?: SandboxPermissions; - wait_for_output_seconds?: number; } export class ShellToolInvocation extends BaseToolInvocation< @@ -228,8 +227,8 @@ export class ShellToolInvocation extends BaseToolInvocation< override getExplanation(): string { let explanation = this.getContextualDetails().trim(); const isAiMode = this.context.config.getInteractiveShellMode() === 'ai'; - if (this.params.wait_for_output_seconds !== undefined || isAiMode) { - explanation += ` [auto-background after ${this.params.wait_for_output_seconds ?? 5}s]`; + if (isAiMode) { + explanation += ` [auto-background after 3s]`; } return explanation; } @@ -507,9 +506,8 @@ export class ShellToolInvocation extends BaseToolInvocation< let currentPid: number | undefined; const isAiMode = this.context.config.getInteractiveShellMode() === 'ai'; - const shouldAutoPromote = - this.params.wait_for_output_seconds !== undefined || isAiMode; - const waitMs = (this.params.wait_for_output_seconds ?? 5) * 1000; + const shouldAutoPromote = isAiMode; + const waitMs = isAiMode ? 3000 : 0; const resetAutoPromoteTimer = () => { if (shouldAutoPromote && currentPid) { @@ -650,7 +648,7 @@ export class ShellToolInvocation extends BaseToolInvocation< } } - // In AI mode with wait_for_output_seconds, set up auto-promotion timer. + // In AI mode, set up auto-promotion timer. // When the timer fires, promote to background instead of cancelling. currentPid = pid; resetAutoPromoteTimer(); diff --git a/packages/core/src/tools/write-to-shell.ts b/packages/core/src/tools/write-to-shell.ts index 652cb31bf5..2ac6862cab 100644 --- a/packages/core/src/tools/write-to-shell.ts +++ b/packages/core/src/tools/write-to-shell.ts @@ -167,7 +167,7 @@ export class WriteToShellTool extends BaseDeclarativeTool< super( WriteToShellTool.Name, 'WriteToShell', - 'Sends input to a running background shell process. Use this to interact with TUI applications, REPLs, and interactive commands. After writing, the current screen state is returned. Works with processes that were auto-promoted to background via wait_for_output_seconds or started with is_background=true.', + 'Sends input to a running background shell process. Use this to interact with TUI applications, REPLs, and interactive commands. After writing, the current screen state is returned. Works with processes that were auto-promoted to background or started with is_background=true.', Kind.Execute, { type: 'object',