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/toolkit.py
CHANGED
|
@@ -1,43 +1,168 @@
|
|
|
1
1
|
from collections import OrderedDict
|
|
2
|
-
from typing import Any, Callable, Dict
|
|
2
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
3
3
|
|
|
4
4
|
from agno.tools.function import Function
|
|
5
|
-
from agno.utils.log import logger
|
|
5
|
+
from agno.utils.log import log_debug, log_warning, logger
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Toolkit:
|
|
9
|
-
|
|
9
|
+
# Set to True for toolkits that require connection management (e.g., database connections)
|
|
10
|
+
# When True, the Agent will automatically call connect() before using tools and close() after
|
|
11
|
+
_requires_connect: bool = False
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
name: str = "toolkit",
|
|
16
|
+
tools: List[Callable] = [],
|
|
17
|
+
instructions: Optional[str] = None,
|
|
18
|
+
add_instructions: bool = False,
|
|
19
|
+
include_tools: Optional[list[str]] = None,
|
|
20
|
+
exclude_tools: Optional[list[str]] = None,
|
|
21
|
+
requires_confirmation_tools: Optional[list[str]] = None,
|
|
22
|
+
external_execution_required_tools: Optional[list[str]] = None,
|
|
23
|
+
stop_after_tool_call_tools: Optional[List[str]] = None,
|
|
24
|
+
show_result_tools: Optional[List[str]] = None,
|
|
25
|
+
cache_results: bool = False,
|
|
26
|
+
cache_ttl: int = 3600,
|
|
27
|
+
cache_dir: Optional[str] = None,
|
|
28
|
+
auto_register: bool = True,
|
|
29
|
+
):
|
|
10
30
|
"""Initialize a new Toolkit.
|
|
11
31
|
|
|
12
32
|
Args:
|
|
13
33
|
name: A descriptive name for the toolkit
|
|
34
|
+
tools: List of tools to include in the toolkit
|
|
35
|
+
instructions: Instructions for the toolkit
|
|
36
|
+
add_instructions: Whether to add instructions to the toolkit
|
|
37
|
+
include_tools: List of tool names to include in the toolkit
|
|
38
|
+
exclude_tools: List of tool names to exclude from the toolkit
|
|
39
|
+
requires_confirmation_tools: List of tool names that require user confirmation
|
|
40
|
+
external_execution_required_tools: List of tool names that will be executed outside of the agent loop
|
|
41
|
+
cache_results (bool): Enable in-memory caching of function results.
|
|
42
|
+
cache_ttl (int): Time-to-live for cached results in seconds.
|
|
43
|
+
cache_dir (Optional[str]): Directory to store cache files. Defaults to system temp dir.
|
|
44
|
+
auto_register (bool): Whether to automatically register all methods in the class.
|
|
45
|
+
stop_after_tool_call_tools (Optional[List[str]]): List of function names that should stop the agent after execution.
|
|
46
|
+
show_result_tools (Optional[List[str]]): List of function names whose results should be shown.
|
|
14
47
|
"""
|
|
15
48
|
self.name: str = name
|
|
49
|
+
self.tools: List[Callable] = tools
|
|
16
50
|
self.functions: Dict[str, Function] = OrderedDict()
|
|
51
|
+
self.instructions: Optional[str] = instructions
|
|
52
|
+
self.add_instructions: bool = add_instructions
|
|
53
|
+
|
|
54
|
+
self.requires_confirmation_tools: list[str] = requires_confirmation_tools or []
|
|
55
|
+
self.external_execution_required_tools: list[str] = external_execution_required_tools or []
|
|
56
|
+
|
|
57
|
+
self.stop_after_tool_call_tools: list[str] = stop_after_tool_call_tools or []
|
|
58
|
+
self.show_result_tools: list[str] = show_result_tools or []
|
|
59
|
+
|
|
60
|
+
self._check_tools_filters(
|
|
61
|
+
available_tools=[tool.__name__ for tool in tools], include_tools=include_tools, exclude_tools=exclude_tools
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
self.include_tools = include_tools
|
|
65
|
+
self.exclude_tools = exclude_tools
|
|
66
|
+
|
|
67
|
+
self.cache_results: bool = cache_results
|
|
68
|
+
self.cache_ttl: int = cache_ttl
|
|
69
|
+
self.cache_dir: Optional[str] = cache_dir
|
|
70
|
+
|
|
71
|
+
# Automatically register all methods if auto_register is True
|
|
72
|
+
if auto_register and self.tools:
|
|
73
|
+
self._register_tools()
|
|
74
|
+
|
|
75
|
+
def _check_tools_filters(
|
|
76
|
+
self,
|
|
77
|
+
available_tools: List[str],
|
|
78
|
+
include_tools: Optional[list[str]] = None,
|
|
79
|
+
exclude_tools: Optional[list[str]] = None,
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Check if `include_tools` and `exclude_tools` are valid"""
|
|
82
|
+
if include_tools or exclude_tools:
|
|
83
|
+
if include_tools:
|
|
84
|
+
missing_includes = set(include_tools) - set(available_tools)
|
|
85
|
+
if missing_includes:
|
|
86
|
+
raise ValueError(f"Included tool(s) not present in the toolkit: {', '.join(missing_includes)}")
|
|
87
|
+
|
|
88
|
+
if exclude_tools:
|
|
89
|
+
missing_excludes = set(exclude_tools) - set(available_tools)
|
|
90
|
+
if missing_excludes:
|
|
91
|
+
raise ValueError(f"Excluded tool(s) not present in the toolkit: {', '.join(missing_excludes)}")
|
|
92
|
+
|
|
93
|
+
if self.requires_confirmation_tools:
|
|
94
|
+
missing_requires_confirmation = set(self.requires_confirmation_tools) - set(available_tools)
|
|
95
|
+
if missing_requires_confirmation:
|
|
96
|
+
log_warning(
|
|
97
|
+
f"Requires confirmation tool(s) not present in the toolkit: {', '.join(missing_requires_confirmation)}"
|
|
98
|
+
)
|
|
17
99
|
|
|
18
|
-
|
|
100
|
+
if self.external_execution_required_tools:
|
|
101
|
+
missing_external_execution_required = set(self.external_execution_required_tools) - set(available_tools)
|
|
102
|
+
if missing_external_execution_required:
|
|
103
|
+
log_warning(
|
|
104
|
+
f"External execution required tool(s) not present in the toolkit: {', '.join(missing_external_execution_required)}"
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def _register_tools(self) -> None:
|
|
108
|
+
"""Register all tools."""
|
|
109
|
+
for tool in self.tools:
|
|
110
|
+
self.register(tool)
|
|
111
|
+
|
|
112
|
+
def register(self, function: Callable[..., Any], name: Optional[str] = None):
|
|
19
113
|
"""Register a function with the toolkit.
|
|
20
114
|
|
|
21
115
|
Args:
|
|
22
116
|
function: The callable to register
|
|
117
|
+
name: Optional custom name for the function
|
|
23
118
|
|
|
24
119
|
Returns:
|
|
25
120
|
The registered function
|
|
26
121
|
"""
|
|
27
122
|
try:
|
|
123
|
+
tool_name = name or function.__name__
|
|
124
|
+
if self.include_tools is not None and tool_name not in self.include_tools:
|
|
125
|
+
return
|
|
126
|
+
if self.exclude_tools is not None and tool_name in self.exclude_tools:
|
|
127
|
+
return
|
|
128
|
+
|
|
28
129
|
f = Function(
|
|
29
|
-
name=
|
|
130
|
+
name=tool_name,
|
|
30
131
|
entrypoint=function,
|
|
31
|
-
|
|
132
|
+
cache_results=self.cache_results,
|
|
133
|
+
cache_dir=self.cache_dir,
|
|
134
|
+
cache_ttl=self.cache_ttl,
|
|
135
|
+
requires_confirmation=tool_name in self.requires_confirmation_tools,
|
|
136
|
+
external_execution=tool_name in self.external_execution_required_tools,
|
|
137
|
+
stop_after_tool_call=tool_name in self.stop_after_tool_call_tools,
|
|
138
|
+
show_result=tool_name in self.show_result_tools or tool_name in self.stop_after_tool_call_tools,
|
|
32
139
|
)
|
|
33
140
|
self.functions[f.name] = f
|
|
34
|
-
|
|
141
|
+
log_debug(f"Function: {f.name} registered with {self.name}")
|
|
35
142
|
except Exception as e:
|
|
36
143
|
logger.warning(f"Failed to create Function for: {function.__name__}")
|
|
37
144
|
raise e
|
|
38
145
|
|
|
39
|
-
|
|
40
|
-
|
|
146
|
+
@property
|
|
147
|
+
def requires_connect(self) -> bool:
|
|
148
|
+
"""Whether the toolkit requires connection management."""
|
|
149
|
+
return self._requires_connect
|
|
150
|
+
|
|
151
|
+
def connect(self) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Establish any required connections for the toolkit.
|
|
154
|
+
Override this method in subclasses that require connection management.
|
|
155
|
+
Called automatically by the Agent when _requires_connect is True.
|
|
156
|
+
"""
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
def close(self) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Close any open connections for the toolkit.
|
|
162
|
+
Override this method in subclasses that require connection management.
|
|
163
|
+
Called automatically by the Agent when _requires_connect is True.
|
|
164
|
+
"""
|
|
165
|
+
pass
|
|
41
166
|
|
|
42
167
|
def __repr__(self):
|
|
43
168
|
return f"<{self.__class__.__name__} name={self.name} functions={list(self.functions.keys())}>"
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Any, Callable, Dict, List, Optional, Set
|
|
3
|
+
|
|
4
|
+
from agno.tools import Toolkit
|
|
5
|
+
from agno.utils.log import log_debug, logger
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from trafilatura import (
|
|
9
|
+
extract,
|
|
10
|
+
extract_metadata,
|
|
11
|
+
fetch_url,
|
|
12
|
+
html2txt,
|
|
13
|
+
)
|
|
14
|
+
from trafilatura.meta import reset_caches
|
|
15
|
+
|
|
16
|
+
# Import spider functionality
|
|
17
|
+
try:
|
|
18
|
+
from trafilatura.spider import focused_crawler
|
|
19
|
+
|
|
20
|
+
SPIDER_AVAILABLE = True
|
|
21
|
+
except ImportError:
|
|
22
|
+
SPIDER_AVAILABLE = False
|
|
23
|
+
logger.warning("Trafilatura spider module not available. Web crawling functionality will be disabled.")
|
|
24
|
+
|
|
25
|
+
except ImportError:
|
|
26
|
+
raise ImportError("`trafilatura` not installed. Please install using `pip install trafilatura`")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TrafilaturaTools(Toolkit):
|
|
30
|
+
"""
|
|
31
|
+
TrafilaturaTools is a toolkit for web scraping and text extraction.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
output_format (str): Default output format for extractions. Options: 'txt', 'json', 'xml', 'markdown', 'csv', 'html', 'xmltei'.
|
|
35
|
+
include_comments (bool): Whether to extract comments along with main text by default.
|
|
36
|
+
include_tables (bool): Whether to include table content by default.
|
|
37
|
+
include_images (bool): Whether to include image information by default (experimental).
|
|
38
|
+
include_formatting (bool): Whether to preserve formatting by default.
|
|
39
|
+
include_links (bool): Whether to preserve links by default (experimental).
|
|
40
|
+
with_metadata (bool): Whether to include metadata in extractions by default.
|
|
41
|
+
favor_precision (bool): Whether to prefer precision over recall by default.
|
|
42
|
+
favor_recall (bool): Whether to prefer recall over precision by default.
|
|
43
|
+
target_language (Optional[str]): Default target language filter (ISO 639-1 format).
|
|
44
|
+
deduplicate (bool): Whether to remove duplicate segments by default.
|
|
45
|
+
max_tree_size (Optional[int]): Maximum tree size for processing.
|
|
46
|
+
max_crawl_urls (int): Maximum number of URLs to crawl per website.
|
|
47
|
+
max_known_urls (int): Maximum number of known URLs during crawling.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
output_format: str = "txt",
|
|
53
|
+
include_comments: bool = True,
|
|
54
|
+
include_tables: bool = True,
|
|
55
|
+
include_images: bool = False,
|
|
56
|
+
include_formatting: bool = False,
|
|
57
|
+
include_links: bool = False,
|
|
58
|
+
with_metadata: bool = False,
|
|
59
|
+
favor_precision: bool = False,
|
|
60
|
+
favor_recall: bool = False,
|
|
61
|
+
target_language: Optional[str] = None,
|
|
62
|
+
deduplicate: bool = False,
|
|
63
|
+
max_tree_size: Optional[int] = None,
|
|
64
|
+
max_crawl_urls: int = 10,
|
|
65
|
+
max_known_urls: int = 100000,
|
|
66
|
+
# Tool enable flags for <6 functions
|
|
67
|
+
enable_extract_text: bool = True,
|
|
68
|
+
enable_extract_metadata_only: bool = True,
|
|
69
|
+
enable_html_to_text: bool = True,
|
|
70
|
+
enable_extract_batch: bool = True,
|
|
71
|
+
enable_crawl_website: bool = True,
|
|
72
|
+
all: bool = False,
|
|
73
|
+
**kwargs,
|
|
74
|
+
):
|
|
75
|
+
self.output_format = output_format
|
|
76
|
+
self.include_comments = include_comments
|
|
77
|
+
self.include_tables = include_tables
|
|
78
|
+
self.include_images = include_images
|
|
79
|
+
self.include_formatting = include_formatting
|
|
80
|
+
self.include_links = include_links
|
|
81
|
+
self.with_metadata = with_metadata
|
|
82
|
+
self.favor_precision = favor_precision
|
|
83
|
+
self.favor_recall = favor_recall
|
|
84
|
+
self.target_language = target_language
|
|
85
|
+
self.deduplicate = deduplicate
|
|
86
|
+
self.max_tree_size = max_tree_size
|
|
87
|
+
self.max_crawl_urls = max_crawl_urls
|
|
88
|
+
self.max_known_urls = max_known_urls
|
|
89
|
+
|
|
90
|
+
tools: List[Callable] = []
|
|
91
|
+
if all or enable_extract_text:
|
|
92
|
+
tools.append(self.extract_text)
|
|
93
|
+
if all or enable_extract_metadata_only:
|
|
94
|
+
tools.append(self.extract_metadata_only)
|
|
95
|
+
if all or enable_html_to_text:
|
|
96
|
+
tools.append(self.html_to_text)
|
|
97
|
+
if all or enable_extract_batch:
|
|
98
|
+
tools.append(self.extract_batch)
|
|
99
|
+
|
|
100
|
+
if all or enable_crawl_website:
|
|
101
|
+
if not SPIDER_AVAILABLE:
|
|
102
|
+
logger.warning("Web crawling requested but spider module not available. Skipping crawler tool.")
|
|
103
|
+
else:
|
|
104
|
+
tools.append(self.crawl_website)
|
|
105
|
+
|
|
106
|
+
super().__init__(name="trafilatura_tools", tools=tools, **kwargs)
|
|
107
|
+
|
|
108
|
+
def _get_extraction_params(
|
|
109
|
+
self,
|
|
110
|
+
output_format: Optional[str] = None,
|
|
111
|
+
include_comments: Optional[bool] = None,
|
|
112
|
+
include_tables: Optional[bool] = None,
|
|
113
|
+
include_images: Optional[bool] = None,
|
|
114
|
+
include_formatting: Optional[bool] = None,
|
|
115
|
+
include_links: Optional[bool] = None,
|
|
116
|
+
with_metadata: Optional[bool] = None,
|
|
117
|
+
favor_precision: Optional[bool] = None,
|
|
118
|
+
favor_recall: Optional[bool] = None,
|
|
119
|
+
target_language: Optional[str] = None,
|
|
120
|
+
deduplicate: Optional[bool] = None,
|
|
121
|
+
max_tree_size: Optional[int] = None,
|
|
122
|
+
url_blacklist: Optional[Set[str]] = None,
|
|
123
|
+
author_blacklist: Optional[Set[str]] = None,
|
|
124
|
+
) -> Dict[str, Any]:
|
|
125
|
+
"""Helper method to build extraction parameters with fallbacks to instance defaults."""
|
|
126
|
+
return {
|
|
127
|
+
"output_format": output_format if output_format is not None else self.output_format,
|
|
128
|
+
"include_comments": include_comments if include_comments is not None else self.include_comments,
|
|
129
|
+
"include_tables": include_tables if include_tables is not None else self.include_tables,
|
|
130
|
+
"include_images": include_images if include_images is not None else self.include_images,
|
|
131
|
+
"include_formatting": include_formatting if include_formatting is not None else self.include_formatting,
|
|
132
|
+
"include_links": include_links if include_links is not None else self.include_links,
|
|
133
|
+
"with_metadata": with_metadata if with_metadata is not None else self.with_metadata,
|
|
134
|
+
"favor_precision": favor_precision if favor_precision is not None else self.favor_precision,
|
|
135
|
+
"favor_recall": favor_recall if favor_recall is not None else self.favor_recall,
|
|
136
|
+
"target_language": target_language if target_language is not None else self.target_language,
|
|
137
|
+
"deduplicate": deduplicate if deduplicate is not None else self.deduplicate,
|
|
138
|
+
"max_tree_size": max_tree_size if max_tree_size is not None else self.max_tree_size,
|
|
139
|
+
"url_blacklist": url_blacklist,
|
|
140
|
+
"author_blacklist": author_blacklist,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
def extract_text(
|
|
144
|
+
self,
|
|
145
|
+
url: str,
|
|
146
|
+
output_format: Optional[str] = None,
|
|
147
|
+
) -> str:
|
|
148
|
+
"""
|
|
149
|
+
Extract main text content from a web page URL using Trafilatura.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
url (str): The URL to extract content from.
|
|
153
|
+
output_format (Optional[str]): Output format. Options: 'txt', 'json', 'xml', 'markdown', 'csv', 'html', 'xmltei'.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
str: Extracted content in the specified format, or error message if extraction fails.
|
|
157
|
+
"""
|
|
158
|
+
try:
|
|
159
|
+
log_debug(f"Extracting text from URL: {url}")
|
|
160
|
+
|
|
161
|
+
# Fetch the webpage content
|
|
162
|
+
html_content = fetch_url(url)
|
|
163
|
+
if not html_content:
|
|
164
|
+
return f"Error: Could not fetch content from URL: {url}"
|
|
165
|
+
|
|
166
|
+
# Get extraction parameters
|
|
167
|
+
params = self._get_extraction_params(output_format=output_format)
|
|
168
|
+
|
|
169
|
+
result = extract(html_content, url=url, **params)
|
|
170
|
+
|
|
171
|
+
if result is None:
|
|
172
|
+
return f"Error: Could not extract readable content from URL: {url}"
|
|
173
|
+
|
|
174
|
+
# Reset caches
|
|
175
|
+
reset_caches()
|
|
176
|
+
|
|
177
|
+
return result
|
|
178
|
+
|
|
179
|
+
except Exception as e:
|
|
180
|
+
logger.warning(f"Error extracting text from {url}: {e}")
|
|
181
|
+
return f"Error extracting text from {url}: {e}"
|
|
182
|
+
|
|
183
|
+
def extract_metadata_only(
|
|
184
|
+
self,
|
|
185
|
+
url: str,
|
|
186
|
+
as_json: bool = True,
|
|
187
|
+
) -> str:
|
|
188
|
+
"""
|
|
189
|
+
Extract only metadata from a web page URL.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
url (str): The URL to extract metadata from.
|
|
193
|
+
as_json (bool): Whether to return metadata as JSON string.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
str: Extracted metadata as JSON string or formatted text.
|
|
197
|
+
"""
|
|
198
|
+
try:
|
|
199
|
+
log_debug(f"Extracting metadata from URL: {url}")
|
|
200
|
+
|
|
201
|
+
# Fetch the webpage content
|
|
202
|
+
html_content = fetch_url(url)
|
|
203
|
+
if not html_content:
|
|
204
|
+
return f"Error: Could not fetch content from URL: {url}"
|
|
205
|
+
|
|
206
|
+
# Extract metadata
|
|
207
|
+
metadata_doc = extract_metadata(
|
|
208
|
+
html_content,
|
|
209
|
+
default_url=url,
|
|
210
|
+
extensive=True, # default
|
|
211
|
+
author_blacklist=None,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
if metadata_doc is None:
|
|
215
|
+
return f"Error: Could not extract metadata from URL: {url}"
|
|
216
|
+
|
|
217
|
+
metadata_dict = metadata_doc.as_dict()
|
|
218
|
+
|
|
219
|
+
# Reset caches
|
|
220
|
+
reset_caches()
|
|
221
|
+
|
|
222
|
+
if as_json:
|
|
223
|
+
return json.dumps(metadata_dict, indent=2, default=str)
|
|
224
|
+
else:
|
|
225
|
+
return "\n".join(f"{key}: {value}" for key, value in metadata_dict.items())
|
|
226
|
+
|
|
227
|
+
except Exception as e:
|
|
228
|
+
logger.warning(f"Error extracting metadata from {url}: {e}")
|
|
229
|
+
return f"Error extracting metadata from {url}: {e}"
|
|
230
|
+
|
|
231
|
+
def crawl_website(
|
|
232
|
+
self,
|
|
233
|
+
homepage_url: str,
|
|
234
|
+
extract_content: bool = False,
|
|
235
|
+
) -> str:
|
|
236
|
+
"""
|
|
237
|
+
Crawl a website and optionally extract content from discovered pages.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
homepage_url (str): The starting URL (preferably homepage) to crawl from.
|
|
241
|
+
extract_content (bool): Whether to extract content from discovered URLs.
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
str: JSON containing crawl results and optionally extracted content.
|
|
245
|
+
"""
|
|
246
|
+
if not SPIDER_AVAILABLE:
|
|
247
|
+
return "Error: Web crawling functionality not available. Trafilatura spider module could not be imported."
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
log_debug(f"Starting website crawl from: {homepage_url}")
|
|
251
|
+
|
|
252
|
+
# Use instance configuration
|
|
253
|
+
max_seen = self.max_crawl_urls
|
|
254
|
+
max_known = self.max_known_urls
|
|
255
|
+
lang = self.target_language
|
|
256
|
+
|
|
257
|
+
# Perform focused crawling
|
|
258
|
+
to_visit, known_links = focused_crawler(
|
|
259
|
+
homepage=homepage_url,
|
|
260
|
+
max_seen_urls=max_seen,
|
|
261
|
+
max_known_urls=max_known,
|
|
262
|
+
lang=lang,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
crawl_results = {
|
|
266
|
+
"homepage": homepage_url,
|
|
267
|
+
"to_visit": list(to_visit) if to_visit else [],
|
|
268
|
+
"known_links": list(known_links) if known_links else [],
|
|
269
|
+
"stats": {
|
|
270
|
+
"urls_to_visit": len(to_visit) if to_visit else 0,
|
|
271
|
+
"known_links_count": len(known_links) if known_links else 0,
|
|
272
|
+
},
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
# Optionally extract content from discovered URLs
|
|
276
|
+
if extract_content and known_links:
|
|
277
|
+
log_debug("Extracting content from discovered URLs")
|
|
278
|
+
extracted_content = {}
|
|
279
|
+
|
|
280
|
+
# Limit extraction to avoid overwhelming responses
|
|
281
|
+
urls_to_extract = list(known_links)[: min(10, len(known_links))]
|
|
282
|
+
|
|
283
|
+
for url in urls_to_extract:
|
|
284
|
+
try:
|
|
285
|
+
params = self._get_extraction_params()
|
|
286
|
+
|
|
287
|
+
html_content = fetch_url(url)
|
|
288
|
+
if html_content:
|
|
289
|
+
content = extract(html_content, url=url, **params)
|
|
290
|
+
if content:
|
|
291
|
+
extracted_content[url] = content
|
|
292
|
+
except Exception as e:
|
|
293
|
+
extracted_content[url] = f"Error extracting content: {e}"
|
|
294
|
+
|
|
295
|
+
crawl_results["extracted_content"] = extracted_content
|
|
296
|
+
|
|
297
|
+
# Reset caches
|
|
298
|
+
reset_caches()
|
|
299
|
+
|
|
300
|
+
return json.dumps(crawl_results, indent=2, default=str)
|
|
301
|
+
|
|
302
|
+
except Exception as e:
|
|
303
|
+
logger.warning(f"Error crawling website {homepage_url}: {e}")
|
|
304
|
+
return f"Error crawling website {homepage_url}: {e}"
|
|
305
|
+
|
|
306
|
+
def html_to_text(
|
|
307
|
+
self,
|
|
308
|
+
html_content: str,
|
|
309
|
+
clean: bool = True,
|
|
310
|
+
) -> str:
|
|
311
|
+
"""
|
|
312
|
+
Convert HTML content to plain text using Trafilatura's html2txt function.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
html_content (str): The HTML content to convert.
|
|
316
|
+
clean (bool): Whether to remove potentially undesirable elements.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
str: Plain text extracted from HTML.
|
|
320
|
+
"""
|
|
321
|
+
try:
|
|
322
|
+
log_debug("Converting HTML to text")
|
|
323
|
+
|
|
324
|
+
result = html2txt(html_content, clean=clean)
|
|
325
|
+
|
|
326
|
+
# Reset caches
|
|
327
|
+
reset_caches()
|
|
328
|
+
|
|
329
|
+
return result if result else "Error: Could not extract text from HTML content"
|
|
330
|
+
|
|
331
|
+
except Exception as e:
|
|
332
|
+
logger.warning(f"Error converting HTML to text: {e}")
|
|
333
|
+
return f"Error converting HTML to text: {e}"
|
|
334
|
+
|
|
335
|
+
def extract_batch(
|
|
336
|
+
self,
|
|
337
|
+
urls: List[str],
|
|
338
|
+
) -> str:
|
|
339
|
+
"""
|
|
340
|
+
Extract content from multiple URLs in batch.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
urls (List[str]): List of URLs to extract content from.
|
|
344
|
+
|
|
345
|
+
Returns:
|
|
346
|
+
str: JSON containing batch extraction results.
|
|
347
|
+
"""
|
|
348
|
+
try:
|
|
349
|
+
log_debug(f"Starting batch extraction for {len(urls)} URLs")
|
|
350
|
+
|
|
351
|
+
results = {}
|
|
352
|
+
failed_urls = []
|
|
353
|
+
|
|
354
|
+
for url in urls:
|
|
355
|
+
try:
|
|
356
|
+
params = self._get_extraction_params()
|
|
357
|
+
|
|
358
|
+
html_content = fetch_url(url)
|
|
359
|
+
if html_content:
|
|
360
|
+
content = extract(html_content, url=url, **params)
|
|
361
|
+
if content:
|
|
362
|
+
results[url] = content
|
|
363
|
+
else:
|
|
364
|
+
failed_urls.append(url)
|
|
365
|
+
else:
|
|
366
|
+
failed_urls.append(url)
|
|
367
|
+
|
|
368
|
+
except Exception as e:
|
|
369
|
+
failed_urls.append(url)
|
|
370
|
+
results[url] = f"Error: {e}"
|
|
371
|
+
|
|
372
|
+
# Reset caches after batch processing
|
|
373
|
+
reset_caches()
|
|
374
|
+
|
|
375
|
+
batch_results = {
|
|
376
|
+
"successful_extractions": len(results)
|
|
377
|
+
- len([k for k, v in results.items() if str(v).startswith("Error:")]),
|
|
378
|
+
"failed_extractions": len(failed_urls),
|
|
379
|
+
"total_urls": len(urls),
|
|
380
|
+
"results": results,
|
|
381
|
+
"failed_urls": failed_urls,
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return json.dumps(batch_results, indent=2, default=str)
|
|
385
|
+
|
|
386
|
+
except Exception as e:
|
|
387
|
+
logger.warning(f"Error in batch extraction: {e}")
|
|
388
|
+
return f"Error in batch extraction: {e}"
|
agno/tools/trello.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from os import getenv
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Any, List, Optional
|
|
4
4
|
|
|
5
5
|
from agno.tools import Toolkit
|
|
6
|
-
from agno.utils.log import logger
|
|
6
|
+
from agno.utils.log import log_debug, log_info, logger
|
|
7
7
|
|
|
8
8
|
try:
|
|
9
9
|
from trello import TrelloClient # type: ignore
|
|
@@ -17,16 +17,8 @@ class TrelloTools(Toolkit):
|
|
|
17
17
|
api_key: Optional[str] = None,
|
|
18
18
|
api_secret: Optional[str] = None,
|
|
19
19
|
token: Optional[str] = None,
|
|
20
|
-
|
|
21
|
-
get_board_lists: bool = True,
|
|
22
|
-
move_card: bool = True,
|
|
23
|
-
get_cards: bool = True,
|
|
24
|
-
create_board: bool = True,
|
|
25
|
-
create_list: bool = True,
|
|
26
|
-
list_boards: bool = True,
|
|
20
|
+
**kwargs,
|
|
27
21
|
):
|
|
28
|
-
super().__init__(name="trello")
|
|
29
|
-
|
|
30
22
|
self.api_key = api_key or getenv("TRELLO_API_KEY")
|
|
31
23
|
self.api_secret = api_secret or getenv("TRELLO_API_SECRET")
|
|
32
24
|
self.token = token or getenv("TRELLO_TOKEN")
|
|
@@ -40,20 +32,17 @@ class TrelloTools(Toolkit):
|
|
|
40
32
|
logger.error(f"Error initializing Trello client: {e}")
|
|
41
33
|
self.client = None
|
|
42
34
|
|
|
43
|
-
|
|
44
|
-
self.
|
|
45
|
-
|
|
46
|
-
self.
|
|
47
|
-
|
|
48
|
-
self.
|
|
49
|
-
|
|
50
|
-
self.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
self.register(self.create_list)
|
|
55
|
-
if list_boards:
|
|
56
|
-
self.register(self.list_boards)
|
|
35
|
+
tools: List[Any] = [
|
|
36
|
+
self.create_card,
|
|
37
|
+
self.get_board_lists,
|
|
38
|
+
self.move_card,
|
|
39
|
+
self.get_cards,
|
|
40
|
+
self.create_board,
|
|
41
|
+
self.create_list,
|
|
42
|
+
self.list_boards,
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
super().__init__(name="trello", tools=tools, **kwargs)
|
|
57
46
|
|
|
58
47
|
def create_card(self, board_id: str, list_name: str, card_title: str, description: str = "") -> str:
|
|
59
48
|
"""
|
|
@@ -72,7 +61,7 @@ class TrelloTools(Toolkit):
|
|
|
72
61
|
if not self.client:
|
|
73
62
|
return "Trello client not initialized"
|
|
74
63
|
|
|
75
|
-
|
|
64
|
+
log_info(f"Creating card {card_title}")
|
|
76
65
|
|
|
77
66
|
board = self.client.get_board(board_id)
|
|
78
67
|
target_list = None
|
|
@@ -106,6 +95,8 @@ class TrelloTools(Toolkit):
|
|
|
106
95
|
if not self.client:
|
|
107
96
|
return "Trello client not initialized"
|
|
108
97
|
|
|
98
|
+
log_debug(f"Getting lists for board {board_id}")
|
|
99
|
+
|
|
109
100
|
board = self.client.get_board(board_id)
|
|
110
101
|
lists = board.list_lists()
|
|
111
102
|
|
|
@@ -131,6 +122,8 @@ class TrelloTools(Toolkit):
|
|
|
131
122
|
if not self.client:
|
|
132
123
|
return "Trello client not initialized"
|
|
133
124
|
|
|
125
|
+
log_debug(f"Moving card {card_id} to list {list_id}")
|
|
126
|
+
|
|
134
127
|
card = self.client.get_card(card_id)
|
|
135
128
|
card.change_list(list_id)
|
|
136
129
|
|
|
@@ -153,6 +146,8 @@ class TrelloTools(Toolkit):
|
|
|
153
146
|
if not self.client:
|
|
154
147
|
return "Trello client not initialized"
|
|
155
148
|
|
|
149
|
+
log_debug(f"Getting cards for list {list_id}")
|
|
150
|
+
|
|
156
151
|
trello_list = self.client.get_list(list_id)
|
|
157
152
|
cards = trello_list.list_cards()
|
|
158
153
|
|
|
@@ -187,7 +182,7 @@ class TrelloTools(Toolkit):
|
|
|
187
182
|
if not self.client:
|
|
188
183
|
return "Trello client not initialized"
|
|
189
184
|
|
|
190
|
-
|
|
185
|
+
log_info(f"Creating board {name}")
|
|
191
186
|
|
|
192
187
|
board = self.client.add_board(board_name=name, default_lists=default_lists)
|
|
193
188
|
|
|
@@ -218,7 +213,7 @@ class TrelloTools(Toolkit):
|
|
|
218
213
|
if not self.client:
|
|
219
214
|
return "Trello client not initialized"
|
|
220
215
|
|
|
221
|
-
|
|
216
|
+
log_info(f"Creating list {list_name}")
|
|
222
217
|
|
|
223
218
|
board = self.client.get_board(board_id)
|
|
224
219
|
new_list = board.add_list(name=list_name, pos=pos)
|
|
@@ -250,6 +245,8 @@ class TrelloTools(Toolkit):
|
|
|
250
245
|
if not self.client:
|
|
251
246
|
return "Trello client not initialized"
|
|
252
247
|
|
|
248
|
+
log_debug(f"Listing boards with filter: {board_filter}")
|
|
249
|
+
|
|
253
250
|
boards = self.client.list_boards(board_filter=board_filter)
|
|
254
251
|
|
|
255
252
|
boards_list = []
|