NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #2937 most downloaded on PyPI
The programming language for agentic software.
Last release 2 days ago
02 Oct 2026
Ships on a steady schedule
a new release about every 9 days
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
266 releases · first in 2024
One column per month.
Live progress & cancellation for page sync: Knowledge.stream_sync_pages() / astream_sync_pages() yield typed PageSyncProgress snapshots plus one termi
Knowledge.stream_sync_pages() / astream_sync_pages() yield typed PageSyncProgress snapshots plus one terminal SyncReport, and sync_pages / async_sync_pages accept an on_progress observer. A workflow function step can now yield StepProgress(content=..., data=...) before its StepOutput, emitted as a native StepProgressEvent under the existing workflow run/step ID — AgentOS streams it over the existing workflow REST/SSE route, and AgentOSClient.run_workflow_stream() parses it. Cancelling a sync now actually reaches the work instead of draining to the end. (#10098)SyncReport.failed_paths lists the site paths of pages that failed to publish/delete (capped at the first 20, like errors; failed keeps the full count; defaults to () so existing callers/stored reports are unaffected). Logs now name the page and its cause chain, e.g. Page sync failed for /guides/setup.md (SyncFailed: sync_failed <- ConnectError: [Errno 104] Connection reset by peer), plus a new Page delete failed for … warning on the prune path. (#10729)Connection reset by peer. Each attempt previously consumed the entire 30s fetch deadline (leaving no time to retry) and retries were too short — both are fixed with a bounded per-attempt timeout and backoff. (#10730)partial even when every page indexed — and a partial result skips pruning, so removed pages stayed searchable indefinitely. Discovery now skips links to non-page files (.json, .yaml, .xml, .csv, .pdf, images/audio/video, archives, fonts — while keeping .js/.css as valid page names like /guides/node.js), and handles nested indexes, MDX code blocks and redirect aliases. Off-host page links still block pruning (by design). (#10726)Full Changelog: v3.1.0...v3.1.1
User Management / Authorization (RBAC): a new agno.os.authz package adds role-based access control to AgentOS — a role store, scope policy, audit log,
agno.os.authz package adds role-based access control to AgentOS — a role store, scope policy, audit log, user directory and an admin router, with pluggable authorization engines (a native engine plus a fine-grained fga engine). Scopes and auth middleware were extended to enforce it.agno.fs filesystem (DbFileSystem) with dedicated /filesystem routes (list/read/manage files) backed by an agno_fs table.agno_fs): v3.1 keys the filesystem table by (namespace, user_id, path), where user_id is the user partition ("" for the shared/no-user partition). A table created by an earlier release is refused with SchemaOutdatedError until upgraded — the re-key never runs automatically. Upgrade once, with the application stopped, using the script for your database (#10530):This affects you only if you use DbFileSystem. The table is managed by DbFileSystem (its own schema, buildable from a bare db_url), so it is deliberately not part of MigrationManager.
python libs/agno/migrations/migrate_filesystem_postgres.py # PostgreSQL
python libs/agno/migrations/migrate_filesystem_sqlite.py # SQLiteMCPConfig(tools=[...]) now publishes exactly the tools you list — both default_tools and lifecycle_tools default to False. Previously a tools=[...] config also served the built-in default tools (and the lifecycle continue_run / cancel_run).background + stream no longer duplicates the paused run in its own history.Nonevalued results from missing variables.\r) record endings.tail.generate_video artifact.get_file_content preserves valid non-ASCII UTF-8 texttest_encoded_sse_cannot_bypass_public_error_inspection test more robust by @sannya-singal in #10533Full Changelog: v3.0.11...v3.1.0
Vector DB Reranker : The reranker parameter on vector databases is deprecated in favour of the reranker on Knowledge , which applies to every vector d…
Knowledge.search() now runs a knowledge level retrieval pipeline that can widen the candidate pool before a reranker reorders it, so rerankers no longer need to be implemented per vector db.MMRReranker (Maximal Marginal Relevance) as a retrieval strategy that balances relevance against diversity so near-duplicate chunks do not crowd out the result set.Knowledge.inspect_page_source / ainspect_page_source and guarded migrate_page_source / amigrate_page_source to move an indexed documentation source to a new hostname. Migration is a dry run by default.RecencyReranker, which blends the search score with an exponential decay on a timestamp so newer revisions outrank superseded ones. Built on the knowledge level pipeline, focused on pgvector.PageCommandResult and PageFileSystem.run_command_result / arun_command_result with explicit error, completeness and truncation metadata. Knowledge.get_tools(page_results=True) returns ranked SearchResult objects, including as MCP structured output.YAPI as an OpenAI-compatible model provider.cancellation_stage (PENDING, EXECUTING, INTERRUPTED, or unknown) to RunOutput, TeamRunOutput, WorkflowRunOutput and the run API schemas, so clients no longer match on the cancellation message text.use_previous_response_id so store=True no longer forces automatic previous_response_id chaining.inputSchema, and get_sessions bounds limit and page to a minimum of 1.OpenAILike provider such as DashScope.Args entries from tool docstrings and corrected streaming docstring parameter names in two model classes.function_call(**arguments) now work in the async execution path. Previously the chain treated the unawaited coroutine as the tool result and the tool body never ran.mcp=True now installs the same routing layer as MCPConfig, so the Host check and mount prefix apply on both spellings. Dropped the unimplemented ETag / If-None-Match CORS headers.ClientSession now collects every tools/list page instead of only the first.ag-ui-protocol 1.0, including list-valued tool result content on resume.page_size before reading, so zero or negative values raise ValueError instead of silently returning no documents..pptx text.read_yaml_file / write_yaml_file, AntigravityTools and AirflowTools now read and write files as UTF-8 regardless of locale.reranker parameter on vector databases is deprecated in favour of the reranker on Knowledge, which applies to every vector db and supports async.Full Changelog: v3.0.10...v3.0.11
Azure OpenAI Responses : Added AzureOpenAIResponses to use the Responses API with Azure OpenAI deployments. See cookbook .
AzureOpenAIResponses to use the Responses API with Azure OpenAI deployments. See cookbook.Elasticsearch vector database with vector, keyword and hybrid search. See cookbook.transform for Knowledge.sync_pages that converts Mintlify and Fumadocs components into plain Markdown. See cookbook.root_host, path and path_aliases to serve MCP on a dedicated hostname or a custom endpoint path./mcp/server-card now returns pretty-printed JSON.AudioContent from MCP tool results as audio artifacts.event_id instead of dropping them.RemoteAgent.role and RemoteTeam.role are now properties that return the role instead of a bound method; use .role, not .role().TextReader, MarkdownReader and FieldLabeledCSVReader now accept text streams.async_read() now uses the chunking strategy's async achunk().async_read() keeps every data row across pages with RowChunking(skip_header=True).myindex.html intact and continue discovery past an invalid .xml.gz sitemap.0, False and [] in sync tool results and Parallel workflow step outputs.agno connect now reads and writes client configs as UTF-8 (agnoctl 0.2.1).BOOL values.run_shell is now opt-in (enable_run_shell=True), and restricted mode runs commands without a shell.authorization=True and PublicSurface(mcp=True), MCP now accepts only localhost by default; add your domain to MCPConfig(allowed_hosts=[...]).Full Changelog: v3.0.9...v3.0.10
fix: clean startup logs and initialize durable queue storage by @ashpreetbedi in #10071
Full Changelog: v3.0.8...v3.0.9
Complete page reads: Knowledge.read_full_page and aread_full_page return an entire published page from one bounded SQL read and read-only snapshot. Bo
Knowledge.read_full_page and aread_full_page return an entire published page from one bounded SQL read and read-only snapshot. Both support revision pinning, character limits and deadlines. Oversized pages return None; missing or changed pages retain typed errors. Calls share the existing eight-slot page-read worker pool. (feat: add bounded full-page reads and shared fence tracking #10063)create_postgres_engine and create_async_postgres_engine expose Agno's connection-pool and JSON serialization defaults with configurable SQLAlchemy options. Plain postgres:// and postgresql:// URLs select Psycopg 3 in these new factories; explicit drivers and TLS settings are preserved. Existing database constructor driver selection is unchanged. (feat: add PostgreSQL engine factories with shared defaults #10062)agno.utils.markdown.advance_code_fence exposes the page chunker's fence rules for application transforms that need to preserve code examples. A full-page cookbook demonstrates reads and prose normalization. (feat: add bounded full-page reads and shared fence tracking #10063)upsert_sessions() in SqliteDb / AsyncSqliteDb now applies the same owner check as the single-row upsert_session() — previously a batch containing another user's session_id would reassign the row and overwrite its data. Rows the predicate refuses are omitted from the returned list, matching Postgres and the single-row path. (#9937)MCPConfig(tools=[custom_function], default_tools=False, stateless=True) now work without an unnecessary lifecycle_tools=False override. Public exposure of agents, teams or workflows still requires disabling the automatically added lifecycle tools with lifecycle_tools=False or exclude_tags={"lifecycle"}. (fix: validate effective public MCP lifecycle tools #10060)Full Changelog: v3.0.7...v3.0.8
Page storage in agno.knowledge.page . Knowledge atomically publishes catalog metadata, filesystem text and vectors, preserves previous revisions when
agno.knowledge.page. Knowledge atomically publishes catalog metadata, filesystem text and vectors, preserves previous revisions when a refresh fails, and exposes bounded sync and async setup, source synchronization, search, read, list and grep APIs. Installed through the new agno[pages] extra. (#9963)
Knowledge(page_search=PageSearchConfig(...)) provides typed, transaction-local planner controls. Unset scan preferences, costs, worker counts and thresholds inherit the PostgreSQL settings.PublicSurface for public serving: serves selected Agents, native stateless MCP and authenticated durable-sync Workflows, with shared quotas, request and output bounds, CORS and internal-service authentication. (#9963)
PageFileSystem(knowledge=...): a bounded read-only page filesystem toolkit with sync and async execution, exposed explicitly through files.tools(). Commands read pages lazily against pinned revisions, list scoped metadata and run bounded literal grep; they cannot execute a shell or write files. (#9997)run_input and session, alongside the existing agent and run_context. Resolution runs before pre-hooks and reuses successful values on model retries. add_dependencies_to_context still defaults to False. (#9963)agno.models.aimlapi.AIMLAPI_HEADERS and overridable per model via default_headers, where caller-supplied keys win. The headers carry no user data and do not affect routing, model selection or billing. The default model also moves from the retired gpt-4o-mini to gpt-5.6-terra. (#9898)StepError for both raised executor failures and explicitly failed outputs, carrying the current step's identity. Function reports are still preserved as StepOutput, and Agent, Team and nested Workflow content keeps its existing executor stream. Both console streaming printers render StepError explicitly, showing the original failure and clearing stale progress output. (#10001)ERROR to the database and leave its tracked stream stuck at PAUSED; fresh streaming failures yielded WorkflowError before the failed run was saved, so a consumer closing at that event could lose the run entirely. (#10001)
skip_on_failure is honored through the existing final-attempt policy and ordinary executor retries are preserved._format_message overrides had drifted from OpenAIChat, which passes compress_tool_results positionally, so each call raised TypeError: _format_message() takes 2 positional arguments but 3 were given. (#10031, #9898, fixes #9034)function.arguments for. Streaming and non-streaming parsing now serialize every tool input, so empty input becomes "{}". (#8970, fixes #8971)validate_call stores the caller's f_locals on the wrapper it builds and Function caches those wrappers for the life of the process, so on Python 3.13 every cached tool kept the wrapping frame alive along with the Agent, session and run state on the stack. The namespace resolver is cleared once the validators are built. (#9941, fixes #9940)ERROR and nested model diagnostics, and is now a safe 503 run_failed, matching the streaming error protection. Authenticated operator diagnostics are unaffected. (#9963)Knowledge constructor arguments are keyword-only. Positional calls such as Knowledge("docs") must become Knowledge(name="docs"). content_db is now the preferred spelling; contents_db remains a supported read/write alias sharing the same dataclass field, so serialization, copy and dataclasses.replace(..., contents_db=...) are unchanged. Passing both keywords requires the same object. (#9963)PgVector HNSW ef_search instead of silently forcing 200, so deployments that relied on the implicit 200 should set it explicitly. Page indexes built from interim main builds can carry an implicit ef_construction=64 and need an operator-managed rebuild; setup reports an actionable error rather than rebuilding automatically. (#9963)Full Changelog: v3.0.6...v3.0.7
Stateless MCP serving. MCPConfig(stateless=True) serves /mcp without session tracking, so any replica can answer any request and a multi-instance depl
MCPConfig(stateless=True) serves /mcp without session tracking, so any replica can answer any request and a multi-instance deployment needs no session affinity. Costs server-initiated notifications and SSE resumability, so it stays off by default. See cookbook.MCPTools(protocol_mode=...) selects which MCP protocol era to negotiate. Defaults to "legacy", preserving today's session-based behaviour; "auto" negotiates the newest era both sides support (sessionless from 2026-07-28). Existing servers are unaffected — a modern server still accepts the legacy handshake. Internally, MCP clients are now built on fastmcp.Client. See cookbook.GET /mcp/server-card, listing the served tools and carrying a configurable name, version and instructions..zip and .eml file uploads in AgentOS. See cookbook.AuthorizationConfig.excluded_route_paths marks custom routes public without disabling auth globally.image/jpeg.RunContext to remote entities.tree-sitter-language-pack<1.16 to unblock the chonkie code chunker.fastmcp.Client by @sannya-singal in #9927Full Changelog: v3.0.5...v3.0.6
Embedding failures are surfaced, not masked. Ingestion now reports embedding failures instead of returning success. Content that previously showed com
completed may now show failed or partial — those ingests were always incomplete, they were only reported as successful. The ContentStatus enum in the API (/openapi.json) gains partial, changing from ["processing","completed","failed"] to ["processing","completed","partial","failed"]. No schema migration is required (the status column is already varchar).EmbeddingError instead of returning an empty vector on failure. Calling a vector DB's search() directly now raises where it previously returned []; Knowledge.search() is unaffected and still returns no results.EmbeddingError, not ModelProviderError. Existing except ModelProviderError handlers around Bedrock embedding will stop catching — switch to except EmbeddingError.GET /knowledge/content/{id}/status returns 404 for missing/non-owned content instead of 200 with status: "failed".skip_if_exists=True no longer skips content recorded as failed or partial, so incomplete content is re-embedded rather than silently marked complete.partial content status: new ContentStatus.PARTIAL for files where some chunks embedded and others did not — searchable but incomplete, so neither completed nor failed. (#9814)Knowledge(max_embedding_retries=3, embedding_retry_backoff=1.0). Authentication failures ignore both settings and fail on the first attempt (the same credential is rejected every time). Note: each retry re-embeds the whole document.embed_before_replace guard embeds documents before deleting existing ones, so a failing re-ingest aborts before anything is removed (previously a failed re-embed could leave a document with zero chunks).MCPTools accepts static headers=: connect-time auth headers can be passed directly on the url= path for Streamable HTTP and SSE, without constructing StreamableHTTPClientParams.Full Changelog: v3.0.4...v3.0.5
KnowledgeManagementTools constructor flags renamed, ingest_path now opt-in : the 2.x-style enable_ingest / enable_remove flags are replaced by flags n
KnowledgeManagementTools constructor flags renamed, ingest_path now opt-in: the 2.x-style enable_ingest / enable_remove flags are replaced by flags named after the tools they register — ingest_url, ingest_path, ingest_text, remove_content (the old names are no longer recognised and are ignored if passed). ingest_path defaults to off: it reads any path the server process can read, and under scope="shared" what it loads becomes readable by every agent on that knowledge base, so registering it is now an explicit choice. list_content and ingest_status stay unflagged — they only read. (#9861)agno.tools.knowledge_management import path moved: KnowledgeManagementTools (introduced in 3.0.3) now lives at agno.tools.knowledge; the old module path is gone. from agno.tools.file_generation import FileGenerationTools keeps working through a compatibility shim. (#9861)agno.tools.file and agno.tools.knowledge are packages: FileTools and FileGenerationTools share agno.tools.file; KnowledgeTools (read side) and KnowledgeManagementTools (write side) share agno.tools.knowledge, following the agno.tools.mcp and agno.tools.finance layout. Names resolve on first access, so importing FileTools no longer pulls reportlab and python-docx in behind it — measured at 44.8 ms with both installed, previously paid on every FilesystemContextProvider import. (#9861)pow_workers argument, default min(4, cpu_count()), with pow_workers=1 matching the old sequential search exactly. Measured at difficulty 10: mean solve 25.9 s → 10.4 s on 4 workers. pow_timeout still bounds the search, and a worker that finds a solution wins over a concurrent timeout. (#9825)list_inbox returned the agent's own sent mail: send_email files the outgoing message in the inbox mailbox with $draft set, and list_inbox queried that mailbox unfiltered, so an agent could not tell its own outgoing mail from a reply. The query now filters notKeyword: "$draft", the parser drops any $draft entry, and a rejected query is reported as an error instead of an empty inbox. (#9825)requires_confirmation_tools dropped the remove_content gate: KnowledgeManagementTools set its confirmation list with setdefault, so passing your own list silently removed the built-in confirmation requirement on remove_content — the one tool in the kit that destroys data. The lists now union. (#9861)Per-page website ingestion : loading a website into a knowledge base now lands one content row per page, with each row's id equal to the content_id it
content_id its vectors carry, so pages can be listed, refreshed, and deleted individually. The parent row becomes the site row — named after the host, aggregating status ("9 of 10 pages loaded; failed: …"), and cascading deletes to every page and its vectors. Re-ingest is digest-driven: unchanged pages skip embedding entirely, changed pages replace only their own vectors, failed pages retry, and pages that left the sitemap are pruned. (#9856)SitemapReader: discovers a site's pages per the sitemap protocol — the URL itself, robots.txt Sitemap: lines, /sitemap.xml, /sitemap_index.xml, gzip and nested indexes — with canonical dedup and a max_pages cap. It is auto-selected for bare sitemap*.xml(.gz) URLs and registered in the reader factory, so it appears in the UI reader dropdown. Each page becomes one whole-page Document, chunked exactly once, and failed pages return as data rather than aborting the read. (#9856)PageFetcher: a fetch seam below the URL readers. HttpxPageFetcher fetches with bounded concurrency and a redirect guard; ParallelPageFetcher resolves Parallel's keyed SDK, then its keyless MCP endpoint, then plain httpx — honoring retry-after with exponential backoff, falling back per page, and recording per-page extractor and attempts provenance. (#9856)HttpxPageFetcher routes application/pdf responses — and %PDF- bytes served under a wrong content type — through PDFReader. A missing pypdf surfaces as a per-page error naming agno[pdf] rather than an exception through the read. (#9858)KnowledgeManagementTools: the write-side operator toolkit for knowledge bases — ingest_url, ingest_text, ingest_path (file or folder), list_content (grouped by site and folder), ingest_status, and remove_content (requires confirmation by default), with sync and async variants under the same tool names, JSON envelopes, and scope="shared"|"user". (#9856, #9858)GET /knowledge/content?parent_id= lists a site's or folder's rows with correct totals, and POST /knowledge/content/{id}/refresh re-runs a URL or path-sourced row's ingest in the background. (#9856, #9858)WebsiteReader crawls and LLMsTxtReader wrote per-URL vector groups whose content_id matched no contents row (#6054 follow-on), so deleting the row from the Knowledge page left every page's vectors behind. Per-page content rows now own those vector groups — existing groups are adopted without re-embedding — so both per-page and cascade delete remove them. (#9856)max_pages with entries remaining — the exact shape of POST /refresh — reported complete discovery, so reconciliation deleted every beyond-cap page row and its vectors. Cap truncation and never-opened index shards now mark discovery incomplete, which suppresses pruning and is reflected in the site status. (#9860)parent_id filtering: GET /knowledge/content?parent_id=… against a RemoteKnowledge silently dropped the filter and returned the full base as a filtered-looking response; it now returns 501, matching remote refresh. (#9860)chunk flag. (#9856)Run metadata precedence : metadata now resolves as component, then session, then call-site on Agent , Team , and Workflow , so a metadata= passed to r
metadata now resolves as component, then session, then call-site on Agent, Team, and Workflow, so a metadata= passed to run() wins over agent.metadata where the component value previously won. A run no longer assigns session metadata back onto the shared component, so code that read agent.metadata after a run to observe session values now sees the constructor value. The session layer only applies where the dispatch pre-reads the session, so Team.arun and the async-DB agent and workflow paths still resolve from component and call-site alone. (#9104)MCPConfig rejects unknown fields: MCPConfig/MCPServerConfig now raise on unrecognised keyword arguments at construction instead of ignoring them, so a typo such as tool= fails at boot rather than silently serving a different tool surface. (#9819)BaseRemote.acancel_run signature: the abstract method gained an auth_token parameter that the cancel surfaces pass by keyword, so a third-party BaseRemote subclass must accept it. (#9819)Gemini or Claude model 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-5 variants match on OpenAI and Azure OpenAI, Groq and Ollama match gpt-oss and qwen3, and Ollama's qwen2.5-coder is no longer treated as a reasoning model. (#8616)AgentOS(mcp=...), MCPConfig, and default_tools are the new spellings for mcp_server=, MCPServerConfig, and enable_builtin_tools. The old names keep working as aliases with removal targeted for 3.1; passing both spellings with different values raises. (#9819)Synthorai (agno.models.synthorai) talks to the Synthorai gateway over its OpenAI-compatible endpoint, reading SYNTHORAI_API_KEY and defaulting to https://synthorai.io/v1. It is registered in the provider lookup table, so model="synthorai:<model-id>" strings resolve as well. (#9788)WaveSpeedTools (pip install agno[wavespeed], key from WAVESPEED_API_KEY) generates media through the WaveSpeed API. generate_image and generate_video take a text prompt and return a ToolResult carrying Image/Video artifacts, polling synchronously within poll_interval and timeout. (#9620, fixes #9621)SerplyTools searches Google web, News, and Scholar through the Serply API, reading SERPLY_API_KEY. Web search is on by default; search_news, search_scholar, or all=True enable the others. A missing key or failed request returns an error field instead of raising. (#9780, fixes #9779)AtomicMailTools gives an agent its own inbox. register_inbox provisions one through AtomicMail's proof-of-work signup with no domain setup or human verification, and send_email and list_inbox work over JMAP. Credentials are cached to ~/.atomicmail/credentials.json so later runs reuse the same inbox, and pow_timeout (default 300s) caps the solve. (#9130)MCPConfig.tools now accepts Agent, Team, and Workflow instances, remote proxies, and component factories, publishing each as its own named MCP tool — chief, rather than run_agent(agent_id="chief"). component.as_tool(name=..., description=...) publishes one under a name and description of your choosing. continue_run and cancel_run register alongside exposed components even with default_tools=False, so a run that pauses on a confirmation stays resumable over MCP. (#9819)MCPConfig.tools now accepts a Toolkit and publishes one MCP tool per registered method, narrowed by the toolkit's own enable_*/include_tools/exclude_tools, where it previously raised TypeError. Framework parameters (RunContext, Agent, Team, and the _agno_* channels) are kept out of the client-facing schema and filled server-side. A tool returning a ToolResult is rendered as MCP content blocks — text, image and audio, embedded resources for video and file bytes, and resource_link for url-only artifacts. A **kwargs entrypoint, which previously took get_app() down, now publishes its declared schema or its named parameters. (#9846)as_tool() and @tool/Function now accept title and annotations, 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 assert readOnlyHint: False, destructiveHint: True, openWorldHint: True by default, with your overrides merged per key. Unknown annotation keys raise rather than travelling to the client. (#9844)query_timeout and write_tools: every context provider accepts query_timeout, a wall-clock deadline applied to each query_<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 accept write_tools to replace the default write sub-agent toolset. (#9104)GitBackend keeps the PAT off disk: the token is injected per git call through an ephemeral credential helper instead of being baked into the origin URL, and existing clones are rewritten to the bare URL on setup. This needs git 2.31 or later. (#9104)markdown, unfurl_links, and unfurl_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)AuthConfig(interactive=False), or GOOGLE_OAUTH_NONINTERACTIVE=1, to raise instead of blocking on a browser OAuth flow that will never complete on a headless host. (#9104)ScheduleManager.list_all() and alist_all() page the whole schedule catalog and surface database errors instead of returning an empty catalog, backed by a new raise_on_error argument on get_schedules. Listings now break created_at ties by id, so rows sharing a timestamp are no longer skipped or duplicated across pages. (#9104)MoonShot (Kimi) gains sync, async, and streaming reasoning handlers that read reasoning_content, and OpenRouter is routed through the OpenAI reasoning path. Previously both were picked up only when their id happened to contain deepseek-r1 or minimax-m2/m3. (#8616)MCPConfig logs a warning at construction when the default tools are on but include_tags/exclude_tags scope out every tag and no custom tools were passed — the config that boots a /mcp endpoint listing nothing. The config is still accepted and the resolved tool surface is unchanged. (#9748)CodeMode(allow_shell=False) on IPython 9.17: IPython 9.17 registers script magics lazily and recreates them on lookup, so removing bash from the cell-magic table no longer disabled it — %%bash still ran in a kernel configured to forbid shell access. The kernel now materialises the script-magic provider first and drops bash from both the lazy table and the live registry, so loading a sibling magic such as %%sh cannot re-register it.StudioTools now 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/acli take a new mcp_tools=[...] argument that connects those toolkits before the cases run, and MCPToolbox clears its client state on close() and on a failed filter so a reconnect re-applies toolsets/tool_name. (#9845)Step's Agent or Team executor failed mid-stream, the streaming paths treated the error event as a finished step and emitted an empty StepOutput with success=True. Step.execute_stream and Step.aexecute_stream now raise a RuntimeError naming the step and its executor, so the failure goes through normal step error handling and the resulting StepOutput carries success=False and the error text. Failing streaming steps are now retried like any other step failure. (#9138, fixes #7185)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 way format_tool_calls already did. This is display-only; the arguments passed to the tool were never affected. (#9246, fixes #9248)gpt-4o, gpt-4o-mini, or gpt-5.4-mini now use gpt-5.6-luna, across 355 files. Gateway examples were rewritten too, so LiteLLM, OpenRouter, AzureOpenAI, AzureAIFoundry, CometAPI, Requesty, LangDB, and AIMLAPI examples depend on that gateway or Azure deployment resolving gpt-5.6-luna. Specialized ids and dated snapshots are unchanged. (#8939)Faster agent runs with many tools : Tool schemas are now derived once and cached across runs, cutting per-run overhead for agents that carry large too
PubmedTools now accepts a timeout and passes it to both NCBI E-utilities requests, so a stalled PubMed response cannot hold a tool call indefinitely. (#9463)properties: Function.process_schema_for_strict no longer raises KeyError on schemas that omit properties (for example MCP server schemas registered verbatim). (#9578, fixes #9409)FunctionResponse.parts for Gemini 3 and later models instead of being emitted as sibling inline_data parts; legacy models keep the previous representation. URI-backed response media on Vertex AI is only sent when the MIME type is supported. (#9647)agno.utils.location used the undeclared requests package, so add_location_to_context=True raised ModuleNotFoundError without extras installed. It now uses httpx. (#9793, fixes #9772)ScheduleManager cleanup: close() tolerates a partially constructed manager (for example after a failed deepcopy), so garbage collection no longer raises AttributeError on a missing _pool. (#9792)properties in strict mode (#9409) by @Anai-Guo in #9578Full Changelog: v3.0.0...v3.0.1
Groq : replaced deprecated llama-3.3-70b-versatile with openai/gpt-oss-120b .
⚠️ Breaking release. A database migration is required before v3.0 serves traffic. Read the v3 Migration Guide first, and see the full v3.0 Changelog for every change.
Agent(offload_tool_results=True) / Team(...) writes any tool result over 16,000 chars to AgentFS and leaves a short envelope (preview, size, result_id) in the message; the agent gets read_result / search_result (+ async) to fetch the rest. No model call on the write path. Tune via ResultStore(threshold_chars=..., ttl_seconds=...). (#9436, #9684)media_storage=S3MediaStorage(bucket=...) on an Agent/Team/Workflow uploads images, audio, video and files to local disk, S3 or GCS before persistence; the row keeps a small MediaReference instead of base64 (a 113 KB JPEG drops from ~151,000 chars to 2,897). No schema change. (#9340) DocsCodeMode(tools=[...]) swaps a wide tool schema for one programmable IPython kernel that persists across a session — the model writes Python and calls tools as awaitable handles, composing them (variables, loops, helpers) without round-tripping through the transcript.agno_runs with real columns (session_id, run_type, agent_id, team_id, workflow_id, user_id, parent_run_id, status, run_index) + JSON payload. Takes session write amplification from O(N²) to O(N) and removes the DynamoDB/Firestore item-size ceiling. session.get_messages(), get_chat_history(), db.get_session() and AgentOS session routes are unchanged (runs re-attach on read). (#8350)
db.get_run(), db.get_runs(session_id=..., status=..., limit=..., page=...), db.upsert_run(), db.delete_run(), db.delete_runs() (sync + async); db.get_session(runs_limit=N) and db.get_sessions(include_runs=False). (#8350)MigrationManager(db).up() creates the runs store and copies legacy runs across, non-destructively and idempotently, on 12 sync + 4 async backends; un-migrated DBs still work (reads merge runs table with legacy blob). Schema versions tracked on every adapter. (#8350)MigrationRequiredError / SchemaMismatchError name both remedies; AgentOS carries error_id: "migration_required_error" in the JSON body. (#9669, #9631)agno_runs, agno_jobs (durable background queue), agno_tool_results (offload index) — all auto-created.AgentOS(queue=QueueConfig(durable=True)) — accepted runs are committed rows that survive crashes/restarts/deploys, executed by any replica. Bounded concurrency (default 32, AGNO_BACKGROUND_MAX_CONCURRENCY), cancellable while queued, Idempotency-Key dedupe, 429 on full queue. Queue REST surface (GET /queue/jobs, .../{job_id}, POST .../requeue, GET /queue/stats). Redis is optional coordination, never truth. (#9079, #9504)create_* writes a DRAFT that serves nobody until publish_component; compare-and-set guards (typed 409s), tombstoned deletes, archive/restore, dependent-tracking. StudioTools returns a machine-readable envelope ({ok, status, data, error{...}, warnings}) across ~31 tools. (#9604)id used by AgentOS to reference tools.gpt-oss-120b (was llama-4-scout-17b-16e-instruct). (#9244)llama-3.3-70b-versatile with openai/gpt-oss-120b. (#9588)reasoning_effort, reasoning_summary, service_tier, verbosity accept the full API value set (widened types; no call breaks).anthropic 1.0.0 (#9686): SDK-compat update for Claude modelsEvery 2.x user must read this. A database migration is required before v3.0 serves traffic.
agno_runs. Run MigrationManager(db).up() (or AgentOS POST /databases/all/migrate) before serving. The v2→v3 migration preserves the legacy runs column as a backup; reclaim it with db.cleanup_legacy_runs_column() (SQL) / db.cleanup_legacy_runs_field() (document/KV) after verifying.page without a limit (or page < 1) now raises ValueError instead of returning unbounded/negative results.secret_key removed from JWTMiddleware and authorization_config — use verification_keys (a list).GET /models removed (model data moved to GET /config under available_models); GET / returns a minimal landing response; GET /info is the single unauthenticated metadata endpoint.AgentOS(enable_mcp_server=..., mcp_config=...) removed — pass a single mcp_server= instead.db on the component (returns 400 without one). External-framework agents (LangGraph, Claude, DSPy, etc.) stream inline for background=true and are not resumable.enable_user_memories → update_memory_on_runsearch_session_history → search_past_sessionsnum_history_sessions → num_past_sessions_to_searchnum_past_session_runs → num_past_session_runs_in_searchreasoning=True removed — set reasoning_model=<native reasoning model> explicitly.continue_run / acontinue_run: updated_tools removed — pass requirements (list of RunRequirement from the paused run output).enable_agentic_culture, add_culture_to_context, CulturalKnowledge, culture tools, and the agno_culture table. Use Knowledge for shared cross-user info.Workflow constructor is keyword-only: Workflow(name=..., steps=[...]). Team is unchanged — Team([agent_1, agent_2]) still works, though Team(members=[...]) is preferred.requires_confirmation, confirmation_message, on_reject, requires_user_input, user_input_message, user_input_schema, requires_output_review, output_review_message, requires_iteration_review, iteration_review_message, on_error, hitl_max_retries, hitl_timeout, on_timeout). Use human_review=HumanReview(...) (from agno.workflow.types); names unchanged except hitl_max_retries → max_retries, hitl_timeout → timeout.MultiMCPTools deleted (along with allow_partial_failure) — use one MCPTools per server.MCPToolbox: auth_tokens / auth_headers removed — use auth_token_getters.DuckDuckGoTools.duckduckgo_search → web_search, duckduckgo_news → search_news (now built on WebSearchTools).agno.tools.gmail, googlesheets, googlecalendar, google_maps, google_drive, google_bigquery) — import from agno.tools.google.*.creds_path / auth_port → credentials_path / oauth_port; Sheets enable_read_sheet etc. → bare method names.FileTools.check_escape → Toolkit._check_path (LocalFileSystemTools.check_escape unaffected).SQLTools: enable_list_tables / enable_describe_table / enable_run_sql_query → bare method names.max_documents → max_results.StudioTool alias removed — use StudioTools.BrightData.get_screenshot: unused output_path removed. PgVector.enable_prefix_matching removed (dead helper).Knowledge.add_content / add_content_async / add_contents_async removed → use insert() / ainsert() / ainsert_many().GDriveContextProvider renamed → GoogleDriveContextProvider.use_tantivy removed/ignored.user_id raises ValueError (directing you to the vector DB migration) instead of returning empty results.update_schedule is now allow-listed (only name, description, method, endpoint, payload, cron_expr, timezone, timeout_seconds, max_retries, retry_delay_seconds, enabled, next_run_at, disabled_reason); any other key raises ValueError. Ownership/provenance/lock state are no longer writable via the generic path. New provenance columns added by the v3.0.0 migration.name to (user_id, name). If duplicate schedule names exist across the same user, the migration aborts — deduplicate before migrating.eval_id → run_id (#9739): eval classes no longer carry eval_id; every run gets its own run_id. store_result_in_file renames the eval_id parameter to run_id, the {eval_id} placeholder in file_path_to_save_results templates is no longer accepted (use {run_id}), and POST /eval-runs returns the id the row was actually stored under (run_id). Re-runs no longer overwrite each other.mistralai v1 compatibility layer removed — agno[mistral] requires mistralai>=2.0.0 (and is back in the models extra).agno.models.metrics module and the Metrics alias removed → import from agno.metrics (RunMetrics).Model.classify_error removed → use ModelProviderError.classify(error).namespace="user" is now isolated per user (row keys embed a user_id digest); pre-v3 rows re-keyed by the v3.0.0 migration (agno.learn.migrations.rekey_user_entity_learnings); EntityMemoryStore.delete/get require a keyword-only user_id in that namespace.MemoriesConfig → UserMemoryConfig; MemoriesStore → UserMemoryStore; Decision → DecisionLog.knowledge_retriever(dependencies=...) → prefer run_context. A retriever whose signature still names dependencies keeps working via an explicit backward-compat branch; run_context wins when both are present.system:read / system:write → config:read / config:write. The old names remain valid aliases and existing tokens keep working.RedisDB (vector DB) → RedisDb. Note RedisVectorDb is also still exported, to disambiguate from the agno.db.redis storage adapter.Docs: Step-by-step guide, database migration, and a paste-into-your-coding-agent prompt
import asyncio
from agno.db.migrations.manager import MigrationManager
# Step 1: run before serving v3.0 traffic (up() is async)
asyncio.run(MigrationManager(db).up())
# Step 2: VERIFY the runs landed before any cleanup
assert len(db.get_runs(limit=5)) > 0, "Migration copied nothing - do NOT clean up"
# Step 3 (optional, destructive): reclaim the legacy blob column.
# The migration preserves it as a backup, so force=True is required.
db.cleanup_legacy_runs_column(force=True) # SQL adapters
# db.cleanup_legacy_runs_field(force=True) # document / KV adaptersOn AgentOS: POST /databases/all/migrate. Full details in the v3.0 changelog docs.
llama-3.3-70b-versatile with openai/gpt-oss-120b by @sannya-singal in #9588Full Changelog: v2.9.0...v3.0.0
test: stop three suites reading state they do not control by @ashpreetbedi in #9736
Full Changelog: v3.0.0a4...v3.0.0a5
feat: run SqliteDb in WAL journal mode and restore the durable benchmark row by @ashpreetbedi in #9707
Full Changelog: v3.0.0a3...v3.0.0a4
fix: keep a workflow session's runs to its own runs by @harshsinha03 in #9634
Full Changelog: v3.0.0a2...v3.0.0a3
chore: remove deprecated enable_user_memories , search_session_history , num_history_sessions and num_past_session_runs params by @sannya-singal in #7…
enable_user_memories, search_session_history, num_history_sessions and num_past_session_runs params by @sannya-singal in #7834human_review=HumanReview(...) by @sannya-singal in #8354llama-3.3-70b-versatile with openai/gpt-oss-120b by @sannya-singal in #9588Full Changelog: v2.9.0...v3.0.0a2
Nothing published for this version
StudioRunnerTools : New identity-aware dispatch toolkit ( agno.tools.studio_runner.StudioRunnerTools ) that splits execution out of StudioTools . Any
agno.tools.studio_runner.StudioRunnerTools) that splits execution out of StudioTools. Any component (team lead, router) can mount it to discover and run Studio-built agents/teams/workflows without getting the Studio's create/edit/delete surface. run_* tools thread the caller's user_id into the sub-run so per-user state lands on the right person.list_components name filter: Added a name filter to list_components.tool_name override blocked (Security): MCP tool entrypoints no longer allow a call-time tool_name override. Previously a model could pass tool_name="delete_repo" to any MCP tool and the server would execute that tool while allow-lists, requires_confirmation, HITL approval, and logging all resolved from the declared name — bypassing any HITL/approval gate. The executed tool name is now closed over from tool.name. Model-supplied tool_name args are forwarded as ordinary arguments (not used to pick the tool), so tools that legitimately declare a tool_name parameter keep working.cache_results=True, the cache key now includes stable run-context identity (user_id, session_id), fixing a cross-user cache leak where a cached tool taking run_context (e.g. MemoryTools) served one user's result to another. run_id stays out of the key so caching remains useful across a user's runs. Existing cache behaviour changes — keys are composed differently, so prior cache hits won't line up the same way.[], a team lost members, schemas/knowledge dropped) and then run. Unresolvable references now raise ComponentRehydrationError (an AgnoError, status_code=422) on strict paths. Strictness is a caller property: public from_dict/load default strict=False (round-trips keep working), but AgentOS lookups and every dispatch path (REST POST /runs, continue, MCP run tools, StudioRunner) default strict=True and now return a 422 naming the unresolvable piece instead of running a degraded component. Pinned member versions are also honored.Full Changelog: v2.8.7...v2.9.0
AdvisorTools : Added AdvisorTools for asking advisor models for feedback.
AdvisorTools for asking advisor models for feedback.OpenRouteService toolkit for accurate routing.FileSystemTools toolkit name.tool_execution on requirement deserialization.label.nltk 3.10.1, which breaks the unstructured import chain.Full Changelog: v2.8.6...v2.8.7
Smallest AI : Added SmallestTools , a text-to-speech toolkit for Smallest AI with text_to_speech (returns audio as a ToolResult artifact, optionally s
SmallestTools, a text-to-speech toolkit for Smallest AI with text_to_speech (returns audio as a ToolResult artifact, optionally saved to disk) and get_voices. Supports the lightning_v3.1 and lightning_v3.1_pro models.GET /metrics/refresh/status to observe background metrics refreshes:
idle, running, completed or failed with started_at, finished_at and error, so clients can poll for completion instead of timing out silently. The state updates even when a refresh finishes without writing new data.AgentOSClient.get_metrics_refresh_status()OpenSearch vector database support (agno.vectordb.opensearch) with vector, keyword and hybrid search in both sync and async variants, installable via the agno[opensearch] extra. Includes cookbook examples and a run_opensearch.sh script for local setup.POST /metrics/refresh no longer blocks uvicorn workers on large datasets:
calculate_metrics() call now runs in the threadpool, so other requests keep flowing during a refresh. Same 200 + metrics list response as before.?background=true query param returns 202 immediately and runs the refresh as a background task. Background refreshes are single-flight per database.GET /metrics with a sync BaseDb also moves its lazy refresh to the threadpool.open() calls now pass explicit encoding="utf-8", so JSON cache and config files written on one platform stay readable on another (Windows defaults to cp1252).Full Changelog: v2.8.5...v2.8.6
AgentOS Tools : Added AgentOSTools to report on AgentOS usage, latency, failures, schedules, evals, components, and pending approvals.
AgentOSTools to report on AgentOS usage, latency, failures, schedules, evals, components, and pending approvals.PostgresDb and SqliteDb.kimi-k3.use_thinking to toggle thinking mode.delete_by_metadata.reasoning_content across turns.Full Changelog: v2.8.4...v2.8.5
fix: serialize nested executor requirements by @pratikm778 in #9162
Full Changelog: v2.8.3...v2.8.4
cookbook: number the filesystem cookbook as 13_filesystem by @ashpreetbedi in #9156
Full Changelog: v2.8.2...v2.8.3
FileSystem (durable agent filesystem): A net-new state primitive — agents get a private, persistent filesystem with pluggable DB/local backends and fa
Full Changelog: v2.8.1...v2.8.2
TwelveLabsTools: Added support for Marengo video embeddings. See docs.
respond_to_other_agents flag for peer-agent communication.extraction_tool_call_limit to prevent infinite loops.stream_sub_agent_events supported across all providers.list_files now exposes its optional directory parameter in the tool schema, so agents can list a specific subdirectory directly.read() now supports CSV file paths passed as strings.google_search now targets the Scavio Google v2 API for proper localization and paging. See DocsFull Changelog: https://github.com/agno-agi/agno/compare/v2.8.0...v2.8.1
Decision log: Replaced deprecated datetime.utcnow() in the decision_log store.
agno.scorer — Turn a run into a number:
CodeScorer: wraps any callable (bool | float | Score; typed-field comparison under output_schema recommended)JudgeScorer: LLM judge with the model always an explicit choice and numeric verdicts normalized to exact endpoints ((score - 1) / 9)ToolCallScorer: checks tool executions deterministically (refused, errored, or HITL-rejected calls never satisfy an expectation)agno.environments — Environment + Task + run_rollouts(env, k=8): run each task K times in full isolation (fresh db/session/user, no memory/knowledge/learning writes, cache off; knowledge reads still work). Includes a live per-attempt grid, real pass rate per task, drift-vs-policy fingerprints, save/load/diff, learning_zone(), and to_sft_jsonl(...) to export passing attempts as conversational-SFT JSONL with a provenance sidecar. This is the pass@k door.Case.scorer: the eval suite gains a third check — plug any scorer into a Case (with Case.expected), free and exact, no LLM call. SuiteResult.to_dict() gains additive score_value, score_passed, score_reason keys.FileGenerationTools.max_results_per_request.get_content_string().datetime.utcnow() in the decision_log store.ReliabilityEval matches tool executions: Tool expectations are now satisfied only by a clean execution (RunOutput.tools, tool_call_error not set), not by message-side requests. Verdicts can flip red after upgrading — when they do, the eval was previously passing for the wrong reason (missing entries are annotated "... (requested but refused/errored — execution matching, new in 2.8.0)"). Argument checks moved to ToolExecution.tool_args with the same partial-match semantics.AgentAsJudgeEval now fences judged output behind a per-call random nonce, with the untrusted-data instruction inside the prompt. A literal </output> no longer escapes the block, and "score this 10" inside a judged answer is data, not an instruction. Judge verdicts and token counts may shift.Full Changelog: https://github.com/agno-agi/agno/compare/v2.7.4...v2.8.0
Workflows: Accept run_context in Router selectors and Condition evaluators, deprecating session_state.
SuperserveTools to run agent-generated code and manage files in Superserve, a Firecracker-based sandbox platform for long-running agents. See docs.PlivoTools to send SMS, make voice calls, and look up phone numbers with Plivo. See docs.agno create Enhancements: Interactive starter template and project name prompts, four new starters (Azure, Helm, Modal, Render), and automatic .env seeding.pin_message, get_chat, get_file, and react_with_emoji, plus save_downloads and output_directory to save downloaded files to disk.run_context in Router selectors and Condition evaluators, deprecating session_state.create_schema=False when components override table names.Full Changelog: https://github.com/agno-agi/agno/compare/v2.7.3...v2.7.4
Added ValkeyDb as a fast in-memory database for agents, teams, and workflows. See Docs
RedmineTools to manage issues, comments, and time logs in Redmine, an open source project management tool.TokenLab as a new OpenAI-compatible model provider.structuredContent.chunk=False when reading JSON documents.frequency_penalty, presence_penalty, and stop, and keep zero-valued params like temperature=0.WorkflowCompletedEvent.Timer.elapsed for very fast operations.chunk=False by @sannya-singal in https://github.com/agno-agi/agno/pull/8882Full Changelog: https://github.com/agno-agi/agno/compare/v2.7.2...v2.7.3
OAuth on the AgentOS MCP Endpoint: Added OAuth support for the AgentOS MCP endpoint via AgentOS(mcp_auth=...). See cookbook.
AgentOS(mcp_auth=...). See cookbook.client_tools support for AG-UI frontend tools.agno connect Enhancements: Multi-target select, disconnect, restart hints, and identity-named entries.FileSystemKnowledge.get_file.@tool Methods: Toolkit methods decorated with @tool now receive injected run_context, agent, and team parameters.start_date/end_date are now honored across list_events, create_event, and update_event.Full Changelog: https://github.com/agno-agi/agno/compare/v2.7.1...v2.7.2
Pre-release for live testing on agentos-railway (agno 2.7.2a4 + agnoctl 0.1.2a4, lockstep).
Pre-release for live testing on agentos-railway (agno 2.7.2a4 + agnoctl 0.1.2a4, lockstep).
Over v2.7.2a3:
form-action directive dropped) — fixes the built-in AS sign-in flow in browsers that enforce itclient_tools support (#8565)Pre-release for live testing on agentos-railway (agno 2.7.2a3 + agnoctl 0.1.2a3, lockstep).
Pre-release for live testing on agentos-railway (agno 2.7.2a3 + agnoctl 0.1.2a3, lockstep).
Over v2.7.2a2:
token_endpoint_auth_methods_supported) in its AS metadata — connector (claude.ai / ChatGPT) DCR compatibilityagno connect reads the OAuth signal from /info mcp.oauth instead of auth_modeagno connect honors exported PATs on open REST planes, fails dead-ends up front, and prints a readable connect reportPre-release for live testing on agentos-railway (agno 2.7.2a2 + agnoctl 0.1.2a2, lockstep).
Pre-release for live testing on agentos-railway (agno 2.7.2a2 + agnoctl 0.1.2a2, lockstep).
Over v2.7.2a1:
sa:* subjects rejected, refresh-token reuse detection, refined auth_mode reporting, typed mcp_auth: AuthProviderAGENTOS_MCP_SIGNING_KEY honored in the built-in AS example (env-pinned token key)from agno.os import * works without the mcp extra again (AgentOSBuiltinAuth left to lazy import)AgentOS(mcp_server=...) replaces enable_mcp_server + mcp_config (deprecated aliases kept, wire format unchanged)
Pre-release for live testing (agno 2.7.2a1 + agnoctl 0.1.2a1, lockstep).
Nothing published for this version
Service Accounts (PATs): Expose any AgentOS as a Model Context Protocol server and connect it to your coding agent in one command. uvx agno connect mi
uvx agno connect mints per-client tokens, writes the MCP config into each client, and verifies the handshake — no manual JSON config editing. Tokens are agno_pat_... machine identities: SHA-256-hashed storage, scoped per-user, revocable via agno tokens revoke, and enforced across every deployment mode.agno CLI): New CLI distributed as agnoctl on PyPI, invoked as agno. uvx agno connect provisions PATs and wires up coding-agent MCP clients in one command.
agno connect — discover an AgentOS, mint per-client PATs (--name for a shared token), write MCP config for Claude Code, Claude Desktop, Cursor, Codex, and ChatGPT, then verify each connection.agno tokens create/list/revoke — mint, inventory, and rotate PATs.agno create — scaffold a new AgentOS project from a template (agentos-<provider>).agno up/down/restart/status — lifecycle management for local AgentOS deployments.agno.eval package: Case, run_cases, and CLI runner with team subjects and numeric judge scoring.GET /info Discovery Endpoint: Reports agno_version, mcp: {enabled, path}, and auth_mode so external tooling (e.g. agnoctl) can discover an AgentOS's capabilities before touching it./mcp: get_agentos_config, run_agent, run_team, run_workflow, continue_run, cancel_run, get_sessions, get_session_runs. Trimmed run results (with result_mode="full" escape hatch), MCP progress notifications for long-running tools, HITL continue/cancel lifecycle.AuthMiddleware on the parent app covers REST, /mcp, and WebSocket transports — no more per-transport drift. JWTMiddleware is preserved as an alias for backward compatibility.check_route_scopes used identically by JWT, service-account, and MCP paths, with a data-driven get_resource_context_from_path (replacing hardcoded substring matches). Every MCP built-in tool maps onto its REST-equivalent route for scope checks.GET /traces/{trace_id} now enforces per-user ownership (returns 404 on mismatch, matching listing behavior)._add_auth_middleware no longer excludes A2A interface routes — Slack/Telegram/WhatsApp self-authenticate their own inbound requests, but A2A did not and was previously bypassing the single auth layer.get_agentos_config Db-List Deduping: The reported databases list is now deduplicated across agent/team/workflow db references.get_db Guard: Now raises a clear 400 "No database is configured on this AgentOS" when no db is registered, instead of raising bare StopIteration.MCPServerConfig(include_tags={"memory"}) now fails Pydantic validation. Users who relied on these tools must call REST endpoints instead.RunOutput shape must either handle the new trimmed shape or set result_mode="full" in MCPServerConfig.AgentOS(authorization=True) Without JWT Keys Fails Fast: Previously this configuration silently served an OPEN instance (JWT and anonymous requests fell through unauthenticated). Now raises ValueError at construction. Set JWT_VERIFICATION_KEY/JWT_JWKS_FILE env vars or pass verification_keys/jwks_file via authorization_config.AGENTOS_URL Env Var: Renamed from AGNO_OS_URL. Migration: update any environment or CI config that referenced the old name.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.22...v2.7.0
agno 2.7.0a7 + agnoctl 0.1.0a7.
agno 2.7.0a7 + agnoctl 0.1.0a7.
agno 2.7.0a6. agnoctl and agno-infra unchanged since a5.
agno 2.7.0a6. agnoctl and agno-infra unchanged since a5.
agno 2.7.0a5 + agnoctl 0.1.0a5.
agno 2.7.0a5 + agnoctl 0.1.0a5.
agno 2.7.0a4 + agnoctl 0.1.0a4. Eval suite runner (Case, run_cases, cli) in agno.eval, plus A2A authorization gating and self-scoped service-account p
agno 2.7.0a4 + agnoctl 0.1.0a4. Eval suite runner (Case, run_cases, cli) in agno.eval, plus A2A authorization gating and self-scoped service-account principals.
Third v2.7 alpha — agno 2.7.0a3 + agnoctl 0.1.0a3. Folds fastmcp into the agno[mcp] extra so AgentOS serves /mcp without a separate install. Service a
Third v2.7 alpha — agno 2.7.0a3 + agnoctl 0.1.0a3. Folds fastmcp into the agno[mcp] extra so AgentOS serves /mcp without a separate install. Service accounts (PATs), MCP interface v2, and agnoctl connect. See PR #8747.
Second v2.7 alpha — agno 2.7.0a2 + agnoctl 0.1.0a2. Service accounts (PATs), MCP interface v2, and agnoctl connect. See PR #8747.
Second v2.7 alpha — agno 2.7.0a2 + agnoctl 0.1.0a2. Service accounts (PATs), MCP interface v2, and agnoctl connect. See PR #8747.
Nothing published for this version
TwelveLabs Tools: Added TwelveLabsTools to analyze videos and generate multimodal text embeddings. See docs.
TwelveLabsTools to analyze videos and generate multimodal text embeddings. See docs.SofyaTools for search, extract, and research.SearchApiTools with Google, News, Images, and YouTube search.timeout to the base Toolkit and wired HTTP timeouts across tools; extended timeout support to more toolkits.ModelResponse.created_at per instance instead of at import time.save_dag_file and read_dag_file.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.21...v2.6.22
Read files via the enable_read_file flag.
LocalFileSystemTools:
enable_read_file flag.target_directory by default; set restrict_to_base_dir=False to opt out.StudioTool to StudioTools with a backward-compatible alias.get_last_run_output no longer returns None for Agent and Team subclasses.CancelledError during MCP reconnection and drop redundant build_tools.Reader(chunk=False) is set.CancelledError during MCP reconnection and drop redundant build_tools by @sannya-singal in https://github.com/agno-agi/agno/pull/8666Reader(chunk=False) and chunks docs by @sannya-singal in https://github.com/agno-agi/agno/pull/8708Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.20...v2.6.21
ClickhouseDB for Traces: Added support for ClickHouse for high-volume trace ingest and OLAP scans. See docs.
response.citations for OpenAIChat and OpenAILike providers.FastAPI >= 0.137 so get_routes() lists every route.supports_native_structured_outputs or supports_json_schema_outputs).quick_prompts to 3 per agent/team/workflow._meta and structuredContent from MCP tool results on ToolResult.metadata.step_id across concurrent runs while keeping it stable across pause/continue in HITL runs.Toolkit and Searxng no longer reuse a mutable default list across instances.OpenAIResponses to support Chat Completions–style json_schema output schemas.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.19...v2.6.20
Checkpointing: Added tool batch level checkpointing and unified /continue for regenerate and forking a run. Also added support for forking sessions. S
/continue for regenerate and forking a run. Also added support for forking sessions. See cookbooks.StudioTool for dynamic agent, team , workflow composition.GeminiInteractions is now lazily imported, so Gemini no longer requires google-genai 2.0.custom_patterns now accepts raw regex strings.get_supported_search_types()None scores.retry_with_guidance_limit after a retryable error.image field.Chat suffix for OpenAILike providers.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.18...v2.6.19
Preserve Registered Model Params on Reconstruction: Reuse the live registry model instance when rebuilding DB-stored agents/teams so connection params
azure_endpoint/base_url and credentials
survive instead of being dropped to None. (#8476)Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.17...v2.6.18
Resilient DB Component Loading: Isolate each agent/team load so one bad component is skipped instead of dropping all, fix model provider round-trip on
TuningEngines, and dedupe the catalog by model class. (#8461)(type, name, function set) so they collapse instead of accumulating duplicate registry entries. (#8450)xoxp-) for search_messages, which bot tokens can't call. (#8411)required rows aren't orphaned. (#8386)Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.16...v2.6.17
Support parallel-web >= 1.0 GA API in ParallelBackend: migrate web_search/web_extract to the top-level client and pin the floor to >=1.0
Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.15...v2.6.16
Custom, Scoped, Identity-Aware MCP Tools: The AgentOS MCP server (served at /mcp) is now a real extension point, configured through a single MCPServer
MCPServerConfig object. You can register custom tools (plain callables or Agno @tool/Functions), scope the built-ins (enable_builtin_tools=False, or filter with include_tags/exclude_tags), inject the authenticated caller identity into a tool (declare user_id and AgentOS supplies the JWT subject while hiding it from the client schema), gate calls with a one-line authorize function, and opt into built-in DNS-rebinding protection via allowed_hosts/allowed_origins. All with data, no custom middleware classes. Fully backward compatible: without mcp_config, all built-in tools register exactly as before.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.14...v2.6.15
Learnings CRUD on AgentOS: Added create, read, update, and delete endpoints for learnings on AgentOS.
json_object providers.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.13...v2.6.14
Sub-Agent Event Streaming: Sub-agent events from the context provider update tool now stream through to the parent run.
json_schema now handles Optional dataclass fields that have no declared type.MCPTools sessions are now closed in the call task.upsert=False inserts of the same document no longer collapse.DaytonaTools.upsert=False inserts of the same document don't collapse by @sannya-singal in https://github.com/agno-agi/agno/pull/8310Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.12...v2.6.13
HTML File Generation: Added HTML file generation support with example app.
drop_ratio_search and remove drop_ratio_buildClient.results() usage.IndexError when runs list is empty in from_dict.enable_agentic_state tool receives correct schema for dict params.ag-ui-protocol>=0.1.14 to prevent reasoning role validation error.Client.results() in ArxivReader by @sannya-singal in https://github.com/agno-agi/agno/pull/8261Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.11...v2.6.12
Parallel Web Task API & Monitor API Tools: Added tools for Task API and Monitor API integration for parallel web.
Manifest for per-entity AgentOS UI metadata configuration.v25.0.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.10...v2.6.11
Replace deprecated asyncio.get_event_loop() with get_running_loop() in embedders.
YouTools for You.com Search API integration.files field on RunCompleted event.google-interactions provider to model string parser.team/agent/run_context params.Attachment.read() instead of blocking requests.get in Discord client.time.sleep with await asyncio.sleep in _async_create_collection_and_scope.asyncio.get_event_loop() with get_running_loop() in embedders.CSVReader.async_read uses newline join to match sync read behavior.OpenAITools.transcribe_audio._acontinue_run_background_stream to prevent AttributeError on continue-run SSE.parser_model is set (Agent and Team); added parser_model guard to continue_run_dispatch and acontinue_run_dispatch.contents_db; removed deprecated Tantivy FTS, fixed Redis hset mypy error.fal.py.memory_topics signature mismatch across DB backends.ValueError in delete_session when called with async db.team/agent/run_context params by @sannya-singal in https://github.com/agno-agi/agno/pull/8066time.sleep with await asyncio.sleep in _async_create_collection_and_scope by @kratos0718 in https://github.com/agno-agi/agno/pull/8158OpenAITools.transcribe_audio (resource leak) by @kratos0718 in https://github.com/agno-agi/agno/pull/8161Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.9...v2.6.10
decision_log - drop deprecated `datetime.utcnow()`: Replaced with datetime.now(timezone.utc) to clear the Python 3.12 deprecation warning. (Closes #80…
resolved_by, resolved_at, etc.) via run_response.metadata["approval"]. Previously only status and resolution_data were exposed. Lives in metadata so it works uniformly across RunOutput / TeamRunOutput / future WorkflowRunOutput. (#7366, #8032)PgVector(prefix_match=True) was a silent no-op - it appended * then routed through websearch_to_tsquery, which ignores wildcards. Now routes through to_tsquery('tok:*') with proper tokenization, so partial queries like "ani" FTS-match "animal" as documented. New cookbook cookbook/07_knowledge/04_advanced/06_prefix_search.py shows the help-center typeahead use case. (#8048, #8051, #8052)to_tsquery(language, '') fallback with a literal ''::tsquery cast so behavior no longer depends on the parser tolerating empty input. (#8053)0.0 values due to bare truthiness checks. Switched to is not None so deterministic output works as intended. (#8009, fixes #8004)DEFAULT_READ_INSTRUCTIONS / DEFAULT_WRITE_INSTRUCTIONS from 157 lines to 27 by removing content already supplied by the toolkit-side instructions. Provider now owns role + safety; toolkit owns the technical reference. (#7982)datetime.utcnow(): Replaced with datetime.now(timezone.utc) to clear the Python 3.12 deprecation warning. (Closes #8030)>=1.6.7 to pick up the upstream language auto-detection fix; removed the temporary test workarounds from #7904. (#8012)FunctionCallSteps describe tools the autonomous loop runs inside the server-managed sandbox. Previously we surfaced them as local tool_calls, leading to Function <name> not found and follow-up 400 invalid_request errors. Gated the FunctionCallStep branch on self.agent is None for both streaming and non-streaming. Model path with user-declared tools is unchanged. (#8045)temperature=0 silently dropped: See Improvements. Every prior release silently fell back to API defaults (~1.0) when callers explicitly set 0. (#8009, fixes #8004)>=1.6.7 by @sannya-singal in https://github.com/agno-agi/agno/pull/8012Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.8...v2.6.9
Introduced PathSecurityError (FileGenerationSecurityError kept as deprecation alias). Bumped requires-python to >=3.9,<4.
AntigravityAgent (a BaseExternalAgent served through AgentOS with native sessions/streaming/UI) and AntigravityTools (a Toolkit that lets any Agno agent delegate a sub-task to a managed Antigravity sandbox).GeminiInteractions support for Google's managed agents — Deep Research (autonomous research with citations, background streaming with reconnect/last_event_id resume) and Antigravity (general-purpose agent in a managed Linux sandbox). New agent / agent_config / environment fields, per-agent forcing of background and store, and support for mcp_servers + file_search_store_names on the agent path.cookbook/data_labeling/ with 18 self-contained workflows covering text, image, audio, video, document, and composed (LLM-as-judge, quality review) labeling primitives.tool_choice="required", user_input echo, and clean termination via stop_after_tool_call=True.agno.utils.path_safety module with safe_join and safe_join_subpath. Hardened FileGenerationTools, SlackTools, Toolkit._check_path, agno.skills.utils.is_safe_path, and FileTools.check_escape against path traversal, symlink escape, control-char injection, Windows MagicDot, and Unicode normalization attacks. Introduced PathSecurityError (FileGenerationSecurityError kept as deprecation alias). Bumped requires-python to >=3.9,<4.ParallelMCPBackend now sends User-Agent: agno/<version> on every request so Parallel can attribute traffic to agno.available_models field from EvalsDomainConfig; the top-level AgentOSConfig.available_models is now the only supported source for the Evals UI dropdown.gemini-3-flash-preview to gemini-3.5-flash across the Gemini Interactions cookbooks.stream_steps → stream_events) that caused teams running via AG-UI to silently drop all intermediate streaming events (lifecycle, reasoning, tool calls, member delegations) for ~7 months.aiohttp>=3.7.3,<4 to the slack optional extra — AsyncWebClient imports aiohttp at module load, so pip install agno[slack] was broken for all Slack operations.incompleteSearch flag from GoogleDriveTools.search_files() so corpora="allDrives" callers can detect when Drive did not search every drive.generation_config passthrough field for advanced controls (top_k, presence_penalty, etc.) and fixed history handling — when previous_interaction_id is set, only the new turn is sent rather than replaying the full history. Now actually leverages server-side statefulness.server_tool_use and code-execution content blocks in message history so multi-turn server-tool flows no longer break across turns.redacted_thinking type literal (the SDK rejects redacted_reasoning_content), accepted both spellings on the streaming start event, added a dedup guard on round-tripped server tool blocks, made coercion failures visible via log_warning, and coerced non-block tool-result items to text.str(error) is empty or weak, preserving error context across invoke / invoke_stream / ainvoke / ainvoke_stream.n1n provider mapping in get_model() so Agent(model="n1n:...") model-string paths now resolve correctly.Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.7...v2.6.8
Gemini Interactions: Added a new GeminiInteractions model class that makes use of Googles new stateful interactions API
GeminiInteractions model class that makes use of Googles new stateful interactions APIallowed_hosts parameter to URL-fetching readers to restrict outbound fetches.async_insert.session_id / agent_id / team_id from being overwritten by a child agent's spans when both share a trace_id. Most visible when a Team uses a post-hook (e.g. @hook(run_in_background=True).acleanup_run if running in an async context.async_insert by @sannya-singal in https://github.com/agno-agi/agno/pull/7893allowed_hosts SSRF guard to knowledge readers by @sannya-singal in https://github.com/agno-agi/agno/pull/7892Full Changelog: https://github.com/agno-agi/agno/compare/v2.6.6...v2.6.7
Your coding agent can read these notes before it upgrades. Set up the MCP server →