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
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
from io import BytesIO
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
from agno.document.base import Document
|
|
5
|
-
from agno.document.reader.base import Reader
|
|
6
|
-
from agno.utils.log import logger
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from agno.aws.resource.s3.object import S3Object # type: ignore
|
|
10
|
-
except (ModuleNotFoundError, ImportError):
|
|
11
|
-
raise ImportError("`agno-aws` not installed. Please install using `pip install agno-aws`")
|
|
12
|
-
|
|
13
|
-
try:
|
|
14
|
-
from pypdf import PdfReader as DocumentReader # noqa: F401
|
|
15
|
-
except ImportError:
|
|
16
|
-
raise ImportError("`pypdf` not installed. Please install it via `pip install pypdf`.")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class S3PDFReader(Reader):
|
|
20
|
-
"""Reader for PDF files on S3"""
|
|
21
|
-
|
|
22
|
-
def read(self, s3_object: S3Object) -> List[Document]:
|
|
23
|
-
try:
|
|
24
|
-
logger.info(f"Reading: {s3_object.uri}")
|
|
25
|
-
|
|
26
|
-
object_resource = s3_object.get_resource()
|
|
27
|
-
object_body = object_resource.get()["Body"]
|
|
28
|
-
doc_name = s3_object.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
29
|
-
doc_reader = DocumentReader(BytesIO(object_body.read()))
|
|
30
|
-
documents = [
|
|
31
|
-
Document(
|
|
32
|
-
name=doc_name,
|
|
33
|
-
id=f"{doc_name}_{page_number}",
|
|
34
|
-
meta_data={"page": page_number},
|
|
35
|
-
content=page.extract_text(),
|
|
36
|
-
)
|
|
37
|
-
for page_number, page in enumerate(doc_reader.pages, start=1)
|
|
38
|
-
]
|
|
39
|
-
if self.chunk:
|
|
40
|
-
chunked_documents = []
|
|
41
|
-
for document in documents:
|
|
42
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
43
|
-
return chunked_documents
|
|
44
|
-
return documents
|
|
45
|
-
except Exception:
|
|
46
|
-
raise
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
from agno.document.base import Document
|
|
5
|
-
from agno.document.reader.base import Reader
|
|
6
|
-
from agno.utils.log import logger
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from agno.aws.resource.s3.object import S3Object # type: ignore
|
|
10
|
-
except (ModuleNotFoundError, ImportError):
|
|
11
|
-
raise ImportError("`agno-aws` not installed. Please install using `pip install agno-aws`")
|
|
12
|
-
|
|
13
|
-
try:
|
|
14
|
-
import textract # noqa: F401
|
|
15
|
-
except ImportError:
|
|
16
|
-
raise ImportError("`textract` not installed. Please install it via `pip install textract`.")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class S3TextReader(Reader):
|
|
20
|
-
"""Reader for text files on S3"""
|
|
21
|
-
|
|
22
|
-
def read(self, s3_object: S3Object) -> List[Document]:
|
|
23
|
-
try:
|
|
24
|
-
logger.info(f"Reading: {s3_object.uri}")
|
|
25
|
-
|
|
26
|
-
obj_name = s3_object.name.split("/")[-1]
|
|
27
|
-
temporary_file = Path("storage").joinpath(obj_name)
|
|
28
|
-
s3_object.download(temporary_file)
|
|
29
|
-
|
|
30
|
-
logger.info(f"Parsing: {temporary_file}")
|
|
31
|
-
doc_name = s3_object.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
32
|
-
doc_content = textract.process(temporary_file)
|
|
33
|
-
documents = [
|
|
34
|
-
Document(
|
|
35
|
-
name=doc_name,
|
|
36
|
-
id=doc_name,
|
|
37
|
-
content=doc_content.decode("utf-8"),
|
|
38
|
-
)
|
|
39
|
-
]
|
|
40
|
-
if self.chunk:
|
|
41
|
-
chunked_documents = []
|
|
42
|
-
for document in documents:
|
|
43
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
44
|
-
return chunked_documents
|
|
45
|
-
|
|
46
|
-
logger.debug(f"Deleting: {temporary_file}")
|
|
47
|
-
temporary_file.unlink()
|
|
48
|
-
return documents
|
|
49
|
-
except Exception as e:
|
|
50
|
-
logger.error(f"Error reading: {s3_object.uri}: {e}")
|
|
51
|
-
return []
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import IO, Any, List, Union
|
|
3
|
-
|
|
4
|
-
from agno.document.base import Document
|
|
5
|
-
from agno.document.reader.base import Reader
|
|
6
|
-
from agno.utils.log import logger
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TextReader(Reader):
|
|
10
|
-
"""Reader for Text files"""
|
|
11
|
-
|
|
12
|
-
def read(self, file: Union[Path, IO[Any]]) -> List[Document]:
|
|
13
|
-
try:
|
|
14
|
-
if isinstance(file, Path):
|
|
15
|
-
if not file.exists():
|
|
16
|
-
raise FileNotFoundError(f"Could not find file: {file}")
|
|
17
|
-
logger.info(f"Reading: {file}")
|
|
18
|
-
file_name = file.stem
|
|
19
|
-
file_contents = file.read_text()
|
|
20
|
-
else:
|
|
21
|
-
logger.info(f"Reading uploaded file: {file.name}")
|
|
22
|
-
file_name = file.name.split(".")[0]
|
|
23
|
-
file.seek(0)
|
|
24
|
-
file_contents = file.read().decode("utf-8")
|
|
25
|
-
|
|
26
|
-
documents = [
|
|
27
|
-
Document(
|
|
28
|
-
name=file_name,
|
|
29
|
-
id=file_name,
|
|
30
|
-
content=file_contents,
|
|
31
|
-
)
|
|
32
|
-
]
|
|
33
|
-
if self.chunk:
|
|
34
|
-
chunked_documents = []
|
|
35
|
-
for document in documents:
|
|
36
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
37
|
-
return chunked_documents
|
|
38
|
-
return documents
|
|
39
|
-
except Exception as e:
|
|
40
|
-
logger.error(f"Error reading: {file}: {e}")
|
|
41
|
-
return []
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import random
|
|
2
|
-
import time
|
|
3
|
-
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Dict, List, Set, Tuple
|
|
5
|
-
from urllib.parse import urljoin, urlparse
|
|
6
|
-
|
|
7
|
-
from agno.document.base import Document
|
|
8
|
-
from agno.document.reader.base import Reader
|
|
9
|
-
from agno.utils.log import logger
|
|
10
|
-
|
|
11
|
-
try:
|
|
12
|
-
from bs4 import BeautifulSoup # noqa: F401
|
|
13
|
-
except ImportError:
|
|
14
|
-
raise ImportError("The `bs4` package is not installed. Please install it via `pip install beautifulsoup4`.")
|
|
15
|
-
|
|
16
|
-
try:
|
|
17
|
-
import httpx
|
|
18
|
-
except ImportError:
|
|
19
|
-
raise ImportError("`httpx` not installed. Please install it via `pip install httpx`.")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class WebsiteReader(Reader):
|
|
24
|
-
"""Reader for Websites"""
|
|
25
|
-
|
|
26
|
-
max_depth: int = 3
|
|
27
|
-
max_links: int = 10
|
|
28
|
-
|
|
29
|
-
_visited: Set[str] = field(default_factory=set)
|
|
30
|
-
_urls_to_crawl: List[Tuple[str, int]] = field(default_factory=list)
|
|
31
|
-
|
|
32
|
-
def delay(self, min_seconds=1, max_seconds=3):
|
|
33
|
-
"""
|
|
34
|
-
Introduce a random delay.
|
|
35
|
-
|
|
36
|
-
:param min_seconds: Minimum number of seconds to delay. Default is 1.
|
|
37
|
-
:param max_seconds: Maximum number of seconds to delay. Default is 3.
|
|
38
|
-
"""
|
|
39
|
-
sleep_time = random.uniform(min_seconds, max_seconds)
|
|
40
|
-
time.sleep(sleep_time)
|
|
41
|
-
|
|
42
|
-
def _get_primary_domain(self, url: str) -> str:
|
|
43
|
-
"""
|
|
44
|
-
Extract primary domain from the given URL.
|
|
45
|
-
|
|
46
|
-
:param url: The URL to extract the primary domain from.
|
|
47
|
-
:return: The primary domain.
|
|
48
|
-
"""
|
|
49
|
-
domain_parts = urlparse(url).netloc.split(".")
|
|
50
|
-
# Return primary domain (excluding subdomains)
|
|
51
|
-
return ".".join(domain_parts[-2:])
|
|
52
|
-
|
|
53
|
-
def _extract_main_content(self, soup: BeautifulSoup) -> str:
|
|
54
|
-
"""
|
|
55
|
-
Extracts the main content from a BeautifulSoup object.
|
|
56
|
-
|
|
57
|
-
:param soup: The BeautifulSoup object to extract the main content from.
|
|
58
|
-
:return: The main content.
|
|
59
|
-
"""
|
|
60
|
-
# Try to find main content by specific tags or class names
|
|
61
|
-
for tag in ["article", "main"]:
|
|
62
|
-
element = soup.find(tag)
|
|
63
|
-
if element:
|
|
64
|
-
return element.get_text(strip=True, separator=" ")
|
|
65
|
-
|
|
66
|
-
for class_name in ["content", "main-content", "post-content"]:
|
|
67
|
-
element = soup.find(class_=class_name)
|
|
68
|
-
if element:
|
|
69
|
-
return element.get_text(strip=True, separator=" ")
|
|
70
|
-
|
|
71
|
-
return ""
|
|
72
|
-
|
|
73
|
-
def crawl(self, url: str, starting_depth: int = 1) -> Dict[str, str]:
|
|
74
|
-
"""
|
|
75
|
-
Crawls a website and returns a dictionary of URLs and their corresponding content.
|
|
76
|
-
|
|
77
|
-
Parameters:
|
|
78
|
-
- url (str): The starting URL to begin the crawl.
|
|
79
|
-
- starting_depth (int, optional): The starting depth level for the crawl. Defaults to 1.
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
- Dict[str, str]: A dictionary where each key is a URL and the corresponding value is the main
|
|
83
|
-
content extracted from that URL.
|
|
84
|
-
|
|
85
|
-
Note:
|
|
86
|
-
The function focuses on extracting the main content by prioritizing content inside common HTML tags
|
|
87
|
-
like `<article>`, `<main>`, and `<div>` with class names such as "content", "main-content", etc.
|
|
88
|
-
The crawler will also respect the `max_depth` attribute of the WebCrawler class, ensuring it does not
|
|
89
|
-
crawl deeper than the specified depth.
|
|
90
|
-
"""
|
|
91
|
-
num_links = 0
|
|
92
|
-
crawler_result: Dict[str, str] = {}
|
|
93
|
-
primary_domain = self._get_primary_domain(url)
|
|
94
|
-
# Add starting URL with its depth to the global list
|
|
95
|
-
self._urls_to_crawl.append((url, starting_depth))
|
|
96
|
-
while self._urls_to_crawl:
|
|
97
|
-
# Unpack URL and depth from the global list
|
|
98
|
-
current_url, current_depth = self._urls_to_crawl.pop(0)
|
|
99
|
-
|
|
100
|
-
# Skip if
|
|
101
|
-
# - URL is already visited
|
|
102
|
-
# - does not end with the primary domain,
|
|
103
|
-
# - exceeds max depth
|
|
104
|
-
# - exceeds max links
|
|
105
|
-
if (
|
|
106
|
-
current_url in self._visited
|
|
107
|
-
or not urlparse(current_url).netloc.endswith(primary_domain)
|
|
108
|
-
or current_depth > self.max_depth
|
|
109
|
-
or num_links >= self.max_links
|
|
110
|
-
):
|
|
111
|
-
continue
|
|
112
|
-
|
|
113
|
-
self._visited.add(current_url)
|
|
114
|
-
self.delay()
|
|
115
|
-
|
|
116
|
-
try:
|
|
117
|
-
logger.debug(f"Crawling: {current_url}")
|
|
118
|
-
response = httpx.get(current_url, timeout=10)
|
|
119
|
-
soup = BeautifulSoup(response.content, "html.parser")
|
|
120
|
-
|
|
121
|
-
# Extract main content
|
|
122
|
-
main_content = self._extract_main_content(soup)
|
|
123
|
-
if main_content:
|
|
124
|
-
crawler_result[current_url] = main_content
|
|
125
|
-
num_links += 1
|
|
126
|
-
|
|
127
|
-
# Add found URLs to the global list, with incremented depth
|
|
128
|
-
for link in soup.find_all("a", href=True):
|
|
129
|
-
full_url = urljoin(current_url, link["href"])
|
|
130
|
-
parsed_url = urlparse(full_url)
|
|
131
|
-
if parsed_url.netloc.endswith(primary_domain) and not any(
|
|
132
|
-
parsed_url.path.endswith(ext) for ext in [".pdf", ".jpg", ".png"]
|
|
133
|
-
):
|
|
134
|
-
if full_url not in self._visited and (full_url, current_depth + 1) not in self._urls_to_crawl:
|
|
135
|
-
self._urls_to_crawl.append((full_url, current_depth + 1))
|
|
136
|
-
|
|
137
|
-
except Exception as e:
|
|
138
|
-
logger.debug(f"Failed to crawl: {current_url}: {e}")
|
|
139
|
-
pass
|
|
140
|
-
|
|
141
|
-
return crawler_result
|
|
142
|
-
|
|
143
|
-
def read(self, url: str) -> List[Document]:
|
|
144
|
-
"""
|
|
145
|
-
Reads a website and returns a list of documents.
|
|
146
|
-
|
|
147
|
-
This function first converts the website into a dictionary of URLs and their corresponding content.
|
|
148
|
-
Then iterates through the dictionary and returns chunks of content.
|
|
149
|
-
|
|
150
|
-
:param url: The URL of the website to read.
|
|
151
|
-
:return: A list of documents.
|
|
152
|
-
"""
|
|
153
|
-
|
|
154
|
-
logger.debug(f"Reading: {url}")
|
|
155
|
-
crawler_result = self.crawl(url)
|
|
156
|
-
documents = []
|
|
157
|
-
for crawled_url, crawled_content in crawler_result.items():
|
|
158
|
-
if self.chunk:
|
|
159
|
-
documents.extend(
|
|
160
|
-
self.chunk_document(
|
|
161
|
-
Document(
|
|
162
|
-
name=url, id=str(crawled_url), meta_data={"url": str(crawled_url)}, content=crawled_content
|
|
163
|
-
)
|
|
164
|
-
)
|
|
165
|
-
)
|
|
166
|
-
else:
|
|
167
|
-
documents.append(
|
|
168
|
-
Document(
|
|
169
|
-
name=url,
|
|
170
|
-
id=str(crawled_url),
|
|
171
|
-
meta_data={"url": str(crawled_url)},
|
|
172
|
-
content=crawled_content,
|
|
173
|
-
)
|
|
174
|
-
)
|
|
175
|
-
return documents
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
from agno.document.base import Document
|
|
4
|
-
from agno.document.reader.base import Reader
|
|
5
|
-
from agno.utils.log import logger
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
from youtube_transcript_api import YouTubeTranscriptApi
|
|
9
|
-
except ImportError:
|
|
10
|
-
raise ImportError(
|
|
11
|
-
"`youtube_transcript_api` not installed. Please install it via `pip install youtube_transcript_api`."
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class YouTubeReader(Reader):
|
|
16
|
-
"""Reader for YouTube video transcripts"""
|
|
17
|
-
|
|
18
|
-
def read(self, video_url: str) -> List[Document]:
|
|
19
|
-
try:
|
|
20
|
-
# Extract video ID from URL
|
|
21
|
-
video_id = video_url.split("v=")[-1].split("&")[0]
|
|
22
|
-
logger.info(f"Reading transcript for video: {video_id}")
|
|
23
|
-
|
|
24
|
-
# Get transcript
|
|
25
|
-
transcript_list = YouTubeTranscriptApi.get_transcript(video_id)
|
|
26
|
-
|
|
27
|
-
# Combine transcript segments into full text
|
|
28
|
-
transcript_text = ""
|
|
29
|
-
for segment in transcript_list:
|
|
30
|
-
transcript_text += f"{segment['text']} "
|
|
31
|
-
|
|
32
|
-
documents = [
|
|
33
|
-
Document(
|
|
34
|
-
name=f"youtube_{video_id}",
|
|
35
|
-
id=f"youtube_{video_id}",
|
|
36
|
-
meta_data={"video_url": video_url, "video_id": video_id},
|
|
37
|
-
content=transcript_text.strip(),
|
|
38
|
-
)
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
if self.chunk:
|
|
42
|
-
chunked_documents = []
|
|
43
|
-
for document in documents:
|
|
44
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
45
|
-
return chunked_documents
|
|
46
|
-
return documents
|
|
47
|
-
|
|
48
|
-
except Exception as e:
|
|
49
|
-
logger.error(f"Error reading transcript for {video_url}: {e}")
|
|
50
|
-
return []
|
agno/embedder/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from agno.embedder.base import Embedder
|
agno/embedder/azure_openai.py
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
from os import getenv
|
|
2
|
-
from typing import Any, Dict, List, Optional, Tuple
|
|
3
|
-
|
|
4
|
-
from typing_extensions import Literal
|
|
5
|
-
|
|
6
|
-
from agno.embedder.base import Embedder
|
|
7
|
-
from agno.utils.log import logger
|
|
8
|
-
|
|
9
|
-
try:
|
|
10
|
-
from openai import AzureOpenAI as AzureOpenAIClient
|
|
11
|
-
from openai.types.create_embedding_response import CreateEmbeddingResponse
|
|
12
|
-
except ImportError:
|
|
13
|
-
raise ImportError("`openai` not installed")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class AzureOpenAIEmbedder(Embedder):
|
|
17
|
-
id: str = "text-embedding-3-small" # This has to match the model that you deployed at the provided URL
|
|
18
|
-
|
|
19
|
-
dimensions: int = 1536
|
|
20
|
-
encoding_format: Literal["float", "base64"] = "float"
|
|
21
|
-
user: Optional[str] = None
|
|
22
|
-
api_key: Optional[str] = getenv("AZURE_EMBEDDER_OPENAI_API_KEY")
|
|
23
|
-
api_version: str = getenv("AZURE_EMBEDDER_OPENAI_API_VERSION", "2024-10-21")
|
|
24
|
-
azure_endpoint: Optional[str] = getenv("AZURE_EMBEDDER_OPENAI_ENDPOINT")
|
|
25
|
-
azure_deployment: Optional[str] = getenv("AZURE_EMBEDDER_DEPLOYMENT")
|
|
26
|
-
base_url: Optional[str] = None
|
|
27
|
-
azure_ad_token: Optional[str] = None
|
|
28
|
-
azure_ad_token_provider: Optional[Any] = None
|
|
29
|
-
organization: Optional[str] = None
|
|
30
|
-
request_params: Optional[Dict[str, Any]] = None
|
|
31
|
-
client_params: Optional[Dict[str, Any]] = None
|
|
32
|
-
openai_client: Optional[AzureOpenAIClient] = None
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def client(self) -> AzureOpenAIClient:
|
|
36
|
-
if self.openai_client:
|
|
37
|
-
return self.openai_client
|
|
38
|
-
|
|
39
|
-
_client_params: Dict[str, Any] = {}
|
|
40
|
-
if self.api_key:
|
|
41
|
-
_client_params["api_key"] = self.api_key
|
|
42
|
-
if self.api_version:
|
|
43
|
-
_client_params["api_version"] = self.api_version
|
|
44
|
-
if self.organization:
|
|
45
|
-
_client_params["organization"] = self.organization
|
|
46
|
-
if self.azure_endpoint:
|
|
47
|
-
_client_params["azure_endpoint"] = self.azure_endpoint
|
|
48
|
-
if self.azure_deployment:
|
|
49
|
-
_client_params["azure_deployment"] = self.azure_deployment
|
|
50
|
-
if self.base_url:
|
|
51
|
-
_client_params["base_url"] = self.base_url
|
|
52
|
-
if self.azure_ad_token:
|
|
53
|
-
_client_params["azure_ad_token"] = self.azure_ad_token
|
|
54
|
-
if self.azure_ad_token_provider:
|
|
55
|
-
_client_params["azure_ad_token_provider"] = self.azure_ad_token_provider
|
|
56
|
-
return AzureOpenAIClient(**_client_params)
|
|
57
|
-
|
|
58
|
-
def _response(self, text: str) -> CreateEmbeddingResponse:
|
|
59
|
-
_request_params: Dict[str, Any] = {
|
|
60
|
-
"input": text,
|
|
61
|
-
"model": self.id,
|
|
62
|
-
"encoding_format": self.encoding_format,
|
|
63
|
-
}
|
|
64
|
-
if self.user is not None:
|
|
65
|
-
_request_params["user"] = self.user
|
|
66
|
-
if self.id.startswith("text-embedding-3"):
|
|
67
|
-
_request_params["dimensions"] = self.dimensions
|
|
68
|
-
if self.request_params:
|
|
69
|
-
_request_params.update(self.request_params)
|
|
70
|
-
|
|
71
|
-
return self.client.embeddings.create(**_request_params)
|
|
72
|
-
|
|
73
|
-
def get_embedding(self, text: str) -> List[float]:
|
|
74
|
-
response: CreateEmbeddingResponse = self._response(text=text)
|
|
75
|
-
try:
|
|
76
|
-
return response.data[0].embedding
|
|
77
|
-
except Exception as e:
|
|
78
|
-
logger.warning(e)
|
|
79
|
-
return []
|
|
80
|
-
|
|
81
|
-
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
82
|
-
response: CreateEmbeddingResponse = self._response(text=text)
|
|
83
|
-
|
|
84
|
-
embedding = response.data[0].embedding
|
|
85
|
-
usage = response.usage
|
|
86
|
-
return embedding, usage.model_dump()
|
agno/embedder/cohere.py
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
3
|
-
|
|
4
|
-
from agno.embedder.base import Embedder
|
|
5
|
-
from agno.utils.log import logger
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
from cohere import Client as CohereClient
|
|
9
|
-
from cohere.types.embed_response import EmbeddingsByTypeEmbedResponse, EmbeddingsFloatsEmbedResponse
|
|
10
|
-
except ImportError:
|
|
11
|
-
raise ImportError("`cohere` not installed. Please install using `pip install cohere`.")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass
|
|
15
|
-
class CohereEmbedder(Embedder):
|
|
16
|
-
id: str = "embed-english-v3.0"
|
|
17
|
-
input_type: str = "search_query"
|
|
18
|
-
embedding_types: Optional[List[str]] = None
|
|
19
|
-
api_key: Optional[str] = None
|
|
20
|
-
request_params: Optional[Dict[str, Any]] = None
|
|
21
|
-
client_params: Optional[Dict[str, Any]] = None
|
|
22
|
-
cohere_client: Optional[CohereClient] = None
|
|
23
|
-
|
|
24
|
-
@property
|
|
25
|
-
def client(self) -> CohereClient:
|
|
26
|
-
if self.cohere_client:
|
|
27
|
-
return self.cohere_client
|
|
28
|
-
client_params: Dict[str, Any] = {}
|
|
29
|
-
if self.api_key:
|
|
30
|
-
client_params["api_key"] = self.api_key
|
|
31
|
-
return CohereClient(**client_params)
|
|
32
|
-
|
|
33
|
-
def response(self, text: str) -> Union[EmbeddingsFloatsEmbedResponse, EmbeddingsByTypeEmbedResponse]:
|
|
34
|
-
request_params: Dict[str, Any] = {}
|
|
35
|
-
|
|
36
|
-
if self.id:
|
|
37
|
-
request_params["model"] = self.id
|
|
38
|
-
if self.input_type:
|
|
39
|
-
request_params["input_type"] = self.input_type
|
|
40
|
-
if self.embedding_types:
|
|
41
|
-
request_params["embedding_types"] = self.embedding_types
|
|
42
|
-
if self.request_params:
|
|
43
|
-
request_params.update(self.request_params)
|
|
44
|
-
return self.client.embed(texts=[text], **request_params)
|
|
45
|
-
|
|
46
|
-
def get_embedding(self, text: str) -> List[float]:
|
|
47
|
-
response: Union[EmbeddingsFloatsEmbedResponse, EmbeddingsByTypeEmbedResponse] = self.response(text=text)
|
|
48
|
-
try:
|
|
49
|
-
if isinstance(response, EmbeddingsFloatsEmbedResponse):
|
|
50
|
-
return response.embeddings[0]
|
|
51
|
-
elif isinstance(response, EmbeddingsByTypeEmbedResponse):
|
|
52
|
-
return response.embeddings.float_[0] if response.embeddings.float_ else []
|
|
53
|
-
else:
|
|
54
|
-
logger.warning("No embeddings found")
|
|
55
|
-
return []
|
|
56
|
-
except Exception as e:
|
|
57
|
-
logger.warning(e)
|
|
58
|
-
return []
|
|
59
|
-
|
|
60
|
-
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict[str, Any]]]:
|
|
61
|
-
response: Union[EmbeddingsFloatsEmbedResponse, EmbeddingsByTypeEmbedResponse] = self.response(text=text)
|
|
62
|
-
|
|
63
|
-
embedding: List[float] = []
|
|
64
|
-
if isinstance(response, EmbeddingsFloatsEmbedResponse):
|
|
65
|
-
embedding = response.embeddings[0]
|
|
66
|
-
elif isinstance(response, EmbeddingsByTypeEmbedResponse):
|
|
67
|
-
embedding = response.embeddings.float_[0] if response.embeddings.float_ else []
|
|
68
|
-
|
|
69
|
-
usage = response.meta.billed_units if response.meta else None
|
|
70
|
-
if usage:
|
|
71
|
-
return embedding, usage.model_dump()
|
|
72
|
-
return embedding, None
|
agno/embedder/fastembed.py
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Dict, List, Optional, Tuple
|
|
3
|
-
|
|
4
|
-
from agno.embedder.base import Embedder
|
|
5
|
-
from agno.utils.log import logger
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
from fastembed import TextEmbedding # type: ignore
|
|
9
|
-
|
|
10
|
-
except ImportError:
|
|
11
|
-
raise ImportError("fastembed not installed, use pip install fastembed")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass
|
|
15
|
-
class FastEmbedEmbedder(Embedder):
|
|
16
|
-
"""Using BAAI/bge-small-en-v1.5 model, more models available: https://qdrant.github.io/fastembed/examples/Supported_Models/"""
|
|
17
|
-
|
|
18
|
-
id: str = "BAAI/bge-small-en-v1.5"
|
|
19
|
-
dimensions: int = 384
|
|
20
|
-
|
|
21
|
-
def get_embedding(self, text: str) -> List[float]:
|
|
22
|
-
model = TextEmbedding(model_name=self.id)
|
|
23
|
-
embeddings = model.embed(text)
|
|
24
|
-
embedding_list = list(embeddings)
|
|
25
|
-
|
|
26
|
-
try:
|
|
27
|
-
return embedding_list
|
|
28
|
-
except Exception as e:
|
|
29
|
-
logger.warning(e)
|
|
30
|
-
return []
|
|
31
|
-
|
|
32
|
-
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
33
|
-
embedding = self.get_embedding(text=text)
|
|
34
|
-
# Currently, FastEmbed does not provide usage information
|
|
35
|
-
usage = None
|
|
36
|
-
|
|
37
|
-
return embedding, usage
|
agno/embedder/google.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from os import getenv
|
|
3
|
-
from types import ModuleType
|
|
4
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
5
|
-
|
|
6
|
-
from agno.embedder.base import Embedder
|
|
7
|
-
from agno.utils.log import logger
|
|
8
|
-
|
|
9
|
-
try:
|
|
10
|
-
import google.generativeai as genai
|
|
11
|
-
from google.generativeai.types.text_types import BatchEmbeddingDict, EmbeddingDict
|
|
12
|
-
except ImportError:
|
|
13
|
-
logger.error("`google-generativeai` not installed. Please install it using `pip install google-generativeai`")
|
|
14
|
-
raise
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass
|
|
18
|
-
class GeminiEmbedder(Embedder):
|
|
19
|
-
id: str = "models/text-embedding-004"
|
|
20
|
-
task_type: str = "RETRIEVAL_QUERY"
|
|
21
|
-
title: Optional[str] = None
|
|
22
|
-
dimensions: Optional[int] = 768
|
|
23
|
-
api_key: Optional[str] = None
|
|
24
|
-
request_params: Optional[Dict[str, Any]] = None
|
|
25
|
-
client_params: Optional[Dict[str, Any]] = None
|
|
26
|
-
gemini_client: Optional[ModuleType] = None
|
|
27
|
-
|
|
28
|
-
@property
|
|
29
|
-
def client(self):
|
|
30
|
-
if self.gemini_client:
|
|
31
|
-
return self.gemini_client
|
|
32
|
-
_client_params: Dict[str, Any] = {}
|
|
33
|
-
|
|
34
|
-
self.api_key = self.api_key or getenv("GOOGLE_API_KEY")
|
|
35
|
-
if not self.api_key:
|
|
36
|
-
logger.error("GOOGLE_API_KEY not set. Please set the GOOGLE_API_KEY environment variable.")
|
|
37
|
-
|
|
38
|
-
if self.api_key:
|
|
39
|
-
_client_params["api_key"] = self.api_key
|
|
40
|
-
if self.client_params:
|
|
41
|
-
_client_params.update(self.client_params)
|
|
42
|
-
self.gemini_client = genai
|
|
43
|
-
self.gemini_client.configure(**_client_params) # type: ignore
|
|
44
|
-
return self.gemini_client
|
|
45
|
-
|
|
46
|
-
def _response(self, text: str) -> Union[EmbeddingDict, BatchEmbeddingDict]:
|
|
47
|
-
_request_params: Dict[str, Any] = {
|
|
48
|
-
"content": text,
|
|
49
|
-
"model": self.id,
|
|
50
|
-
"output_dimensionality": self.dimensions,
|
|
51
|
-
"task_type": self.task_type,
|
|
52
|
-
"title": self.title,
|
|
53
|
-
}
|
|
54
|
-
if self.request_params:
|
|
55
|
-
_request_params.update(self.request_params)
|
|
56
|
-
return self.client.embed_content(**_request_params)
|
|
57
|
-
|
|
58
|
-
def get_embedding(self, text: str) -> List[float]:
|
|
59
|
-
response = self._response(text=text)
|
|
60
|
-
try:
|
|
61
|
-
return response.get("embedding", [])
|
|
62
|
-
except Exception as e:
|
|
63
|
-
logger.warning(e)
|
|
64
|
-
return []
|
|
65
|
-
|
|
66
|
-
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
67
|
-
response = self._response(text=text)
|
|
68
|
-
usage = None
|
|
69
|
-
try:
|
|
70
|
-
return response.get("embedding", []), usage
|
|
71
|
-
except Exception as e:
|
|
72
|
-
logger.warning(e)
|
|
73
|
-
return [], usage
|