v3.1.4

agno-agi/agnov3.1.4Oct 16, 2026by kausmeows

Upgrading?

AI Summary

This release introduces comprehensive sandboxed execution environments (Docker and AgentCore) for Claude and Codex agents, featuring isolated state, warm resume, and AgentOS integration. It also enhances queue management, introduces ChartTools, and adds new Company management features.

Key Highlights

  • Sandboxed Harness Agents with Docker and AgentCore providers
  • Warm Sandbox Turns for faster resume times (4.6s vs 8.2s)
  • Queue Per Session and Instant Durable Submissions
  • ChartTools for inline visualization
  • Company Products and Playbooks management

Breaking Changes

  • `sandbox=` parameter changed from string (e.g., 'read-only') to provider objects (DockerSandbox, AgentCoreSandbox)
  • Host-only settings (`cwd`, `retries`, `env`) are now rejected by name at agent construction
  • Codex permission policy naming changed from `sandbox="read-only"` to `sandbox_mode`

New Features

  • Sandboxed Harness Agents (ClaudeAgent, CodexAgent)
  • Docker Sandbox (customer-operated provider)
  • Amazon Bedrock AgentCore Sandbox
  • Warm Sandbox Turns
  • Sandbox Through AgentOS
  • Attachments for Sandboxed Agents
  • Images and PDFs Inline for Claude Code
  • Queue Per Session
  • Instant Durable Submissions
  • ChartTools
  • Company Products and Playbooks

Full Release Notes

# Changelog

## New Features:

