Changelog
New Features:
- Durable External Agent Sessions:
ClaudeAgentsessions 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 newagno_transcriptstable, 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:
ClaudeAgentandCodexAgentsupportbackground=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_runtake the samecontinue_from,forkandinputarguments asAgent.continue_run, withstream=Trueandbackground=True. Each tool result is a checkpoint listed byGET /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, andcontinue_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:
ClaudeAgentandCodexAgenttakeretries,delay_between_retriesandexponential_backoffwith the same defaults asAgent. 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 atype: "retry"warning event between attempts, a retried run recordsmetadata["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
ClaudeAgentandCodexAgentrun reports tokens, cache usage and cost (Claude) onRunOutput.metrics, with one entry per model inmetrics.details["model"], plus Agno's wall-clockdurationandtime_to_first_token. Completed runs accumulate into the session'ssession_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
/compactworks through the database-backed session store, so a compacted session resumes from its summary on any replica, andCodexAgent.compact/acompactcompact 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:
BaseExternalAgenttakesstore_eventsandevents_to_skiplikeAgent. AgentOS turns it on for external agents, so the run view and/agents/{id}/runs/{run_id}/resumereplay a finished run from the database once the event stream's retention has expired, in order and honouringlast_event_index. (#10957, #10958) - Structured Output for External Agents:
output_schemaonClaudeAgentandCodexAgenttakes 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) withcontent_typeset, as forAgent. 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-requestoutput_schemaform field now applies to external agents. See cookbook. (#10965) - Media for External Agents: Images and files can be attached to
ClaudeAgentandCodexAgentruns, 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 unlesskeep_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 samemetadata.sdkvalue as the agents API ("codex","claude-agent-sdk"), overlaid at read time from theagent_dataexternal agents already persist, so existing sessions are labelled with no migration and stored metadata is untouched. Native, team and workflow sessions are unchanged.RunSchemagains ametadatafield, which also surfaces run metadata such as retryattemptsandwarnings. (#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:
ClaudeAgentandCodexAgenttake typed native options (tools, permissions, MCP servers, thread and turn options) instead of untyped_kwargsdictionaries, which still work with a warning. Adapter constructors are keyword-only,agent.sdknames the SDK (API and session metadata emit onlysdk; theframeworkalias remains on the Python object), andprint_response/aprint_responsereturn 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:
ClaudeAgentandCodexAgentruns recordmodelandmodel_providerlike 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,modeldefaults toclaude-sonnet-4-6for Claude andgpt-5.6-lunafor 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_idonToolExecutionand on tool events, so tracing shows nested tool spans under the delegating tool. See cookbook. (#10959) - Development Setup:
scripts/dev_setup.shandscripts/demo_setup.shinstall 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
SessionBusyErrorhandler 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,videosandinput_fileson run requests are rejected with HTTP 422 before dispatch instead of vanishing or failing mid-run, and a malformed or scalar-rootoutput_schemais 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=Trueinstead ofnull, 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:
/resumeon a run submitted withstream=falsereports 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
- fix: persist ClaudeAgent SDK session id across restarts by @ysolanky in #10903
- fix: make partial-tool collision test independent of FastMCP's naming by @sannya-singal in #10914
- fix: include tool calls in Codex fallback history prompt by @ysolanky in #10909
- feat: persist external agent transcripts and tool results by @ashpreetbedi in #10904
- [feat] Add AnakinTools: scrape, crawl, map and search via Anakin.io by @aryan-anakin in #10650
- feat: add background lifecycle and cancellation to external agents by @ashpreetbedi in #10905
- chore: align dev and demo setup environments by @ashpreetbedi in #10920
- feat: continue ClaudeAgent runs from a step by @ysolanky in #10917
- feat: capture ext agent harness metrics by @kausmeows in #10925
- fix: keep failed attempts' tools and announce retries to streaming consumers by @kausmeows in #10937
- feat: compaction cookbooks for Claude and Codex, CodexAgent.compact by @kausmeows in #10924
- feat: store run events for external agents by @kausmeows in #10957
- feat: preserve Claude subagent tool lineage for tracing by @kausmeows in #10959
- feat: output_schema for external agents (Claude, Codex) by @ysolanky in #10965
- fix: harness soak follow-ups: tool errors, resume status, one turn per session by @kausmeows in #10958
- feat: improve external agent APIs and framework cookbooks by @ashpreetbedi in #10926
- fix: serialize queued external-agent turns before claiming attempts by @ashpreetbedi in #10974
- fix: confine harness attachment staging and roll back failures by @ashpreetbedi in #10971
- fix: reject malformed run media and output schema inputs by @ashpreetbedi in #11005
- cookbook: validate Phase 1 harness examples and reliability contracts by @ashpreetbedi in #10973
- fix: answer a busy session without closing the client connection by @kausmeows in #11017
- fix: record the model and provider on external agent runs by @kausmeows in #11018
- feat: expose the external agent sdk on session and run reads by @kausmeows in #11020
- feat: Release v3.1.3 by @kausmeows in #10984
New Contributors
- @aryan-anakin made their first contribution in #10650
Full Changelog: v3.1.2...v3.1.3