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/utils/prompts.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Type, Union
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
from agno.utils.log import log_warning
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_json_output_prompt(output_schema: Union[str, list, BaseModel]) -> str:
|
|
10
|
+
"""Return the JSON output prompt for the Agent.
|
|
11
|
+
|
|
12
|
+
This is added to the system prompt when the output_schema is set and structured_outputs is False.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
json_output_prompt = "Provide your output as a JSON containing the following fields:"
|
|
16
|
+
if output_schema is not None:
|
|
17
|
+
if isinstance(output_schema, str):
|
|
18
|
+
json_output_prompt += "\n<json_fields>"
|
|
19
|
+
json_output_prompt += f"\n{output_schema}"
|
|
20
|
+
json_output_prompt += "\n</json_fields>"
|
|
21
|
+
elif isinstance(output_schema, list):
|
|
22
|
+
json_output_prompt += "\n<json_fields>"
|
|
23
|
+
json_output_prompt += f"\n{json.dumps(output_schema)}"
|
|
24
|
+
json_output_prompt += "\n</json_fields>"
|
|
25
|
+
elif (
|
|
26
|
+
issubclass(type(output_schema), BaseModel)
|
|
27
|
+
or issubclass(output_schema, BaseModel) # type: ignore
|
|
28
|
+
or isinstance(output_schema, BaseModel)
|
|
29
|
+
): # type: ignore
|
|
30
|
+
json_schema = output_schema.model_json_schema()
|
|
31
|
+
if json_schema is not None:
|
|
32
|
+
response_model_properties = {}
|
|
33
|
+
json_schema_properties = json_schema.get("properties")
|
|
34
|
+
if json_schema_properties is not None:
|
|
35
|
+
for field_name, field_properties in json_schema_properties.items():
|
|
36
|
+
formatted_field_properties = {
|
|
37
|
+
prop_name: prop_value
|
|
38
|
+
for prop_name, prop_value in field_properties.items()
|
|
39
|
+
if prop_name != "title"
|
|
40
|
+
}
|
|
41
|
+
# Handle enum references
|
|
42
|
+
if "allOf" in formatted_field_properties:
|
|
43
|
+
ref = formatted_field_properties["allOf"][0].get("$ref", "")
|
|
44
|
+
if ref.startswith("#/$defs/"):
|
|
45
|
+
enum_name = ref.split("/")[-1]
|
|
46
|
+
formatted_field_properties["enum_type"] = enum_name
|
|
47
|
+
|
|
48
|
+
response_model_properties[field_name] = formatted_field_properties
|
|
49
|
+
|
|
50
|
+
json_schema_defs = json_schema.get("$defs")
|
|
51
|
+
if json_schema_defs is not None:
|
|
52
|
+
response_model_properties["$defs"] = {}
|
|
53
|
+
for def_name, def_properties in json_schema_defs.items():
|
|
54
|
+
# Handle both regular object definitions and enums
|
|
55
|
+
if "enum" in def_properties:
|
|
56
|
+
# This is an enum definition
|
|
57
|
+
response_model_properties["$defs"][def_name] = {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": def_properties["enum"],
|
|
60
|
+
"description": def_properties.get("description", ""),
|
|
61
|
+
}
|
|
62
|
+
else:
|
|
63
|
+
# This is a regular object definition
|
|
64
|
+
def_fields = def_properties.get("properties")
|
|
65
|
+
formatted_def_properties = {}
|
|
66
|
+
if def_fields is not None:
|
|
67
|
+
for field_name, field_properties in def_fields.items():
|
|
68
|
+
formatted_field_properties = {
|
|
69
|
+
prop_name: prop_value
|
|
70
|
+
for prop_name, prop_value in field_properties.items()
|
|
71
|
+
if prop_name != "title"
|
|
72
|
+
}
|
|
73
|
+
formatted_def_properties[field_name] = formatted_field_properties
|
|
74
|
+
if len(formatted_def_properties) > 0:
|
|
75
|
+
response_model_properties["$defs"][def_name] = formatted_def_properties
|
|
76
|
+
|
|
77
|
+
if len(response_model_properties) > 0:
|
|
78
|
+
json_output_prompt += "\n<json_fields>"
|
|
79
|
+
json_output_prompt += (
|
|
80
|
+
f"\n{json.dumps([key for key in response_model_properties.keys() if key != '$defs'])}"
|
|
81
|
+
)
|
|
82
|
+
json_output_prompt += "\n</json_fields>"
|
|
83
|
+
json_output_prompt += "\n\nHere are the properties for each field:"
|
|
84
|
+
json_output_prompt += "\n<json_field_properties>"
|
|
85
|
+
json_output_prompt += f"\n{json.dumps(response_model_properties, indent=2)}"
|
|
86
|
+
json_output_prompt += "\n</json_field_properties>"
|
|
87
|
+
else:
|
|
88
|
+
log_warning(f"Could not build json schema for {output_schema}")
|
|
89
|
+
else:
|
|
90
|
+
json_output_prompt += "Provide the output as JSON."
|
|
91
|
+
|
|
92
|
+
json_output_prompt += "\nStart your response with `{` and end it with `}`."
|
|
93
|
+
json_output_prompt += "\nYour output will be passed to json.loads() to convert it to a Python object."
|
|
94
|
+
json_output_prompt += "\nMake sure it only contains valid JSON."
|
|
95
|
+
return json_output_prompt
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_response_model_format_prompt(output_schema: Type[BaseModel]) -> str:
|
|
99
|
+
"""Return the format prompt for the response model."""
|
|
100
|
+
|
|
101
|
+
message = "Make sure your response is a valid string (NOT JSON) that mentions the following topics:"
|
|
102
|
+
|
|
103
|
+
# Extract field names and descriptions
|
|
104
|
+
for field_name, field_info in output_schema.model_fields.items():
|
|
105
|
+
description = field_info.description or ""
|
|
106
|
+
if description:
|
|
107
|
+
message += f"\n- {field_name}: {description}"
|
|
108
|
+
else:
|
|
109
|
+
message += f"\n- {field_name}"
|
|
110
|
+
|
|
111
|
+
return message
|
agno/utils/reasoning.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List, Optional, Tuple, Union
|
|
2
|
+
|
|
3
|
+
from agno.models.message import Message
|
|
4
|
+
from agno.models.metrics import Metrics
|
|
5
|
+
from agno.reasoning.step import ReasoningStep
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from agno.run.agent import RunOutput
|
|
9
|
+
from agno.team.team import TeamRunOutput
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def extract_thinking_content(content: str) -> Tuple[Optional[str], str]:
|
|
13
|
+
"""Extract thinking content from response text between <think> tags."""
|
|
14
|
+
if not content or "</think>" not in content:
|
|
15
|
+
return None, content
|
|
16
|
+
|
|
17
|
+
# Find the end of thinking content
|
|
18
|
+
end_idx = content.find("</think>")
|
|
19
|
+
|
|
20
|
+
# Look for opening <think> tag, if not found, assume thinking starts at beginning
|
|
21
|
+
start_idx = content.find("<think>")
|
|
22
|
+
if start_idx == -1:
|
|
23
|
+
reasoning_content = content[:end_idx].strip()
|
|
24
|
+
else:
|
|
25
|
+
start_idx = start_idx + len("<think>")
|
|
26
|
+
reasoning_content = content[start_idx:end_idx].strip()
|
|
27
|
+
|
|
28
|
+
output_content = content[end_idx + len("</think>") :].strip()
|
|
29
|
+
|
|
30
|
+
return reasoning_content, output_content
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def append_to_reasoning_content(run_response: Union["RunOutput", "TeamRunOutput"], content: str) -> None:
|
|
34
|
+
"""Helper to append content to the reasoning_content field."""
|
|
35
|
+
if not hasattr(run_response, "reasoning_content") or not run_response.reasoning_content: # type: ignore
|
|
36
|
+
run_response.reasoning_content = content # type: ignore
|
|
37
|
+
else:
|
|
38
|
+
run_response.reasoning_content += content # type: ignore
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def add_reasoning_step_to_metadata(
|
|
42
|
+
run_response: Union["RunOutput", "TeamRunOutput"], reasoning_step: ReasoningStep
|
|
43
|
+
) -> None:
|
|
44
|
+
if run_response.reasoning_steps is None:
|
|
45
|
+
run_response.reasoning_steps = []
|
|
46
|
+
|
|
47
|
+
run_response.reasoning_steps.append(reasoning_step)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def add_reasoning_metrics_to_metadata(
|
|
51
|
+
run_response: Union["RunOutput", "TeamRunOutput"], reasoning_time_taken: float
|
|
52
|
+
) -> None:
|
|
53
|
+
try:
|
|
54
|
+
# Initialize reasoning_messages if it doesn't exist
|
|
55
|
+
if run_response.reasoning_messages is None:
|
|
56
|
+
run_response.reasoning_messages = []
|
|
57
|
+
|
|
58
|
+
metrics_message = Message(
|
|
59
|
+
role="assistant",
|
|
60
|
+
content=run_response.reasoning_content,
|
|
61
|
+
metrics=Metrics(duration=reasoning_time_taken),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Add the metrics message to the reasoning_messages
|
|
65
|
+
run_response.reasoning_messages.append(metrics_message)
|
|
66
|
+
|
|
67
|
+
except Exception as e:
|
|
68
|
+
# Log the error but don't crash
|
|
69
|
+
from agno.utils.log import log_error
|
|
70
|
+
|
|
71
|
+
log_error(f"Failed to add reasoning metrics to metadata: {str(e)}")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def update_run_output_with_reasoning(
|
|
75
|
+
run_response: Union["RunOutput", "TeamRunOutput"],
|
|
76
|
+
reasoning_steps: List[ReasoningStep],
|
|
77
|
+
reasoning_agent_messages: List[Message],
|
|
78
|
+
) -> None:
|
|
79
|
+
# Update reasoning_steps
|
|
80
|
+
if run_response.reasoning_steps is None:
|
|
81
|
+
run_response.reasoning_steps = reasoning_steps
|
|
82
|
+
else:
|
|
83
|
+
run_response.reasoning_steps.extend(reasoning_steps)
|
|
84
|
+
|
|
85
|
+
# Update reasoning_messages
|
|
86
|
+
if run_response.reasoning_messages is None:
|
|
87
|
+
run_response.reasoning_messages = reasoning_agent_messages
|
|
88
|
+
else:
|
|
89
|
+
run_response.reasoning_messages.extend(reasoning_agent_messages)
|
|
90
|
+
|
|
91
|
+
# Create and store reasoning_content
|
|
92
|
+
reasoning_content = ""
|
|
93
|
+
for step in reasoning_steps:
|
|
94
|
+
if step.title:
|
|
95
|
+
reasoning_content += f"## {step.title}\n"
|
|
96
|
+
if step.reasoning:
|
|
97
|
+
reasoning_content += f"{step.reasoning}\n"
|
|
98
|
+
if step.action:
|
|
99
|
+
reasoning_content += f"Action: {step.action}\n"
|
|
100
|
+
if step.result:
|
|
101
|
+
reasoning_content += f"Result: {step.result}\n"
|
|
102
|
+
reasoning_content += "\n"
|
|
103
|
+
|
|
104
|
+
# Add to existing reasoning_content or set it
|
|
105
|
+
if not run_response.reasoning_content:
|
|
106
|
+
run_response.reasoning_content = reasoning_content
|
|
107
|
+
else:
|
|
108
|
+
run_response.reasoning_content += reasoning_content
|
agno/utils/response.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
from typing import AsyncIterator, Iterator, List, Set, Union
|
|
2
|
+
|
|
3
|
+
from agno.exceptions import RunCancelledException
|
|
4
|
+
from agno.models.response import ToolExecution
|
|
5
|
+
from agno.reasoning.step import ReasoningStep
|
|
6
|
+
from agno.run.agent import RunOutput, RunOutputEvent, RunPausedEvent
|
|
7
|
+
from agno.run.team import TeamRunOutput, TeamRunOutputEvent
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def create_panel(content, title, border_style="blue"):
|
|
11
|
+
from rich.box import HEAVY
|
|
12
|
+
from rich.panel import Panel
|
|
13
|
+
|
|
14
|
+
return Panel(
|
|
15
|
+
content, title=title, title_align="left", border_style=border_style, box=HEAVY, expand=True, padding=(1, 1)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def build_reasoning_step_panel(
|
|
20
|
+
step_idx: int, step: ReasoningStep, show_full_reasoning: bool = False, color: str = "green"
|
|
21
|
+
):
|
|
22
|
+
from rich.text import Text
|
|
23
|
+
|
|
24
|
+
# Build step content
|
|
25
|
+
step_content = Text.assemble()
|
|
26
|
+
if step.title is not None:
|
|
27
|
+
step_content.append(f"{step.title}\n", "bold")
|
|
28
|
+
if step.action is not None:
|
|
29
|
+
step_content.append(Text.from_markup(f"[bold]Action:[/bold] {step.action}\n", style="dim"))
|
|
30
|
+
if step.result is not None:
|
|
31
|
+
step_content.append(Text.from_markup(step.result, style="dim"))
|
|
32
|
+
|
|
33
|
+
if show_full_reasoning:
|
|
34
|
+
# Add detailed reasoning information if available
|
|
35
|
+
if step.reasoning is not None:
|
|
36
|
+
step_content.append(Text.from_markup(f"\n[bold]Reasoning:[/bold] {step.reasoning}", style="dim"))
|
|
37
|
+
if step.confidence is not None:
|
|
38
|
+
step_content.append(Text.from_markup(f"\n[bold]Confidence:[/bold] {step.confidence}", style="dim"))
|
|
39
|
+
return create_panel(content=step_content, title=f"Reasoning step {step_idx}", border_style=color)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def escape_markdown_tags(content: str, tags: Set[str]) -> str:
|
|
43
|
+
"""Escape special tags in markdown content."""
|
|
44
|
+
escaped_content = content
|
|
45
|
+
for tag in tags:
|
|
46
|
+
# Escape opening tag
|
|
47
|
+
escaped_content = escaped_content.replace(f"<{tag}>", f"<{tag}>")
|
|
48
|
+
# Escape closing tag
|
|
49
|
+
escaped_content = escaped_content.replace(f"</{tag}>", f"</{tag}>")
|
|
50
|
+
return escaped_content
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def check_if_run_cancelled(run_output: Union[RunOutput, RunOutputEvent, TeamRunOutput, TeamRunOutputEvent]):
|
|
54
|
+
if run_output.is_cancelled:
|
|
55
|
+
raise RunCancelledException()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def format_tool_calls(tool_calls: List[ToolExecution]) -> List[str]:
|
|
59
|
+
"""Format tool calls for display in a readable format.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
tool_calls: List of tool call dictionaries containing tool_name and tool_args
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
List[str]: List of formatted tool call strings
|
|
66
|
+
"""
|
|
67
|
+
formatted_tool_calls = []
|
|
68
|
+
|
|
69
|
+
for tool_call in tool_calls:
|
|
70
|
+
if tool_call.tool_name is not None:
|
|
71
|
+
tool_name = tool_call.tool_name
|
|
72
|
+
args_str = ""
|
|
73
|
+
if tool_call.tool_args is not None and tool_call.tool_args: # Check if args exist and are non-empty
|
|
74
|
+
args_str = ", ".join(f"{k}={v}" for k, v in tool_call.tool_args.items())
|
|
75
|
+
formatted_tool_calls.append(f"{tool_name}({args_str})")
|
|
76
|
+
|
|
77
|
+
return formatted_tool_calls
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def create_paused_run_output_panel(run_output: Union[RunPausedEvent, RunOutput]):
|
|
81
|
+
from rich.text import Text
|
|
82
|
+
|
|
83
|
+
tool_calls_content = Text("Run is paused. ")
|
|
84
|
+
if run_output.tools is not None:
|
|
85
|
+
if any(tc.requires_confirmation for tc in run_output.tools):
|
|
86
|
+
tool_calls_content.append("The following tool calls require confirmation:\n")
|
|
87
|
+
for tool_call in run_output.tools:
|
|
88
|
+
if tool_call.requires_confirmation:
|
|
89
|
+
args_str = ""
|
|
90
|
+
for arg, value in tool_call.tool_args.items() if tool_call.tool_args else {}:
|
|
91
|
+
args_str += f"{arg}={value}, "
|
|
92
|
+
args_str = args_str.rstrip(", ")
|
|
93
|
+
tool_calls_content.append(f"• {tool_call.tool_name}({args_str})\n")
|
|
94
|
+
if any(tc.requires_user_input for tc in run_output.tools):
|
|
95
|
+
tool_calls_content.append("The following tool calls require user input:\n")
|
|
96
|
+
for tool_call in run_output.tools:
|
|
97
|
+
if tool_call.requires_user_input:
|
|
98
|
+
args_str = ""
|
|
99
|
+
for arg, value in tool_call.tool_args.items() if tool_call.tool_args else {}:
|
|
100
|
+
args_str += f"{arg}={value}, "
|
|
101
|
+
args_str = args_str.rstrip(", ")
|
|
102
|
+
tool_calls_content.append(f"• {tool_call.tool_name}({args_str})\n")
|
|
103
|
+
if any(tc.external_execution_required for tc in run_output.tools):
|
|
104
|
+
tool_calls_content.append("The following tool calls require external execution:\n")
|
|
105
|
+
for tool_call in run_output.tools:
|
|
106
|
+
if tool_call.external_execution_required:
|
|
107
|
+
args_str = ""
|
|
108
|
+
for arg, value in tool_call.tool_args.items() if tool_call.tool_args else {}:
|
|
109
|
+
args_str += f"{arg}={value}, "
|
|
110
|
+
args_str = args_str.rstrip(", ")
|
|
111
|
+
tool_calls_content.append(f"• {tool_call.tool_name}({args_str})\n")
|
|
112
|
+
|
|
113
|
+
# Create panel for response
|
|
114
|
+
response_panel = create_panel(
|
|
115
|
+
content=tool_calls_content,
|
|
116
|
+
title="Run Paused",
|
|
117
|
+
border_style="blue",
|
|
118
|
+
)
|
|
119
|
+
return response_panel
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_paused_content(run_output: RunOutput) -> str:
|
|
123
|
+
paused_content = ""
|
|
124
|
+
for tool in run_output.tools or []:
|
|
125
|
+
# Initialize flags for each tool
|
|
126
|
+
confirmation_required = False
|
|
127
|
+
user_input_required = False
|
|
128
|
+
external_execution_required = False
|
|
129
|
+
|
|
130
|
+
if tool.requires_confirmation is not None and tool.requires_confirmation is True and not tool.confirmed:
|
|
131
|
+
confirmation_required = True
|
|
132
|
+
if tool.requires_user_input is not None and tool.requires_user_input is True:
|
|
133
|
+
user_input_required = True
|
|
134
|
+
if tool.external_execution_required is not None and tool.external_execution_required is True:
|
|
135
|
+
external_execution_required = True
|
|
136
|
+
|
|
137
|
+
if confirmation_required and user_input_required and external_execution_required:
|
|
138
|
+
paused_content = "I have tools to execute, but I need confirmation, user input, or external execution."
|
|
139
|
+
elif confirmation_required and user_input_required:
|
|
140
|
+
paused_content = "I have tools to execute, but I need confirmation or user input."
|
|
141
|
+
elif confirmation_required and external_execution_required:
|
|
142
|
+
paused_content = "I have tools to execute, but I need confirmation or external execution."
|
|
143
|
+
elif user_input_required and external_execution_required:
|
|
144
|
+
paused_content = "I have tools to execute, but I need user input or external execution."
|
|
145
|
+
elif confirmation_required:
|
|
146
|
+
paused_content = "I have tools to execute, but I need confirmation."
|
|
147
|
+
elif user_input_required:
|
|
148
|
+
paused_content = "I have tools to execute, but I need user input."
|
|
149
|
+
elif external_execution_required:
|
|
150
|
+
paused_content = "I have tools to execute, but it needs external execution."
|
|
151
|
+
return paused_content
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def generator_wrapper(
|
|
155
|
+
event: Union[RunOutputEvent, TeamRunOutputEvent],
|
|
156
|
+
) -> Iterator[Union[RunOutputEvent, TeamRunOutputEvent]]:
|
|
157
|
+
yield event
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
async def async_generator_wrapper(
|
|
161
|
+
event: Union[RunOutputEvent, TeamRunOutputEvent],
|
|
162
|
+
) -> AsyncIterator[Union[RunOutputEvent, TeamRunOutputEvent]]:
|
|
163
|
+
yield event
|
agno/utils/serialize.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""JSON serialization utilities for handling datetime and enum objects."""
|
|
2
|
+
|
|
3
|
+
from datetime import date, datetime, time
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def json_serializer(obj: Any) -> Any:
|
|
9
|
+
"""Custom JSON serializer for objects not serializable by default json module.
|
|
10
|
+
|
|
11
|
+
Handles:
|
|
12
|
+
- datetime, date, time objects -> ISO format strings
|
|
13
|
+
- Enum objects -> their values (or names if values are not JSON-serializable)
|
|
14
|
+
- All other objects -> string representation
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
obj: Object to serialize
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
JSON-serializable representation of the object
|
|
21
|
+
"""
|
|
22
|
+
# Datetime like
|
|
23
|
+
if isinstance(obj, (datetime, date, time)):
|
|
24
|
+
return obj.isoformat()
|
|
25
|
+
|
|
26
|
+
# Enums
|
|
27
|
+
if isinstance(obj, Enum):
|
|
28
|
+
v = obj.value
|
|
29
|
+
return v if isinstance(v, (str, int, float, bool, type(None))) else obj.name
|
|
30
|
+
|
|
31
|
+
# Fallback to string
|
|
32
|
+
return str(obj)
|
agno/utils/shell.py
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
from typing import List
|
|
2
2
|
|
|
3
|
-
from agno.utils.log import logger
|
|
3
|
+
from agno.utils.log import log_debug, log_info, logger
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def run_shell_command(args: List[str], tail: int = 100) -> str:
|
|
7
|
-
|
|
7
|
+
log_info(f"Running shell command: {args}")
|
|
8
8
|
|
|
9
9
|
import subprocess
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
12
|
result = subprocess.run(args, capture_output=True, text=True)
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
log_debug(f"Result: {result}")
|
|
14
|
+
log_debug(f"Return code: {result.returncode}")
|
|
15
15
|
if result.returncode != 0:
|
|
16
16
|
return f"Error: {result.stderr}"
|
|
17
17
|
|