- **Sandboxed Harness Agents**: `ClaudeAgent` and `CodexAgent` take a `sandbox=` parameter and run the whole harness process inside an isolated, per-session computer instead of on the host, with session state that survives losing the container, the host or the replica that ran the last turn. No new classes to hold: `ClaudeAgent(id="coder", db=PostgresDb(...), sandbox=DockerSandbox("agno-sandbox:local", network="isolated"))` is the whole setup, and the agent builds its coordinator from its `PostgresDb` on first use. Each turn claims the session through a lease row in the agent's Postgres (`<session_table>_sandbox_bindings`, created on first use), starts compute restored from the session's last committed checkpoint (workspace plus the harness's own conversation files), runs the turn, then captures and verifies a new checkpoint and publishes the run row and recovery point in one transaction. A cancelled or failed turn publishes nothing and the previous checkpoint stays the recovery point. The turn refuses to continue on state it cannot verify: it passes the native conversation id (Claude session id, Codex thread id) committed with the last checkpoint, and a restore that lost it fails with `native_state_missing` before the model runs instead of silently starting a new conversation. Typed harness settings travel to the runtime as JSON; host-only settings (`cwd`, `retries`, `env`, native option objects) are rejected by name at construction. `require_native_resume` and `strict_persistence` are new options on `BaseExternalAgent`, and `agno[claude]` / `agno[codex]` install extras cover the harness SDKs. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/docker/sandbox_claude.py). (#11028, #11043, #11056, #11057)
- **Docker Sandbox**: `DockerSandbox` is the customer-operated provider. Containers run as UID 1000 with a read-only image filesystem, dropped capabilities, no privilege escalation, CPU, memory and process limits, bounded tmpfs for `/workspace` and `/runtime`, no host or Docker socket mounts, and only explicitly configured environment values plus the harness's model API key. Networking defaults to `none`; `network="isolated"` gives a managed bridge with inter-container traffic off, and `subnet=` picks its range. Deterministic session and generation identity reconciles creation races and lost responses; commands are never retried automatically. `pause` / `resume` are provided through the kernel freezer, and `DockerCheckpointTransfer` moves checkpoints in and out. `cookbook/frameworks/sandbox/build_image.py` builds the runtime image. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/docker/docker_execution.py). (#10975, #11028)
- **Amazon Bedrock AgentCore Sandbox**: `AgentCoreSandbox` implements the same contract on AgentCore Runtime, with `AgentCoreCheckpointTransfer` next to the Docker transfer. Each sandbox generation is one AgentCore runtime session in a Firecracker microVM; `create` is idempotent through a session id derived from the namespace, agent, session and generation. A root server on port 8080 claims the microVM, starts the runtime as UID 1000, fences every later operation with the claimed configuration and a random incarnation so a stale handle can never act on a later claim, forwards start and poll calls, and runs commands behind a guard that drops to UID 1000 in `/workspace`. Checkpoints stop UID 1000 processes during capture and restore and move through `InvokeAgentRuntime` in chunks, up to 2 GiB. Pause is not supported and AgentCore session storage is not used. The provider packages moved to `agno.sandbox.docker` and `agno.sandbox.agentcore`; `DockerCheckpointTransfer` now imports from `agno.sandbox.docker`. The runtime also gained two Codex fixes that apply to Docker as well: it creates `CODEX_HOME`, and it logs Codex in from `OPENAI_API_KEY` when no stored login matches, since checkpoints exclude `auth.json`. `cookbook/frameworks/sandbox/agentcore/agentcore_setup.py` builds, pushes and deploys the runtime. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/agentcore/sandbox_claude_agentcore.py). (#11050)
- **Warm Sandbox Turns**: The coordinator keeps a session's computer for `warm_computer_seconds` (default 300) after a turn instead of destroying it: paused on Docker, left idle on AgentCore. The next turn inside that window resumes it and restores nothing; otherwise it retires the old computer and takes the cold path on a fresh generation restored from the checkpoint. The checkpoint is still captured after every turn, so a warm computer is only a shortcut to the state the checkpoint already holds. `metadata.sandbox.resumed` on every completed run says which path the turn took, and `retire_computer` / `sweep_warm` on the coordinator remove computers that sessions never came back for. Live on Docker a warm Claude turn took 4.6 s against 8.2 s cold; on AgentCore 3.3 s against 8.2 s. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/warm_turns.py). (#11088)
- **Sandbox Through AgentOS**: `POST /agents/{agent_id}/runs` for a sandboxed agent submits foreground, streaming and background requests to the durable queue with no new endpoints. An `Idempotency-Key` retry returns the same run, while a different session, input, options or attachment bytes returns 409. Clients reconnect with `/runs/{run_id}/resume` (`last_event_index`) and cancel with `/runs/{run_id}/cancel`, including across replicas: a cancel settled on another replica now records the run as cancelled and keeps the user's turn on the run row. AgentOS fails at startup if a sandboxed agent has no Postgres to coordinate on, refuses the host-local default checkpoint store once a queue worker is active, and validates each sandboxed agent's bindings table at startup and before a submission, naming the remedy for a table from an earlier build. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/docker/sandbox_claude_agentos.py). (#11043, #11105)
- **Attachments for Sandboxed Agents**: `run` / `arun` on a sandboxed `ClaudeAgent` or `CodexAgent` accept `images=` and `files=`, and the AgentOS run route accepts them as uploads. Only bytes cross into the sandbox: each attachment is validated and encoded before any durable write, staged under `/workspace/.agno/uploads/<run_id>/` by the harness's own staging, and kept in the turn's checkpoint so later turns on a new computer can still read it. A request carries at most 16 attachments and 512 KiB in total; URLs, media references, server file paths, audio and video are refused. Queued runs store the attachments with the submission, so a retry sends the same bytes. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/docker/sandbox_attachments.py). (#10990, #11091)
- **Images and PDFs Inline for Claude Code**: `ClaudeAgent` now sends attached images (PNG, JPEG, GIF, WEBP) and PDFs up to 4 MiB inside the message as content blocks, the form the Agent SDK's streaming input takes, instead of only writing them to disk for Claude's Read tool. Claude sees the picture directly and never reads the file back, which used to return the whole file as base64 and overflow the SDK's 1 MiB message buffer and the sandbox's 256 KiB event frame for images of a few hundred KB. Whether a file goes inline is decided from its bytes, so a mislabelled file stays on disk for the file tools; other files and larger images keep the Read path. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/sandbox/docker/sandbox_image_sizes.py). (#11115)
- **Queue Per Session**: Durable background runs on one session now execute at most one at a time, in submission order, for every component. Each ticket carries a store-assigned `session_seq`; a ticket is claimed only while no sibling in its session is running or paused and no earlier sibling is still queued, so waiting tickets spend no attempt and no worker slot. Different sessions stay concurrent within `max_concurrency`. A paused run holds its session, a continued or retried run keeps its place, and a PENDING run poll carries `waiting_on` with the run it is blocked behind. `QueueConfig.queue_per_session` (default on) controls it, external agents are serialized regardless, and `GET /config` reports the effective setting. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/background_tasks/queue_per_session.py). (#9587)
- **Instant Durable Submissions**: The replica that accepts a durable submission wakes its own queue worker after the ticket commits, so the run starts in milliseconds instead of waiting up to `poll_interval` for the next poll. A saturated replica wakes on slot release, and peers still pick up jobs on their own poll. Durability is untouched: the row is committed before anyone is woken. (#9667)
- **ChartTools**: New toolkit with a single `create_chart` tool that validates a chart payload (`bar`, `line`, `area`, `pie`, `bar-horizontal`, `bar-stacked`, `area-stacked`) and returns a ready fenced chart block for Agno OS to render, replacing the schema prompt users had to carry. Validation failures tell the model what to fix, and the toolkit ships its own instructions, so `tools=[ChartTools()]` is all an agent needs. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/chart_responses/agentos_chart_responses.py). (#8295)

## Improvements:

- **Durable Queue for Db-Backed and Factory Components**: Background runs on components created through the components API, on version-pinned runs, and on `AgentFactory` / `TeamFactory` / `WorkflowFactory` submissions now ride the durable queue instead of dropping to a detached task on the accepting replica. The accepting endpoint stamps a resolution scope on the ticket (source, owner, version, and for factories the trusted claims and factory input), and the worker replays that resolution at claim time. A factory that reads `ctx.request` on the worker fails the run with a message naming the fix, since the live request cannot ride the ticket. The run read routes for factory runs no longer answer 400 on every poll. See [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/21_factories/08_durable_queue.py). (#9796, #11045)
- **Codex Permission Policy Naming**: `CodexAgent(sandbox="read-only")` is renamed `sandbox_mode`, matching Codex's own config key, since `sandbox=` now takes a provider. The old string form still works with a `DeprecationWarning`. (#11043)
- **Sandbox Cookbooks**: `cookbook/frameworks/sandbox/` is split into `docker/` and `agentcore/` folders, each with its own README and test log, covering the provider, checkpoints, the coordinator, recovery, cancellation, attachments, warm turns and AgentOS. `build_image.py` loads the built tag into the image store and verifies it is there. (#11050, #11081, #11105)
- **Gemini Cookbooks**: Updated to the current models and API. (#11038)

## Bug Fixes:

- **Sandbox Checkpoint Restore**: Every second turn in a sandbox session failed with `getent unable to find entry "1000:1000" in passwd database`, because `docker cp --archive` asks the daemon to resolve the container's user as a name. Restore now copies without archive mode and pins every restored entry to 1000:1000 itself. (#11094)
- **Sandbox Store and Coordinator**: A queue cancel racing a worker claim of the same run could deadlock on lock order; the stop path now takes the session, run and binding in the same order as every other store transaction. Sync calls through `DockerSandbox` leaked an HTTP client per call. Cancelled sandbox runs now record the `EXECUTING` cancellation stage the queue expects. A run marked finished between cleanup and commit goes through the stop path instead of leaving the binding in `finalizing`, and long provider calls extend their lease. (#11057, #11092)
- **Sandbox Submissions**: Submitting with a `user_id` to a session created without one, or the reverse, answers 404 before any ticket exists instead of a 500 with a cancelled job left behind. A foreground request whose job failed before its run row existed returns the ticket's error as a 500 instead of a 503 asking the client to reconnect. (#11105)
- **WebSocket Tails**: With a durable queue, a chat client that sent a second message while a workflow run was streaming over the WebSocket stopped getting events for the first run. Tail pumps are now keyed per (socket, run), a re-subscribe replaces only that run's pump, and a socket may attach up to 32 runs. (#11039)
- **API Docs Order**: The FileSystem routes are registered after the Database routes on setup and resync, so the generated API docs list them in order. (#11099)
- **Tests**: The WebSocket factory workflow tests pin the inline path they were written for, after factory submissions started riding the durable queue. (#11106)

## What's Changed
* fix: let db-backed components ride the durable queue by @ysolanky in https://github.com/agno-agi/agno/pull/9796
* feat: queue per session - at most one live run per session (head-of-line durable claims) by @ysolanky in https://github.com/agno-agi/agno/pull/9587
* cookbook: update Gemini cookbooks by @Ayush0054 in https://github.com/agno-agi/agno/pull/11038
* feat: wake the local queue worker on enqueue (durable submissions start in milliseconds) by @ysolanky in https://github.com/agno-agi/agno/pull/9667
* fix: run factory-backed components on the durable queue by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11045
* feat: add the AgentOS manager by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11036
* feat: add ChartTools toolkit for inline Agno OS charts by @anuragts in https://github.com/agno-agi/agno/pull/8295
* fix: keep OS Manager specialists internal by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11077
* fix: keep every run's WebSocket tail alive when a socket submits another run by @ysolanky in https://github.com/agno-agi/agno/pull/11039
* fix: order filesystem routes after database by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11099
* feat: add opt-in Company Products by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11095
* feat: add Company work records by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11097
* feat: add Company playbooks and Product Manager by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11100
* fix: pin the inline path in the websocket factory version test by @ysolanky in https://github.com/agno-agi/agno/pull/11106
* fix: repair Company manager routing, database identity and tool arguments by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11112
* feat: add Company Task execution and attention by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11101
* feat: cascade Company archives and add grouped counts by @ashpreetbedi in https://github.com/agno-agi/agno/pull/11114
* feat: sandbox support by @ysolanky in https://github.com/agno-agi/agno/pull/11028
* feat: session run previews and status filter for the chat tray; queue listing stays admin-only by @ysolanky in https://github.com/agno-agi/agno/pull/9815
* feat: Release v3.1.4 by @kausmeows in https://github.com/agno-agi/agno/pull/11113


**Full Changelog**: https://github.com/agno-agi/agno/compare/v3.1.3...v3.1.4

Related Repositories