Repository navigation
fix(local-sandbox): load artifacts into a local agent's container - #60
Conversation
|
@greptileai review |
load_artifact into an agent on the local provider failed: its scripts start with `sudo docker ...`, which ran this host's sudo, and the /app rewrite also changed the container side of `docker cp f c:/app/x`, so the files landed outside the container. LocalSandbox now drops `sudo` where a bash -c script runs it as a command, and leaves /app alone after ":" (the container side of a copy or a -v mount). collect_artifacts, verify_sandbox and the validator each had their own agent-container lookup. They now share find_agent_container. The validator's copy lacked the guard against borrowing another run's container, so its changelog marker check could read the wrong agent. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Dropping sudo from a script also reached a command quoted for a container (`docker exec c bash -c 'make; sudo make install'`). Only sudo outside quotes, where this host's shell runs it, is dropped now. Skipping /app after every ":" also skipped host paths such as `PATH=$PATH:/app/bin`. Only the container side of a `docker cp` and of a `-v`/`--volume` mount is skipped now. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Eight scripts in load_artifact and the unit-tests verifier began with `sudo docker`. Each already runs under exec_script's `sudo bash -c`, so the inner sudo gave no extra privilege where the provider keeps the outer one (E2B, the Scale sandboxes). Where the provider drops it, the inner one broke the script: the host's sudo asks for a password locally, and the Modal VM image has no sudo. The other docker calls in scripts, such as run_docker_container's, already had none. With the inner sudo gone, LocalSandbox no longer rewrites sudo in script text. New local integration tests load an EnvironmentArtifact into a container and run the unit-tests verifier in one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
d4ab287 to
34f702d
Compare
|
@greptileai review |
This comment has been minimized.
This comment has been minimized.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Finding the container side of a copy or mount in script text kept missing forms. A script that starts with `docker cp` is now treated like one that starts with `docker exec`: the /app it names is the container's, and the host side of these copies is a VM temp path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@greptileai review |
Leaving a whole `docker cp` script alone broke the MCP artifact load on the local provider: it stages under the host's /app, which must still point at the work dir. The five copies now go through VmSandbox.docker_cp, which hands both paths to a fixed script as arguments. The local sandbox already maps an argument that starts with /app and leaves `container:/app/...` alone, so it maps the host side and never the container's, without reading script text. LocalSandbox is back to main's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@greptileai review |
|
On the summary's remaining point (direct Verification on ab51673: all CI green, including Step pipeline, dev stage: passes 7 of 7: local ×3 at once, the hosted VM provider ×2, modal_vm ×2. Full task runs through
The local runs used |
What and why
On the local provider,
load_artifactinto a container left the files on the host or failed. The same was true of the unit-tests verifier:sudoinside scripts. Eight scripts inload_artifactandrun_container_unit_testsbegan withsudo docker …. They all already run underexec_script'ssudo bash -c, so the innersudoadds nothing on providers that keep the outer one (E2B, the Scale sandboxes). On providers that drop it, the inner one breaks the script: locally, the host'ssudoasks for a password, and the Modal VM image has nosudo. Every otherdockercall inside a script, such asrun_docker_container's, already ran without it.docker cp. The local sandbox points/appat its work dir by rewriting script text, and that also changedagent-local-x:/app/x, so the copy targeted a path that doesn't exist in the container.Changes:
sudo; root comes only from the outersudo bash -c, which each provider keeps or drops.docker cpcalls go through a newVmSandbox.docker_cp(source, destination), which hands both paths to a fixed script as arguments. The local sandbox already maps an argument that starts with/appand leavescontainer:/app/...alone, so it now maps the host side of a copy (the MCP artifact load stages under the host's/app) and never the container's, without reading script text.LocalSandboxitself is unchanged.collect_artifacts,verify_sandboxand the A2A validator each had their own copy; they now sharefind_agent_container. The validator's copy lacked the check that stops a sandbox that owns its container from taking anothera2a-agent-*container on a shared Docker host, so its changelog marker check could read another run's agent.#37 already kept a reattached local sandbox in VM mode, so
collect_artifacts,verify_sandboxandrun_codeagainst a local agent already reached its container.How it was tested
make unit-test: 6101 passed. New tests coverdocker_cppassing its paths as arguments and raising on failure, the local sandbox mapping only a copy's host side, the shared container lookup, and the validator not reading another run's container.The two slow-tier tests that load an MCP artifact on local compose (
test_a_multi_env_deploys_restores_loads_and_tears_down_on_local_compose,test_load_universe_on_single_mcp_server_env[default]): passed.tst/integration/task_step/test_verify_sandbox_local.py, against Docker on macOS: 7 passed. Three new tests: a universe and an EnvironmentArtifact loaded into a local container, and the unit-tests verifier run in one. Onmainall three fail, two of them withsudo: a terminal is required to read the password.A pipeline run against the real step classes and a remote object and document store:
deploy_sandbox→run_docker_container→load_artifact→run_container_unit_tests→collect_artifacts→load_artifactagain.load_artifactcovers a universe with nested files, a quoted name and a 20 MB blob, plus an EnvironmentArtifact into a path with a space.run_container_unit_testsruns a setup command and checks every file's sha256, its result file is copied out, and a deliberately wrong check must fail.collect_artifactscontents are compared byte for byte.mainsudoasks for a passwordsudo: command not foundOn modal_vm, the EnvironmentArtifact step fails on
mainand on this PR alike, because the VM image has nopython3; it's tracked separately and was left out of those runs. E2B and one other hosted VM provider weren't run. Every sandbox the runs created has exited.🤖 Generated with Claude Code
The PR should not merge until direct local Docker-copy scripts keep their container paths.
What we checked:
Summary
This PR fixes container file copies and Docker commands for local agent sandboxes, so artifact loads and container checks can reach the agent’s files. It also gives artifact collection, sandbox verification, and A2A changelog checks one shared way to find the agent container.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR A["Artifact or verifier"] --> B["VmSandbox.docker_cp"] B --> C["Host path mapped by local sandbox"] B --> D["Container path kept unchanged"] E["Direct exec_script docker cp"] --> F["Whole script rewritten"]Reviews (6) · Last reviewed commit: "Pass docker cp paths as arguments, not s..."