tool_call step in the same execution as the agent’s model calls. The sandbox
keeps the working files between dispatches and pauses while a call waits for
approval.
The design follows Coding agents on Rebuno.
Find the sandbox
Each task belongs to a session. The agent looks up the session’s sandbox by metadata, and creates one when there is none:step, which records the
sandbox id:
connect resumes that
sandbox, with the files the first attempt changed. If the sandbox no longer
exists, connect fails rather than the agent continuing in an empty one.
on_timeout: "pause" pauses a sandbox whose worker died instead of deleting it
when its timeout expires.
Wrap the tools
The tools run inside the sandbox:shell for git as well, committing to the session’s branch and
pushing it. All three keep the default safe_to_retry. A command that runs again
after a worker dies affects only the sandbox, and write_file replaces the whole
file, so writing it twice leaves the same result. See
idempotency.
Keep credentials out of the sandbox
Cloning and pushing need a GitHub token. Instead of placing the token in the sandbox, the agent adds a network rule that sets theAuthorization header on
requests to github.com at E2B’s egress proxy:
github.com, so code in the sandbox can push a branch but
cannot reach the API to open a pull request, and the policy on open_pr holds.
Pushes are not checked by policy. Protect the default branch with a GitHub
ruleset that requires a pull request, so a push can only land on other branches.
Pause while waiting
When a call waits for approval, the handler unwinds withBlocked. The agent
pauses the sandbox on the way out, and again when the run finishes:
execution().suspension because a framework can catch Blocked
inside its own loop. While the approval is pending, no worker holds the run and
the sandbox only keeps its storage. Once the approval is decided, the next
dispatch replays up to the held call and connect resumes the sandbox. A
dispatch that ends because another worker took over the run leaves the sandbox
running for that worker.
Sessions
A session carries over between executions: the sandbox, the branchrebuno/<session>, and the conversation. The handler takes an optional
session, and derives one from the execution id when it’s missing:
session resumes the sandbox, continues the conversation, and pushes to
the same branch, which updates the open pull request.
Write the policy
local steps that find the sandbox and load the
conversation are allowed without a rule.
Run it
examples/integrations/e2b
has the full agent, the policy, and a dev kernel config. It stores conversations
as files in sessions/ beside the agent.
Set E2B_API_KEY, REPO (the repository as owner/name), GITHUB_TOKEN,
LLM_MODEL, LLM_BASE_URL, and LLM_API_KEY. The token needs read and write
access to the repository’s contents and pull requests. Then start the kernel and
the agent from that directory:
open_pr call appears in rebuno exec watch. See
Approvals to approve it. The execution’s output includes
its session. Pass it to continue the same work:
lease_timeout_seconds sets a shorter lease for the agent.