Serve sandboxed Claude and Codex agents from AgentOS with no new endpoints
October 16, 20262 min read
Agno AgentOS accepts a sandboxed ClaudeAgent or CodexAgent only on a durable queue with Redis coordination, because any replica may run the next turn. Register the agent the way you register any other and the run route does the rest.
from agno.agents.claude import ClaudeAgent
from agno.db.postgres import PostgresDb
from agno.job_queue.config import QueueConfig, RedisCoordination
from agno.os import AgentOS
from agno.sandbox.checkpoint import FileCheckpointStore
from agno.sandbox.docker import DockerSandbox
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
agent = ClaudeAgent(
id="coder",
permission_mode="bypassPermissions",
sandbox=DockerSandbox(
"agno-sandbox:local",
network="isolated",
checkpoints=FileCheckpointStore("/shared/checkpoints"),
),
)
agent_os = AgentOS(
agents=[agent],
db=db,
queue=QueueConfig(durable=True, db=db, redis=RedisCoordination(url="redis://localhost:6379/0")),
)A foreground request waits on the queued run and returns it, stream=true tails its events, and background=true answers 202 with a run_id. A client that drops reconnects with /runs/{run_id}/resume and its last_event_index, and /runs/{run_id}/cancel works from any replica. When the cancel settles on another replica, the run row records the run as cancelled and keeps the user's message.
Retries with an Idempotency-Key
A client that retries with the same Idempotency-Key gets the run it already started. If the key comes back with another session, user or agent, AgentOS answers 409, and the same goes for changed input, run options or attachment bytes. Changing only stream or background still returns the original run.
We ran the release's AgentOS through FastAPI's TestClient on an embedded Postgres, with fakeredis for Redis and a stand-in sandbox that has no compute, since every check here happens before a computer starts.

Mistakes caught before a turn runs
A sandboxed agent coordinates every turn through Postgres, so AgentOS(...) raises at construction when neither the agent nor AgentOS has a PostgresDb or AsyncPostgresDb. Once a queue worker is active, AgentOS also refuses a sandbox left on the default ~/.agno/sandbox/checkpoints folder, which other replicas can't read. That submission came back as a 500 in the test run, and AgentOS cancelled the ticket before it could execute.
AgentOS validates each sandboxed agent's <session_table>_sandbox_bindings table at startup and again before a submission creates its ticket. A table left by an earlier build fails with its remedy, telling you to drop or rename that table or pass PostgresDb(sandbox_table=...) to create a new one. A user_id that doesn't match the session's owner gets a 404 before any ticket exists, and a foreground job that failed before its run row was written returns that job's error as a 500.
See the cookbook, and learn more about the durable queue and idempotency keys in the documentation.
Frequently asked questions
The usual POST /agents/{agent_id}/runs. AgentOS puts the request on its durable queue whether you ask for a foreground answer, a stream or a background run, and /runs/{run_id}/resume and /runs/{run_id}/cancel work from any replica.
A PostgresDb or AsyncPostgresDb, on the agent or on AgentOS, and QueueConfig(durable=True) with Redis coordination. Without Postgres, building AgentOS raises a ValueError; without the durable queue and Redis, the run route answers 400.
When the key was already used for a different session, user or agent, or for different input, run options or attachment bytes. The same submission sent again returns the original run, even with another stream or background value.
Once a queue worker is active, any replica may run the next attempt, and the default ~/.agno/sandbox/checkpoints lives on one host. AgentOS cancels the submission before it executes, so pass checkpoints= storage that every replica can read.




