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/constants.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
PYTHONPATH_ENV_VAR: str = "PYTHONPATH"
|
|
2
|
-
AGNO_RUNTIME_ENV_VAR: str = "AGNO_RUNTIME"
|
|
3
|
-
AGNO_API_KEY_ENV_VAR: str = "AGNO_API_KEY"
|
|
4
|
-
|
|
5
|
-
WORKSPACE_ID_ENV_VAR: str = "AGNO_WORKSPACE_ID"
|
|
6
|
-
WORKSPACE_NAME_ENV_VAR: str = "AGNO_WORKSPACE_NAME"
|
|
7
|
-
WORKSPACE_ROOT_ENV_VAR: str = "AGNO_WORKSPACE_ROOT"
|
|
8
|
-
WORKSPACE_DIR_ENV_VAR: str = "AGNO_WORKSPACE_DIR"
|
|
9
|
-
REQUIREMENTS_FILE_PATH_ENV_VAR: str = "REQUIREMENTS_FILE_PATH"
|
|
10
|
-
|
|
11
|
-
AWS_REGION_ENV_VAR: str = "AWS_REGION"
|
|
12
|
-
AWS_DEFAULT_REGION_ENV_VAR: str = "AWS_DEFAULT_REGION"
|
|
13
|
-
AWS_PROFILE_ENV_VAR: str = "AWS_PROFILE"
|
agno/document/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from agno.document.base import Document
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
2
|
-
|
|
3
|
-
from agno.document.base import Document
|
|
4
|
-
from agno.document.chunking.strategy import ChunkingStrategy
|
|
5
|
-
from agno.embedder.base import Embedder
|
|
6
|
-
from agno.embedder.openai import OpenAIEmbedder
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from chonkie import SemanticChunker
|
|
10
|
-
except ImportError:
|
|
11
|
-
raise ImportError("`chonkie` is required for semantic chunking, please install using `uv pip install chonkie`")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class SemanticChunking(ChunkingStrategy):
|
|
15
|
-
"""Chunking strategy that splits text into semantic chunks using chonkie"""
|
|
16
|
-
|
|
17
|
-
def __init__(
|
|
18
|
-
self, embedder: Optional[Embedder] = None, chunk_size: int = 5000, similarity_threshold: Optional[float] = 0.5
|
|
19
|
-
):
|
|
20
|
-
self.embedder = embedder or OpenAIEmbedder(id="text-embedding-3-small") # type: ignore
|
|
21
|
-
self.chunk_size = chunk_size
|
|
22
|
-
self.similarity_threshold = similarity_threshold
|
|
23
|
-
self.chunker = SemanticChunker(
|
|
24
|
-
embedding_model=self.embedder.model, # type: ignore
|
|
25
|
-
chunk_size=self.chunk_size,
|
|
26
|
-
threshold=self.similarity_threshold,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
def chunk(self, document: Document) -> List[Document]:
|
|
30
|
-
"""Split document into semantic chunks using chokie"""
|
|
31
|
-
if not document.content:
|
|
32
|
-
return [document]
|
|
33
|
-
|
|
34
|
-
# Use chonkie to split into semantic chunks
|
|
35
|
-
chunks = self.chunker.chunk(self.clean_text(document.content))
|
|
36
|
-
|
|
37
|
-
# Convert chunks to Documents
|
|
38
|
-
chunked_documents: List[Document] = []
|
|
39
|
-
for i, chunk in enumerate(chunks, 1):
|
|
40
|
-
meta_data = document.meta_data.copy()
|
|
41
|
-
meta_data["chunk"] = i
|
|
42
|
-
chunk_id = f"{document.id}_{i}" if document.id else None
|
|
43
|
-
meta_data["chunk_size"] = len(chunk.text)
|
|
44
|
-
|
|
45
|
-
chunked_documents.append(Document(id=chunk_id, name=document.name, meta_data=meta_data, content=chunk.text))
|
|
46
|
-
|
|
47
|
-
return chunked_documents
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
from agno.document.base import Document
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ChunkingStrategy(ABC):
|
|
8
|
-
"""Base class for chunking strategies"""
|
|
9
|
-
|
|
10
|
-
@abstractmethod
|
|
11
|
-
def chunk(self, document: Document) -> List[Document]:
|
|
12
|
-
raise NotImplementedError
|
|
13
|
-
|
|
14
|
-
def clean_text(self, text: str) -> str:
|
|
15
|
-
"""Clean the text by replacing multiple newlines with a single newline"""
|
|
16
|
-
import re
|
|
17
|
-
|
|
18
|
-
# Replace multiple newlines with a single newline
|
|
19
|
-
cleaned_text = re.sub(r"\n+", "\n", text)
|
|
20
|
-
# Replace multiple spaces with a single space
|
|
21
|
-
cleaned_text = re.sub(r"\s+", " ", cleaned_text)
|
|
22
|
-
# Replace multiple tabs with a single tab
|
|
23
|
-
cleaned_text = re.sub(r"\t+", "\t", cleaned_text)
|
|
24
|
-
# Replace multiple carriage returns with a single carriage return
|
|
25
|
-
cleaned_text = re.sub(r"\r+", "\r", cleaned_text)
|
|
26
|
-
# Replace multiple form feeds with a single form feed
|
|
27
|
-
cleaned_text = re.sub(r"\f+", "\f", cleaned_text)
|
|
28
|
-
# Replace multiple vertical tabs with a single vertical tab
|
|
29
|
-
cleaned_text = re.sub(r"\v+", "\v", cleaned_text)
|
|
30
|
-
|
|
31
|
-
return cleaned_text
|
agno/document/reader/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from agno.document.reader.base import Reader
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
from agno.document.base import Document
|
|
4
|
-
from agno.document.reader.base import Reader
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
import arxiv # noqa: F401
|
|
8
|
-
except ImportError:
|
|
9
|
-
raise ImportError("The `arxiv` package is not installed. Please install it via `pip install arxiv`.")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ArxivReader(Reader):
|
|
13
|
-
max_results: int = 5 # Top articles
|
|
14
|
-
sort_by: arxiv.SortCriterion = arxiv.SortCriterion.Relevance
|
|
15
|
-
|
|
16
|
-
def read(self, query: str) -> List[Document]:
|
|
17
|
-
"""
|
|
18
|
-
Search a query from arXiv database
|
|
19
|
-
|
|
20
|
-
This function gets the top_k articles based on a user's query, sorted by relevance from arxiv
|
|
21
|
-
|
|
22
|
-
@param query:
|
|
23
|
-
@return: List of documents
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
documents = []
|
|
27
|
-
search = arxiv.Search(query=query, max_results=self.max_results, sort_by=self.sort_by)
|
|
28
|
-
|
|
29
|
-
for result in search.results():
|
|
30
|
-
links = ", ".join([x.href for x in result.links])
|
|
31
|
-
|
|
32
|
-
documents.append(
|
|
33
|
-
Document(
|
|
34
|
-
name=result.title,
|
|
35
|
-
id=result.title,
|
|
36
|
-
meta_data={"pdf_url": str(result.pdf_url), "article_links": links},
|
|
37
|
-
content=result.summary,
|
|
38
|
-
)
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
return documents
|
agno/document/reader/base.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass, field
|
|
2
|
-
from typing import Any, List
|
|
3
|
-
|
|
4
|
-
from agno.document.base import Document
|
|
5
|
-
from agno.document.chunking.fixed import FixedSizeChunking
|
|
6
|
-
from agno.document.chunking.strategy import ChunkingStrategy
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@dataclass
|
|
10
|
-
class Reader:
|
|
11
|
-
"""Base class for reading documents"""
|
|
12
|
-
|
|
13
|
-
chunk: bool = True
|
|
14
|
-
chunk_size: int = 3000
|
|
15
|
-
separators: List[str] = field(default_factory=lambda: ["\n", "\n\n", "\r", "\r\n", "\n\r", "\t", " ", " "])
|
|
16
|
-
chunking_strategy: ChunkingStrategy = field(default_factory=FixedSizeChunking)
|
|
17
|
-
|
|
18
|
-
def read(self, obj: Any) -> List[Document]:
|
|
19
|
-
raise NotImplementedError
|
|
20
|
-
|
|
21
|
-
def chunk_document(self, document: Document) -> List[Document]:
|
|
22
|
-
return self.chunking_strategy.chunk(document)
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
import io
|
|
3
|
-
import os
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import IO, Any, List, Union
|
|
6
|
-
from urllib.parse import urlparse
|
|
7
|
-
|
|
8
|
-
from agno.document.base import Document
|
|
9
|
-
from agno.document.reader.base import Reader
|
|
10
|
-
from agno.utils.log import logger
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class CSVReader(Reader):
|
|
14
|
-
"""Reader for CSV files"""
|
|
15
|
-
|
|
16
|
-
def read(self, file: Union[Path, IO[Any]], delimiter: str = ",", quotechar: str = '"') -> List[Document]:
|
|
17
|
-
try:
|
|
18
|
-
if isinstance(file, Path):
|
|
19
|
-
if not file.exists():
|
|
20
|
-
raise FileNotFoundError(f"Could not find file: {file}")
|
|
21
|
-
logger.info(f"Reading: {file}")
|
|
22
|
-
file_content = file.open(newline="", mode="r", encoding="utf-8")
|
|
23
|
-
else:
|
|
24
|
-
logger.info(f"Reading uploaded file: {file.name}")
|
|
25
|
-
file.seek(0)
|
|
26
|
-
file_content = io.StringIO(file.read().decode("utf-8")) # type: ignore
|
|
27
|
-
|
|
28
|
-
csv_name = Path(file.name).stem if isinstance(file, Path) else file.name.split(".")[0]
|
|
29
|
-
csv_content = ""
|
|
30
|
-
with file_content as csvfile:
|
|
31
|
-
csv_reader = csv.reader(csvfile, delimiter=delimiter, quotechar=quotechar)
|
|
32
|
-
for row in csv_reader:
|
|
33
|
-
csv_content += ", ".join(row) + "\n"
|
|
34
|
-
|
|
35
|
-
documents = [
|
|
36
|
-
Document(
|
|
37
|
-
name=csv_name,
|
|
38
|
-
id=csv_name,
|
|
39
|
-
content=csv_content,
|
|
40
|
-
)
|
|
41
|
-
]
|
|
42
|
-
if self.chunk:
|
|
43
|
-
chunked_documents = []
|
|
44
|
-
for document in documents:
|
|
45
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
46
|
-
return chunked_documents
|
|
47
|
-
return documents
|
|
48
|
-
except Exception as e:
|
|
49
|
-
logger.error(f"Error reading: {file.name if isinstance(file, IO) else file}: {e}")
|
|
50
|
-
return []
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class CSVUrlReader(Reader):
|
|
54
|
-
"""Reader for CSV files"""
|
|
55
|
-
|
|
56
|
-
def read(self, url: str) -> List[Document]:
|
|
57
|
-
if not url:
|
|
58
|
-
raise ValueError("No URL provided")
|
|
59
|
-
|
|
60
|
-
try:
|
|
61
|
-
import httpx
|
|
62
|
-
except ImportError:
|
|
63
|
-
raise ImportError("`httpx` not installed")
|
|
64
|
-
|
|
65
|
-
logger.info(f"Reading: {url}")
|
|
66
|
-
response = httpx.get(url)
|
|
67
|
-
|
|
68
|
-
try:
|
|
69
|
-
response.raise_for_status()
|
|
70
|
-
except httpx.HTTPStatusError as e:
|
|
71
|
-
logger.error(f"HTTP error occurred: {e.response.status_code} - {e.response.text}")
|
|
72
|
-
raise
|
|
73
|
-
|
|
74
|
-
parsed_url = urlparse(url)
|
|
75
|
-
filename = os.path.basename(parsed_url.path) or "data.csv"
|
|
76
|
-
|
|
77
|
-
file_obj = io.BytesIO(response.content)
|
|
78
|
-
file_obj.name = filename
|
|
79
|
-
|
|
80
|
-
documents = CSVReader().read(file=file_obj)
|
|
81
|
-
|
|
82
|
-
file_obj.close()
|
|
83
|
-
|
|
84
|
-
return documents
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import List, Union
|
|
4
|
-
|
|
5
|
-
from agno.document.base import Document
|
|
6
|
-
from agno.document.reader.base import Reader
|
|
7
|
-
from agno.utils.log import logger
|
|
8
|
-
|
|
9
|
-
try:
|
|
10
|
-
from docx import Document as DocxDocument # type: ignore
|
|
11
|
-
except ImportError:
|
|
12
|
-
raise ImportError("The `python-docx` package is not installed. Please install it via `pip install python-docx`.")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class DocxReader(Reader):
|
|
16
|
-
"""Reader for Doc/Docx files"""
|
|
17
|
-
|
|
18
|
-
def read(self, file: Union[Path, io.BytesIO]) -> List[Document]:
|
|
19
|
-
try:
|
|
20
|
-
if isinstance(file, Path):
|
|
21
|
-
logger.info(f"Reading: {file}")
|
|
22
|
-
docx_document = DocxDocument(str(file))
|
|
23
|
-
doc_name = file.stem
|
|
24
|
-
else: # Handle file-like object from upload
|
|
25
|
-
logger.info(f"Reading uploaded file: {file.name}")
|
|
26
|
-
docx_document = DocxDocument(file)
|
|
27
|
-
doc_name = file.name.split(".")[0]
|
|
28
|
-
|
|
29
|
-
doc_content = "\n\n".join([para.text for para in docx_document.paragraphs])
|
|
30
|
-
|
|
31
|
-
documents = [
|
|
32
|
-
Document(
|
|
33
|
-
name=doc_name,
|
|
34
|
-
id=doc_name,
|
|
35
|
-
content=doc_content,
|
|
36
|
-
)
|
|
37
|
-
]
|
|
38
|
-
if self.chunk:
|
|
39
|
-
chunked_documents = []
|
|
40
|
-
for document in documents:
|
|
41
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
42
|
-
return chunked_documents
|
|
43
|
-
return documents
|
|
44
|
-
except Exception as e:
|
|
45
|
-
logger.error(f"Error reading file: {e}")
|
|
46
|
-
return []
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Dict, List, Literal, Optional
|
|
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 firecrawl import FirecrawlApp
|
|
10
|
-
except ImportError:
|
|
11
|
-
raise ImportError("The `firecrawl` package is not installed. Please install it via `pip install firecrawl-py`.")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dataclass
|
|
15
|
-
class FirecrawlReader(Reader):
|
|
16
|
-
api_key: Optional[str] = None
|
|
17
|
-
params: Optional[Dict] = None
|
|
18
|
-
mode: Literal["scrape", "crawl"] = "scrape"
|
|
19
|
-
|
|
20
|
-
def scrape(self, url: str) -> List[Document]:
|
|
21
|
-
"""
|
|
22
|
-
Scrapes a website and returns a list of documents.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
url: The URL of the website to scrape
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
A list of documents
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
logger.debug(f"Scraping: {url}")
|
|
32
|
-
|
|
33
|
-
app = FirecrawlApp(api_key=self.api_key)
|
|
34
|
-
scraped_data = app.scrape_url(url, params=self.params)
|
|
35
|
-
# print(scraped_data)
|
|
36
|
-
content = scraped_data.get("markdown", "")
|
|
37
|
-
|
|
38
|
-
# Debug logging
|
|
39
|
-
logger.debug(f"Received content type: {type(content)}")
|
|
40
|
-
logger.debug(f"Content empty: {not bool(content)}")
|
|
41
|
-
|
|
42
|
-
# Ensure content is a string
|
|
43
|
-
if content is None:
|
|
44
|
-
content = "" # or you could use metadata to create a meaningful message
|
|
45
|
-
logger.warning(f"No content received for URL: {url}")
|
|
46
|
-
|
|
47
|
-
documents = []
|
|
48
|
-
if self.chunk and content: # Only chunk if there's content
|
|
49
|
-
documents.extend(self.chunk_document(Document(name=url, id=url, content=content)))
|
|
50
|
-
else:
|
|
51
|
-
documents.append(Document(name=url, id=url, content=content))
|
|
52
|
-
return documents
|
|
53
|
-
|
|
54
|
-
def crawl(self, url: str) -> List[Document]:
|
|
55
|
-
"""
|
|
56
|
-
Crawls a website and returns a list of documents.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
url: The URL of the website to crawl
|
|
60
|
-
|
|
61
|
-
Returns:
|
|
62
|
-
A list of documents
|
|
63
|
-
"""
|
|
64
|
-
logger.debug(f"Crawling: {url}")
|
|
65
|
-
|
|
66
|
-
app = FirecrawlApp(api_key=self.api_key)
|
|
67
|
-
crawl_result = app.crawl_url(url, params=self.params)
|
|
68
|
-
documents = []
|
|
69
|
-
|
|
70
|
-
# Extract data from crawl results
|
|
71
|
-
results_data = crawl_result.get("data", [])
|
|
72
|
-
for result in results_data:
|
|
73
|
-
# Get markdown content, default to empty string if not found
|
|
74
|
-
content = result.get("markdown", "")
|
|
75
|
-
|
|
76
|
-
if content: # Only create document if content exists
|
|
77
|
-
if self.chunk:
|
|
78
|
-
documents.extend(self.chunk_document(Document(name=url, id=url, content=content)))
|
|
79
|
-
else:
|
|
80
|
-
documents.append(Document(name=url, id=url, content=content))
|
|
81
|
-
|
|
82
|
-
return documents
|
|
83
|
-
|
|
84
|
-
def read(self, url: str) -> List[Document]:
|
|
85
|
-
"""
|
|
86
|
-
|
|
87
|
-
Args:
|
|
88
|
-
url: The URL of the website to scrape
|
|
89
|
-
|
|
90
|
-
Returns:
|
|
91
|
-
A list of documents
|
|
92
|
-
"""
|
|
93
|
-
|
|
94
|
-
if self.mode == "scrape":
|
|
95
|
-
return self.scrape(url)
|
|
96
|
-
elif self.mode == "crawl":
|
|
97
|
-
return self.crawl(url)
|
|
98
|
-
else:
|
|
99
|
-
raise NotImplementedError(f"Mode {self.mode} not implemented")
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import List
|
|
4
|
-
|
|
5
|
-
from agno.document.base import Document
|
|
6
|
-
from agno.document.reader.base import Reader
|
|
7
|
-
from agno.utils.log import logger
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class JSONReader(Reader):
|
|
11
|
-
"""Reader for JSON files"""
|
|
12
|
-
|
|
13
|
-
chunk: bool = False
|
|
14
|
-
|
|
15
|
-
def read(self, path: Path) -> List[Document]:
|
|
16
|
-
if not path.exists():
|
|
17
|
-
raise FileNotFoundError(f"Could not find file: {path}")
|
|
18
|
-
|
|
19
|
-
try:
|
|
20
|
-
logger.info(f"Reading: {path}")
|
|
21
|
-
json_name = path.name.split(".")[0]
|
|
22
|
-
json_contents = json.loads(path.read_text("utf-8"))
|
|
23
|
-
|
|
24
|
-
if isinstance(json_contents, dict):
|
|
25
|
-
json_contents = [json_contents]
|
|
26
|
-
|
|
27
|
-
documents = [
|
|
28
|
-
Document(
|
|
29
|
-
name=json_name,
|
|
30
|
-
id=f"{json_name}_{page_number}",
|
|
31
|
-
meta_data={"page": page_number},
|
|
32
|
-
content=json.dumps(content),
|
|
33
|
-
)
|
|
34
|
-
for page_number, content in enumerate(json_contents, start=1)
|
|
35
|
-
]
|
|
36
|
-
if self.chunk:
|
|
37
|
-
chunked_documents = []
|
|
38
|
-
for document in documents:
|
|
39
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
40
|
-
return chunked_documents
|
|
41
|
-
return documents
|
|
42
|
-
except Exception:
|
|
43
|
-
raise
|
|
@@ -1,219 +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
|
-
try:
|
|
9
|
-
from pypdf import PdfReader as DocumentReader # noqa: F401
|
|
10
|
-
except ImportError:
|
|
11
|
-
raise ImportError("`pypdf` not installed. Please install it via `pip install pypdf`.")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class PDFReader(Reader):
|
|
15
|
-
"""Reader for PDF files"""
|
|
16
|
-
|
|
17
|
-
def read(self, pdf: Union[str, Path, IO[Any]]) -> List[Document]:
|
|
18
|
-
doc_name = ""
|
|
19
|
-
try:
|
|
20
|
-
if isinstance(pdf, str):
|
|
21
|
-
doc_name = pdf.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
22
|
-
else:
|
|
23
|
-
doc_name = pdf.name.split(".")[0]
|
|
24
|
-
except Exception:
|
|
25
|
-
doc_name = "pdf"
|
|
26
|
-
|
|
27
|
-
logger.info(f"Reading: {doc_name}")
|
|
28
|
-
doc_reader = DocumentReader(pdf)
|
|
29
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
class PDFUrlReader(Reader):
|
|
48
|
-
"""Reader for PDF files from URL"""
|
|
49
|
-
|
|
50
|
-
def read(self, url: str) -> List[Document]:
|
|
51
|
-
if not url:
|
|
52
|
-
raise ValueError("No url provided")
|
|
53
|
-
|
|
54
|
-
from io import BytesIO
|
|
55
|
-
|
|
56
|
-
try:
|
|
57
|
-
import httpx
|
|
58
|
-
except ImportError:
|
|
59
|
-
raise ImportError("`httpx` not installed. Please install it via `pip install httpx`.")
|
|
60
|
-
|
|
61
|
-
logger.info(f"Reading: {url}")
|
|
62
|
-
response = httpx.get(url)
|
|
63
|
-
|
|
64
|
-
try:
|
|
65
|
-
response.raise_for_status()
|
|
66
|
-
except httpx.HTTPStatusError as e:
|
|
67
|
-
logger.error(f"HTTP error occurred: {e.response.status_code} - {e.response.text}")
|
|
68
|
-
raise
|
|
69
|
-
|
|
70
|
-
doc_name = url.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
71
|
-
doc_reader = DocumentReader(BytesIO(response.content))
|
|
72
|
-
|
|
73
|
-
documents = [
|
|
74
|
-
Document(
|
|
75
|
-
name=doc_name,
|
|
76
|
-
id=f"{doc_name}_{page_number}",
|
|
77
|
-
meta_data={"page": page_number},
|
|
78
|
-
content=page.extract_text(),
|
|
79
|
-
)
|
|
80
|
-
for page_number, page in enumerate(doc_reader.pages, start=1)
|
|
81
|
-
]
|
|
82
|
-
if self.chunk:
|
|
83
|
-
chunked_documents = []
|
|
84
|
-
for document in documents:
|
|
85
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
86
|
-
return chunked_documents
|
|
87
|
-
return documents
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class PDFImageReader(Reader):
|
|
91
|
-
"""Reader for PDF files with text and images extraction"""
|
|
92
|
-
|
|
93
|
-
def read(self, pdf: Union[str, Path, IO[Any]]) -> List[Document]:
|
|
94
|
-
if not pdf:
|
|
95
|
-
raise ValueError("No pdf provided")
|
|
96
|
-
|
|
97
|
-
try:
|
|
98
|
-
import rapidocr_onnxruntime as rapidocr
|
|
99
|
-
except ImportError:
|
|
100
|
-
raise ImportError(
|
|
101
|
-
"`rapidocr_onnxruntime` not installed. Please install it via `pip install rapidocr_onnxruntime`."
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
doc_name = ""
|
|
105
|
-
try:
|
|
106
|
-
if isinstance(pdf, str):
|
|
107
|
-
doc_name = pdf.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
108
|
-
else:
|
|
109
|
-
doc_name = pdf.name.split(".")[0]
|
|
110
|
-
except Exception:
|
|
111
|
-
doc_name = "pdf"
|
|
112
|
-
|
|
113
|
-
logger.info(f"Reading: {doc_name}")
|
|
114
|
-
doc_reader = DocumentReader(pdf)
|
|
115
|
-
|
|
116
|
-
# Initialize RapidOCR
|
|
117
|
-
ocr = rapidocr.RapidOCR()
|
|
118
|
-
|
|
119
|
-
documents = []
|
|
120
|
-
for page_number, page in enumerate(doc_reader.pages, start=1):
|
|
121
|
-
page_text = page.extract_text() or ""
|
|
122
|
-
images_text_list: List = []
|
|
123
|
-
|
|
124
|
-
for image_object in page.images:
|
|
125
|
-
image_data = image_object.data
|
|
126
|
-
|
|
127
|
-
# Perform OCR on the image
|
|
128
|
-
ocr_result, elapse = ocr(image_data)
|
|
129
|
-
|
|
130
|
-
# Extract text from OCR result
|
|
131
|
-
if ocr_result:
|
|
132
|
-
images_text_list += [item[1] for item in ocr_result]
|
|
133
|
-
|
|
134
|
-
images_text: str = "\n".join(images_text_list)
|
|
135
|
-
content = page_text + "\n" + images_text
|
|
136
|
-
|
|
137
|
-
documents.append(
|
|
138
|
-
Document(
|
|
139
|
-
name=doc_name,
|
|
140
|
-
id=f"{doc_name}_{page_number}",
|
|
141
|
-
meta_data={"page": page_number},
|
|
142
|
-
content=content,
|
|
143
|
-
)
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
if self.chunk:
|
|
147
|
-
chunked_documents = []
|
|
148
|
-
for document in documents:
|
|
149
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
150
|
-
return chunked_documents
|
|
151
|
-
|
|
152
|
-
return documents
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
class PDFUrlImageReader(Reader):
|
|
156
|
-
"""Reader for PDF files from URL with text and images extraction"""
|
|
157
|
-
|
|
158
|
-
def read(self, url: str) -> List[Document]:
|
|
159
|
-
if not url:
|
|
160
|
-
raise ValueError("No url provided")
|
|
161
|
-
|
|
162
|
-
from io import BytesIO
|
|
163
|
-
|
|
164
|
-
try:
|
|
165
|
-
import httpx
|
|
166
|
-
import rapidocr_onnxruntime as rapidocr
|
|
167
|
-
except ImportError:
|
|
168
|
-
raise ImportError(
|
|
169
|
-
"`httpx`, `rapidocr_onnxruntime` not installed. Please install it via `pip install httpx rapidocr_onnxruntime`."
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
# Read the PDF from the URL
|
|
173
|
-
logger.info(f"Reading: {url}")
|
|
174
|
-
response = httpx.get(url)
|
|
175
|
-
|
|
176
|
-
doc_name = url.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
177
|
-
doc_reader = DocumentReader(BytesIO(response.content))
|
|
178
|
-
|
|
179
|
-
# Initialize RapidOCR
|
|
180
|
-
ocr = rapidocr.RapidOCR()
|
|
181
|
-
|
|
182
|
-
# Process each page of the PDF
|
|
183
|
-
documents = []
|
|
184
|
-
for page_number, page in enumerate(doc_reader.pages, start=1):
|
|
185
|
-
page_text = page.extract_text() or ""
|
|
186
|
-
images_text_list = []
|
|
187
|
-
|
|
188
|
-
# Extract and process images
|
|
189
|
-
for image_object in page.images:
|
|
190
|
-
image_data = image_object.data
|
|
191
|
-
|
|
192
|
-
# Perform OCR on the image
|
|
193
|
-
ocr_result, elapse = ocr(image_data)
|
|
194
|
-
|
|
195
|
-
# Extract text from OCR result
|
|
196
|
-
if ocr_result:
|
|
197
|
-
images_text_list += [item[1] for item in ocr_result]
|
|
198
|
-
|
|
199
|
-
images_text = "\n".join(images_text_list)
|
|
200
|
-
content = page_text + "\n" + images_text
|
|
201
|
-
|
|
202
|
-
# Append the document
|
|
203
|
-
documents.append(
|
|
204
|
-
Document(
|
|
205
|
-
name=doc_name,
|
|
206
|
-
id=f"{doc_name}_{page_number}",
|
|
207
|
-
meta_data={"page": page_number},
|
|
208
|
-
content=content,
|
|
209
|
-
)
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
# Optionally chunk documents
|
|
213
|
-
if self.chunk:
|
|
214
|
-
chunked_documents = []
|
|
215
|
-
for document in documents:
|
|
216
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
217
|
-
return chunked_documents
|
|
218
|
-
|
|
219
|
-
return documents
|