From 0e5e0b344d4e319cc8e9a9aadbe91d1bd1670a70 Mon Sep 17 00:00:00 2001 From: kausmeows Date: Tue, 18 Aug 2026 15:34:11 +0530 Subject: [PATCH 1/9] feat: v3 migration guide --- docs.json | 1 + other/v3-migration.mdx | 336 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 337 insertions(+) create mode 100644 other/v3-migration.mdx diff --git a/docs.json b/docs.json index 5a3d4dde0..e672e8b0b 100644 --- a/docs.json +++ b/docs.json @@ -4642,6 +4642,7 @@ { "group": "Migrations", "pages": [ + "other/v3-migration", { "group": "Agno v2 Migration", "pages": [ diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx new file mode 100644 index 000000000..b8de1c35c --- /dev/null +++ b/other/v3-migration.mdx @@ -0,0 +1,336 @@ +--- +title: Migrating to Agno v3.0 +sidebarTitle: Agno v3 Migration +description: Guide to migrate your Agno applications from v2 to v3. +--- + +If you have questions during your migration, we can help! See [Get Help](/get-help) for more information. + + + Want to migrate automatically? Jump to [Migrate with AI](#migrate-with-ai) for + a prompt you can paste into Claude, Cursor or any coding agent. + + +## Installing Agno v3 + +If you are already using Agno, you can upgrade to v3 by running: + +```bash +pip install -U agno +``` + +## Migrating your Agno DB + +v3.0 changes how session runs are stored. In v2, every session row held its full +run history as a single JSON blob in the `runs` column. In v3, each run is its +own row in a dedicated runs table (`agno_runs` by default), which removes the +write amplification and unbounded row growth of the blob design. + +The migration is built into Agno. No external script is needed: + +```python migrate_to_v3.py +import asyncio + +from agno.db.postgres import PostgresDb # or SqliteDb, MongoDb, RedisDb, ... +from agno.db.migrations.manager import MigrationManager + +db = PostgresDb(db_url="postgresql+psycopg://...") + +# Step 1: copy every run from the legacy blob into the runs table +asyncio.run(MigrationManager(db).up()) + +# Step 2: VERIFY the runs actually landed before any cleanup +runs = db.get_runs(limit=5) +assert len(runs) > 0, "Migration copied nothing - do NOT run cleanup" + +# Step 3 (optional, after verifying): reclaim the legacy blob storage +db.cleanup_legacy_runs_column() # SQL adapters +# db.cleanup_legacy_runs_field() # Mongo / Redis / Valkey / Firestore / Dynamo / JSON adapters +``` + +Notes: + +- The migration is **non-destructive and idempotent**: the legacy `runs` column + is preserved as a backup, and re-running the migration never duplicates runs. +- Reads keep working before, during and after the migration. Sessions merge the + runs table with any legacy blob, so an un-migrated session still shows its + history. +- `cleanup_legacy_runs_column()` refuses to run while legacy data is present + unless you pass `force=True`. **Only pass `force=True` after Step 2 passes.** + Cleanup permanently deletes the blob, which is the only copy of your history + if the migration did not actually copy it. +- Supported everywhere sessions are stored: Postgres, MySQL, SQLite, + SingleStore (+ async variants), MongoDB, Redis, Valkey, Firestore, DynamoDB, + SurrealDB, JSON, and GCS JSON. + +For the full storage design and per-adapter details, see the +[v3 storage migration guide](https://github.com/agno-agi/agno/blob/main/libs/agno/agno/db/migrations/V3_MIGRATION_GUIDE.md) +in the repository. + +## Migrating your Agno code + +Each section covers one breaking change, with before and after examples. + +### 1. Sessions and runs (denormalization) + +Reading sessions is unchanged. `session.runs` is still populated, now from the +runs table: + +```python v3_sessions.py +session = agent.get_session(session_id="s1") +session.runs # still works, loaded from the runs table + +# New: fetch runs directly, without loading the whole session +runs = db.get_runs(session_id="s1") +run = db.get_run(run_id="...") +``` + +If you queried the `runs` column of the sessions table directly (SQL, dashboards, +exports), point those queries at the runs table instead. After cleanup the +column no longer exists: + +```sql +SELECT run_id, run_data FROM agno_runs WHERE session_id = 's1' ORDER BY run_index; +``` + +### 2. Workflow HITL: flat kwargs → `HumanReview` + +Workflow primitives no longer accept flat HITL kwargs. All human-in-the-loop +configuration lives in one `HumanReview` object. + +This is how it looked in v2: + +```python v2_hitl.py +from agno.workflow.step import Step + +step = Step( + name="deploy", + executor=deploy, + requires_confirmation=True, + confirmation_message="Deploy to production?", +) +``` + +This is how it looks in v3: + +```python v3_hitl.py +from agno.workflow.step import Step +from agno.workflow.types import HumanReview + +step = Step( + name="deploy", + executor=deploy, + human_review=HumanReview( + requires_confirmation=True, + confirmation_message="Deploy to production?", + ), +) +``` + +Field mapping: every flat kwarg keeps its name inside `HumanReview`, except +`hitl_max_retries` → `max_retries` and `hitl_timeout` → `timeout`. This applies +to `Step`, `Steps`, `Loop`, `Condition` and `Router`. + +### 3. Removed `Agent` and `Team` parameters + +These deprecated parameters have been removed. Update them to their v3 names: + +| v2 (removed) | v3 | +|---|---| +| `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` | + +```python v3_agent_params.py +agent = Agent( + update_memory_on_run=True, + search_past_sessions=True, + num_past_sessions_to_search=3, +) +``` + +### 4. Reasoning requires an explicit model + +The `reasoning=True` shortcut has been removed. Pass a native reasoning model +explicitly: + +```python v2_reasoning.py +agent = Agent(model=OpenAIResponses(id="gpt-5.5"), reasoning=True) +``` + +```python v3_reasoning.py +agent = Agent( + model=OpenAIResponses(id="gpt-5.5"), + reasoning_model=OpenAIResponses(id="gpt-5.5"), +) +``` + +### 5. `Team` and `Workflow` constructors are keyword-only + +Positional arguments are no longer accepted: + +```python v2_team.py +team = Team([agent_1, agent_2]) +workflow = Workflow("my-workflow", steps=[...]) +``` + +```python v3_team.py +team = Team(members=[agent_1, agent_2]) +workflow = Workflow(name="my-workflow", steps=[...]) +``` + +### 6. User isolation: `user_id` across the platform + +With `user_isolation` enabled on AgentOS, data is now scoped per user across +**memories, knowledge, evals, metrics, schedules and vector databases**, in +addition to sessions. What this means for your code and data: + +- `user_id` columns were added to the schedules, schedule-runs and evals tables; + the built-in migration handles this. +- Metrics aggregate **per user**: the unique key changed from + `(date, aggregation_period)` to `(user_id, date, aggregation_period)`. + Deployments without isolation see the same single-row-per-date shape as + before; sessions without a `user_id` aggregate into a shared bucket. +- Vector database collections created before v3 have no per-user scoping. When + isolation is on, searching them with a `user_id` raises a `ValueError` telling + you to run the vector database migration. This is deliberate: an un-migrated + table fails loudly instead of silently returning empty results. + +### 7. Background execution and durable queues + +`background=True` on AgentOS is rebuilt around a durable job queue. In v2 it +spawned an unbounded `asyncio.create_task`, and a process death silently lost +every waiting and in-flight run. In v3: + +- Accepted requests are **committed rows** that survive crashes, restarts and + deploys; any replica's worker can execute them. +- Runs are **bounded** by a concurrency cap; excess submissions wait in the + queue in `pending` status instead of overloading the process. +- Every run can be watched (`stream=true` tails), resumed after a disconnect + (`/resume`) and cancelled from any replica. +- `Idempotency-Key` headers deduplicate resubmissions. +- Redis is optional **coordination** (live event streams, cross-replica + cancellation), never truth. A Redis fault degrades the live view; it cannot + lose or corrupt a run. + +Breaking implications: background execution requires a `db` on the agent +(enforced with a 400), run status now transitions `pending → running → +completed` (poll `GET /agents/{id}/runs/{run_id}` for the terminal state), and +external framework agents (LangGraph, Claude, etc.) stream inline, so their +runs are not resumable. + +### 8. Culture feature removed + +The experimental culture feature (`enable_agentic_culture`, +`add_culture_to_context`, `CulturalKnowledge`, the `agno_culture` table) has +been removed. Remove any references; if you need shared knowledge across users, +use [Knowledge](/knowledge/overview) instead. + +### 9. Smaller changes + +- **Toolkit parameters**: `enable_*` prefixes are dropped + (e.g. `SlackTools(enable_send_message=True)` → `SlackTools(send_message=True)`). + v2 names still work with a deprecation warning. +- **AgentOS metadata routes**: `GET /models` was removed (its data moved into + `GET /config` under `available_models`), and `GET /` is now a minimal landing + response. `GET /info` is the single unauthenticated metadata endpoint. +- **Toolkits have an `id`**, used by AgentOS to reference tools stably. + +## Migrate with AI + +Paste the prompt below into Claude, Cursor, or any coding agent with access to +your repository. It applies the mechanical changes and flags everything that +needs your judgment. + +````markdown Copy this prompt expandable +You are migrating a codebase from Agno v2 to Agno v3. Apply the following +changes carefully. Make the mechanical edits directly; for anything marked +JUDGMENT, report it to me instead of guessing. + +## 1. Renamed Agent/Team parameters (mechanical) + +Rename these constructor parameters wherever Agent(...) or Team(...) is called: +- 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 + +## 2. Workflow HITL config (mechanical) + +Step, Steps, Loop, Condition and Router no longer accept flat HITL kwargs. +Collect any of these kwargs from their constructors: + 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 +and move them into a single human_review=HumanReview(...) argument +(import: from agno.workflow.types import HumanReview). +Rename while moving: hitl_max_retries -> max_retries, hitl_timeout -> timeout. +All other names are unchanged inside HumanReview. + +## 3. Reasoning (JUDGMENT) + +Agent(reasoning=True) no longer exists. Find every use and report it: the fix +is to set reasoning_model=, and I need to +choose which model. + +## 4. Keyword-only constructors (mechanical) + +Team and Workflow constructors are keyword-only. Convert positional arguments: + Team([a, b]) -> Team(members=[a, b]) + Workflow("name", ...) -> Workflow(name="name", ...) + +## 5. Culture feature (JUDGMENT) + +The culture feature was removed. Find and report any use of: +enable_agentic_culture, add_culture_to_context, CulturalKnowledge, +update_cultural_knowledge, or imports from agno.culture. + +## 6. Toolkit parameters (mechanical, optional) + +Toolkit constructor params dropped their enable_ prefix (old names still work +but warn). Where obvious, rename e.g. enable_send_message -> send_message. + +## 7. Direct SQL against sessions (JUDGMENT) + +Search for SQL, dashboard queries or exports reading the `runs` column of the +agno_sessions table. In v3 runs live in the agno_runs table +(run_id, session_id, run_type, run_index, run_data, ...). Report every hit. + +## 8. AgentOS API consumers (JUDGMENT) + +If this codebase calls the AgentOS HTTP API: GET /models was removed (use +GET /config -> available_models), and GET / returns a minimal landing payload. +Report any client code using those routes. + +## 9. Database migration (do NOT automate the destructive step) + +Write (but do not execute) a migration script for me with exactly this shape: + + import asyncio + from agno.db.migrations.manager import MigrationManager + # build db exactly as the app does + asyncio.run(MigrationManager(db).up()) + runs = db.get_runs(limit=5) + assert len(runs) > 0, "Migration copied nothing - do NOT run cleanup" + print("Migration verified. Run db.cleanup_legacy_runs_column() manually " + "once you have confirmed history is intact in the UI.") + +Never call cleanup_legacy_runs_column / cleanup_legacy_runs_field yourself, +and never pass force=True on my behalf: cleanup permanently deletes the legacy +run history, and must only happen after the verification assert passes AND I +have confirmed the migrated history looks right. + +## Output + +When done: list every file you changed with a one-line summary, then a +JUDGMENT section listing every finding from steps 3, 5, 7 and 8 that needs my +decision. If the repo pins agno in requirements/pyproject, update it to >=3.0. +```` + + + The prompt deliberately refuses to run the destructive cleanup step. Keep it + that way: verify your migrated history in the AgentOS UI before reclaiming + the legacy storage. + From caf969515a9755614b6432d18479517538afbdeb Mon Sep 17 00:00:00 2001 From: kausmeows Date: Tue, 18 Aug 2026 15:35:32 +0530 Subject: [PATCH 2/9] update --- other/v3-migration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index b8de1c35c..221f3f606 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -237,7 +237,7 @@ use [Knowledge](/knowledge/overview) instead. response. `GET /info` is the single unauthenticated metadata endpoint. - **Toolkits have an `id`**, used by AgentOS to reference tools stably. -## Migrate with AI +## Migrate with a Coding Agent Paste the prompt below into Claude, Cursor, or any coding agent with access to your repository. It applies the mechanical changes and flags everything that From b2aec6feecabc349325ed08d6d6f616a949df28e Mon Sep 17 00:00:00 2001 From: kausmeows Date: Tue, 18 Aug 2026 15:49:06 +0530 Subject: [PATCH 3/9] update --- docs.json | 8 ++- other/v3-changelog.mdx | 138 +++++++++++++++++++++++++++++++++++++++++ other/v3-migration.mdx | 31 +++++++-- 3 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 other/v3-changelog.mdx diff --git a/docs.json b/docs.json index e672e8b0b..54821448f 100644 --- a/docs.json +++ b/docs.json @@ -4642,7 +4642,13 @@ { "group": "Migrations", "pages": [ - "other/v3-migration", + { + "group": "Agno v3 Migration", + "pages": [ + "other/v3-migration", + "other/v3-changelog" + ] + }, { "group": "Agno v2 Migration", "pages": [ diff --git a/other/v3-changelog.mdx b/other/v3-changelog.mdx new file mode 100644 index 000000000..54c65d56e --- /dev/null +++ b/other/v3-changelog.mdx @@ -0,0 +1,138 @@ +--- +title: Agno v3.0 Changelog +sidebarTitle: Agno v3.0 Changelog +description: "Full list of storage, parameter, and behavior changes introduced in Agno v3.0." +--- + +This release rebuilds the storage layer around a normalized runs table, extends +per-user isolation across the platform, and makes AgentOS background execution +durable. + +The major changes are: + +- Session runs are stored one row per run in a dedicated runs table. +- `user_id` scoping extends to metrics, schedules, evals, knowledge and vector databases. +- `background=True` on AgentOS is backed by a durable job queue that survives crashes and deploys. +- Database migrations run through the built-in `MigrationManager`, with schema versions tracked on every adapter. + +## Storage + + + - Runs are no longer stored as a JSON blob in the sessions table. Each run is + a row in the runs table (`agno_runs` by default) with `run_id`, + `session_id`, `run_type`, `run_index`, `user_id`, `status` and `run_data`. + - Saving a run writes one row instead of rewriting the whole session history. + This removes the quadratic write amplification and unbounded row growth of + the blob design. + - `session.runs` is still populated on read: sessions merge the runs table + with any legacy blob, so un-migrated sessions keep working. + - New direct accessors: `db.get_run(run_id)` and + `db.get_runs(session_id=..., user_id=..., status=..., limit=...)`. + - The v2 -> v3 migration preserves the legacy `runs` column as a backup. + Reclaim it with `db.cleanup_legacy_runs_column()` (SQL) or + `db.cleanup_legacy_runs_field()` (document/KV adapters) after verifying the + migration. + + + + - `MigrationManager(db).up()` walks all registered migrations for every table + and stamps the resulting schema version. + - Schema versions are tracked on every adapter, including the document and + key-value stores (MongoDB, Redis, Valkey, Firestore, DynamoDB, SurrealDB, + JSON, GCS JSON, in-memory). An unstamped database is treated as pre-v3 and + migrated. + - Migrations are idempotent and non-destructive. Failures raise and abort + before any version stamp is written. + + +## User Isolation + + + - `user_id` columns added to the schedules, schedule-runs and evals tables. + All user-facing read and write methods accept `user_id`. + - Metrics aggregate per user. The unique key changed from + `(date, aggregation_period)` to `(user_id, date, aggregation_period)`. + Sessions without a `user_id` aggregate into a shared bucket that + `get_metrics` maps back to `None`. + - Knowledge and vector database contents are scoped per user when isolation + is enabled. Searching a pre-v3 vector table with a `user_id` raises a + `ValueError` directing you to the vector database migration, instead of + silently returning empty results. + - Schedule polling (`claim_due_schedule` / `release_schedule`) stays + unscoped so background execution fires across all users; each schedule run + records the owner denormalized from its parent schedule. + + +## AgentOS + + + - Accepted `background=True` requests are committed job rows that survive + crashes, restarts and deploys. Any replica's worker can claim and execute + them. + - Concurrency is bounded. Excess submissions wait in `pending` status instead + of overloading the process. + - Runs can be tailed (`stream=true`), resumed after a disconnect (`/resume`) + and cancelled from any replica. + - `Idempotency-Key` headers deduplicate resubmissions. + - Redis is optional coordination (live event streams, cross-replica + cancellation), never truth. A Redis fault degrades the live view; it cannot + lose or corrupt a run. + - Background execution requires a `db` on the component and returns a 400 + without one. + - External framework agents (LangGraph, Claude, DSPy, etc.) stream inline + when `background=true` is requested; their runs are not resumable. + + + + - `GET /models` removed. Model data moved into `GET /config` under + `available_models`. + - `GET /` returns a minimal landing response linking to `/docs`, `/info` and + `/health`. + - `GET /info` is the single unauthenticated metadata endpoint. + + +## Agents + + + - `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=` + explicitly. + + + + - The experimental culture feature is removed: `enable_agentic_culture`, + `add_culture_to_context`, `CulturalKnowledge`, the culture tools and the + `agno_culture` table. + - Use [Knowledge](/knowledge/overview) for shared cross-user information. + + +## Teams & Workflows + + + - `Team` and `Workflow` constructors no longer accept positional arguments: + `Team(members=[...])`, `Workflow(name=..., steps=[...])`. + + + + - Flat HITL kwargs on `Step`, `Steps`, `Loop`, `Condition` and `Router` are + removed: `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`. + - Pass `human_review=HumanReview(...)` instead + (import from `agno.workflow.types`). Field names are unchanged except + `hitl_max_retries` -> `max_retries` and `hitl_timeout` -> `timeout`. + + +## Tools + + + - Toolkit constructor parameters drop the `enable_` prefix + (e.g. `SlackTools(send_message=True)`). The old names still work and log a + deprecation warning. + - Toolkits have an `id`, used by AgentOS to reference tools stably. + diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 221f3f606..12fa05e8a 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -6,6 +6,11 @@ description: Guide to migrate your Agno applications from v2 to v3. If you have questions during your migration, we can help! See [Get Help](/get-help) for more information. + + Reference the [v3.0 Changelog](/other/v3-changelog) for the full list of + changes. + + Want to migrate automatically? Jump to [Migrate with AI](#migrate-with-ai) for a prompt you can paste into Claude, Cursor or any coding agent. @@ -21,12 +26,18 @@ pip install -U agno ## Migrating your Agno DB -v3.0 changes how session runs are stored. In v2, every session row held its full -run history as a single JSON blob in the `runs` column. In v3, each run is its -own row in a dedicated runs table (`agno_runs` by default), which removes the -write amplification and unbounded row growth of the blob design. +The built-in migration makes two schema changes: -The migration is built into Agno. No external script is needed: +1. **Session runs move to their own table.** In v2, every session row held its + full run history as a single JSON blob in the `runs` column. In v3, each run + is its own row in a dedicated runs table (`agno_runs` by default), which + removes the write amplification and unbounded row growth of the blob design. +2. **A `user_id` column (with index) is added** to the evals, components, + knowledge, schedules, schedule-runs and metrics tables, for + [user isolation](#6-user-isolation-user-id-across-the-platform). The metrics + unique key changes from `(date, aggregation_period)` to include `user_id`. + +One command applies both: ```python migrate_to_v3.py import asyncio @@ -36,7 +47,7 @@ from agno.db.migrations.manager import MigrationManager db = PostgresDb(db_url="postgresql+psycopg://...") -# Step 1: copy every run from the legacy blob into the runs table +# Step 1: run all v3 migrations (runs table + user_id columns) asyncio.run(MigrationManager(db).up()) # Step 2: VERIFY the runs actually landed before any cleanup @@ -48,6 +59,14 @@ db.cleanup_legacy_runs_column() # SQL adapters # db.cleanup_legacy_runs_field() # Mongo / Redis / Valkey / Firestore / Dynamo / JSON adapters ``` +Vector databases are migrated separately. If you use per-user knowledge with a +vector table created before v3, run the matching script from +[`libs/agno/migrations/v2_to_v3`](https://github.com/agno-agi/agno/tree/main/libs/agno/migrations/v2_to_v3) +(`migrate_sql_vectordbs.py`, `migrate_field_vectordbs.py` or +`migrate_sentinel_vectordbs.py`, depending on your vector store) to add +`user_id` scoping to existing collections. Un-migrated tables raise a +`ValueError` on user-scoped searches instead of returning empty results. + Notes: - The migration is **non-destructive and idempotent**: the legacy `runs` column From 1e437afbbef8107616fd8ef291e41981b67ed899 Mon Sep 17 00:00:00 2001 From: kausmeows Date: Tue, 18 Aug 2026 15:53:00 +0530 Subject: [PATCH 4/9] update --- other/v3-migration.mdx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 12fa05e8a..913b6d2d8 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -290,9 +290,10 @@ All other names are unchanged inside HumanReview. ## 3. Reasoning (JUDGMENT) -Agent(reasoning=True) no longer exists. Find every use and report it: the fix -is to set reasoning_model=, and I need to -choose which model. +Agent(reasoning=True) no longer exists. Comment the argument out with a +`# TODO(agno-v3):` marker so the file stays importable, and report every +occurrence: the fix is to set reasoning_model=, and I need to choose which model. ## 4. Keyword-only constructors (mechanical) @@ -302,9 +303,11 @@ Team and Workflow constructors are keyword-only. Convert positional arguments: ## 5. Culture feature (JUDGMENT) -The culture feature was removed. Find and report any use of: -enable_agentic_culture, add_culture_to_context, CulturalKnowledge, -update_cultural_knowledge, or imports from agno.culture. +The culture feature was removed. Find any use of: enable_agentic_culture, +add_culture_to_context, CulturalKnowledge, update_cultural_knowledge, or +imports from agno.culture. Comment constructor arguments out with a +`# TODO(agno-v3):` marker so files stay importable; leave other usages in +place. Report every occurrence. ## 6. Toolkit parameters (mechanical, optional) From 12ed9f6e9d090650696f87b47bd5407b8f60620c Mon Sep 17 00:00:00 2001 From: kausmeows Date: Tue, 18 Aug 2026 19:08:19 +0530 Subject: [PATCH 5/9] update --- other/v3-changelog.mdx | 14 +++++++++++++ other/v3-migration.mdx | 45 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/other/v3-changelog.mdx b/other/v3-changelog.mdx index 54c65d56e..9460b35bd 100644 --- a/other/v3-changelog.mdx +++ b/other/v3-changelog.mdx @@ -83,6 +83,11 @@ The major changes are: when `background=true` is requested; their runs are not resumable. + + - `secret_key` removed from `JWTMiddleware` and `authorization_config`. Use + `verification_keys`, which takes a list of keys. + + - `GET /models` removed. Model data moved into `GET /config` under `available_models`. @@ -100,6 +105,13 @@ The major changes are: - `num_past_session_runs` -> `num_past_session_runs_in_search` - `reasoning=True` removed. Set `reasoning_model=` explicitly. + - `continue_run` / `acontinue_run`: `updated_tools` removed. Pass + `requirements` (a list of `RunRequirement` from the paused run output). + + + + - `agent.run()` executes async tools automatically. The v2 guard that raised + and required `arun()` is removed. @@ -134,5 +146,7 @@ The major changes are: - Toolkit constructor parameters drop the `enable_` prefix (e.g. `SlackTools(send_message=True)`). The old names still work and log a deprecation warning. + - `MCPToolbox`: `auth_tokens` and `auth_headers` removed. Use + `auth_token_getters`. - Toolkits have an `id`, used by AgentOS to reference tools stably. diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 913b6d2d8..37910b489 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -150,10 +150,12 @@ Field mapping: every flat kwarg keeps its name inside `HumanReview`, except `hitl_max_retries` → `max_retries` and `hitl_timeout` → `timeout`. This applies to `Step`, `Steps`, `Loop`, `Condition` and `Router`. -### 3. Removed `Agent` and `Team` parameters +### 3. Removed and renamed parameters These deprecated parameters have been removed. Update them to their v3 names: +**`Agent` and `Team` constructors:** + | v2 (removed) | v3 | |---|---| | `enable_user_memories` | `update_memory_on_run` | @@ -169,6 +171,28 @@ agent = Agent( ) ``` +**`continue_run` / `acontinue_run`:** the `updated_tools` parameter is removed. +Pass `requirements` (a list of `RunRequirement`, available on the paused run +output) instead of a modified `ToolExecution` list: + +```python v3_continue_run.py +run = agent.run("...") # pauses for confirmation +for requirement in run.requirements: + requirement.confirm() +agent.continue_run(run_id=run.run_id, requirements=run.requirements) +``` + +**JWT middleware and `authorization_config`:** `secret_key` is removed. Use +`verification_keys`, which takes a list: + +```python v3_jwt.py +JWTMiddleware(verification_keys=["your-key"]) # was: secret_key="your-key" +``` + +**`MCPToolbox`:** `auth_tokens` and `auth_headers` are removed. Use +`auth_token_getters` (same shape: a mapping of auth source names to token +callables). + ### 4. Reasoning requires an explicit model The `reasoning=True` shortcut has been removed. Pass a native reasoning model @@ -248,6 +272,9 @@ use [Knowledge](/knowledge/overview) instead. ### 9. Smaller changes +- **Async tools run in sync runs**: v2's `agent.run()` raised when the agent + had async tools, forcing `arun()`. v3 executes them automatically; the guard + and its error are gone. - **Toolkit parameters**: `enable_*` prefixes are dropped (e.g. `SlackTools(enable_send_message=True)` → `SlackTools(send_message=True)`). v2 names still work with a deprecation warning. @@ -267,14 +294,26 @@ You are migrating a codebase from Agno v2 to Agno v3. Apply the following changes carefully. Make the mechanical edits directly; for anything marked JUDGMENT, report it to me instead of guessing. -## 1. Renamed Agent/Team parameters (mechanical) +## 1. Renamed parameters (mechanical) Rename these constructor parameters wherever Agent(...) or Team(...) is called: - enable_user_memories -> update_memory_on_run - search_session_history -> search_past_sessions -- num_history_sessions -> num_past_sessions_to_search +- num_history_sessions -> num_past_sessions_to_search - num_past_session_runs -> num_past_session_runs_in_search +Rename these too, wherever they appear: +- JWTMiddleware / authorization_config: secret_key="k" -> verification_keys=["k"] + (note the list wrapping) +- MCPToolbox: auth_tokens= or auth_headers= -> auth_token_getters= (same value) + +## 1b. continue_run updated_tools (JUDGMENT) + +Agent/Team continue_run and acontinue_run no longer accept updated_tools +(List[ToolExecution]). The v3 path is requirements=. This is a structural change to HITL continue code, not +a rename: find every call site passing updated_tools and report it. + ## 2. Workflow HITL config (mechanical) Step, Steps, Loop, Condition and Router no longer accept flat HITL kwargs. From 80dbb90397627f4e193dea6060d8194e5b015d1c Mon Sep 17 00:00:00 2001 From: kausmeows Date: Fri, 21 Aug 2026 17:52:42 +0530 Subject: [PATCH 6/9] update --- other/v3-changelog.mdx | 89 +++++++++++++++++++++++++++++- other/v3-migration.mdx | 122 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 195 insertions(+), 16 deletions(-) diff --git a/other/v3-changelog.mdx b/other/v3-changelog.mdx index 9460b35bd..ee4c10322 100644 --- a/other/v3-changelog.mdx +++ b/other/v3-changelog.mdx @@ -143,10 +143,93 @@ The major changes are: ## Tools - - Toolkit constructor parameters drop the `enable_` prefix - (e.g. `SlackTools(send_message=True)`). The old names still work and log a - deprecation warning. - `MCPToolbox`: `auth_tokens` and `auth_headers` removed. Use `auth_token_getters`. - Toolkits have an `id`, used by AgentOS to reference tools stably. + + + - `DuckDuckGoTools.duckduckgo_search` -> `web_search`, and + `DuckDuckGoTools.duckduckgo_news` -> `search_news`. The toolkit now builds + on `WebSearchTools`, which supplies both methods. + - `FileTools.check_escape` -> `Toolkit._check_path`. `LocalFileSystemTools` + keeps its own `check_escape`, which is unaffected. + - `BrightData.get_screenshot`: the unused `output_path` parameter is removed. + - `PgVector.enable_prefix_matching` is removed. It was a dead helper with no + effect on search. + + +## Scheduler + + + - The schedules table gains eight nullable columns recording where a schedule + came from and who last touched it: `managed_by`, `target_type`, `target_id`, + `created_by_run_id`, `created_by_session_id`, `updated_by_run_id`, + `updated_by_session_id` and `disabled_reason`. `managed_by` and `target_id` + are indexed. + - The v3.0.0 migration adds the columns and indexes on SQLite and PostgreSQL + (sync and async). Existing rows are left as-is with `NULL` provenance; no + data is rewritten. MongoDB needs no schema change. + + + + - `update_schedule` can only write `name`, `description`, `method`, + `endpoint`, `payload`, `cron_expr`, `timezone`, `timeout_seconds`, + `max_retries`, `retry_delay_seconds`, `enabled`, `next_run_at` and + `disabled_reason`. Any other key raises a `ValueError` naming the rejected + columns. + - Ownership, provenance and lock state are no longer writable through the + generic update path, so a name-keyed upsert cannot repoint who a schedule + belongs to or what it targets. + + +## Models + + + - The `mistralai` v1 compatibility layer is removed. `agno[mistral]` now + requires `mistralai>=2.0.0`. + - `agno[mistral]` is included in the `models` extra again. + + + + - `Cerebras` and `CerebrasOpenAI` default to `gpt-oss-120b`, replacing + `llama-4-scout-17b-16e-instruct`. + - OpenAI `reasoning_effort`, `reasoning_summary`, `service_tier` and + `verbosity` accept the full set of API values (including `none`, `xhigh`, + `max`, `scale`, `fast`, `ultrafast`) and any future string. This widens the + accepted types; no existing call breaks. + + +## Learning + + + - `EntityMemoryStore` with `namespace="user"` did not isolate users: the row + key carried no user component, so two users recording the same entity name + and type shared one row. One user's facts overwrote the other's and leaked + into their prompt context. + - Row keys under `namespace="user"` now embed a digest of the `user_id`. + Global and custom namespaces are unchanged and do not re-key. + - Pre-v3 rows are re-keyed by the v3.0.0 migration, not at runtime. Run it + with the rest of your migrations, or call + `agno.learn.migrations.rekey_user_entity_learnings` directly. The + migration's `down()` refuses to reverse the re-key, since the old key + collides users by design. + - `EntityMemoryStore.delete` / `adelete` take a keyword-only `user_id` and + refuse `namespace="user"` deletes without it. `get` / `aget` now require a + `user_id` in that namespace instead of returning an arbitrary user's row. + + + + - `MemoriesConfig` -> `UserMemoryConfig` + - `MemoriesStore` -> `UserMemoryStore` + - `Decision` -> `DecisionLog` + + +## Errors + + + - SQL adapters raised `Table has an invalid schema` with no next step. + The error now names the likely cause (a database created by an older Agno + version) and points at both fixes: `asyncio.run(MigrationManager(db).up())` + or `POST /databases/all/migrate` on AgentOS. + diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 37910b489..8d9181924 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -270,18 +270,100 @@ The experimental culture feature (`enable_agentic_culture`, been removed. Remove any references; if you need shared knowledge across users, use [Knowledge](/knowledge/overview) instead. -### 9. Smaller changes +### 9. Entity memory is isolated per user + +If you use `EntityMemoryStore` with `namespace="user"`, your existing rows are +shared across users and must be re-keyed. + +In v2 the row key carried no user component, so two users who recorded an +entity with the same name and type wrote to the same physical row: one user's +facts overwrote the other's and then appeared in their prompt context. In v3 +the key embeds a digest of the `user_id`. Global and custom namespaces are +unchanged. + +Pre-v3 rows are re-keyed **by the migration, not at runtime** — until you run +it, reads still match the old shared rows. The re-key is part of the v3.0.0 +migration, so `MigrationManager(db).up()` (or `POST /databases/all/migrate`) +covers it along with everything else: + +```python v3_rekey_entities.py +from agno.learn.migrations import rekey_user_entity_learnings + +# Only needed if you are not running the full v3.0.0 migration. +# dry_run=True is the default: it reports what would change without writing. +print(rekey_user_entity_learnings(db)) + +# Apply it once the dry run looks right +result = rekey_user_entity_learnings(db, dry_run=False) +print(result["rekeyed"], result["merged"], result["failed"]) +``` + + + This migration cannot be reversed. `down()` refuses the re-key, because the + pre-v3 key is shared across users and restoring it would collide the rows + again. Back up the learnings table before running it. + + +Reading the report: `rekeyed` moved to the owner's key, and `keyed` was already +correct. `merged` is expected rather than an error — if the upgraded application +wrote to the user-scoped key before the migration ran, the entity exists in two +rows and they are folded together, with the newer row winning. `conflicts` and +`failed` need an operator: resolve them, then re-run the helper. + +Rows whose stored content records a different user than their owner column held +two users' data before the fix and cannot be separated. The migration moves +these to the `quarantined_user` namespace instead of deleting them: the content +is preserved and entity memory stops reading it. They remain listed and mutable +through the `/learnings` API for whichever user the owner column names. To +delete them instead — along with every row that has no owner — and let entity +memory re-capture from conversation, pass `purge_unrecoverable=True`. + +Two API changes come with it: + +- `delete` / `adelete` take a keyword-only `user_id` and refuse + `namespace="user"` deletes without it. Previously any caller could delete + another user's entity by name. +- `get` / `aget` require a `user_id` in that namespace instead of returning an + arbitrary user's row. + +### 10. Smaller changes - **Async tools run in sync runs**: v2's `agent.run()` raised when the agent had async tools, forcing `arun()`. v3 executes them automatically; the guard and its error are gone. -- **Toolkit parameters**: `enable_*` prefixes are dropped - (e.g. `SlackTools(enable_send_message=True)` → `SlackTools(send_message=True)`). - v2 names still work with a deprecation warning. - **AgentOS metadata routes**: `GET /models` was removed (its data moved into `GET /config` under `available_models`), and `GET /` is now a minimal landing response. `GET /info` is the single unauthenticated metadata endpoint. - **Toolkits have an `id`**, used by AgentOS to reference tools stably. +- **Schedule provenance columns**: the schedules table gains eight nullable + columns (`managed_by`, `target_type`, `target_id`, `created_by_run_id`, + `created_by_session_id`, `updated_by_run_id`, `updated_by_session_id`, + `disabled_reason`), added by the v3.0.0 migration on SQLite and PostgreSQL. + Existing rows keep `NULL` provenance and no data is rewritten, so this needs + no action beyond running the migration. If you query the schedules table + directly with `SELECT *`, expect the extra columns. +- **`update_schedule` is restricted to a column allow-list**: it now writes only + `name`, `description`, `method`, `endpoint`, `payload`, `cron_expr`, + `timezone`, `timeout_seconds`, `max_retries`, `retry_delay_seconds`, + `enabled`, `next_run_at` and `disabled_reason`. Passing anything else — such + as `user_id` or a provenance column — raises a `ValueError` instead of + silently repointing the row's owner or target. +- **Removed toolkit methods**: `DuckDuckGoTools.duckduckgo_search` -> + `web_search` and `duckduckgo_news` -> `search_news`; + `FileTools.check_escape` -> `Toolkit._check_path`; + `PgVector.enable_prefix_matching` removed (dead helper); + `BrightData.get_screenshot` no longer takes `output_path`. +- **Removed learn aliases**: `MemoriesConfig` -> `UserMemoryConfig`, + `MemoriesStore` -> `UserMemoryStore`, `Decision` -> `DecisionLog`. +- **Mistral requires `mistralai>=2.0.0`**: the v1 compatibility layer is gone. + Upgrade with `pip install -U "agno[mistral]"`. +- **Cerebras default model**: `Cerebras` and `CerebrasOpenAI` now default to + `gpt-oss-120b` instead of `llama-4-scout-17b-16e-instruct`. Pin the old id + explicitly if you depend on it. +- **`agno[postgres]` installs a working driver**: the extra previously + installed `psycopg-binary` only, so `PostgresDb` failed with + `ModuleNotFoundError: No module named 'sqlalchemy'`. It now pulls `psycopg` + and `sqlalchemy`; you can drop any manual pins you added to work around it. ## Migrate with a Coding Agent @@ -307,6 +389,17 @@ Rename these too, wherever they appear: (note the list wrapping) - MCPToolbox: auth_tokens= or auth_headers= -> auth_token_getters= (same value) +Rename these methods and imports wherever they appear: +- DuckDuckGoTools: .duckduckgo_search( -> .web_search( +- DuckDuckGoTools: .duckduckgo_news( -> .search_news( +- FileTools: .check_escape( -> ._check_path( + (do NOT rename LocalFileSystemTools.check_escape - that one still exists) +- BrightData.get_screenshot(...): drop any output_path= argument +- PgVector: remove any enable_prefix_matching= argument (the helper is gone) +- from agno.learn import MemoriesConfig -> UserMemoryConfig +- from agno.learn import MemoriesStore -> UserMemoryStore +- from agno.learn import Decision -> DecisionLog + ## 1b. continue_run updated_tools (JUDGMENT) Agent/Team continue_run and acontinue_run no longer accept updated_tools @@ -340,6 +433,14 @@ Team and Workflow constructors are keyword-only. Convert positional arguments: Team([a, b]) -> Team(members=[a, b]) Workflow("name", ...) -> Workflow(name="name", ...) +## 4b. Entity memory user isolation (JUDGMENT) + +If the code constructs EntityMemoryStore(...) with namespace="user", report it. +The row key changed in v3 and existing rows must be re-keyed by the v3.0.0 +migration; the change is not reversible, so I need to confirm it. Also report +any call to that store's delete/adelete or get/aget: they now require a +keyword-only user_id in the "user" namespace. + ## 5. Culture feature (JUDGMENT) The culture feature was removed. Find any use of: enable_agentic_culture, @@ -348,24 +449,19 @@ imports from agno.culture. Comment constructor arguments out with a `# TODO(agno-v3):` marker so files stay importable; leave other usages in place. Report every occurrence. -## 6. Toolkit parameters (mechanical, optional) - -Toolkit constructor params dropped their enable_ prefix (old names still work -but warn). Where obvious, rename e.g. enable_send_message -> send_message. - -## 7. Direct SQL against sessions (JUDGMENT) +## 6. Direct SQL against sessions (JUDGMENT) Search for SQL, dashboard queries or exports reading the `runs` column of the agno_sessions table. In v3 runs live in the agno_runs table (run_id, session_id, run_type, run_index, run_data, ...). Report every hit. -## 8. AgentOS API consumers (JUDGMENT) +## 7. AgentOS API consumers (JUDGMENT) If this codebase calls the AgentOS HTTP API: GET /models was removed (use GET /config -> available_models), and GET / returns a minimal landing payload. Report any client code using those routes. -## 9. Database migration (do NOT automate the destructive step) +## 8. Database migration (do NOT automate the destructive step) Write (but do not execute) a migration script for me with exactly this shape: @@ -386,7 +482,7 @@ have confirmed the migrated history looks right. ## Output When done: list every file you changed with a one-line summary, then a -JUDGMENT section listing every finding from steps 3, 5, 7 and 8 that needs my +JUDGMENT section listing every finding from steps 1b, 3, 5, 6 and 7 that needs my decision. If the repo pins agno in requirements/pyproject, update it to >=3.0. ```` From e8017642c0045fd08572ef91fd98728462196fa3 Mon Sep 17 00:00:00 2001 From: kausmeows Date: Mon, 24 Aug 2026 17:08:54 +0530 Subject: [PATCH 7/9] update --- other/v3-changelog.mdx | 132 ++++++++++++++++++++++++++++++++++++++++- other/v3-migration.mdx | 86 +++++++++++++++++++++++---- 2 files changed, 203 insertions(+), 15 deletions(-) diff --git a/other/v3-changelog.mdx b/other/v3-changelog.mdx index ee4c10322..711962db5 100644 --- a/other/v3-changelog.mdx +++ b/other/v3-changelog.mdx @@ -34,6 +34,14 @@ The major changes are: migration. + + - `SqliteDb` and `AsyncSqliteDb` issue `PRAGMA journal_mode=WAL` on connect, + replacing SQLite's default DELETE journal (a journal create, double fsync and + delete on every commit). + - WAL is persistent on the database file and produces `-wal` and `-shm` + sidecar files next to it. Copy or back up all three together. + + - `MigrationManager(db).up()` walks all registered migrations for every table and stamps the resulting schema version. @@ -45,6 +53,21 @@ The major changes are: before any version stamp is written. +## Knowledge + + + - `Knowledge.add_content` -> `insert()` + - `Knowledge.add_content_async` -> `ainsert()` + - `Knowledge.add_contents_async` -> `ainsert_many()` + + + + - `LanceDb`: `use_tantivy` is removed and ignored. + - Searching a pre-v3 vector table with a `user_id` raises a `ValueError` + directing you to the vector database migration, instead of silently + returning empty results. + + ## User Isolation @@ -65,6 +88,18 @@ The major changes are: ## AgentOS + + - `AgentOS(enable_mcp_server=..., mcp_config=...)` is replaced by a single + `mcp_server=` parameter, which takes a bool or an `MCPServerConfig`. + - Passing `websocket=` no longer implies `enable_websocket=True`; set it + explicitly. + + + + - Passing `page` without `limit`, or a `page` below 1, now raises a + `ValueError` instead of being silently ignored. Pages are 1-indexed. + + - Accepted `background=True` requests are committed job rows that survive crashes, restarts and deploys. Any replica's worker can claim and execute @@ -123,9 +158,11 @@ The major changes are: ## Teams & Workflows - - - `Team` and `Workflow` constructors no longer accept positional arguments: - `Team(members=[...])`, `Workflow(name=..., steps=[...])`. + + - The `Workflow` constructor no longer accepts positional arguments: + `Workflow(name=..., steps=[...])`. + - `Team` still accepts `Team([agent_1, agent_2])`; the keyword form + `Team(members=[...])` is preferred but not required. @@ -148,6 +185,44 @@ The major changes are: - Toolkits have an `id`, used by AgentOS to reference tools stably. + + - `Workspace` now excludes env files (`.env*`, `*.env`) and conventional + credential files — private keys and keystores (`*.pem`, `*.key`, `id_rsa*`), + credential directories (`.ssh`, `.aws`, `.kube`), registry and host tokens + (`.npmrc`, `.netrc`, `.git-credentials`), credential data files + (`credentials.json`, `secrets.yaml`, `service_account*.json`) and Terraform + inputs (`*.tfvars`). + - An agent that reads one of these today starts getting a refusal. Re-allow a + specific path explicitly: + + ```python + Workspace(".", allow_paths=["config/credentials.json"]) + ``` + + - Committed templates go the other way and become readable + (`.env.example`, `.env.sample`, `.env.template`, `.env.dist`). + - `credentials.*` and `secrets.*` are deliberately absent from the list: they + would also refuse ordinary source such as `credentials.py`. + - Known limit: a hard link to an excluded file bypasses the boundary. Symlinks + are caught. + + + + - `MultiMCPTools` is removed, along with its `allow_partial_failure` parameter. + Use one `MCPTools` per server. + - The flat Google tool modules are removed: `agno.tools.gmail`, + `agno.tools.googlesheets`, `agno.tools.googlecalendar`, + `agno.tools.google_maps`, `agno.tools.google_drive` and + `agno.tools.google_bigquery`. Import from `agno.tools.google.*` instead. + - Google toolkits: `creds_path` -> `credentials_path`, `auth_port` -> + `oauth_port`. + - `SeltzTools`: `max_documents` -> `max_results`. The legacy SDK path is gone; + `seltz>=1.2.0` is required. + - `BrandfetchTools`: the `async_tools` parameter is removed. + - `StudioTool` -> `StudioTools`. + - `GDriveContextProvider` -> `GoogleDriveContextProvider`. + + - `DuckDuckGoTools.duckduckgo_search` -> `web_search`, and `DuckDuckGoTools.duckduckgo_news` -> `search_news`. The toolkit now builds @@ -172,6 +247,12 @@ The major changes are: data is rewritten. MongoDB needs no schema change. + + - The schedules unique key becomes `(user_id, name)`. + - If duplicate schedule names already exist, the v3.0.0 migration **aborts** + rather than stamping itself as done. Resolve the duplicates and re-run. + + - `update_schedule` can only write `name`, `description`, `method`, `endpoint`, `payload`, `cron_expr`, `timezone`, `timeout_seconds`, @@ -183,8 +264,27 @@ The major changes are: belongs to or what it targets. +## Evals + + + - `store_result_in_file`: the `eval_id` parameter is renamed to `run_id`. + - `{eval_id}` is no longer accepted in `file_path_to_save_results` templates. + Use `{run_id}`. + - `POST /eval-runs` now returns the id the row was actually stored under + (`run_id`), instead of the eval object's `eval_id`. Every eval run gets its + own `run_id`. + - The eval classes no longer carry `eval_id`; results carry a per-run `run_id`, + so re-runs no longer overwrite each other's stored results. + + ## Models + + - The `agno.models.metrics` module and its `Metrics` alias are removed. Use + `agno.metrics` and `RunMetrics`. + - `Model.classify_error` -> `ModelProviderError.classify(error)`. + + - The `mistralai` v1 compatibility layer is removed. `agno[mistral]` now requires `mistralai>=2.0.0`. @@ -219,12 +319,38 @@ The major changes are: `user_id` in that namespace instead of returning an arbitrary user's row. + + - `enable_agentic_memory` and `memory_manager_id` are removed from every Studio + create/edit form (sync and async). Studio components declare memory through + `LearningMachine` instead: `learning_name` binds a registry-declared machine, + or `enable_learning=True` builds the default one. + - The `Agent` and `Team` constructor parameters are unchanged, as are + `Registry.memory_managers` and `resolve_memory_manager_reference`, so configs + stored with the legacy fields keep rehydrating. Only the Studio authoring + surface dropped them. + - Setting `learning_name` or `enable_learning` on a component clears + `enable_agentic_memory` and `memory_manager`: both register a tool named + `update_user_memory`, and the legacy one silently shadowed the store's. + + - `MemoriesConfig` -> `UserMemoryConfig` - `MemoriesStore` -> `UserMemoryStore` - `Decision` -> `DecisionLog` +## Packaging + + + - `agno[postgres]` installed `psycopg-binary` only, which ships the C + accelerator but no importable `psycopg` and no engine layer, so + `PostgresDb` raised `ModuleNotFoundError: No module named 'sqlalchemy'` on + a clean install. The extra now installs `psycopg`, `psycopg-binary` and + `sqlalchemy`. + - If you worked around this by installing `psycopg` or `sqlalchemy` + yourself, you can drop those pins. + + ## Errors diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 8d9181924..62852fd78 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -54,9 +54,12 @@ asyncio.run(MigrationManager(db).up()) runs = db.get_runs(limit=5) assert len(runs) > 0, "Migration copied nothing - do NOT run cleanup" -# Step 3 (optional, after verifying): reclaim the legacy blob storage -db.cleanup_legacy_runs_column() # SQL adapters -# db.cleanup_legacy_runs_field() # Mongo / Redis / Valkey / Firestore / Dynamo / JSON adapters +# Step 3 (optional, after verifying): reclaim the legacy blob storage. +# The migration deliberately PRESERVES the legacy column as a backup, so the +# rows still hold it and the unforced call refuses. Pass force=True once you +# have verified step 2 -- that is what makes this destructive step explicit. +db.cleanup_legacy_runs_column(force=True) # SQL adapters +# db.cleanup_legacy_runs_field(force=True) # Mongo / Redis / Valkey / Firestore / Dynamo / JSON adapters ``` Vector databases are migrated separately. If you use per-user knowledge with a @@ -209,20 +212,21 @@ agent = Agent( ) ``` -### 5. `Team` and `Workflow` constructors are keyword-only +### 5. The `Workflow` constructor is keyword-only -Positional arguments are no longer accepted: +`Workflow` no longer accepts positional arguments: -```python v2_team.py -team = Team([agent_1, agent_2]) +```python v2_workflow.py workflow = Workflow("my-workflow", steps=[...]) ``` -```python v3_team.py -team = Team(members=[agent_1, agent_2]) +```python v3_workflow.py workflow = Workflow(name="my-workflow", steps=[...]) ``` +`Team` is unchanged: `Team([agent_1, agent_2])` still works. The keyword form +`Team(members=[...])` is preferred for clarity but is not required. + ### 6. User isolation: `user_id` across the platform With `user_isolation` enabled on AgentOS, data is now scoped per user across @@ -355,6 +359,48 @@ Two API changes come with it: `BrightData.get_screenshot` no longer takes `output_path`. - **Removed learn aliases**: `MemoriesConfig` -> `UserMemoryConfig`, `MemoriesStore` -> `UserMemoryStore`, `Decision` -> `DecisionLog`. +- **Eval result files**: `store_result_in_file`'s `eval_id` parameter is now + `run_id`, and `{eval_id}` is no longer accepted in `file_path_to_save_results` + templates -- use `{run_id}`. `POST /eval-runs` returns the id the row was + stored under. +- **`Workspace` refuses credential files by default**: env files and + conventional credential paths (`*.pem`, `.ssh`, `.aws`, `credentials.json`, + `*.tfvars`, ...) are excluded, so an agent that reads one starts getting a + refusal. Re-allow specific paths with + `Workspace(".", allow_paths=["config/credentials.json"])`. Committed templates + such as `.env.example` become readable. +- **Studio memory forms**: `enable_agentic_memory` and `memory_manager_id` are + gone from the Studio create/edit forms. Use `learning_name` (a registry + machine) or `enable_learning=True`. The `Agent`/`Team` constructor parameters + are unchanged, so stored configs keep rehydrating. +- **SQLite uses WAL**: `SqliteDb`/`AsyncSqliteDb` connect in WAL journal mode, + which creates `-wal` and `-shm` sidecar files next to the database. Copy or + back up all three together. +- **`MultiMCPTools` removed**: use one `MCPTools` per server. The + `allow_partial_failure` parameter is gone with it. +- **Knowledge insert API**: `add_content` -> `insert()`, `add_content_async` -> + `ainsert()`, `add_contents_async` -> `ainsert_many()`. +- **Flat Google tool modules removed**: import from `agno.tools.google.*` + instead of `agno.tools.gmail`, `agno.tools.googlesheets`, + `agno.tools.googlecalendar`, `agno.tools.google_maps`, + `agno.tools.google_drive`, `agno.tools.google_bigquery`. Their parameters + changed too: `creds_path` -> `credentials_path`, `auth_port` -> `oauth_port`. +- **Other toolkit renames**: `SeltzTools.max_documents` -> `max_results` (and + `seltz>=1.2.0` is now required); `BrandfetchTools` drops `async_tools`; + `StudioTool` -> `StudioTools`; `GDriveContextProvider` -> + `GoogleDriveContextProvider`. +- **AgentOS MCP config**: `AgentOS(enable_mcp_server=..., mcp_config=...)` -> + `mcp_server=` (a bool or `MCPServerConfig`). Passing `websocket=` no longer + implies `enable_websocket=True`. +- **Removed model APIs**: the `agno.models.metrics` module and its `Metrics` + alias are gone -- use `agno.metrics` / `RunMetrics`. `Model.classify_error` + -> `ModelProviderError.classify(error)`. +- **`LanceDb.use_tantivy`** is removed and ignored. +- **Pagination is validated**: `page` without `limit`, or `page < 1`, now raises + a `ValueError` instead of being ignored. +- **Schedule names are unique per user**: the unique key becomes + `(user_id, name)`. If duplicate names already exist, the v3.0.0 migration + aborts rather than stamping itself done -- resolve the duplicates and re-run. - **Mistral requires `mistralai>=2.0.0`**: the v1 compatibility layer is gone. Upgrade with `pip install -U "agno[mistral]"`. - **Cerebras default model**: `Cerebras` and `CerebrasOpenAI` now default to @@ -389,6 +435,22 @@ Rename these too, wherever they appear: (note the list wrapping) - MCPToolbox: auth_tokens= or auth_headers= -> auth_token_getters= (same value) +Rename these imports and modules wherever they appear: +- from agno.tools.gmail / googlesheets / googlecalendar / google_maps / + google_drive / google_bigquery -> from agno.tools.google. +- Google toolkit kwargs: creds_path= -> credentials_path=, auth_port= -> oauth_port= +- MultiMCPTools(...) -> one MCPTools per server (JUDGMENT: report it) +- Knowledge.add_content( -> .insert( +- Knowledge.add_content_async( -> .ainsert( +- Knowledge.add_contents_async( -> .ainsert_many( +- StudioTool -> StudioTools +- GDriveContextProvider -> GoogleDriveContextProvider +- from agno.models.metrics import Metrics -> from agno.metrics import RunMetrics +- SeltzTools kwarg max_documents= -> max_results= +- BrandfetchTools: drop any async_tools= argument +- LanceDb: drop any use_tantivy= argument +- AgentOS(enable_mcp_server=X, mcp_config=Y) -> AgentOS(mcp_server=Y or X) + Rename these methods and imports wherever they appear: - DuckDuckGoTools: .duckduckgo_search( -> .web_search( - DuckDuckGoTools: .duckduckgo_news( -> .search_news( @@ -427,11 +489,11 @@ Agent(reasoning=True) no longer exists. Comment the argument out with a occurrence: the fix is to set reasoning_model=, and I need to choose which model. -## 4. Keyword-only constructors (mechanical) +## 4. Keyword-only Workflow constructor (mechanical) -Team and Workflow constructors are keyword-only. Convert positional arguments: - Team([a, b]) -> Team(members=[a, b]) +The Workflow constructor is keyword-only. Convert positional arguments: Workflow("name", ...) -> Workflow(name="name", ...) +Team is NOT keyword-only: leave Team([a, b]) alone. ## 4b. Entity memory user isolation (JUDGMENT) From 1d6df20e94eafa422a6d8ccd2842d8c7ddcbf36a Mon Sep 17 00:00:00 2001 From: Harsh Sinha Date: Mon, 24 Aug 2026 17:26:24 +0530 Subject: [PATCH 8/9] update --- other/v3-changelog.mdx | 11 +++---- other/v3-migration.mdx | 67 ++++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/other/v3-changelog.mdx b/other/v3-changelog.mdx index 711962db5..021463713 100644 --- a/other/v3-changelog.mdx +++ b/other/v3-changelog.mdx @@ -29,9 +29,10 @@ The major changes are: - New direct accessors: `db.get_run(run_id)` and `db.get_runs(session_id=..., user_id=..., status=..., limit=...)`. - The v2 -> v3 migration preserves the legacy `runs` column as a backup. - Reclaim it with `db.cleanup_legacy_runs_column()` (SQL) or - `db.cleanup_legacy_runs_field()` (document/KV adapters) after verifying the - migration. + Reclaim it with `db.cleanup_legacy_runs_column(force=True)` (SQL) or + `db.cleanup_legacy_runs_field(force=True)` (document/KV adapters) after + verifying the migration — the migration keeps every legacy blob as a backup, + so the unforced call refuses by design. @@ -144,10 +145,6 @@ The major changes are: `requirements` (a list of `RunRequirement` from the paused run output). - - - `agent.run()` executes async tools automatically. The v2 guard that raised - and required `arun()` is removed. - - The experimental culture feature is removed: `enable_agentic_culture`, diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 62852fd78..9373e0f40 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -12,7 +12,7 @@ If you have questions during your migration, we can help! See [Get Help](/get-he - Want to migrate automatically? Jump to [Migrate with AI](#migrate-with-ai) for + Want to migrate automatically? Jump to [Migrate with AI](#migrate-with-a-coding-agent) for a prompt you can paste into Claude, Cursor or any coding agent. @@ -32,10 +32,12 @@ The built-in migration makes two schema changes: full run history as a single JSON blob in the `runs` column. In v3, each run is its own row in a dedicated runs table (`agno_runs` by default), which removes the write amplification and unbounded row growth of the blob design. -2. **A `user_id` column (with index) is added** to the evals, components, - knowledge, schedules, schedule-runs and metrics tables, for - [user isolation](#6-user-isolation-user-id-across-the-platform). The metrics +2. **On the SQL adapters, a `user_id` column (with index) is added** to the + evals, components, knowledge, schedules, schedule-runs and metrics tables, for + [user isolation](#6-user-isolation-user_id-across-the-platform). The metrics unique key changes from `(date, aggregation_period)` to include `user_id`. + Document and KV backends need no schema change here: per-user scoping on those + comes from the v3 write path, so on them the migration only moves the runs. One command applies both: @@ -59,16 +61,27 @@ assert len(runs) > 0, "Migration copied nothing - do NOT run cleanup" # rows still hold it and the unforced call refuses. Pass force=True once you # have verified step 2 -- that is what makes this destructive step explicit. db.cleanup_legacy_runs_column(force=True) # SQL adapters -# db.cleanup_legacy_runs_field(force=True) # Mongo / Redis / Valkey / Firestore / Dynamo / JSON adapters +# db.cleanup_legacy_runs_field(force=True) # Mongo / Redis / Valkey / Firestore / Dynamo / SurrealDB / JSON adapters ``` + + On the async adapters (`AsyncPostgresDb`, `AsyncMySQLDb`, `AsyncSqliteDb`, + `AsyncMongoDb`) `get_runs` and the cleanup method are coroutines — await them: + `runs = asyncio.run(db.get_runs(limit=5))` and + `asyncio.run(db.cleanup_legacy_runs_field(force=True))`. + + Vector databases are migrated separately. If you use per-user knowledge with a vector table created before v3, run the matching script from [`libs/agno/migrations/v2_to_v3`](https://github.com/agno-agi/agno/tree/main/libs/agno/migrations/v2_to_v3) (`migrate_sql_vectordbs.py`, `migrate_field_vectordbs.py` or `migrate_sentinel_vectordbs.py`, depending on your vector store) to add -`user_id` scoping to existing collections. Un-migrated tables raise a -`ValueError` on user-scoped searches instead of returning empty results. +`user_id` scoping to existing collections. On the schema-based stores (PgVector, +SingleStore, LanceDB, Milvus, ClickHouse, Redis, Cassandra, Couchbase) an +un-migrated table raises a `ValueError` on user-scoped searches instead of +returning empty results. Schemaless stores (Qdrant, Pinecone, Upstash, Chroma, +MongoDB, OpenSearch, SurrealDB) need no migration: pre-v3 documents stay +visible to every user as shared. Notes: @@ -208,7 +221,7 @@ agent = Agent(model=OpenAIResponses(id="gpt-5.5"), reasoning=True) ```python v3_reasoning.py agent = Agent( model=OpenAIResponses(id="gpt-5.5"), - reasoning_model=OpenAIResponses(id="gpt-5.5"), + reasoning_model=OpenAIResponses(id="o4-mini"), ) ``` @@ -239,10 +252,12 @@ addition to sessions. What this means for your code and data: `(date, aggregation_period)` to `(user_id, date, aggregation_period)`. Deployments without isolation see the same single-row-per-date shape as before; sessions without a `user_id` aggregate into a shared bucket. -- Vector database collections created before v3 have no per-user scoping. When - isolation is on, searching them with a `user_id` raises a `ValueError` telling - you to run the vector database migration. This is deliberate: an un-migrated - table fails loudly instead of silently returning empty results. +- Vector database collections created before v3 have no per-user scoping. On + schema-based stores, searching them with a `user_id` raises a `ValueError` + telling you to run the vector database migration — an un-migrated table fails + loudly instead of silently returning empty results. On schemaless stores + (Qdrant, Pinecone, Upstash, Chroma, MongoDB, OpenSearch, SurrealDB) pre-v3 + documents are simply treated as shared. ### 7. Background execution and durable queues @@ -332,9 +347,6 @@ Two API changes come with it: ### 10. Smaller changes -- **Async tools run in sync runs**: v2's `agent.run()` raised when the agent - had async tools, forcing `arun()`. v3 executes them automatically; the guard - and its error are gone. - **AgentOS metadata routes**: `GET /models` was removed (its data moved into `GET /config` under `available_models`), and `GET /` is now a minimal landing response. `GET /info` is the single unauthenticated metadata endpoint. @@ -349,9 +361,10 @@ Two API changes come with it: - **`update_schedule` is restricted to a column allow-list**: it now writes only `name`, `description`, `method`, `endpoint`, `payload`, `cron_expr`, `timezone`, `timeout_seconds`, `max_retries`, `retry_delay_seconds`, - `enabled`, `next_run_at` and `disabled_reason`. Passing anything else — such - as `user_id` or a provenance column — raises a `ValueError` instead of - silently repointing the row's owner or target. + `enabled`, `next_run_at` and `disabled_reason`. Passing a provenance column + raises a `ValueError` instead of silently repointing the row's owner or + target. `user_id` is not an update field either: it scopes the update to that + owner, so an update passing the wrong `user_id` matches nothing. - **Removed toolkit methods**: `DuckDuckGoTools.duckduckgo_search` -> `web_search` and `duckduckgo_news` -> `search_news`; `FileTools.check_escape` -> `Toolkit._check_path`; @@ -454,8 +467,9 @@ Rename these imports and modules wherever they appear: Rename these methods and imports wherever they appear: - DuckDuckGoTools: .duckduckgo_search( -> .web_search( - DuckDuckGoTools: .duckduckgo_news( -> .search_news( -- FileTools: .check_escape( -> ._check_path( - (do NOT rename LocalFileSystemTools.check_escape - that one still exists) +- FileTools: .check_escape() -> ._check_path(, self.base_dir) + (the v3 helper takes the base dir explicitly; a bare token rename breaks the call. + Do NOT rename LocalFileSystemTools.check_escape - that one still exists) - BrightData.get_screenshot(...): drop any output_path= argument - PgVector: remove any enable_prefix_matching= argument (the helper is gone) - from agno.learn import MemoriesConfig -> UserMemoryConfig @@ -474,9 +488,9 @@ a rename: find every call site passing updated_tools and report it. Step, Steps, Loop, Condition and Router no longer accept flat HITL kwargs. Collect any of these kwargs from their constructors: 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 + user_input_message, user_input_schema, allow_multiple_selections, + requires_output_review, output_review_message, requires_iteration_review, + iteration_review_message, on_error, hitl_max_retries, hitl_timeout, on_timeout and move them into a single human_review=HumanReview(...) argument (import: from agno.workflow.types import HumanReview). Rename while moving: hitl_max_retries -> max_retries, hitl_timeout -> timeout. @@ -492,7 +506,10 @@ instance>, and I need to choose which model. ## 4. Keyword-only Workflow constructor (mechanical) The Workflow constructor is keyword-only. Convert positional arguments: - Workflow("name", ...) -> Workflow(name="name", ...) + Workflow("wf-id", ...) -> Workflow(id="wf-id", ...) + (v2's first positional argument was `id`, NOT `name` - converting it to name= + would silently re-identify the workflow: new auto-generated id, different + AgentOS routing and database rows) Team is NOT keyword-only: leave Team([a, b]) alone. ## 4b. Entity memory user isolation (JUDGMENT) @@ -544,7 +561,7 @@ have confirmed the migrated history looks right. ## Output When done: list every file you changed with a one-line summary, then a -JUDGMENT section listing every finding from steps 1b, 3, 5, 6 and 7 that needs my +JUDGMENT section listing every finding from steps 1b, 3, 4b, 5, 6 and 7 that needs my decision. If the repo pins agno in requirements/pyproject, update it to >=3.0. ```` From a9df5ff2cc570d7369bbb9f700737f444e560ec5 Mon Sep 17 00:00:00 2001 From: Harsh Sinha Date: Mon, 24 Aug 2026 17:46:54 +0530 Subject: [PATCH 9/9] update --- other/v3-changelog.mdx | 33 ++++++++++++++++++--------------- other/v3-migration.mdx | 23 ++++++++++++----------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/other/v3-changelog.mdx b/other/v3-changelog.mdx index 021463713..7963d3b4e 100644 --- a/other/v3-changelog.mdx +++ b/other/v3-changelog.mdx @@ -63,10 +63,12 @@ The major changes are: - - `LanceDb`: `use_tantivy` is removed and ignored. - - Searching a pre-v3 vector table with a `user_id` raises a `ValueError` - directing you to the vector database migration, instead of silently - returning empty results. + - `LanceDb`: `use_tantivy` is removed; passing it now raises a `TypeError`. + - On schema-based stores, searching a pre-v3 vector table with a `user_id` + raises a `ValueError` directing you to the vector database migration, + instead of silently returning empty results. Schemaless stores (Qdrant, + Pinecone, Upstash, Chroma, MongoDB, OpenSearch, SurrealDB) treat pre-v3 + documents as shared. ## User Isolation @@ -79,9 +81,9 @@ The major changes are: Sessions without a `user_id` aggregate into a shared bucket that `get_metrics` maps back to `None`. - Knowledge and vector database contents are scoped per user when isolation - is enabled. Searching a pre-v3 vector table with a `user_id` raises a - `ValueError` directing you to the vector database migration, instead of - silently returning empty results. + is enabled. On schema-based stores, searching a pre-v3 vector table with a + `user_id` raises a `ValueError` directing you to the vector database + migration; schemaless stores treat pre-v3 documents as shared. - Schedule polling (`claim_due_schedule` / `release_schedule`) stays unscoped so background execution fires across all users; each schedule run records the owner denormalized from its parent schedule. @@ -92,8 +94,6 @@ The major changes are: - `AgentOS(enable_mcp_server=..., mcp_config=...)` is replaced by a single `mcp_server=` parameter, which takes a bool or an `MCPServerConfig`. - - Passing `websocket=` no longer implies `enable_websocket=True`; set it - explicitly. @@ -213,8 +213,9 @@ The major changes are: `agno.tools.google_bigquery`. Import from `agno.tools.google.*` instead. - Google toolkits: `creds_path` -> `credentials_path`, `auth_port` -> `oauth_port`. - - `SeltzTools`: `max_documents` -> `max_results`. The legacy SDK path is gone; - `seltz>=1.2.0` is required. + - `SeltzTools`: `max_documents` -> `max_results`. Older `seltz` SDKs still + work through a fallback; `seltz>=1.2.0` is needed for the `scope`, domain + and date filters. - `BrandfetchTools`: the `async_tools` parameter is removed. - `StudioTool` -> `StudioTools`. - `GDriveContextProvider` -> `GoogleDriveContextProvider`. @@ -226,7 +227,7 @@ The major changes are: on `WebSearchTools`, which supplies both methods. - `FileTools.check_escape` -> `Toolkit._check_path`. `LocalFileSystemTools` keeps its own `check_escape`, which is unaffected. - - `BrightData.get_screenshot`: the unused `output_path` parameter is removed. + - `BrightDataTools.get_screenshot`: the unused `output_path` parameter is removed. - `PgVector.enable_prefix_matching` is removed. It was a dead helper with no effect on search. @@ -325,9 +326,11 @@ The major changes are: `Registry.memory_managers` and `resolve_memory_manager_reference`, so configs stored with the legacy fields keep rehydrating. Only the Studio authoring surface dropped them. - - Setting `learning_name` or `enable_learning` on a component clears - `enable_agentic_memory` and `memory_manager`: both register a tool named - `update_user_memory`, and the legacy one silently shadowed the store's. + - Enabling learning on a component (a learning machine actually configured + via `learning_name` / `enable_learning`) clears `enable_agentic_memory` and + `memory_manager`: both register a tool named `update_user_memory`, and the + legacy one silently shadowed the store's. Setting them to `False`/`""` + leaves the legacy pair alone. diff --git a/other/v3-migration.mdx b/other/v3-migration.mdx index 9373e0f40..362188a50 100644 --- a/other/v3-migration.mdx +++ b/other/v3-migration.mdx @@ -68,7 +68,8 @@ db.cleanup_legacy_runs_column(force=True) # SQL adapters On the async adapters (`AsyncPostgresDb`, `AsyncMySQLDb`, `AsyncSqliteDb`, `AsyncMongoDb`) `get_runs` and the cleanup method are coroutines — await them: `runs = asyncio.run(db.get_runs(limit=5))` and - `asyncio.run(db.cleanup_legacy_runs_field(force=True))`. + `asyncio.run(db.cleanup_legacy_runs_column(force=True))` (on `AsyncMongoDb` + the method is `cleanup_legacy_runs_field`). Vector databases are migrated separately. If you use per-user knowledge with a @@ -95,8 +96,8 @@ Notes: Cleanup permanently deletes the blob, which is the only copy of your history if the migration did not actually copy it. - Supported everywhere sessions are stored: Postgres, MySQL, SQLite, - SingleStore (+ async variants), MongoDB, Redis, Valkey, Firestore, DynamoDB, - SurrealDB, JSON, and GCS JSON. + SingleStore, MongoDB, Redis, Valkey, Firestore, DynamoDB, SurrealDB, JSON, + and GCS JSON, plus the async Postgres, MySQL, SQLite and MongoDB adapters. For the full storage design and per-adapter details, see the [v3 storage migration guide](https://github.com/agno-agi/agno/blob/main/libs/agno/agno/db/migrations/V3_MIGRATION_GUIDE.md) @@ -369,7 +370,7 @@ Two API changes come with it: `web_search` and `duckduckgo_news` -> `search_news`; `FileTools.check_escape` -> `Toolkit._check_path`; `PgVector.enable_prefix_matching` removed (dead helper); - `BrightData.get_screenshot` no longer takes `output_path`. + `BrightDataTools.get_screenshot` no longer takes `output_path`. - **Removed learn aliases**: `MemoriesConfig` -> `UserMemoryConfig`, `MemoriesStore` -> `UserMemoryStore`, `Decision` -> `DecisionLog`. - **Eval result files**: `store_result_in_file`'s `eval_id` parameter is now @@ -398,17 +399,17 @@ Two API changes come with it: `agno.tools.googlecalendar`, `agno.tools.google_maps`, `agno.tools.google_drive`, `agno.tools.google_bigquery`. Their parameters changed too: `creds_path` -> `credentials_path`, `auth_port` -> `oauth_port`. -- **Other toolkit renames**: `SeltzTools.max_documents` -> `max_results` (and - `seltz>=1.2.0` is now required); `BrandfetchTools` drops `async_tools`; +- **Other toolkit renames**: `SeltzTools.max_documents` -> `max_results` + (older `seltz` SDKs still work through a fallback; `seltz>=1.2.0` is needed + for the `scope`, domain and date filters); `BrandfetchTools` drops `async_tools`; `StudioTool` -> `StudioTools`; `GDriveContextProvider` -> `GoogleDriveContextProvider`. - **AgentOS MCP config**: `AgentOS(enable_mcp_server=..., mcp_config=...)` -> - `mcp_server=` (a bool or `MCPServerConfig`). Passing `websocket=` no longer - implies `enable_websocket=True`. + `mcp_server=` (a bool or `MCPServerConfig`). - **Removed model APIs**: the `agno.models.metrics` module and its `Metrics` alias are gone -- use `agno.metrics` / `RunMetrics`. `Model.classify_error` -> `ModelProviderError.classify(error)`. -- **`LanceDb.use_tantivy`** is removed and ignored. +- **`LanceDb.use_tantivy`** is removed; passing it now raises a `TypeError`. - **Pagination is validated**: `page` without `limit`, or `page < 1`, now raises a `ValueError` instead of being ignored. - **Schedule names are unique per user**: the unique key becomes @@ -470,8 +471,8 @@ Rename these methods and imports wherever they appear: - FileTools: .check_escape() -> ._check_path(, self.base_dir) (the v3 helper takes the base dir explicitly; a bare token rename breaks the call. Do NOT rename LocalFileSystemTools.check_escape - that one still exists) -- BrightData.get_screenshot(...): drop any output_path= argument -- PgVector: remove any enable_prefix_matching= argument (the helper is gone) +- BrightDataTools.get_screenshot(...): drop any output_path= argument +- PgVector: remove any .enable_prefix_matching(...) call (the helper method is gone) - from agno.learn import MemoriesConfig -> UserMemoryConfig - from agno.learn import MemoriesStore -> UserMemoryStore - from agno.learn import Decision -> DecisionLog