Skip to content
Changelog

Read what a sandboxed run left behind after its container is gone

October 19, 20261 min read

Agno's open_run_checkpoint(run_id) looks up the checkpoint reference on the run's row, has the checkpoint store verify the archive, and yields its path for the length of the with block. CheckpointArchive.restore unpacks that path into workspace/ and native/, minus the credential files the capture left out, so a host process can turn an engineer's edits into a patch.

from pathlib import Path
 
from agno.sandbox.checkpoint import CheckpointArchive
 
with engineer.open_run_checkpoint(result.run_id) as archive:
    CheckpointArchive().restore(archive, Path("/tmp/review/turn"))
 
# async code, or an async database:
async with engineer.aopen_run_checkpoint(result.run_id) as archive:
    await CheckpointArchive().arestore(archive, Path("/tmp/review/turn-async"))

engineer.checkpoint_store returns the sandbox's checkpoints= store, or the host-local file default when none is set. Agno refuses that default while a durable queue worker is active, since another replica cannot read this host's disk. A file store now writes its objects read-only, so a reader writing through the yielded path cannot damage the session's recovery point.

We ran a FixtureAgent with Repository("https://github.com/octocat/Hello-World", branch="master") on a real DockerSandbox and Postgres, with the fixture runtime standing in for the model. A shell command in the warm computer appended a line to README, turn 2 committed, and we removed the container. With no container left in the namespace, open_run_checkpoint opened turn 2's 12,156-byte archive, and git diff in the restored checkout printed the edit.

A sandboxed run's checkpoint opened on the host after its container was removed, with the fixture runtime standing in for the model, real output. docker ps filtered to the sandbox namespace lists no containers. Inside with agent.open_run_checkpoint(run_id), the 12156-byte archive is verified by the store and restored to native/fixture-session, native/repository.json, workspace/fixture-effects.txt, workspace/fixture-env.txt and workspace/repository. git diff in workspace/repository shows README gaining the line edited by the engineer after Hello World!

Only a completed run of the same agent opens. On a second session without a repository, an agent with the id reviewer got Run open-26783431-2 belongs to another agent, and an id that was never run got Run open-26783431-never does not exist. A run that failed, was cancelled or is still running is refused the same way, since only a completed turn commits a checkpoint.

See the cookbook, and learn more about deploying harness agents in the documentation.

Frequently asked questions

Call agent.open_run_checkpoint(run_id) in a with block and pass the yielded path to CheckpointArchive().restore(path, destination). The destination then holds workspace/ and native/, with the repository checkout under workspace/repository when the agent has one.

No. Each completed turn commits its checkpoint to the checkpoint store outside the computer, so the host can open it after the container is paused or removed.

Only a COMPLETED run of the same agent that committed a checkpoint. An unknown run, another agent's run, a run that failed, was cancelled or is still running raises ValueError.

In async code, and always with an async database such as AsyncPostgresDb. The sync open_run_checkpoint refuses an async database and points to the async form.

Shipped around the same time