agno 2.3.12__tar.gz → 2.3.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agno-2.3.12 → agno-2.3.13}/PKG-INFO +1 -1
- {agno-2.3.12 → agno-2.3.13}/agno/agent/agent.py +3 -8
- {agno-2.3.12 → agno-2.3.13}/agno/models/azure/openai_chat.py +11 -5
- {agno-2.3.12 → agno-2.3.13}/agno/models/openai/chat.py +0 -2
- {agno-2.3.12 → agno-2.3.13}/agno/os/app.py +73 -5
- agno-2.3.13/agno/os/auth.py +244 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/config.py +9 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/middleware/__init__.py +2 -0
- agno-2.3.13/agno/os/middleware/jwt.py +797 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/router.py +0 -1
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/agents/router.py +22 -4
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/teams/router.py +20 -4
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/workflows/router.py +88 -9
- agno-2.3.13/agno/os/scopes.py +469 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/utils.py +25 -0
- {agno-2.3.12 → agno-2.3.13}/agno/team/team.py +3 -7
- {agno-2.3.12 → agno-2.3.13}/agno/tools/postgres.py +1 -1
- agno-2.3.13/agno/utils/cryptography.py +22 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/print_response/agent.py +26 -2
- {agno-2.3.12 → agno-2.3.13}/agno/utils/print_response/team.py +130 -10
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/chroma/chromadb.py +1 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/redis/redisdb.py +16 -2
- {agno-2.3.12 → agno-2.3.13}/agno.egg-info/PKG-INFO +1 -1
- {agno-2.3.12 → agno-2.3.13}/agno.egg-info/SOURCES.txt +2 -0
- {agno-2.3.12 → agno-2.3.13}/pyproject.toml +17 -2
- agno-2.3.12/agno/os/auth.py +0 -57
- agno-2.3.12/agno/os/middleware/jwt.py +0 -235
- {agno-2.3.12 → agno-2.3.13}/LICENSE +0 -0
- {agno-2.3.12 → agno-2.3.13}/README.md +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/agent/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/agent.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/api.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/evals.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/os.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/routes.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/agent.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/evals.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/os.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/response.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/team.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/schemas/workflows.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/settings.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/team.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/api/workflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/cloud/aws/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/cloud/aws/s3/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/cloud/aws/s3/api_client.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/cloud/aws/s3/bucket.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/cloud/aws/s3/object.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/compression/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/compression/manager.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/culture/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/culture/manager.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/async_postgres/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/dynamo/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/dynamo/dynamo.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/dynamo/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/dynamo/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/firestore/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/firestore/firestore.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/firestore/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/firestore/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/gcs_json/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/gcs_json/gcs_json_db.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/gcs_json/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/in_memory/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/in_memory/in_memory_db.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/in_memory/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/json/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/json/json_db.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/json/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/migrations/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/migrations/manager.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/migrations/v1_to_v2.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/migrations/versions/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/migrations/versions/v2_3_0.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mongo/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mongo/async_mongo.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mongo/mongo.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mongo/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mongo/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mysql/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mysql/async_mysql.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mysql/mysql.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mysql/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/mysql/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/postgres/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/postgres/async_postgres.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/postgres/postgres.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/postgres/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/postgres/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/redis/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/redis/redis.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/redis/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/redis/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/schemas/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/schemas/culture.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/schemas/evals.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/schemas/knowledge.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/schemas/memory.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/schemas/metrics.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/singlestore/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/singlestore/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/singlestore/singlestore.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/singlestore/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/sqlite/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/sqlite/async_sqlite.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/sqlite/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/sqlite/sqlite.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/sqlite/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/surrealdb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/surrealdb/metrics.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/surrealdb/models.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/surrealdb/queries.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/surrealdb/surrealdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/surrealdb/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/db/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/debug.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/accuracy.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/agent_as_judge.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/performance.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/reliability.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/eval/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/exceptions.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/filters.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/guardrails/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/guardrails/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/guardrails/openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/guardrails/pii.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/guardrails/prompt_injection.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/hooks/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/hooks/decorator.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/integrations/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/integrations/discord/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/integrations/discord/client.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/agentic.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/document.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/fixed.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/markdown.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/recursive.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/row.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/semantic.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/chunking/strategy.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/content.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/document/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/document/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/aws_bedrock.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/azure_openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/cohere.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/fastembed.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/fireworks.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/google.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/huggingface.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/jina.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/langdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/mistral.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/nebius.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/ollama.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/sentence_transformer.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/together.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/vllm.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/embedder/voyageai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/knowledge.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/arxiv_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/csv_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/docx_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/field_labeled_csv_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/firecrawl_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/json_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/markdown_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/pdf_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/pptx_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/reader_factory.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/s3_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/tavily_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/text_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/web_search_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/website_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/wikipedia_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reader/youtube_reader.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/remote_content/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/remote_content/remote_content.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reranker/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reranker/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reranker/cohere.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reranker/infinity.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/reranker/sentence_transformer.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/types.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/knowledge/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/media.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/memory/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/memory/manager.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/memory/strategies/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/memory/strategies/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/memory/strategies/summarize.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/memory/strategies/types.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/aimlapi/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/aimlapi/aimlapi.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/anthropic/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/anthropic/claude.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/aws/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/aws/bedrock.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/aws/claude.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/azure/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/azure/ai_foundry.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cerebras/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cerebras/cerebras.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cerebras/cerebras_openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cohere/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cohere/chat.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cometapi/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/cometapi/cometapi.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/dashscope/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/dashscope/dashscope.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/deepinfra/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/deepinfra/deepinfra.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/deepseek/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/deepseek/deepseek.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/defaults.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/fireworks/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/fireworks/fireworks.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/google/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/google/gemini.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/google/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/groq/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/groq/groq.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/huggingface/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/huggingface/huggingface.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/ibm/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/ibm/watsonx.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/internlm/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/internlm/internlm.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/langdb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/langdb/langdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/litellm/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/litellm/chat.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/litellm/litellm_openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/llama_cpp/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/llama_cpp/llama_cpp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/lmstudio/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/lmstudio/lmstudio.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/message.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/meta/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/meta/llama.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/meta/llama_openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/metrics.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/mistral/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/mistral/mistral.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/nebius/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/nebius/nebius.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/nexus/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/nexus/nexus.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/nvidia/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/nvidia/nvidia.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/ollama/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/ollama/chat.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/openai/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/openai/like.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/openai/responses.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/openrouter/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/openrouter/openrouter.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/perplexity/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/perplexity/perplexity.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/portkey/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/portkey/portkey.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/requesty/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/requesty/requesty.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/response.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/sambanova/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/sambanova/sambanova.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/siliconflow/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/siliconflow/siliconflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/together/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/together/together.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/vercel/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/vercel/v0.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/vertexai/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/vertexai/claude.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/vllm/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/vllm/vllm.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/xai/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/models/xai/xai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/a2a/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/a2a/a2a.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/a2a/router.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/a2a/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/agui/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/agui/agui.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/agui/router.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/agui/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/slack/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/slack/router.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/slack/security.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/slack/slack.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/whatsapp/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/whatsapp/router.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/whatsapp/security.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/interfaces/whatsapp/whatsapp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/mcp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/agents/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/agents/schema.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/evals/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/evals/evals.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/evals/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/evals/utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/health.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/home.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/knowledge/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/knowledge/knowledge.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/knowledge/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/memory/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/memory/memory.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/memory/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/metrics/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/metrics/metrics.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/metrics/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/session/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/session/session.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/teams/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/teams/schema.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/traces/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/traces/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/traces/traces.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/workflows/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/routers/workflows/schema.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/schema.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/os/settings.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/py.typed +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/anthropic.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/azure_ai_foundry.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/deepseek.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/default.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/gemini.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/groq.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/helpers.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/ollama.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/step.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/reasoning/vertexai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/agent.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/cancel.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/messages.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/requirement.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/team.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/run/workflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/session/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/session/agent.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/session/summary.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/session/team.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/session/workflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/table.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/team/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/agentql.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/airflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/api.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/apify.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/arxiv.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/aws_lambda.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/aws_ses.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/baidusearch.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/bitbucket.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/brandfetch.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/bravesearch.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/brightdata.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/browserbase.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/calcom.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/calculator.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/cartesia.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/clickup.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/confluence.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/crawl4ai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/csv_toolkit.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/dalle.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/daytona.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/decorator.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/desi_vocal.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/discord.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/docker.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/duckdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/duckduckgo.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/e2b.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/eleven_labs.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/email.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/evm.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/exa.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/fal.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/file.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/file_generation.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/financial_datasets.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/firecrawl.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/function.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/giphy.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/github.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/gmail.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/google_bigquery.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/google_drive.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/google_maps.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/googlecalendar.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/googlesheets.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/hackernews.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/jina.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/jira.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/knowledge.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/linear.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/linkup.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/local_file_system.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/lumalab.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mcp/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mcp/mcp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mcp/multi_mcp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mcp/params.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mcp_toolbox.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mem0.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/memory.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/mlx_transcribe.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models/azure_openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models/gemini.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models/groq.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models/morph.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models/nebius.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/models_labs.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/moviepy_video.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/nano_banana.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/neo4j.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/newspaper.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/newspaper4k.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/notion.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/openbb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/opencv.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/openweather.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/oxylabs.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/pandas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/parallel.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/pubmed.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/python.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/reasoning.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/reddit.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/redshift.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/replicate.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/resend.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/scrapegraph.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/searxng.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/serpapi.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/serper.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/shell.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/shopify.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/slack.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/sleep.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/spider.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/spotify.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/sql.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/streamlit/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/streamlit/components.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/tavily.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/telegram.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/todoist.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/tool_registry.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/toolkit.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/trafilatura.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/trello.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/twilio.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/user_control_flow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/valyu.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/visualization.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/webbrowser.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/webex.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/website.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/webtools.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/whatsapp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/wikipedia.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/workflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/x.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/yfinance.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/youtube.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/zendesk.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/zep.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tools/zoom.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tracing/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tracing/exporter.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tracing/schemas.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/tracing/setup.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/agent.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/audio.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/certs.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/code_execution.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/common.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/dttm.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/enum.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/env.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/events.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/format_str.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/functions.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/gemini.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/hooks.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/http.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/json_schema.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/knowledge.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/location.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/log.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/mcp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/media.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/merge_dict.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/message.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/ai_foundry.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/claude.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/cohere.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/llama.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/mistral.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/openai_responses.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/schema_utils.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/models/watsonx.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/openai.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/pickle.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/pprint.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/print_response/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/print_response/workflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/prompts.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/reasoning.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/response.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/response_iterator.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/safe_formatter.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/serialize.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/shell.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/streamlit.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/string.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/team.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/timer.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/tokens.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/tools.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/web.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/whatsapp.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/utils/yaml_io.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/base.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/cassandra/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/cassandra/cassandra.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/cassandra/index.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/chroma/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/clickhouse/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/clickhouse/index.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/couchbase/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/couchbase/couchbase.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/distance.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/lancedb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/lancedb/lance_db.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/langchaindb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/langchaindb/langchaindb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/lightrag/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/lightrag/lightrag.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/llamaindex/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/llamaindex/llamaindexdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/milvus/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/milvus/milvus.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/mongodb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/mongodb/mongodb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/pgvector/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/pgvector/index.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/pgvector/pgvector.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/pineconedb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/pineconedb/pineconedb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/qdrant/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/qdrant/qdrant.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/redis/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/search.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/singlestore/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/singlestore/index.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/singlestore/singlestore.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/surrealdb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/surrealdb/surrealdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/upstashdb/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/upstashdb/upstashdb.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/weaviate/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/weaviate/index.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/vectordb/weaviate/weaviate.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/__init__.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/agent.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/condition.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/loop.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/parallel.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/router.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/step.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/steps.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/types.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno/workflow/workflow.py +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno.egg-info/dependency_links.txt +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno.egg-info/requires.txt +0 -0
- {agno-2.3.12 → agno-2.3.13}/agno.egg-info/top_level.txt +0 -0
- {agno-2.3.12 → agno-2.3.13}/setup.cfg +0 -0
|
@@ -10408,9 +10408,8 @@ class Agent:
|
|
|
10408
10408
|
"""Use this function to add information to the knowledge base for future use.
|
|
10409
10409
|
|
|
10410
10410
|
Args:
|
|
10411
|
-
query: The query to add.
|
|
10412
|
-
result: The
|
|
10413
|
-
|
|
10411
|
+
query (str): The query or topic to add.
|
|
10412
|
+
result (str): The actual content or information to store.
|
|
10414
10413
|
Returns:
|
|
10415
10414
|
str: A string indicating the status of the addition.
|
|
10416
10415
|
"""
|
|
@@ -10421,13 +10420,9 @@ class Agent:
|
|
|
10421
10420
|
document_name = query.replace(" ", "_").replace("?", "").replace("!", "").replace(".", "")
|
|
10422
10421
|
document_content = json.dumps({"query": query, "result": result})
|
|
10423
10422
|
log_info(f"Adding document to Knowledge: {document_name}: {document_content}")
|
|
10424
|
-
import asyncio
|
|
10425
|
-
|
|
10426
10423
|
from agno.knowledge.reader.text_reader import TextReader
|
|
10427
10424
|
|
|
10428
|
-
|
|
10429
|
-
self.knowledge.add_content_async(name=document_name, text_content=document_content, reader=TextReader())
|
|
10430
|
-
)
|
|
10425
|
+
self.knowledge.add_content(name=document_name, text_content=document_content, reader=TextReader())
|
|
10431
10426
|
return "Successfully added to knowledge base"
|
|
10432
10427
|
|
|
10433
10428
|
def _get_previous_sessions_messages_function(
|
|
@@ -65,11 +65,17 @@ class AzureOpenAI(OpenAILike):
|
|
|
65
65
|
self.azure_endpoint = self.azure_endpoint or getenv("AZURE_OPENAI_ENDPOINT")
|
|
66
66
|
self.azure_deployment = self.azure_deployment or getenv("AZURE_OPENAI_DEPLOYMENT")
|
|
67
67
|
|
|
68
|
-
if not self.api_key:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
if not (self.api_key or self.azure_ad_token):
|
|
69
|
+
if not self.api_key:
|
|
70
|
+
raise ModelAuthenticationError(
|
|
71
|
+
message="AZURE_OPENAI_API_KEY not set. Please set the AZURE_OPENAI_API_KEY environment variable.",
|
|
72
|
+
model_name=self.name,
|
|
73
|
+
)
|
|
74
|
+
if not self.azure_ad_token:
|
|
75
|
+
raise ModelAuthenticationError(
|
|
76
|
+
message="AZURE_AD_TOKEN not set. Please set the AZURE_AD_TOKEN environment variable.",
|
|
77
|
+
model_name=self.name,
|
|
78
|
+
)
|
|
73
79
|
|
|
74
80
|
params_mapping = {
|
|
75
81
|
"api_key": self.api_key,
|
|
@@ -768,7 +768,6 @@ class OpenAIChat(Model):
|
|
|
768
768
|
# Add role
|
|
769
769
|
if response_message.role is not None:
|
|
770
770
|
model_response.role = response_message.role
|
|
771
|
-
|
|
772
771
|
# Add content
|
|
773
772
|
if response_message.content is not None:
|
|
774
773
|
model_response.content = response_message.content
|
|
@@ -846,7 +845,6 @@ class OpenAIChat(Model):
|
|
|
846
845
|
|
|
847
846
|
if response_delta.choices and len(response_delta.choices) > 0:
|
|
848
847
|
choice_delta: ChoiceDelta = response_delta.choices[0].delta
|
|
849
|
-
|
|
850
848
|
if choice_delta:
|
|
851
849
|
# Add content
|
|
852
850
|
if choice_delta.content is not None:
|
|
@@ -16,6 +16,7 @@ from agno.db.base import AsyncBaseDb, BaseDb
|
|
|
16
16
|
from agno.knowledge.knowledge import Knowledge
|
|
17
17
|
from agno.os.config import (
|
|
18
18
|
AgentOSConfig,
|
|
19
|
+
AuthorizationConfig,
|
|
19
20
|
DatabaseConfig,
|
|
20
21
|
EvalsConfig,
|
|
21
22
|
EvalsDomainConfig,
|
|
@@ -49,11 +50,12 @@ from agno.os.utils import (
|
|
|
49
50
|
collect_mcp_tools_from_workflow,
|
|
50
51
|
find_conflicting_routes,
|
|
51
52
|
load_yaml_config,
|
|
53
|
+
resolve_origins,
|
|
52
54
|
setup_tracing_for_os,
|
|
53
55
|
update_cors_middleware,
|
|
54
56
|
)
|
|
55
57
|
from agno.team.team import Team
|
|
56
|
-
from agno.utils.log import log_debug, log_error, log_warning
|
|
58
|
+
from agno.utils.log import log_debug, log_error, log_info, log_warning
|
|
57
59
|
from agno.utils.string import generate_id, generate_id_from_name
|
|
58
60
|
from agno.workflow.workflow import Workflow
|
|
59
61
|
|
|
@@ -118,17 +120,20 @@ class AgentOS:
|
|
|
118
120
|
knowledge: Optional[List[Knowledge]] = None,
|
|
119
121
|
interfaces: Optional[List[BaseInterface]] = None,
|
|
120
122
|
a2a_interface: bool = False,
|
|
123
|
+
authorization: bool = False,
|
|
124
|
+
authorization_config: Optional[AuthorizationConfig] = None,
|
|
125
|
+
cors_allowed_origins: Optional[List[str]] = None,
|
|
121
126
|
config: Optional[Union[str, AgentOSConfig]] = None,
|
|
122
127
|
settings: Optional[AgnoAPISettings] = None,
|
|
123
128
|
lifespan: Optional[Any] = None,
|
|
124
129
|
enable_mcp_server: bool = False,
|
|
125
130
|
base_app: Optional[FastAPI] = None,
|
|
126
131
|
on_route_conflict: Literal["preserve_agentos", "preserve_base_app", "error"] = "preserve_agentos",
|
|
127
|
-
telemetry: bool = True,
|
|
128
132
|
tracing: bool = False,
|
|
129
133
|
tracing_db: Optional[Union[BaseDb, AsyncBaseDb]] = None,
|
|
130
134
|
auto_provision_dbs: bool = True,
|
|
131
135
|
run_hooks_in_background: bool = False,
|
|
136
|
+
telemetry: bool = True,
|
|
132
137
|
):
|
|
133
138
|
"""Initialize AgentOS.
|
|
134
139
|
|
|
@@ -149,11 +154,15 @@ class AgentOS:
|
|
|
149
154
|
enable_mcp_server: Whether to enable MCP (Model Context Protocol)
|
|
150
155
|
base_app: Optional base FastAPI app to use for the AgentOS. All routes and middleware will be added to this app.
|
|
151
156
|
on_route_conflict: What to do when a route conflict is detected in case a custom base_app is provided.
|
|
152
|
-
|
|
157
|
+
auto_provision_dbs: Whether to automatically provision databases
|
|
158
|
+
authorization: Whether to enable authorization
|
|
159
|
+
authorization_config: Configuration for the authorization middleware
|
|
160
|
+
cors_allowed_origins: List of allowed CORS origins (will be merged with default Agno domains)
|
|
153
161
|
tracing: If True, enables OpenTelemetry tracing for all agents and teams in the OS
|
|
154
162
|
tracing_db: Dedicated database for storing and reading traces. Recommended for multi-db setups.
|
|
155
163
|
If not provided and tracing=True, the first available db from agents/teams/workflows is used.
|
|
156
164
|
run_hooks_in_background: If True, run agent/team pre/post hooks as FastAPI background tasks (non-blocking)
|
|
165
|
+
telemetry: Whether to enable telemetry
|
|
157
166
|
|
|
158
167
|
"""
|
|
159
168
|
if not agents and not workflows and not teams and not knowledge:
|
|
@@ -198,6 +207,13 @@ class AgentOS:
|
|
|
198
207
|
self.enable_mcp_server = enable_mcp_server
|
|
199
208
|
self.lifespan = lifespan
|
|
200
209
|
|
|
210
|
+
# RBAC
|
|
211
|
+
self.authorization = authorization
|
|
212
|
+
self.authorization_config = authorization_config
|
|
213
|
+
|
|
214
|
+
# CORS configuration - merge user-provided origins with defaults from settings
|
|
215
|
+
self.cors_allowed_origins = resolve_origins(cors_allowed_origins, self.settings.cors_origin_list)
|
|
216
|
+
|
|
201
217
|
# If True, run agent/team hooks as FastAPI background tasks
|
|
202
218
|
self.run_hooks_in_background = run_hooks_in_background
|
|
203
219
|
|
|
@@ -558,10 +574,53 @@ class AgentOS:
|
|
|
558
574
|
)
|
|
559
575
|
|
|
560
576
|
# Update CORS middleware
|
|
561
|
-
update_cors_middleware(fastapi_app, self.
|
|
577
|
+
update_cors_middleware(fastapi_app, self.cors_allowed_origins) # type: ignore
|
|
578
|
+
|
|
579
|
+
# Set agent_os_id and cors_allowed_origins on app state
|
|
580
|
+
# This allows middleware (like JWT) to access these values
|
|
581
|
+
fastapi_app.state.agent_os_id = self.id
|
|
582
|
+
fastapi_app.state.cors_allowed_origins = self.cors_allowed_origins
|
|
583
|
+
|
|
584
|
+
# Add JWT middleware if authorization is enabled
|
|
585
|
+
if self.authorization:
|
|
586
|
+
self._add_jwt_middleware(fastapi_app)
|
|
562
587
|
|
|
563
588
|
return fastapi_app
|
|
564
589
|
|
|
590
|
+
def _add_jwt_middleware(self, fastapi_app: FastAPI) -> None:
|
|
591
|
+
from agno.os.middleware.jwt import JWTMiddleware, JWTValidator
|
|
592
|
+
|
|
593
|
+
verify_audience = False
|
|
594
|
+
jwks_file = None
|
|
595
|
+
verification_keys = None
|
|
596
|
+
algorithm = "RS256"
|
|
597
|
+
|
|
598
|
+
if self.authorization_config:
|
|
599
|
+
algorithm = self.authorization_config.algorithm or "RS256"
|
|
600
|
+
verification_keys = self.authorization_config.verification_keys
|
|
601
|
+
jwks_file = self.authorization_config.jwks_file
|
|
602
|
+
verify_audience = self.authorization_config.verify_audience or False
|
|
603
|
+
|
|
604
|
+
log_info(f"Adding JWT middleware for authorization (algorithm: {algorithm})")
|
|
605
|
+
|
|
606
|
+
# Create validator and store on app.state for WebSocket access
|
|
607
|
+
jwt_validator = JWTValidator(
|
|
608
|
+
verification_keys=verification_keys,
|
|
609
|
+
jwks_file=jwks_file,
|
|
610
|
+
algorithm=algorithm,
|
|
611
|
+
)
|
|
612
|
+
fastapi_app.state.jwt_validator = jwt_validator
|
|
613
|
+
|
|
614
|
+
# Add middleware to stack
|
|
615
|
+
fastapi_app.add_middleware(
|
|
616
|
+
JWTMiddleware,
|
|
617
|
+
verification_keys=verification_keys,
|
|
618
|
+
jwks_file=jwks_file,
|
|
619
|
+
algorithm=algorithm,
|
|
620
|
+
authorization=self.authorization,
|
|
621
|
+
verify_audience=verify_audience,
|
|
622
|
+
)
|
|
623
|
+
|
|
565
624
|
def get_routes(self) -> List[Any]:
|
|
566
625
|
"""Retrieve all routes from the FastAPI app.
|
|
567
626
|
|
|
@@ -956,4 +1015,13 @@ class AgentOS:
|
|
|
956
1015
|
)
|
|
957
1016
|
)
|
|
958
1017
|
|
|
959
|
-
uvicorn.run(
|
|
1018
|
+
uvicorn.run(
|
|
1019
|
+
app=app,
|
|
1020
|
+
host=host,
|
|
1021
|
+
port=port,
|
|
1022
|
+
reload=reload,
|
|
1023
|
+
workers=workers,
|
|
1024
|
+
access_log=access_log,
|
|
1025
|
+
lifespan="on",
|
|
1026
|
+
**kwargs,
|
|
1027
|
+
)
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
from typing import List, Set
|
|
2
|
+
|
|
3
|
+
from fastapi import Depends, HTTPException, Request
|
|
4
|
+
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
5
|
+
|
|
6
|
+
from agno.os.scopes import get_accessible_resource_ids
|
|
7
|
+
from agno.os.settings import AgnoAPISettings
|
|
8
|
+
|
|
9
|
+
# Create a global HTTPBearer instance
|
|
10
|
+
security = HTTPBearer(auto_error=False)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_authentication_dependency(settings: AgnoAPISettings):
|
|
14
|
+
"""
|
|
15
|
+
Create an authentication dependency function for FastAPI routes.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
settings: The API settings containing the security key
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
A dependency function that can be used with FastAPI's Depends()
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
async def auth_dependency(credentials: HTTPAuthorizationCredentials = Depends(security)) -> bool:
|
|
25
|
+
# If no security key is set, skip authentication entirely
|
|
26
|
+
if not settings or not settings.os_security_key:
|
|
27
|
+
return True
|
|
28
|
+
|
|
29
|
+
# If security is enabled but no authorization header provided, fail
|
|
30
|
+
if not credentials:
|
|
31
|
+
raise HTTPException(status_code=401, detail="Authorization header required")
|
|
32
|
+
|
|
33
|
+
token = credentials.credentials
|
|
34
|
+
|
|
35
|
+
# Verify the token
|
|
36
|
+
if token != settings.os_security_key:
|
|
37
|
+
raise HTTPException(status_code=401, detail="Invalid authentication token")
|
|
38
|
+
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
return auth_dependency
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def validate_websocket_token(token: str, settings: AgnoAPISettings) -> bool:
|
|
45
|
+
"""
|
|
46
|
+
Validate a bearer token for WebSocket authentication (legacy os_security_key method).
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
token: The bearer token to validate
|
|
50
|
+
settings: The API settings containing the security key
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
True if the token is valid or authentication is disabled, False otherwise
|
|
54
|
+
"""
|
|
55
|
+
# If no security key is set, skip authentication entirely
|
|
56
|
+
if not settings or not settings.os_security_key:
|
|
57
|
+
return True
|
|
58
|
+
|
|
59
|
+
# Verify the token matches the configured security key
|
|
60
|
+
return token == settings.os_security_key
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_accessible_resources(request: Request, resource_type: str) -> Set[str]:
|
|
64
|
+
"""
|
|
65
|
+
Get the set of resource IDs the user has access to based on their scopes.
|
|
66
|
+
|
|
67
|
+
This function is used to filter lists of resources (agents, teams, workflows)
|
|
68
|
+
based on the user's scopes from their JWT token.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
request: The FastAPI request object (contains request.state.scopes)
|
|
72
|
+
resource_type: Type of resource ("agents", "teams", "workflows")
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Set of resource IDs the user can access. Returns {"*"} for wildcard access.
|
|
76
|
+
|
|
77
|
+
Usage:
|
|
78
|
+
accessible_ids = get_accessible_resources(request, "agents")
|
|
79
|
+
if "*" not in accessible_ids:
|
|
80
|
+
agents = [a for a in agents if a.id in accessible_ids]
|
|
81
|
+
|
|
82
|
+
Examples:
|
|
83
|
+
>>> # User with specific agent access
|
|
84
|
+
>>> # Token scopes: ["agent-os:my-os:agents:my-agent:read"]
|
|
85
|
+
>>> get_accessible_resources(request, "agents")
|
|
86
|
+
{'my-agent'}
|
|
87
|
+
|
|
88
|
+
>>> # User with wildcard access
|
|
89
|
+
>>> # Token scopes: ["agent-os:my-os:agents:*:read"] or ["admin"]
|
|
90
|
+
>>> get_accessible_resources(request, "agents")
|
|
91
|
+
{'*'}
|
|
92
|
+
|
|
93
|
+
>>> # User with agent-os level access (global resource scope)
|
|
94
|
+
>>> # Token scopes: ["agent-os:my-os:agents:read"]
|
|
95
|
+
>>> get_accessible_resources(request, "agents")
|
|
96
|
+
{'*'}
|
|
97
|
+
"""
|
|
98
|
+
# Check if accessible_resource_ids is already cached in request state (set by JWT middleware)
|
|
99
|
+
# This happens when user doesn't have global scope but has specific resource scopes
|
|
100
|
+
cached_ids = getattr(request.state, "accessible_resource_ids", None)
|
|
101
|
+
if cached_ids is not None:
|
|
102
|
+
return cached_ids
|
|
103
|
+
|
|
104
|
+
# Get user's scopes from request state (set by JWT middleware)
|
|
105
|
+
user_scopes = getattr(request.state, "scopes", [])
|
|
106
|
+
|
|
107
|
+
# Get accessible resource IDs
|
|
108
|
+
accessible_ids = get_accessible_resource_ids(user_scopes=user_scopes, resource_type=resource_type)
|
|
109
|
+
|
|
110
|
+
return accessible_ids
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def filter_resources_by_access(request: Request, resources: List, resource_type: str) -> List:
|
|
114
|
+
"""
|
|
115
|
+
Filter a list of resources based on user's access permissions.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
request: The FastAPI request object
|
|
119
|
+
resources: List of resource objects (agents, teams, or workflows) with 'id' attribute
|
|
120
|
+
resource_type: Type of resource ("agents", "teams", "workflows")
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Filtered list of resources the user has access to
|
|
124
|
+
|
|
125
|
+
Usage:
|
|
126
|
+
agents = filter_resources_by_access(request, all_agents, "agents")
|
|
127
|
+
teams = filter_resources_by_access(request, all_teams, "teams")
|
|
128
|
+
workflows = filter_resources_by_access(request, all_workflows, "workflows")
|
|
129
|
+
|
|
130
|
+
Examples:
|
|
131
|
+
>>> # User with specific access
|
|
132
|
+
>>> agents = [Agent(id="agent-1"), Agent(id="agent-2"), Agent(id="agent-3")]
|
|
133
|
+
>>> # Token scopes: ["agent-os:my-os:agents:agent-1:read", "agent-os:my-os:agents:agent-2:read"]
|
|
134
|
+
>>> filter_resources_by_access(request, agents, "agents")
|
|
135
|
+
[Agent(id="agent-1"), Agent(id="agent-2")]
|
|
136
|
+
|
|
137
|
+
>>> # User with wildcard access
|
|
138
|
+
>>> # Token scopes: ["admin"]
|
|
139
|
+
>>> filter_resources_by_access(request, agents, "agents")
|
|
140
|
+
[Agent(id="agent-1"), Agent(id="agent-2"), Agent(id="agent-3")]
|
|
141
|
+
"""
|
|
142
|
+
accessible_ids = get_accessible_resources(request, resource_type)
|
|
143
|
+
|
|
144
|
+
# Wildcard access - return all resources
|
|
145
|
+
if "*" in accessible_ids:
|
|
146
|
+
return resources
|
|
147
|
+
|
|
148
|
+
# Filter to only accessible resources
|
|
149
|
+
return [r for r in resources if r.id in accessible_ids]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def check_resource_access(request: Request, resource_id: str, resource_type: str, action: str = "read") -> bool:
|
|
153
|
+
"""
|
|
154
|
+
Check if user has access to a specific resource.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
request: The FastAPI request object
|
|
158
|
+
resource_id: ID of the resource to check
|
|
159
|
+
resource_type: Type of resource ("agents", "teams", "workflows")
|
|
160
|
+
action: Action to check ("read", "run", etc.)
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
True if user has access, False otherwise
|
|
164
|
+
|
|
165
|
+
Usage:
|
|
166
|
+
if not check_resource_access(request, agent_id, "agents", "run"):
|
|
167
|
+
raise HTTPException(status_code=403, detail="Access denied")
|
|
168
|
+
|
|
169
|
+
Examples:
|
|
170
|
+
>>> # Token scopes: ["agent-os:my-os:agents:my-agent:read", "agent-os:my-os:agents:my-agent:run"]
|
|
171
|
+
>>> check_resource_access(request, "my-agent", "agents", "run")
|
|
172
|
+
True
|
|
173
|
+
|
|
174
|
+
>>> check_resource_access(request, "other-agent", "agents", "run")
|
|
175
|
+
False
|
|
176
|
+
"""
|
|
177
|
+
accessible_ids = get_accessible_resources(request, resource_type)
|
|
178
|
+
|
|
179
|
+
# Wildcard access grants all permissions
|
|
180
|
+
if "*" in accessible_ids:
|
|
181
|
+
return True
|
|
182
|
+
|
|
183
|
+
# Check if user has access to this specific resource
|
|
184
|
+
return resource_id in accessible_ids
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def require_resource_access(resource_type: str, action: str, resource_id_param: str):
|
|
188
|
+
"""
|
|
189
|
+
Create a dependency that checks if the user has access to a specific resource.
|
|
190
|
+
|
|
191
|
+
This dependency factory creates a FastAPI dependency that automatically checks
|
|
192
|
+
authorization when authorization is enabled. It extracts the resource ID from
|
|
193
|
+
the path parameters and verifies the user has the required access.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
resource_type: Type of resource ("agents", "teams", "workflows")
|
|
197
|
+
action: Action to check ("read", "run")
|
|
198
|
+
resource_id_param: Name of the path parameter containing the resource ID
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
A dependency function for use with FastAPI's Depends()
|
|
202
|
+
|
|
203
|
+
Usage:
|
|
204
|
+
@router.post("/agents/{agent_id}/runs")
|
|
205
|
+
async def create_agent_run(
|
|
206
|
+
agent_id: str,
|
|
207
|
+
request: Request,
|
|
208
|
+
_: None = Depends(require_resource_access("agents", "run", "agent_id")),
|
|
209
|
+
):
|
|
210
|
+
...
|
|
211
|
+
|
|
212
|
+
@router.get("/agents/{agent_id}")
|
|
213
|
+
async def get_agent(
|
|
214
|
+
agent_id: str,
|
|
215
|
+
request: Request,
|
|
216
|
+
_: None = Depends(require_resource_access("agents", "read", "agent_id")),
|
|
217
|
+
):
|
|
218
|
+
...
|
|
219
|
+
|
|
220
|
+
Examples:
|
|
221
|
+
>>> # Creates dependency for checking agent run access
|
|
222
|
+
>>> dep = require_resource_access("agents", "run", "agent_id")
|
|
223
|
+
|
|
224
|
+
>>> # Creates dependency for checking team read access
|
|
225
|
+
>>> dep = require_resource_access("teams", "read", "team_id")
|
|
226
|
+
"""
|
|
227
|
+
# Map resource_type to singular form for error messages
|
|
228
|
+
resource_singular = {
|
|
229
|
+
"agents": "agent",
|
|
230
|
+
"teams": "team",
|
|
231
|
+
"workflows": "workflow",
|
|
232
|
+
}.get(resource_type, resource_type.rstrip("s"))
|
|
233
|
+
|
|
234
|
+
async def dependency(request: Request):
|
|
235
|
+
# Only check authorization if it's enabled
|
|
236
|
+
if not getattr(request.state, "authorization_enabled", False):
|
|
237
|
+
return
|
|
238
|
+
|
|
239
|
+
# Get the resource_id from path parameters
|
|
240
|
+
resource_id = request.path_params.get(resource_id_param)
|
|
241
|
+
if resource_id and not check_resource_access(request, resource_id, resource_type, action):
|
|
242
|
+
raise HTTPException(status_code=403, detail=f"Access denied to {action} this {resource_singular}")
|
|
243
|
+
|
|
244
|
+
return dependency
|
|
@@ -5,6 +5,15 @@ from typing import Generic, List, Optional, TypeVar
|
|
|
5
5
|
from pydantic import BaseModel, field_validator
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class AuthorizationConfig(BaseModel):
|
|
9
|
+
"""Configuration for the JWT middleware"""
|
|
10
|
+
|
|
11
|
+
verification_keys: Optional[List[str]] = None
|
|
12
|
+
jwks_file: Optional[str] = None
|
|
13
|
+
algorithm: Optional[str] = None
|
|
14
|
+
verify_audience: Optional[bool] = None
|
|
15
|
+
|
|
16
|
+
|
|
8
17
|
class EvalsDomainConfig(BaseModel):
|
|
9
18
|
"""Configuration for the Evals domain of the AgentOS"""
|
|
10
19
|
|