mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-28 06:00:38 +00:00
fix(sandbox): forward bash command timeout to remote providers (#6782)
This commit is contained in:
parent
8b62537847
commit
12397d2142
@ -327,10 +327,10 @@ class SandboxConfig(BaseModel):
|
||||
"(1.9.3+, recommended 1.11.0) enforce it server-side through "
|
||||
"`hard_timeout`; the frozen legacy `all-in-one-sandbox:latest` image "
|
||||
"only gets the bounded host-side request. `bash_command_timeout` is "
|
||||
"used by providers that explicitly wire this setting (currently "
|
||||
"LocalSandbox, AioSandbox, and OpenSandbox). Other providers retain "
|
||||
"their provider-specific command defaults unless a caller supplies an "
|
||||
"explicit timeout."
|
||||
"forwarded to each provider's command API. LocalSandbox, AioSandbox, "
|
||||
"OpenSandbox, E2B, BoxLite, and Tenki apply it to bash commands; "
|
||||
"providers without per-command timeout support retain their own "
|
||||
"defaults."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ subshell. Keep parser filtering as a backstop; test ignored roots, metacharacter
|
||||
symlinks, and visible depth/size bounds.
|
||||
|
||||
- Every sandbox tool keeps a model-visible `description` field for a human-readable progress label, but the field is optional and defaults to an empty string. Tool execution must depend only on its operational arguments; the frontend supplies localized fallback labels when a provider omits `description`.
|
||||
- `bash` - Execute commands with path translation and error handling. For `LocalSandbox`, POSIX/Windows output uses bounded pipe-drain threads with `/dev/null` stdin; Windows decodes locale-code-page/UTF-8/CRLF/bare-CR output with universal-newline translation, while POSIX stays byte-decoded. POSIX background commands return without blocking on inherited pipes; unredirected output is drained without unbounded temp files. Commands that read stdin get immediate EOF. `bash_command_timeout` sets T (600s) for Local/AIO/OpenSandbox; others keep defaults unless explicit. Local: T is a wall-clock process-group deadline. Supported-semver AIO: server-side `hard_timeout`; frozen legacy `all-in-one-sandbox:latest`: command requests get a bounded host `T+5s` wait (`max_retries=0`), so a wedged command request cannot hold the sandbox lock for the SDK's full 600s budget; file/list RPCs are not bounded by it. Explicit AIO shell/bash session creation uses a separate 5s/no-retry host bound; an ambiguous create is never replayed and forces container recycle before warm reuse. Never replay ambiguous outcomes: transport timeout, terminated, no_change_timeout, unknown statuses. `hard_timeout` => terminated + Exit Code: 124, keep session; `no_change_timeout` => may still be running, fence session generation. The description scopes host-environment probes to LocalSandbox (`uname -s`, then `sw_vers` on Darwin; Linux files only when policy permits), gives conditional recovery for local path/`file://` rejections, and tells the model to background long-lived processes. See `LocalSandbox.execute_command`, its platform runners, and `bash_tool`'s docstring.
|
||||
- `bash` - Execute commands with path translation and error handling. For `LocalSandbox`, POSIX/Windows output uses bounded pipe-drain threads with `/dev/null` stdin; Windows decodes locale-code-page/UTF-8/CRLF/bare-CR output with universal-newline translation, while POSIX stays byte-decoded. POSIX background commands return without blocking on inherited pipes; unredirected output is drained without unbounded temp files. Commands that read stdin get immediate EOF. `bash_command_timeout` is forwarded to providers with a per-command timeout API (Local/AIO/OpenSandbox/E2B/BoxLite/Tenki); providers without one keep their own defaults. Local: T is a wall-clock process-group deadline. Supported-semver AIO: server-side `hard_timeout`; frozen legacy `all-in-one-sandbox:latest`: command requests get a bounded host `T+5s` wait (`max_retries=0`), so a wedged command request cannot hold the sandbox lock for the SDK's full 600s budget; file/list RPCs are not bounded by it. Explicit AIO shell/bash session creation uses a separate 5s/no-retry host bound; an ambiguous create is never replayed and forces container recycle before warm reuse. Never replay ambiguous outcomes: transport timeout, terminated, no_change_timeout, unknown statuses. `hard_timeout` => terminated + Exit Code: 124, keep session; `no_change_timeout` => may still be running, fence session generation. The description scopes host-environment probes to LocalSandbox (`uname -s`, then `sw_vers` on Darwin; Linux files only when policy permits), gives conditional recovery for local path/`file://` rejections, and tells the model to background long-lived processes. See `LocalSandbox.execute_command`, its platform runners, and `bash_tool`'s docstring.
|
||||
- `ls` - Directory listing (tree format, max 2 levels). Remote commands precheck root existence and emit `__DF_FIND_STATUS__:missing`; `find` status 1 is always an incomplete-traversal `OSError`. `AioSandbox.list_dir` parses only `completed`/`None` on #5634's selected generation: `hard_timeout` raises `TimeoutError` and keeps that generation reusable; an ambiguous timeout or status raises `OSError`, replays nothing, and fences that generation. Missing-session 404s drop the stale id without replay. Persistent/scoped shells fence all `httpx.TransportError`s before cleanup.
|
||||
- `glob` - Find files or directories below a root directory with bounded results
|
||||
- `grep` - Search one text file or recursively search a directory, with optional glob filtering and bounded line-level results
|
||||
|
||||
@ -2472,8 +2472,10 @@ def bash_tool(runtime: Runtime, command: str, description: str = "") -> str:
|
||||
|
||||
sandbox_cfg = get_app_config().sandbox
|
||||
max_chars = sandbox_cfg.bash_output_max_chars if sandbox_cfg else 20000
|
||||
command_timeout = sandbox_cfg.bash_command_timeout if sandbox_cfg else None
|
||||
except Exception:
|
||||
max_chars = 20000
|
||||
command_timeout = None
|
||||
return _truncate_bash_output(
|
||||
mask_secret_values(
|
||||
_execute_bash_command(
|
||||
@ -2481,6 +2483,7 @@ def bash_tool(runtime: Runtime, command: str, description: str = "") -> str:
|
||||
command,
|
||||
runtime=runtime,
|
||||
env=injected_env,
|
||||
timeout=command_timeout,
|
||||
),
|
||||
injected_env,
|
||||
),
|
||||
|
||||
@ -1553,7 +1553,7 @@ class TestBashToolInjectsActiveSecrets:
|
||||
assert captured["command"] == "echo hi"
|
||||
assert captured["env"] == {"ERP_TOKEN": "tok-789", USER_ID_ENV: "u-win"}
|
||||
|
||||
def test_remote_bash_does_not_forward_shared_timeout(self):
|
||||
def test_remote_bash_forwards_shared_timeout(self):
|
||||
from deerflow.sandbox import tools as tools_mod
|
||||
|
||||
captured = {}
|
||||
@ -1600,7 +1600,7 @@ class TestBashToolInjectsActiveSecrets:
|
||||
)
|
||||
|
||||
assert out == "done"
|
||||
assert captured["timeout"] is None
|
||||
assert captured["timeout"] == 42
|
||||
|
||||
|
||||
_SECRET = "sk-erp-9f3c-DO-NOT-LEAK"
|
||||
|
||||
@ -1728,9 +1728,9 @@ sandbox:
|
||||
# semver line (1.9.3+, recommended 1.11.0) enforce it server-side through
|
||||
# `hard_timeout`; the frozen legacy `all-in-one-sandbox:latest` image only
|
||||
# gets the bounded host-side request. `bash_command_timeout` is used by
|
||||
# providers that explicitly wire this setting (currently LocalSandbox,
|
||||
# AioSandbox, and OpenSandbox). Other providers retain their provider-specific
|
||||
# command defaults unless a caller supplies an explicit timeout. For providers
|
||||
# providers that expose a per-command timeout (LocalSandbox, AioSandbox,
|
||||
# OpenSandbox, E2B, BoxLite, and Tenki). Providers without per-command timeout
|
||||
# support retain their provider-specific command defaults. For providers
|
||||
# that enforce this deadline server- or process-side, blocking foreground
|
||||
# commands are terminated at the configured deadline. Long-lived processes
|
||||
# should be started in the background with output redirected; unredirected
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user