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/tools/knowledge.py
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from textwrap import dedent
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
from agno.knowledge.document import Document
|
|
6
|
+
from agno.knowledge.knowledge import Knowledge
|
|
7
|
+
from agno.tools import Toolkit
|
|
8
|
+
from agno.utils.log import log_debug, log_error
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class KnowledgeTools(Toolkit):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
knowledge: Knowledge,
|
|
15
|
+
enable_think: bool = True,
|
|
16
|
+
enable_search: bool = True,
|
|
17
|
+
enable_analyze: bool = True,
|
|
18
|
+
instructions: Optional[str] = None,
|
|
19
|
+
add_instructions: bool = True,
|
|
20
|
+
add_few_shot: bool = False,
|
|
21
|
+
few_shot_examples: Optional[str] = None,
|
|
22
|
+
all: bool = False,
|
|
23
|
+
**kwargs,
|
|
24
|
+
):
|
|
25
|
+
if knowledge is None:
|
|
26
|
+
raise ValueError("knowledge must be provided when using KnowledgeTools")
|
|
27
|
+
|
|
28
|
+
# Add instructions for using this toolkit
|
|
29
|
+
if instructions is None:
|
|
30
|
+
self.instructions = self.DEFAULT_INSTRUCTIONS
|
|
31
|
+
if add_few_shot:
|
|
32
|
+
if few_shot_examples is not None:
|
|
33
|
+
self.instructions += "\n" + few_shot_examples
|
|
34
|
+
else:
|
|
35
|
+
self.instructions += "\n" + self.FEW_SHOT_EXAMPLES
|
|
36
|
+
else:
|
|
37
|
+
self.instructions = instructions
|
|
38
|
+
|
|
39
|
+
# The knowledge to search
|
|
40
|
+
self.knowledge: Knowledge = knowledge
|
|
41
|
+
|
|
42
|
+
tools: List[Any] = []
|
|
43
|
+
if enable_think or all:
|
|
44
|
+
tools.append(self.think)
|
|
45
|
+
if enable_search or all:
|
|
46
|
+
tools.append(self.search_knowledge)
|
|
47
|
+
if enable_analyze or all:
|
|
48
|
+
tools.append(self.analyze)
|
|
49
|
+
|
|
50
|
+
super().__init__(
|
|
51
|
+
name="knowledge_tools",
|
|
52
|
+
tools=tools,
|
|
53
|
+
instructions=self.instructions,
|
|
54
|
+
add_instructions=add_instructions,
|
|
55
|
+
**kwargs,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def think(self, session_state: Dict[str, Any], thought: str) -> str:
|
|
59
|
+
"""Use this tool as a scratchpad to reason about the question, refine your approach, brainstorm search terms, or revise your plan.
|
|
60
|
+
|
|
61
|
+
Call `Think` whenever you need to figure out what to do next, analyze the user's question, or plan your approach.
|
|
62
|
+
You should use this tool as frequently as needed.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
thought: Your thought process and reasoning.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
str: The full log of reasoning and the new thought.
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
log_debug(f"Thought: {thought}")
|
|
72
|
+
|
|
73
|
+
# Add the thought to the Agent state
|
|
74
|
+
if session_state is None:
|
|
75
|
+
session_state = {}
|
|
76
|
+
if "thoughts" not in session_state:
|
|
77
|
+
session_state["thoughts"] = []
|
|
78
|
+
session_state["thoughts"].append(thought)
|
|
79
|
+
|
|
80
|
+
# Return the full log of thoughts and the new thought
|
|
81
|
+
thoughts = "\n".join([f"- {t}" for t in session_state["thoughts"]])
|
|
82
|
+
formatted_thoughts = dedent(
|
|
83
|
+
f"""Thoughts:
|
|
84
|
+
{thoughts}
|
|
85
|
+
"""
|
|
86
|
+
).strip()
|
|
87
|
+
return formatted_thoughts
|
|
88
|
+
except Exception as e:
|
|
89
|
+
log_error(f"Error recording thought: {e}")
|
|
90
|
+
return f"Error recording thought: {e}"
|
|
91
|
+
|
|
92
|
+
def search_knowledge(self, session_state: Dict[str, Any], query: str) -> str:
|
|
93
|
+
"""Use this tool to search the knowledge base for relevant information.
|
|
94
|
+
After thinking through the question, use this tool as many times as needed to search for relevant information.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
query: The query to search the knowledge base for.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
str: A string containing the response from the knowledge base.
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
log_debug(f"Searching knowledge base: {query}")
|
|
104
|
+
|
|
105
|
+
# Get the relevant documents from the knowledge base
|
|
106
|
+
relevant_docs: List[Document] = self.knowledge.search(query=query)
|
|
107
|
+
if len(relevant_docs) == 0:
|
|
108
|
+
return "No documents found"
|
|
109
|
+
return json.dumps([doc.to_dict() for doc in relevant_docs])
|
|
110
|
+
except Exception as e:
|
|
111
|
+
log_error(f"Error searching knowledge base: {e}")
|
|
112
|
+
return f"Error searching knowledge base: {e}"
|
|
113
|
+
|
|
114
|
+
def analyze(self, session_state: Dict[str, Any], analysis: str) -> str:
|
|
115
|
+
"""Use this tool to evaluate whether the returned documents are correct and sufficient.
|
|
116
|
+
If not, go back to "Think" or "Search" with refined queries.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
analysis: A thought to think about and log.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
str: The full log of thoughts and the new thought.
|
|
123
|
+
"""
|
|
124
|
+
try:
|
|
125
|
+
log_debug(f"Analysis: {analysis}")
|
|
126
|
+
|
|
127
|
+
# Add the thought to the Agent state
|
|
128
|
+
if session_state is None:
|
|
129
|
+
session_state = {}
|
|
130
|
+
if "analysis" not in session_state:
|
|
131
|
+
session_state["analysis"] = []
|
|
132
|
+
session_state["analysis"].append(analysis)
|
|
133
|
+
|
|
134
|
+
# Return the full log of thoughts and the new thought
|
|
135
|
+
analysis = "\n".join([f"- {a}" for a in session_state["analysis"]])
|
|
136
|
+
formatted_analysis = dedent(
|
|
137
|
+
f"""Analysis:
|
|
138
|
+
{analysis}
|
|
139
|
+
"""
|
|
140
|
+
).strip()
|
|
141
|
+
return formatted_analysis
|
|
142
|
+
except Exception as e:
|
|
143
|
+
log_error(f"Error recording analysis: {e}")
|
|
144
|
+
return f"Error recording analysis: {e}"
|
|
145
|
+
|
|
146
|
+
DEFAULT_INSTRUCTIONS = dedent("""\
|
|
147
|
+
You have access to the Think, Search, and Analyze tools that will help you search your knowledge for relevant information. Use these tools as frequently as needed to find the most relevant information.
|
|
148
|
+
|
|
149
|
+
## How to use the Think, Search, and Analyze tools:
|
|
150
|
+
1. **Think**
|
|
151
|
+
- Purpose: A scratchpad for planning, brainstorming keywords, and refining your approach. You never reveal your "Think" content to the user.
|
|
152
|
+
- Usage: Call `think` whenever you need to figure out what to do next, analyze your approach, or decide new search terms before (or after) you look up documents.
|
|
153
|
+
|
|
154
|
+
2. **Search**
|
|
155
|
+
- Purpose: Executes a query against the knowledge base.
|
|
156
|
+
- Usage: Call `search` with a clear query string whenever you want to retrieve documents or data. You can and should call this tool multiple times in one conversation.
|
|
157
|
+
- For complex topics, use multiple focused searches rather than one broad search
|
|
158
|
+
- Try different phrasing and keywords if initial searches don't yield useful results
|
|
159
|
+
- Use quotes for exact phrases and OR for alternative terms (e.g., "protein synthesis" OR "protein formation")
|
|
160
|
+
|
|
161
|
+
3. **Analyze**
|
|
162
|
+
- Purpose: Evaluate whether the returned documents are correct and sufficient. If not, go back to "Think" or "Search" with refined queries.
|
|
163
|
+
- Usage: Call `analyze` after getting search results to verify the quality and correctness of that information. Consider:
|
|
164
|
+
- Relevance: Do the documents directly address the user's question?
|
|
165
|
+
- Completeness: Is there enough information to provide a thorough answer?
|
|
166
|
+
- Reliability: Are the sources credible and up-to-date?
|
|
167
|
+
- Consistency: Do the documents agree or contradict each other?
|
|
168
|
+
|
|
169
|
+
**Important Guidelines**:
|
|
170
|
+
- Do not include your internal chain-of-thought in direct user responses.
|
|
171
|
+
- Use "Think" to reason internally. These notes are never exposed to the user.
|
|
172
|
+
- Iterate through the cycle (Think → Search → Analyze) as many times as needed until you have a final answer.
|
|
173
|
+
- When you do provide a final answer to the user, be clear, concise, and accurate.
|
|
174
|
+
- If search results are sparse or contradictory, acknowledge limitations in your response.
|
|
175
|
+
- Synthesize information from multiple sources rather than relying on a single document.\
|
|
176
|
+
""")
|
|
177
|
+
|
|
178
|
+
FEW_SHOT_EXAMPLES = dedent("""\
|
|
179
|
+
You can refer to the examples below as guidance for how to use each tool.
|
|
180
|
+
### Examples
|
|
181
|
+
|
|
182
|
+
#### Example 1: Multiple Searches and Analysis
|
|
183
|
+
|
|
184
|
+
User: What are the recommended dietary guidelines for someone with mild hypertension?
|
|
185
|
+
Think: The user is asking about dietary guidelines for mild hypertension. I'll start broad, then refine if needed.
|
|
186
|
+
Search: "dietary guidelines for mild hypertension", "salt intake recommendations for mild hypertension"
|
|
187
|
+
Analyze: I got one document referencing the DASH diet, but it's quite brief. I might need more info about salt intake recommendations specifically.
|
|
188
|
+
Think: Let me refine my search to see if there are official guidelines from recognized health organizations.
|
|
189
|
+
Search: "WHO or American Heart Association guidelines for hypertension", "fruits and vegetables for mild hypertension"
|
|
190
|
+
Analyze: The new documents mention daily sodium limits, recommended fruit/vegetable intake, and more. This seems thorough. I'm ready to formulate the answer.
|
|
191
|
+
|
|
192
|
+
Final Answer: For mild hypertension, the guidelines typically recommend following the DASH diet, which emphasizes ...
|
|
193
|
+
|
|
194
|
+
#### Example 2: Invalid or Insufficient Search Results
|
|
195
|
+
|
|
196
|
+
User: Do you have any documentation on the 'XYZ Project' from last year?
|
|
197
|
+
Think: I'll try searching for 'XYZ Project last year' but if that fails, I'll look for internal code names or older references.
|
|
198
|
+
Search: "XYZ Project last year"
|
|
199
|
+
Analyze: No relevant documents. Let me refine my search to check for 'XYZ Project' in different date ranges or alternate titles.
|
|
200
|
+
Think: Possibly it's under 'XYZ Initiative' or 'XYZ Rollout.' Let's do a second search.
|
|
201
|
+
Search: "XYZ Initiative OR 'XYZ Rollout' from last year"
|
|
202
|
+
Analyze: Found a relevant archive for 'XYZ Initiative'. Looks correct and references last year's timeline. I'll proceed with that info.
|
|
203
|
+
|
|
204
|
+
Final Answer: Yes, we have some archived documentation under the name 'XYZ Initiative.' It includes ...
|
|
205
|
+
|
|
206
|
+
#### Example 3: Synthesizing Complex Information
|
|
207
|
+
|
|
208
|
+
User: How do quantum computers differ from classical computers in terms of performance?
|
|
209
|
+
Think: This is a technical question requiring clear explanations of quantum vs. classical computing performance characteristics.
|
|
210
|
+
Search: "quantum computing performance vs classical computing"
|
|
211
|
+
Analyze: Found general information but need more specifics on actual performance metrics and use cases.
|
|
212
|
+
Think: Let me search for specific quantum advantages and limitations.
|
|
213
|
+
Search: "quantum supremacy examples", "quantum computing limitations"
|
|
214
|
+
Search: "quantum computing speedup for specific algorithms"
|
|
215
|
+
Analyze: Now I have concrete examples of quantum speedup for certain algorithms, limitations for others, and real-world benchmarks.
|
|
216
|
+
|
|
217
|
+
Final Answer: Quantum computers differ from classical computers in three key ways: [synthesized explanation with specific examples]...\
|
|
218
|
+
""")
|
agno/tools/linear.py
CHANGED
|
@@ -1,47 +1,38 @@
|
|
|
1
1
|
from os import getenv
|
|
2
|
-
from typing import Optional
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
3
|
|
|
4
4
|
import requests
|
|
5
5
|
|
|
6
6
|
from agno.tools import Toolkit
|
|
7
|
-
from agno.utils.log import logger
|
|
7
|
+
from agno.utils.log import log_info, logger
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class LinearTools(Toolkit):
|
|
11
11
|
def __init__(
|
|
12
12
|
self,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
create_issue: bool = True,
|
|
16
|
-
update_issue: bool = True,
|
|
17
|
-
get_user_assigned_issues: bool = True,
|
|
18
|
-
get_workflow_issues: bool = True,
|
|
19
|
-
get_high_priority_issues: bool = True,
|
|
13
|
+
api_key: Optional[str] = None,
|
|
14
|
+
**kwargs,
|
|
20
15
|
):
|
|
21
|
-
|
|
22
|
-
self.api_token = getenv("LINEAR_API_KEY")
|
|
16
|
+
self.api_key = api_key or getenv("LINEAR_API_KEY")
|
|
23
17
|
|
|
24
|
-
if not self.
|
|
25
|
-
|
|
26
|
-
logger.error(api_error_message)
|
|
18
|
+
if not self.api_key:
|
|
19
|
+
raise ValueError("Linear API key is required")
|
|
27
20
|
|
|
28
21
|
self.endpoint = "https://api.linear.app/graphql"
|
|
29
|
-
self.headers = {"Authorization": f"{self.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.
|
|
33
|
-
|
|
34
|
-
self.
|
|
35
|
-
|
|
36
|
-
self.
|
|
37
|
-
|
|
38
|
-
self.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if get_high_priority_issues:
|
|
44
|
-
self.register(self.get_high_priority_issues)
|
|
22
|
+
self.headers = {"Authorization": f"{self.api_key}"}
|
|
23
|
+
|
|
24
|
+
tools: List[Any] = [
|
|
25
|
+
self.get_user_details,
|
|
26
|
+
self.get_teams_details,
|
|
27
|
+
self.get_issue_details,
|
|
28
|
+
self.create_issue,
|
|
29
|
+
self.update_issue,
|
|
30
|
+
self.get_user_assigned_issues,
|
|
31
|
+
self.get_workflow_issues,
|
|
32
|
+
self.get_high_priority_issues,
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
super().__init__(name="linear_tools", tools=tools, **kwargs)
|
|
45
36
|
|
|
46
37
|
def _execute_query(self, query, variables=None):
|
|
47
38
|
"""Helper method to execute GraphQL queries with optional variables."""
|
|
@@ -56,7 +47,7 @@ class LinearTools(Toolkit):
|
|
|
56
47
|
logger.error(f"GraphQL Error: {data['errors']}")
|
|
57
48
|
raise Exception(f"GraphQL Error: {data['errors']}")
|
|
58
49
|
|
|
59
|
-
|
|
50
|
+
log_info("GraphQL query executed successfully.")
|
|
60
51
|
return data.get("data")
|
|
61
52
|
|
|
62
53
|
except requests.exceptions.RequestException as e:
|
|
@@ -94,7 +85,7 @@ class LinearTools(Toolkit):
|
|
|
94
85
|
|
|
95
86
|
if response.get("viewer"):
|
|
96
87
|
user = response["viewer"]
|
|
97
|
-
|
|
88
|
+
log_info(
|
|
98
89
|
f"Retrieved authenticated user details with name: {user['name']}, ID: {user['id']}, Email: {user['email']}"
|
|
99
90
|
)
|
|
100
91
|
return str(user)
|
|
@@ -106,6 +97,44 @@ class LinearTools(Toolkit):
|
|
|
106
97
|
logger.error(f"Error fetching authenticated user details: {e}")
|
|
107
98
|
raise
|
|
108
99
|
|
|
100
|
+
def get_teams_details(self) -> Optional[str]:
|
|
101
|
+
"""
|
|
102
|
+
Fetch the list of authenticated teams.
|
|
103
|
+
It will return the unique ID and team name for each team, from the viewer object in the GraphQL response.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
str or None: A dictionary containing team details like team name, id.
|
|
107
|
+
|
|
108
|
+
Raises:
|
|
109
|
+
Exception: If an error occurs during the query execution or data retrieval.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
query = """
|
|
113
|
+
query Teams {
|
|
114
|
+
teams {
|
|
115
|
+
nodes {
|
|
116
|
+
id
|
|
117
|
+
name
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
response = self._execute_query(query)
|
|
125
|
+
|
|
126
|
+
if response.get("teams"):
|
|
127
|
+
teams = response["teams"]["nodes"]
|
|
128
|
+
log_info(f"Retrieved authenticated team details: {teams}")
|
|
129
|
+
return str(teams)
|
|
130
|
+
else:
|
|
131
|
+
logger.error("Failed to retrieve the current user details")
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.error(f"Error fetching authenticated user details: {e}")
|
|
136
|
+
raise
|
|
137
|
+
|
|
109
138
|
def get_issue_details(self, issue_id: str) -> Optional[str]:
|
|
110
139
|
"""
|
|
111
140
|
Retrieve details of a specific issue by issue ID.
|
|
@@ -136,7 +165,7 @@ class LinearTools(Toolkit):
|
|
|
136
165
|
|
|
137
166
|
if response.get("issue"):
|
|
138
167
|
issue = response["issue"]
|
|
139
|
-
|
|
168
|
+
log_info(f"Issue '{issue['title']}' retrieved successfully with ID {issue['id']}.")
|
|
140
169
|
return str(issue)
|
|
141
170
|
else:
|
|
142
171
|
logger.error(f"Failed to retrieve issue with ID {issue_id}.")
|
|
@@ -147,7 +176,12 @@ class LinearTools(Toolkit):
|
|
|
147
176
|
raise
|
|
148
177
|
|
|
149
178
|
def create_issue(
|
|
150
|
-
self,
|
|
179
|
+
self,
|
|
180
|
+
title: str,
|
|
181
|
+
description: str,
|
|
182
|
+
team_id: str,
|
|
183
|
+
project_id: Optional[str] = None,
|
|
184
|
+
assignee_id: Optional[str] = None,
|
|
151
185
|
) -> Optional[str]:
|
|
152
186
|
"""
|
|
153
187
|
Create a new issue within a specific project and team.
|
|
@@ -156,6 +190,8 @@ class LinearTools(Toolkit):
|
|
|
156
190
|
title (str): The title of the new issue.
|
|
157
191
|
description (str): The description of the new issue.
|
|
158
192
|
team_id (str): The unique identifier of the team in which to create the issue.
|
|
193
|
+
project_id (Optional[str]): The ID of the project (optional).
|
|
194
|
+
assignee_id (Optional[str]): The ID of the assignee (optional).
|
|
159
195
|
|
|
160
196
|
Returns:
|
|
161
197
|
str or None: A string containing the created issue's details like issue id and issue title.
|
|
@@ -166,7 +202,7 @@ class LinearTools(Toolkit):
|
|
|
166
202
|
"""
|
|
167
203
|
|
|
168
204
|
query = """
|
|
169
|
-
mutation IssueCreate ($title: String!, $description: String!, $teamId: String!, $projectId: String
|
|
205
|
+
mutation IssueCreate ($title: String!, $description: String!, $teamId: String!, $projectId: String, $assigneeId: String){
|
|
170
206
|
issueCreate(
|
|
171
207
|
input: { title: $title, description: $description, teamId: $teamId, projectId: $projectId, assigneeId: $assigneeId}
|
|
172
208
|
) {
|
|
@@ -184,16 +220,19 @@ class LinearTools(Toolkit):
|
|
|
184
220
|
"title": title,
|
|
185
221
|
"description": description,
|
|
186
222
|
"teamId": team_id,
|
|
187
|
-
"projectId": project_id,
|
|
188
|
-
"assigneeId": assignee_id,
|
|
189
223
|
}
|
|
224
|
+
if project_id is not None:
|
|
225
|
+
variables["projectId"] = project_id
|
|
226
|
+
if assignee_id is not None:
|
|
227
|
+
variables["assigneeId"] = assignee_id
|
|
228
|
+
|
|
190
229
|
try:
|
|
191
230
|
response = self._execute_query(query, variables)
|
|
192
|
-
|
|
231
|
+
log_info(f"Response: {response}")
|
|
193
232
|
|
|
194
233
|
if response["issueCreate"]["success"]:
|
|
195
234
|
issue = response["issueCreate"]["issue"]
|
|
196
|
-
|
|
235
|
+
log_info(f"Issue '{issue['title']}' created successfully with ID {issue['id']}")
|
|
197
236
|
return str(issue)
|
|
198
237
|
else:
|
|
199
238
|
logger.error("Issue creation failed.")
|
|
@@ -244,7 +283,7 @@ class LinearTools(Toolkit):
|
|
|
244
283
|
|
|
245
284
|
if response["issueUpdate"]["success"]:
|
|
246
285
|
issue = response["issueUpdate"]["issue"]
|
|
247
|
-
|
|
286
|
+
log_info(f"Issue ID {issue_id} updated successfully.")
|
|
248
287
|
return str(issue)
|
|
249
288
|
else:
|
|
250
289
|
logger.error(f"Failed to update issue ID {issue_id}. Success flag was false.")
|
|
@@ -292,7 +331,7 @@ class LinearTools(Toolkit):
|
|
|
292
331
|
if response.get("user"):
|
|
293
332
|
user = response["user"]
|
|
294
333
|
issues = user["assignedIssues"]["nodes"]
|
|
295
|
-
|
|
334
|
+
log_info(f"Retrieved {len(issues)} issues assigned to user '{user['name']}' (ID: {user['id']}).")
|
|
296
335
|
return str(issues)
|
|
297
336
|
else:
|
|
298
337
|
logger.error("Failed to retrieve user or issues.")
|
|
@@ -335,7 +374,7 @@ class LinearTools(Toolkit):
|
|
|
335
374
|
|
|
336
375
|
if response.get("workflowState"):
|
|
337
376
|
issues = response["workflowState"]["issues"]["nodes"]
|
|
338
|
-
|
|
377
|
+
log_info(f"Retrieved {len(issues)} issues in workflow state ID {workflow_id}.")
|
|
339
378
|
return str(issues)
|
|
340
379
|
else:
|
|
341
380
|
logger.error("Failed to retrieve issues for the specified workflow state.")
|
|
@@ -376,7 +415,7 @@ class LinearTools(Toolkit):
|
|
|
376
415
|
|
|
377
416
|
if response.get("issues"):
|
|
378
417
|
high_priority_issues = response["issues"]["nodes"]
|
|
379
|
-
|
|
418
|
+
log_info(f"Retrieved {len(high_priority_issues)} high-priority issues.")
|
|
380
419
|
return str(high_priority_issues)
|
|
381
420
|
else:
|
|
382
421
|
logger.error("Failed to retrieve high-priority issues.")
|
agno/tools/linkup.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from typing import Any, List, Literal, Optional
|
|
3
|
+
|
|
4
|
+
from agno.tools import Toolkit
|
|
5
|
+
from agno.utils.log import logger
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from linkup import LinkupClient
|
|
9
|
+
except ImportError:
|
|
10
|
+
raise ImportError("`linkup-sdk` not installed. Please install using `pip install linkup-sdk`")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LinkupTools(Toolkit):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
api_key: Optional[str] = None,
|
|
17
|
+
depth: Literal["standard", "deep"] = "standard",
|
|
18
|
+
output_type: Literal["sourcedAnswer", "searchResults"] = "searchResults",
|
|
19
|
+
enable_web_search_with_linkup: bool = True,
|
|
20
|
+
all: bool = False,
|
|
21
|
+
**kwargs,
|
|
22
|
+
):
|
|
23
|
+
self.api_key = api_key or getenv("LINKUP_API_KEY")
|
|
24
|
+
if not self.api_key:
|
|
25
|
+
logger.error("LINKUP_API_KEY not set. Please set the LINKUP_API_KEY environment variable.")
|
|
26
|
+
|
|
27
|
+
self.linkup = LinkupClient(api_key=api_key)
|
|
28
|
+
self.depth = depth
|
|
29
|
+
self.output_type = output_type
|
|
30
|
+
|
|
31
|
+
tools: List[Any] = []
|
|
32
|
+
if all or enable_web_search_with_linkup:
|
|
33
|
+
tools.append(self.web_search_with_linkup)
|
|
34
|
+
|
|
35
|
+
super().__init__(name="linkup_tools", tools=tools, **kwargs)
|
|
36
|
+
|
|
37
|
+
def web_search_with_linkup(self, query: str, depth: Optional[str] = None, output_type: Optional[str] = None) -> str:
|
|
38
|
+
"""
|
|
39
|
+
Use this function to search the web for a given query.
|
|
40
|
+
This function uses the Linkup API to provide realtime online information about the query.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
query (str): Query to search for.
|
|
44
|
+
depth (str): (deep|standard) Depth of the search. Defaults to 'standard'.
|
|
45
|
+
output_type (str): (sourcedAnswer|searchResults) Type of output. Defaults to 'searchResults'.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
str: string of results related to the query.
|
|
49
|
+
"""
|
|
50
|
+
try:
|
|
51
|
+
response = self.linkup.search(
|
|
52
|
+
query=query,
|
|
53
|
+
depth=depth or self.depth, # type: ignore
|
|
54
|
+
output_type=output_type or self.output_type, # type: ignore
|
|
55
|
+
)
|
|
56
|
+
return response
|
|
57
|
+
except Exception as e:
|
|
58
|
+
return f"Error: {str(e)}"
|
agno/tools/local_file_system.py
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import os
|
|
2
1
|
from pathlib import Path
|
|
3
2
|
from typing import Optional
|
|
4
3
|
from uuid import uuid4
|
|
5
4
|
|
|
6
5
|
from agno.tools import Toolkit
|
|
7
|
-
from agno.utils.log import logger
|
|
6
|
+
from agno.utils.log import log_debug, logger
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
class LocalFileSystemTools(Toolkit):
|
|
@@ -12,6 +11,9 @@ class LocalFileSystemTools(Toolkit):
|
|
|
12
11
|
self,
|
|
13
12
|
target_directory: Optional[str] = None,
|
|
14
13
|
default_extension: str = "txt",
|
|
14
|
+
enable_write_file: bool = True,
|
|
15
|
+
all: bool = False,
|
|
16
|
+
**kwargs,
|
|
15
17
|
):
|
|
16
18
|
"""
|
|
17
19
|
Initialize the WriteToLocal toolkit.
|
|
@@ -19,15 +21,18 @@ class LocalFileSystemTools(Toolkit):
|
|
|
19
21
|
target_directory (Optional[str]): Default directory to write files to. Creates if doesn't exist.
|
|
20
22
|
default_extension (str): Default file extension to use if none specified.
|
|
21
23
|
"""
|
|
22
|
-
super().__init__(name="write_to_local")
|
|
23
24
|
|
|
24
|
-
self.target_directory = target_directory or
|
|
25
|
+
self.target_directory = target_directory or str(Path.cwd())
|
|
25
26
|
self.default_extension = default_extension.lstrip(".")
|
|
26
27
|
|
|
27
28
|
target_path = Path(self.target_directory)
|
|
28
29
|
target_path.mkdir(parents=True, exist_ok=True)
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
tools = []
|
|
32
|
+
if all or enable_write_file:
|
|
33
|
+
tools.append(self.write_file)
|
|
34
|
+
|
|
35
|
+
super().__init__(name="write_to_local", tools=tools, **kwargs)
|
|
31
36
|
|
|
32
37
|
def write_file(
|
|
33
38
|
self,
|
|
@@ -50,8 +55,11 @@ class LocalFileSystemTools(Toolkit):
|
|
|
50
55
|
filename = filename or str(uuid4())
|
|
51
56
|
directory = directory or self.target_directory
|
|
52
57
|
if filename and "." in filename:
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
path_obj = Path(filename)
|
|
59
|
+
filename = path_obj.stem
|
|
60
|
+
extension = extension or path_obj.suffix.lstrip(".")
|
|
61
|
+
|
|
62
|
+
log_debug(f"Writing file to local system: {filename}")
|
|
55
63
|
|
|
56
64
|
extension = (extension or self.default_extension).lstrip(".")
|
|
57
65
|
|