github agno-agi/agno v3.1.3

5 hours ago

Changelog

New Features:

  • Durable External Agent Sessions: ClaudeAgent sessions now resume on any replica. The Claude SDK session id is stored on the Agno session (#10903), and with a database that supports transcript storage (PostgresDb, AsyncPostgresDb, SqliteDb, AsyncSqliteDb) every transcript line is mirrored into the new agno_transcripts table, so a later turn on another machine resumes from the database instead of a local file. A stored session that cannot be resumed falls back to a fresh SDK session seeded with the Agno history. Claude and Codex non-streaming runs now keep tool calls and results in run history. See cookbook. (#10904)
  • Background Runs & Cancellation for External Agents: ClaudeAgent and CodexAgent support background=True, durable-queue run ids, resumable indexed SSE and cancellation through /agents/{id}/runs/{run_id}/cancel, sharing the background task, slot and event-stream infrastructure of native agents. Claude uses a per-run SDK client and Codex retains turn handles, so the owning process can interrupt either SDK. See cookbook. (#10905)
  • Step Replay for ClaudeAgent: ClaudeAgent.continue_run / acontinue_run take the same continue_from, fork and input arguments as Agent.continue_run, with stream=True and background=True. Each tool result is a checkpoint listed by GET /agents/{id}/runs/{run_id}/checkpoints; continuing forks the stored SDK transcript at that message, so the model only remembers what happened up to it, and continue_from="last_user" replays the turn. A finished run is never rewritten in place: its continuation is a new sibling run. See cookbook. (#10917)
  • Retries for External Agents: ClaudeAgent and CodexAgent take retries, delay_between_retries and exponential_backoff with the same defaults as Agent. A failed attempt is retried with the same run id and resumes the SDK session or Codex thread it started; limits (max_turns, max_budget_usd, Codex budget and usage limits) and permanent errors (authentication, billing, bad requests, context window, policy) are not retried. Tool calls from failed attempts are kept exactly once, streaming consumers get a type: "retry" warning event between attempts, a retried run records metadata["attempts"], and the durable queue fails a job at once when the agent marks its error non-retryable, including across worker restarts. See cookbook. (#10937)
  • Metrics for External Agents: Every ClaudeAgent and CodexAgent run reports tokens, cache usage and cost (Claude) on RunOutput.metrics, with one entry per model in metrics.details["model"], plus Agno's wall-clock duration and time_to_first_token. Completed runs accumulate into the session's session_metrics, which AgentOS shows in the sessions list, the session view and /metrics. Codex sums every model request in a turn, not only the last one. See cookbook. (#10925)
  • Compaction for External Agents: Claude Code's /compact works through the database-backed session store, so a compacted session resumes from its summary on any replica, and CodexAgent.compact / acompact compact the Codex thread behind an Agno session. Compaction refuses while a run on the session is in flight. See cookbook. (#10924)
  • Stored Events for External Agents: BaseExternalAgent takes store_events and events_to_skip like Agent. AgentOS turns it on for external agents, so the run view and /agents/{id}/runs/{run_id}/resume replay a finished run from the database once the event stream's retention has expired, in order and honouring last_event_index. (#10957, #10958)
  • Structured Output for External Agents: output_schema on ClaudeAgent and CodexAgent takes a Pydantic model or a JSON Schema dict, on the agent or per run, and the run's content is the parsed model (or dict) with content_type set, as for Agent. Claude delivers the object through its structured output tool, which is not recorded as a tool call; Codex receives a strict schema. The schema must describe a JSON object; an array or scalar root is refused before the run. The AgentOS per-request output_schema form field now applies to external agents. See cookbook. (#10965)
  • Media for External Agents: Images and files can be attached to ClaudeAgent and CodexAgent runs, directly and through the AgentOS API and UI. Attachments are staged under <cwd>/.agno/uploads/<run_id>/, named in the prompt (Codex also receives images natively), recorded on the run's input, restored for later turns on any replica and removed after the run unless keep_uploads=True. Audio and video are rejected with a 400 instead of a server error. See cookbook. (#10926)
  • External Agent Identity on Session APIs: GET /sessions, GET /sessions/{session_id} and the session run reads carry the same metadata.sdk value as the agents API ("codex", "claude-agent-sdk"), overlaid at read time from the agent_data external agents already persist, so existing sessions are labelled with no migration and stored metadata is untouched. Native, team and workflow sessions are unchanged. RunSchema gains a metadata field, which also surfaces run metadata such as retry attempts and warnings. (#11020)
  • AnakinTools: New toolkit for Anakin.io's scrape, crawl, map and search APIs as four flag-gated methods, polling asynchronous jobs until they complete so the model receives page content or links rather than a job id. See cookbook. (#10650)

Improvements:

  • External Agent APIs: ClaudeAgent and CodexAgent take typed native options (tools, permissions, MCP servers, thread and turn options) instead of untyped _kwargs dictionaries, which still work with a warning. Adapter constructors are keyword-only, agent.sdk names the SDK (API and session metadata emit only sdk; the framework alias remains on the Python object), and print_response / aprint_response return the final run and raise on failure. Framework cookbooks were reworked with native SDK comparisons, a sample project and a reproducible reliability kit. (#10926)
  • Model Identity for External Agents: ClaudeAgent and CodexAgent runs record model and model_provider like native agents, so they count on the Models Runs card of the AgentOS metrics page. When no model is set on the agent or in its options, model defaults to claude-sonnet-4-6 for Claude and gpt-5.6-luna for Codex, as a native model has a default id; the default is what the SDK is asked to run. A model set in options still wins. Previously an unset model left the choice to the CLI. (#11018)
  • Queued Turns Per Session: Queued external-agent turns on one session no longer claim attempts together and burn them on SessionBusyError. Each built-in queue store (Postgres, Redis, in-memory) elects the next turn for a session before it spends an attempt or a worker slot. (#10974)
  • Harness Cookbooks: The Claude and Codex cookbooks were refreshed after Phase 1 acceptance testing with typed native options throughout, a corrected reliability runner, and live results recorded in each folder's test log. (#10973)
  • One Turn Per Session: Claude Code and Codex keep one conversation per session on their side, so a second turn started while one is in flight is now refused with SessionBusyError (HTTP 409, error_type: session_busy) instead of being accepted and failing later. Cancelling a run left pending or running by a crash frees its session. (#10958)
  • Subagent Tool Lineage: Tool calls made by Claude subagents carry parent_tool_call_id on ToolExecution and on tool events, so tracing shows nested tool spans under the delegating tool. See cookbook. (#10959)
  • Development Setup: scripts/dev_setup.sh and scripts/demo_setup.sh install the same dependencies, so cookbooks run from either environment. (#10920)

Bug Fixes:

  • Session Busy Keep-Alive: The 409 for a busy external-agent session is answered by a dedicated SessionBusyError handler instead of the catch-all, so the keep-alive connection stays open and the conflict is logged as a warning rather than a traceback. The response body is unchanged and no other exception takes the new path. See cookbook. (#11017)
  • Attachment Staging: Files attached to external-agent runs are staged and restored only under the active workspace, with the harness told when historical paths moved. A failed staging rolls back every file it created, including partial writes and with keep_uploads=True, while preexisting files are preserved. Traversal run ids and symlinked upload paths are rejected. (#10971)
  • Run Input Validation: Malformed JSON images, audio, videos and input_files on run requests are rejected with HTTP 422 before dispatch instead of vanishing or failing mid-run, and a malformed or scalar-root output_schema is rejected instead of being silently dropped. (#11005)
  • CodexAgent: Failed tool calls (a non-zero exit, a declined command, an MCP tool error) are stored with tool_call_error=True instead of null, on streamed and non-streamed runs. (#10958)
  • CodexAgent: When a thread cannot be resumed, the history replayed into the fresh thread now includes earlier tool calls and their results, truncated to 2000 characters each, instead of only user and assistant text. (#10909)
  • External Agent Resume: /resume on a run submitted with stream=false reports the run's real status and says to poll the run endpoint, instead of claiming the run completed while it was still running. (#10958)
  • Tests: The partial-tool collision test no longer depends on FastMCP's tool naming. (#10914)

What's Changed

New Contributors

Full Changelog: v3.1.2...v3.1.3

Don't miss a new agno release

NewReleases is sending notifications on new releases.