agno 1.8.1__py3-none-any.whl → 2.0.0__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 +3143 -4170
- agno/api/agent.py +11 -67
- agno/api/api.py +5 -46
- agno/api/evals.py +8 -19
- 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 +11 -66
- 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 +1743 -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 +1432 -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 +882 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1045 -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 +1416 -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 +297 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1710 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +280 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1367 -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 +1712 -0
- agno/db/singlestore/utils.py +326 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1676 -0
- agno/db/sqlite/utils.py +268 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +154 -48
- 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 +15 -11
- 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 +1551 -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 +47 -65
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +58 -9
- agno/{document → knowledge}/reader/pdf_reader.py +71 -126
- agno/knowledge/reader/reader_factory.py +268 -0
- agno/knowledge/reader/s3_reader.py +101 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +128 -0
- agno/knowledge/reader/web_search_reader.py +366 -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 +269 -268
- 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 +131 -131
- agno/models/aws/bedrock.py +110 -182
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +346 -290
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/google/gemini.py +105 -46
- 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 +46 -151
- 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 +85 -47
- agno/models/openai/chat.py +154 -37
- agno/models/openai/responses.py +178 -105
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +15 -9
- 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 +497 -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 +77 -33
- 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 +32 -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 +29 -0
- agno/os/mcp.py +235 -0
- agno/os/router.py +1400 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +393 -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 +850 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +410 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +178 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +536 -0
- agno/os/schema.py +945 -0
- agno/{app/playground → os}/settings.py +7 -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/agent.py +633 -0
- agno/run/base.py +53 -77
- agno/run/cancel.py +81 -0
- agno/run/team.py +243 -96
- agno/run/workflow.py +550 -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 +3260 -4824
- 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 +43 -23
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +20 -17
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +8 -8
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +22 -12
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +17 -8
- 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 +36 -29
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +30 -30
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +127 -18
- agno/tools/giphy.py +23 -11
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +45 -61
- 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 +19 -34
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +32 -20
- agno/tools/mcp.py +1 -2
- 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 +33 -15
- agno/tools/models/gemini.py +59 -32
- agno/tools/models/groq.py +30 -23
- agno/tools/models/nebius.py +28 -12
- agno/tools/models_labs.py +40 -16
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +10 -8
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +58 -32
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +63 -47
- 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 +55 -42
- 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 +100 -123
- agno/utils/gemini.py +32 -2
- agno/utils/knowledge.py +29 -0
- agno/utils/log.py +54 -4
- agno/utils/mcp.py +68 -10
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +47 -4
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1669 -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/streamlit.py +481 -0
- 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 +334 -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} +207 -49
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2410 -696
- agno-2.0.0.dist-info/METADATA +494 -0
- agno-2.0.0.dist-info/RECORD +515 -0
- agno-2.0.0.dist-info/licenses/LICENSE +201 -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 -702
- 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/response.py +0 -467
- 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.1.dist-info/METADATA +0 -982
- agno-1.8.1.dist-info/RECORD +0 -566
- agno-1.8.1.dist-info/entry_points.txt +0 -3
- agno-1.8.1.dist-info/licenses/LICENSE +0 -375
- /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.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/api/user.py
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
from typing import Dict, List, Optional, Union
|
|
2
|
-
|
|
3
|
-
from httpx import Response, codes
|
|
4
|
-
|
|
5
|
-
from agno.api.api import api, invalid_response
|
|
6
|
-
from agno.api.routes import ApiRoutes
|
|
7
|
-
from agno.api.schemas.user import EmailPasswordAuthSchema, UserSchema
|
|
8
|
-
from agno.cli.config import AgnoCliConfig
|
|
9
|
-
from agno.cli.settings import agno_cli_settings
|
|
10
|
-
from agno.utils.log import logger
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def user_ping() -> bool:
|
|
14
|
-
if not agno_cli_settings.api_enabled:
|
|
15
|
-
return False
|
|
16
|
-
|
|
17
|
-
logger.debug("--**-- Ping user api")
|
|
18
|
-
with api.Client() as api_client:
|
|
19
|
-
try:
|
|
20
|
-
r: Response = api_client.get(ApiRoutes.USER_HEALTH)
|
|
21
|
-
if invalid_response(r):
|
|
22
|
-
return False
|
|
23
|
-
|
|
24
|
-
if r.status_code == codes.OK:
|
|
25
|
-
return True
|
|
26
|
-
except Exception as e:
|
|
27
|
-
logger.debug(f"Could not ping user api: {e}")
|
|
28
|
-
return False
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def authenticate_and_get_user(auth_token: str, existing_user: Optional[UserSchema] = None) -> Optional[UserSchema]:
|
|
32
|
-
if not agno_cli_settings.api_enabled:
|
|
33
|
-
return None
|
|
34
|
-
|
|
35
|
-
from agno.cli.credentials import read_auth_token
|
|
36
|
-
|
|
37
|
-
logger.debug("--**-- Getting user")
|
|
38
|
-
auth_header = {agno_cli_settings.auth_token_header: auth_token}
|
|
39
|
-
anon_user = None
|
|
40
|
-
if existing_user is not None:
|
|
41
|
-
if existing_user.email == "anon":
|
|
42
|
-
logger.debug(f"Claiming anonymous user: {existing_user.id_user}")
|
|
43
|
-
anon_user = {
|
|
44
|
-
"email": existing_user.email,
|
|
45
|
-
"id_user": existing_user.id_user,
|
|
46
|
-
"auth_token": read_auth_token() or "",
|
|
47
|
-
}
|
|
48
|
-
with api.Client() as api_client:
|
|
49
|
-
try:
|
|
50
|
-
r: Response = api_client.post(ApiRoutes.USER_CLI_AUTH, headers=auth_header, json=anon_user)
|
|
51
|
-
if invalid_response(r):
|
|
52
|
-
return None
|
|
53
|
-
|
|
54
|
-
user_data = r.json()
|
|
55
|
-
if not isinstance(user_data, dict):
|
|
56
|
-
return None
|
|
57
|
-
|
|
58
|
-
return UserSchema.model_validate(user_data)
|
|
59
|
-
|
|
60
|
-
except Exception as e:
|
|
61
|
-
logger.debug(f"Could not authenticate user: {e}")
|
|
62
|
-
return None
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def sign_in_user(sign_in_data: EmailPasswordAuthSchema) -> Optional[UserSchema]:
|
|
66
|
-
if not agno_cli_settings.api_enabled:
|
|
67
|
-
return None
|
|
68
|
-
|
|
69
|
-
from agno.cli.credentials import save_auth_token
|
|
70
|
-
|
|
71
|
-
logger.debug("--**-- Signing in user")
|
|
72
|
-
with api.Client() as api_client:
|
|
73
|
-
try:
|
|
74
|
-
r: Response = api_client.post(ApiRoutes.USER_SIGN_IN, json=sign_in_data.model_dump())
|
|
75
|
-
if invalid_response(r):
|
|
76
|
-
return None
|
|
77
|
-
|
|
78
|
-
agno_auth_token = r.headers.get(agno_cli_settings.auth_token_header)
|
|
79
|
-
if agno_auth_token is None:
|
|
80
|
-
logger.error("Could not authenticate user")
|
|
81
|
-
return None
|
|
82
|
-
|
|
83
|
-
user_data = r.json()
|
|
84
|
-
if not isinstance(user_data, dict):
|
|
85
|
-
return None
|
|
86
|
-
|
|
87
|
-
current_user: UserSchema = UserSchema.model_validate(user_data)
|
|
88
|
-
|
|
89
|
-
if current_user is not None:
|
|
90
|
-
save_auth_token(agno_auth_token)
|
|
91
|
-
return current_user
|
|
92
|
-
except Exception as e:
|
|
93
|
-
logger.debug(f"Could not sign in user: {e}")
|
|
94
|
-
return None
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def user_is_authenticated() -> bool:
|
|
98
|
-
if not agno_cli_settings.api_enabled:
|
|
99
|
-
return False
|
|
100
|
-
|
|
101
|
-
logger.debug("--**-- Checking if user is authenticated")
|
|
102
|
-
agno_config: Optional[AgnoCliConfig] = AgnoCliConfig.from_saved_config()
|
|
103
|
-
if agno_config is None:
|
|
104
|
-
return False
|
|
105
|
-
user: Optional[UserSchema] = agno_config.user
|
|
106
|
-
if user is None:
|
|
107
|
-
return False
|
|
108
|
-
|
|
109
|
-
with api.AuthenticatedClient() as api_client:
|
|
110
|
-
try:
|
|
111
|
-
r: Response = api_client.post(
|
|
112
|
-
ApiRoutes.USER_AUTHENTICATE, json=user.model_dump(include={"id_user", "email"})
|
|
113
|
-
)
|
|
114
|
-
if invalid_response(r):
|
|
115
|
-
return False
|
|
116
|
-
|
|
117
|
-
response_json: Union[Dict, List] = r.json()
|
|
118
|
-
if response_json is None or not isinstance(response_json, dict):
|
|
119
|
-
logger.error("Could not parse response")
|
|
120
|
-
return False
|
|
121
|
-
if response_json.get("status") == "success":
|
|
122
|
-
return True
|
|
123
|
-
except Exception as e:
|
|
124
|
-
logger.debug(f"Could not check if user is authenticated: {e}")
|
|
125
|
-
return False
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def create_anon_user() -> Optional[UserSchema]:
|
|
129
|
-
if not agno_cli_settings.api_enabled:
|
|
130
|
-
return None
|
|
131
|
-
|
|
132
|
-
from agno.cli.credentials import save_auth_token
|
|
133
|
-
|
|
134
|
-
logger.debug("--**-- Creating anon user")
|
|
135
|
-
with api.Client() as api_client:
|
|
136
|
-
try:
|
|
137
|
-
r: Response = api_client.post(
|
|
138
|
-
ApiRoutes.USER_CREATE_ANON,
|
|
139
|
-
json={"user": {"email": "anon", "username": "anon", "is_machine": True}},
|
|
140
|
-
timeout=2.0,
|
|
141
|
-
)
|
|
142
|
-
if invalid_response(r):
|
|
143
|
-
return None
|
|
144
|
-
|
|
145
|
-
agno_auth_token = r.headers.get(agno_cli_settings.auth_token_header)
|
|
146
|
-
if agno_auth_token is None:
|
|
147
|
-
logger.debug("Could not create anon user")
|
|
148
|
-
return None
|
|
149
|
-
|
|
150
|
-
user_data = r.json()
|
|
151
|
-
if not isinstance(user_data, dict):
|
|
152
|
-
return None
|
|
153
|
-
|
|
154
|
-
current_user: UserSchema = UserSchema.model_validate(user_data)
|
|
155
|
-
if current_user is not None:
|
|
156
|
-
save_auth_token(agno_auth_token)
|
|
157
|
-
return current_user
|
|
158
|
-
except Exception as e:
|
|
159
|
-
logger.debug(f"Could not create anon user: {e}")
|
|
160
|
-
return None
|
agno/api/workflows.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from agno.api.api import api
|
|
2
|
-
from agno.api.routes import ApiRoutes
|
|
3
|
-
from agno.api.schemas.workflows import WorkflowCreate
|
|
4
|
-
from agno.cli.settings import agno_cli_settings
|
|
5
|
-
from agno.utils.log import log_debug
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def create_workflow(workflow: WorkflowCreate) -> None:
|
|
9
|
-
if not agno_cli_settings.api_enabled:
|
|
10
|
-
return
|
|
11
|
-
|
|
12
|
-
with api.AuthenticatedClient() as api_client:
|
|
13
|
-
try:
|
|
14
|
-
api_client.post(
|
|
15
|
-
ApiRoutes.WORKFLOW_CREATE,
|
|
16
|
-
json=workflow.model_dump(exclude_none=True),
|
|
17
|
-
)
|
|
18
|
-
except Exception as e:
|
|
19
|
-
log_debug(f"Could not create Workflow: {e}")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
async def acreate_workflow(workflow: WorkflowCreate) -> None:
|
|
23
|
-
if not agno_cli_settings.api_enabled:
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
async with api.AuthenticatedAsyncClient() as api_client:
|
|
27
|
-
try:
|
|
28
|
-
await api_client.post(
|
|
29
|
-
ApiRoutes.WORKFLOW_CREATE,
|
|
30
|
-
json=workflow.model_dump(exclude_none=True),
|
|
31
|
-
)
|
|
32
|
-
except Exception as e:
|
|
33
|
-
log_debug(f"Could not create Team: {e}")
|
agno/api/workspace.py
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
from typing import Dict, List, Optional, Union
|
|
2
|
-
|
|
3
|
-
from httpx import Response
|
|
4
|
-
|
|
5
|
-
from agno.api.api import api, invalid_response
|
|
6
|
-
from agno.api.routes import ApiRoutes
|
|
7
|
-
from agno.api.schemas.user import TeamIdentifier, TeamSchema, UserSchema
|
|
8
|
-
from agno.api.schemas.workspace import (
|
|
9
|
-
WorkspaceCreate,
|
|
10
|
-
WorkspaceEvent,
|
|
11
|
-
WorkspaceSchema,
|
|
12
|
-
WorkspaceUpdate,
|
|
13
|
-
)
|
|
14
|
-
from agno.cli.settings import agno_cli_settings
|
|
15
|
-
from agno.utils.log import logger
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def get_teams_for_user(user: UserSchema) -> Optional[List[TeamSchema]]:
|
|
19
|
-
logger.debug("--**-- Reading teams for user")
|
|
20
|
-
with api.AuthenticatedClient() as api_client:
|
|
21
|
-
try:
|
|
22
|
-
r: Response = api_client.post(
|
|
23
|
-
ApiRoutes.TEAM_READ_ALL,
|
|
24
|
-
json={
|
|
25
|
-
"user": user.model_dump(include={"id_user", "email"}),
|
|
26
|
-
},
|
|
27
|
-
timeout=2.0,
|
|
28
|
-
)
|
|
29
|
-
if invalid_response(r):
|
|
30
|
-
return None
|
|
31
|
-
|
|
32
|
-
response_json: Optional[List[Dict]] = r.json()
|
|
33
|
-
if response_json is None:
|
|
34
|
-
return None
|
|
35
|
-
|
|
36
|
-
teams: List[TeamSchema] = [TeamSchema.model_validate(team) for team in response_json]
|
|
37
|
-
return teams
|
|
38
|
-
except Exception as e:
|
|
39
|
-
logger.debug(f"Could not read teams: {e}")
|
|
40
|
-
return None
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def create_workspace_for_user(
|
|
44
|
-
user: UserSchema, workspace: WorkspaceCreate, team: Optional[TeamIdentifier] = None
|
|
45
|
-
) -> Optional[WorkspaceSchema]:
|
|
46
|
-
logger.debug("--**-- Creating workspace")
|
|
47
|
-
with api.AuthenticatedClient() as api_client:
|
|
48
|
-
try:
|
|
49
|
-
payload = {
|
|
50
|
-
"user": user.model_dump(include={"id_user", "email"}),
|
|
51
|
-
"workspace": workspace.model_dump(exclude_none=True),
|
|
52
|
-
}
|
|
53
|
-
if team is not None:
|
|
54
|
-
payload["team"] = team.model_dump(exclude_none=True)
|
|
55
|
-
|
|
56
|
-
r: Response = api_client.post(
|
|
57
|
-
ApiRoutes.WORKSPACE_CREATE,
|
|
58
|
-
json=payload,
|
|
59
|
-
timeout=2.0,
|
|
60
|
-
)
|
|
61
|
-
if invalid_response(r):
|
|
62
|
-
try:
|
|
63
|
-
error_msg = r.json().get("detail", "Permission denied")
|
|
64
|
-
except Exception:
|
|
65
|
-
error_msg = f"Could not create workspace: {r.text}"
|
|
66
|
-
logger.error(error_msg)
|
|
67
|
-
return None
|
|
68
|
-
|
|
69
|
-
response_json: Union[Dict, List] = r.json()
|
|
70
|
-
if response_json is None:
|
|
71
|
-
return None
|
|
72
|
-
|
|
73
|
-
created_workspace: WorkspaceSchema = WorkspaceSchema.model_validate(response_json)
|
|
74
|
-
if created_workspace is not None:
|
|
75
|
-
return created_workspace
|
|
76
|
-
except Exception as e:
|
|
77
|
-
logger.debug(f"Could not create workspace: {e}")
|
|
78
|
-
return None
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def update_workspace_for_user(user: UserSchema, workspace: WorkspaceUpdate) -> Optional[WorkspaceSchema]:
|
|
82
|
-
logger.debug("--**-- Updating workspace for user")
|
|
83
|
-
with api.AuthenticatedClient() as api_client:
|
|
84
|
-
try:
|
|
85
|
-
payload = {
|
|
86
|
-
"user": user.model_dump(include={"id_user", "email"}),
|
|
87
|
-
"workspace": workspace.model_dump(exclude_none=True),
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
r: Response = api_client.post(
|
|
91
|
-
ApiRoutes.WORKSPACE_UPDATE,
|
|
92
|
-
json=payload,
|
|
93
|
-
)
|
|
94
|
-
if invalid_response(r):
|
|
95
|
-
try:
|
|
96
|
-
error_msg = r.json().get("detail", "Could not update workspace")
|
|
97
|
-
except Exception:
|
|
98
|
-
error_msg = f"Could not update workspace: {r.text}"
|
|
99
|
-
logger.error(error_msg)
|
|
100
|
-
return None
|
|
101
|
-
|
|
102
|
-
response_json: Union[Dict, List] = r.json()
|
|
103
|
-
if response_json is None:
|
|
104
|
-
return None
|
|
105
|
-
|
|
106
|
-
updated_workspace: WorkspaceSchema = WorkspaceSchema.model_validate(response_json)
|
|
107
|
-
if updated_workspace is not None:
|
|
108
|
-
return updated_workspace
|
|
109
|
-
except Exception as e:
|
|
110
|
-
logger.debug(f"Could not update workspace: {e}")
|
|
111
|
-
return None
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def update_workspace_for_team(
|
|
115
|
-
user: UserSchema, workspace: WorkspaceUpdate, team: TeamIdentifier
|
|
116
|
-
) -> Optional[WorkspaceSchema]:
|
|
117
|
-
logger.debug("--**-- Updating workspace for team")
|
|
118
|
-
with api.AuthenticatedClient() as api_client:
|
|
119
|
-
try:
|
|
120
|
-
payload = {
|
|
121
|
-
"user": user.model_dump(include={"id_user", "email"}),
|
|
122
|
-
"team_workspace": workspace.model_dump(exclude_none=True).update({"id_team": team.id_team}),
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
r: Response = api_client.post(
|
|
126
|
-
ApiRoutes.WORKSPACE_UPDATE,
|
|
127
|
-
json=payload,
|
|
128
|
-
)
|
|
129
|
-
if invalid_response(r):
|
|
130
|
-
try:
|
|
131
|
-
error_msg = r.json().get("detail", "Could not update workspace")
|
|
132
|
-
except Exception:
|
|
133
|
-
error_msg = f"Could not update workspace: {r.text}"
|
|
134
|
-
logger.error(error_msg)
|
|
135
|
-
return None
|
|
136
|
-
|
|
137
|
-
response_json: Union[Dict, List] = r.json()
|
|
138
|
-
if response_json is None:
|
|
139
|
-
return None
|
|
140
|
-
|
|
141
|
-
updated_workspace: WorkspaceSchema = WorkspaceSchema.model_validate(response_json)
|
|
142
|
-
if updated_workspace is not None:
|
|
143
|
-
return updated_workspace
|
|
144
|
-
except Exception as e:
|
|
145
|
-
logger.debug(f"Could not update workspace: {e}")
|
|
146
|
-
return None
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def log_workspace_event(user: UserSchema, workspace_event: WorkspaceEvent) -> bool:
|
|
150
|
-
if not agno_cli_settings.api_enabled:
|
|
151
|
-
return False
|
|
152
|
-
|
|
153
|
-
logger.debug("--**-- Log workspace event")
|
|
154
|
-
with api.AuthenticatedClient() as api_client:
|
|
155
|
-
try:
|
|
156
|
-
r: Response = api_client.post(
|
|
157
|
-
ApiRoutes.WORKSPACE_EVENT_CREATE,
|
|
158
|
-
json={
|
|
159
|
-
"user": user.model_dump(include={"id_user", "email"}),
|
|
160
|
-
"event": workspace_event.model_dump(exclude_none=True),
|
|
161
|
-
},
|
|
162
|
-
)
|
|
163
|
-
if invalid_response(r):
|
|
164
|
-
return False
|
|
165
|
-
|
|
166
|
-
response_json: Union[Dict, List] = r.json()
|
|
167
|
-
if response_json is None:
|
|
168
|
-
return False
|
|
169
|
-
|
|
170
|
-
if isinstance(response_json, dict) and response_json.get("status") == "success":
|
|
171
|
-
return True
|
|
172
|
-
return False
|
|
173
|
-
except Exception as e:
|
|
174
|
-
logger.debug(f"Could not log workspace event: {e}")
|
|
175
|
-
return False
|
agno/app/agui/__init__.py
DELETED
agno/app/agui/app.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""Main class for the AG-UI app, used to expose an Agno Agent or Team in an AG-UI compatible format."""
|
|
2
|
-
|
|
3
|
-
from fastapi.routing import APIRouter
|
|
4
|
-
|
|
5
|
-
from agno.app.agui.async_router import get_async_agui_router
|
|
6
|
-
from agno.app.agui.sync_router import get_sync_agui_router
|
|
7
|
-
from agno.app.base import BaseAPIApp
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class AGUIApp(BaseAPIApp):
|
|
11
|
-
type = "agui"
|
|
12
|
-
|
|
13
|
-
def get_router(self) -> APIRouter:
|
|
14
|
-
return get_sync_agui_router(agent=self.agent, team=self.team)
|
|
15
|
-
|
|
16
|
-
def get_async_router(self) -> APIRouter:
|
|
17
|
-
return get_async_agui_router(agent=self.agent, team=self.team)
|
agno/app/agui/sync_router.py
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
"""Async router handling exposing an Agno Agent or Team in an AG-UI compatible format."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
import uuid
|
|
5
|
-
from typing import Iterator, Optional
|
|
6
|
-
|
|
7
|
-
from ag_ui.core import (
|
|
8
|
-
BaseEvent,
|
|
9
|
-
EventType,
|
|
10
|
-
RunAgentInput,
|
|
11
|
-
RunErrorEvent,
|
|
12
|
-
RunStartedEvent,
|
|
13
|
-
)
|
|
14
|
-
from ag_ui.encoder import EventEncoder
|
|
15
|
-
from fastapi import APIRouter
|
|
16
|
-
from fastapi.responses import StreamingResponse
|
|
17
|
-
|
|
18
|
-
from agno.agent.agent import Agent
|
|
19
|
-
from agno.app.agui.utils import convert_agui_messages_to_agno_messages, stream_agno_response_as_agui_events
|
|
20
|
-
from agno.team.team import Team
|
|
21
|
-
|
|
22
|
-
logger = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def run_agent(agent: Agent, run_input: RunAgentInput) -> Iterator[BaseEvent]:
|
|
26
|
-
"""Run the contextual Agent, mapping AG-UI input messages to Agno format, and streaming the response in AG-UI format."""
|
|
27
|
-
run_id = run_input.run_id or str(uuid.uuid4())
|
|
28
|
-
|
|
29
|
-
try:
|
|
30
|
-
# Preparing the input for the Agent and emitting the run started event
|
|
31
|
-
messages = convert_agui_messages_to_agno_messages(run_input.messages or [])
|
|
32
|
-
yield RunStartedEvent(type=EventType.RUN_STARTED, thread_id=run_input.thread_id, run_id=run_id)
|
|
33
|
-
|
|
34
|
-
# Request streaming response from agent
|
|
35
|
-
response_stream = agent.run(
|
|
36
|
-
messages=messages,
|
|
37
|
-
session_id=run_input.thread_id,
|
|
38
|
-
stream=True,
|
|
39
|
-
stream_intermediate_steps=True,
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
# Stream the response content in AG-UI format
|
|
43
|
-
for event in stream_agno_response_as_agui_events(
|
|
44
|
-
response_stream=response_stream, thread_id=run_input.thread_id, run_id=run_id
|
|
45
|
-
):
|
|
46
|
-
yield event
|
|
47
|
-
|
|
48
|
-
# Emit a RunErrorEvent if any error occurs
|
|
49
|
-
except Exception as e:
|
|
50
|
-
logger.error(f"Error running agent: {e}", exc_info=True)
|
|
51
|
-
yield RunErrorEvent(type=EventType.RUN_ERROR, message=str(e))
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def run_team(team: Team, input: RunAgentInput) -> Iterator[BaseEvent]:
|
|
55
|
-
"""Run the contextual Team, mapping AG-UI input messages to Agno format, and streaming the response in AG-UI format."""
|
|
56
|
-
run_id = input.run_id or str(uuid.uuid4())
|
|
57
|
-
try:
|
|
58
|
-
# Extract the last user message for team execution
|
|
59
|
-
messages = convert_agui_messages_to_agno_messages(input.messages or [])
|
|
60
|
-
yield RunStartedEvent(type=EventType.RUN_STARTED, thread_id=input.thread_id, run_id=run_id)
|
|
61
|
-
|
|
62
|
-
# Request streaming response from team
|
|
63
|
-
response_stream = team.run(
|
|
64
|
-
message=messages,
|
|
65
|
-
session_id=input.thread_id,
|
|
66
|
-
stream=True,
|
|
67
|
-
stream_intermediate_steps=True,
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
# Stream the response content in AG-UI format
|
|
71
|
-
for event in stream_agno_response_as_agui_events(
|
|
72
|
-
response_stream=response_stream, thread_id=input.thread_id, run_id=run_id
|
|
73
|
-
):
|
|
74
|
-
yield event
|
|
75
|
-
|
|
76
|
-
except Exception as e:
|
|
77
|
-
logger.error(f"Error running team: {e}", exc_info=True)
|
|
78
|
-
yield RunErrorEvent(type=EventType.RUN_ERROR, message=str(e))
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def get_sync_agui_router(agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
|
|
82
|
-
"""Return an AG-UI compatible FastAPI router."""
|
|
83
|
-
if (agent is None and team is None) or (agent is not None and team is not None):
|
|
84
|
-
raise ValueError("One of 'agent' or 'team' must be provided.")
|
|
85
|
-
|
|
86
|
-
router = APIRouter()
|
|
87
|
-
encoder = EventEncoder()
|
|
88
|
-
|
|
89
|
-
def _run(run_input: RunAgentInput):
|
|
90
|
-
def event_generator():
|
|
91
|
-
if agent:
|
|
92
|
-
for event in run_agent(agent, run_input):
|
|
93
|
-
encoded_event = encoder.encode(event)
|
|
94
|
-
yield encoded_event
|
|
95
|
-
elif team:
|
|
96
|
-
for event in run_team(team, run_input):
|
|
97
|
-
encoded_event = encoder.encode(event)
|
|
98
|
-
yield encoded_event
|
|
99
|
-
|
|
100
|
-
return StreamingResponse(
|
|
101
|
-
event_generator(),
|
|
102
|
-
media_type="text/event-stream",
|
|
103
|
-
headers={
|
|
104
|
-
"Cache-Control": "no-cache",
|
|
105
|
-
"Connection": "keep-alive",
|
|
106
|
-
"Access-Control-Allow-Origin": "*",
|
|
107
|
-
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
|
|
108
|
-
"Access-Control-Allow-Headers": "*",
|
|
109
|
-
},
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
@router.post("/agui")
|
|
113
|
-
def run_agent_agui(run_input: RunAgentInput):
|
|
114
|
-
return _run(run_input)
|
|
115
|
-
|
|
116
|
-
@router.get("/status")
|
|
117
|
-
def get_status():
|
|
118
|
-
return {"status": "available"}
|
|
119
|
-
|
|
120
|
-
return router
|
agno/app/base.py
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from os import getenv
|
|
3
|
-
from typing import Any, Dict, Optional, Union
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
|
|
6
|
-
import uvicorn
|
|
7
|
-
from fastapi import FastAPI, HTTPException, Request
|
|
8
|
-
from fastapi.responses import JSONResponse
|
|
9
|
-
from fastapi.routing import APIRouter
|
|
10
|
-
from starlette.middleware.cors import CORSMiddleware
|
|
11
|
-
|
|
12
|
-
from agno.agent.agent import Agent
|
|
13
|
-
from agno.api.app import AppCreate, create_app
|
|
14
|
-
from agno.app.settings import APIAppSettings
|
|
15
|
-
from agno.team.team import Team
|
|
16
|
-
from agno.utils.log import log_debug, log_info
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class BaseAPIApp(ABC):
|
|
20
|
-
type: Optional[str] = None
|
|
21
|
-
|
|
22
|
-
def __init__(
|
|
23
|
-
self,
|
|
24
|
-
agent: Optional[Agent] = None,
|
|
25
|
-
team: Optional[Team] = None,
|
|
26
|
-
settings: Optional[APIAppSettings] = None,
|
|
27
|
-
api_app: Optional[FastAPI] = None,
|
|
28
|
-
router: Optional[APIRouter] = None,
|
|
29
|
-
monitoring: bool = True,
|
|
30
|
-
app_id: Optional[str] = None,
|
|
31
|
-
name: Optional[str] = None,
|
|
32
|
-
description: Optional[str] = None,
|
|
33
|
-
version: Optional[str] = None,
|
|
34
|
-
):
|
|
35
|
-
if not agent and not team:
|
|
36
|
-
raise ValueError("Either agent or team must be provided.")
|
|
37
|
-
|
|
38
|
-
if agent and team:
|
|
39
|
-
raise ValueError("Only one of agent or team can be provided.")
|
|
40
|
-
|
|
41
|
-
self.agent: Optional[Agent] = agent
|
|
42
|
-
self.team: Optional[Team] = team
|
|
43
|
-
self.settings: APIAppSettings = settings or APIAppSettings()
|
|
44
|
-
self.api_app: Optional[FastAPI] = api_app
|
|
45
|
-
self.router: Optional[APIRouter] = router
|
|
46
|
-
self.monitoring = monitoring
|
|
47
|
-
self.app_id: Optional[str] = app_id
|
|
48
|
-
self.name: Optional[str] = name
|
|
49
|
-
self.description = description
|
|
50
|
-
self.version = version
|
|
51
|
-
self.set_app_id()
|
|
52
|
-
|
|
53
|
-
if self.agent:
|
|
54
|
-
if not self.agent.app_id:
|
|
55
|
-
self.agent.app_id = self.app_id
|
|
56
|
-
self.agent.initialize_agent()
|
|
57
|
-
|
|
58
|
-
if self.team:
|
|
59
|
-
if not self.team.app_id:
|
|
60
|
-
self.team.app_id = self.app_id
|
|
61
|
-
self.team.initialize_team()
|
|
62
|
-
for member in self.team.members:
|
|
63
|
-
if isinstance(member, Agent):
|
|
64
|
-
if not member.app_id:
|
|
65
|
-
member.app_id = self.app_id
|
|
66
|
-
member.team_id = None
|
|
67
|
-
member.initialize_agent()
|
|
68
|
-
elif isinstance(member, Team):
|
|
69
|
-
member.initialize_team()
|
|
70
|
-
|
|
71
|
-
def set_app_id(self) -> str:
|
|
72
|
-
# If app_id is already set, keep it instead of overriding with UUID
|
|
73
|
-
if self.app_id is None:
|
|
74
|
-
self.app_id = str(uuid4())
|
|
75
|
-
|
|
76
|
-
# Don't override existing app_id
|
|
77
|
-
return self.app_id
|
|
78
|
-
|
|
79
|
-
def _set_monitoring(self) -> None:
|
|
80
|
-
monitor_env = getenv("AGNO_MONITOR")
|
|
81
|
-
if monitor_env is not None:
|
|
82
|
-
self.monitoring = monitor_env.lower() == "true"
|
|
83
|
-
|
|
84
|
-
@abstractmethod
|
|
85
|
-
def get_router(self) -> APIRouter:
|
|
86
|
-
raise NotImplementedError("get_router must be implemented")
|
|
87
|
-
|
|
88
|
-
@abstractmethod
|
|
89
|
-
def get_async_router(self) -> APIRouter:
|
|
90
|
-
raise NotImplementedError("get_async_router must be implemented")
|
|
91
|
-
|
|
92
|
-
def get_app(self, use_async: bool = True, prefix: str = "") -> FastAPI:
|
|
93
|
-
if not self.api_app:
|
|
94
|
-
kwargs = {
|
|
95
|
-
"title": self.settings.title,
|
|
96
|
-
}
|
|
97
|
-
if self.version:
|
|
98
|
-
kwargs["version"] = self.version
|
|
99
|
-
if self.settings.docs_enabled:
|
|
100
|
-
kwargs["docs_url"] = "/docs"
|
|
101
|
-
kwargs["redoc_url"] = "/redoc"
|
|
102
|
-
kwargs["openapi_url"] = "/openapi.json"
|
|
103
|
-
|
|
104
|
-
self.api_app = FastAPI(
|
|
105
|
-
**kwargs, # type: ignore
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if not self.api_app:
|
|
109
|
-
raise Exception("API App could not be created.")
|
|
110
|
-
|
|
111
|
-
@self.api_app.exception_handler(HTTPException)
|
|
112
|
-
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
|
|
113
|
-
return JSONResponse(
|
|
114
|
-
status_code=exc.status_code,
|
|
115
|
-
content={"detail": str(exc.detail)},
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
async def general_exception_handler(request: Request, call_next):
|
|
119
|
-
try:
|
|
120
|
-
return await call_next(request)
|
|
121
|
-
except Exception as e:
|
|
122
|
-
return JSONResponse(
|
|
123
|
-
status_code=e.status_code if hasattr(e, "status_code") else 500,
|
|
124
|
-
content={"detail": str(e)},
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
self.api_app.middleware("http")(general_exception_handler)
|
|
128
|
-
|
|
129
|
-
if not self.router:
|
|
130
|
-
self.router = APIRouter(prefix=prefix)
|
|
131
|
-
|
|
132
|
-
if not self.router:
|
|
133
|
-
raise Exception("API Router could not be created.")
|
|
134
|
-
|
|
135
|
-
if use_async:
|
|
136
|
-
self.router.include_router(self.get_async_router())
|
|
137
|
-
else:
|
|
138
|
-
self.router.include_router(self.get_router())
|
|
139
|
-
|
|
140
|
-
self.api_app.include_router(self.router)
|
|
141
|
-
|
|
142
|
-
self.api_app.add_middleware(
|
|
143
|
-
CORSMiddleware,
|
|
144
|
-
allow_origins=["*"],
|
|
145
|
-
allow_credentials=True,
|
|
146
|
-
allow_methods=["*"],
|
|
147
|
-
allow_headers=["*"],
|
|
148
|
-
expose_headers=["*"],
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
return self.api_app
|
|
152
|
-
|
|
153
|
-
def serve(
|
|
154
|
-
self,
|
|
155
|
-
app: Union[str, FastAPI],
|
|
156
|
-
*,
|
|
157
|
-
host: str = "localhost",
|
|
158
|
-
port: int = 7777,
|
|
159
|
-
reload: bool = False,
|
|
160
|
-
**kwargs,
|
|
161
|
-
):
|
|
162
|
-
self.set_app_id()
|
|
163
|
-
self.register_app_on_platform()
|
|
164
|
-
log_info(f"Starting API on {host}:{port}")
|
|
165
|
-
|
|
166
|
-
uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs)
|
|
167
|
-
|
|
168
|
-
def register_app_on_platform(self) -> None:
|
|
169
|
-
self._set_monitoring()
|
|
170
|
-
if not self.monitoring:
|
|
171
|
-
return
|
|
172
|
-
|
|
173
|
-
try:
|
|
174
|
-
log_debug(f"Creating app on Platform: {self.name}, {self.app_id}")
|
|
175
|
-
create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.to_dict()))
|
|
176
|
-
except Exception as e:
|
|
177
|
-
log_debug(f"Could not create Agent app: {e}")
|
|
178
|
-
log_debug(f"Agent app created: {self.name}, {self.app_id}")
|
|
179
|
-
|
|
180
|
-
def to_dict(self) -> Dict[str, Any]:
|
|
181
|
-
payload = {
|
|
182
|
-
"type": self.type,
|
|
183
|
-
"description": self.description,
|
|
184
|
-
}
|
|
185
|
-
payload = {k: v for k, v in payload.items() if v is not None}
|
|
186
|
-
return payload
|