# Agno Admin Guide

This guide is for the engineers, architects, and operators who run Agno in production: people standing up an `AgentOS` service, wiring it to a database, securing it with JWT and RBAC, instrumenting it with tracing, and deploying it to a cloud. It documents the system's architecture, the monorepo layout, the full configuration surface, the storage and security models, operational procedures, and the internals you need to extend or debug the framework.

For end-user, task-oriented material — building agents, adding tools, writing workflows — see the companion **User Guide**. This guide assumes you have read it and focuses on running Agno *as a platform*.

> **Source of truth.** Everything here is derived from the Agno source at commit `5b9cfec` (package version `2.6.12`). Where behavior depends on a constructor flag or environment variable, the exact name from the source is given.

---

## 1. Executive Summary

Agno is a Python SDK — distributed as the `agno` package — for building agent platforms. It is not a hosted service: you embed it in your own code and run it on your own infrastructure, against your own database. There is no required Agno-operated backend; the optional `os.agno.com` control plane is a UI that talks to *your* AgentOS instance.

The system has three layers, each opt-in:

| Layer | What it is | When you need it |
|---|---|---|
| **Core SDK** (`agno`) | The `Agent`, `Team`, `Workflow` primitives plus models, tools, knowledge, memory, and DB adapters. | Always. |
| **AgentOS** (`agno[os]`) | A FastAPI runtime that exposes your agents as a REST API with auth, tracing, scheduling, and chat interfaces. | When serving agents over HTTP or to a product. |
| **Infra** (`agno-infra` / the `ag` CLI) | Scaffolding and deployment tooling for Docker and AWS. | When deploying AgentOS to a cloud. |

Architecturally significant properties:

- **Stateless compute, stateful database.** Agents themselves hold no durable state. Sessions, user memories, knowledge, traces, and component definitions all live in a database you supply (`db=`). This makes AgentOS horizontally scalable — run many replicas behind a load balancer, all pointed at the same DB.
- **Provider-agnostic.** 50+ model providers sit behind a single `Model` interface; switching providers is a one-line change.
- **Dependency-light core, heavy optional surface.** The core depends only on `pydantic`, `httpx`, `typer`, `rich`, `pyyaml`, and a few others. Every model, tool, vector DB, and storage backend is an **optional extra**, so a production image installs only what it uses.

---

## 2. Architecture

### 2.1 Request lifecycle

When a client calls an AgentOS run endpoint (e.g. `POST /agents/{id}/runs`), the flow is:

```text
HTTP request
   │
   ▼
FastAPI route (os/routers/agents)
   │  ── JWT/auth middleware: validate token, resolve scopes ──┐
   │                                                            │ (RBAC)
   ▼                                                            │
Resolve Agent by id (from registered agents or DB)             │
   │                                                            │
   ▼                                                            │
Agent.arun(input, session_id, user_id)                         │
   │   1. Load session + history from db                        │
   │   2. Build context (system msg, history, knowledge, memory)│
   │   3. Resolve tools (incl. MCP, callable factories)         │
   │   4. Call Model  ◄──► tool-call loop ──► provider API      │
   │   5. Optional: reasoning, guardrails (pre/post hooks)      │
   │   6. Persist run, update memory/summaries (async)          │
   │   7. Emit OpenTelemetry trace span (if tracing=True)       │
   ▼                                                            │
RunOutput  ── serialized to JSON or streamed via SSE ──────────┘
```

The agent's logic is intentionally split across private submodules under `agno/agent/` — `_run.py` (the run loop), `_messages.py` (context building), `_tools.py` (tool resolution), `_session.py` (persistence), `_managers.py` (memory/culture). The public `agent.py` is a thin dataclass plus a facade that delegates to these. **When debugging the run loop, read `agno/agent/_run.py`, not `agent.py`.**

### 2.2 The core primitives

| Primitive | Module | Role |
|---|---|---|
| `Agent` | `agno/agent/agent.py` | One model + context + tools. The atomic unit of work. |
| `Team` | `agno/team/team.py` | A leader model coordinating member agents/teams in one of four modes. |
| `Workflow` | `agno/workflow/workflow.py` | A deterministic step graph (`Step`, `Parallel`, `Loop`, `Condition`, `Router`). |
| `Model` | `agno/models/base.py` + `agno/models/<provider>/` | Provider adapter; uniform interface over chat/completions APIs. |
| `Toolkit` | `agno/tools/toolkit.py` | A named bundle of callable tools. |
| `Knowledge` | `agno/knowledge/knowledge.py` | RAG layer: readers → chunkers → embedders → vector DB → reranker. |
| `AgentOS` | `agno/os/app.py` | FastAPI app that wires primitives to HTTP. |

