agno 1.8.1__py3-none-any.whl → 2.0.0rc1__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 +3181 -4169
- 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 +1411 -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 +142 -43
- 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 +1515 -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 +68 -15
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/knowledge/reader/gcs_reader.py +67 -0
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +36 -9
- agno/{document → knowledge}/reader/pdf_reader.py +79 -21
- agno/knowledge/reader/reader_factory.py +275 -0
- agno/knowledge/reader/s3_reader.py +171 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +84 -0
- agno/knowledge/reader/web_search_reader.py +389 -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/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 +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +347 -287
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/google/gemini.py +100 -42
- 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 +45 -150
- 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 +84 -46
- agno/models/openai/chat.py +121 -23
- 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 +14 -8
- 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 +489 -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 +255 -0
- agno/os/router.py +869 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +208 -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 +436 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +188 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +60 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +168 -0
- agno/os/schema.py +892 -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/{response.py → agent.py} +231 -74
- agno/run/base.py +44 -58
- agno/run/cancel.py +81 -0
- agno/run/team.py +133 -77
- agno/run/workflow.py +537 -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 +2960 -4252
- 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 +42 -22
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +18 -13
- 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 +18 -11
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +16 -7
- 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 +61 -61
- agno/tools/eleven_labs.py +35 -28
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +29 -29
- 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 +22 -10
- 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 +31 -19
- 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 +32 -14
- agno/tools/models/gemini.py +58 -31
- agno/tools/models/groq.py +29 -20
- agno/tools/models/nebius.py +27 -11
- agno/tools/models_labs.py +39 -15
- 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 +57 -26
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +62 -46
- 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 +54 -41
- 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 +95 -118
- agno/utils/gemini.py +31 -1
- agno/utils/knowledge.py +29 -0
- agno/utils/log.py +2 -2
- agno/utils/mcp.py +11 -5
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/claude.py +55 -4
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1565 -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 +454 -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} +200 -42
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2401 -696
- agno-2.0.0rc1.dist-info/METADATA +355 -0
- agno-2.0.0rc1.dist-info/RECORD +516 -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/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/{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.0rc1.dist-info}/WHEEL +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/top_level.txt +0 -0
agno/knowledge/docx.py
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Union
|
|
3
|
-
|
|
4
|
-
from agno.document import Document
|
|
5
|
-
from agno.document.reader.docx_reader import DocxReader
|
|
6
|
-
from agno.knowledge.agent import AgentKnowledge
|
|
7
|
-
from agno.utils.log import log_info, logger
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class DocxKnowledgeBase(AgentKnowledge):
|
|
11
|
-
path: Optional[Union[str, Path, List[Dict[str, Union[str, Dict[str, Any]]]]]] = None
|
|
12
|
-
formats: List[str] = [".doc", ".docx"]
|
|
13
|
-
reader: DocxReader = DocxReader()
|
|
14
|
-
|
|
15
|
-
@property
|
|
16
|
-
def document_lists(self) -> Iterator[List[Document]]:
|
|
17
|
-
"""Iterate over doc/docx files and yield lists of documents."""
|
|
18
|
-
if self.path is None:
|
|
19
|
-
raise ValueError("Path is not set")
|
|
20
|
-
|
|
21
|
-
if isinstance(self.path, list):
|
|
22
|
-
for item in self.path:
|
|
23
|
-
if isinstance(item, dict) and "path" in item:
|
|
24
|
-
# Handle path with metadata
|
|
25
|
-
file_path = item["path"]
|
|
26
|
-
config = item.get("metadata", {})
|
|
27
|
-
_file_path = Path(file_path) # type: ignore
|
|
28
|
-
if self._is_valid_docx(_file_path):
|
|
29
|
-
documents = self.reader.read(file=_file_path)
|
|
30
|
-
if config:
|
|
31
|
-
for doc in documents:
|
|
32
|
-
log_info(f"Adding metadata {config} to document: {doc.name}")
|
|
33
|
-
doc.meta_data.update(config) # type: ignore
|
|
34
|
-
yield documents
|
|
35
|
-
else:
|
|
36
|
-
# Handle single path
|
|
37
|
-
_file_path = Path(self.path)
|
|
38
|
-
if _file_path.is_dir():
|
|
39
|
-
for _file in _file_path.glob("**/*"):
|
|
40
|
-
if self._is_valid_docx(_file):
|
|
41
|
-
yield self.reader.read(file=_file)
|
|
42
|
-
elif self._is_valid_docx(_file_path):
|
|
43
|
-
yield self.reader.read(file=_file_path)
|
|
44
|
-
|
|
45
|
-
def _is_valid_docx(self, path: Path) -> bool:
|
|
46
|
-
"""Helper to check if path is a valid doc/docx file."""
|
|
47
|
-
return path.exists() and path.is_file() and path.suffix in self.formats
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
async def async_document_lists(self) -> AsyncIterator[List[Document]]:
|
|
51
|
-
"""Iterate over doc/docx files and yield lists of documents asynchronously."""
|
|
52
|
-
if self.path is None:
|
|
53
|
-
raise ValueError("Path is not set")
|
|
54
|
-
|
|
55
|
-
if isinstance(self.path, list):
|
|
56
|
-
for item in self.path:
|
|
57
|
-
if isinstance(item, dict) and "path" in item:
|
|
58
|
-
# Handle path with metadata
|
|
59
|
-
file_path = item["path"]
|
|
60
|
-
config = item.get("metadata", {})
|
|
61
|
-
_file_path = Path(file_path) # type: ignore
|
|
62
|
-
if self._is_valid_docx(_file_path):
|
|
63
|
-
documents = await self.reader.async_read(file=_file_path)
|
|
64
|
-
if config:
|
|
65
|
-
for doc in documents:
|
|
66
|
-
log_info(f"Adding metadata {config} to document: {doc.name}")
|
|
67
|
-
doc.meta_data.update(config) # type: ignore
|
|
68
|
-
yield documents
|
|
69
|
-
else:
|
|
70
|
-
# Handle single path
|
|
71
|
-
_file_path = Path(self.path)
|
|
72
|
-
if _file_path.is_dir():
|
|
73
|
-
for _file in _file_path.glob("**/*"):
|
|
74
|
-
if self._is_valid_docx(_file):
|
|
75
|
-
yield await self.reader.async_read(file=_file)
|
|
76
|
-
elif self._is_valid_docx(_file_path):
|
|
77
|
-
yield await self.reader.async_read(file=_file_path)
|
|
78
|
-
|
|
79
|
-
def load_document(
|
|
80
|
-
self,
|
|
81
|
-
path: Union[str, Path],
|
|
82
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
83
|
-
recreate: bool = False,
|
|
84
|
-
upsert: bool = False,
|
|
85
|
-
skip_existing: bool = True,
|
|
86
|
-
) -> None:
|
|
87
|
-
_file_path = Path(path) if isinstance(path, str) else path
|
|
88
|
-
|
|
89
|
-
# Validate file and prepare collection in one step
|
|
90
|
-
if not self.prepare_load(_file_path, self.formats, metadata, recreate):
|
|
91
|
-
return
|
|
92
|
-
|
|
93
|
-
# Read documents
|
|
94
|
-
try:
|
|
95
|
-
documents = self.reader.read(file=_file_path)
|
|
96
|
-
except Exception as e:
|
|
97
|
-
logger.exception(f"Failed to read documents from file {_file_path}: {e}")
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
# Process documents
|
|
101
|
-
self.process_documents(
|
|
102
|
-
documents=documents,
|
|
103
|
-
metadata=metadata,
|
|
104
|
-
upsert=upsert,
|
|
105
|
-
skip_existing=skip_existing,
|
|
106
|
-
source_info=str(_file_path),
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
async def aload_document(
|
|
110
|
-
self,
|
|
111
|
-
path: Union[str, Path],
|
|
112
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
113
|
-
recreate: bool = False,
|
|
114
|
-
upsert: bool = False,
|
|
115
|
-
skip_existing: bool = True,
|
|
116
|
-
) -> None:
|
|
117
|
-
_file_path = Path(path) if isinstance(path, str) else path
|
|
118
|
-
|
|
119
|
-
# Validate file and prepare collection in one step
|
|
120
|
-
if not await self.aprepare_load(_file_path, self.formats, metadata, recreate):
|
|
121
|
-
return
|
|
122
|
-
|
|
123
|
-
# Read documents
|
|
124
|
-
try:
|
|
125
|
-
documents = await self.reader.async_read(file=_file_path)
|
|
126
|
-
except Exception as e:
|
|
127
|
-
logger.exception(f"Failed to read documents from file {_file_path}: {e}")
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
# Process documents
|
|
131
|
-
await self.aprocess_documents(
|
|
132
|
-
documents=documents,
|
|
133
|
-
metadata=metadata,
|
|
134
|
-
upsert=upsert,
|
|
135
|
-
skip_existing=skip_existing,
|
|
136
|
-
source_info=str(_file_path),
|
|
137
|
-
)
|
agno/knowledge/firecrawl.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
from typing import AsyncIterator, Iterator, List
|
|
2
|
-
|
|
3
|
-
from agno.document import Document
|
|
4
|
-
from agno.document.reader.firecrawl_reader import FirecrawlReader
|
|
5
|
-
from agno.knowledge.agent import AgentKnowledge
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class FireCrawlKnowledgeBase(AgentKnowledge):
|
|
9
|
-
urls: List[str] = []
|
|
10
|
-
reader: FirecrawlReader = FirecrawlReader()
|
|
11
|
-
|
|
12
|
-
@property
|
|
13
|
-
def document_lists(self) -> Iterator[List[Document]]:
|
|
14
|
-
"""Scrape urls using FireCrawl and yield lists of documents.
|
|
15
|
-
Each object yielded by the iterator is a list of documents.
|
|
16
|
-
|
|
17
|
-
Returns:
|
|
18
|
-
Iterator[List[Document]]: Iterator yielding list of documents
|
|
19
|
-
"""
|
|
20
|
-
for url in self.urls:
|
|
21
|
-
yield self.reader.read(url=url)
|
|
22
|
-
|
|
23
|
-
@property
|
|
24
|
-
async def async_document_lists(self) -> AsyncIterator[List[Document]]:
|
|
25
|
-
"""Asynchronously scrape urls using FireCrawl and yield lists of documents.
|
|
26
|
-
Each object yielded by the iterator is a list of documents.
|
|
27
|
-
|
|
28
|
-
Returns:
|
|
29
|
-
AsyncIterator[List[Document]]: Async iterator yielding list of documents
|
|
30
|
-
"""
|
|
31
|
-
for url in self.urls:
|
|
32
|
-
documents = await self.reader.async_read(url=url)
|
|
33
|
-
if documents:
|
|
34
|
-
yield documents
|
agno/knowledge/gcs/__init__.py
DELETED
|
File without changes
|
agno/knowledge/gcs/base.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
from typing import AsyncIterator, Iterator, List, Optional
|
|
2
|
-
|
|
3
|
-
from google.cloud import storage
|
|
4
|
-
|
|
5
|
-
from agno.document import Document
|
|
6
|
-
from agno.knowledge.agent import AgentKnowledge
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class GCSKnowledgeBase(AgentKnowledge):
|
|
10
|
-
bucket: Optional[storage.Bucket] = None
|
|
11
|
-
bucket_name: Optional[str] = None
|
|
12
|
-
blob_name: Optional[str] = None
|
|
13
|
-
prefix: Optional[str] = None
|
|
14
|
-
|
|
15
|
-
@property
|
|
16
|
-
def gcs_blobs(self) -> List[storage.Blob]:
|
|
17
|
-
if self.bucket is None and self.bucket_name is None:
|
|
18
|
-
raise ValueError("No bucket or bucket_name provided")
|
|
19
|
-
if self.bucket is not None and self.bucket_name is not None:
|
|
20
|
-
raise ValueError("Provide either bucket or bucket_name")
|
|
21
|
-
if self.bucket_name is not None:
|
|
22
|
-
client = storage.Client()
|
|
23
|
-
self.bucket = client.bucket(self.bucket_name)
|
|
24
|
-
blobs_to_read = []
|
|
25
|
-
if self.blob_name is not None:
|
|
26
|
-
blobs_to_read.append(self.bucket.blob(self.blob_name)) # type: ignore
|
|
27
|
-
elif self.prefix is not None:
|
|
28
|
-
blobs_to_read.extend(self.bucket.list_blobs(prefix=self.prefix)) # type: ignore
|
|
29
|
-
else:
|
|
30
|
-
blobs_to_read.extend(self.bucket.list_blobs()) # type: ignore
|
|
31
|
-
return list(blobs_to_read)
|
|
32
|
-
|
|
33
|
-
@property
|
|
34
|
-
def document_lists(self) -> Iterator[List[Document]]:
|
|
35
|
-
raise NotImplementedError
|
|
36
|
-
|
|
37
|
-
@property
|
|
38
|
-
def async_document_lists(self) -> AsyncIterator[List[Document]]:
|
|
39
|
-
raise NotImplementedError
|
agno/knowledge/gcs/pdf.py
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional
|
|
2
|
-
|
|
3
|
-
from agno.document import Document
|
|
4
|
-
from agno.document.reader.gcs.pdf_reader import GCSPDFReader
|
|
5
|
-
from agno.knowledge.gcs.base import GCSKnowledgeBase
|
|
6
|
-
from agno.utils.log import log_debug, log_info
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class GCSPDFKnowledgeBase(GCSKnowledgeBase):
|
|
10
|
-
reader: GCSPDFReader = GCSPDFReader()
|
|
11
|
-
|
|
12
|
-
@property
|
|
13
|
-
def document_lists(self) -> Iterator[List[Document]]:
|
|
14
|
-
for blob in self.gcs_blobs:
|
|
15
|
-
if blob.name.endswith(".pdf"):
|
|
16
|
-
yield self.reader.read(blob=blob)
|
|
17
|
-
|
|
18
|
-
@property
|
|
19
|
-
async def async_document_lists(self) -> AsyncIterator[List[Document]]:
|
|
20
|
-
for blob in self.gcs_blobs:
|
|
21
|
-
if blob.name.endswith(".pdf"):
|
|
22
|
-
yield await self.reader.async_read(blob=blob)
|
|
23
|
-
|
|
24
|
-
def load(
|
|
25
|
-
self,
|
|
26
|
-
recreate: bool = False,
|
|
27
|
-
upsert: bool = False,
|
|
28
|
-
skip_existing: bool = True,
|
|
29
|
-
) -> None:
|
|
30
|
-
"""Load the knowledge base to the vector db
|
|
31
|
-
Args:
|
|
32
|
-
recreate (bool): If True, recreates the collection in the vector db. Defaults to False.
|
|
33
|
-
upsert (bool): If True, upserts documents to the vector db. Defaults to False.
|
|
34
|
-
skip_existing (bool): If True, skips documents which already exist in the vector db when inserting. Defaults to True.
|
|
35
|
-
"""
|
|
36
|
-
self._load_init(recreate, upsert)
|
|
37
|
-
if self.vector_db is None:
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
log_info("Loading knowledge base")
|
|
41
|
-
num_documents = 0
|
|
42
|
-
for document_list in self.document_lists:
|
|
43
|
-
documents_to_load = document_list
|
|
44
|
-
|
|
45
|
-
# Track metadata for filtering capabilities and collect metadata for filters
|
|
46
|
-
filters_metadata: Optional[Dict[str, Any]] = None
|
|
47
|
-
for doc in document_list:
|
|
48
|
-
if doc.meta_data:
|
|
49
|
-
self._track_metadata_structure(doc.meta_data)
|
|
50
|
-
# Use the first non-None metadata for filters
|
|
51
|
-
if filters_metadata is None:
|
|
52
|
-
filters_metadata = doc.meta_data
|
|
53
|
-
|
|
54
|
-
# Skip processing if no documents in this batch
|
|
55
|
-
if not documents_to_load:
|
|
56
|
-
log_debug("Skipping empty document batch")
|
|
57
|
-
continue
|
|
58
|
-
|
|
59
|
-
# Upsert documents if upsert is True and vector db supports upsert
|
|
60
|
-
if upsert and self.vector_db.upsert_available():
|
|
61
|
-
self.vector_db.upsert(documents=documents_to_load, filters=filters_metadata)
|
|
62
|
-
# Insert documents
|
|
63
|
-
else:
|
|
64
|
-
# Filter out documents which already exist in the vector db
|
|
65
|
-
if skip_existing:
|
|
66
|
-
log_debug("Filtering out existing documents before insertion.")
|
|
67
|
-
documents_to_load = self.filter_existing_documents(document_list)
|
|
68
|
-
|
|
69
|
-
if documents_to_load:
|
|
70
|
-
self.vector_db.insert(documents=documents_to_load, filters=filters_metadata)
|
|
71
|
-
|
|
72
|
-
num_documents += len(documents_to_load)
|
|
73
|
-
log_info(f"Added {num_documents} documents to knowledge base")
|
|
74
|
-
|
|
75
|
-
async def aload(
|
|
76
|
-
self,
|
|
77
|
-
recreate: bool = False,
|
|
78
|
-
upsert: bool = False,
|
|
79
|
-
skip_existing: bool = True,
|
|
80
|
-
) -> None:
|
|
81
|
-
"""Load the knowledge base to the vector db asynchronously
|
|
82
|
-
Args:
|
|
83
|
-
recreate (bool): If True, recreates the collection in the vector db. Defaults to False.
|
|
84
|
-
upsert (bool): If True, upserts documents to the vector db. Defaults to False.
|
|
85
|
-
skip_existing (bool): If True, skips documents which already exist in the vector db when inserting. Defaults to True.
|
|
86
|
-
"""
|
|
87
|
-
await self._aload_init(recreate, upsert)
|
|
88
|
-
if self.vector_db is None:
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
log_info("Loading knowledge base")
|
|
92
|
-
num_documents = 0
|
|
93
|
-
document_iterator = self.async_document_lists
|
|
94
|
-
async for document_list in document_iterator: # type: ignore
|
|
95
|
-
documents_to_load = document_list
|
|
96
|
-
|
|
97
|
-
# Track metadata for filtering capabilities and collect metadata for filters
|
|
98
|
-
filters_metadata: Optional[Dict[str, Any]] = None
|
|
99
|
-
for doc in document_list:
|
|
100
|
-
if doc.meta_data:
|
|
101
|
-
self._track_metadata_structure(doc.meta_data)
|
|
102
|
-
# Use the first non-None metadata for filters
|
|
103
|
-
if filters_metadata is None:
|
|
104
|
-
filters_metadata = doc.meta_data
|
|
105
|
-
|
|
106
|
-
# Skip processing if no documents in this batch
|
|
107
|
-
if not documents_to_load:
|
|
108
|
-
log_debug("Skipping empty document batch")
|
|
109
|
-
continue
|
|
110
|
-
|
|
111
|
-
# Upsert documents if upsert is True and vector db supports upsert
|
|
112
|
-
if upsert and self.vector_db.upsert_available():
|
|
113
|
-
await self.vector_db.async_upsert(documents=documents_to_load, filters=filters_metadata)
|
|
114
|
-
# Insert documents
|
|
115
|
-
else:
|
|
116
|
-
# Filter out documents which already exist in the vector db
|
|
117
|
-
if skip_existing:
|
|
118
|
-
log_debug("Filtering out existing documents before insertion.")
|
|
119
|
-
documents_to_load = await self.async_filter_existing_documents(document_list)
|
|
120
|
-
|
|
121
|
-
if documents_to_load:
|
|
122
|
-
await self.vector_db.async_insert(documents=documents_to_load, filters=filters_metadata)
|
|
123
|
-
|
|
124
|
-
num_documents += len(documents_to_load)
|
|
125
|
-
log_info(f"Added {num_documents} documents to knowledge base")
|
agno/knowledge/json.py
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Union
|
|
3
|
-
|
|
4
|
-
from agno.document import Document
|
|
5
|
-
from agno.document.reader.json_reader import JSONReader
|
|
6
|
-
from agno.knowledge.agent import AgentKnowledge
|
|
7
|
-
from agno.utils.log import log_info, logger
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class JSONKnowledgeBase(AgentKnowledge):
|
|
11
|
-
path: Optional[Union[str, Path, List[Dict[str, Union[str, Dict[str, Any]]]]]] = None
|
|
12
|
-
reader: JSONReader = JSONReader()
|
|
13
|
-
formats: List[str] = [".json"]
|
|
14
|
-
|
|
15
|
-
@property
|
|
16
|
-
def document_lists(self) -> Iterator[List[Document]]:
|
|
17
|
-
"""Iterate over JSON files and yield lists of documents."""
|
|
18
|
-
if self.path is None:
|
|
19
|
-
raise ValueError("Path is not set")
|
|
20
|
-
|
|
21
|
-
if isinstance(self.path, list):
|
|
22
|
-
for item in self.path:
|
|
23
|
-
if isinstance(item, dict) and "path" in item:
|
|
24
|
-
# Handle path with metadata
|
|
25
|
-
file_path = item["path"]
|
|
26
|
-
config = item.get("metadata", {})
|
|
27
|
-
_file_path = Path(file_path) # type: ignore
|
|
28
|
-
if self._is_valid_json(_file_path):
|
|
29
|
-
documents = self.reader.read(path=_file_path)
|
|
30
|
-
if config:
|
|
31
|
-
for doc in documents:
|
|
32
|
-
log_info(f"Adding metadata {config} to document: {doc.name}")
|
|
33
|
-
doc.meta_data.update(config) # type: ignore
|
|
34
|
-
yield documents
|
|
35
|
-
else:
|
|
36
|
-
# Handle single path
|
|
37
|
-
_file_path = Path(self.path)
|
|
38
|
-
if _file_path.is_dir():
|
|
39
|
-
for _file in _file_path.glob("**/*"):
|
|
40
|
-
if self._is_valid_json(_file):
|
|
41
|
-
yield self.reader.read(path=_file)
|
|
42
|
-
elif self._is_valid_json(_file_path):
|
|
43
|
-
yield self.reader.read(path=_file_path)
|
|
44
|
-
|
|
45
|
-
def _is_valid_json(self, path: Path) -> bool:
|
|
46
|
-
"""Helper to check if path is a valid JSON file."""
|
|
47
|
-
return path.exists() and path.is_file() and path.suffix in self.formats
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
async def async_document_lists(self) -> AsyncIterator[List[Document]]:
|
|
51
|
-
"""Iterate over JSON files and yield lists of documents asynchronously."""
|
|
52
|
-
if self.path is None:
|
|
53
|
-
raise ValueError("Path is not set")
|
|
54
|
-
|
|
55
|
-
if isinstance(self.path, list):
|
|
56
|
-
for item in self.path:
|
|
57
|
-
if isinstance(item, dict) and "path" in item:
|
|
58
|
-
# Handle path with metadata
|
|
59
|
-
file_path = item["path"]
|
|
60
|
-
config = item.get("metadata", {})
|
|
61
|
-
_file_path = Path(file_path) # type: ignore
|
|
62
|
-
if self._is_valid_json(_file_path):
|
|
63
|
-
documents = await self.reader.async_read(path=_file_path)
|
|
64
|
-
if config:
|
|
65
|
-
for doc in documents:
|
|
66
|
-
log_info(f"Adding metadata {config} to document: {doc.name}")
|
|
67
|
-
doc.meta_data.update(config) # type: ignore
|
|
68
|
-
yield documents
|
|
69
|
-
else:
|
|
70
|
-
# Handle single path
|
|
71
|
-
_file_path = Path(self.path)
|
|
72
|
-
if _file_path.is_dir():
|
|
73
|
-
for _file in _file_path.glob("**/*"):
|
|
74
|
-
if self._is_valid_json(_file):
|
|
75
|
-
yield await self.reader.async_read(path=_file)
|
|
76
|
-
elif self._is_valid_json(_file_path):
|
|
77
|
-
yield await self.reader.async_read(path=_file_path)
|
|
78
|
-
|
|
79
|
-
def load_document(
|
|
80
|
-
self,
|
|
81
|
-
path: Union[str, Path],
|
|
82
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
83
|
-
recreate: bool = False,
|
|
84
|
-
upsert: bool = False,
|
|
85
|
-
skip_existing: bool = True,
|
|
86
|
-
) -> None:
|
|
87
|
-
_file_path = Path(path) if isinstance(path, str) else path
|
|
88
|
-
|
|
89
|
-
# Validate file and prepare collection in one step
|
|
90
|
-
if not self.prepare_load(_file_path, self.formats, metadata, recreate):
|
|
91
|
-
return
|
|
92
|
-
|
|
93
|
-
# Read documents
|
|
94
|
-
try:
|
|
95
|
-
documents = self.reader.read(path=_file_path)
|
|
96
|
-
except Exception as e:
|
|
97
|
-
logger.exception(f"Failed to read documents from file {_file_path}: {e}")
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
# Process documents
|
|
101
|
-
self.process_documents(
|
|
102
|
-
documents=documents,
|
|
103
|
-
metadata=metadata,
|
|
104
|
-
upsert=upsert,
|
|
105
|
-
skip_existing=skip_existing,
|
|
106
|
-
source_info=str(_file_path),
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
async def aload_document(
|
|
110
|
-
self,
|
|
111
|
-
path: Union[str, Path],
|
|
112
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
113
|
-
recreate: bool = False,
|
|
114
|
-
upsert: bool = False,
|
|
115
|
-
skip_existing: bool = True,
|
|
116
|
-
) -> None:
|
|
117
|
-
_file_path = Path(path) if isinstance(path, str) else path
|
|
118
|
-
|
|
119
|
-
# Validate file and prepare collection in one step
|
|
120
|
-
if not await self.aprepare_load(_file_path, self.formats, metadata, recreate):
|
|
121
|
-
return
|
|
122
|
-
|
|
123
|
-
# Read documents
|
|
124
|
-
try:
|
|
125
|
-
documents = await self.reader.async_read(path=_file_path)
|
|
126
|
-
except Exception as e:
|
|
127
|
-
logger.exception(f"Failed to read documents from file {_file_path}: {e}")
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
# Process documents
|
|
131
|
-
await self.aprocess_documents(
|
|
132
|
-
documents=documents,
|
|
133
|
-
metadata=metadata,
|
|
134
|
-
upsert=upsert,
|
|
135
|
-
skip_existing=skip_existing,
|
|
136
|
-
source_info=str(_file_path),
|
|
137
|
-
)
|
agno/knowledge/langchain.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
2
|
-
|
|
3
|
-
from agno.document import Document
|
|
4
|
-
from agno.knowledge.agent import AgentKnowledge
|
|
5
|
-
from agno.utils.log import log_debug, logger
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class LangChainKnowledgeBase(AgentKnowledge):
|
|
9
|
-
loader: Optional[Callable] = None
|
|
10
|
-
|
|
11
|
-
vectorstore: Optional[Any] = None
|
|
12
|
-
search_kwargs: Optional[dict] = None
|
|
13
|
-
|
|
14
|
-
retriever: Optional[Any] = None
|
|
15
|
-
|
|
16
|
-
def search(
|
|
17
|
-
self, query: str, num_documents: Optional[int] = None, filters: Optional[Dict[str, Any]] = None
|
|
18
|
-
) -> List[Document]:
|
|
19
|
-
"""Returns relevant documents matching the query"""
|
|
20
|
-
|
|
21
|
-
try:
|
|
22
|
-
from langchain_core.documents import Document as LangChainDocument
|
|
23
|
-
from langchain_core.retrievers import BaseRetriever
|
|
24
|
-
except ImportError:
|
|
25
|
-
raise ImportError(
|
|
26
|
-
"The `langchain` package is not installed. Please install it via `pip install langchain`."
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
if self.vectorstore is not None and self.retriever is None:
|
|
30
|
-
log_debug("Creating retriever")
|
|
31
|
-
if self.search_kwargs is None:
|
|
32
|
-
self.search_kwargs = {"k": self.num_documents}
|
|
33
|
-
if filters is not None:
|
|
34
|
-
self.search_kwargs.update(filters)
|
|
35
|
-
self.retriever = self.vectorstore.as_retriever(search_kwargs=self.search_kwargs)
|
|
36
|
-
|
|
37
|
-
if self.retriever is None:
|
|
38
|
-
logger.error("No retriever provided")
|
|
39
|
-
return []
|
|
40
|
-
|
|
41
|
-
if not isinstance(self.retriever, BaseRetriever):
|
|
42
|
-
raise ValueError(f"Retriever is not of type BaseRetriever: {self.retriever}")
|
|
43
|
-
|
|
44
|
-
_num_documents = num_documents or self.num_documents
|
|
45
|
-
log_debug(f"Getting {_num_documents} relevant documents for query: {query}")
|
|
46
|
-
lc_documents: List[LangChainDocument] = self.retriever.invoke(input=query)
|
|
47
|
-
documents = []
|
|
48
|
-
for lc_doc in lc_documents:
|
|
49
|
-
documents.append(
|
|
50
|
-
Document(
|
|
51
|
-
content=lc_doc.page_content,
|
|
52
|
-
meta_data=lc_doc.metadata,
|
|
53
|
-
)
|
|
54
|
-
)
|
|
55
|
-
return documents
|
|
56
|
-
|
|
57
|
-
def load(
|
|
58
|
-
self,
|
|
59
|
-
recreate: bool = False,
|
|
60
|
-
upsert: bool = True,
|
|
61
|
-
skip_existing: bool = True,
|
|
62
|
-
filters: Optional[Dict[str, Any]] = None,
|
|
63
|
-
) -> None:
|
|
64
|
-
if self.loader is None:
|
|
65
|
-
logger.error("No loader provided for LangChainKnowledgeBase")
|
|
66
|
-
return
|
|
67
|
-
self.loader()
|
|
68
|
-
|
|
69
|
-
def exists(self) -> bool:
|
|
70
|
-
logger.warning("LangChainKnowledgeBase.exists() not supported - please check the vectorstore manually.")
|
|
71
|
-
return True
|