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
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import TYPE_CHECKING, Any, AsyncGenerator, List, Optional, cast
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from fastapi import (
|
|
6
|
+
APIRouter,
|
|
7
|
+
BackgroundTasks,
|
|
8
|
+
Depends,
|
|
9
|
+
File,
|
|
10
|
+
Form,
|
|
11
|
+
HTTPException,
|
|
12
|
+
Request,
|
|
13
|
+
UploadFile,
|
|
14
|
+
)
|
|
15
|
+
from fastapi.responses import JSONResponse, StreamingResponse
|
|
16
|
+
|
|
17
|
+
from agno.agent.agent import Agent
|
|
18
|
+
from agno.exceptions import InputCheckError, OutputCheckError
|
|
19
|
+
from agno.media import Audio, Image, Video
|
|
20
|
+
from agno.media import File as FileMedia
|
|
21
|
+
from agno.os.auth import get_authentication_dependency, require_resource_access
|
|
22
|
+
from agno.os.routers.agents.schema import AgentResponse
|
|
23
|
+
from agno.os.schema import (
|
|
24
|
+
BadRequestResponse,
|
|
25
|
+
InternalServerErrorResponse,
|
|
26
|
+
NotFoundResponse,
|
|
27
|
+
UnauthenticatedResponse,
|
|
28
|
+
ValidationErrorResponse,
|
|
29
|
+
)
|
|
30
|
+
from agno.os.settings import AgnoAPISettings
|
|
31
|
+
from agno.os.utils import (
|
|
32
|
+
format_sse_event,
|
|
33
|
+
get_agent_by_id,
|
|
34
|
+
get_request_kwargs,
|
|
35
|
+
process_audio,
|
|
36
|
+
process_document,
|
|
37
|
+
process_image,
|
|
38
|
+
process_video,
|
|
39
|
+
)
|
|
40
|
+
from agno.run.agent import RunErrorEvent, RunOutput
|
|
41
|
+
from agno.utils.log import log_debug, log_error, log_warning
|
|
42
|
+
|
|
43
|
+
if TYPE_CHECKING:
|
|
44
|
+
from agno.os.app import AgentOS
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def agent_response_streamer(
|
|
48
|
+
agent: Agent,
|
|
49
|
+
message: str,
|
|
50
|
+
session_id: Optional[str] = None,
|
|
51
|
+
user_id: Optional[str] = None,
|
|
52
|
+
images: Optional[List[Image]] = None,
|
|
53
|
+
audio: Optional[List[Audio]] = None,
|
|
54
|
+
videos: Optional[List[Video]] = None,
|
|
55
|
+
files: Optional[List[FileMedia]] = None,
|
|
56
|
+
background_tasks: Optional[BackgroundTasks] = None,
|
|
57
|
+
**kwargs: Any,
|
|
58
|
+
) -> AsyncGenerator:
|
|
59
|
+
try:
|
|
60
|
+
# Pass background_tasks if provided
|
|
61
|
+
if background_tasks is not None:
|
|
62
|
+
kwargs["background_tasks"] = background_tasks
|
|
63
|
+
|
|
64
|
+
run_response = agent.arun(
|
|
65
|
+
input=message,
|
|
66
|
+
session_id=session_id,
|
|
67
|
+
user_id=user_id,
|
|
68
|
+
images=images,
|
|
69
|
+
audio=audio,
|
|
70
|
+
videos=videos,
|
|
71
|
+
files=files,
|
|
72
|
+
stream=True,
|
|
73
|
+
stream_events=True,
|
|
74
|
+
**kwargs,
|
|
75
|
+
)
|
|
76
|
+
async for run_response_chunk in run_response:
|
|
77
|
+
yield format_sse_event(run_response_chunk) # type: ignore
|
|
78
|
+
except (InputCheckError, OutputCheckError) as e:
|
|
79
|
+
error_response = RunErrorEvent(
|
|
80
|
+
content=str(e),
|
|
81
|
+
error_type=e.type,
|
|
82
|
+
error_id=e.error_id,
|
|
83
|
+
additional_data=e.additional_data,
|
|
84
|
+
)
|
|
85
|
+
yield format_sse_event(error_response)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
import traceback
|
|
88
|
+
|
|
89
|
+
traceback.print_exc(limit=3)
|
|
90
|
+
error_response = RunErrorEvent(
|
|
91
|
+
content=str(e),
|
|
92
|
+
)
|
|
93
|
+
yield format_sse_event(error_response)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
async def agent_continue_response_streamer(
|
|
97
|
+
agent: Agent,
|
|
98
|
+
run_id: Optional[str] = None,
|
|
99
|
+
updated_tools: Optional[List] = None,
|
|
100
|
+
session_id: Optional[str] = None,
|
|
101
|
+
user_id: Optional[str] = None,
|
|
102
|
+
background_tasks: Optional[BackgroundTasks] = None,
|
|
103
|
+
) -> AsyncGenerator:
|
|
104
|
+
try:
|
|
105
|
+
continue_response = agent.acontinue_run(
|
|
106
|
+
run_id=run_id,
|
|
107
|
+
updated_tools=updated_tools,
|
|
108
|
+
session_id=session_id,
|
|
109
|
+
user_id=user_id,
|
|
110
|
+
stream=True,
|
|
111
|
+
stream_events=True,
|
|
112
|
+
background_tasks=background_tasks,
|
|
113
|
+
)
|
|
114
|
+
async for run_response_chunk in continue_response:
|
|
115
|
+
yield format_sse_event(run_response_chunk) # type: ignore
|
|
116
|
+
except (InputCheckError, OutputCheckError) as e:
|
|
117
|
+
error_response = RunErrorEvent(
|
|
118
|
+
content=str(e),
|
|
119
|
+
error_type=e.type,
|
|
120
|
+
error_id=e.error_id,
|
|
121
|
+
additional_data=e.additional_data,
|
|
122
|
+
)
|
|
123
|
+
yield format_sse_event(error_response)
|
|
124
|
+
|
|
125
|
+
except Exception as e:
|
|
126
|
+
import traceback
|
|
127
|
+
|
|
128
|
+
traceback.print_exc(limit=3)
|
|
129
|
+
error_response = RunErrorEvent(
|
|
130
|
+
content=str(e),
|
|
131
|
+
error_type=e.type if hasattr(e, "type") else None,
|
|
132
|
+
error_id=e.error_id if hasattr(e, "error_id") else None,
|
|
133
|
+
)
|
|
134
|
+
yield format_sse_event(error_response)
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def get_agent_router(
|
|
139
|
+
os: "AgentOS",
|
|
140
|
+
settings: AgnoAPISettings = AgnoAPISettings(),
|
|
141
|
+
) -> APIRouter:
|
|
142
|
+
"""
|
|
143
|
+
Create the agent router with comprehensive OpenAPI documentation.
|
|
144
|
+
"""
|
|
145
|
+
router = APIRouter(
|
|
146
|
+
dependencies=[Depends(get_authentication_dependency(settings))],
|
|
147
|
+
responses={
|
|
148
|
+
400: {"description": "Bad Request", "model": BadRequestResponse},
|
|
149
|
+
401: {"description": "Unauthorized", "model": UnauthenticatedResponse},
|
|
150
|
+
404: {"description": "Not Found", "model": NotFoundResponse},
|
|
151
|
+
422: {"description": "Validation Error", "model": ValidationErrorResponse},
|
|
152
|
+
500: {"description": "Internal Server Error", "model": InternalServerErrorResponse},
|
|
153
|
+
},
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
@router.post(
|
|
157
|
+
"/agents/{agent_id}/runs",
|
|
158
|
+
tags=["Agents"],
|
|
159
|
+
operation_id="create_agent_run",
|
|
160
|
+
response_model_exclude_none=True,
|
|
161
|
+
summary="Create Agent Run",
|
|
162
|
+
description=(
|
|
163
|
+
"Execute an agent with a message and optional media files. Supports both streaming and non-streaming responses.\n\n"
|
|
164
|
+
"**Features:**\n"
|
|
165
|
+
"- Text message input with optional session management\n"
|
|
166
|
+
"- Multi-media support: images (PNG, JPEG, WebP), audio (WAV, MP3), video (MP4, WebM, etc.)\n"
|
|
167
|
+
"- Document processing: PDF, CSV, DOCX, TXT, JSON\n"
|
|
168
|
+
"- Real-time streaming responses with Server-Sent Events (SSE)\n"
|
|
169
|
+
"- User and session context preservation\n\n"
|
|
170
|
+
"**Streaming Response:**\n"
|
|
171
|
+
"When `stream=true`, returns SSE events with `event` and `data` fields."
|
|
172
|
+
),
|
|
173
|
+
responses={
|
|
174
|
+
200: {
|
|
175
|
+
"description": "Agent run executed successfully",
|
|
176
|
+
"content": {
|
|
177
|
+
"text/event-stream": {
|
|
178
|
+
"examples": {
|
|
179
|
+
"event_stream": {
|
|
180
|
+
"summary": "Example event stream response",
|
|
181
|
+
"value": 'event: RunStarted\ndata: {"content": "Hello!", "run_id": "123..."}\n\n',
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
400: {"description": "Invalid request or unsupported file type", "model": BadRequestResponse},
|
|
188
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
189
|
+
},
|
|
190
|
+
dependencies=[Depends(require_resource_access("agents", "run", "agent_id"))],
|
|
191
|
+
)
|
|
192
|
+
async def create_agent_run(
|
|
193
|
+
agent_id: str,
|
|
194
|
+
request: Request,
|
|
195
|
+
background_tasks: BackgroundTasks,
|
|
196
|
+
message: str = Form(...),
|
|
197
|
+
stream: bool = Form(False),
|
|
198
|
+
session_id: Optional[str] = Form(None),
|
|
199
|
+
user_id: Optional[str] = Form(None),
|
|
200
|
+
files: Optional[List[UploadFile]] = File(None),
|
|
201
|
+
):
|
|
202
|
+
kwargs = await get_request_kwargs(request, create_agent_run)
|
|
203
|
+
|
|
204
|
+
if hasattr(request.state, "user_id"):
|
|
205
|
+
if user_id:
|
|
206
|
+
log_warning("User ID parameter passed in both request state and kwargs, using request state")
|
|
207
|
+
user_id = request.state.user_id
|
|
208
|
+
if hasattr(request.state, "session_id"):
|
|
209
|
+
if session_id:
|
|
210
|
+
log_warning("Session ID parameter passed in both request state and kwargs, using request state")
|
|
211
|
+
session_id = request.state.session_id
|
|
212
|
+
if hasattr(request.state, "session_state"):
|
|
213
|
+
session_state = request.state.session_state
|
|
214
|
+
if "session_state" in kwargs:
|
|
215
|
+
log_warning("Session state parameter passed in both request state and kwargs, using request state")
|
|
216
|
+
kwargs["session_state"] = session_state
|
|
217
|
+
if hasattr(request.state, "dependencies"):
|
|
218
|
+
dependencies = request.state.dependencies
|
|
219
|
+
if "dependencies" in kwargs:
|
|
220
|
+
log_warning("Dependencies parameter passed in both request state and kwargs, using request state")
|
|
221
|
+
kwargs["dependencies"] = dependencies
|
|
222
|
+
if hasattr(request.state, "metadata"):
|
|
223
|
+
metadata = request.state.metadata
|
|
224
|
+
if "metadata" in kwargs:
|
|
225
|
+
log_warning("Metadata parameter passed in both request state and kwargs, using request state")
|
|
226
|
+
kwargs["metadata"] = metadata
|
|
227
|
+
|
|
228
|
+
agent = get_agent_by_id(agent_id, os.agents)
|
|
229
|
+
if agent is None:
|
|
230
|
+
raise HTTPException(status_code=404, detail="Agent not found")
|
|
231
|
+
|
|
232
|
+
if session_id is None or session_id == "":
|
|
233
|
+
log_debug("Creating new session")
|
|
234
|
+
session_id = str(uuid4())
|
|
235
|
+
|
|
236
|
+
base64_images: List[Image] = []
|
|
237
|
+
base64_audios: List[Audio] = []
|
|
238
|
+
base64_videos: List[Video] = []
|
|
239
|
+
input_files: List[FileMedia] = []
|
|
240
|
+
|
|
241
|
+
if files:
|
|
242
|
+
for file in files:
|
|
243
|
+
if file.content_type in [
|
|
244
|
+
"image/png",
|
|
245
|
+
"image/jpeg",
|
|
246
|
+
"image/jpg",
|
|
247
|
+
"image/gif",
|
|
248
|
+
"image/webp",
|
|
249
|
+
"image/bmp",
|
|
250
|
+
"image/tiff",
|
|
251
|
+
"image/tif",
|
|
252
|
+
"image/avif",
|
|
253
|
+
]:
|
|
254
|
+
try:
|
|
255
|
+
base64_image = process_image(file)
|
|
256
|
+
base64_images.append(base64_image)
|
|
257
|
+
except Exception as e:
|
|
258
|
+
log_error(f"Error processing image {file.filename}: {e}")
|
|
259
|
+
continue
|
|
260
|
+
elif file.content_type in [
|
|
261
|
+
"audio/wav",
|
|
262
|
+
"audio/wave",
|
|
263
|
+
"audio/mp3",
|
|
264
|
+
"audio/mpeg",
|
|
265
|
+
"audio/ogg",
|
|
266
|
+
"audio/mp4",
|
|
267
|
+
"audio/m4a",
|
|
268
|
+
"audio/aac",
|
|
269
|
+
"audio/flac",
|
|
270
|
+
]:
|
|
271
|
+
try:
|
|
272
|
+
audio = process_audio(file)
|
|
273
|
+
base64_audios.append(audio)
|
|
274
|
+
except Exception as e:
|
|
275
|
+
log_error(f"Error processing audio {file.filename} with content type {file.content_type}: {e}")
|
|
276
|
+
continue
|
|
277
|
+
elif file.content_type in [
|
|
278
|
+
"video/x-flv",
|
|
279
|
+
"video/quicktime",
|
|
280
|
+
"video/mpeg",
|
|
281
|
+
"video/mpegs",
|
|
282
|
+
"video/mpgs",
|
|
283
|
+
"video/mpg",
|
|
284
|
+
"video/mpg",
|
|
285
|
+
"video/mp4",
|
|
286
|
+
"video/webm",
|
|
287
|
+
"video/wmv",
|
|
288
|
+
"video/3gpp",
|
|
289
|
+
]:
|
|
290
|
+
try:
|
|
291
|
+
base64_video = process_video(file)
|
|
292
|
+
base64_videos.append(base64_video)
|
|
293
|
+
except Exception as e:
|
|
294
|
+
log_error(f"Error processing video {file.filename}: {e}")
|
|
295
|
+
continue
|
|
296
|
+
elif file.content_type in [
|
|
297
|
+
"application/pdf",
|
|
298
|
+
"application/json",
|
|
299
|
+
"application/x-javascript",
|
|
300
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
301
|
+
"text/javascript",
|
|
302
|
+
"application/x-python",
|
|
303
|
+
"text/x-python",
|
|
304
|
+
"text/plain",
|
|
305
|
+
"text/html",
|
|
306
|
+
"text/css",
|
|
307
|
+
"text/md",
|
|
308
|
+
"text/csv",
|
|
309
|
+
"text/xml",
|
|
310
|
+
"text/rtf",
|
|
311
|
+
]:
|
|
312
|
+
# Process document files
|
|
313
|
+
try:
|
|
314
|
+
input_file = process_document(file)
|
|
315
|
+
if input_file is not None:
|
|
316
|
+
input_files.append(input_file)
|
|
317
|
+
except Exception as e:
|
|
318
|
+
log_error(f"Error processing file {file.filename}: {e}")
|
|
319
|
+
continue
|
|
320
|
+
else:
|
|
321
|
+
raise HTTPException(status_code=400, detail="Unsupported file type")
|
|
322
|
+
|
|
323
|
+
if stream:
|
|
324
|
+
return StreamingResponse(
|
|
325
|
+
agent_response_streamer(
|
|
326
|
+
agent,
|
|
327
|
+
message,
|
|
328
|
+
session_id=session_id,
|
|
329
|
+
user_id=user_id,
|
|
330
|
+
images=base64_images if base64_images else None,
|
|
331
|
+
audio=base64_audios if base64_audios else None,
|
|
332
|
+
videos=base64_videos if base64_videos else None,
|
|
333
|
+
files=input_files if input_files else None,
|
|
334
|
+
background_tasks=background_tasks,
|
|
335
|
+
**kwargs,
|
|
336
|
+
),
|
|
337
|
+
media_type="text/event-stream",
|
|
338
|
+
)
|
|
339
|
+
else:
|
|
340
|
+
try:
|
|
341
|
+
run_response = cast(
|
|
342
|
+
RunOutput,
|
|
343
|
+
await agent.arun(
|
|
344
|
+
input=message,
|
|
345
|
+
session_id=session_id,
|
|
346
|
+
user_id=user_id,
|
|
347
|
+
images=base64_images if base64_images else None,
|
|
348
|
+
audio=base64_audios if base64_audios else None,
|
|
349
|
+
videos=base64_videos if base64_videos else None,
|
|
350
|
+
files=input_files if input_files else None,
|
|
351
|
+
stream=False,
|
|
352
|
+
background_tasks=background_tasks,
|
|
353
|
+
**kwargs,
|
|
354
|
+
),
|
|
355
|
+
)
|
|
356
|
+
return run_response.to_dict()
|
|
357
|
+
|
|
358
|
+
except InputCheckError as e:
|
|
359
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
360
|
+
|
|
361
|
+
@router.post(
|
|
362
|
+
"/agents/{agent_id}/runs/{run_id}/cancel",
|
|
363
|
+
tags=["Agents"],
|
|
364
|
+
operation_id="cancel_agent_run",
|
|
365
|
+
response_model_exclude_none=True,
|
|
366
|
+
summary="Cancel Agent Run",
|
|
367
|
+
description=(
|
|
368
|
+
"Cancel a currently executing agent run. This will attempt to stop the agent's execution gracefully.\n\n"
|
|
369
|
+
"**Note:** Cancellation may not be immediate for all operations."
|
|
370
|
+
),
|
|
371
|
+
responses={
|
|
372
|
+
200: {},
|
|
373
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
374
|
+
500: {"description": "Failed to cancel run", "model": InternalServerErrorResponse},
|
|
375
|
+
},
|
|
376
|
+
dependencies=[Depends(require_resource_access("agents", "run", "agent_id"))],
|
|
377
|
+
)
|
|
378
|
+
async def cancel_agent_run(
|
|
379
|
+
agent_id: str,
|
|
380
|
+
run_id: str,
|
|
381
|
+
):
|
|
382
|
+
agent = get_agent_by_id(agent_id, os.agents)
|
|
383
|
+
if agent is None:
|
|
384
|
+
raise HTTPException(status_code=404, detail="Agent not found")
|
|
385
|
+
|
|
386
|
+
if not agent.cancel_run(run_id=run_id):
|
|
387
|
+
raise HTTPException(status_code=500, detail="Failed to cancel run")
|
|
388
|
+
|
|
389
|
+
return JSONResponse(content={}, status_code=200)
|
|
390
|
+
|
|
391
|
+
@router.post(
|
|
392
|
+
"/agents/{agent_id}/runs/{run_id}/continue",
|
|
393
|
+
tags=["Agents"],
|
|
394
|
+
operation_id="continue_agent_run",
|
|
395
|
+
response_model_exclude_none=True,
|
|
396
|
+
summary="Continue Agent Run",
|
|
397
|
+
description=(
|
|
398
|
+
"Continue a paused or incomplete agent run with updated tool results.\n\n"
|
|
399
|
+
"**Use Cases:**\n"
|
|
400
|
+
"- Resume execution after tool approval/rejection\n"
|
|
401
|
+
"- Provide manual tool execution results\n\n"
|
|
402
|
+
"**Tools Parameter:**\n"
|
|
403
|
+
"JSON string containing array of tool execution objects with results."
|
|
404
|
+
),
|
|
405
|
+
responses={
|
|
406
|
+
200: {
|
|
407
|
+
"description": "Agent run continued successfully",
|
|
408
|
+
"content": {
|
|
409
|
+
"text/event-stream": {
|
|
410
|
+
"example": 'event: RunContent\ndata: {"created_at": 1757348314, "run_id": "123..."}\n\n'
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
400: {"description": "Invalid JSON in tools field or invalid tool structure", "model": BadRequestResponse},
|
|
415
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
416
|
+
},
|
|
417
|
+
dependencies=[Depends(require_resource_access("agents", "run", "agent_id"))],
|
|
418
|
+
)
|
|
419
|
+
async def continue_agent_run(
|
|
420
|
+
agent_id: str,
|
|
421
|
+
run_id: str,
|
|
422
|
+
request: Request,
|
|
423
|
+
background_tasks: BackgroundTasks,
|
|
424
|
+
tools: str = Form(...), # JSON string of tools
|
|
425
|
+
session_id: Optional[str] = Form(None),
|
|
426
|
+
user_id: Optional[str] = Form(None),
|
|
427
|
+
stream: bool = Form(True),
|
|
428
|
+
):
|
|
429
|
+
if hasattr(request.state, "user_id"):
|
|
430
|
+
user_id = request.state.user_id
|
|
431
|
+
if hasattr(request.state, "session_id"):
|
|
432
|
+
session_id = request.state.session_id
|
|
433
|
+
|
|
434
|
+
# Parse the JSON string manually
|
|
435
|
+
try:
|
|
436
|
+
tools_data = json.loads(tools) if tools else None
|
|
437
|
+
except json.JSONDecodeError:
|
|
438
|
+
raise HTTPException(status_code=400, detail="Invalid JSON in tools field")
|
|
439
|
+
|
|
440
|
+
agent = get_agent_by_id(agent_id, os.agents)
|
|
441
|
+
if agent is None:
|
|
442
|
+
raise HTTPException(status_code=404, detail="Agent not found")
|
|
443
|
+
|
|
444
|
+
if session_id is None or session_id == "":
|
|
445
|
+
log_warning(
|
|
446
|
+
"Continuing run without session_id. This might lead to unexpected behavior if session context is important."
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
# Convert tools dict to ToolExecution objects if provided
|
|
450
|
+
updated_tools = None
|
|
451
|
+
if tools_data:
|
|
452
|
+
try:
|
|
453
|
+
from agno.models.response import ToolExecution
|
|
454
|
+
|
|
455
|
+
updated_tools = [ToolExecution.from_dict(tool) for tool in tools_data]
|
|
456
|
+
except Exception as e:
|
|
457
|
+
raise HTTPException(status_code=400, detail=f"Invalid structure or content for tools: {str(e)}")
|
|
458
|
+
|
|
459
|
+
if stream:
|
|
460
|
+
return StreamingResponse(
|
|
461
|
+
agent_continue_response_streamer(
|
|
462
|
+
agent,
|
|
463
|
+
run_id=run_id, # run_id from path
|
|
464
|
+
updated_tools=updated_tools,
|
|
465
|
+
session_id=session_id,
|
|
466
|
+
user_id=user_id,
|
|
467
|
+
background_tasks=background_tasks,
|
|
468
|
+
),
|
|
469
|
+
media_type="text/event-stream",
|
|
470
|
+
)
|
|
471
|
+
else:
|
|
472
|
+
try:
|
|
473
|
+
run_response_obj = cast(
|
|
474
|
+
RunOutput,
|
|
475
|
+
await agent.acontinue_run(
|
|
476
|
+
run_id=run_id, # run_id from path
|
|
477
|
+
updated_tools=updated_tools,
|
|
478
|
+
session_id=session_id,
|
|
479
|
+
user_id=user_id,
|
|
480
|
+
stream=False,
|
|
481
|
+
background_tasks=background_tasks,
|
|
482
|
+
),
|
|
483
|
+
)
|
|
484
|
+
return run_response_obj.to_dict()
|
|
485
|
+
|
|
486
|
+
except InputCheckError as e:
|
|
487
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
488
|
+
|
|
489
|
+
@router.get(
|
|
490
|
+
"/agents",
|
|
491
|
+
response_model=List[AgentResponse],
|
|
492
|
+
response_model_exclude_none=True,
|
|
493
|
+
tags=["Agents"],
|
|
494
|
+
operation_id="get_agents",
|
|
495
|
+
summary="List All Agents",
|
|
496
|
+
description=(
|
|
497
|
+
"Retrieve a comprehensive list of all agents configured in this OS instance.\n\n"
|
|
498
|
+
"**Returns:**\n"
|
|
499
|
+
"- Agent metadata (ID, name, description)\n"
|
|
500
|
+
"- Model configuration and capabilities\n"
|
|
501
|
+
"- Available tools and their configurations\n"
|
|
502
|
+
"- Session, knowledge, memory, and reasoning settings\n"
|
|
503
|
+
"- Only meaningful (non-default) configurations are included"
|
|
504
|
+
),
|
|
505
|
+
responses={
|
|
506
|
+
200: {
|
|
507
|
+
"description": "List of agents retrieved successfully",
|
|
508
|
+
"content": {
|
|
509
|
+
"application/json": {
|
|
510
|
+
"example": [
|
|
511
|
+
{
|
|
512
|
+
"id": "main-agent",
|
|
513
|
+
"name": "Main Agent",
|
|
514
|
+
"db_id": "c6bf0644-feb8-4930-a305-380dae5ad6aa",
|
|
515
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
516
|
+
"tools": None,
|
|
517
|
+
"sessions": {"session_table": "agno_sessions"},
|
|
518
|
+
"knowledge": {"knowledge_table": "main_knowledge"},
|
|
519
|
+
"system_message": {"markdown": True, "add_datetime_to_context": True},
|
|
520
|
+
}
|
|
521
|
+
]
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
)
|
|
527
|
+
async def get_agents(request: Request) -> List[AgentResponse]:
|
|
528
|
+
"""Return the list of all Agents present in the contextual OS"""
|
|
529
|
+
if os.agents is None:
|
|
530
|
+
return []
|
|
531
|
+
|
|
532
|
+
# Filter agents based on user's scopes (only if authorization is enabled)
|
|
533
|
+
if getattr(request.state, "authorization_enabled", False):
|
|
534
|
+
from agno.os.auth import filter_resources_by_access, get_accessible_resources
|
|
535
|
+
|
|
536
|
+
# Check if user has any agent scopes at all
|
|
537
|
+
accessible_ids = get_accessible_resources(request, "agents")
|
|
538
|
+
if not accessible_ids:
|
|
539
|
+
raise HTTPException(status_code=403, detail="Insufficient permissions")
|
|
540
|
+
|
|
541
|
+
# Limit results based on the user's access/scopes
|
|
542
|
+
accessible_agents = filter_resources_by_access(request, os.agents, "agents")
|
|
543
|
+
else:
|
|
544
|
+
accessible_agents = os.agents
|
|
545
|
+
|
|
546
|
+
agents = []
|
|
547
|
+
for agent in accessible_agents:
|
|
548
|
+
agent_response = await AgentResponse.from_agent(agent=agent)
|
|
549
|
+
agents.append(agent_response)
|
|
550
|
+
|
|
551
|
+
return agents
|
|
552
|
+
|
|
553
|
+
@router.get(
|
|
554
|
+
"/agents/{agent_id}",
|
|
555
|
+
response_model=AgentResponse,
|
|
556
|
+
response_model_exclude_none=True,
|
|
557
|
+
tags=["Agents"],
|
|
558
|
+
operation_id="get_agent",
|
|
559
|
+
summary="Get Agent Details",
|
|
560
|
+
description=(
|
|
561
|
+
"Retrieve detailed configuration and capabilities of a specific agent.\n\n"
|
|
562
|
+
"**Returns comprehensive agent information including:**\n"
|
|
563
|
+
"- Model configuration and provider details\n"
|
|
564
|
+
"- Complete tool inventory and configurations\n"
|
|
565
|
+
"- Session management settings\n"
|
|
566
|
+
"- Knowledge base and memory configurations\n"
|
|
567
|
+
"- Reasoning capabilities and settings\n"
|
|
568
|
+
"- System prompts and response formatting options"
|
|
569
|
+
),
|
|
570
|
+
responses={
|
|
571
|
+
200: {
|
|
572
|
+
"description": "Agent details retrieved successfully",
|
|
573
|
+
"content": {
|
|
574
|
+
"application/json": {
|
|
575
|
+
"example": {
|
|
576
|
+
"id": "main-agent",
|
|
577
|
+
"name": "Main Agent",
|
|
578
|
+
"db_id": "9e064c70-6821-4840-a333-ce6230908a70",
|
|
579
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
580
|
+
"tools": None,
|
|
581
|
+
"sessions": {"session_table": "agno_sessions"},
|
|
582
|
+
"knowledge": {"knowledge_table": "main_knowledge"},
|
|
583
|
+
"system_message": {"markdown": True, "add_datetime_to_context": True},
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
589
|
+
},
|
|
590
|
+
dependencies=[Depends(require_resource_access("agents", "read", "agent_id"))],
|
|
591
|
+
)
|
|
592
|
+
async def get_agent(agent_id: str, request: Request) -> AgentResponse:
|
|
593
|
+
agent = get_agent_by_id(agent_id, os.agents)
|
|
594
|
+
if agent is None:
|
|
595
|
+
raise HTTPException(status_code=404, detail="Agent not found")
|
|
596
|
+
|
|
597
|
+
return await AgentResponse.from_agent(agent)
|
|
598
|
+
|
|
599
|
+
return router
|