github agno-agi/agno v3.0.0

3 hours ago

⚠️ 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.

New Features

  • Tool result offloadingAgent(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 offloadingmedia_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) Docs
  • CodeMode: CodeMode(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.
  • FinanceTools: One unified finance toolkit with swappable data providers.
  • RampRouter model: New model provider for Ramp Router (router.com).
  • SuperGrok OAuth: Device-code auth for the xAI model.
  • AtomicMail Toolkit: Adds an AtomicMail toolkit (AtomicMailTools) that gives an Agno agent its own email inbox

Database

  • Runs get their own table: each run is a row in agno_runs with real columns (session_idrun_typeagent_idteam_idworkflow_iduser_idparent_run_idstatusrun_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)
    • Direct run APIsdb.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)
    • One-line migrationMigrationManager(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)
    • Typed stale-DB errorsMigrationRequiredError / SchemaMismatchError name both remedies; AgentOS carries error_id: "migration_required_error" in the JSON body. (#9669#9631)
    • Three new tablesagno_runsagno_jobs (durable background queue), agno_tool_results (offload index) — all auto-created.

Per-user isolation

  • Extends beyond sessions to metrics, schedules, evals, knowledge, components, entity memory, and 17 vector databases. Metrics aggregate per user per day; unowned components/knowledge are shared (readable by all, editable by admin) so enabling isolation doesn't 404 pre-isolation building blocks. (#8245#8262)

AgentOS & Studio

  • Durable background executionAgentOS(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 .../requeueGET /queue/stats). Redis is optional coordination, never truth. (#9079#9504)
  • Studio 3.0 — governed catalogcreate_* 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)

Tools

  • MiniMax video generation tools. (#9529)
  • Toolkits now have a stable id used by AgentOS to reference tools.

Model Updates

  • Cerebras / CerebrasOpenAI default to gpt-oss-120b (was llama-4-scout-17b-16e-instruct). (#9244)
  • Gemini defaults updated to 3.7 Flash. (#9666)
  • Groq: replaced deprecated llama-3.3-70b-versatile with openai/gpt-oss-120b. (#9588)
  • OpenAIreasoning_effortreasoning_summaryservice_tierverbosity accept the full API value set (widened types; no call breaks).
  • Claude works with anthropic 1.0.0 (#9686): SDK-compat update for Claude models

⚠️ Breaking Changes

Every 2.x user must read this. A database migration is required before v3.0 serves traffic.

Storage & migrations

  • Runs are no longer a JSON blob in the sessions table — they live in 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.
  • Stale/unmigrated databases raise typed errors instead of silently misbehaving.
  • Paginationpage without a limit (or page < 1) now raises ValueError instead of returning unbounded/negative results.

AgentOS

  • JWTsecret_key removed from JWTMiddleware and authorization_config — use verification_keys (a list).
  • Metadata routesGET /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.
  • MCP server configAgentOS(enable_mcp_server=..., mcp_config=...) removed — pass a single mcp_server= instead.
  • Background execution requires a db on the component (returns 400 without one). External-framework agents (LangGraph, Claude, DSPy, etc.) stream inline for background=true and are not resumable.

Agents

  • Renamed params:
    • enable_user_memories → update_memory_on_run
    • search_session_history → search_past_sessions
    • num_history_sessions → num_past_sessions_to_search
    • num_past_session_runs → num_past_session_runs_in_search
  • reasoning=True removed — set reasoning_model=<native reasoning model> explicitly.
  • continue_run / acontinue_runupdated_tools removed — pass requirements (list of RunRequirement from the paused run output).
  • Culture feature removedenable_agentic_cultureadd_culture_to_contextCulturalKnowledge, culture tools, and the agno_culture table. Use Knowledge for shared cross-user info.

Teams & Workflows

  • The Workflow constructor is keyword-onlyWorkflow(name=..., steps=[...])Team is unchanged — Team([agent_1, agent_2]) still works, though Team(members=[...]) is preferred.
  • Flat HITL kwargs removed on Step/Steps/Loop/Condition/Router (requires_confirmationconfirmation_messageon_rejectrequires_user_inputuser_input_messageuser_input_schemarequires_output_reviewoutput_review_messagerequires_iteration_reviewiteration_review_messageon_errorhitl_max_retrieshitl_timeouton_timeout). Use human_review=HumanReview(...) (from agno.workflow.types); names unchanged except hitl_max_retries → max_retrieshitl_timeout → timeout.

Tools

  • MultiMCPTools deleted (along with allow_partial_failure) — use one MCPTools per server.
  • MCPToolboxauth_tokens / auth_headers removed — use auth_token_getters.
  • DuckDuckGoTools.duckduckgo_search → web_searchduckduckgo_news → search_news (now built on WebSearchTools).
  • Flat Google tool modules deleted (agno.tools.gmailgooglesheetsgooglecalendargoogle_mapsgoogle_drivegoogle_bigquery) — import from agno.tools.google.*.
  • Google toolscreds_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).
  • SQLToolsenable_list_tables / enable_describe_table / enable_run_sql_query → bare method names.
  • Seltzmax_documents → max_results; the legacy SDK path is removed (seltz>=1.2.0 required).
  • StudioTool alias removed — use StudioTools.
  • BrightData.get_screenshot: unused output_path removed. PgVector.enable_prefix_matching removed (dead helper).

Knowledge & Vector DBs

  • Knowledge.add_content / add_content_async / add_contents_async removed → use insert() / ainsert() / ainsert_many().
  • GDriveContextProvider renamed → GoogleDriveContextProvider.
  • LanceDBuse_tantivy removed/ignored.
  • Searching a pre-v3 vector table with a user_id raises ValueError (directing you to the vector DB migration) instead of returning empty results.

Scheduler

  • update_schedule is now allow-listed (only namedescriptionmethodendpointpayloadcron_exprtimezonetimeout_secondsmax_retriesretry_delay_secondsenablednext_run_atdisabled_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.
  • The schedules unique key changes from name to (user_id, name). If duplicate schedule names exist across the same user, the migration aborts — deduplicate before migrating.

Evals

  • eval_id → run_id (#9739): eval classes no longer carry eval_id; every run gets its own run_idstore_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.

Models & Learning

  • Mistralmistralai 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).
  • Entity memory under 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.
  • Removed learn aliases: MemoriesConfig → UserMemoryConfigMemoriesStore → UserMemoryStoreDecision → DecisionLog.

Deprecated (still working)

  • 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.
  • Scopessystem: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.

Migration quick-reference

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 adapters

On AgentOS: POST /databases/all/migrate. Full details in the v3.0 changelog docs.

What's Changed

New Contributors

Full Changelog: v2.9.0...v3.0.0

Don't miss a new agno release

NewReleases is sending notifications on new releases.