Changelog
Behavior Changes
- Run metadata precedence:
metadatanow resolves as component, then session, then call-site onAgent,Team, andWorkflow, so ametadata=passed torun()wins overagent.metadatawhere the component value previously won. A run no longer assigns session metadata back onto the shared component, so code that readagent.metadataafter a run to observe session values now sees the constructor value. The session layer only applies where the dispatch pre-reads the session, soTeam.arunand the async-DB agent and workflow paths still resolve from component and call-site alone. (#9104) MCPConfigrejects unknown fields:MCPConfig/MCPServerConfignow raise on unrecognised keyword arguments at construction instead of ignoring them, so a typo such astool=fails at boot rather than silently serving a different tool surface. (#9819)BaseRemote.acancel_runsignature: the abstract method gained anauth_tokenparameter that the cancel surfaces pass by keyword, so a third-partyBaseRemotesubclass must accept it. (#9819)- Reasoning detection asks the provider: native reasoning detection now queries the provider before falling back to model-id matching, so a
GeminiorClaudemodel configured for thinking is classified as non-reasoning when the provider reports thinking unsupported. The lookup is a blocking HTTP call cached on the reasoning manager, with a 10 second timeout on the Ollama, OpenRouter, and Moonshot paths. Id-based fallbacks changed too:gpt-5variants match on OpenAI and Azure OpenAI, Groq and Ollama matchgpt-ossandqwen3, and Ollama'sqwen2.5-coderis no longer treated as a reasoning model. (#8616) - MCP configuration renames:
AgentOS(mcp=...),MCPConfig, anddefault_toolsare the new spellings formcp_server=,MCPServerConfig, andenable_builtin_tools. The old names keep working as aliases with removal targeted for 3.1; passing both spellings with different values raises. (#9819)
New Integrations
- Synthorai model provider:
Synthorai(agno.models.synthorai) talks to the Synthorai gateway over its OpenAI-compatible endpoint, readingSYNTHORAI_API_KEYand defaulting tohttps://synthorai.io/v1. It is registered in the provider lookup table, somodel="synthorai:<model-id>"strings resolve as well. (#9788) - WaveSpeed image and video generation:
WaveSpeedTools(pip install agno[wavespeed], key fromWAVESPEED_API_KEY) generates media through the WaveSpeed API.generate_imageandgenerate_videotake a text prompt and return aToolResultcarryingImage/Videoartifacts, polling synchronously withinpoll_intervalandtimeout. (#9620, fixes #9621) - Serply search toolkit:
SerplyToolssearches Google web, News, and Scholar through the Serply API, readingSERPLY_API_KEY. Web search is on by default;search_news,search_scholar, orall=Trueenable the others. A missing key or failed request returns anerrorfield instead of raising. (#9780, fixes #9779) - AtomicMail toolkit:
AtomicMailToolsgives an agent its own inbox.register_inboxprovisions one through AtomicMail's proof-of-work signup with no domain setup or human verification, andsend_emailandlist_inboxwork over JMAP. Credentials are cached to~/.atomicmail/credentials.jsonso later runs reuse the same inbox, andpow_timeout(default 300s) caps the solve. (#9130)
Improvements
- Agents, teams, and workflows as MCP tools:
MCPConfig.toolsnow acceptsAgent,Team, andWorkflowinstances, remote proxies, and component factories, publishing each as its own named MCP tool —chief, rather thanrun_agent(agent_id="chief").component.as_tool(name=..., description=...)publishes one under a name and description of your choosing.continue_runandcancel_runregister alongside exposed components even withdefault_tools=False, so a run that pauses on a confirmation stays resumable over MCP. (#9819) - Toolkits as MCP tools:
MCPConfig.toolsnow accepts aToolkitand publishes one MCP tool per registered method, narrowed by the toolkit's ownenable_*/include_tools/exclude_tools, where it previously raisedTypeError. Framework parameters (RunContext,Agent,Team, and the_agno_*channels) are kept out of the client-facing schema and filled server-side. A tool returning aToolResultis rendered as MCP content blocks — text, image and audio, embedded resources for video and file bytes, andresource_linkfor url-only artifacts. A**kwargsentrypoint, which previously tookget_app()down, now publishes its declared schema or its named parameters. (#9846) - MCP tool titles and behaviour annotations:
as_tool()and@tool/Functionnow accepttitleandannotations, which AgentOS publishes over MCP for exposed components, custom tools, and its eight built-in tools. Exposed components publish a title even when you set none and assertreadOnlyHint: False,destructiveHint: True,openWorldHint: Trueby default, with your overrides merged per key. Unknown annotation keys raise rather than travelling to the client. (#9844) - Context provider
query_timeoutandwrite_tools: every context provider acceptsquery_timeout, a wall-clock deadline applied to eachquery_<id>tool call that yields an error chunk instead of hanging the run. It needs Python 3.11 or later and raises at construction below that. The five write-capable providers also acceptwrite_toolsto replace the default write sub-agent toolset. (#9104) - Wiki
GitBackendkeeps the PAT off disk: the token is injected per git call through an ephemeral credential helper instead of being baked into theoriginURL, and existing clones are rewritten to the bare URL on setup. This needs git 2.31 or later. (#9104) - Slack delivery options and safer approval cards: the Slack interface gains
markdown,unfurl_links, andunfurl_media, now sent explicitly on every message. Approval cards make backticks, newlines, and angle brackets in model-produced tool args inert so they cannot break out of the inline code span. (#9104) - Headless Google OAuth: Google toolkits accept
AuthConfig(interactive=False), orGOOGLE_OAUTH_NONINTERACTIVE=1, to raise instead of blocking on a browser OAuth flow that will never complete on a headless host. (#9104) - Schedule listing: new
ScheduleManager.list_all()andalist_all()page the whole schedule catalog and surface database errors instead of returning an empty catalog, backed by a newraise_on_errorargument onget_schedules. Listings now breakcreated_atties byid, so rows sharing a timestamp are no longer skipped or duplicated across pages. (#9104) - Moonshot and OpenRouter reasoning:
MoonShot(Kimi) gains sync, async, and streaming reasoning handlers that readreasoning_content, andOpenRouteris routed through the OpenAI reasoning path. Previously both were picked up only when their id happened to containdeepseek-r1orminimax-m2/m3. (#8616) - MCP configs scoped down to zero tools now warn:
MCPConfiglogs a warning at construction when the default tools are on butinclude_tags/exclude_tagsscope out every tag and no customtoolswere passed — the config that boots a/mcpendpoint listing nothing. The config is still accepted and the resolved tool surface is unchanged. (#9748)
Bug Fixes
CodeMode(allow_shell=False)on IPython 9.17: IPython 9.17 registers script magics lazily and recreates them on lookup, so removingbashfrom the cell-magic table no longer disabled it —%%bashstill ran in a kernel configured to forbid shell access. The kernel now materialises the script-magic provider first and dropsbashfrom both the lazy table and the live registry, so loading a sibling magic such as%%shcannot re-register it.- Registry MCP toolkits from standalone processes:
StudioToolsnow connects an unconnected registry MCP toolkit on demand while resolving tools, so creating or editing a component from a script, notebook, or eval run no longer fails with "Toolkits have no functions and cannot be persisted".eval.suite.cli/aclitake a newmcp_tools=[...]argument that connects those toolkits before the cases run, andMCPToolboxclears its client state onclose()and on a failed filter so a reconnect re-appliestoolsets/tool_name. (#9845) - Executor errors in streaming workflow steps: when a
Step'sAgentorTeamexecutor failed mid-stream, the streaming paths treated the error event as a finished step and emitted an emptyStepOutputwithsuccess=True.Step.execute_streamandStep.aexecute_streamnow raise aRuntimeErrornaming the step and its executor, so the failure goes through normal step error handling and the resultingStepOutputcarriessuccess=Falseand the error text. Failing streaming steps are now retried like any other step failure. (#9138, fixes #7185) - Truncated tool arguments in the paused-run panel: the human-in-the-loop panel built its argument list with
rstrip(", "), which strips a set of characters rather than a suffix and so also ate trailing commas and spaces belonging to the last argument's own value. All three blocks now join arguments the wayformat_tool_callsalready did. This is display-only; the arguments passed to the tool were never affected. (#9246, fixes #9248)
Cookbooks
- Cookbook examples that pinned
gpt-4o,gpt-4o-mini, orgpt-5.4-mininow usegpt-5.6-luna, across 355 files. Gateway examples were rewritten too, soLiteLLM,OpenRouter,AzureOpenAI,AzureAIFoundry,CometAPI,Requesty,LangDB, andAIMLAPIexamples depend on that gateway or Azure deployment resolvinggpt-5.6-luna. Specialized ids and dated snapshots are unchanged. (#8939)