feat(tools): add "sandbox" toolset to run code snippets in an ephemeral, isolated container#3639
Open
dwin-gharibi wants to merge 5 commits into
Open
feat(tools): add "sandbox" toolset to run code snippets in an ephemeral, isolated container#3639dwin-gharibi wants to merge 5 commits into
dwin-gharibi wants to merge 5 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3638
Summary
Adds a new built-in toolset,
sandbox, that runs a code snippet (python,node, orbash) inside an ephemeral, isolated container and returns stdout, stderr, and the exit code. Every run is disposable (--rm), resource-limited (memory / CPU / PID), time-bounded, and network-disabled by default.Tool:
run_code(language, code, timeout_seconds?, network?).Motivation
Agents often need to run code — compute a result, transform data, verify an approach — not just read/write files. Today the only option is
shell, which runs on the host with full access. The sandbox runs untrusted / model-generated code in a disposable, isolated container instead. It fits docker-agent naturally, since a container runtime is already the environment it ships on.Works with docker or other runtimes
Execution goes through an injectable
Executor, and the default one auto-detects a docker-compatible CLI in order: docker → podman → nerdctl (they sharerun --rm -i --network none …syntax). If none is present,run_codereturns a clear error.What changed
pkg/tools/builtin/sandbox/sandbox.gorun_code, purebuildRunArgs,Executorseam, runtime detection.pkg/tools/builtin/sandbox/sandbox_test.gopkg/teamloader/toolsets/toolsets.gosandboxcreator.pkg/teamloader/toolsets/catalog.gosandboxcatalog entry (required by the drift-guard test).docs/configuration/tools/index.mdsandboxto the built-in toolsets table.docs/tools/sandbox/index.mdDesign for testability
The container command is a pure
buildRunArgsfunction, and execution goes through anExecutorinterface. Tests cover argument construction, language aliasing, timeout capping, output formatting, and every error path with a fake executor — everything except the literaldocker run, which needs a daemon (covered by CI/integration).Example
The command it builds:
Tool output:
Testing
go test ./pkg/tools/builtin/sandbox/ ./pkg/teamloader/toolsets/buildRunArgs(isolation flags, limits, image;--network nonepresent by default and absent whennetwork: true), language aliasing,run_code(success, non-zero exit, empty code, unknown language, timeout cap, executor error), and the tool/interface check.TestBuiltinToolsetsCatalogMatchesRegistrypasses withsandboxin both registry and catalog.All pass;
gofmt -landgo vetclean. (CI runstask lint/task test.)Safety / scope
--rm,--network none,--memory 512m,--cpus 1,--pids-limit 256, and a time limit (default 30s, capped 300s).network: trueopts into a network only when the agent explicitly asks.