agno 1.8.1__py3-none-any.whl → 2.0.0__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 +19 -27
- agno/agent/agent.py +3143 -4170
- agno/api/agent.py +11 -67
- agno/api/api.py +5 -46
- agno/api/evals.py +8 -19
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +11 -66
- 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/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1743 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1432 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +882 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1045 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1416 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +297 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1710 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +280 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1367 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1712 -0
- agno/db/singlestore/utils.py +326 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1676 -0
- agno/db/sqlite/utils.py +268 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +154 -48
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +15 -11
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -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/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1551 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +47 -65
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +58 -9
- agno/{document → knowledge}/reader/pdf_reader.py +71 -126
- agno/knowledge/reader/reader_factory.py +268 -0
- agno/knowledge/reader/s3_reader.py +101 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +128 -0
- agno/knowledge/reader/web_search_reader.py +366 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +269 -268
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +131 -131
- agno/models/aws/bedrock.py +110 -182
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +346 -290
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/google/gemini.py +105 -46
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +46 -151
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +85 -47
- agno/models/openai/chat.py +154 -37
- agno/models/openai/responses.py +178 -105
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +15 -9
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +497 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +77 -33
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +32 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +29 -0
- agno/os/mcp.py +235 -0
- agno/os/router.py +1400 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +393 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +850 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +410 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +178 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +536 -0
- agno/os/schema.py +945 -0
- agno/{app/playground → os}/settings.py +7 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/agent.py +633 -0
- agno/run/base.py +53 -77
- agno/run/cancel.py +81 -0
- agno/run/team.py +243 -96
- agno/run/workflow.py +550 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +3260 -4824
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +43 -23
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +20 -17
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +8 -8
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +22 -12
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +17 -8
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +36 -29
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +30 -30
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +127 -18
- agno/tools/giphy.py +23 -11
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +45 -61
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +19 -34
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +32 -20
- agno/tools/mcp.py +1 -2
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +33 -15
- agno/tools/models/gemini.py +59 -32
- agno/tools/models/groq.py +30 -23
- agno/tools/models/nebius.py +28 -12
- agno/tools/models_labs.py +40 -16
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +10 -8
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +58 -32
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +63 -47
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +55 -42
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +100 -123
- agno/utils/gemini.py +32 -2
- agno/utils/knowledge.py +29 -0
- agno/utils/log.py +54 -4
- agno/utils/mcp.py +68 -10
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +47 -4
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1669 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/streamlit.py +481 -0
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +334 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +207 -49
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2410 -696
- agno-2.0.0.dist-info/METADATA +494 -0
- agno-2.0.0.dist-info/RECORD +515 -0
- agno-2.0.0.dist-info/licenses/LICENSE +201 -0
- agno/agent/metrics.py +0 -107
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1050
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -220
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1042
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- 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 -702
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- 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 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/response.py +0 -467
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- 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/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3312
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.1.dist-info/METADATA +0 -982
- agno-1.8.1.dist-info/RECORD +0 -566
- agno-1.8.1.dist-info/entry_points.txt +0 -3
- agno-1.8.1.dist-info/licenses/LICENSE +0 -375
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0.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,45 +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 `pip install chonkie`")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class SemanticChunking(ChunkingStrategy):
|
|
15
|
-
"""Chunking strategy that splits text into semantic chunks using chonkie"""
|
|
16
|
-
|
|
17
|
-
def __init__(self, embedder: Optional[Embedder] = None, chunk_size: int = 5000, similarity_threshold: float = 0.5):
|
|
18
|
-
self.embedder = embedder or OpenAIEmbedder(id="text-embedding-3-small") # type: ignore
|
|
19
|
-
self.chunk_size = chunk_size
|
|
20
|
-
self.similarity_threshold = similarity_threshold
|
|
21
|
-
self.chunker = SemanticChunker(
|
|
22
|
-
embedding_model=self.embedder.id, # type: ignore
|
|
23
|
-
chunk_size=self.chunk_size,
|
|
24
|
-
threshold=self.similarity_threshold,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
def chunk(self, document: Document) -> List[Document]:
|
|
28
|
-
"""Split document into semantic chunks using chokie"""
|
|
29
|
-
if not document.content:
|
|
30
|
-
return [document]
|
|
31
|
-
|
|
32
|
-
# Use chonkie to split into semantic chunks
|
|
33
|
-
chunks = self.chunker.chunk(self.clean_text(document.content))
|
|
34
|
-
|
|
35
|
-
# Convert chunks to Documents
|
|
36
|
-
chunked_documents: List[Document] = []
|
|
37
|
-
for i, chunk in enumerate(chunks, 1):
|
|
38
|
-
meta_data = document.meta_data.copy()
|
|
39
|
-
meta_data["chunk"] = i
|
|
40
|
-
chunk_id = f"{document.id}_{i}" if document.id else None
|
|
41
|
-
meta_data["chunk_size"] = len(chunk.text)
|
|
42
|
-
|
|
43
|
-
chunked_documents.append(Document(id=chunk_id, name=document.name, meta_data=meta_data, content=chunk.text))
|
|
44
|
-
|
|
45
|
-
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
agno/document/reader/base.py
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from dataclasses import dataclass, field
|
|
3
|
-
from typing import Any, List, Optional
|
|
4
|
-
|
|
5
|
-
from agno.document.base import Document
|
|
6
|
-
from agno.document.chunking.fixed import FixedSizeChunking
|
|
7
|
-
from agno.document.chunking.strategy import ChunkingStrategy
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@dataclass
|
|
11
|
-
class Reader:
|
|
12
|
-
"""Base class for reading documents"""
|
|
13
|
-
|
|
14
|
-
chunk: bool = True
|
|
15
|
-
chunk_size: int = 5000
|
|
16
|
-
separators: List[str] = field(default_factory=lambda: ["\n", "\n\n", "\r", "\r\n", "\n\r", "\t", " ", " "])
|
|
17
|
-
chunking_strategy: Optional[ChunkingStrategy] = None
|
|
18
|
-
|
|
19
|
-
def read(self, obj: Any) -> List[Document]:
|
|
20
|
-
raise NotImplementedError
|
|
21
|
-
|
|
22
|
-
async def async_read(self, obj: Any) -> List[Document]:
|
|
23
|
-
raise NotImplementedError
|
|
24
|
-
|
|
25
|
-
def chunk_document(self, document: Document) -> List[Document]:
|
|
26
|
-
if self.chunking_strategy is None:
|
|
27
|
-
self.chunking_strategy = FixedSizeChunking(chunk_size=self.chunk_size)
|
|
28
|
-
return self.chunking_strategy.chunk(document) # type: ignore
|
|
29
|
-
|
|
30
|
-
async def chunk_documents_async(self, documents: List[Document]) -> List[Document]:
|
|
31
|
-
"""
|
|
32
|
-
Asynchronously chunk a list of documents using the instance's chunk_document method.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
documents: List of documents to be chunked.
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
A flattened list of chunked documents.
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
async def _chunk_document_async(doc: Document) -> List[Document]:
|
|
42
|
-
return await asyncio.to_thread(self.chunk_document, doc)
|
|
43
|
-
|
|
44
|
-
# Process chunking in parallel for all documents
|
|
45
|
-
chunked_lists = await asyncio.gather(*[_chunk_document_async(doc) for doc in documents])
|
|
46
|
-
# Flatten the result
|
|
47
|
-
return [chunk for sublist in chunked_lists for chunk in sublist]
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import IO, Any, List, Union
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
|
|
6
|
-
from agno.document.base import Document
|
|
7
|
-
from agno.document.reader.base import Reader
|
|
8
|
-
from agno.utils.log import log_info, logger
|
|
9
|
-
|
|
10
|
-
try:
|
|
11
|
-
from docx import Document as DocxDocument # type: ignore
|
|
12
|
-
except ImportError:
|
|
13
|
-
raise ImportError("The `python-docx` package is not installed. Please install it via `pip install python-docx`.")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class DocxReader(Reader):
|
|
17
|
-
"""Reader for Doc/Docx files"""
|
|
18
|
-
|
|
19
|
-
def read(self, file: Union[Path, IO[Any]]) -> List[Document]:
|
|
20
|
-
"""Read a docx file and return a list of documents"""
|
|
21
|
-
try:
|
|
22
|
-
if isinstance(file, Path):
|
|
23
|
-
if not file.exists():
|
|
24
|
-
raise FileNotFoundError(f"Could not find file: {file}")
|
|
25
|
-
log_info(f"Reading: {file}")
|
|
26
|
-
docx_document = DocxDocument(str(file))
|
|
27
|
-
doc_name = file.stem
|
|
28
|
-
else:
|
|
29
|
-
log_info(f"Reading uploaded file: {file.name}")
|
|
30
|
-
docx_document = DocxDocument(file)
|
|
31
|
-
doc_name = file.name.split(".")[0]
|
|
32
|
-
|
|
33
|
-
doc_content = "\n\n".join([para.text for para in docx_document.paragraphs])
|
|
34
|
-
|
|
35
|
-
documents = [
|
|
36
|
-
Document(
|
|
37
|
-
name=doc_name,
|
|
38
|
-
id=str(uuid4()),
|
|
39
|
-
content=doc_content,
|
|
40
|
-
)
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
if self.chunk:
|
|
44
|
-
chunked_documents = []
|
|
45
|
-
for document in documents:
|
|
46
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
47
|
-
return chunked_documents
|
|
48
|
-
return documents
|
|
49
|
-
|
|
50
|
-
except Exception as e:
|
|
51
|
-
logger.error(f"Error reading file: {e}")
|
|
52
|
-
return []
|
|
53
|
-
|
|
54
|
-
async def async_read(self, file: Union[Path, IO[Any]]) -> List[Document]:
|
|
55
|
-
"""Asynchronously read a docx file and return a list of documents"""
|
|
56
|
-
try:
|
|
57
|
-
return await asyncio.to_thread(self.read, file)
|
|
58
|
-
except Exception as e:
|
|
59
|
-
logger.error(f"Error reading file asynchronously: {e}")
|
|
60
|
-
return []
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from io import BytesIO
|
|
3
|
-
from typing import List
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
|
|
6
|
-
from agno.document.base import Document
|
|
7
|
-
from agno.document.reader.base import Reader
|
|
8
|
-
from agno.utils.log import log_info
|
|
9
|
-
|
|
10
|
-
try:
|
|
11
|
-
from google.cloud import storage
|
|
12
|
-
except ImportError:
|
|
13
|
-
raise ImportError("`google-cloud-storage` not installed. Please install it via `pip install google-cloud-storage`.")
|
|
14
|
-
|
|
15
|
-
try:
|
|
16
|
-
from pypdf import PdfReader as DocumentReader
|
|
17
|
-
except ImportError:
|
|
18
|
-
raise ImportError("`pypdf` not installed. Please install it via `pip install pypdf`.")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class GCSPDFReader(Reader):
|
|
22
|
-
def read(self, blob: storage.Blob) -> List[Document]:
|
|
23
|
-
log_info(f"Reading: gs://{blob.bucket.name}/{blob.name}")
|
|
24
|
-
data = blob.download_as_bytes()
|
|
25
|
-
doc_name = blob.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
26
|
-
doc_reader = DocumentReader(BytesIO(data))
|
|
27
|
-
documents = [
|
|
28
|
-
Document(
|
|
29
|
-
name=doc_name,
|
|
30
|
-
id=str(uuid4()),
|
|
31
|
-
meta_data={"page": page_number},
|
|
32
|
-
content=page.extract_text(),
|
|
33
|
-
)
|
|
34
|
-
for page_number, page in enumerate(doc_reader.pages, 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
|
-
|
|
43
|
-
async def async_read(self, blob: storage.Blob) -> List[Document]:
|
|
44
|
-
return await asyncio.to_thread(self.read, blob)
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from io import BytesIO
|
|
3
|
-
from typing import List
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
|
|
6
|
-
from agno.document.base import Document
|
|
7
|
-
from agno.document.reader.base import Reader
|
|
8
|
-
from agno.utils.log import log_info
|
|
9
|
-
|
|
10
|
-
try:
|
|
11
|
-
from agno.aws.resource.s3.object import S3Object # type: ignore
|
|
12
|
-
except (ModuleNotFoundError, ImportError):
|
|
13
|
-
raise ImportError("`agno-aws` not installed. Please install using `pip install agno-aws`")
|
|
14
|
-
|
|
15
|
-
try:
|
|
16
|
-
from pypdf import PdfReader as DocumentReader # noqa: F401
|
|
17
|
-
except ImportError:
|
|
18
|
-
raise ImportError("`pypdf` not installed. Please install it via `pip install pypdf`.")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class S3PDFReader(Reader):
|
|
22
|
-
"""Reader for PDF files on S3"""
|
|
23
|
-
|
|
24
|
-
def read(self, s3_object: S3Object) -> List[Document]:
|
|
25
|
-
try:
|
|
26
|
-
log_info(f"Reading: {s3_object.uri}")
|
|
27
|
-
|
|
28
|
-
object_resource = s3_object.get_resource()
|
|
29
|
-
object_body = object_resource.get()["Body"]
|
|
30
|
-
doc_name = s3_object.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
31
|
-
doc_reader = DocumentReader(BytesIO(object_body.read()))
|
|
32
|
-
documents = [
|
|
33
|
-
Document(
|
|
34
|
-
name=doc_name,
|
|
35
|
-
id=str(uuid4()),
|
|
36
|
-
meta_data={"page": page_number},
|
|
37
|
-
content=page.extract_text(),
|
|
38
|
-
)
|
|
39
|
-
for page_number, page in enumerate(doc_reader.pages, start=1)
|
|
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
|
-
except Exception:
|
|
48
|
-
raise
|
|
49
|
-
|
|
50
|
-
async def async_read(self, s3_object: S3Object) -> List[Document]:
|
|
51
|
-
"""Asynchronously read PDF files from S3 by running the synchronous read operation in a thread.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
s3_object (S3Object): The S3 object to read
|
|
55
|
-
|
|
56
|
-
Returns:
|
|
57
|
-
List[Document]: List of documents from the PDF file
|
|
58
|
-
"""
|
|
59
|
-
return await asyncio.to_thread(self.read, s3_object)
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
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 log_debug, log_info, logger
|
|
8
|
-
|
|
9
|
-
try:
|
|
10
|
-
from agno.aws.resource.s3.object import S3Object # type: ignore
|
|
11
|
-
except (ModuleNotFoundError, ImportError):
|
|
12
|
-
raise ImportError("`agno-aws` not installed. Please install using `pip install agno-aws`")
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
import textract # noqa: F401
|
|
16
|
-
except ImportError:
|
|
17
|
-
raise ImportError("`textract` not installed. Please install it via `pip install textract`.")
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class S3TextReader(Reader):
|
|
21
|
-
"""Reader for text files on S3"""
|
|
22
|
-
|
|
23
|
-
def read(self, s3_object: S3Object) -> List[Document]:
|
|
24
|
-
try:
|
|
25
|
-
log_info(f"Reading: {s3_object.uri}")
|
|
26
|
-
|
|
27
|
-
obj_name = s3_object.name.split("/")[-1]
|
|
28
|
-
temporary_file = Path("storage").joinpath(obj_name)
|
|
29
|
-
s3_object.download(temporary_file)
|
|
30
|
-
|
|
31
|
-
log_info(f"Parsing: {temporary_file}")
|
|
32
|
-
doc_name = s3_object.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
33
|
-
doc_content = textract.process(temporary_file)
|
|
34
|
-
documents = [
|
|
35
|
-
Document(
|
|
36
|
-
name=doc_name,
|
|
37
|
-
id=doc_name,
|
|
38
|
-
content=doc_content.decode("utf-8"),
|
|
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
|
-
|
|
47
|
-
log_debug(f"Deleting: {temporary_file}")
|
|
48
|
-
temporary_file.unlink()
|
|
49
|
-
return documents
|
|
50
|
-
except Exception as e:
|
|
51
|
-
logger.error(f"Error reading: {s3_object.uri}: {e}")
|
|
52
|
-
return []
|
|
53
|
-
|
|
54
|
-
async def async_read(self, s3_object: S3Object) -> List[Document]:
|
|
55
|
-
"""Asynchronously read text files from S3 by running the synchronous read operation in a thread.
|
|
56
|
-
|
|
57
|
-
Args:
|
|
58
|
-
s3_object (S3Object): The S3 object to read
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
List[Document]: List of documents from the text file
|
|
62
|
-
"""
|
|
63
|
-
return await asyncio.to_thread(self.read, s3_object)
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
from typing import List, Optional
|
|
2
|
-
from urllib.parse import urlparse
|
|
3
|
-
|
|
4
|
-
import httpx
|
|
5
|
-
|
|
6
|
-
from agno.document.base import Document
|
|
7
|
-
from agno.document.reader.base import Reader
|
|
8
|
-
from agno.utils.http import async_fetch_with_retry, fetch_with_retry
|
|
9
|
-
from agno.utils.log import log_debug
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class URLReader(Reader):
|
|
13
|
-
"""Reader for general URL content"""
|
|
14
|
-
|
|
15
|
-
def __init__(self, proxy: Optional[str] = None, **kwargs):
|
|
16
|
-
super().__init__(**kwargs)
|
|
17
|
-
self.proxy = proxy
|
|
18
|
-
|
|
19
|
-
def read(self, url: str) -> List[Document]:
|
|
20
|
-
if not url:
|
|
21
|
-
raise ValueError("No url provided")
|
|
22
|
-
|
|
23
|
-
log_debug(f"Reading: {url}")
|
|
24
|
-
# Retry the request up to 3 times with exponential backoff
|
|
25
|
-
response = fetch_with_retry(url, proxy=self.proxy)
|
|
26
|
-
|
|
27
|
-
document = self._create_document(url, response.text)
|
|
28
|
-
if self.chunk:
|
|
29
|
-
return self.chunk_document(document)
|
|
30
|
-
return [document]
|
|
31
|
-
|
|
32
|
-
async def async_read(self, url: str) -> List[Document]:
|
|
33
|
-
"""Async version of read method"""
|
|
34
|
-
if not url:
|
|
35
|
-
raise ValueError("No url provided")
|
|
36
|
-
|
|
37
|
-
log_debug(f"Reading async: {url}")
|
|
38
|
-
client_args = {"proxy": self.proxy} if self.proxy else {}
|
|
39
|
-
async with httpx.AsyncClient(**client_args) as client: # type: ignore
|
|
40
|
-
response = await async_fetch_with_retry(url, client=client)
|
|
41
|
-
|
|
42
|
-
document = self._create_document(url, response.text)
|
|
43
|
-
if self.chunk:
|
|
44
|
-
return await self.chunk_documents_async([document])
|
|
45
|
-
return [document]
|
|
46
|
-
|
|
47
|
-
def _create_document(self, url: str, content: str) -> Document:
|
|
48
|
-
"""Helper method to create a document from URL content"""
|
|
49
|
-
parsed_url = urlparse(url)
|
|
50
|
-
doc_name = parsed_url.path.strip("/").replace("/", "_").replace(" ", "_")
|
|
51
|
-
if not doc_name:
|
|
52
|
-
doc_name = parsed_url.netloc
|
|
53
|
-
|
|
54
|
-
return Document(
|
|
55
|
-
name=doc_name,
|
|
56
|
-
id=doc_name,
|
|
57
|
-
meta_data={"url": url},
|
|
58
|
-
content=content,
|
|
59
|
-
)
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
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 log_debug, log_info, logger
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from youtube_transcript_api import YouTubeTranscriptApi
|
|
10
|
-
except ImportError:
|
|
11
|
-
raise ImportError(
|
|
12
|
-
"`youtube_transcript_api` not installed. Please install it via `pip install youtube_transcript_api`."
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class YouTubeReader(Reader):
|
|
17
|
-
"""Reader for YouTube video transcripts"""
|
|
18
|
-
|
|
19
|
-
def read(self, video_url: str) -> List[Document]:
|
|
20
|
-
try:
|
|
21
|
-
# Extract video ID from URL
|
|
22
|
-
video_id = video_url.split("v=")[-1].split("&")[0]
|
|
23
|
-
log_info(f"Reading transcript for video: {video_id}")
|
|
24
|
-
|
|
25
|
-
# Get transcript
|
|
26
|
-
log_debug(f"Fetching transcript for video: {video_id}")
|
|
27
|
-
# Create an instance of YouTubeTranscriptApi
|
|
28
|
-
ytt_api = YouTubeTranscriptApi()
|
|
29
|
-
transcript_data = ytt_api.fetch(video_id)
|
|
30
|
-
|
|
31
|
-
# Combine transcript segments into full text
|
|
32
|
-
transcript_text = ""
|
|
33
|
-
|
|
34
|
-
for segment in transcript_data:
|
|
35
|
-
transcript_text += f"{segment.text} "
|
|
36
|
-
|
|
37
|
-
documents = [
|
|
38
|
-
Document(
|
|
39
|
-
name=f"youtube_{video_id}",
|
|
40
|
-
id=f"youtube_{video_id}",
|
|
41
|
-
meta_data={"video_url": video_url, "video_id": video_id},
|
|
42
|
-
content=transcript_text.strip(),
|
|
43
|
-
)
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
if self.chunk:
|
|
47
|
-
chunked_documents = []
|
|
48
|
-
for document in documents:
|
|
49
|
-
chunked_documents.extend(self.chunk_document(document))
|
|
50
|
-
return chunked_documents
|
|
51
|
-
return documents
|
|
52
|
-
|
|
53
|
-
except Exception as e:
|
|
54
|
-
logger.error(f"Error reading transcript for {video_url}: {e}")
|
|
55
|
-
return []
|
|
56
|
-
|
|
57
|
-
async def async_read(self, video_url: str) -> List[Document]:
|
|
58
|
-
return await asyncio.get_event_loop().run_in_executor(None, self.read, video_url)
|
agno/embedder/__init__.py
DELETED
agno/embedder/langdb.py
DELETED
|
@@ -1,80 +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 OpenAI as OpenAIClient
|
|
11
|
-
from openai.types.create_embedding_response import CreateEmbeddingResponse
|
|
12
|
-
except ImportError:
|
|
13
|
-
raise ImportError("`openai` not installed")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class LangDBEmbedder(Embedder):
|
|
17
|
-
model: str = "text-embedding-ada-002"
|
|
18
|
-
dimensions: int = 1536
|
|
19
|
-
encoding_format: Literal["float", "base64"] = "float"
|
|
20
|
-
user: Optional[str] = None
|
|
21
|
-
api_key: Optional[str] = getenv("LANGDB_API_KEY")
|
|
22
|
-
project_id: Optional[str] = getenv("LANGDB_PROJECT_ID")
|
|
23
|
-
organization: Optional[str] = None
|
|
24
|
-
base_url: Optional[str] = None
|
|
25
|
-
request_params: Optional[Dict[str, Any]] = None
|
|
26
|
-
client_params: Optional[Dict[str, Any]] = None
|
|
27
|
-
openai_client: Optional[OpenAIClient] = None
|
|
28
|
-
|
|
29
|
-
@property
|
|
30
|
-
def client(self) -> OpenAIClient:
|
|
31
|
-
if self.openai_client:
|
|
32
|
-
return self.openai_client
|
|
33
|
-
|
|
34
|
-
if not self.project_id:
|
|
35
|
-
raise ValueError("LANGDB_PROJECT_ID not set in the environment")
|
|
36
|
-
|
|
37
|
-
_client_params: Dict[str, Any] = {}
|
|
38
|
-
if self.api_key:
|
|
39
|
-
_client_params["api_key"] = self.api_key
|
|
40
|
-
if self.organization:
|
|
41
|
-
_client_params["organization"] = self.organization
|
|
42
|
-
|
|
43
|
-
if not self.base_url:
|
|
44
|
-
self.base_url = f"https://api.us-east-1.langdb.ai/{self.project_id}/v1"
|
|
45
|
-
_client_params["base_url"] = self.base_url
|
|
46
|
-
|
|
47
|
-
if self.client_params:
|
|
48
|
-
_client_params.update(self.client_params)
|
|
49
|
-
return OpenAIClient(**_client_params)
|
|
50
|
-
|
|
51
|
-
def response(self, text: str) -> CreateEmbeddingResponse:
|
|
52
|
-
_request_params: Dict[str, Any] = {
|
|
53
|
-
"input": text,
|
|
54
|
-
"model": self.model,
|
|
55
|
-
"encoding_format": self.encoding_format,
|
|
56
|
-
}
|
|
57
|
-
if self.user is not None:
|
|
58
|
-
_request_params["user"] = self.user
|
|
59
|
-
if self.model.startswith("text-embedding-3"):
|
|
60
|
-
_request_params["dimensions"] = self.dimensions
|
|
61
|
-
if self.request_params:
|
|
62
|
-
_request_params.update(self.request_params)
|
|
63
|
-
return self.client.embeddings.create(**_request_params)
|
|
64
|
-
|
|
65
|
-
def get_embedding(self, text: str) -> List[float]:
|
|
66
|
-
response: CreateEmbeddingResponse = self.response(text=text)
|
|
67
|
-
try:
|
|
68
|
-
return response.data[0].embedding
|
|
69
|
-
except Exception as e:
|
|
70
|
-
logger.warning(e)
|
|
71
|
-
return []
|
|
72
|
-
|
|
73
|
-
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
74
|
-
response: CreateEmbeddingResponse = self.response(text=text)
|
|
75
|
-
|
|
76
|
-
embedding = response.data[0].embedding
|
|
77
|
-
usage = response.usage
|
|
78
|
-
if usage:
|
|
79
|
-
return embedding, usage.model_dump()
|
|
80
|
-
return embedding, None
|
agno/embedder/mistral.py
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from os import getenv
|
|
3
|
-
from typing import Any, Dict, List, Optional, Tuple
|
|
4
|
-
|
|
5
|
-
from agno.embedder.base import Embedder
|
|
6
|
-
from agno.utils.log import logger
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from mistralai import Mistral
|
|
10
|
-
from mistralai.models.embeddingresponse import EmbeddingResponse
|
|
11
|
-
except ImportError:
|
|
12
|
-
raise ImportError("`mistralai` not installed")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@dataclass
|
|
16
|
-
class MistralEmbedder(Embedder):
|
|
17
|
-
id: str = "mistral-embed"
|
|
18
|
-
dimensions: int = 1024
|
|
19
|
-
# -*- Request parameters
|
|
20
|
-
request_params: Optional[Dict[str, Any]] = None
|
|
21
|
-
# -*- Client parameters
|
|
22
|
-
api_key: Optional[str] = getenv("MISTRAL_API_KEY")
|
|
23
|
-
endpoint: Optional[str] = None
|
|
24
|
-
max_retries: Optional[int] = None
|
|
25
|
-
timeout: Optional[int] = None
|
|
26
|
-
client_params: Optional[Dict[str, Any]] = None
|
|
27
|
-
# -*- Provide the Mistral Client manually
|
|
28
|
-
mistral_client: Optional[Mistral] = None
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def client(self) -> Mistral:
|
|
32
|
-
if self.mistral_client:
|
|
33
|
-
return self.mistral_client
|
|
34
|
-
|
|
35
|
-
_client_params: Dict[str, Any] = {
|
|
36
|
-
"api_key": self.api_key,
|
|
37
|
-
"endpoint": self.endpoint,
|
|
38
|
-
"max_retries": self.max_retries,
|
|
39
|
-
"timeout": self.timeout,
|
|
40
|
-
}
|
|
41
|
-
_client_params = {k: v for k, v in _client_params.items() if v is not None}
|
|
42
|
-
|
|
43
|
-
if self.client_params:
|
|
44
|
-
_client_params.update(self.client_params)
|
|
45
|
-
|
|
46
|
-
self.mistral_client = Mistral(**_client_params)
|
|
47
|
-
|
|
48
|
-
return self.mistral_client
|
|
49
|
-
|
|
50
|
-
def _response(self, text: str) -> EmbeddingResponse:
|
|
51
|
-
_request_params: Dict[str, Any] = {
|
|
52
|
-
"inputs": text,
|
|
53
|
-
"model": self.id,
|
|
54
|
-
}
|
|
55
|
-
if self.request_params:
|
|
56
|
-
_request_params.update(self.request_params)
|
|
57
|
-
response = self.client.embeddings.create(**_request_params)
|
|
58
|
-
if response is None:
|
|
59
|
-
raise ValueError("Failed to get embedding response")
|
|
60
|
-
return response
|
|
61
|
-
|
|
62
|
-
def get_embedding(self, text: str) -> List[float]:
|
|
63
|
-
try:
|
|
64
|
-
response: EmbeddingResponse = self._response(text=text)
|
|
65
|
-
if response.data and response.data[0].embedding:
|
|
66
|
-
return response.data[0].embedding
|
|
67
|
-
return []
|
|
68
|
-
except Exception as e:
|
|
69
|
-
logger.warning(f"Error getting embedding: {e}")
|
|
70
|
-
return []
|
|
71
|
-
|
|
72
|
-
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Dict[str, Any]]:
|
|
73
|
-
try:
|
|
74
|
-
response: EmbeddingResponse = self._response(text=text)
|
|
75
|
-
embedding: List[float] = (
|
|
76
|
-
response.data[0].embedding if (response.data and response.data[0].embedding) else []
|
|
77
|
-
)
|
|
78
|
-
usage: Dict[str, Any] = response.usage.model_dump() if response.usage else {}
|
|
79
|
-
return embedding, usage
|
|
80
|
-
except Exception as e:
|
|
81
|
-
logger.warning(f"Error getting embedding and usage: {e}")
|
|
82
|
-
return [], {}
|