diff --git a/docs/pr-infographics/kilocode-background-wait-guidance.svg b/docs/pr-infographics/kilocode-background-wait-guidance.svg new file mode 100644 index 0000000000..57edccd0b9 --- /dev/null +++ b/docs/pr-infographics/kilocode-background-wait-guidance.svg @@ -0,0 +1,76 @@ + + Terminal Waits, Clearly Routed + Holographic collectible-card infographic about routing fixed waits to foreground terminal calls and independent processes to background mode. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Terminal Waits + clearly routed + + + Foreground + fixed waits + + + + sleep 30 timeout=60 + + + Background + independent processes + + + server + + background=true + + + No sleep, timers, cooldowns, or polling loops in background mode + + + Schema lock + tool wording + + + Validation + 11 tests + E2E + + + Port + Kilo #13224 + + Nous Research + diff --git a/tests/tools/test_terminal_tool.py b/tests/tools/test_terminal_tool.py index 40c62fcb7d..e409167526 100644 --- a/tests/tools/test_terminal_tool.py +++ b/tests/tools/test_terminal_tool.py @@ -31,6 +31,14 @@ def test_terminal_schema_advertises_persistent_env_state(): assert "once per session" in description +def test_terminal_schema_keeps_fixed_waits_out_of_background_mode(): + description = terminal_tool.TERMINAL_TOOL_DESCRIPTION + + assert "only for commands that must keep running independently" in description + assert "Do not start sleep, timers, cooldowns, delays, or polling loops" in description + assert "run the wait as a normal foreground command" in description + + def test_printf_literal_sudo_does_not_trigger_rewrite(monkeypatch): monkeypatch.delenv("SUDO_PASSWORD", raising=False) monkeypatch.delenv("HERMES_INTERACTIVE", raising=False) diff --git a/tools/terminal_tool.py b/tools/terminal_tool.py index 46ceeb586b..1fc0003939 100644 --- a/tools/terminal_tool.py +++ b/tools/terminal_tool.py @@ -160,8 +160,8 @@ TERMINAL_TOOL_DESCRIPTION = """Execute shell commands. The host OS, shell, and t Do NOT use cat/head/tail (use read_file), grep/rg/find/ls (use search_files), sed/awk (use patch), or echo/heredoc file creation (use write_file). Reserve terminal for: builds, installs, git, processes, scripts, network, package managers — anything that needs a shell. Output is auto-truncated with the full text saved to a file — never pipe through tail/head to shorten it. Environment state persists: activate a virtualenv or export variables once per session, not before every command. -Foreground (default): returns INSTANTLY when the command finishes, even with a high timeout — set timeout generously for long builds. -Background: set background=true (returns a session_id); add notify=true for bounded tasks, leave silent only for servers/daemons that never exit. After starting a server, verify readiness with a health check in a separate call (no blind sleep loops); manage with process(action="poll"/"wait"). +Foreground (default): returns INSTANTLY when the command finishes, even with a high timeout — set timeout generously for long builds and fixed waits. +Background: set background=true (returns a session_id) only for commands that must keep running independently after this tool call returns; add notify=true for bounded tasks, leave silent only for servers/daemons that never exit. Do not start sleep, timers, cooldowns, delays, or polling loops with background=true — to wait a fixed time, run the wait as a normal foreground command with a high enough timeout. After starting a server, verify readiness with a health check in a separate call (no blind sleep loops); manage with process(action="poll"/"wait"). Working directory: use 'workdir' for per-command cwd; when a command changes the session cwd (cd, pushd), trust the result's "cwd" field instead of prefixing every command with 'cd'. PTY: pty=true + background=true for interactive CLIs (they hang without a terminal); drive them with process(action="write"/"submit"). Local backend only. """