### 2.3 The database as the system of record

Every durable concern routes through a `BaseDb` implementation (`agno/db/base.py`). One database can hold all component types: sessions, runs, user memories, session summaries, knowledge metadata, traces, eval runs, and saved component definitions (versioned agents/teams/workflows). The `ComponentType` and `SessionType` enums in `agno/db/base.py` classify what is stored.

This single-DB design is why `AgentOS(db=...)` can auto-provision tables (`auto_provision_dbs=True` by default) and why agents declared without their own `db` inherit the OS-level one.

---

## 3. Repository Layout (Monorepo)

Agno is a monorepo. Operators should understand which package provides what.

```text
agno/                          (repository root)
├── libs/
│   ├── agno/                  → the `agno` PyPI package (the SDK)
│   │   ├── agno/
│   │   │   ├── agent/         Agent class + private run/message/tool/session modules
│   │   │   ├── team/          Team class + coordination modes
│   │   │   ├── workflow/      Workflow + Step/Parallel/Loop/Condition/Router
│   │   │   ├── models/        50+ provider adapters (openai, anthropic, google, …)
│   │   │   ├── tools/         ~130 toolkits + @tool decorator + Toolkit base
│   │   │   ├── knowledge/     readers, chunking, embedders, rerankers
│   │   │   ├── vectordb/      pgvector, lancedb, chroma, qdrant, milvus, …
│   │   │   ├── db/            postgres, sqlite, mysql, mongo, redis, dynamo, …
│   │   │   ├── memory/        user-memory managers + strategies
│   │   │   ├── session/       session + summary objects
│   │   │   ├── os/            AgentOS: app.py, routers/, middleware/, auth, scopes
│   │   │   ├── reasoning/     step-by-step reasoning
│   │   │   ├── guardrails/    input/output guardrails
│   │   │   ├── scheduler/     cron scheduling
│   │   │   ├── tracing/       OpenTelemetry spans + schemas
│   │   │   └── registry/      component registry
│   │   ├── migrations/        v1→v2 migration helpers
│   │   └── pyproject.toml     package metadata + ALL optional extras
│   └── agno_infra/            → the `agno-infra` package (the `ag` CLI)
│       └── agno/
│           ├── cli/           entrypoint + `infra` subcommands
│           ├── docker/        Docker resource definitions
│           └── aws/           AWS resource definitions (ECS, RDS, S3, …)
├── cookbook/                  hundreds of runnable examples (not shipped)
└── scripts/                   dev/release scripts
```

> [!NOTE]
> `cookbook/` is the single best onboarding resource — every feature has a runnable example there, organized by topic (`02_agents`, `03_teams`, `04_workflows`, `05_agent_os`, `07_knowledge`, `91_tools`, `90_models`). It is not part of the installed package.

---

## 4. Requirements

| Requirement | Detail |
|---|---|
| Python | 3.9+ (metadata says 3.7+, but 3.9 is the realistic floor). |
| Core dependencies | `pydantic`, `pydantic-settings`, `httpx[http2]`, `typer`, `rich`, `pyyaml`, `python-dotenv`, `python-multipart`, `gitpython`, `packaging`, `docstring-parser`, `typing-extensions`. |
| Model provider | At least one, installed as an extra (`agno[openai]`, etc.) plus its API key. |
| AgentOS | `agno[os]` → `fastapi[standard]`, `uvicorn`, `sqlalchemy`, `PyJWT`, `opentelemetry-sdk`, `croniter`, `pytz`. |
| Database (for persistence) | A backend extra: `agno[postgres]`, `agno[sqlite]`, `agno[redis]`, etc. |
| Deployment (optional) | `agno-infra`, plus Docker and/or AWS credentials. |

Production images should pin Agno and install exactly the extras needed:

```bash
pip install "agno[os,postgres,pgvector,openai,anthropic]==2.6.12"
```

