agno 1.8.0__py3-none-any.whl → 2.0.0a1__py3-none-any.whl
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/__init__.py +8 -0
- agno/agent/__init__.py +19 -27
- agno/agent/agent.py +2781 -4126
- agno/api/agent.py +9 -65
- agno/api/api.py +5 -46
- agno/api/evals.py +6 -17
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +9 -64
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1749 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1438 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +888 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1051 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1417 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +298 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1720 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +281 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1371 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1722 -0
- agno/db/singlestore/utils.py +327 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1680 -0
- agno/db/sqlite/utils.py +269 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +142 -43
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1515 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +68 -15
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/knowledge/reader/gcs_reader.py +67 -0
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +36 -9
- agno/{document → knowledge}/reader/pdf_reader.py +79 -21
- agno/knowledge/reader/reader_factory.py +275 -0
- agno/knowledge/reader/s3_reader.py +171 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +84 -0
- agno/knowledge/reader/web_search_reader.py +389 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +2 -2
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +129 -82
- agno/models/aws/bedrock.py +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +347 -287
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/dashscope/dashscope.py +14 -5
- agno/models/google/gemini.py +123 -53
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +38 -144
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +84 -46
- agno/models/openai/chat.py +135 -27
- agno/models/openai/responses.py +233 -115
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +14 -8
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +393 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +33 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +30 -0
- agno/os/router.py +843 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +204 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +413 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +179 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +58 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +163 -0
- agno/os/schema.py +892 -0
- agno/{app/playground → os}/settings.py +8 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/{response.py → agent.py} +144 -72
- agno/run/base.py +44 -58
- agno/run/cancel.py +83 -0
- agno/run/team.py +133 -77
- agno/run/workflow.py +537 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +2967 -4243
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +42 -22
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +18 -13
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +71 -18
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +18 -11
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +16 -7
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +35 -28
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +29 -29
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +68 -17
- agno/tools/giphy.py +22 -10
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +46 -62
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +18 -33
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +31 -19
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +32 -14
- agno/tools/models/gemini.py +58 -31
- agno/tools/models/groq.py +29 -20
- agno/tools/models/nebius.py +27 -11
- agno/tools/models_labs.py +39 -15
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +57 -26
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +62 -46
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +54 -41
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +95 -118
- agno/utils/knowledge.py +29 -0
- agno/utils/location.py +2 -2
- agno/utils/log.py +2 -2
- agno/utils/mcp.py +11 -5
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/claude.py +6 -4
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1565 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +356 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +200 -42
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2394 -696
- agno-2.0.0a1.dist-info/METADATA +355 -0
- agno-2.0.0a1.dist-info/RECORD +514 -0
- agno/agent/metrics.py +0 -107
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1050
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -220
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1042
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -698
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3312
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.0.dist-info/METADATA +0 -979
- agno-1.8.0.dist-info/RECORD +0 -565
- agno-1.8.0.dist-info/entry_points.txt +0 -3
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
agno/models/response.py
CHANGED
|
@@ -3,8 +3,9 @@ from enum import Enum
|
|
|
3
3
|
from time import time
|
|
4
4
|
from typing import Any, Dict, List, Optional
|
|
5
5
|
|
|
6
|
-
from agno.media import AudioResponse, ImageArtifact
|
|
7
|
-
from agno.models.message import Citations
|
|
6
|
+
from agno.media import AudioArtifact, AudioResponse, ImageArtifact, VideoArtifact
|
|
7
|
+
from agno.models.message import Citations
|
|
8
|
+
from agno.models.metrics import Metrics
|
|
8
9
|
from agno.tools.function import UserInputField
|
|
9
10
|
|
|
10
11
|
|
|
@@ -26,7 +27,7 @@ class ToolExecution:
|
|
|
26
27
|
tool_args: Optional[Dict[str, Any]] = None
|
|
27
28
|
tool_call_error: Optional[bool] = None
|
|
28
29
|
result: Optional[str] = None
|
|
29
|
-
metrics: Optional[
|
|
30
|
+
metrics: Optional[Metrics] = None
|
|
30
31
|
|
|
31
32
|
# If True, the agent will stop executing after this tool call.
|
|
32
33
|
stop_after_tool_call: bool = False
|
|
@@ -74,7 +75,7 @@ class ToolExecution:
|
|
|
74
75
|
if "user_input_schema" in data
|
|
75
76
|
else None,
|
|
76
77
|
external_execution_required=data.get("external_execution_required"),
|
|
77
|
-
metrics=
|
|
78
|
+
metrics=Metrics(**(data.get("metrics", {}) or {})),
|
|
78
79
|
)
|
|
79
80
|
|
|
80
81
|
|
|
@@ -87,7 +88,11 @@ class ModelResponse:
|
|
|
87
88
|
content: Optional[Any] = None
|
|
88
89
|
parsed: Optional[Any] = None
|
|
89
90
|
audio: Optional[AudioResponse] = None
|
|
90
|
-
|
|
91
|
+
|
|
92
|
+
# Unified media fields for LLM-generated and tool-generated media artifacts
|
|
93
|
+
images: Optional[List[ImageArtifact]] = None
|
|
94
|
+
videos: Optional[List[VideoArtifact]] = None
|
|
95
|
+
audios: Optional[List[AudioArtifact]] = None
|
|
91
96
|
|
|
92
97
|
# Model tool calls
|
|
93
98
|
tool_calls: List[Dict[str, Any]] = field(default_factory=list)
|
|
@@ -99,18 +104,19 @@ class ModelResponse:
|
|
|
99
104
|
|
|
100
105
|
provider_data: Optional[Dict[str, Any]] = None
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
redacted_thinking: Optional[str] = None
|
|
107
|
+
redacted_reasoning_content: Optional[str] = None
|
|
104
108
|
reasoning_content: Optional[str] = None
|
|
105
109
|
|
|
106
110
|
citations: Optional[Citations] = None
|
|
107
111
|
|
|
108
|
-
response_usage: Optional[
|
|
112
|
+
response_usage: Optional[Metrics] = None
|
|
109
113
|
|
|
110
114
|
created_at: int = int(time())
|
|
111
115
|
|
|
112
116
|
extra: Optional[Dict[str, Any]] = None
|
|
113
117
|
|
|
118
|
+
updated_session_state: Optional[Dict[str, Any]] = None
|
|
119
|
+
|
|
114
120
|
|
|
115
121
|
class FileType(str, Enum):
|
|
116
122
|
MP4 = "mp4"
|
agno/models/utils.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from agno.models.base import Model
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# TODO: add all supported models
|
|
5
|
+
def get_model(model_id: str, model_provider: str) -> Model:
|
|
6
|
+
"""Return the right Agno model instance given a pair of model provider and id"""
|
|
7
|
+
if model_provider == "openai":
|
|
8
|
+
from agno.models.openai import OpenAIChat
|
|
9
|
+
|
|
10
|
+
return OpenAIChat(id=model_id)
|
|
11
|
+
elif model_provider == "anthropic":
|
|
12
|
+
from agno.models.anthropic import Claude
|
|
13
|
+
|
|
14
|
+
return Claude(id=model_id)
|
|
15
|
+
elif model_provider == "gemini":
|
|
16
|
+
from agno.models.google import Gemini
|
|
17
|
+
|
|
18
|
+
return Gemini(id=model_id)
|
|
19
|
+
else:
|
|
20
|
+
raise ValueError(f"Model provider {model_provider} not supported")
|
agno/models/vercel/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from agno.models.vercel.v0 import
|
|
1
|
+
from agno.models.vercel.v0 import V0
|
|
2
2
|
|
|
3
|
-
__all__ = ["
|
|
3
|
+
__all__ = ["V0"]
|
agno/models/vercel/v0.py
CHANGED
agno/models/vllm/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from agno.models.vllm.vllm import
|
|
1
|
+
from agno.models.vllm.vllm import VLLM
|
|
2
2
|
|
|
3
|
-
__all__ = ["
|
|
3
|
+
__all__ = ["VLLM"]
|
agno/models/vllm/vllm.py
CHANGED
|
@@ -9,7 +9,7 @@ from agno.utils.log import log_debug
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@dataclass
|
|
12
|
-
class
|
|
12
|
+
class VLLM(OpenAILike):
|
|
13
13
|
"""
|
|
14
14
|
Class for interacting with vLLM models via OpenAI-compatible API.
|
|
15
15
|
|
|
@@ -26,8 +26,8 @@ class vLLM(OpenAILike):
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
id: str = "not-set"
|
|
29
|
-
name: str = "
|
|
30
|
-
provider: str = "
|
|
29
|
+
name: str = "VLLM"
|
|
30
|
+
provider: str = "VLLM"
|
|
31
31
|
|
|
32
32
|
api_key: Optional[str] = getenv("VLLM_API_KEY") or "EMPTY"
|
|
33
33
|
base_url: Optional[str] = getenv("VLLM_BASE_URL", "http://localhost:8000/v1/")
|
agno/models/xai/xai.py
CHANGED
|
@@ -65,7 +65,7 @@ class xAI(OpenAILike):
|
|
|
65
65
|
|
|
66
66
|
return request_params
|
|
67
67
|
|
|
68
|
-
def
|
|
68
|
+
def _parse_provider_response(
|
|
69
69
|
self,
|
|
70
70
|
response: ChatCompletion,
|
|
71
71
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
@@ -73,21 +73,21 @@ class xAI(OpenAILike):
|
|
|
73
73
|
"""
|
|
74
74
|
Parse the xAI response into a ModelResponse.
|
|
75
75
|
"""
|
|
76
|
-
model_response = super().
|
|
76
|
+
model_response = super()._parse_provider_response(response, response_format)
|
|
77
77
|
|
|
78
|
-
if hasattr(response, "citations") and response.citations:
|
|
78
|
+
if hasattr(response, "citations") and response.citations: # type: ignore
|
|
79
79
|
citations = Citations()
|
|
80
80
|
url_citations = []
|
|
81
|
-
for citation_url in response.citations:
|
|
81
|
+
for citation_url in response.citations: # type: ignore
|
|
82
82
|
url_citations.append(UrlCitation(url=str(citation_url)))
|
|
83
83
|
|
|
84
84
|
citations.urls = url_citations
|
|
85
|
-
citations.raw = response.citations
|
|
85
|
+
citations.raw = response.citations # type: ignore
|
|
86
86
|
model_response.citations = citations
|
|
87
87
|
|
|
88
88
|
return model_response
|
|
89
89
|
|
|
90
|
-
def
|
|
90
|
+
def _parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
|
|
91
91
|
"""
|
|
92
92
|
Parse the xAI streaming response.
|
|
93
93
|
|
|
@@ -97,16 +97,16 @@ class xAI(OpenAILike):
|
|
|
97
97
|
Returns:
|
|
98
98
|
ModelResponse: Parsed response data
|
|
99
99
|
"""
|
|
100
|
-
model_response = super().
|
|
100
|
+
model_response = super()._parse_provider_response_delta(response_delta)
|
|
101
101
|
|
|
102
|
-
if hasattr(response_delta, "citations") and response_delta.citations:
|
|
102
|
+
if hasattr(response_delta, "citations") and response_delta.citations: # type: ignore
|
|
103
103
|
citations = Citations()
|
|
104
104
|
url_citations = []
|
|
105
|
-
for citation_url in response_delta.citations:
|
|
105
|
+
for citation_url in response_delta.citations: # type: ignore
|
|
106
106
|
url_citations.append(UrlCitation(url=str(citation_url)))
|
|
107
107
|
|
|
108
108
|
citations.urls = url_citations
|
|
109
|
-
citations.raw = response_delta.citations
|
|
109
|
+
citations.raw = response_delta.citations # type: ignore
|
|
110
110
|
model_response.citations = citations
|
|
111
111
|
|
|
112
112
|
return model_response
|
agno/os/__init__.py
ADDED
agno/os/app.py
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from fastapi import FastAPI, HTTPException
|
|
6
|
+
from fastapi.responses import JSONResponse
|
|
7
|
+
from rich import box
|
|
8
|
+
from rich.panel import Panel
|
|
9
|
+
from starlette.middleware.cors import CORSMiddleware
|
|
10
|
+
from starlette.requests import Request
|
|
11
|
+
|
|
12
|
+
from agno.agent.agent import Agent
|
|
13
|
+
from agno.os.config import (
|
|
14
|
+
AgentOSConfig,
|
|
15
|
+
DatabaseConfig,
|
|
16
|
+
EvalsConfig,
|
|
17
|
+
EvalsDomainConfig,
|
|
18
|
+
KnowledgeConfig,
|
|
19
|
+
KnowledgeDomainConfig,
|
|
20
|
+
MemoryConfig,
|
|
21
|
+
MemoryDomainConfig,
|
|
22
|
+
MetricsConfig,
|
|
23
|
+
MetricsDomainConfig,
|
|
24
|
+
SessionConfig,
|
|
25
|
+
SessionDomainConfig,
|
|
26
|
+
)
|
|
27
|
+
from agno.os.interfaces.base import BaseInterface
|
|
28
|
+
from agno.os.router import get_base_router
|
|
29
|
+
from agno.os.routers.evals import get_eval_router
|
|
30
|
+
from agno.os.routers.knowledge import get_knowledge_router
|
|
31
|
+
from agno.os.routers.memory import get_memory_router
|
|
32
|
+
from agno.os.routers.metrics import get_metrics_router
|
|
33
|
+
from agno.os.routers.session import get_session_router
|
|
34
|
+
from agno.os.settings import AgnoAPISettings
|
|
35
|
+
from agno.os.utils import generate_id
|
|
36
|
+
from agno.team.team import Team
|
|
37
|
+
from agno.workflow.workflow import Workflow
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AgentOS:
|
|
41
|
+
host_url: Optional[str] = None
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
os_id: Optional[str] = None,
|
|
46
|
+
description: Optional[str] = None,
|
|
47
|
+
agents: Optional[List[Agent]] = None,
|
|
48
|
+
teams: Optional[List[Team]] = None,
|
|
49
|
+
workflows: Optional[List[Workflow]] = None,
|
|
50
|
+
interfaces: Optional[List[BaseInterface]] = None,
|
|
51
|
+
config: Optional[Union[str, AgentOSConfig]] = None,
|
|
52
|
+
settings: Optional[AgnoAPISettings] = None,
|
|
53
|
+
fastapi_app: Optional[FastAPI] = None,
|
|
54
|
+
telemetry: bool = True,
|
|
55
|
+
):
|
|
56
|
+
if not agents and not workflows and not teams:
|
|
57
|
+
raise ValueError("Either agents, teams or workflows must be provided.")
|
|
58
|
+
|
|
59
|
+
self.config = self._load_yaml_config(config) if isinstance(config, str) else config
|
|
60
|
+
self.description = description
|
|
61
|
+
|
|
62
|
+
self.agents: Optional[List[Agent]] = agents
|
|
63
|
+
self.workflows: Optional[List[Workflow]] = workflows
|
|
64
|
+
self.teams: Optional[List[Team]] = teams
|
|
65
|
+
self.interfaces = interfaces or []
|
|
66
|
+
|
|
67
|
+
self.settings: AgnoAPISettings = settings or AgnoAPISettings()
|
|
68
|
+
self.fastapi_app: Optional[FastAPI] = fastapi_app
|
|
69
|
+
|
|
70
|
+
self.interfaces = interfaces or []
|
|
71
|
+
|
|
72
|
+
self.os_id: Optional[str] = os_id
|
|
73
|
+
self.description = description
|
|
74
|
+
|
|
75
|
+
self.telemetry = telemetry
|
|
76
|
+
|
|
77
|
+
self.interfaces_loaded: List[Tuple[str, str]] = []
|
|
78
|
+
|
|
79
|
+
if self.agents:
|
|
80
|
+
for agent in self.agents:
|
|
81
|
+
agent.initialize_agent()
|
|
82
|
+
|
|
83
|
+
# Required for the built-in routes to work
|
|
84
|
+
agent.store_events = True
|
|
85
|
+
|
|
86
|
+
if self.teams:
|
|
87
|
+
for team in self.teams:
|
|
88
|
+
team.initialize_team()
|
|
89
|
+
|
|
90
|
+
# Required for the built-in routes to work
|
|
91
|
+
team.store_events = True
|
|
92
|
+
|
|
93
|
+
for member in team.members:
|
|
94
|
+
if isinstance(member, Agent):
|
|
95
|
+
member.team_id = None
|
|
96
|
+
member.initialize_agent()
|
|
97
|
+
elif isinstance(member, Team):
|
|
98
|
+
member.initialize_team()
|
|
99
|
+
|
|
100
|
+
if self.workflows:
|
|
101
|
+
for workflow in self.workflows:
|
|
102
|
+
if not workflow.id:
|
|
103
|
+
workflow.id = generate_id(workflow.name)
|
|
104
|
+
|
|
105
|
+
if self.telemetry:
|
|
106
|
+
from agno.api.os import OSLaunch, log_os_telemetry
|
|
107
|
+
|
|
108
|
+
log_os_telemetry(launch=OSLaunch(os_id=self.os_id, data=self._get_telemetry_data()))
|
|
109
|
+
|
|
110
|
+
def _get_telemetry_data(self) -> Dict[str, Any]:
|
|
111
|
+
"""Get the telemetry data for the OS"""
|
|
112
|
+
return {
|
|
113
|
+
"agents": [agent.id for agent in self.agents] if self.agents else None,
|
|
114
|
+
"teams": [team.id for team in self.teams] if self.teams else None,
|
|
115
|
+
"workflows": [workflow.id for workflow in self.workflows] if self.workflows else None,
|
|
116
|
+
"interfaces": [interface.type for interface in self.interfaces] if self.interfaces else None,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
def _load_yaml_config(self, config_file_path: str) -> AgentOSConfig:
|
|
120
|
+
"""Load a YAML config file and return the configuration as an AgentOSConfig instance."""
|
|
121
|
+
from pathlib import Path
|
|
122
|
+
|
|
123
|
+
import yaml
|
|
124
|
+
|
|
125
|
+
# Validate that the path points to a YAML file
|
|
126
|
+
path = Path(config_file_path)
|
|
127
|
+
if path.suffix.lower() not in [".yaml", ".yml"]:
|
|
128
|
+
raise ValueError(f"Config file must have a .yaml or .yml extension, got: {config_file_path}")
|
|
129
|
+
|
|
130
|
+
# Load the YAML file
|
|
131
|
+
with open(config_file_path, "r") as f:
|
|
132
|
+
return AgentOSConfig.model_validate(yaml.safe_load(f))
|
|
133
|
+
|
|
134
|
+
def _auto_discover_databases(self) -> None:
|
|
135
|
+
"""Auto-discover the databases used by all contextual agents, teams and workflows."""
|
|
136
|
+
dbs = {}
|
|
137
|
+
|
|
138
|
+
for agent in self.agents or []:
|
|
139
|
+
if agent.db:
|
|
140
|
+
dbs[agent.db.id] = agent.db
|
|
141
|
+
if agent.knowledge and agent.knowledge.contents_db:
|
|
142
|
+
dbs[agent.knowledge.contents_db.id] = agent.knowledge.contents_db
|
|
143
|
+
|
|
144
|
+
for team in self.teams or []:
|
|
145
|
+
if team.db:
|
|
146
|
+
dbs[team.db.id] = team.db
|
|
147
|
+
if team.knowledge and team.knowledge.contents_db:
|
|
148
|
+
dbs[team.knowledge.contents_db.id] = team.knowledge.contents_db
|
|
149
|
+
|
|
150
|
+
for workflow in self.workflows or []:
|
|
151
|
+
if workflow.db:
|
|
152
|
+
dbs[workflow.db.id] = workflow.db
|
|
153
|
+
|
|
154
|
+
for interface in self.interfaces or []:
|
|
155
|
+
if interface.agent and interface.agent.db:
|
|
156
|
+
dbs[interface.agent.db.id] = interface.agent.db
|
|
157
|
+
elif interface.team and interface.team.db:
|
|
158
|
+
dbs[interface.team.db.id] = interface.team.db
|
|
159
|
+
|
|
160
|
+
self.dbs = dbs
|
|
161
|
+
|
|
162
|
+
def _auto_discover_knowledge_instances(self) -> None:
|
|
163
|
+
"""Auto-discover the knowledge instances used by all contextual agents, teams and workflows."""
|
|
164
|
+
knowledge_instances = []
|
|
165
|
+
for agent in self.agents or []:
|
|
166
|
+
if agent.knowledge:
|
|
167
|
+
knowledge_instances.append(agent.knowledge)
|
|
168
|
+
|
|
169
|
+
for team in self.teams or []:
|
|
170
|
+
if team.knowledge:
|
|
171
|
+
knowledge_instances.append(team.knowledge)
|
|
172
|
+
|
|
173
|
+
self.knowledge_instances = knowledge_instances
|
|
174
|
+
|
|
175
|
+
def _get_session_config(self) -> SessionConfig:
|
|
176
|
+
session_config = self.config.session if self.config and self.config.session else SessionConfig()
|
|
177
|
+
|
|
178
|
+
if session_config.dbs is None:
|
|
179
|
+
session_config.dbs = []
|
|
180
|
+
|
|
181
|
+
multiple_dbs: bool = len(self.dbs.keys()) > 1
|
|
182
|
+
dbs_with_specific_config = [db.db_id for db in session_config.dbs]
|
|
183
|
+
|
|
184
|
+
for db_id in self.dbs.keys():
|
|
185
|
+
if db_id not in dbs_with_specific_config:
|
|
186
|
+
session_config.dbs.append(
|
|
187
|
+
DatabaseConfig(
|
|
188
|
+
db_id=db_id,
|
|
189
|
+
domain_config=SessionDomainConfig(
|
|
190
|
+
display_name="Sessions" if not multiple_dbs else "Sessions " + db_id
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return session_config
|
|
196
|
+
|
|
197
|
+
def _get_memory_config(self) -> MemoryConfig:
|
|
198
|
+
memory_config = self.config.memory if self.config and self.config.memory else MemoryConfig()
|
|
199
|
+
|
|
200
|
+
if memory_config.dbs is None:
|
|
201
|
+
memory_config.dbs = []
|
|
202
|
+
|
|
203
|
+
multiple_dbs: bool = len(self.dbs.keys()) > 1
|
|
204
|
+
dbs_with_specific_config = [db.db_id for db in memory_config.dbs]
|
|
205
|
+
|
|
206
|
+
for db_id in self.dbs.keys():
|
|
207
|
+
if db_id not in dbs_with_specific_config:
|
|
208
|
+
memory_config.dbs.append(
|
|
209
|
+
DatabaseConfig(
|
|
210
|
+
db_id=db_id,
|
|
211
|
+
domain_config=MemoryDomainConfig(
|
|
212
|
+
display_name="Memory" if not multiple_dbs else "Memory " + db_id
|
|
213
|
+
),
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
return memory_config
|
|
218
|
+
|
|
219
|
+
def _get_knowledge_config(self) -> KnowledgeConfig:
|
|
220
|
+
knowledge_config = self.config.knowledge if self.config and self.config.knowledge else KnowledgeConfig()
|
|
221
|
+
|
|
222
|
+
if knowledge_config.dbs is None:
|
|
223
|
+
knowledge_config.dbs = []
|
|
224
|
+
|
|
225
|
+
multiple_dbs: bool = len(self.dbs.keys()) > 1
|
|
226
|
+
dbs_with_specific_config = [db.db_id for db in knowledge_config.dbs]
|
|
227
|
+
|
|
228
|
+
for db_id in self.dbs.keys():
|
|
229
|
+
if db_id not in dbs_with_specific_config:
|
|
230
|
+
knowledge_config.dbs.append(
|
|
231
|
+
DatabaseConfig(
|
|
232
|
+
db_id=db_id,
|
|
233
|
+
domain_config=KnowledgeDomainConfig(
|
|
234
|
+
display_name="Knowledge" if not multiple_dbs else "Knowledge " + db_id
|
|
235
|
+
),
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return knowledge_config
|
|
240
|
+
|
|
241
|
+
def _get_metrics_config(self) -> MetricsConfig:
|
|
242
|
+
metrics_config = self.config.metrics if self.config and self.config.metrics else MetricsConfig()
|
|
243
|
+
|
|
244
|
+
if metrics_config.dbs is None:
|
|
245
|
+
metrics_config.dbs = []
|
|
246
|
+
|
|
247
|
+
multiple_dbs: bool = len(self.dbs.keys()) > 1
|
|
248
|
+
dbs_with_specific_config = [db.db_id for db in metrics_config.dbs]
|
|
249
|
+
|
|
250
|
+
for db_id in self.dbs.keys():
|
|
251
|
+
if db_id not in dbs_with_specific_config:
|
|
252
|
+
metrics_config.dbs.append(
|
|
253
|
+
DatabaseConfig(
|
|
254
|
+
db_id=db_id,
|
|
255
|
+
domain_config=MetricsDomainConfig(
|
|
256
|
+
display_name="Metrics" if not multiple_dbs else "Metrics " + db_id
|
|
257
|
+
),
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
return metrics_config
|
|
262
|
+
|
|
263
|
+
def _get_evals_config(self) -> EvalsConfig:
|
|
264
|
+
evals_config = self.config.evals if self.config and self.config.evals else EvalsConfig()
|
|
265
|
+
|
|
266
|
+
if evals_config.dbs is None:
|
|
267
|
+
evals_config.dbs = []
|
|
268
|
+
|
|
269
|
+
multiple_dbs: bool = len(self.dbs.keys()) > 1
|
|
270
|
+
dbs_with_specific_config = [db.db_id for db in evals_config.dbs]
|
|
271
|
+
|
|
272
|
+
for db_id in self.dbs.keys():
|
|
273
|
+
if db_id not in dbs_with_specific_config:
|
|
274
|
+
evals_config.dbs.append(
|
|
275
|
+
DatabaseConfig(
|
|
276
|
+
db_id=db_id,
|
|
277
|
+
domain_config=EvalsDomainConfig(display_name="Evals" if not multiple_dbs else "Evals " + db_id),
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
return evals_config
|
|
282
|
+
|
|
283
|
+
def _setup_routers(self) -> None:
|
|
284
|
+
"""Add all routers to the FastAPI app."""
|
|
285
|
+
if not self.dbs or not self.fastapi_app:
|
|
286
|
+
return
|
|
287
|
+
|
|
288
|
+
routers = [
|
|
289
|
+
get_session_router(dbs=self.dbs),
|
|
290
|
+
get_memory_router(dbs=self.dbs),
|
|
291
|
+
get_eval_router(dbs=self.dbs, agents=self.agents, teams=self.teams),
|
|
292
|
+
get_metrics_router(dbs=self.dbs),
|
|
293
|
+
get_knowledge_router(knowledge_instances=self.knowledge_instances),
|
|
294
|
+
]
|
|
295
|
+
|
|
296
|
+
for router in routers:
|
|
297
|
+
self.fastapi_app.include_router(router)
|
|
298
|
+
|
|
299
|
+
def set_os_id(self) -> str:
|
|
300
|
+
# If os_id is already set, keep it instead of overriding with UUID
|
|
301
|
+
if self.os_id is None:
|
|
302
|
+
self.os_id = str(uuid4())
|
|
303
|
+
|
|
304
|
+
return self.os_id
|
|
305
|
+
|
|
306
|
+
def get_app(self) -> FastAPI:
|
|
307
|
+
if not self.fastapi_app:
|
|
308
|
+
self.fastapi_app = FastAPI(
|
|
309
|
+
title=self.settings.title,
|
|
310
|
+
docs_url="/docs" if self.settings.docs_enabled else None,
|
|
311
|
+
redoc_url="/redoc" if self.settings.docs_enabled else None,
|
|
312
|
+
openapi_url="/openapi.json" if self.settings.docs_enabled else None,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
if not self.fastapi_app:
|
|
316
|
+
raise Exception("API App could not be created.")
|
|
317
|
+
|
|
318
|
+
@self.fastapi_app.exception_handler(HTTPException)
|
|
319
|
+
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
|
|
320
|
+
return JSONResponse(
|
|
321
|
+
status_code=exc.status_code,
|
|
322
|
+
content={"detail": str(exc.detail)},
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
async def general_exception_handler(request: Request, call_next):
|
|
326
|
+
try:
|
|
327
|
+
return await call_next(request)
|
|
328
|
+
except Exception as e:
|
|
329
|
+
return JSONResponse(
|
|
330
|
+
status_code=e.status_code if hasattr(e, "status_code") else 500, # type: ignore
|
|
331
|
+
content={"detail": str(e)},
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
self.fastapi_app.middleware("http")(general_exception_handler)
|
|
335
|
+
|
|
336
|
+
self.fastapi_app.include_router(get_base_router(self, settings=self.settings))
|
|
337
|
+
|
|
338
|
+
for interface in self.interfaces:
|
|
339
|
+
interface_router = interface.get_router()
|
|
340
|
+
self.fastapi_app.include_router(interface_router)
|
|
341
|
+
self.interfaces_loaded.append((interface.type, interface.router_prefix))
|
|
342
|
+
|
|
343
|
+
self._auto_discover_databases()
|
|
344
|
+
self._auto_discover_knowledge_instances()
|
|
345
|
+
self._setup_routers()
|
|
346
|
+
|
|
347
|
+
self.fastapi_app.add_middleware(
|
|
348
|
+
CORSMiddleware,
|
|
349
|
+
allow_origins=self.settings.cors_origin_list, # type: ignore
|
|
350
|
+
allow_credentials=True,
|
|
351
|
+
allow_methods=["*"],
|
|
352
|
+
allow_headers=["*"],
|
|
353
|
+
expose_headers=["*"],
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
return self.fastapi_app
|
|
357
|
+
|
|
358
|
+
def serve(
|
|
359
|
+
self,
|
|
360
|
+
app: Union[str, FastAPI],
|
|
361
|
+
*,
|
|
362
|
+
host: str = "localhost",
|
|
363
|
+
port: int = 7777,
|
|
364
|
+
reload: bool = False,
|
|
365
|
+
**kwargs,
|
|
366
|
+
):
|
|
367
|
+
import uvicorn
|
|
368
|
+
|
|
369
|
+
if getenv("AGNO_API_RUNTIME", "").lower() == "stg":
|
|
370
|
+
public_endpoint = "https://os-stg.agno.com/"
|
|
371
|
+
else:
|
|
372
|
+
public_endpoint = "https://os.agno.com/"
|
|
373
|
+
|
|
374
|
+
# Create a terminal panel to announce OS initialization and provide useful info
|
|
375
|
+
from rich.align import Align
|
|
376
|
+
from rich.console import Console, Group
|
|
377
|
+
|
|
378
|
+
aligned_endpoint = Align.center(f"[bold cyan]{public_endpoint}[/bold cyan]")
|
|
379
|
+
connection_endpoint = f"\n\n[bold dark_orange]Running on:[/bold dark_orange] http://{host}:{port}"
|
|
380
|
+
|
|
381
|
+
console = Console()
|
|
382
|
+
console.print(
|
|
383
|
+
Panel(
|
|
384
|
+
Group(aligned_endpoint, connection_endpoint),
|
|
385
|
+
title="AgentOS",
|
|
386
|
+
expand=False,
|
|
387
|
+
border_style="dark_orange",
|
|
388
|
+
box=box.DOUBLE_EDGE,
|
|
389
|
+
padding=(2, 2),
|
|
390
|
+
)
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs)
|
agno/os/auth.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from fastapi import Header, HTTPException
|
|
4
|
+
from fastapi.security import HTTPBearer
|
|
5
|
+
|
|
6
|
+
from agno.os.settings import AgnoAPISettings
|
|
7
|
+
|
|
8
|
+
# Create a global HTTPBearer instance
|
|
9
|
+
security = HTTPBearer(auto_error=False)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_authentication_dependency(settings: AgnoAPISettings):
|
|
13
|
+
"""
|
|
14
|
+
Create an authentication dependency function for FastAPI routes.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
settings: The API settings containing the security key
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
A dependency function that can be used with FastAPI's Depends()
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def auth_dependency(authorization: Optional[str] = Header(None)) -> bool:
|
|
24
|
+
# If no security key is set, skip authentication entirely
|
|
25
|
+
if not settings or not settings.os_security_key:
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
# If security is enabled but no authorization header provided, fail
|
|
29
|
+
if not authorization:
|
|
30
|
+
raise HTTPException(status_code=401, detail="Authorization header required")
|
|
31
|
+
|
|
32
|
+
# Check if the authorization header starts with "Bearer "
|
|
33
|
+
if not authorization.startswith("Bearer "):
|
|
34
|
+
raise HTTPException(
|
|
35
|
+
status_code=401, detail="Invalid authorization header format. Expected 'Bearer <token>'"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Extract the token from the authorization header
|
|
39
|
+
token = authorization[7:] # Remove "Bearer " prefix
|
|
40
|
+
|
|
41
|
+
# Verify the token
|
|
42
|
+
if token != settings.os_security_key:
|
|
43
|
+
raise HTTPException(status_code=401, detail="Invalid authentication token")
|
|
44
|
+
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
return auth_dependency
|