agno 1.8.2__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/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 +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 +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 +128 -72
- 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 +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 +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 +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 +17 -18
- 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 +18 -33
- 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 +1 -1
- 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 +6 -12
- 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 -110
- 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 -1053
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -223
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1045
- 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 -3313
- 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.2.dist-info/METADATA +0 -982
- agno-1.8.2.dist-info/RECORD +0 -566
- agno-1.8.2.dist-info/entry_points.txt +0 -3
- agno-1.8.2.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.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/app/fastapi/sync_router.py
DELETED
|
@@ -1,448 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from dataclasses import asdict
|
|
3
|
-
from io import BytesIO
|
|
4
|
-
from typing import Any, Dict, Generator, List, Optional, Union, cast
|
|
5
|
-
from uuid import uuid4
|
|
6
|
-
|
|
7
|
-
from fastapi import APIRouter, File, Form, HTTPException, Query, UploadFile
|
|
8
|
-
from fastapi.responses import StreamingResponse
|
|
9
|
-
|
|
10
|
-
from agno.agent.agent import Agent, RunResponse
|
|
11
|
-
from agno.app.playground.utils import process_audio, process_document, process_image, process_video
|
|
12
|
-
from agno.media import Audio, Image, Video
|
|
13
|
-
from agno.media import File as FileMedia
|
|
14
|
-
from agno.run.base import RunStatus
|
|
15
|
-
from agno.run.response import RunResponseEvent
|
|
16
|
-
from agno.run.team import RunResponseErrorEvent as TeamRunResponseErrorEvent
|
|
17
|
-
from agno.run.team import TeamRunResponseEvent
|
|
18
|
-
from agno.run.v2.workflow import WorkflowErrorEvent
|
|
19
|
-
from agno.team.team import Team
|
|
20
|
-
from agno.utils.log import logger
|
|
21
|
-
from agno.workflow.v2.workflow import Workflow as WorkflowV2
|
|
22
|
-
from agno.workflow.workflow import Workflow
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def agent_chat_response_streamer(
|
|
26
|
-
agent: Agent,
|
|
27
|
-
message: str,
|
|
28
|
-
session_id: Optional[str] = None,
|
|
29
|
-
user_id: Optional[str] = None,
|
|
30
|
-
images: Optional[List[Image]] = None,
|
|
31
|
-
audio: Optional[List[Audio]] = None,
|
|
32
|
-
videos: Optional[List[Video]] = None,
|
|
33
|
-
) -> Generator:
|
|
34
|
-
try:
|
|
35
|
-
run_response = agent.run(
|
|
36
|
-
message,
|
|
37
|
-
session_id=session_id,
|
|
38
|
-
user_id=user_id,
|
|
39
|
-
images=images,
|
|
40
|
-
audio=audio,
|
|
41
|
-
videos=videos,
|
|
42
|
-
stream=True,
|
|
43
|
-
stream_intermediate_steps=True,
|
|
44
|
-
)
|
|
45
|
-
for run_response_chunk in run_response:
|
|
46
|
-
run_response_chunk = cast(RunResponseEvent, run_response_chunk)
|
|
47
|
-
yield run_response_chunk.to_json()
|
|
48
|
-
except Exception as e:
|
|
49
|
-
error_response = RunResponse(content=str(e), status=RunStatus.error)
|
|
50
|
-
yield error_response.to_json()
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def team_chat_response_streamer(
|
|
55
|
-
team: Team,
|
|
56
|
-
message: str,
|
|
57
|
-
session_id: Optional[str] = None,
|
|
58
|
-
user_id: Optional[str] = None,
|
|
59
|
-
images: Optional[List[Image]] = None,
|
|
60
|
-
audio: Optional[List[Audio]] = None,
|
|
61
|
-
videos: Optional[List[Video]] = None,
|
|
62
|
-
files: Optional[List[FileMedia]] = None,
|
|
63
|
-
) -> Generator:
|
|
64
|
-
try:
|
|
65
|
-
run_response = team.run(
|
|
66
|
-
message,
|
|
67
|
-
session_id=session_id,
|
|
68
|
-
user_id=user_id,
|
|
69
|
-
images=images,
|
|
70
|
-
audio=audio,
|
|
71
|
-
videos=videos,
|
|
72
|
-
files=files,
|
|
73
|
-
stream=True,
|
|
74
|
-
stream_intermediate_steps=True,
|
|
75
|
-
)
|
|
76
|
-
for run_response_chunk in run_response:
|
|
77
|
-
run_response_chunk = cast(TeamRunResponseEvent, run_response_chunk)
|
|
78
|
-
yield run_response_chunk.to_json()
|
|
79
|
-
except Exception as e:
|
|
80
|
-
error_response = TeamRunResponseErrorEvent(
|
|
81
|
-
content=str(e),
|
|
82
|
-
)
|
|
83
|
-
yield error_response.to_json()
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def workflow_response_streamer(
|
|
88
|
-
workflow: WorkflowV2,
|
|
89
|
-
body: Union[Dict[str, Any], str],
|
|
90
|
-
session_id: Optional[str] = None,
|
|
91
|
-
user_id: Optional[str] = None,
|
|
92
|
-
) -> Generator:
|
|
93
|
-
try:
|
|
94
|
-
if isinstance(body, dict):
|
|
95
|
-
run_response = workflow.run(
|
|
96
|
-
**body,
|
|
97
|
-
user_id=user_id,
|
|
98
|
-
session_id=session_id,
|
|
99
|
-
stream=True,
|
|
100
|
-
stream_intermediate_steps=True,
|
|
101
|
-
)
|
|
102
|
-
else:
|
|
103
|
-
run_response = workflow.run(
|
|
104
|
-
body,
|
|
105
|
-
user_id=user_id,
|
|
106
|
-
session_id=session_id,
|
|
107
|
-
stream=True,
|
|
108
|
-
stream_intermediate_steps=True,
|
|
109
|
-
)
|
|
110
|
-
for run_response_chunk in run_response:
|
|
111
|
-
yield run_response_chunk.to_json()
|
|
112
|
-
except Exception as e:
|
|
113
|
-
import traceback
|
|
114
|
-
|
|
115
|
-
traceback.print_exc(limit=3)
|
|
116
|
-
error_response = WorkflowErrorEvent(
|
|
117
|
-
error=str(e),
|
|
118
|
-
)
|
|
119
|
-
yield error_response.to_json()
|
|
120
|
-
return
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def get_sync_router(
|
|
124
|
-
agents: Optional[List[Agent]] = None, teams: Optional[List[Team]] = None, workflows: Optional[List[Workflow]] = None
|
|
125
|
-
) -> APIRouter:
|
|
126
|
-
router = APIRouter()
|
|
127
|
-
|
|
128
|
-
if agents is None and teams is None and workflows is None:
|
|
129
|
-
raise ValueError("Either agents, teams or workflows must be provided.")
|
|
130
|
-
|
|
131
|
-
@router.get("/status")
|
|
132
|
-
def status():
|
|
133
|
-
return {"status": "available"}
|
|
134
|
-
|
|
135
|
-
def agent_process_file(
|
|
136
|
-
files: List[UploadFile],
|
|
137
|
-
agent: Agent,
|
|
138
|
-
):
|
|
139
|
-
base64_images: List[Image] = []
|
|
140
|
-
base64_audios: List[Audio] = []
|
|
141
|
-
base64_videos: List[Video] = []
|
|
142
|
-
for file in files:
|
|
143
|
-
logger.info(f"Processing file: {file.content_type}")
|
|
144
|
-
if file.content_type in ["image/png", "image/jpeg", "image/jpg", "image/webp"]:
|
|
145
|
-
try:
|
|
146
|
-
base64_image = process_image(file)
|
|
147
|
-
base64_images.append(base64_image)
|
|
148
|
-
except Exception as e:
|
|
149
|
-
logger.error(f"Error processing image {file.filename}: {e}")
|
|
150
|
-
continue
|
|
151
|
-
elif file.content_type in ["audio/wav", "audio/mp3", "audio/mpeg"]:
|
|
152
|
-
try:
|
|
153
|
-
base64_audio = process_audio(file)
|
|
154
|
-
base64_audios.append(base64_audio)
|
|
155
|
-
except Exception as e:
|
|
156
|
-
logger.error(f"Error processing audio {file.filename}: {e}")
|
|
157
|
-
continue
|
|
158
|
-
elif file.content_type in [
|
|
159
|
-
"video/x-flv",
|
|
160
|
-
"video/quicktime",
|
|
161
|
-
"video/mpeg",
|
|
162
|
-
"video/mpegs",
|
|
163
|
-
"video/mpgs",
|
|
164
|
-
"video/mpg",
|
|
165
|
-
"video/mpg",
|
|
166
|
-
"video/mp4",
|
|
167
|
-
"video/webm",
|
|
168
|
-
"video/wmv",
|
|
169
|
-
"video/3gpp",
|
|
170
|
-
]:
|
|
171
|
-
try:
|
|
172
|
-
base64_video = process_video(file)
|
|
173
|
-
base64_videos.append(base64_video)
|
|
174
|
-
except Exception as e:
|
|
175
|
-
logger.error(f"Error processing video {file.filename}: {e}")
|
|
176
|
-
continue
|
|
177
|
-
else:
|
|
178
|
-
# Check for knowledge base before processing documents
|
|
179
|
-
if agent.knowledge is None:
|
|
180
|
-
raise HTTPException(status_code=404, detail="KnowledgeBase not found")
|
|
181
|
-
|
|
182
|
-
if file.content_type == "application/pdf":
|
|
183
|
-
from agno.document.reader.pdf_reader import PDFReader
|
|
184
|
-
|
|
185
|
-
contents = file.file.read()
|
|
186
|
-
pdf_file = BytesIO(contents)
|
|
187
|
-
pdf_file.name = file.filename
|
|
188
|
-
file_content = PDFReader().read(pdf_file)
|
|
189
|
-
if agent.knowledge is not None:
|
|
190
|
-
agent.knowledge.load_documents(file_content)
|
|
191
|
-
elif file.content_type == "text/csv":
|
|
192
|
-
from agno.document.reader.csv_reader import CSVReader
|
|
193
|
-
|
|
194
|
-
contents = file.file.read()
|
|
195
|
-
csv_file = BytesIO(contents)
|
|
196
|
-
csv_file.name = file.filename
|
|
197
|
-
file_content = CSVReader().read(csv_file)
|
|
198
|
-
if agent.knowledge is not None:
|
|
199
|
-
agent.knowledge.load_documents(file_content)
|
|
200
|
-
elif file.content_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
201
|
-
from agno.document.reader.docx_reader import DocxReader
|
|
202
|
-
|
|
203
|
-
contents = file.file.read()
|
|
204
|
-
docx_file = BytesIO(contents)
|
|
205
|
-
docx_file.name = file.filename
|
|
206
|
-
file_content = DocxReader().read(docx_file)
|
|
207
|
-
if agent.knowledge is not None:
|
|
208
|
-
agent.knowledge.load_documents(file_content)
|
|
209
|
-
elif file.content_type == "text/plain":
|
|
210
|
-
from agno.document.reader.text_reader import TextReader
|
|
211
|
-
|
|
212
|
-
contents = file.file.read()
|
|
213
|
-
text_file = BytesIO(contents)
|
|
214
|
-
text_file.name = file.filename
|
|
215
|
-
file_content = TextReader().read(text_file)
|
|
216
|
-
if agent.knowledge is not None:
|
|
217
|
-
agent.knowledge.load_documents(file_content)
|
|
218
|
-
|
|
219
|
-
elif file.content_type == "application/json":
|
|
220
|
-
from agno.document.reader.json_reader import JSONReader
|
|
221
|
-
|
|
222
|
-
contents = file.file.read()
|
|
223
|
-
json_file = BytesIO(contents)
|
|
224
|
-
json_file.name = file.filename
|
|
225
|
-
file_content = JSONReader().read(json_file)
|
|
226
|
-
if agent.knowledge is not None:
|
|
227
|
-
agent.knowledge.load_documents(file_content)
|
|
228
|
-
else:
|
|
229
|
-
raise HTTPException(status_code=400, detail="Unsupported file type")
|
|
230
|
-
|
|
231
|
-
return base64_images, base64_audios, base64_videos
|
|
232
|
-
|
|
233
|
-
def team_process_file(
|
|
234
|
-
files: List[UploadFile],
|
|
235
|
-
):
|
|
236
|
-
base64_images: List[Image] = []
|
|
237
|
-
base64_audios: List[Audio] = []
|
|
238
|
-
base64_videos: List[Video] = []
|
|
239
|
-
document_files: List[FileMedia] = []
|
|
240
|
-
for file in files:
|
|
241
|
-
if file.content_type in ["image/png", "image/jpeg", "image/jpg", "image/webp"]:
|
|
242
|
-
try:
|
|
243
|
-
base64_image = process_image(file)
|
|
244
|
-
base64_images.append(base64_image)
|
|
245
|
-
except Exception as e:
|
|
246
|
-
logger.error(f"Error processing image {file.filename}: {e}")
|
|
247
|
-
continue
|
|
248
|
-
elif file.content_type in ["audio/wav", "audio/mp3", "audio/mpeg"]:
|
|
249
|
-
try:
|
|
250
|
-
base64_audio = process_audio(file)
|
|
251
|
-
base64_audios.append(base64_audio)
|
|
252
|
-
except Exception as e:
|
|
253
|
-
logger.error(f"Error processing audio {file.filename}: {e}")
|
|
254
|
-
continue
|
|
255
|
-
elif file.content_type in [
|
|
256
|
-
"video/x-flv",
|
|
257
|
-
"video/quicktime",
|
|
258
|
-
"video/mpeg",
|
|
259
|
-
"video/mpegs",
|
|
260
|
-
"video/mpgs",
|
|
261
|
-
"video/mpg",
|
|
262
|
-
"video/mpg",
|
|
263
|
-
"video/mp4",
|
|
264
|
-
"video/webm",
|
|
265
|
-
"video/wmv",
|
|
266
|
-
"video/3gpp",
|
|
267
|
-
]:
|
|
268
|
-
try:
|
|
269
|
-
base64_video = process_video(file)
|
|
270
|
-
base64_videos.append(base64_video)
|
|
271
|
-
except Exception as e:
|
|
272
|
-
logger.error(f"Error processing video {file.filename}: {e}")
|
|
273
|
-
continue
|
|
274
|
-
elif file.content_type in [
|
|
275
|
-
"application/pdf",
|
|
276
|
-
"text/csv",
|
|
277
|
-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
278
|
-
"text/plain",
|
|
279
|
-
"application/json",
|
|
280
|
-
]:
|
|
281
|
-
document_file = process_document(file)
|
|
282
|
-
if document_file is not None:
|
|
283
|
-
document_files.append(document_file)
|
|
284
|
-
else:
|
|
285
|
-
raise HTTPException(status_code=400, detail="Unsupported file type")
|
|
286
|
-
|
|
287
|
-
return base64_images, base64_audios, base64_videos, document_files
|
|
288
|
-
|
|
289
|
-
@router.post("/runs")
|
|
290
|
-
def run_agent_or_team_or_workflow(
|
|
291
|
-
message: str = Form(None),
|
|
292
|
-
stream: bool = Form(False),
|
|
293
|
-
monitor: bool = Form(False),
|
|
294
|
-
agent_id: Optional[str] = Query(None),
|
|
295
|
-
team_id: Optional[str] = Query(None),
|
|
296
|
-
workflow_id: Optional[str] = Query(None),
|
|
297
|
-
workflow_input: Optional[str] = Form(None),
|
|
298
|
-
session_id: Optional[str] = Form(None),
|
|
299
|
-
user_id: Optional[str] = Form(None),
|
|
300
|
-
files: Optional[List[UploadFile]] = File(None),
|
|
301
|
-
):
|
|
302
|
-
if session_id is not None and session_id != "":
|
|
303
|
-
logger.debug(f"Continuing session: {session_id}")
|
|
304
|
-
else:
|
|
305
|
-
logger.debug("Creating new session")
|
|
306
|
-
session_id = str(uuid4())
|
|
307
|
-
|
|
308
|
-
# Only one of agent_id, team_id or workflow_id can be provided
|
|
309
|
-
if agent_id and team_id or agent_id and workflow_id or team_id and workflow_id:
|
|
310
|
-
raise HTTPException(status_code=400, detail="Only one of agent_id, team_id or workflow_id can be provided")
|
|
311
|
-
|
|
312
|
-
if not agent_id and not team_id and not workflow_id:
|
|
313
|
-
raise HTTPException(status_code=400, detail="One of agent_id, team_id or workflow_id must be provided")
|
|
314
|
-
|
|
315
|
-
agent = None
|
|
316
|
-
team = None
|
|
317
|
-
workflow = None
|
|
318
|
-
|
|
319
|
-
if agent_id and agents:
|
|
320
|
-
agent = next((agent for agent in agents if agent.agent_id == agent_id), None)
|
|
321
|
-
if agent is None:
|
|
322
|
-
raise HTTPException(status_code=404, detail="Agent not found")
|
|
323
|
-
if not message:
|
|
324
|
-
raise HTTPException(status_code=400, detail="Message is required")
|
|
325
|
-
if team_id and teams:
|
|
326
|
-
team = next((team for team in teams if team.team_id == team_id), None)
|
|
327
|
-
if team is None:
|
|
328
|
-
raise HTTPException(status_code=404, detail="Team not found")
|
|
329
|
-
if not message:
|
|
330
|
-
raise HTTPException(status_code=400, detail="Message is required")
|
|
331
|
-
if workflow_id and workflows:
|
|
332
|
-
workflow = next((workflow for workflow in workflows if workflow.workflow_id == workflow_id), None)
|
|
333
|
-
if workflow is None:
|
|
334
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
335
|
-
if not workflow_input:
|
|
336
|
-
raise HTTPException(status_code=400, detail="Workflow input is required")
|
|
337
|
-
|
|
338
|
-
# Parse workflow_input into a dict if it is a valid JSON
|
|
339
|
-
try:
|
|
340
|
-
parsed_workflow_input = json.loads(workflow_input)
|
|
341
|
-
workflow_input = parsed_workflow_input
|
|
342
|
-
except json.JSONDecodeError:
|
|
343
|
-
pass
|
|
344
|
-
|
|
345
|
-
if agent:
|
|
346
|
-
agent.monitoring = bool(monitor)
|
|
347
|
-
elif team:
|
|
348
|
-
team.monitoring = bool(monitor)
|
|
349
|
-
elif workflow:
|
|
350
|
-
workflow.monitoring = bool(monitor)
|
|
351
|
-
|
|
352
|
-
if files:
|
|
353
|
-
if agent:
|
|
354
|
-
base64_images, base64_audios, base64_videos = agent_process_file(files, agent)
|
|
355
|
-
elif team:
|
|
356
|
-
base64_images, base64_audios, base64_videos, document_files = team_process_file(files)
|
|
357
|
-
|
|
358
|
-
if stream:
|
|
359
|
-
if agent:
|
|
360
|
-
return StreamingResponse(
|
|
361
|
-
agent_chat_response_streamer(
|
|
362
|
-
agent,
|
|
363
|
-
message,
|
|
364
|
-
session_id=session_id,
|
|
365
|
-
user_id=user_id,
|
|
366
|
-
images=base64_images if base64_images else None,
|
|
367
|
-
audio=base64_audios if base64_audios else None,
|
|
368
|
-
videos=base64_videos if base64_videos else None,
|
|
369
|
-
),
|
|
370
|
-
media_type="text/event-stream",
|
|
371
|
-
)
|
|
372
|
-
elif team:
|
|
373
|
-
return StreamingResponse(
|
|
374
|
-
team_chat_response_streamer(
|
|
375
|
-
team,
|
|
376
|
-
message,
|
|
377
|
-
session_id=session_id,
|
|
378
|
-
user_id=user_id,
|
|
379
|
-
images=base64_images if base64_images else None,
|
|
380
|
-
audio=base64_audios if base64_audios else None,
|
|
381
|
-
videos=base64_videos if base64_videos else None,
|
|
382
|
-
files=document_files if document_files else None,
|
|
383
|
-
),
|
|
384
|
-
media_type="text/event-stream",
|
|
385
|
-
)
|
|
386
|
-
elif workflow:
|
|
387
|
-
if isinstance(workflow, Workflow):
|
|
388
|
-
workflow_instance = workflow.deep_copy(update={"workflow_id": workflow_id})
|
|
389
|
-
workflow_instance.user_id = user_id
|
|
390
|
-
workflow_instance.session_name = None
|
|
391
|
-
if isinstance(workflow_input, dict):
|
|
392
|
-
return StreamingResponse(
|
|
393
|
-
(json.dumps(asdict(result)) for result in workflow_instance.run(**workflow_input)),
|
|
394
|
-
media_type="text/event-stream",
|
|
395
|
-
)
|
|
396
|
-
else:
|
|
397
|
-
return StreamingResponse(
|
|
398
|
-
(json.dumps(asdict(result)) for result in workflow_instance.run(workflow_input)), # type: ignore
|
|
399
|
-
media_type="text/event-stream",
|
|
400
|
-
)
|
|
401
|
-
else:
|
|
402
|
-
return StreamingResponse(
|
|
403
|
-
workflow_response_streamer(workflow, workflow_input, session_id=session_id, user_id=user_id),
|
|
404
|
-
media_type="text/event-stream",
|
|
405
|
-
)
|
|
406
|
-
else:
|
|
407
|
-
if agent:
|
|
408
|
-
run_response = cast(
|
|
409
|
-
RunResponse,
|
|
410
|
-
agent.run(
|
|
411
|
-
message=message,
|
|
412
|
-
session_id=session_id,
|
|
413
|
-
user_id=user_id,
|
|
414
|
-
images=base64_images if base64_images else None,
|
|
415
|
-
audio=base64_audios if base64_audios else None,
|
|
416
|
-
videos=base64_videos if base64_videos else None,
|
|
417
|
-
stream=False,
|
|
418
|
-
),
|
|
419
|
-
)
|
|
420
|
-
return run_response.to_dict()
|
|
421
|
-
elif team:
|
|
422
|
-
team_run_response = team.run(
|
|
423
|
-
message=message,
|
|
424
|
-
session_id=session_id,
|
|
425
|
-
user_id=user_id,
|
|
426
|
-
images=base64_images if base64_images else None,
|
|
427
|
-
audio=base64_audios if base64_audios else None,
|
|
428
|
-
videos=base64_videos if base64_videos else None,
|
|
429
|
-
files=document_files if document_files else None,
|
|
430
|
-
stream=False,
|
|
431
|
-
)
|
|
432
|
-
return team_run_response.to_dict()
|
|
433
|
-
elif workflow:
|
|
434
|
-
if isinstance(workflow, Workflow):
|
|
435
|
-
workflow_instance = workflow.deep_copy(update={"workflow_id": workflow_id})
|
|
436
|
-
workflow_instance.user_id = user_id
|
|
437
|
-
workflow_instance.session_name = None
|
|
438
|
-
if isinstance(workflow_input, dict):
|
|
439
|
-
return workflow_instance.run(**workflow_input).to_dict()
|
|
440
|
-
else:
|
|
441
|
-
return workflow_instance.run(workflow_input).to_dict() # type: ignore
|
|
442
|
-
else:
|
|
443
|
-
if isinstance(workflow_input, dict):
|
|
444
|
-
return workflow.run(**workflow_input, session_id=session_id, user_id=user_id).to_dict()
|
|
445
|
-
else:
|
|
446
|
-
return workflow.run(workflow_input, session_id=session_id, user_id=user_id).to_dict()
|
|
447
|
-
|
|
448
|
-
return router
|
agno/app/playground/app.py
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
from os import getenv
|
|
2
|
-
from typing import Any, Callable, Dict, List, Optional, Union
|
|
3
|
-
from urllib.parse import quote
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
|
|
6
|
-
from fastapi import FastAPI, HTTPException
|
|
7
|
-
from fastapi.responses import JSONResponse
|
|
8
|
-
from fastapi.routing import APIRouter
|
|
9
|
-
from rich import box
|
|
10
|
-
from rich.panel import Panel
|
|
11
|
-
from starlette.middleware.cors import CORSMiddleware
|
|
12
|
-
from starlette.requests import Request
|
|
13
|
-
|
|
14
|
-
from agno.agent.agent import Agent
|
|
15
|
-
from agno.api.playground import PlaygroundEndpointCreate
|
|
16
|
-
from agno.app.playground.async_router import get_async_playground_router
|
|
17
|
-
from agno.app.playground.sync_router import get_sync_playground_router
|
|
18
|
-
from agno.app.utils import generate_id
|
|
19
|
-
from agno.cli.console import console
|
|
20
|
-
from agno.cli.settings import agno_cli_settings
|
|
21
|
-
from agno.playground.settings import PlaygroundSettings
|
|
22
|
-
from agno.team.team import Team
|
|
23
|
-
from agno.utils.log import log_debug, logger
|
|
24
|
-
from agno.workflow.workflow import Workflow
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class Playground:
|
|
28
|
-
def __init__(
|
|
29
|
-
self,
|
|
30
|
-
agents: Optional[List[Agent]] = None,
|
|
31
|
-
teams: Optional[List[Team]] = None,
|
|
32
|
-
workflows: Optional[List[Workflow]] = None,
|
|
33
|
-
settings: Optional[PlaygroundSettings] = None,
|
|
34
|
-
api_app: Optional[FastAPI] = None,
|
|
35
|
-
router: Optional[APIRouter] = None,
|
|
36
|
-
app_id: Optional[str] = None,
|
|
37
|
-
name: Optional[str] = None,
|
|
38
|
-
description: Optional[str] = None,
|
|
39
|
-
monitoring: bool = True,
|
|
40
|
-
):
|
|
41
|
-
if not agents and not workflows and not teams:
|
|
42
|
-
raise ValueError("Either agents, teams or workflows must be provided.")
|
|
43
|
-
|
|
44
|
-
self.agents: Optional[List[Agent]] = agents
|
|
45
|
-
self.workflows: Optional[List[Workflow]] = workflows
|
|
46
|
-
self.teams: Optional[List[Team]] = teams
|
|
47
|
-
|
|
48
|
-
self.settings: PlaygroundSettings = settings or PlaygroundSettings()
|
|
49
|
-
self.api_app: Optional[FastAPI] = api_app
|
|
50
|
-
self.router: Optional[APIRouter] = router
|
|
51
|
-
|
|
52
|
-
self.endpoints_created: Optional[PlaygroundEndpointCreate] = None
|
|
53
|
-
|
|
54
|
-
self.app_id: Optional[str] = app_id
|
|
55
|
-
self.name: Optional[str] = name
|
|
56
|
-
self.monitoring = monitoring
|
|
57
|
-
self.description = description
|
|
58
|
-
self.set_app_id()
|
|
59
|
-
if self.agents:
|
|
60
|
-
for agent in self.agents:
|
|
61
|
-
if not agent.app_id:
|
|
62
|
-
agent.app_id = self.app_id
|
|
63
|
-
agent.initialize_agent()
|
|
64
|
-
# Required for playground to work
|
|
65
|
-
agent.store_events = True
|
|
66
|
-
|
|
67
|
-
if self.teams:
|
|
68
|
-
for team in self.teams:
|
|
69
|
-
if not team.app_id:
|
|
70
|
-
team.app_id = self.app_id
|
|
71
|
-
team.initialize_team()
|
|
72
|
-
# Required for playground to work
|
|
73
|
-
team.store_events = True
|
|
74
|
-
for member in team.members:
|
|
75
|
-
if isinstance(member, Agent):
|
|
76
|
-
if not member.app_id:
|
|
77
|
-
member.app_id = self.app_id
|
|
78
|
-
|
|
79
|
-
member.team_id = None
|
|
80
|
-
member.initialize_agent()
|
|
81
|
-
elif isinstance(member, Team):
|
|
82
|
-
member.initialize_team()
|
|
83
|
-
|
|
84
|
-
if self.workflows:
|
|
85
|
-
for workflow in self.workflows:
|
|
86
|
-
if hasattr(workflow, "app_id") and not workflow.app_id:
|
|
87
|
-
workflow.app_id = self.app_id
|
|
88
|
-
if not workflow.workflow_id:
|
|
89
|
-
workflow.workflow_id = generate_id(workflow.name)
|
|
90
|
-
workflow.initialize_workflow()
|
|
91
|
-
|
|
92
|
-
def set_app_id(self) -> str:
|
|
93
|
-
# If app_id is already set, keep it instead of overriding with UUID
|
|
94
|
-
if self.app_id is None:
|
|
95
|
-
self.app_id = str(uuid4())
|
|
96
|
-
|
|
97
|
-
# Don't override existing app_id
|
|
98
|
-
return self.app_id
|
|
99
|
-
|
|
100
|
-
def _set_monitoring(self) -> None:
|
|
101
|
-
"""Override monitoring and telemetry settings based on environment variables."""
|
|
102
|
-
|
|
103
|
-
# Only override if the environment variable is set
|
|
104
|
-
monitor_env = getenv("AGNO_MONITOR")
|
|
105
|
-
if monitor_env is not None:
|
|
106
|
-
self.monitoring = monitor_env.lower() == "true"
|
|
107
|
-
|
|
108
|
-
def get_router(self) -> APIRouter:
|
|
109
|
-
return get_sync_playground_router(self.agents, self.workflows, self.teams, self.app_id)
|
|
110
|
-
|
|
111
|
-
def get_async_router(self) -> APIRouter:
|
|
112
|
-
return get_async_playground_router(self.agents, self.workflows, self.teams, self.app_id)
|
|
113
|
-
|
|
114
|
-
def get_app(self, use_async: bool = True, prefix: str = "/v1", lifespan: Optional[Callable] = None) -> FastAPI:
|
|
115
|
-
if not self.api_app:
|
|
116
|
-
self.api_app = FastAPI(
|
|
117
|
-
title=self.settings.title,
|
|
118
|
-
docs_url="/docs" if self.settings.docs_enabled else None,
|
|
119
|
-
redoc_url="/redoc" if self.settings.docs_enabled else None,
|
|
120
|
-
openapi_url="/openapi.json" if self.settings.docs_enabled else None,
|
|
121
|
-
lifespan=lifespan,
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
if not self.api_app:
|
|
125
|
-
raise Exception("API App could not be created.")
|
|
126
|
-
|
|
127
|
-
@self.api_app.exception_handler(HTTPException)
|
|
128
|
-
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
|
|
129
|
-
return JSONResponse(
|
|
130
|
-
status_code=exc.status_code,
|
|
131
|
-
content={"detail": str(exc.detail)},
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
async def general_exception_handler(request: Request, call_next):
|
|
135
|
-
try:
|
|
136
|
-
return await call_next(request)
|
|
137
|
-
except Exception as e:
|
|
138
|
-
return JSONResponse(
|
|
139
|
-
status_code=e.status_code if hasattr(e, "status_code") else 500,
|
|
140
|
-
content={"detail": str(e)},
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
self.api_app.middleware("http")(general_exception_handler)
|
|
144
|
-
|
|
145
|
-
if not self.router:
|
|
146
|
-
self.router = APIRouter(prefix=prefix)
|
|
147
|
-
|
|
148
|
-
if not self.router:
|
|
149
|
-
raise Exception("API Router could not be created.")
|
|
150
|
-
|
|
151
|
-
if use_async:
|
|
152
|
-
self.router.include_router(self.get_async_router())
|
|
153
|
-
else:
|
|
154
|
-
self.router.include_router(self.get_router())
|
|
155
|
-
self.api_app.include_router(self.router)
|
|
156
|
-
|
|
157
|
-
self.api_app.add_middleware(
|
|
158
|
-
CORSMiddleware,
|
|
159
|
-
allow_origins=self.settings.cors_origin_list,
|
|
160
|
-
allow_credentials=True,
|
|
161
|
-
allow_methods=["*"],
|
|
162
|
-
allow_headers=["*"],
|
|
163
|
-
expose_headers=["*"],
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
return self.api_app
|
|
167
|
-
|
|
168
|
-
def serve(
|
|
169
|
-
self,
|
|
170
|
-
app: Union[str, FastAPI],
|
|
171
|
-
*,
|
|
172
|
-
scheme: str = "http",
|
|
173
|
-
host: str = "localhost",
|
|
174
|
-
port: int = 7777,
|
|
175
|
-
reload: bool = False,
|
|
176
|
-
prefix="/v1",
|
|
177
|
-
**kwargs,
|
|
178
|
-
):
|
|
179
|
-
import uvicorn
|
|
180
|
-
|
|
181
|
-
logger.info(f"Starting playground on {scheme}://{host}:{port}")
|
|
182
|
-
# Encode the full endpoint (host:port)
|
|
183
|
-
encoded_endpoint = quote(f"{host}:{port}{prefix}")
|
|
184
|
-
self.endpoints_created = PlaygroundEndpointCreate(
|
|
185
|
-
endpoint=f"{scheme}://{host}:{port}", playground_data={"prefix": prefix}
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
# Create a panel with the playground URL
|
|
189
|
-
url = f"{agno_cli_settings.playground_url}?endpoint={encoded_endpoint}"
|
|
190
|
-
panel = Panel(
|
|
191
|
-
f"[bold green]Playground URL:[/bold green] [link={url}]{url}[/link]",
|
|
192
|
-
title="Agent Playground",
|
|
193
|
-
expand=False,
|
|
194
|
-
border_style="cyan",
|
|
195
|
-
box=box.HEAVY,
|
|
196
|
-
padding=(2, 2),
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
# Print the panel
|
|
200
|
-
console.print(panel)
|
|
201
|
-
self.set_app_id()
|
|
202
|
-
|
|
203
|
-
self.register_app_on_platform()
|
|
204
|
-
|
|
205
|
-
uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs)
|
|
206
|
-
|
|
207
|
-
def register_app_on_platform(self) -> None:
|
|
208
|
-
self._set_monitoring()
|
|
209
|
-
if not self.monitoring:
|
|
210
|
-
return
|
|
211
|
-
|
|
212
|
-
from agno.api.app import AppCreate, create_app
|
|
213
|
-
|
|
214
|
-
try:
|
|
215
|
-
log_debug(f"Creating app on Platform: {self.name}, {self.app_id}")
|
|
216
|
-
create_app(app=AppCreate(name=self.name, app_id=self.app_id, config=self.to_dict()))
|
|
217
|
-
except Exception as e:
|
|
218
|
-
log_debug(f"Could not create Agent app: {e}")
|
|
219
|
-
log_debug(f"Agent app created: {self.name}, {self.app_id}")
|
|
220
|
-
|
|
221
|
-
def to_dict(self) -> Dict[str, Any]:
|
|
222
|
-
payload = {
|
|
223
|
-
"endpointData": self.endpoints_created.model_dump(exclude_none=True) if self.endpoints_created else {},
|
|
224
|
-
"type": "playground",
|
|
225
|
-
"description": self.description,
|
|
226
|
-
}
|
|
227
|
-
payload = {k: v for k, v in payload.items() if v is not None}
|
|
228
|
-
return payload
|