agno 0.1.2__py3-none-any.whl → 2.3.13__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 +44 -5
- agno/agent/agent.py +10531 -2975
- agno/api/agent.py +14 -53
- agno/api/api.py +7 -46
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -25
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +6 -9
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +10 -10
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +22 -26
- 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/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/__init__.py +24 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +946 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2781 -0
- agno/db/dynamo/schemas.py +442 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +2379 -0
- agno/db/firestore/schemas.py +181 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1791 -0
- agno/db/gcs_json/utils.py +228 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +1312 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1777 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +2597 -0
- agno/db/mongo/schemas.py +119 -0
- agno/db/mongo/utils.py +276 -0
- agno/db/mysql/__init__.py +4 -0
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +2923 -0
- agno/db/mysql/schemas.py +186 -0
- agno/db/mysql/utils.py +488 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +2870 -0
- agno/db/postgres/schemas.py +187 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +2141 -0
- agno/db/redis/schemas.py +159 -0
- agno/db/redis/utils.py +346 -0
- agno/db/schemas/__init__.py +4 -0
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/evals.py +34 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +61 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +179 -0
- agno/db/singlestore/singlestore.py +2877 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +181 -0
- agno/db/sqlite/sqlite.py +2908 -0
- agno/db/sqlite/utils.py +429 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +118 -0
- agno/eval/__init__.py +24 -0
- agno/eval/accuracy.py +666 -276
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +779 -0
- agno/eval/reliability.py +241 -62
- agno/eval/utils.py +120 -0
- agno/exceptions.py +143 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -1
- agno/{document → knowledge}/chunking/agentic.py +22 -14
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +7 -6
- agno/knowledge/chunking/markdown.py +151 -0
- agno/{document → knowledge}/chunking/recursive.py +15 -3
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +91 -0
- agno/knowledge/chunking/strategy.py +165 -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/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/{embedder → knowledge/embedder}/base.py +8 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/knowledge/embedder/google.py +258 -0
- agno/knowledge/embedder/huggingface.py +94 -0
- agno/knowledge/embedder/jina.py +182 -0
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +206 -0
- agno/knowledge/embedder/nebius.py +13 -0
- agno/knowledge/embedder/ollama.py +154 -0
- agno/knowledge/embedder/openai.py +195 -0
- agno/knowledge/embedder/sentence_transformer.py +63 -0
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +3006 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/knowledge/reader/arxiv_reader.py +81 -0
- agno/knowledge/reader/base.py +95 -0
- agno/knowledge/reader/csv_reader.py +164 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +88 -0
- agno/knowledge/reader/markdown_reader.py +137 -0
- agno/knowledge/reader/pdf_reader.py +431 -0
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +313 -0
- agno/knowledge/reader/s3_reader.py +89 -0
- agno/knowledge/reader/tavily_reader.py +193 -0
- agno/knowledge/reader/text_reader.py +127 -0
- agno/knowledge/reader/web_search_reader.py +325 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +91 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/knowledge/reranker/infinity.py +195 -0
- agno/knowledge/reranker/sentence_transformer.py +54 -0
- agno/knowledge/types.py +39 -0
- agno/knowledge/utils.py +234 -0
- agno/media.py +439 -95
- agno/memory/__init__.py +16 -3
- agno/memory/manager.py +1474 -123
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +62 -0
- agno/models/anthropic/__init__.py +4 -0
- agno/models/anthropic/claude.py +960 -496
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +686 -451
- agno/models/aws/claude.py +190 -183
- agno/models/azure/__init__.py +18 -1
- agno/models/azure/ai_foundry.py +489 -0
- agno/models/azure/openai_chat.py +89 -40
- agno/models/base.py +2477 -550
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +565 -0
- agno/models/cerebras/cerebras_openai.py +131 -0
- agno/models/cohere/__init__.py +4 -0
- agno/models/cohere/chat.py +306 -492
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +74 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +90 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +45 -0
- agno/models/deepseek/__init__.py +4 -0
- agno/models/deepseek/deepseek.py +110 -9
- agno/models/fireworks/__init__.py +4 -0
- agno/models/fireworks/fireworks.py +19 -22
- agno/models/google/__init__.py +3 -7
- agno/models/google/gemini.py +1717 -662
- agno/models/google/utils.py +22 -0
- agno/models/groq/__init__.py +4 -0
- agno/models/groq/groq.py +391 -666
- agno/models/huggingface/__init__.py +4 -0
- agno/models/huggingface/huggingface.py +266 -538
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +432 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +20 -3
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +60 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +503 -0
- agno/models/litellm/litellm_openai.py +42 -0
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/lmstudio/__init__.py +5 -0
- agno/models/lmstudio/lmstudio.py +25 -0
- agno/models/message.py +361 -39
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +502 -0
- agno/models/meta/llama_openai.py +79 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +4 -0
- agno/models/mistral/mistral.py +293 -393
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +53 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +4 -0
- agno/models/nvidia/nvidia.py +22 -3
- agno/models/ollama/__init__.py +4 -2
- agno/models/ollama/chat.py +257 -492
- agno/models/openai/__init__.py +7 -0
- agno/models/openai/chat.py +725 -770
- agno/models/openai/like.py +16 -2
- agno/models/openai/responses.py +1121 -0
- agno/models/openrouter/__init__.py +4 -0
- agno/models/openrouter/openrouter.py +62 -5
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +203 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +82 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +69 -0
- agno/models/response.py +177 -7
- agno/models/sambanova/__init__.py +4 -0
- agno/models/sambanova/sambanova.py +23 -4
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +42 -0
- agno/models/together/__init__.py +4 -0
- agno/models/together/together.py +21 -164
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +43 -0
- agno/models/vertexai/__init__.py +0 -1
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +83 -0
- agno/models/xai/__init__.py +2 -0
- agno/models/xai/xai.py +111 -7
- agno/os/__init__.py +3 -0
- agno/os/app.py +1027 -0
- agno/os/auth.py +244 -0
- agno/os/config.py +126 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +249 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +47 -0
- agno/os/interfaces/agui/router.py +147 -0
- agno/os/interfaces/agui/utils.py +574 -0
- agno/os/interfaces/base.py +25 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/os/interfaces/slack/router.py +148 -0
- agno/os/interfaces/slack/security.py +30 -0
- agno/os/interfaces/slack/slack.py +47 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/os/interfaces/whatsapp/router.py +210 -0
- agno/os/interfaces/whatsapp/security.py +55 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +293 -0
- agno/os/middleware/__init__.py +9 -0
- agno/os/middleware/jwt.py +797 -0
- agno/os/router.py +258 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +450 -0
- agno/os/routers/evals/schemas.py +174 -0
- agno/os/routers/evals/utils.py +231 -0
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +1008 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +661 -0
- agno/os/routers/memory/schemas.py +88 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +190 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +997 -0
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +534 -0
- agno/os/scopes.py +469 -0
- agno/{playground → os}/settings.py +7 -15
- agno/os/utils.py +973 -0
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +67 -0
- agno/reasoning/deepseek.py +63 -0
- agno/reasoning/default.py +97 -0
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +71 -0
- agno/reasoning/helpers.py +24 -1
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +2 -1
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +822 -0
- agno/run/base.py +247 -0
- agno/run/cancel.py +81 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +767 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +260 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +342 -0
- agno/session/workflow.py +501 -0
- agno/table.py +10 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +9536 -0
- agno/tools/__init__.py +7 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +22 -12
- agno/tools/api.py +122 -0
- agno/tools/apify.py +276 -83
- agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
- agno/tools/aws_lambda.py +28 -7
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +11 -4
- agno/tools/bitbucket.py +292 -0
- agno/tools/brandfetch.py +213 -0
- agno/tools/bravesearch.py +106 -0
- agno/tools/brightdata.py +367 -0
- agno/tools/browserbase.py +209 -0
- agno/tools/calcom.py +32 -23
- agno/tools/calculator.py +24 -37
- agno/tools/cartesia.py +187 -0
- agno/tools/{clickup_tool.py → clickup.py} +17 -28
- agno/tools/confluence.py +91 -26
- agno/tools/crawl4ai.py +139 -43
- agno/tools/csv_toolkit.py +28 -22
- agno/tools/dalle.py +36 -22
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +169 -14
- agno/tools/desi_vocal.py +23 -11
- agno/tools/discord.py +32 -29
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +76 -81
- agno/tools/duckduckgo.py +43 -40
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +65 -54
- agno/tools/email.py +13 -5
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +324 -42
- agno/tools/fal.py +39 -35
- agno/tools/file.py +196 -30
- agno/tools/file_generation.py +356 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +108 -33
- agno/tools/function.py +960 -122
- agno/tools/giphy.py +34 -12
- agno/tools/github.py +1294 -97
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +271 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +607 -107
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +20 -12
- agno/tools/jina.py +24 -14
- agno/tools/jira.py +48 -19
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +82 -43
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +15 -7
- agno/tools/lumalab.py +41 -26
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +193 -0
- agno/tools/memory.py +419 -0
- agno/tools/mlx_transcribe.py +11 -9
- agno/tools/models/azure_openai.py +190 -0
- agno/tools/models/gemini.py +203 -0
- agno/tools/models/groq.py +158 -0
- agno/tools/models/morph.py +186 -0
- agno/tools/models/nebius.py +124 -0
- agno/tools/models_labs.py +163 -82
- agno/tools/moviepy_video.py +18 -13
- agno/tools/nano_banana.py +151 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +15 -4
- agno/tools/newspaper4k.py +19 -6
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +181 -17
- agno/tools/openbb.py +27 -20
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +25 -15
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +238 -185
- agno/tools/pubmed.py +125 -13
- agno/tools/python.py +48 -35
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +207 -29
- agno/tools/redshift.py +406 -0
- agno/tools/replicate.py +69 -26
- agno/tools/resend.py +11 -6
- agno/tools/scrapegraph.py +179 -19
- agno/tools/searxng.py +23 -31
- agno/tools/serpapi.py +15 -10
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +23 -12
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +56 -14
- agno/tools/sleep.py +8 -6
- agno/tools/spider.py +35 -11
- agno/tools/spotify.py +919 -0
- agno/tools/sql.py +34 -19
- agno/tools/tavily.py +158 -8
- agno/tools/telegram.py +18 -8
- agno/tools/todoist.py +218 -0
- agno/tools/toolkit.py +134 -9
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +25 -28
- agno/tools/twilio.py +18 -9
- agno/tools/user_control_flow.py +78 -0
- agno/tools/valyu.py +228 -0
- agno/tools/visualization.py +467 -0
- agno/tools/webbrowser.py +28 -0
- agno/tools/webex.py +76 -0
- agno/tools/website.py +23 -19
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +28 -19
- agno/tools/workflow.py +285 -0
- agno/tools/{twitter.py → x.py} +142 -46
- agno/tools/yfinance.py +41 -39
- agno/tools/youtube.py +34 -17
- agno/tools/zendesk.py +15 -5
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +86 -37
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/audio.py +37 -1
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +103 -20
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +700 -0
- agno/utils/functions.py +107 -37
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +171 -0
- agno/utils/http.py +185 -0
- agno/utils/json_schema.py +159 -37
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +221 -8
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +335 -14
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +77 -2
- agno/utils/models/ai_foundry.py +50 -0
- agno/utils/models/claude.py +373 -0
- agno/utils/models/cohere.py +94 -0
- agno/utils/models/llama.py +85 -0
- agno/utils/models/mistral.py +100 -0
- agno/utils/models/openai_responses.py +140 -0
- agno/utils/models/schema_utils.py +153 -0
- agno/utils/models/watsonx.py +41 -0
- agno/utils/openai.py +257 -0
- agno/utils/pickle.py +1 -1
- agno/utils/pprint.py +124 -8
- agno/utils/print_response/agent.py +930 -0
- agno/utils/print_response/team.py +1914 -0
- agno/utils/print_response/workflow.py +1668 -0
- agno/utils/prompts.py +111 -0
- agno/utils/reasoning.py +108 -0
- agno/utils/response.py +163 -0
- agno/utils/serialize.py +32 -0
- agno/utils/shell.py +4 -4
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +204 -51
- agno/utils/team.py +139 -0
- agno/utils/timer.py +9 -2
- agno/utils/tokens.py +657 -0
- agno/utils/tools.py +19 -1
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +3 -3
- agno/vectordb/__init__.py +2 -0
- agno/vectordb/base.py +87 -9
- agno/vectordb/cassandra/__init__.py +5 -1
- agno/vectordb/cassandra/cassandra.py +383 -27
- agno/vectordb/chroma/__init__.py +4 -0
- agno/vectordb/chroma/chromadb.py +748 -83
- agno/vectordb/clickhouse/__init__.py +7 -1
- agno/vectordb/clickhouse/clickhousedb.py +554 -53
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1446 -0
- agno/vectordb/lancedb/__init__.py +5 -0
- agno/vectordb/lancedb/lance_db.py +730 -98
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +163 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +388 -0
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +166 -0
- agno/vectordb/milvus/__init__.py +3 -0
- agno/vectordb/milvus/milvus.py +966 -78
- agno/vectordb/mongodb/__init__.py +9 -1
- agno/vectordb/mongodb/mongodb.py +1175 -172
- agno/vectordb/pgvector/__init__.py +8 -0
- agno/vectordb/pgvector/pgvector.py +599 -115
- agno/vectordb/pineconedb/__init__.py +5 -1
- agno/vectordb/pineconedb/pineconedb.py +406 -43
- agno/vectordb/qdrant/__init__.py +4 -0
- agno/vectordb/qdrant/qdrant.py +914 -61
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/__init__.py +8 -1
- agno/vectordb/singlestore/singlestore.py +771 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +663 -0
- agno/vectordb/upstashdb/__init__.py +5 -0
- agno/vectordb/upstashdb/upstashdb.py +718 -0
- agno/vectordb/weaviate/__init__.py +8 -0
- agno/vectordb/weaviate/index.py +15 -0
- agno/vectordb/weaviate/weaviate.py +1009 -0
- agno/workflow/__init__.py +23 -1
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +759 -0
- agno/workflow/loop.py +756 -0
- agno/workflow/parallel.py +853 -0
- agno/workflow/router.py +723 -0
- agno/workflow/step.py +1564 -0
- agno/workflow/steps.py +613 -0
- agno/workflow/types.py +556 -0
- agno/workflow/workflow.py +4327 -514
- agno-2.3.13.dist-info/METADATA +639 -0
- agno-2.3.13.dist-info/RECORD +613 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
- agno-2.3.13.dist-info/licenses/LICENSE +201 -0
- agno/api/playground.py +0 -91
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -22
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workspace.py +0 -151
- agno/cli/auth_server.py +0 -118
- agno/cli/config.py +0 -275
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -355
- agno/cli/settings.py +0 -85
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -1
- agno/document/chunking/semantic.py +0 -47
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -1
- agno/document/reader/arxiv_reader.py +0 -41
- agno/document/reader/base.py +0 -22
- agno/document/reader/csv_reader.py +0 -84
- agno/document/reader/docx_reader.py +0 -46
- agno/document/reader/firecrawl_reader.py +0 -99
- agno/document/reader/json_reader.py +0 -43
- agno/document/reader/pdf_reader.py +0 -219
- agno/document/reader/s3/pdf_reader.py +0 -46
- agno/document/reader/s3/text_reader.py +0 -51
- agno/document/reader/text_reader.py +0 -41
- agno/document/reader/website_reader.py +0 -175
- agno/document/reader/youtube_reader.py +0 -50
- agno/embedder/__init__.py +0 -1
- agno/embedder/azure_openai.py +0 -86
- agno/embedder/cohere.py +0 -72
- agno/embedder/fastembed.py +0 -37
- agno/embedder/google.py +0 -73
- agno/embedder/huggingface.py +0 -54
- agno/embedder/mistral.py +0 -80
- agno/embedder/ollama.py +0 -57
- agno/embedder/openai.py +0 -74
- agno/embedder/sentence_transformer.py +0 -38
- agno/embedder/voyageai.py +0 -64
- agno/eval/perf.py +0 -201
- agno/file/__init__.py +0 -1
- 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 -230
- agno/knowledge/arxiv.py +0 -22
- agno/knowledge/combined.py +0 -22
- agno/knowledge/csv.py +0 -28
- agno/knowledge/csv_url.py +0 -19
- agno/knowledge/document.py +0 -20
- agno/knowledge/docx.py +0 -30
- agno/knowledge/json.py +0 -28
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/pdf.py +0 -28
- agno/knowledge/pdf_url.py +0 -26
- agno/knowledge/s3/base.py +0 -60
- agno/knowledge/s3/pdf.py +0 -21
- agno/knowledge/s3/text.py +0 -23
- agno/knowledge/text.py +0 -30
- agno/knowledge/website.py +0 -88
- agno/knowledge/wikipedia.py +0 -31
- agno/knowledge/youtube.py +0 -22
- agno/memory/agent.py +0 -392
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -1
- 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 -15
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -192
- agno/memory/summary.py +0 -19
- agno/memory/workflow.py +0 -38
- agno/models/google/gemini_openai.py +0 -26
- agno/models/ollama/hermes.py +0 -221
- agno/models/ollama/tools.py +0 -362
- agno/models/vertexai/gemini.py +0 -595
- agno/playground/__init__.py +0 -3
- agno/playground/async_router.py +0 -421
- agno/playground/deploy.py +0 -249
- agno/playground/operator.py +0 -92
- agno/playground/playground.py +0 -91
- agno/playground/schemas.py +0 -76
- agno/playground/serve.py +0 -55
- agno/playground/sync_router.py +0 -405
- agno/reasoning/agent.py +0 -68
- agno/run/response.py +0 -112
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/base.py +0 -38
- agno/storage/agent/dynamodb.py +0 -350
- agno/storage/agent/json.py +0 -92
- agno/storage/agent/mongodb.py +0 -228
- agno/storage/agent/postgres.py +0 -367
- agno/storage/agent/session.py +0 -79
- agno/storage/agent/singlestore.py +0 -303
- agno/storage/agent/sqlite.py +0 -357
- agno/storage/agent/yaml.py +0 -93
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/base.py +0 -40
- agno/storage/workflow/mongodb.py +0 -233
- agno/storage/workflow/postgres.py +0 -366
- agno/storage/workflow/session.py +0 -60
- agno/storage/workflow/sqlite.py +0 -359
- agno/tools/googlesearch.py +0 -88
- 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/vectordb/singlestore/s2vectordb.py +0 -390
- agno/vectordb/singlestore/s2vectordb2.py +0 -355
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -48
- agno/workspace/operator.py +0 -758
- agno/workspace/settings.py +0 -63
- agno-0.1.2.dist-info/LICENSE +0 -375
- agno-0.1.2.dist-info/METADATA +0 -502
- agno-0.1.2.dist-info/RECORD +0 -352
- agno-0.1.2.dist-info/entry_points.txt +0 -3
- /agno/{cli → db/migrations}/__init__.py +0 -0
- /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
- /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
- /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
- /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
- /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
- /agno/{reranker → utils/models}/__init__.py +0 -0
- /agno/{storage → utils/print_response}/__init__.py +0 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/playground/async_router.py
DELETED
|
@@ -1,421 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from dataclasses import asdict
|
|
3
|
-
from io import BytesIO
|
|
4
|
-
from typing import AsyncGenerator, List, Optional, cast
|
|
5
|
-
|
|
6
|
-
from fastapi import APIRouter, File, Form, HTTPException, Query, UploadFile
|
|
7
|
-
from fastapi.responses import JSONResponse, StreamingResponse
|
|
8
|
-
|
|
9
|
-
from agno.agent.agent import Agent, RunResponse
|
|
10
|
-
from agno.media import Audio, Image, Video
|
|
11
|
-
from agno.playground.operator import (
|
|
12
|
-
format_tools,
|
|
13
|
-
get_agent_by_id,
|
|
14
|
-
get_session_title,
|
|
15
|
-
get_session_title_from_workflow_session,
|
|
16
|
-
get_workflow_by_id,
|
|
17
|
-
)
|
|
18
|
-
from agno.playground.schemas import (
|
|
19
|
-
AgentGetResponse,
|
|
20
|
-
AgentModel,
|
|
21
|
-
AgentRenameRequest,
|
|
22
|
-
AgentSessionsResponse,
|
|
23
|
-
WorkflowGetResponse,
|
|
24
|
-
WorkflowRenameRequest,
|
|
25
|
-
WorkflowRunRequest,
|
|
26
|
-
WorkflowSessionResponse,
|
|
27
|
-
WorkflowsGetResponse,
|
|
28
|
-
)
|
|
29
|
-
from agno.storage.agent.session import AgentSession
|
|
30
|
-
from agno.storage.workflow.session import WorkflowSession
|
|
31
|
-
from agno.utils.log import logger
|
|
32
|
-
from agno.workflow.workflow import Workflow
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def get_async_playground_router(
|
|
36
|
-
agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None
|
|
37
|
-
) -> APIRouter:
|
|
38
|
-
playground_router = APIRouter(prefix="/playground", tags=["Playground"])
|
|
39
|
-
|
|
40
|
-
if agents is None and workflows is None:
|
|
41
|
-
raise ValueError("Either agents or workflows must be provided.")
|
|
42
|
-
|
|
43
|
-
@playground_router.get("/status")
|
|
44
|
-
async def playground_status():
|
|
45
|
-
return {"playground": "available"}
|
|
46
|
-
|
|
47
|
-
@playground_router.get("/agents", response_model=List[AgentGetResponse])
|
|
48
|
-
async def get_agents():
|
|
49
|
-
agent_list: List[AgentGetResponse] = []
|
|
50
|
-
if agents is None:
|
|
51
|
-
return agent_list
|
|
52
|
-
|
|
53
|
-
for agent in agents:
|
|
54
|
-
agent_tools = agent.get_tools()
|
|
55
|
-
formatted_tools = format_tools(agent_tools)
|
|
56
|
-
|
|
57
|
-
name = agent.model.name or agent.model.__class__.__name__ if agent.model else None
|
|
58
|
-
provider = agent.model.provider or agent.model.__class__.__name__ if agent.model else ""
|
|
59
|
-
model_id = agent.model.id if agent.model else None
|
|
60
|
-
|
|
61
|
-
# Create an agent_id if its not set on the agent
|
|
62
|
-
if agent.agent_id is None:
|
|
63
|
-
agent.set_agent_id()
|
|
64
|
-
|
|
65
|
-
if provider and model_id:
|
|
66
|
-
provider = f"{provider} {model_id}"
|
|
67
|
-
elif name and model_id:
|
|
68
|
-
provider = f"{name} {model_id}"
|
|
69
|
-
elif model_id:
|
|
70
|
-
provider = model_id
|
|
71
|
-
else:
|
|
72
|
-
provider = ""
|
|
73
|
-
|
|
74
|
-
agent_list.append(
|
|
75
|
-
AgentGetResponse(
|
|
76
|
-
agent_id=agent.agent_id,
|
|
77
|
-
name=agent.name,
|
|
78
|
-
model=AgentModel(
|
|
79
|
-
name=name,
|
|
80
|
-
model=model_id,
|
|
81
|
-
provider=provider,
|
|
82
|
-
),
|
|
83
|
-
add_context=agent.add_context,
|
|
84
|
-
tools=formatted_tools,
|
|
85
|
-
memory={"name": agent.memory.db.__class__.__name__} if agent.memory and agent.memory.db else None,
|
|
86
|
-
storage={"name": agent.storage.__class__.__name__} if agent.storage else None,
|
|
87
|
-
knowledge={"name": agent.knowledge.__class__.__name__} if agent.knowledge else None,
|
|
88
|
-
description=agent.description,
|
|
89
|
-
instructions=agent.instructions,
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
return agent_list
|
|
94
|
-
|
|
95
|
-
async def chat_response_streamer(
|
|
96
|
-
agent: Agent,
|
|
97
|
-
message: str,
|
|
98
|
-
images: Optional[List[Image]] = None,
|
|
99
|
-
audio: Optional[List[Audio]] = None,
|
|
100
|
-
videos: Optional[List[Video]] = None,
|
|
101
|
-
) -> AsyncGenerator:
|
|
102
|
-
run_response = await agent.arun(
|
|
103
|
-
message,
|
|
104
|
-
images=images,
|
|
105
|
-
audio=audio,
|
|
106
|
-
videos=videos,
|
|
107
|
-
stream=True,
|
|
108
|
-
stream_intermediate_steps=True,
|
|
109
|
-
)
|
|
110
|
-
async for run_response_chunk in run_response:
|
|
111
|
-
run_response_chunk = cast(RunResponse, run_response_chunk)
|
|
112
|
-
yield run_response_chunk.to_json()
|
|
113
|
-
|
|
114
|
-
async def process_image(file: UploadFile) -> Image:
|
|
115
|
-
content = file.file.read()
|
|
116
|
-
|
|
117
|
-
return Image(content=content)
|
|
118
|
-
|
|
119
|
-
@playground_router.post("/agents/{agent_id}/runs")
|
|
120
|
-
async def create_agent_run(
|
|
121
|
-
agent_id: str,
|
|
122
|
-
message: str = Form(...),
|
|
123
|
-
stream: bool = Form(True),
|
|
124
|
-
monitor: bool = Form(False),
|
|
125
|
-
session_id: Optional[str] = Form(None),
|
|
126
|
-
user_id: Optional[str] = Form(None),
|
|
127
|
-
files: Optional[List[UploadFile]] = File(None),
|
|
128
|
-
image: Optional[UploadFile] = File(None),
|
|
129
|
-
):
|
|
130
|
-
logger.debug(f"AgentRunRequest: {message} {session_id} {user_id} {agent_id}")
|
|
131
|
-
agent = get_agent_by_id(agent_id, agents)
|
|
132
|
-
if agent is None:
|
|
133
|
-
raise HTTPException(status_code=404, detail="Agent not found")
|
|
134
|
-
|
|
135
|
-
if files:
|
|
136
|
-
if agent.knowledge is None:
|
|
137
|
-
raise HTTPException(status_code=404, detail="KnowledgeBase not found")
|
|
138
|
-
|
|
139
|
-
if session_id is not None:
|
|
140
|
-
logger.debug(f"Continuing session: {session_id}")
|
|
141
|
-
else:
|
|
142
|
-
logger.debug("Creating new session")
|
|
143
|
-
|
|
144
|
-
# Create a new instance of this agent
|
|
145
|
-
new_agent_instance = agent.deep_copy(update={"session_id": session_id})
|
|
146
|
-
if user_id is not None:
|
|
147
|
-
new_agent_instance.user_id = user_id
|
|
148
|
-
|
|
149
|
-
if monitor:
|
|
150
|
-
new_agent_instance.monitoring = True
|
|
151
|
-
else:
|
|
152
|
-
new_agent_instance.monitoring = False
|
|
153
|
-
|
|
154
|
-
base64_image: Optional[Image] = None
|
|
155
|
-
if image:
|
|
156
|
-
base64_image = await process_image(image)
|
|
157
|
-
|
|
158
|
-
if files:
|
|
159
|
-
for file in files:
|
|
160
|
-
if file.content_type == "application/pdf":
|
|
161
|
-
from agno.document.reader.pdf_reader import PDFReader
|
|
162
|
-
|
|
163
|
-
contents = await file.read()
|
|
164
|
-
pdf_file = BytesIO(contents)
|
|
165
|
-
pdf_file.name = file.filename
|
|
166
|
-
file_content = PDFReader().read(pdf_file)
|
|
167
|
-
if agent.knowledge is not None:
|
|
168
|
-
agent.knowledge.load_documents(file_content)
|
|
169
|
-
elif file.content_type == "text/csv":
|
|
170
|
-
from agno.document.reader.csv_reader import CSVReader
|
|
171
|
-
|
|
172
|
-
contents = await file.read()
|
|
173
|
-
csv_file = BytesIO(contents)
|
|
174
|
-
csv_file.name = file.filename
|
|
175
|
-
file_content = CSVReader().read(csv_file)
|
|
176
|
-
if agent.knowledge is not None:
|
|
177
|
-
agent.knowledge.load_documents(file_content)
|
|
178
|
-
elif file.content_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
179
|
-
from agno.document.reader.docx_reader import DocxReader
|
|
180
|
-
|
|
181
|
-
contents = await file.read()
|
|
182
|
-
docx_file = BytesIO(contents)
|
|
183
|
-
docx_file.name = file.filename
|
|
184
|
-
file_content = DocxReader().read(docx_file)
|
|
185
|
-
if agent.knowledge is not None:
|
|
186
|
-
agent.knowledge.load_documents(file_content)
|
|
187
|
-
elif file.content_type == "text/plain":
|
|
188
|
-
from agno.document.reader.text_reader import TextReader
|
|
189
|
-
|
|
190
|
-
contents = await file.read()
|
|
191
|
-
text_file = BytesIO(contents)
|
|
192
|
-
text_file.name = file.filename
|
|
193
|
-
file_content = TextReader().read(text_file)
|
|
194
|
-
if agent.knowledge is not None:
|
|
195
|
-
agent.knowledge.load_documents(file_content)
|
|
196
|
-
else:
|
|
197
|
-
raise HTTPException(status_code=400, detail="Unsupported file type")
|
|
198
|
-
|
|
199
|
-
if stream:
|
|
200
|
-
return StreamingResponse(
|
|
201
|
-
chat_response_streamer(new_agent_instance, message, images=[base64_image] if base64_image else None),
|
|
202
|
-
media_type="text/event-stream",
|
|
203
|
-
)
|
|
204
|
-
else:
|
|
205
|
-
run_response = cast(
|
|
206
|
-
RunResponse,
|
|
207
|
-
await new_agent_instance.arun(
|
|
208
|
-
message,
|
|
209
|
-
images=[base64_image] if base64_image else None,
|
|
210
|
-
stream=False,
|
|
211
|
-
),
|
|
212
|
-
)
|
|
213
|
-
return run_response
|
|
214
|
-
|
|
215
|
-
@playground_router.get("/agents/{agent_id}/sessions")
|
|
216
|
-
async def get_all_agent_sessions(agent_id: str, user_id: str = Query(..., min_length=1)):
|
|
217
|
-
logger.debug(f"AgentSessionsRequest: {agent_id} {user_id}")
|
|
218
|
-
agent = get_agent_by_id(agent_id, agents)
|
|
219
|
-
if agent is None:
|
|
220
|
-
return JSONResponse(status_code=404, content="Agent not found.")
|
|
221
|
-
|
|
222
|
-
if agent.storage is None:
|
|
223
|
-
return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
|
|
224
|
-
|
|
225
|
-
agent_sessions: List[AgentSessionsResponse] = []
|
|
226
|
-
all_agent_sessions: List[AgentSession] = agent.storage.get_all_sessions(user_id=user_id)
|
|
227
|
-
for session in all_agent_sessions:
|
|
228
|
-
title = get_session_title(session)
|
|
229
|
-
agent_sessions.append(
|
|
230
|
-
AgentSessionsResponse(
|
|
231
|
-
title=title,
|
|
232
|
-
session_id=session.session_id,
|
|
233
|
-
session_name=session.session_data.get("session_name") if session.session_data else None,
|
|
234
|
-
created_at=session.created_at,
|
|
235
|
-
)
|
|
236
|
-
)
|
|
237
|
-
return agent_sessions
|
|
238
|
-
|
|
239
|
-
@playground_router.get("/agents/{agent_id}/sessions/{session_id}")
|
|
240
|
-
async def get_agent_session(agent_id: str, session_id: str, user_id: str = Query(..., min_length=1)):
|
|
241
|
-
logger.debug(f"AgentSessionsRequest: {agent_id} {user_id} {session_id}")
|
|
242
|
-
agent = get_agent_by_id(agent_id, agents)
|
|
243
|
-
if agent is None:
|
|
244
|
-
return JSONResponse(status_code=404, content="Agent not found.")
|
|
245
|
-
|
|
246
|
-
if agent.storage is None:
|
|
247
|
-
return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
|
|
248
|
-
|
|
249
|
-
agent_session: Optional[AgentSession] = agent.storage.read(session_id, user_id)
|
|
250
|
-
if agent_session is None:
|
|
251
|
-
return JSONResponse(status_code=404, content="Session not found.")
|
|
252
|
-
|
|
253
|
-
return agent_session
|
|
254
|
-
|
|
255
|
-
@playground_router.post("/agents/{agent_id}/sessions/{session_id}/rename")
|
|
256
|
-
async def rename_agent_session(agent_id: str, session_id: str, body: AgentRenameRequest):
|
|
257
|
-
agent = get_agent_by_id(agent_id, agents)
|
|
258
|
-
if agent is None:
|
|
259
|
-
return JSONResponse(status_code=404, content=f"couldn't find agent with {agent_id}")
|
|
260
|
-
|
|
261
|
-
if agent.storage is None:
|
|
262
|
-
return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
|
|
263
|
-
|
|
264
|
-
all_agent_sessions: List[AgentSession] = agent.storage.get_all_sessions(user_id=body.user_id)
|
|
265
|
-
for session in all_agent_sessions:
|
|
266
|
-
if session.session_id == session_id:
|
|
267
|
-
agent.session_id = session_id
|
|
268
|
-
agent.rename_session(body.name)
|
|
269
|
-
return JSONResponse(content={"message": f"successfully renamed agent {agent.name}"})
|
|
270
|
-
|
|
271
|
-
return JSONResponse(status_code=404, content="Session not found.")
|
|
272
|
-
|
|
273
|
-
@playground_router.delete("/agents/{agent_id}/sessions/{session_id}")
|
|
274
|
-
async def delete_agent_session(agent_id: str, session_id: str, user_id: str = Query(..., min_length=1)):
|
|
275
|
-
agent = get_agent_by_id(agent_id, agents)
|
|
276
|
-
if agent is None:
|
|
277
|
-
return JSONResponse(status_code=404, content="Agent not found.")
|
|
278
|
-
|
|
279
|
-
if agent.storage is None:
|
|
280
|
-
return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
|
|
281
|
-
|
|
282
|
-
all_agent_sessions: List[AgentSession] = agent.storage.get_all_sessions(user_id=user_id)
|
|
283
|
-
for session in all_agent_sessions:
|
|
284
|
-
if session.session_id == session_id:
|
|
285
|
-
agent.delete_session(session_id)
|
|
286
|
-
return JSONResponse(content={"message": f"successfully deleted agent {agent.name}"})
|
|
287
|
-
|
|
288
|
-
return JSONResponse(status_code=404, content="Session not found.")
|
|
289
|
-
|
|
290
|
-
@playground_router.get("/workflows", response_model=List[WorkflowsGetResponse])
|
|
291
|
-
async def get_workflows():
|
|
292
|
-
if workflows is None:
|
|
293
|
-
return []
|
|
294
|
-
|
|
295
|
-
return [
|
|
296
|
-
WorkflowsGetResponse(
|
|
297
|
-
workflow_id=str(workflow.workflow_id),
|
|
298
|
-
name=workflow.name,
|
|
299
|
-
description=workflow.description,
|
|
300
|
-
)
|
|
301
|
-
for workflow in workflows
|
|
302
|
-
]
|
|
303
|
-
|
|
304
|
-
@playground_router.get("/workflows/{workflow_id}", response_model=WorkflowGetResponse)
|
|
305
|
-
async def get_workflow(workflow_id: str):
|
|
306
|
-
workflow = get_workflow_by_id(workflow_id, workflows)
|
|
307
|
-
if workflow is None:
|
|
308
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
309
|
-
|
|
310
|
-
return WorkflowGetResponse(
|
|
311
|
-
workflow_id=workflow.workflow_id,
|
|
312
|
-
name=workflow.name,
|
|
313
|
-
description=workflow.description,
|
|
314
|
-
parameters=workflow._run_parameters or {},
|
|
315
|
-
storage=workflow.storage.__class__.__name__ if workflow.storage else None,
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
@playground_router.post("/workflows/{workflow_id}/runs")
|
|
319
|
-
async def create_workflow_run(workflow_id: str, body: WorkflowRunRequest):
|
|
320
|
-
# Retrieve the workflow by ID
|
|
321
|
-
workflow = get_workflow_by_id(workflow_id, workflows)
|
|
322
|
-
if workflow is None:
|
|
323
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
324
|
-
|
|
325
|
-
if body.session_id is not None:
|
|
326
|
-
logger.debug(f"Continuing session: {body.session_id}")
|
|
327
|
-
else:
|
|
328
|
-
logger.debug("Creating new session")
|
|
329
|
-
|
|
330
|
-
# Create a new instance of this workflow
|
|
331
|
-
new_workflow_instance = workflow.deep_copy(update={"workflow_id": workflow_id, "session_id": body.session_id})
|
|
332
|
-
new_workflow_instance.user_id = body.user_id
|
|
333
|
-
new_workflow_instance.session_name = None
|
|
334
|
-
|
|
335
|
-
# Return based on the response type
|
|
336
|
-
try:
|
|
337
|
-
if new_workflow_instance._run_return_type == "RunResponse":
|
|
338
|
-
# Return as a normal response
|
|
339
|
-
return new_workflow_instance.run(**body.input)
|
|
340
|
-
else:
|
|
341
|
-
# Return as a streaming response
|
|
342
|
-
return StreamingResponse(
|
|
343
|
-
(json.dumps(asdict(result)) for result in new_workflow_instance.run(**body.input)),
|
|
344
|
-
media_type="text/event-stream",
|
|
345
|
-
)
|
|
346
|
-
except Exception as e:
|
|
347
|
-
# Handle unexpected runtime errors
|
|
348
|
-
raise HTTPException(status_code=500, detail=f"Error running workflow: {str(e)}")
|
|
349
|
-
|
|
350
|
-
@playground_router.get("/workflows/{workflow_id}/sessions", response_model=List[WorkflowSessionResponse])
|
|
351
|
-
async def get_all_workflow_sessions(workflow_id: str, user_id: str = Query(..., min_length=1)):
|
|
352
|
-
# Retrieve the workflow by ID
|
|
353
|
-
workflow = get_workflow_by_id(workflow_id, workflows)
|
|
354
|
-
if not workflow:
|
|
355
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
356
|
-
|
|
357
|
-
# Ensure storage is enabled for the workflow
|
|
358
|
-
if not workflow.storage:
|
|
359
|
-
raise HTTPException(status_code=404, detail="Workflow does not have storage enabled")
|
|
360
|
-
|
|
361
|
-
# Retrieve all sessions for the given workflow and user
|
|
362
|
-
try:
|
|
363
|
-
all_workflow_sessions: List[WorkflowSession] = workflow.storage.get_all_sessions(
|
|
364
|
-
user_id=user_id, workflow_id=workflow_id
|
|
365
|
-
)
|
|
366
|
-
except Exception as e:
|
|
367
|
-
raise HTTPException(status_code=500, detail=f"Error retrieving sessions: {str(e)}")
|
|
368
|
-
|
|
369
|
-
# Return the sessions
|
|
370
|
-
return [
|
|
371
|
-
WorkflowSessionResponse(
|
|
372
|
-
title=get_session_title_from_workflow_session(session),
|
|
373
|
-
session_id=session.session_id,
|
|
374
|
-
session_name=session.session_data.get("session_name") if session.session_data else None,
|
|
375
|
-
created_at=session.created_at,
|
|
376
|
-
)
|
|
377
|
-
for session in all_workflow_sessions
|
|
378
|
-
]
|
|
379
|
-
|
|
380
|
-
@playground_router.get("/workflows/{workflow_id}/sessions/{session_id}")
|
|
381
|
-
async def get_workflow_session(workflow_id: str, session_id: str, user_id: str = Query(..., min_length=1)):
|
|
382
|
-
# Retrieve the workflow by ID
|
|
383
|
-
workflow = get_workflow_by_id(workflow_id, workflows)
|
|
384
|
-
if not workflow:
|
|
385
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
386
|
-
|
|
387
|
-
# Ensure storage is enabled for the workflow
|
|
388
|
-
if not workflow.storage:
|
|
389
|
-
raise HTTPException(status_code=404, detail="Workflow does not have storage enabled")
|
|
390
|
-
|
|
391
|
-
# Retrieve the specific session
|
|
392
|
-
try:
|
|
393
|
-
workflow_session: Optional[WorkflowSession] = workflow.storage.read(session_id, user_id)
|
|
394
|
-
except Exception as e:
|
|
395
|
-
raise HTTPException(status_code=500, detail=f"Error retrieving session: {str(e)}")
|
|
396
|
-
|
|
397
|
-
if not workflow_session:
|
|
398
|
-
raise HTTPException(status_code=404, detail="Session not found")
|
|
399
|
-
|
|
400
|
-
# Return the session
|
|
401
|
-
return workflow_session
|
|
402
|
-
|
|
403
|
-
@playground_router.post("/workflows/{workflow_id}/sessions/{session_id}/rename")
|
|
404
|
-
async def rename_workflow_session(workflow_id: str, session_id: str, body: WorkflowRenameRequest):
|
|
405
|
-
workflow = get_workflow_by_id(workflow_id, workflows)
|
|
406
|
-
if workflow is None:
|
|
407
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
408
|
-
workflow.session_id = session_id
|
|
409
|
-
workflow.rename_session(body.name)
|
|
410
|
-
return JSONResponse(content={"message": f"successfully renamed workflow {workflow.name}"})
|
|
411
|
-
|
|
412
|
-
@playground_router.delete("/workflows/{workflow_id}/sessions/{session_id}")
|
|
413
|
-
async def delete_workflow_session(workflow_id: str, session_id: str):
|
|
414
|
-
workflow = get_workflow_by_id(workflow_id, workflows)
|
|
415
|
-
if workflow is None:
|
|
416
|
-
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
417
|
-
|
|
418
|
-
workflow.delete_session(session_id)
|
|
419
|
-
return JSONResponse(content={"message": f"successfully deleted workflow {workflow.name}"})
|
|
420
|
-
|
|
421
|
-
return playground_router
|
agno/playground/deploy.py
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import tarfile
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import List, Optional, cast
|
|
4
|
-
|
|
5
|
-
from rich import box
|
|
6
|
-
from rich.panel import Panel
|
|
7
|
-
from rich.text import Text
|
|
8
|
-
|
|
9
|
-
from agno.api.playground import deploy_playground_archive
|
|
10
|
-
from agno.cli.settings import agno_cli_settings
|
|
11
|
-
from agno.utils.log import logger
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def create_deployment_info(
|
|
15
|
-
app: str, root: Path, elapsed_time: str = "[waiting...]", status: Optional[str] = None, error: Optional[str] = None
|
|
16
|
-
) -> Text:
|
|
17
|
-
"""Create a formatted text display showing deployment information.
|
|
18
|
-
|
|
19
|
-
Args:
|
|
20
|
-
app (str): The name of the application being deployed
|
|
21
|
-
root (Path): The path to the root directory
|
|
22
|
-
elapsed_time (str): The elapsed deployment time. Defaults to "[waiting...]"
|
|
23
|
-
status (Optional[str]): The current deployment status. Defaults to None
|
|
24
|
-
error (Optional[str]): The deployment error message. Defaults to None
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
Text: A Rich Text object containing formatted deployment information
|
|
28
|
-
"""
|
|
29
|
-
# Base info always shown
|
|
30
|
-
elements = [
|
|
31
|
-
("📦 App: ", "bold"),
|
|
32
|
-
(f"{app}\n", "cyan"),
|
|
33
|
-
("📂 Root: ", "bold"),
|
|
34
|
-
(f"{root}\n", "cyan"),
|
|
35
|
-
("⏱️ Time: ", "bold"),
|
|
36
|
-
(f"{elapsed_time}\n", "yellow"),
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
# Add either status or error, not both
|
|
40
|
-
if error is not None:
|
|
41
|
-
elements.extend(
|
|
42
|
-
[
|
|
43
|
-
("🚨 Error: ", "bold"),
|
|
44
|
-
(f"{error}", "red"),
|
|
45
|
-
]
|
|
46
|
-
)
|
|
47
|
-
elif status is not None:
|
|
48
|
-
elements.extend(
|
|
49
|
-
[
|
|
50
|
-
("🚧 Status: ", "bold"),
|
|
51
|
-
(f"{status}", "yellow"),
|
|
52
|
-
]
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
return Text.assemble(*elements)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def create_info_panel(deployment_info: Text) -> Panel:
|
|
59
|
-
"""Create a formatted panel to display deployment information.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
deployment_info (Text): The Rich Text object containing deployment information
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
Panel: A Rich Panel object containing the formatted deployment information
|
|
66
|
-
"""
|
|
67
|
-
return Panel(
|
|
68
|
-
deployment_info,
|
|
69
|
-
title="[bold green]🚀 Deploying Playground App[/bold green]",
|
|
70
|
-
border_style="cyan",
|
|
71
|
-
box=box.HEAVY,
|
|
72
|
-
padding=(1, 2),
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def create_error_panel(deployment_info: Text) -> Panel:
|
|
77
|
-
"""Create a formatted panel to display deployment error information.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
deployment_info (Text): The Rich Text object containing deployment error information
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
Panel: A Rich Panel object containing the formatted deployment error information
|
|
84
|
-
"""
|
|
85
|
-
return Panel(
|
|
86
|
-
deployment_info,
|
|
87
|
-
title="[bold red]🚨 Deployment Failed[/bold red]",
|
|
88
|
-
border_style="red",
|
|
89
|
-
box=box.HEAVY,
|
|
90
|
-
padding=(1, 2),
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def create_tar_archive(root: Path) -> Path:
|
|
95
|
-
"""Create a gzipped tar archive of the playground files.
|
|
96
|
-
|
|
97
|
-
Args:
|
|
98
|
-
root (Path): The path to the directory to be archived
|
|
99
|
-
|
|
100
|
-
Returns:
|
|
101
|
-
Path: The path to the created tar archive
|
|
102
|
-
|
|
103
|
-
Raises:
|
|
104
|
-
Exception: If archive creation fails
|
|
105
|
-
"""
|
|
106
|
-
tar_path = root.with_suffix(".tar.gz")
|
|
107
|
-
try:
|
|
108
|
-
logger.debug(f"Creating playground archive: {tar_path.name}")
|
|
109
|
-
with tarfile.open(tar_path, "w:gz") as tar:
|
|
110
|
-
tar.add(root, arcname=root.name)
|
|
111
|
-
logger.debug(f"Successfully created playground archive: {tar_path.name}")
|
|
112
|
-
return tar_path
|
|
113
|
-
except Exception as e:
|
|
114
|
-
logger.error(f"Failed to create playground archive: {e}")
|
|
115
|
-
raise
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def deploy_archive(name: str, tar_path: Path) -> None:
|
|
119
|
-
"""Deploying the tar archive to agno-cloud.
|
|
120
|
-
|
|
121
|
-
Args:
|
|
122
|
-
name (str): The name of the playground app
|
|
123
|
-
tar_path (Path): The path to the tar archive to be deployed
|
|
124
|
-
|
|
125
|
-
Raises:
|
|
126
|
-
Exception: If the deployment process fails
|
|
127
|
-
"""
|
|
128
|
-
try:
|
|
129
|
-
logger.debug(f"Deploying playground archive: {tar_path.name}")
|
|
130
|
-
deploy_playground_archive(name=name, tar_path=tar_path)
|
|
131
|
-
logger.debug(f"Successfully deployed playground archive: {tar_path.name}")
|
|
132
|
-
except Exception:
|
|
133
|
-
raise
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def cleanup_archive(tar_path: Path) -> None:
|
|
137
|
-
"""Delete the temporary tar archive after deployment.
|
|
138
|
-
|
|
139
|
-
Args:
|
|
140
|
-
tar_path (Path): The path to the tar archive to be deleted
|
|
141
|
-
|
|
142
|
-
Raises:
|
|
143
|
-
Exception: If the deletion process fails
|
|
144
|
-
"""
|
|
145
|
-
try:
|
|
146
|
-
logger.debug(f"Deleting playground archive: {tar_path.name}")
|
|
147
|
-
tar_path.unlink()
|
|
148
|
-
logger.debug(f"Successfully deleted playground archive: {tar_path.name}")
|
|
149
|
-
except Exception as e:
|
|
150
|
-
logger.error(f"Failed to delete playground archive: {e}")
|
|
151
|
-
raise
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def deploy_playground_app(
|
|
155
|
-
app: str,
|
|
156
|
-
name: str,
|
|
157
|
-
root: Optional[Path] = None,
|
|
158
|
-
) -> None:
|
|
159
|
-
"""Deploy a playground application to agno-cloud.
|
|
160
|
-
|
|
161
|
-
This function:
|
|
162
|
-
1. Creates a tar archive of the root directory.
|
|
163
|
-
2. Uploades the archive to agno-cloud.
|
|
164
|
-
3. Cleaning up temporary files.
|
|
165
|
-
4. Displaying real-time progress updates.
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
app (str): The application to deploy as a string identifier.
|
|
169
|
-
It should be the name of the module containing the Playground app from the root path.
|
|
170
|
-
name (str): The name of the playground app.
|
|
171
|
-
root (Optional[Path]): The root path containing the application files. Defaults to the current working directory.
|
|
172
|
-
|
|
173
|
-
Raises:
|
|
174
|
-
Exception: If any step of the deployment process fails
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
agno_cli_settings.gate_alpha_feature()
|
|
178
|
-
|
|
179
|
-
from rich.console import Group
|
|
180
|
-
from rich.live import Live
|
|
181
|
-
from rich.status import Status
|
|
182
|
-
|
|
183
|
-
from agno.utils.timer import Timer
|
|
184
|
-
|
|
185
|
-
if app is None:
|
|
186
|
-
raise ValueError("PlaygroundApp is required")
|
|
187
|
-
|
|
188
|
-
if name is None:
|
|
189
|
-
raise ValueError("PlaygroundApp name is required")
|
|
190
|
-
|
|
191
|
-
with Live(refresh_per_second=4) as live_display:
|
|
192
|
-
response_timer = Timer()
|
|
193
|
-
response_timer.start()
|
|
194
|
-
root = root or Path.cwd()
|
|
195
|
-
root = cast(Path, root)
|
|
196
|
-
try:
|
|
197
|
-
deployment_info = create_deployment_info(app=app, root=root, status="Initializing...")
|
|
198
|
-
panels: List[Panel] = [create_info_panel(deployment_info=deployment_info)]
|
|
199
|
-
|
|
200
|
-
status = Status(
|
|
201
|
-
"[bold blue]Initializing playground...[/bold blue]",
|
|
202
|
-
spinner="aesthetic",
|
|
203
|
-
speed=2,
|
|
204
|
-
)
|
|
205
|
-
panels.append(status) # type: ignore
|
|
206
|
-
live_display.update(Group(*panels))
|
|
207
|
-
|
|
208
|
-
# Step 1: Create archive
|
|
209
|
-
status.update("[bold blue]Creating playground archive...[/bold blue]")
|
|
210
|
-
tar_path = create_tar_archive(root=root)
|
|
211
|
-
panels[0] = create_info_panel(
|
|
212
|
-
create_deployment_info(
|
|
213
|
-
app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", status="Creating archive..."
|
|
214
|
-
)
|
|
215
|
-
)
|
|
216
|
-
live_display.update(Group(*panels))
|
|
217
|
-
|
|
218
|
-
# Step 2: Upload archive
|
|
219
|
-
status.update("[bold blue]Uploading playground archive...[/bold blue]")
|
|
220
|
-
deploy_archive(name=name, tar_path=tar_path)
|
|
221
|
-
panels[0] = create_info_panel(
|
|
222
|
-
create_deployment_info(
|
|
223
|
-
app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", status="Uploading archive..."
|
|
224
|
-
)
|
|
225
|
-
)
|
|
226
|
-
live_display.update(Group(*panels))
|
|
227
|
-
|
|
228
|
-
# Step 3: Cleanup
|
|
229
|
-
status.update("[bold blue]Deleting playground archive...[/bold blue]")
|
|
230
|
-
cleanup_archive(tar_path)
|
|
231
|
-
panels[0] = create_info_panel(
|
|
232
|
-
create_deployment_info(
|
|
233
|
-
app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", status="Deleting archive..."
|
|
234
|
-
)
|
|
235
|
-
)
|
|
236
|
-
live_display.update(Group(*panels))
|
|
237
|
-
|
|
238
|
-
# Final display update
|
|
239
|
-
status.stop()
|
|
240
|
-
panels.pop()
|
|
241
|
-
live_display.update(Group(*panels))
|
|
242
|
-
except Exception as e:
|
|
243
|
-
status.update(f"[bold red]Deployment failed: {str(e)}[/bold red]")
|
|
244
|
-
panels[0] = create_error_panel(
|
|
245
|
-
create_deployment_info(app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", error=str(e))
|
|
246
|
-
)
|
|
247
|
-
status.stop()
|
|
248
|
-
panels.pop()
|
|
249
|
-
live_display.update(Group(*panels))
|