* fix(sandbox): report truncated remote glob and grep results
BoxLite, Tenki, E2B, and OpenSandbox run find/grep in the sandbox, cap
the raw output with `| head`, and then filter those lines in Python:
ignored directories such as node_modules are dropped and grep's glob
scope is applied. They reported truncated only when max_results matches
survived the filter. When the capped lines were mostly filtered out, a
search with real matches past the cap came back short or empty with
truncated=False, and glob_tool/grep_tool rendered it as "No files
matched" / "No matches found". With the default max_results=200 and
1,200 files under node_modules, glob("**/*.py") reported no matches for
a workspace that has src/app.py.
remote_search_command now lets one line past its limit through, and
parse_remote_search_output(..., limit=) returns RemoteSearchOutput(text,
truncated): the first `limit` lines and whether the extra line arrived.
Exactly `limit` lines stays a complete result. Each provider passes the
cap it already computed to both calls and returns that truncated from
glob and grep when fewer than max_results results survive filtering.
The glob and grep tools now describe an empty truncated result as
incomplete instead of reporting no matches, which also covers AIO grep's
forwarded truncated flag. Sandbox.glob/grep document truncated as "the
matches may be incomplete".
* docs(changelog): reference #5427 in the remote search truncation entry
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
OpenSandbox backend
Runs DeerFlow sandboxes on OpenSandbox,
using the synchronous Python SDK behind DeerFlow's Sandbox and
SandboxProvider contracts.
Installation and configuration
Install the optional SDK, then select the provider:
pip install "deerflow-harness[opensandbox]"
sandbox:
use: deerflow.community.opensandbox:OpenSandboxProvider
image: python:3.11
# api_key: $OPEN_SANDBOX_API_KEY
# domain: localhost:8080
# protocol: http
# request_timeout: 30
# ready_timeout: 30
# use_server_proxy: false
# sandbox_timeout: 14400 # remote lifetime; 0 means explicit cleanup only
# bash_command_timeout: 600 # default command timeout
# replicas: 3 # active + warm sandboxes per gateway process
# idle_timeout: 600 # warm seconds before destroy; 0 disables reaping
# environment:
# PYTHONUNBUFFERED: "1"
api_key and domain may be omitted when OPEN_SANDBOX_API_KEY and
OPEN_SANDBOX_DOMAIN are set. use_server_proxy is useful when DeerFlow can
reach the OpenSandbox management service but cannot directly reach sandbox
execd endpoints.
Values in sandbox.environment that start with $ are resolved from the
Gateway process environment when the provider starts. Missing variables resolve
to an empty string, matching the E2B provider.
Lifecycle and contract
The provider derives a stable local ID from (user_id, thread_id). A released
sandbox enters an in-process warm pool and only the same scope may reclaim it.
Create returns only after the SDK readiness check and DeerFlow's
/mnt/user-data/{workspace,uploads,outputs} bootstrap succeed. A bootstrap
failure explicitly destroys the newly created remote sandbox.
Each remote has an independent SDK connection transport. Before an operation,
the adapter renews sandbox_timeout; commands use bash_command_timeout when
the caller supplies no timeout and extend the renewal horizon when necessary.
Operations are serialized per remote so a shorter renewal cannot overwrite the
horizon of an in-flight long command.
Setting sandbox_timeout: 0 selects explicit-cleanup mode and disables renewal.
The full DeerFlow surface is implemented:
execute_commandforwards per-call environment variables and positive wall-clock timeouts throughRunCommandOpts, preserving stdout, stderr, and non-zero exit information in DeerFlow's string result.- Text and binary file operations use OpenSandbox's native filesystem API. Append is serialized as a read-modify-write because SDK 0.1.x has no append primitive.
list_dir,glob, andgrepuse portablefind/grepcommands and the shared DeerFlow result parsers.- All paths must be absolute and traversal-free. Artifact downloads are further
restricted to
/mnt/user-data. - Command-path HTTP 404, HTTP 410, unhealthy-session errors, and broken transports evict the dead client so the next acquire cold-starts a replacement. A file-path 404 remains an ordinary missing-file error.
reset() parks active clients for later cleanup; shutdown() destroys active
and warm remotes. Cross-process discovery and ownership coordination are not
implemented yet, so each Gateway process has its own warm pool and capacity
accounting.