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/vectordb/milvus/milvus.py
CHANGED
|
@@ -9,10 +9,10 @@ try:
|
|
|
9
9
|
except ImportError:
|
|
10
10
|
raise ImportError("The `pymilvus` package is not installed. Please install it via `pip install pymilvus`.")
|
|
11
11
|
|
|
12
|
-
from agno.document import Document
|
|
13
|
-
from agno.embedder import Embedder
|
|
14
|
-
from agno.reranker.base import Reranker
|
|
15
|
-
from agno.utils.log import log_debug,
|
|
12
|
+
from agno.knowledge.document import Document
|
|
13
|
+
from agno.knowledge.embedder import Embedder
|
|
14
|
+
from agno.knowledge.reranker.base import Reranker
|
|
15
|
+
from agno.utils.log import log_debug, log_error, log_info
|
|
16
16
|
from agno.vectordb.base import VectorDb
|
|
17
17
|
from agno.vectordb.distance import Distance
|
|
18
18
|
from agno.vectordb.search import SearchType
|
|
@@ -66,7 +66,7 @@ class Milvus(VectorDb):
|
|
|
66
66
|
self.collection: str = collection
|
|
67
67
|
|
|
68
68
|
if embedder is None:
|
|
69
|
-
from agno.embedder.openai import OpenAIEmbedder
|
|
69
|
+
from agno.knowledge.embedder.openai import OpenAIEmbedder
|
|
70
70
|
|
|
71
71
|
embedder = OpenAIEmbedder()
|
|
72
72
|
log_info("Embedder not provided, using OpenAIEmbedder as default.")
|
|
@@ -153,6 +153,8 @@ class Milvus(VectorDb):
|
|
|
153
153
|
("id", DataType.VARCHAR, 128, True), # (name, type, max_length, is_primary)
|
|
154
154
|
("name", DataType.VARCHAR, 1000, False),
|
|
155
155
|
("content", DataType.VARCHAR, 65535, False),
|
|
156
|
+
("content_id", DataType.VARCHAR, 1000, False),
|
|
157
|
+
("content_hash", DataType.VARCHAR, 1000, False),
|
|
156
158
|
("text", DataType.VARCHAR, 1000, False),
|
|
157
159
|
("meta_data", DataType.VARCHAR, 65535, False),
|
|
158
160
|
("usage", DataType.VARCHAR, 65535, False),
|
|
@@ -192,7 +194,7 @@ class Milvus(VectorDb):
|
|
|
192
194
|
return index_params
|
|
193
195
|
|
|
194
196
|
def _prepare_document_data(
|
|
195
|
-
self, document: Document, include_vectors: bool = True
|
|
197
|
+
self, content_hash: str, document: Document, include_vectors: bool = True
|
|
196
198
|
) -> Dict[str, Union[str, List[float], Dict[int, float], None]]:
|
|
197
199
|
"""
|
|
198
200
|
Prepare document data for insertion.
|
|
@@ -205,11 +207,6 @@ class Milvus(VectorDb):
|
|
|
205
207
|
Dictionary with document data where values can be strings, vectors (List[float]),
|
|
206
208
|
sparse vectors (Dict[int, float]), or None
|
|
207
209
|
"""
|
|
208
|
-
# Ensure document is embedded if vectors are needed
|
|
209
|
-
if include_vectors and document.embedding is None:
|
|
210
|
-
document.embed(embedder=self.embedder)
|
|
211
|
-
if document.embedding is None:
|
|
212
|
-
raise ValueError(f"Failed to embed document: {document.name}")
|
|
213
210
|
|
|
214
211
|
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
215
212
|
doc_id = md5(cleaned_content.encode()).hexdigest()
|
|
@@ -222,9 +219,11 @@ class Milvus(VectorDb):
|
|
|
222
219
|
"id": doc_id,
|
|
223
220
|
"text": cleaned_content,
|
|
224
221
|
"name": document.name,
|
|
222
|
+
"content_id": document.content_id,
|
|
225
223
|
"meta_data": meta_data_str,
|
|
226
224
|
"content": cleaned_content,
|
|
227
225
|
"usage": usage_str,
|
|
226
|
+
"content_hash": content_hash,
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
if include_vectors:
|
|
@@ -345,7 +344,7 @@ class Milvus(VectorDb):
|
|
|
345
344
|
filter=expr,
|
|
346
345
|
limit=1,
|
|
347
346
|
)
|
|
348
|
-
return len(scroll_result[0]) > 0
|
|
347
|
+
return len(scroll_result) > 0 and len(scroll_result[0]) > 0
|
|
349
348
|
return False
|
|
350
349
|
|
|
351
350
|
def id_exists(self, id: str) -> bool:
|
|
@@ -357,19 +356,56 @@ class Milvus(VectorDb):
|
|
|
357
356
|
return len(collection_points) > 0
|
|
358
357
|
return False
|
|
359
358
|
|
|
360
|
-
def
|
|
361
|
-
"""
|
|
362
|
-
|
|
359
|
+
def content_hash_exists(self, content_hash: str) -> bool:
|
|
360
|
+
"""
|
|
361
|
+
Check if a document with the given content hash exists.
|
|
363
362
|
|
|
363
|
+
Args:
|
|
364
|
+
content_hash (str): The content hash to check.
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
bool: True if a document with the given content hash exists, False otherwise.
|
|
368
|
+
"""
|
|
369
|
+
if self.client:
|
|
370
|
+
expr = f'content_hash == "{content_hash}"'
|
|
371
|
+
scroll_result = self.client.query(
|
|
372
|
+
collection_name=self.collection,
|
|
373
|
+
filter=expr,
|
|
374
|
+
limit=1,
|
|
375
|
+
)
|
|
376
|
+
return len(scroll_result) > 0 and len(scroll_result[0]) > 0
|
|
377
|
+
return False
|
|
378
|
+
|
|
379
|
+
def _delete_by_content_hash(self, content_hash: str) -> bool:
|
|
380
|
+
"""
|
|
381
|
+
Delete documents by content hash.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
content_hash (str): The content hash to delete.
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
bool: True if documents were deleted, False otherwise.
|
|
388
|
+
"""
|
|
389
|
+
if self.client:
|
|
390
|
+
expr = f'content_hash == "{content_hash}"'
|
|
391
|
+
self.client.delete(collection_name=self.collection, filter=expr)
|
|
392
|
+
log_info(f"Deleted documents with content_hash '{content_hash}' from collection '{self.collection}'.")
|
|
393
|
+
return True
|
|
394
|
+
return False
|
|
395
|
+
|
|
396
|
+
def _insert_hybrid_document(self, content_hash: str, document: Document) -> None:
|
|
397
|
+
"""Insert a document with both dense and sparse vectors."""
|
|
398
|
+
data = self._prepare_document_data(content_hash=content_hash, document=document, include_vectors=True)
|
|
399
|
+
document.embed(embedder=self.embedder)
|
|
364
400
|
self.client.insert(
|
|
365
401
|
collection_name=self.collection,
|
|
366
402
|
data=data,
|
|
367
403
|
)
|
|
368
404
|
log_debug(f"Inserted hybrid document: {document.name} ({document.meta_data})")
|
|
369
405
|
|
|
370
|
-
async def _async_insert_hybrid_document(self, document: Document) -> None:
|
|
406
|
+
async def _async_insert_hybrid_document(self, content_hash: str, document: Document) -> None:
|
|
371
407
|
"""Insert a document with both dense and sparse vectors asynchronously."""
|
|
372
|
-
data = self._prepare_document_data(document, include_vectors=True)
|
|
408
|
+
data = self._prepare_document_data(content_hash=content_hash, document=document, include_vectors=True)
|
|
373
409
|
|
|
374
410
|
await self.async_client.insert(
|
|
375
411
|
collection_name=self.collection,
|
|
@@ -377,13 +413,13 @@ class Milvus(VectorDb):
|
|
|
377
413
|
)
|
|
378
414
|
log_debug(f"Inserted hybrid document asynchronously: {document.name} ({document.meta_data})")
|
|
379
415
|
|
|
380
|
-
def insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
|
|
416
|
+
def insert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
|
|
381
417
|
"""Insert documents based on search type."""
|
|
382
418
|
log_debug(f"Inserting {len(documents)} documents")
|
|
383
419
|
|
|
384
420
|
if self.search_type == SearchType.hybrid:
|
|
385
421
|
for document in documents:
|
|
386
|
-
self._insert_hybrid_document(document)
|
|
422
|
+
self._insert_hybrid_document(content_hash=content_hash, document=document)
|
|
387
423
|
else:
|
|
388
424
|
for document in documents:
|
|
389
425
|
document.embed(embedder=self.embedder)
|
|
@@ -398,9 +434,11 @@ class Milvus(VectorDb):
|
|
|
398
434
|
"id": doc_id,
|
|
399
435
|
"vector": document.embedding,
|
|
400
436
|
"name": document.name,
|
|
437
|
+
"content_id": document.content_id,
|
|
401
438
|
"meta_data": meta_data,
|
|
402
439
|
"content": cleaned_content,
|
|
403
440
|
"usage": document.usage,
|
|
441
|
+
"content_hash": content_hash,
|
|
404
442
|
}
|
|
405
443
|
self.client.insert(
|
|
406
444
|
collection_name=self.collection,
|
|
@@ -410,12 +448,19 @@ class Milvus(VectorDb):
|
|
|
410
448
|
|
|
411
449
|
log_info(f"Inserted {len(documents)} documents")
|
|
412
450
|
|
|
413
|
-
async def async_insert(
|
|
451
|
+
async def async_insert(
|
|
452
|
+
self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
|
|
453
|
+
) -> None:
|
|
414
454
|
"""Insert documents asynchronously based on search type."""
|
|
415
|
-
|
|
455
|
+
log_info(f"Inserting {len(documents)} documents asynchronously")
|
|
456
|
+
|
|
457
|
+
embed_tasks = [document.async_embed(embedder=self.embedder) for document in documents]
|
|
458
|
+
await asyncio.gather(*embed_tasks, return_exceptions=True)
|
|
416
459
|
|
|
417
460
|
if self.search_type == SearchType.hybrid:
|
|
418
|
-
await asyncio.gather(
|
|
461
|
+
await asyncio.gather(
|
|
462
|
+
*[self._async_insert_hybrid_document(content_hash=content_hash, document=doc) for doc in documents]
|
|
463
|
+
)
|
|
419
464
|
else:
|
|
420
465
|
|
|
421
466
|
async def process_document(document):
|
|
@@ -431,9 +476,11 @@ class Milvus(VectorDb):
|
|
|
431
476
|
"id": doc_id,
|
|
432
477
|
"vector": document.embedding,
|
|
433
478
|
"name": document.name,
|
|
479
|
+
"content_id": document.content_id,
|
|
434
480
|
"meta_data": meta_data,
|
|
435
481
|
"content": cleaned_content,
|
|
436
482
|
"usage": document.usage,
|
|
483
|
+
"content_hash": content_hash,
|
|
437
484
|
}
|
|
438
485
|
await self.async_client.insert(
|
|
439
486
|
collection_name=self.collection,
|
|
@@ -455,7 +502,7 @@ class Milvus(VectorDb):
|
|
|
455
502
|
"""
|
|
456
503
|
return True
|
|
457
504
|
|
|
458
|
-
def upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
|
|
505
|
+
def upsert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
|
|
459
506
|
"""
|
|
460
507
|
Upsert documents into the database.
|
|
461
508
|
|
|
@@ -468,13 +515,20 @@ class Milvus(VectorDb):
|
|
|
468
515
|
document.embed(embedder=self.embedder)
|
|
469
516
|
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
470
517
|
doc_id = md5(cleaned_content.encode()).hexdigest()
|
|
518
|
+
|
|
519
|
+
meta_data = document.meta_data or {}
|
|
520
|
+
if filters:
|
|
521
|
+
meta_data.update(filters)
|
|
522
|
+
|
|
471
523
|
data = {
|
|
472
524
|
"id": doc_id,
|
|
473
525
|
"vector": document.embedding,
|
|
474
526
|
"name": document.name,
|
|
527
|
+
"content_id": document.content_id,
|
|
475
528
|
"meta_data": document.meta_data,
|
|
476
529
|
"content": cleaned_content,
|
|
477
530
|
"usage": document.usage,
|
|
531
|
+
"content_hash": content_hash,
|
|
478
532
|
}
|
|
479
533
|
self.client.upsert(
|
|
480
534
|
collection_name=self.collection,
|
|
@@ -482,20 +536,26 @@ class Milvus(VectorDb):
|
|
|
482
536
|
)
|
|
483
537
|
log_debug(f"Upserted document: {document.name} ({document.meta_data})")
|
|
484
538
|
|
|
485
|
-
async def async_upsert(
|
|
539
|
+
async def async_upsert(
|
|
540
|
+
self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
|
|
541
|
+
) -> None:
|
|
486
542
|
log_debug(f"Upserting {len(documents)} documents asynchronously")
|
|
487
543
|
|
|
544
|
+
embed_tasks = [document.async_embed(embedder=self.embedder) for document in documents]
|
|
545
|
+
await asyncio.gather(*embed_tasks, return_exceptions=True)
|
|
546
|
+
|
|
488
547
|
async def process_document(document):
|
|
489
|
-
document.embed(embedder=self.embedder)
|
|
490
548
|
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
491
549
|
doc_id = md5(cleaned_content.encode()).hexdigest()
|
|
492
550
|
data = {
|
|
493
551
|
"id": doc_id,
|
|
494
552
|
"vector": document.embedding,
|
|
495
553
|
"name": document.name,
|
|
554
|
+
"content_id": document.content_id,
|
|
496
555
|
"meta_data": document.meta_data,
|
|
497
556
|
"content": cleaned_content,
|
|
498
557
|
"usage": document.usage,
|
|
558
|
+
"content_hash": content_hash,
|
|
499
559
|
}
|
|
500
560
|
await self.async_client.upsert(
|
|
501
561
|
collection_name=self.collection,
|
|
@@ -535,7 +595,7 @@ class Milvus(VectorDb):
|
|
|
535
595
|
|
|
536
596
|
query_embedding = self.embedder.get_embedding(query)
|
|
537
597
|
if query_embedding is None:
|
|
538
|
-
|
|
598
|
+
log_error(f"Error getting embedding for Query: {query}")
|
|
539
599
|
return []
|
|
540
600
|
|
|
541
601
|
results = self.client.search(
|
|
@@ -555,6 +615,7 @@ class Milvus(VectorDb):
|
|
|
555
615
|
name=result["entity"].get("name", None),
|
|
556
616
|
meta_data=result["entity"].get("meta_data", {}),
|
|
557
617
|
content=result["entity"].get("content", ""),
|
|
618
|
+
content_id=result["entity"].get("content_id", None),
|
|
558
619
|
embedder=self.embedder,
|
|
559
620
|
embedding=result["entity"].get("vector", None),
|
|
560
621
|
usage=result["entity"].get("usage", None),
|
|
@@ -572,7 +633,7 @@ class Milvus(VectorDb):
|
|
|
572
633
|
|
|
573
634
|
query_embedding = self.embedder.get_embedding(query)
|
|
574
635
|
if query_embedding is None:
|
|
575
|
-
|
|
636
|
+
log_error(f"Error getting embedding for Query: {query}")
|
|
576
637
|
return []
|
|
577
638
|
|
|
578
639
|
results = await self.async_client.search(
|
|
@@ -592,6 +653,7 @@ class Milvus(VectorDb):
|
|
|
592
653
|
name=result["entity"].get("name", None),
|
|
593
654
|
meta_data=result["entity"].get("meta_data", {}),
|
|
594
655
|
content=result["entity"].get("content", ""),
|
|
656
|
+
content_id=result["entity"].get("content_id", None),
|
|
595
657
|
embedder=self.embedder,
|
|
596
658
|
embedding=result["entity"].get("vector", None),
|
|
597
659
|
usage=result["entity"].get("usage", None),
|
|
@@ -620,11 +682,11 @@ class Milvus(VectorDb):
|
|
|
620
682
|
sparse_vector = self._get_sparse_vector(query)
|
|
621
683
|
|
|
622
684
|
if dense_vector is None:
|
|
623
|
-
|
|
685
|
+
log_error(f"Error getting dense embedding for Query: {query}")
|
|
624
686
|
return []
|
|
625
687
|
|
|
626
688
|
if self._client is None:
|
|
627
|
-
|
|
689
|
+
log_error("Milvus client not initialized")
|
|
628
690
|
return []
|
|
629
691
|
|
|
630
692
|
try:
|
|
@@ -674,6 +736,7 @@ class Milvus(VectorDb):
|
|
|
674
736
|
name=entity.get("name", None),
|
|
675
737
|
meta_data=meta_data, # Now a dictionary
|
|
676
738
|
content=entity.get("content", ""),
|
|
739
|
+
content_id=entity.get("content_id", None),
|
|
677
740
|
embedder=self.embedder,
|
|
678
741
|
embedding=entity.get("dense_vector", None),
|
|
679
742
|
usage=usage, # Now a dictionary or None
|
|
@@ -688,7 +751,7 @@ class Milvus(VectorDb):
|
|
|
688
751
|
return search_results
|
|
689
752
|
|
|
690
753
|
except Exception as e:
|
|
691
|
-
|
|
754
|
+
log_error(f"Error during hybrid search: {e}")
|
|
692
755
|
return []
|
|
693
756
|
|
|
694
757
|
async def async_hybrid_search(
|
|
@@ -712,7 +775,7 @@ class Milvus(VectorDb):
|
|
|
712
775
|
sparse_vector = self._get_sparse_vector(query)
|
|
713
776
|
|
|
714
777
|
if dense_vector is None:
|
|
715
|
-
|
|
778
|
+
log_error(f"Error getting dense embedding for Query: {query}")
|
|
716
779
|
return []
|
|
717
780
|
|
|
718
781
|
try:
|
|
@@ -776,7 +839,7 @@ class Milvus(VectorDb):
|
|
|
776
839
|
return search_results
|
|
777
840
|
|
|
778
841
|
except Exception as e:
|
|
779
|
-
|
|
842
|
+
log_error(f"Error during async hybrid search: {e}")
|
|
780
843
|
return []
|
|
781
844
|
|
|
782
845
|
def drop(self) -> None:
|
|
@@ -818,6 +881,101 @@ class Milvus(VectorDb):
|
|
|
818
881
|
return True
|
|
819
882
|
return False
|
|
820
883
|
|
|
884
|
+
def delete_by_id(self, id: str) -> bool:
|
|
885
|
+
"""
|
|
886
|
+
Delete a document by its ID.
|
|
887
|
+
|
|
888
|
+
Args:
|
|
889
|
+
id (str): The document ID to delete
|
|
890
|
+
|
|
891
|
+
Returns:
|
|
892
|
+
bool: True if document was deleted, False otherwise
|
|
893
|
+
"""
|
|
894
|
+
try:
|
|
895
|
+
log_debug(f"Milvus VectorDB : Deleting document with ID {id}")
|
|
896
|
+
if not self.id_exists(id):
|
|
897
|
+
return False
|
|
898
|
+
|
|
899
|
+
# Delete by ID using Milvus delete operation
|
|
900
|
+
self.client.delete(collection_name=self.collection, ids=[id])
|
|
901
|
+
log_info(f"Deleted document with ID '{id}' from collection '{self.collection}'.")
|
|
902
|
+
return True
|
|
903
|
+
except Exception as e:
|
|
904
|
+
log_info(f"Error deleting document with ID {id}: {e}")
|
|
905
|
+
return False
|
|
906
|
+
|
|
907
|
+
def delete_by_name(self, name: str) -> bool:
|
|
908
|
+
"""
|
|
909
|
+
Delete documents by name.
|
|
910
|
+
|
|
911
|
+
Args:
|
|
912
|
+
name (str): The document name to delete
|
|
913
|
+
|
|
914
|
+
Returns:
|
|
915
|
+
bool: True if documents were deleted, False otherwise
|
|
916
|
+
"""
|
|
917
|
+
try:
|
|
918
|
+
log_debug(f"Milvus VectorDB : Deleting documents with name {name}")
|
|
919
|
+
if not self.name_exists(name):
|
|
920
|
+
return False
|
|
921
|
+
|
|
922
|
+
# Delete by name using Milvus delete operation with filter
|
|
923
|
+
expr = f'name == "{name}"'
|
|
924
|
+
self.client.delete(collection_name=self.collection, filter=expr)
|
|
925
|
+
log_info(f"Deleted documents with name '{name}' from collection '{self.collection}'.")
|
|
926
|
+
return True
|
|
927
|
+
except Exception as e:
|
|
928
|
+
log_info(f"Error deleting documents with name {name}: {e}")
|
|
929
|
+
return False
|
|
930
|
+
|
|
931
|
+
def delete_by_metadata(self, metadata: Dict[str, Any]) -> bool:
|
|
932
|
+
"""
|
|
933
|
+
Delete documents by metadata.
|
|
934
|
+
|
|
935
|
+
Args:
|
|
936
|
+
metadata (Dict[str, Any]): The metadata to match for deletion
|
|
937
|
+
|
|
938
|
+
Returns:
|
|
939
|
+
bool: True if documents were deleted, False otherwise
|
|
940
|
+
"""
|
|
941
|
+
try:
|
|
942
|
+
log_debug(f"Milvus VectorDB : Deleting documents with metadata {metadata}")
|
|
943
|
+
|
|
944
|
+
# Build filter expression for metadata matching
|
|
945
|
+
expr = self._build_expr(metadata)
|
|
946
|
+
if not expr:
|
|
947
|
+
return False
|
|
948
|
+
|
|
949
|
+
# Delete by metadata using Milvus delete operation with filter
|
|
950
|
+
self.client.delete(collection_name=self.collection, filter=expr)
|
|
951
|
+
log_info(f"Deleted documents with metadata '{metadata}' from collection '{self.collection}'.")
|
|
952
|
+
return True
|
|
953
|
+
except Exception as e:
|
|
954
|
+
log_info(f"Error deleting documents with metadata {metadata}: {e}")
|
|
955
|
+
return False
|
|
956
|
+
|
|
957
|
+
def delete_by_content_id(self, content_id: str) -> bool:
|
|
958
|
+
"""
|
|
959
|
+
Delete documents by content ID.
|
|
960
|
+
|
|
961
|
+
Args:
|
|
962
|
+
content_id (str): The content ID to delete
|
|
963
|
+
|
|
964
|
+
Returns:
|
|
965
|
+
bool: True if documents were deleted, False otherwise
|
|
966
|
+
"""
|
|
967
|
+
try:
|
|
968
|
+
log_debug(f"Milvus VectorDB : Deleting documents with content_id {content_id}")
|
|
969
|
+
|
|
970
|
+
# Delete by content_id using Milvus delete operation with filter
|
|
971
|
+
expr = f'content_id == "{content_id}"'
|
|
972
|
+
self.client.delete(collection_name=self.collection, filter=expr)
|
|
973
|
+
log_info(f"Deleted documents with content_id '{content_id}' from collection '{self.collection}'.")
|
|
974
|
+
return True
|
|
975
|
+
except Exception as e:
|
|
976
|
+
log_info(f"Error deleting documents with content_id {content_id}: {e}")
|
|
977
|
+
return False
|
|
978
|
+
|
|
821
979
|
def _build_expr(self, filters: Optional[Dict[str, Any]]) -> Optional[str]:
|
|
822
980
|
"""Build Milvus expression from filters."""
|
|
823
981
|
if not filters:
|
|
@@ -853,3 +1011,55 @@ class Milvus(VectorDb):
|
|
|
853
1011
|
|
|
854
1012
|
def async_name_exists(self, name: str) -> bool:
|
|
855
1013
|
raise NotImplementedError(f"Async not supported on {self.__class__.__name__}.")
|
|
1014
|
+
|
|
1015
|
+
def update_metadata(self, content_id: str, metadata: Dict[str, Any]) -> None:
|
|
1016
|
+
"""
|
|
1017
|
+
Update the metadata for documents with the given content_id.
|
|
1018
|
+
|
|
1019
|
+
Args:
|
|
1020
|
+
content_id (str): The content ID to update
|
|
1021
|
+
metadata (Dict[str, Any]): The metadata to update
|
|
1022
|
+
"""
|
|
1023
|
+
try:
|
|
1024
|
+
# Search for documents with the given content_id
|
|
1025
|
+
search_expr = f'content_id == "{content_id}"'
|
|
1026
|
+
results = self.client.query(
|
|
1027
|
+
collection_name=self.collection, filter=search_expr, output_fields=["id", "meta_data", "filters"]
|
|
1028
|
+
)
|
|
1029
|
+
|
|
1030
|
+
if not results:
|
|
1031
|
+
log_debug(f"No documents found with content_id: {content_id}")
|
|
1032
|
+
return
|
|
1033
|
+
|
|
1034
|
+
# Update each document
|
|
1035
|
+
updated_count = 0
|
|
1036
|
+
for result in results:
|
|
1037
|
+
doc_id = result["id"]
|
|
1038
|
+
current_metadata = result.get("meta_data", {})
|
|
1039
|
+
current_filters = result.get("filters", {})
|
|
1040
|
+
|
|
1041
|
+
# Merge existing metadata with new metadata
|
|
1042
|
+
if isinstance(current_metadata, dict):
|
|
1043
|
+
updated_metadata = current_metadata.copy()
|
|
1044
|
+
updated_metadata.update(metadata)
|
|
1045
|
+
else:
|
|
1046
|
+
updated_metadata = metadata
|
|
1047
|
+
|
|
1048
|
+
if isinstance(current_filters, dict):
|
|
1049
|
+
updated_filters = current_filters.copy()
|
|
1050
|
+
updated_filters.update(metadata)
|
|
1051
|
+
else:
|
|
1052
|
+
updated_filters = metadata
|
|
1053
|
+
|
|
1054
|
+
# Update the document
|
|
1055
|
+
self.client.upsert(
|
|
1056
|
+
collection_name=self.collection,
|
|
1057
|
+
data=[{"id": doc_id, "meta_data": updated_metadata, "filters": updated_filters}],
|
|
1058
|
+
)
|
|
1059
|
+
updated_count += 1
|
|
1060
|
+
|
|
1061
|
+
log_debug(f"Updated metadata for {updated_count} documents with content_id: {content_id}")
|
|
1062
|
+
|
|
1063
|
+
except Exception as e:
|
|
1064
|
+
log_error(f"Error updating metadata for content_id '{content_id}': {e}")
|
|
1065
|
+
raise
|