> [!WARNING]
> Some extras are intentionally disabled at the source level due to upstream supply-chain incidents (the `pyproject.toml` notes `litellm` compromised on PyPI 2026-03-24 and `mistralai` quarantined 2026-05-12, both excluded from the aggregate `agno[models]` extra). If you need those providers, install them deliberately and review their advisories first.

---

## 5. AgentOS: Configuration Mastery

`AgentOS` (`agno/os/app.py`) is the deployment unit. Its constructor is the primary configuration surface.

### 5.1 Constructor reference

```python
from agno.os import AgentOS

agent_os = AgentOS(
    agents=[...], teams=[...], workflows=[...], knowledge=[...],
    db=...,
    ...
)
```

| Argument | Default | Purpose |
|---|---|---|
| `agents` / `teams` / `workflows` / `knowledge` | `None` | The components to serve. **At least one of these or `db` is required** or the constructor raises `ValueError`. |
| `db` | `None` | Default database. Components without their own `db` inherit it. |
| `id` / `name` / `description` / `version` | `None` | Instance identity (shown in the home/registry endpoints). |
| `interfaces` | `None` | Chat interfaces (Slack, Telegram, WhatsApp, Discord, AG-UI). |
| `a2a_interface` | `False` | Expose agents/teams over the A2A (agent-to-agent) protocol. |
| `authorization` | `False` | Enable JWT auth + RBAC middleware. See [§7](#7-security). |
| `authorization_config` | `None` | Fine-tune the JWT middleware (admin scope, claim mapping). |
| `cors_allowed_origins` | `None` | Extra CORS origins (merged with Agno defaults). |
| `config` | `None` | Path to a YAML config file or an `AgentOSConfig`. |
| `settings` | `None` | `AgnoAPISettings` instance (env-driven). |
| `lifespan` | `None` | Custom FastAPI lifespan context manager. |
| `enable_mcp_server` | `False` | Expose the OS itself as an MCP server. |
| `base_app` | `None` | Mount AgentOS onto an existing FastAPI app. |
| `on_route_conflict` | `"preserve_agentos"` | Conflict policy when using `base_app`: keep AgentOS routes, keep base-app routes, or error. |
| `tracing` | `False` | Enable OpenTelemetry tracing for all agents/teams. |
| `auto_provision_dbs` | `True` | Auto-create DB tables on startup. |
| `run_hooks_in_background` | `False` | Run pre/post hooks as FastAPI background tasks (non-blocking). |
| `telemetry` | `True` | Anonymous usage telemetry. Set `False` to disable. |
| `registry` | `None` | Custom component registry. |
| `scheduler` | `False` | Enable the cron scheduler. |
| `scheduler_poll_interval` | `15` | Seconds between scheduler polls. |
| `scheduler_base_url` | `None` | Base URL for scheduler→OS HTTP calls (default `http://127.0.0.1:7777`). |
| `internal_service_token` | `None` | Scheduler-to-OS auth token (auto-generated if unset). |

### 5.2 Getting and serving the app

```python
app = agent_os.get_app()      # returns the FastAPI instance (for uvicorn/gunicorn)

agent_os.serve("module:app", host="0.0.0.0", port=7777, workers=4)
```

`serve()` wraps uvicorn. Host and port can be overridden by environment variables (see below) — env wins over the arguments.

### 5.3 Environment variables

| Variable | Effect |
|---|---|
| `AGENT_OS_HOST` | Override the serve host. |
| `AGENT_OS_PORT` | Override the serve port. |
| `AGNO_API_RUNTIME` | `stg` points the control-plane link at `os-stg.agno.com`; otherwise `os.agno.com`. |
| `AGNO_TELEMETRY` | `false` disables usage telemetry. |
| `JWT_VERIFICATION_KEY` | Symmetric secret (HS*) for JWT validation. |
| `JWT_JWKS_FILE` | Path to a JWKS file for asymmetric (RS*) JWT validation. |
| `<PROVIDER>_API_KEY` | Model provider credentials (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, …). |

### 5.4 `AgnoAPISettings`

The `settings=` argument takes an `AgnoAPISettings` (`agno/os/settings.py`), a `pydantic-settings` model populated from the environment:

| Field | Default | Purpose |
|---|---|---|
| `env` | `"dev"` | Deployment environment label. |
| `docs_enabled` | `True` | Serve `/docs` and `/redoc`. **Set `False` in production** to hide the OpenAPI UI. |
| `os_security_key` | `None` | A static bearer token for simple API auth (alternative to full JWT). |
| `authorization_enabled` | `False` | Set when JWT middleware is active. |
| `cors_origin_list` | Agno domains | Allowed CORS origins (Agno's own domains are always appended). |

> [!IMPORTANT]
> In production, either enable full JWT authorization (`authorization=True`) **or** set `os_security_key` to a strong secret. With neither, the API is unauthenticated. Also set `docs_enabled=False` to avoid exposing your endpoint schema.

---

## 6. Storage Backends

All persistence goes through a `BaseDb` / `AsyncBaseDb` implementation. Pick the backend that matches your operational stack; the agent/OS code is identical regardless.

| Backend | Import | Extra | Notes |
|---|---|---|---|
| PostgreSQL | `agno.db.postgres` → `PostgresDb` / `AsyncPostgresDb` | `agno[postgres]` / `agno[async_postgres]` | Recommended default for production. |
| SQLite | `agno.db.sqlite` → `SqliteDb` / `AsyncSqliteDb` | `agno[sqlite]` | Great for local/dev and single-node. |
| MySQL | `agno.db.mysql` | `agno[mysql]` | |
| MongoDB | `agno.db.mongo` | `agno[async_mongo]` | Document store. |
| Redis | `agno.db.redis` | `agno[redis]` | Fast, ephemeral-friendly. |
| DynamoDB | `agno.db.dynamo` | (AWS SDK) | Serverless on AWS. |
| Firestore / GCS-JSON | `agno.db.firestore` / `agno.db.gcs_json` | GCP SDKs | GCP-native. |
| SingleStore | `agno.db.singlestore` | `agno[singlestore]` | |
| In-memory / JSON | `agno.db.in_memory` / `agno.db.json` | — | Tests, demos. |

```python
from agno.db.postgres import PostgresDb
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@db:5432/agno")
```

### 6.1 Provisioning and migrations

- **Auto-provisioning.** With `auto_provision_dbs=True` (default), AgentOS creates required tables on startup.
- **Migrations.** Schema-evolution helpers live in `agno/db/migrations/` (Alembic-style `versions/`). A `migrations/v1_to_v2/` package exists for upgrading data written by Agno v1 to the v2 schema. Run migrations as a deliberate, backed-up step in production; do not rely on auto-provisioning to alter existing tables.

### 6.2 Vector databases (for Knowledge)

Knowledge persistence is separate from the relational `db`. Supported vector stores include `PgVector`, `LanceDb`, `Chroma`, `Qdrant`, `Milvus`, `Pinecone`, `Weaviate`, `MongoDb`, `Redis`, `Couchbase`, `Cassandra`, `SingleStore`, `Clickhouse`, `SurrealDb`, and `UpstashDb` (each under `agno/vectordb/<name>` with a matching extra).

> [!TIP]
> A common production topology is **one Postgres instance serving both roles**: `PostgresDb` for sessions/memory/traces and `PgVector` (same database, `pgvector` extension) for knowledge. This minimizes operational surface.

---

## 7. Security

### 7.1 Authentication options

AgentOS offers two authentication models:

1. **Static bearer token** — set `settings.os_security_key`. Every request must send `Authorization: Bearer <key>`. Simple, coarse-grained (all-or-nothing). Suitable for internal/single-tenant deployments.
2. **JWT + RBAC** — set `authorization=True` (or configure JWT env vars). The JWT middleware validates tokens and enforces per-resource scopes. Required for multi-user / multi-tenant deployments.

JWT validation is configured via environment:

| Variable | Use |
|---|---|
| `JWT_VERIFICATION_KEY` | Shared secret for symmetric (HS256/384/512) tokens. |
| `JWT_JWKS_FILE` | JWKS file path for asymmetric (RS*/ES*) tokens — point this at your IdP's published keys. |

The middleware extracts the bearer token from the `Authorization` header, validates the signature, and attaches the caller's scopes to the request for downstream authorization.

### 7.2 RBAC scopes

Authorization is scope-based (`agno/os/scopes.py`). Scopes come in three shapes:

| Shape | Example | Grants |
|---|---|---|
| Admin | `agent_os:admin` | Full access to everything. |
| Global resource | `agents:read`, `sessions:write` | An action on *all* resources of a type. |
| Per-resource | `agents:web-agent:run` | An action on one specific resource. |
| Wildcard per-resource | `agents:*:run` | An action on all resources of a type (explicit wildcard). |

Resource types include `agents`, `teams`, `workflows`, `sessions`, `memories`, `knowledge`, `metrics`, `traces`, `schedules`, `approvals`, and `config`. Legacy `system:*` scopes are accepted as aliases for `config:*`.

The middleware filters list endpoints to only the resources a token may see (`get_accessible_resources`, `filter_resources_by_access`) and gates run/mutation endpoints with `check_resource_access` / `require_resource_access`. Multi-tenant isolation is achieved by issuing each tenant a token scoped to their resource ids.

```text
# A token granting run access to one agent and read access to its sessions:
scopes: ["agents:support-bot:run", "sessions:read"]
```

### 7.3 CORS and surface hardening

- CORS origins are controlled by `cors_allowed_origins` / `settings.cors_origin_list`. Agno's own domains (`agno.com`, `app.agno.com`, `os.agno.com`, `localhost:3000`) are always appended so the hosted control-plane UI can connect; remove these in `set_cors_origin_list` if you do not use the Agno UI.
- Disable the OpenAPI docs in production (`docs_enabled=False`).
- Run agents with least-privilege tools. Gate dangerous tools behind `@tool(requires_confirmation=True)` and the approvals workflow (`/approvals` endpoints) so a human resolves them before execution.

### 7.4 Secrets and credentials

Model and tool credentials are read from environment variables (`python-dotenv` loads a `.env` automatically). Never bake keys into images. Per the source's error surface, a missing key fails loudly at first use with `ValueError: <PROVIDER>_API_KEY not set`.

---

## 8. Observability & Tracing

Set `tracing=True` on `AgentOS` (or per agent) to emit **OpenTelemetry** spans for every run. Spans capture the model calls, tool calls, reasoning steps, and timings. Schemas live in `agno/tracing/schemas.py`, which imports `opentelemetry-sdk` at module load — so `opentelemetry-sdk` must be installed wherever tracing-capable routers are imported (it is part of `agno[os]`).

Traces are also queryable through the API:

| Endpoint | Purpose |
|---|---|
| `GET /traces` | List traces. |
| `GET /traces/{trace_id}` | One trace. |
| `POST /traces/search` | Search/filter traces. |
| `GET /traces/filter-schema` | Discover available filters. |
| `GET /trace_session_stats` | Aggregate stats. |

Run-level metrics (token counts, latencies) are on every `RunOutput.metrics` and exposed at `GET /metrics` (with `POST /metrics/refresh` to recompute). For third-party observability, `cookbook/observability/` shows integrations with Langfuse, Langsmith, Arize Phoenix, Logfire, MLflow, and others via OpenInference — configured purely through their own env vars (e.g. `LANGFUSE_PUBLIC_KEY`, `PHOENIX_API_KEY`), not Agno-specific config.

---

## 9. Scheduling & Background Jobs

Enable the cron scheduler with `scheduler=True`. It polls every `scheduler_poll_interval` seconds (default 15) and triggers scheduled runs via HTTP back into the OS (`scheduler_base_url`, default `http://127.0.0.1:7777`), authenticated with `internal_service_token`. The scheduler needs `croniter` and `pytz` (`agno[scheduler]`, also pulled by `agno[os]`).

Manage schedules through the API:

| Endpoint | Purpose |
|---|---|
| `GET /schedules`, `GET /schedules/{id}` | List / get. |
| `POST /schedules/{id}/enable` / `.../disable` | Toggle. |
| `POST /schedules/{id}/trigger` | Fire now. |
| `GET /schedules/{id}/runs` | Execution history. |

> [!NOTE]
> The scheduler runs **in-process** with no external broker (no Celery/Redis queue required). For high-availability scheduling across replicas, ensure only one instance owns scheduling or coordinate via the shared DB; running the scheduler on every replica will multiply triggers.

---

## 10. Deployment

### 10.1 Running the server

AgentOS is a standard ASGI app. For production, run it under uvicorn/gunicorn with multiple workers behind a reverse proxy:

```bash
# directly
python my_os.py            # calls agent_os.serve(..., workers=4)

# or via uvicorn
uvicorn my_os:app --host 0.0.0.0 --port 7777 --workers 4
```

Because compute is stateless, scale horizontally by running more replicas against the same database. Put TLS termination, rate limiting, and (optionally) auth at the proxy.

### 10.2 The `ag` CLI (`agno-infra`)

The `agno-infra` package provides the `ag` entrypoint (`agno.cli.entrypoint:agno_cli`) for scaffolding and deploying AgentOS to Docker or AWS:

| Command | Action |
|---|---|
| `ag infra create` | Scaffold a new AgentOS codebase (optionally from a template/URL). |
| `ag infra up` | Provision/start resources for the active codebase. |
| `ag infra down` | Tear down resources. |
| `ag infra patch` | Apply updates to running resources. |
| `ag infra restart` | Restart resources. |
| `ag infra config` | Print the active codebase's infra config. |
| `ag infra delete` | Remove the codebase's infra record. |

The AWS resource library (`libs/agno_infra/agno/aws/resource/`) covers ECS, EC2, RDS, ElastiCache, S3, IAM, ELB, ACM, Secrets Manager, Glue, EMR, and CloudFormation — i.e. it can stand up a full container-based deployment. The Docker resource library targets local/compose-style deployment.

### 10.3 Containerization

A typical Dockerfile installs only the needed extras and runs `serve`:

```dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install "agno[os,postgres,pgvector,openai]==2.6.12"
ENV AGENT_OS_HOST=0.0.0.0 AGENT_OS_PORT=7777 AGNO_TELEMETRY=false
EXPOSE 7777
CMD ["python", "my_os.py"]
```

> [!TIP]
> Bake your provider API keys in at runtime (env/secret manager), not build time. Point `db_url` at a managed Postgres. Set `auto_provision_dbs=False` once schema is stable and run migrations explicitly.

---

## 11. Operations Runbook

| Task | How |
|---|---|
| Health check | `GET /health` (router `os/routers/health.py`). Wire it to your load balancer. |
| Inspect a stuck run | `GET /sessions/{id}/runs/{run_id}`; cancel with `POST /agents/{id}/runs/{run_id}/cancel`. |
| Resume an interrupted run | `POST /.../runs/{run_id}/continue` or `.../resume` (used for human-in-the-loop and approvals). |
| Resolve a pending approval | `GET /approvals`, then `POST /approvals/{id}/resolve`. |
| Recompute metrics | `POST /metrics/refresh`. |
| Manage knowledge content | `POST /knowledge/content`, `GET /knowledge/content/{id}/status`, `GET /knowledge/search`. |
| Rename/clean sessions | `POST /sessions/{id}/rename`, `DELETE /sessions/{id}`. |
| Audit user memories | `GET /memories`, `DELETE /memories/{id}`, `GET /user_memory_stats`. |

### 11.1 Backups

Your `db` *is* the platform's state. Back it up on your normal cadence; a restore brings back every session, memory, trace, and saved component. Knowledge embeddings live in the vector DB — back that up too, or be prepared to re-ingest source documents.

### 11.2 Scaling guidance

- **Throughput** scales with replicas (stateless compute). 
- **Latency** is dominated by the model provider; use `fallback_models` to ride out provider slowdowns.
- **Context cost** grows with history — cap `num_history_runs`, enable `compress_tool_results=True`, and use session summaries for long sessions to avoid `ModelProviderError: maximum context length` failures.
- Run hooks in the background (`run_hooks_in_background=True`) so guardrails/eval hooks don't block responses.

---

## 12. Internals & Module Reference

For engineers extending or debugging Agno. The codebase is large (~7.7M chars across `libs/agno`); the table below is the navigational map for the highest-traffic modules.

| Module | What lives there |
|---|---|
| `agno/agent/_run.py` | The core run loop — context assembly, model invocation, the tool-call cycle, retries, streaming. **Start here for run behavior.** |
| `agno/agent/_messages.py` | System/user message construction, knowledge retrieval injection, history assembly. |
| `agno/agent/_tools.py` | Tool resolution (Python fns, toolkits, MCP, callable factories), tool-choice handling. |
| `agno/agent/_session.py` / `_storage.py` | Session load/save, `to_dict`/`from_dict`, `save`/`load` of versioned components. |
| `agno/agent/_managers.py` | User-memory and cultural-knowledge management. |
| `agno/models/base.py` | The `Model` ABC; the provider-agnostic chat + tool-call protocol; JSON-serialization, error classification (`ModelProviderError`). |
| `agno/models/utils.py` | Model-string parsing (`"provider:model_id"`), provider resolution. |
| `agno/tools/toolkit.py` | `Toolkit` base + function registration. |
| `agno/tools/decorator.py` | The `@tool` decorator. |
| `agno/os/app.py` | `AgentOS`: router mounting, middleware, lifespan, `serve`. |
| `agno/os/routers/*` | One router package per resource (agents, teams, workflows, sessions, memory, knowledge, metrics, traces, schedules, approvals, components, evals, registry). |
| `agno/os/middleware/` | JWT middleware, request context. |
| `agno/os/auth.py` / `scopes.py` | Token extraction + RBAC scope parsing/enforcement. |
| `agno/workflow/*` | Step graph primitives and the executor. |
| `agno/knowledge/` | Readers, chunking strategies, embedders, rerankers, the `Knowledge` facade. |
| `agno/db/base.py` | `BaseDb`/`AsyncBaseDb` ABCs, `ComponentType`/`SessionType` enums. |
| `agno/registry/registry.py` | Component registry (reconstruct agents/teams from stored definitions). |

### 12.1 The Model interface (extending providers)

A provider adapter subclasses `Model` (`agno/models/base.py`) and implements the request/response/stream methods plus tool-call parsing. Provider classes live under `agno/models/<provider>/` and are re-exported from that package's `__init__.py` (e.g. `OpenAIChat`, `Claude`, `Gemini`, `Groq`, `MistralChat`, `AwsBedrock`, `AzureOpenAI`). Error handling is centralized: providers raise `ModelProviderError`, which the run loop classifies as retryable (server errors, context-length) or fatal (invalid API key) to drive retries and fallbacks.

### 12.2 Component versioning & the registry

Agents, teams, and workflows can be persisted and versioned: `agent.save(db=..., stage="published", label=...)` writes a definition; `Agent.load(id, db=...)` reconstructs it. The `Registry` resolves nested references (a team's members, a workflow's steps) during load. This is what powers the `/components` and `/registry` endpoints and the "edit in the UI, reload without redeploy" workflow.

---

## 13. Code Quality & Conventions

- **Typed throughout.** `py.typed` is shipped; mypy runs with `pydantic.mypy` plugin, `check_untyped_defs`, `no_implicit_optional`. Hundreds of third-party libs are listed under `[[tool.mypy.overrides]]` with `ignore_missing_imports` because they are optional extras.
- **Ruff** for linting/formatting, line length 120, target py39. `F401` (unused import) is ignored in `__init__.py` files because those re-export the public API.
- **Facade pattern.** Large classes (`Agent`, `Team`) are dataclasses whose methods delegate to private `_*` modules, keeping the public file readable while isolating heavy logic. Sync and async paths are maintained in parallel (`x`/`ax`).
- **Optional-by-default dependencies.** Anything beyond the slim core is gated behind an import guard that raises a `pip install`-instructional `ImportError`. This is a deliberate UX choice — keep it when adding integrations.
- **Backward compatibility.** Deprecated constructor params are kept and mapped to their replacements with a `log_warning` (e.g. `enable_user_memories` → `update_memory_on_run`, `search_session_history` → `search_past_sessions`). Honor this pattern when renaming.

---

## 14. Testing Strategy

Tests live under `libs/agno/tests/` split into `unit/`, `integration/`, and `system/`. The `agno[dev]` and `agno[tests]` extras install the toolchain (`pytest`, `pytest-asyncio`, `pytest-cov`, `pytest-mock`, `mypy`, `ruff`, plus provider SDKs for model tests).

- `tests/unit/models/` includes retry/error-classification suites that assert how `ModelProviderError`s (context-length, server errors, invalid key) drive retry vs. fail decisions — read these to understand resilience behavior.
- `asyncio_mode = "auto"` means async tests need no explicit marker.
- Integration tests hit real provider/DB backends and are gated by the `integration-tests` extra and credentials; run unit tests in CI by default.

```bash
cd libs/agno
pip install -e ".[dev]"
pytest tests/unit -q
```

---

## 15. Known Issues, Risks & Improvements

Derived from the community issue tracker and source structure:

| Area | Observation | Mitigation / Suggestion |
|---|---|---|
| Multi-turn reliability | A regression was reported where an agent failed multi-turn conversations on a specific version (GH #8258). | Pin a current version; verify `db` + `add_history_to_context` are set; add a smoke test for multi-turn. |
| Team coordination | Teams reported early termination / incomplete execution / first-chunk timeouts (GH #5326). | Raise `max_iterations`, give members clear `role`s, run long member tasks as background jobs; add per-member timeouts. |
| AG-UI integration | Event-ordering and response-divergence bugs against AG-UI (GH #5466, #5368). | Validate event sequencing when building custom AG-UI frontends; keep `ag-ui-protocol` current. |
| Vector DB params | Backend-specific param name mismatch reported for Milvus (`drop_ratio_search` vs `drop_ratio_build`, GH #5171). | Validate vector-DB-specific search params against that backend's docs; don't assume cross-backend parity. |
| Supply chain | `litellm`/`mistralai` extras disabled due to PyPI incidents. | Treat optional extras as part of your security review; pin and verify. |
| In-process scheduler | No external broker; multiple replicas all schedule. | Designate a single scheduler owner or coordinate via the DB for HA. |
| Surface size | The `Agent`/`Team` constructors expose 100+ params each. | High flexibility, real onboarding cost — lean on `cookbook/` recipes and start from a minimal agent, adding flags as needed. |

---

## 16. Quick Reference

### Minimal production AgentOS

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.db.postgres import PostgresDb
from agno.os import AgentOS

db = PostgresDb(db_url="postgresql+psycopg://ai:ai@db:5432/agno")
assistant = Agent(name="Assistant", model=OpenAIChat(id="gpt-4o"), db=db)

agent_os = AgentOS(
    agents=[assistant],
    db=db,
    authorization=True,     # JWT + RBAC
    tracing=True,           # OpenTelemetry
    scheduler=True,         # cron jobs
    telemetry=False,        # no usage reporting
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve("my_os:app", host="0.0.0.0", port=7777, workers=4)
```

### Production checklist

- [ ] Pin Agno and install only needed extras (`agno[os,postgres,pgvector,openai]==2.6.12`).
- [ ] Point `db` (and vector DB) at managed, backed-up instances.
- [ ] `authorization=True` with `JWT_VERIFICATION_KEY`/`JWT_JWKS_FILE`, **or** a strong `os_security_key`.
- [ ] `docs_enabled=False`; lock down `cors_allowed_origins`.
- [ ] Provider keys via secret manager; `AGNO_TELEMETRY=false`.
- [ ] `tracing=True` wired to your OTel collector; `/health` wired to the load balancer.
- [ ] `auto_provision_dbs=False` after first deploy; run migrations explicitly.
- [ ] Single scheduler owner (or DB coordination) if `scheduler=True` across replicas.
- [ ] Cap history (`num_history_runs`) and enable summaries/compression for long sessions.

### Key environment variables

| Variable | Purpose |
|---|---|
| `AGENT_OS_HOST` / `AGENT_OS_PORT` | Bind address/port (override `serve`). |
| `JWT_VERIFICATION_KEY` / `JWT_JWKS_FILE` | JWT auth (symmetric / asymmetric). |
| `AGNO_TELEMETRY` | `false` to disable usage telemetry. |
| `AGNO_API_RUNTIME` | `stg` for the staging control-plane link. |
| `<PROVIDER>_API_KEY` | Model provider credentials. |

### Endpoint families

`/agents` · `/teams` · `/workflows` · `/sessions` · `/memories` · `/knowledge` · `/metrics` · `/traces` · `/schedules` · `/approvals` · `/components` · `/eval-runs` · `/registry` · `/health` — each with the run sub-resources (`/runs`, `/runs/{id}`, `.../cancel`, `.../continue`, `.../resume`) where applicable.

---

_Generated June 2026 from agno-agi/agno at 5b9cfec. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
