agno 1.8.0__py3-none-any.whl → 2.0.0a1__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 +2781 -4126
- agno/api/agent.py +9 -65
- agno/api/api.py +5 -46
- agno/api/evals.py +6 -17
- 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 +9 -64
- 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 +1749 -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 +1438 -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 +888 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1051 -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 +1417 -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 +298 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1720 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +281 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1371 -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 +1722 -0
- agno/db/singlestore/utils.py +327 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1680 -0
- agno/db/sqlite/utils.py +269 -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 +10 -10
- 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/media.py +2 -2
- 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 +129 -82
- 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/dashscope/dashscope.py +14 -5
- agno/models/google/gemini.py +123 -53
- 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 +38 -144
- 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 +135 -27
- agno/models/openai/responses.py +233 -115
- 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 +393 -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 +65 -28
- 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 +33 -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 +30 -0
- agno/os/router.py +843 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +204 -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 +413 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +179 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +58 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +163 -0
- agno/os/schema.py +892 -0
- agno/{app/playground → os}/settings.py +8 -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} +144 -72
- agno/run/base.py +44 -58
- agno/run/cancel.py +83 -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 +2967 -4243
- 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 +71 -18
- 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 +62 -62
- 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 +68 -17
- agno/tools/giphy.py +22 -10
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +46 -62
- 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 +18 -33
- 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 +134 -0
- 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/knowledge.py +29 -0
- agno/utils/location.py +2 -2
- 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 +6 -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/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 +356 -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 +2394 -696
- agno-2.0.0a1.dist-info/METADATA +355 -0
- agno-2.0.0a1.dist-info/RECORD +514 -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 -698
- 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.0.dist-info/METADATA +0 -979
- agno-1.8.0.dist-info/RECORD +0 -565
- agno-1.8.0.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.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import json
|
|
2
3
|
from hashlib import md5
|
|
3
4
|
from typing import Any, Dict, List, Optional
|
|
@@ -8,17 +9,15 @@ try:
|
|
|
8
9
|
from sqlalchemy.inspection import inspect
|
|
9
10
|
from sqlalchemy.orm import Session, sessionmaker
|
|
10
11
|
from sqlalchemy.schema import Column, MetaData, Table
|
|
11
|
-
from sqlalchemy.sql.expression import func, select, text
|
|
12
|
+
from sqlalchemy.sql.expression import func, select, text, update
|
|
12
13
|
from sqlalchemy.types import DateTime
|
|
13
14
|
except ImportError:
|
|
14
15
|
raise ImportError("`sqlalchemy` not installed")
|
|
15
16
|
|
|
16
|
-
from agno.document import Document
|
|
17
|
-
from agno.embedder import Embedder
|
|
18
|
-
from agno.reranker.base import Reranker
|
|
19
|
-
|
|
20
|
-
# from agno.vectordb.singlestore.index import Ivfflat, HNSWFlat
|
|
21
|
-
from agno.utils.log import log_debug, log_info, logger
|
|
17
|
+
from agno.knowledge.document import Document
|
|
18
|
+
from agno.knowledge.embedder import Embedder
|
|
19
|
+
from agno.knowledge.reranker.base import Reranker
|
|
20
|
+
from agno.utils.log import log_debug, log_error, log_info
|
|
22
21
|
from agno.vectordb.base import VectorDb
|
|
23
22
|
from agno.vectordb.distance import Distance
|
|
24
23
|
|
|
@@ -49,7 +48,7 @@ class SingleStore(VectorDb):
|
|
|
49
48
|
self.metadata: MetaData = MetaData(schema=self.schema)
|
|
50
49
|
|
|
51
50
|
if embedder is None:
|
|
52
|
-
from agno.embedder.openai import OpenAIEmbedder
|
|
51
|
+
from agno.knowledge.embedder.openai import OpenAIEmbedder
|
|
53
52
|
|
|
54
53
|
embedder = OpenAIEmbedder()
|
|
55
54
|
log_info("Embedder not provided, using OpenAIEmbedder as default.")
|
|
@@ -81,6 +80,7 @@ class SingleStore(VectorDb):
|
|
|
81
80
|
Column("created_at", DateTime(timezone=True), server_default=text("now()")),
|
|
82
81
|
Column("updated_at", DateTime(timezone=True), onupdate=text("now()")),
|
|
83
82
|
Column("content_hash", mysql.TEXT),
|
|
83
|
+
Column("content_id", mysql.TEXT),
|
|
84
84
|
extend_existing=True,
|
|
85
85
|
)
|
|
86
86
|
|
|
@@ -102,7 +102,8 @@ class SingleStore(VectorDb):
|
|
|
102
102
|
`usage` TEXT,
|
|
103
103
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
104
104
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
105
|
-
content_hash TEXT
|
|
105
|
+
content_hash TEXT,
|
|
106
|
+
content_id TEXT
|
|
106
107
|
);
|
|
107
108
|
""")
|
|
108
109
|
)
|
|
@@ -120,20 +121,18 @@ class SingleStore(VectorDb):
|
|
|
120
121
|
try:
|
|
121
122
|
return inspect(self.db_engine).has_table(self.table.name, schema=self.schema)
|
|
122
123
|
except Exception as e:
|
|
123
|
-
|
|
124
|
+
log_error(e)
|
|
124
125
|
return False
|
|
125
126
|
|
|
126
|
-
def
|
|
127
|
+
def content_hash_exists(self, content_hash: str) -> bool:
|
|
127
128
|
"""
|
|
128
129
|
Validating if the document exists or not
|
|
129
130
|
|
|
130
131
|
Args:
|
|
131
132
|
document (Document): Document to validate
|
|
132
133
|
"""
|
|
133
|
-
columns = [self.table.c.name, self.table.c.content_hash]
|
|
134
134
|
with self.Session.begin() as sess:
|
|
135
|
-
|
|
136
|
-
stmt = select(*columns).where(self.table.c.content_hash == md5(cleaned_content.encode()).hexdigest())
|
|
135
|
+
stmt = select(self.table.c.name).where(self.table.c.content_hash == content_hash)
|
|
137
136
|
result = sess.execute(stmt).first()
|
|
138
137
|
return result is not None
|
|
139
138
|
|
|
@@ -161,7 +160,13 @@ class SingleStore(VectorDb):
|
|
|
161
160
|
result = sess.execute(stmt).first()
|
|
162
161
|
return result is not None
|
|
163
162
|
|
|
164
|
-
def insert(
|
|
163
|
+
def insert(
|
|
164
|
+
self,
|
|
165
|
+
content_hash: str,
|
|
166
|
+
documents: List[Document],
|
|
167
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
168
|
+
batch_size: int = 10,
|
|
169
|
+
) -> None:
|
|
165
170
|
"""
|
|
166
171
|
Insert documents into the table.
|
|
167
172
|
|
|
@@ -175,8 +180,8 @@ class SingleStore(VectorDb):
|
|
|
175
180
|
for document in documents:
|
|
176
181
|
document.embed(embedder=self.embedder)
|
|
177
182
|
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
178
|
-
|
|
179
|
-
_id = document.id or
|
|
183
|
+
record_id = md5(cleaned_content.encode()).hexdigest()
|
|
184
|
+
_id = document.id or record_id
|
|
180
185
|
|
|
181
186
|
meta_data_json = json.dumps(document.meta_data)
|
|
182
187
|
usage_json = json.dumps(document.usage)
|
|
@@ -192,6 +197,7 @@ class SingleStore(VectorDb):
|
|
|
192
197
|
embedding=embeddings,
|
|
193
198
|
usage=usage_json,
|
|
194
199
|
content_hash=content_hash,
|
|
200
|
+
content_id=document.content_id,
|
|
195
201
|
)
|
|
196
202
|
sess.execute(stmt)
|
|
197
203
|
counter += 1
|
|
@@ -204,7 +210,24 @@ class SingleStore(VectorDb):
|
|
|
204
210
|
"""Indicate that upsert functionality is available."""
|
|
205
211
|
return True
|
|
206
212
|
|
|
207
|
-
def upsert(
|
|
213
|
+
def upsert(
|
|
214
|
+
self,
|
|
215
|
+
content_hash: str,
|
|
216
|
+
documents: List[Document],
|
|
217
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
218
|
+
batch_size: int = 20,
|
|
219
|
+
) -> None:
|
|
220
|
+
if self.content_hash_exists(content_hash):
|
|
221
|
+
self._delete_by_content_hash(content_hash)
|
|
222
|
+
self._upsert(content_hash=content_hash, documents=documents, filters=filters, batch_size=batch_size)
|
|
223
|
+
|
|
224
|
+
def _upsert(
|
|
225
|
+
self,
|
|
226
|
+
content_hash: str,
|
|
227
|
+
documents: List[Document],
|
|
228
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
229
|
+
batch_size: int = 20,
|
|
230
|
+
) -> None:
|
|
208
231
|
"""
|
|
209
232
|
Upsert (insert or update) documents in the table.
|
|
210
233
|
|
|
@@ -218,8 +241,8 @@ class SingleStore(VectorDb):
|
|
|
218
241
|
for document in documents:
|
|
219
242
|
document.embed(embedder=self.embedder)
|
|
220
243
|
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
221
|
-
|
|
222
|
-
_id = document.id or
|
|
244
|
+
record_id = md5(cleaned_content.encode()).hexdigest()
|
|
245
|
+
_id = document.id or record_id
|
|
223
246
|
|
|
224
247
|
meta_data_json = json.dumps(document.meta_data)
|
|
225
248
|
usage_json = json.dumps(document.usage)
|
|
@@ -236,6 +259,7 @@ class SingleStore(VectorDb):
|
|
|
236
259
|
embedding=embeddings,
|
|
237
260
|
usage=usage_json,
|
|
238
261
|
content_hash=content_hash,
|
|
262
|
+
content_id=document.content_id,
|
|
239
263
|
)
|
|
240
264
|
.on_duplicate_key_update(
|
|
241
265
|
name=document.name,
|
|
@@ -244,6 +268,7 @@ class SingleStore(VectorDb):
|
|
|
244
268
|
embedding=embeddings,
|
|
245
269
|
usage=usage_json,
|
|
246
270
|
content_hash=content_hash,
|
|
271
|
+
content_id=document.content_id,
|
|
247
272
|
)
|
|
248
273
|
)
|
|
249
274
|
sess.execute(stmt)
|
|
@@ -267,7 +292,7 @@ class SingleStore(VectorDb):
|
|
|
267
292
|
"""
|
|
268
293
|
query_embedding = self.embedder.get_embedding(query)
|
|
269
294
|
if query_embedding is None:
|
|
270
|
-
|
|
295
|
+
log_error(f"Error getting embedding for Query: {query}")
|
|
271
296
|
return []
|
|
272
297
|
|
|
273
298
|
columns = [
|
|
@@ -276,6 +301,7 @@ class SingleStore(VectorDb):
|
|
|
276
301
|
self.table.c.content,
|
|
277
302
|
self.table.c.embedding,
|
|
278
303
|
self.table.c.usage,
|
|
304
|
+
self.table.c.content_id,
|
|
279
305
|
]
|
|
280
306
|
|
|
281
307
|
stmt = select(*columns)
|
|
@@ -326,7 +352,7 @@ class SingleStore(VectorDb):
|
|
|
326
352
|
try:
|
|
327
353
|
embedding_list = json.loads(neighbor.embedding)
|
|
328
354
|
except Exception as e:
|
|
329
|
-
|
|
355
|
+
log_error(f"Error extracting vector: {e}")
|
|
330
356
|
embedding_list = []
|
|
331
357
|
|
|
332
358
|
search_results.append(
|
|
@@ -393,22 +419,178 @@ class SingleStore(VectorDb):
|
|
|
393
419
|
sess.execute(stmt)
|
|
394
420
|
return True
|
|
395
421
|
|
|
422
|
+
def delete_by_id(self, id: str) -> bool:
|
|
423
|
+
"""
|
|
424
|
+
Delete a document by its ID.
|
|
425
|
+
"""
|
|
426
|
+
from sqlalchemy import delete
|
|
427
|
+
|
|
428
|
+
try:
|
|
429
|
+
with self.Session.begin() as sess:
|
|
430
|
+
stmt = delete(self.table).where(self.table.c.id == id)
|
|
431
|
+
result = sess.execute(stmt)
|
|
432
|
+
log_info(f"Deleted {result.rowcount} records with ID {id} from table '{self.table.name}'.")
|
|
433
|
+
return result.rowcount > 0
|
|
434
|
+
except Exception as e:
|
|
435
|
+
log_error(f"Error deleting document with ID {id}: {e}")
|
|
436
|
+
return False
|
|
437
|
+
|
|
438
|
+
def delete_by_content_id(self, content_id: str) -> bool:
|
|
439
|
+
"""
|
|
440
|
+
Delete a document by its content ID.
|
|
441
|
+
"""
|
|
442
|
+
from sqlalchemy import delete
|
|
443
|
+
|
|
444
|
+
try:
|
|
445
|
+
with self.Session.begin() as sess:
|
|
446
|
+
stmt = delete(self.table).where(self.table.c.content_id == content_id)
|
|
447
|
+
result = sess.execute(stmt)
|
|
448
|
+
log_info(
|
|
449
|
+
f"Deleted {result.rowcount} records with content_id {content_id} from table '{self.table.name}'."
|
|
450
|
+
)
|
|
451
|
+
return result.rowcount > 0
|
|
452
|
+
except Exception as e:
|
|
453
|
+
log_error(f"Error deleting document with content_id {content_id}: {e}")
|
|
454
|
+
return False
|
|
455
|
+
|
|
456
|
+
def delete_by_name(self, name: str) -> bool:
|
|
457
|
+
"""
|
|
458
|
+
Delete a document by its name.
|
|
459
|
+
"""
|
|
460
|
+
from sqlalchemy import delete
|
|
461
|
+
|
|
462
|
+
try:
|
|
463
|
+
with self.Session.begin() as sess:
|
|
464
|
+
stmt = delete(self.table).where(self.table.c.name == name)
|
|
465
|
+
result = sess.execute(stmt)
|
|
466
|
+
log_info(f"Deleted {result.rowcount} records with name '{name}' from table '{self.table.name}'.")
|
|
467
|
+
return result.rowcount > 0
|
|
468
|
+
except Exception as e:
|
|
469
|
+
log_error(f"Error deleting document with name {name}: {e}")
|
|
470
|
+
return False
|
|
471
|
+
|
|
472
|
+
def delete_by_metadata(self, metadata: Dict[str, Any]) -> bool:
|
|
473
|
+
"""
|
|
474
|
+
Delete documents by metadata.
|
|
475
|
+
"""
|
|
476
|
+
from sqlalchemy import delete
|
|
477
|
+
|
|
478
|
+
try:
|
|
479
|
+
with self.Session.begin() as sess:
|
|
480
|
+
# Convert metadata to JSON string for comparison
|
|
481
|
+
metadata_json = json.dumps(metadata, sort_keys=True)
|
|
482
|
+
stmt = delete(self.table).where(self.table.c.meta_data == metadata_json)
|
|
483
|
+
result = sess.execute(stmt)
|
|
484
|
+
log_info(f"Deleted {result.rowcount} records with metadata {metadata} from table '{self.table.name}'.")
|
|
485
|
+
return result.rowcount > 0
|
|
486
|
+
except Exception as e:
|
|
487
|
+
log_error(f"Error deleting documents with metadata {metadata}: {e}")
|
|
488
|
+
return False
|
|
489
|
+
|
|
396
490
|
async def async_create(self) -> None:
|
|
397
491
|
raise NotImplementedError(f"Async not supported on {self.__class__.__name__}.")
|
|
398
492
|
|
|
399
|
-
async def
|
|
400
|
-
|
|
493
|
+
async def async_insert(
|
|
494
|
+
self,
|
|
495
|
+
content_hash: str,
|
|
496
|
+
documents: List[Document],
|
|
497
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
498
|
+
) -> None:
|
|
499
|
+
embed_tasks = [document.async_embed(embedder=self.embedder) for document in documents]
|
|
500
|
+
await asyncio.gather(*embed_tasks, return_exceptions=True)
|
|
401
501
|
|
|
402
|
-
|
|
403
|
-
|
|
502
|
+
with self.Session.begin() as sess:
|
|
503
|
+
counter = 0
|
|
504
|
+
for document in documents:
|
|
505
|
+
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
506
|
+
record_id = md5(cleaned_content.encode()).hexdigest()
|
|
507
|
+
_id = document.id or record_id
|
|
404
508
|
|
|
405
|
-
|
|
406
|
-
|
|
509
|
+
meta_data_json = json.dumps(document.meta_data)
|
|
510
|
+
usage_json = json.dumps(document.usage)
|
|
511
|
+
|
|
512
|
+
# Convert embedding list to SingleStore VECTOR format
|
|
513
|
+
embeddings = f"[{','.join(map(str, document.embedding))}]" if document.embedding else None
|
|
514
|
+
|
|
515
|
+
stmt = mysql.insert(self.table).values(
|
|
516
|
+
id=_id,
|
|
517
|
+
name=document.name,
|
|
518
|
+
meta_data=meta_data_json,
|
|
519
|
+
content=cleaned_content,
|
|
520
|
+
embedding=embeddings,
|
|
521
|
+
usage=usage_json,
|
|
522
|
+
content_hash=content_hash,
|
|
523
|
+
content_id=document.content_id,
|
|
524
|
+
)
|
|
525
|
+
sess.execute(stmt)
|
|
526
|
+
counter += 1
|
|
527
|
+
log_debug(f"Inserted document: {document.name} ({document.meta_data})")
|
|
528
|
+
|
|
529
|
+
sess.commit()
|
|
530
|
+
log_debug(f"Committed {counter} documents")
|
|
531
|
+
|
|
532
|
+
async def async_upsert(
|
|
533
|
+
self,
|
|
534
|
+
content_hash: str,
|
|
535
|
+
documents: List[Document],
|
|
536
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
537
|
+
) -> None:
|
|
538
|
+
"""
|
|
539
|
+
Upsert (insert or update) documents in the table.
|
|
540
|
+
|
|
541
|
+
Args:
|
|
542
|
+
documents (List[Document]): List of documents to upsert.
|
|
543
|
+
filters (Optional[Dict[str, Any]]): Optional filters for the upsert.
|
|
544
|
+
batch_size (int): Number of documents to upsert in each batch.
|
|
545
|
+
"""
|
|
546
|
+
embed_tasks = [document.async_embed(embedder=self.embedder) for document in documents]
|
|
547
|
+
await asyncio.gather(*embed_tasks, return_exceptions=True)
|
|
548
|
+
|
|
549
|
+
with self.Session.begin() as sess:
|
|
550
|
+
counter = 0
|
|
551
|
+
for document in documents:
|
|
552
|
+
cleaned_content = document.content.replace("\x00", "\ufffd")
|
|
553
|
+
record_id = md5(cleaned_content.encode()).hexdigest()
|
|
554
|
+
_id = document.id or record_id
|
|
555
|
+
|
|
556
|
+
meta_data_json = json.dumps(document.meta_data)
|
|
557
|
+
usage_json = json.dumps(document.usage)
|
|
558
|
+
|
|
559
|
+
# Convert embedding list to SingleStore VECTOR format
|
|
560
|
+
embeddings = f"[{','.join(map(str, document.embedding))}]" if document.embedding else None
|
|
561
|
+
stmt = (
|
|
562
|
+
mysql.insert(self.table)
|
|
563
|
+
.values(
|
|
564
|
+
id=_id,
|
|
565
|
+
name=document.name,
|
|
566
|
+
meta_data=meta_data_json,
|
|
567
|
+
content=cleaned_content,
|
|
568
|
+
embedding=embeddings,
|
|
569
|
+
usage=usage_json,
|
|
570
|
+
content_hash=content_hash,
|
|
571
|
+
content_id=document.content_id,
|
|
572
|
+
)
|
|
573
|
+
.on_duplicate_key_update(
|
|
574
|
+
name=document.name,
|
|
575
|
+
meta_data=meta_data_json,
|
|
576
|
+
content=cleaned_content,
|
|
577
|
+
embedding=embeddings,
|
|
578
|
+
usage=usage_json,
|
|
579
|
+
content_hash=content_hash,
|
|
580
|
+
content_id=document.content_id,
|
|
581
|
+
)
|
|
582
|
+
)
|
|
583
|
+
sess.execute(stmt)
|
|
584
|
+
counter += 1
|
|
585
|
+
log_debug(f"Upserted document: {document.name} ({document.meta_data})")
|
|
586
|
+
|
|
587
|
+
sess.commit()
|
|
588
|
+
log_debug(f"Committed {counter} documents")
|
|
407
589
|
|
|
408
590
|
async def async_search(
|
|
409
591
|
self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None
|
|
410
592
|
) -> List[Document]:
|
|
411
|
-
|
|
593
|
+
return self.search(query=query, limit=limit, filters=filters)
|
|
412
594
|
|
|
413
595
|
async def async_drop(self) -> None:
|
|
414
596
|
raise NotImplementedError(f"Async not supported on {self.__class__.__name__}.")
|
|
@@ -418,3 +600,78 @@ class SingleStore(VectorDb):
|
|
|
418
600
|
|
|
419
601
|
async def async_name_exists(self, name: str) -> bool:
|
|
420
602
|
raise NotImplementedError(f"Async not supported on {self.__class__.__name__}.")
|
|
603
|
+
|
|
604
|
+
def _delete_by_content_hash(self, content_hash: str) -> bool:
|
|
605
|
+
"""
|
|
606
|
+
Delete documents by their content hash.
|
|
607
|
+
|
|
608
|
+
Args:
|
|
609
|
+
content_hash (str): The content hash to delete.
|
|
610
|
+
|
|
611
|
+
Returns:
|
|
612
|
+
bool: True if documents were deleted, False otherwise.
|
|
613
|
+
"""
|
|
614
|
+
from sqlalchemy import delete
|
|
615
|
+
|
|
616
|
+
try:
|
|
617
|
+
with self.Session.begin() as sess:
|
|
618
|
+
stmt = delete(self.table).where(self.table.c.content_hash == content_hash)
|
|
619
|
+
result = sess.execute(stmt)
|
|
620
|
+
log_info(
|
|
621
|
+
f"Deleted {result.rowcount} records with content_hash '{content_hash}' from table '{self.table.name}'."
|
|
622
|
+
)
|
|
623
|
+
return result.rowcount > 0
|
|
624
|
+
except Exception as e:
|
|
625
|
+
log_error(f"Error deleting documents with content_hash {content_hash}: {e}")
|
|
626
|
+
return False
|
|
627
|
+
|
|
628
|
+
def update_metadata(self, content_id: str, metadata: Dict[str, Any]) -> None:
|
|
629
|
+
"""
|
|
630
|
+
Update the metadata for documents with the given content_id.
|
|
631
|
+
|
|
632
|
+
Args:
|
|
633
|
+
content_id (str): The content ID to update
|
|
634
|
+
metadata (Dict[str, Any]): The metadata to update
|
|
635
|
+
"""
|
|
636
|
+
import json
|
|
637
|
+
|
|
638
|
+
try:
|
|
639
|
+
with self.Session.begin() as sess:
|
|
640
|
+
# Find documents with the given content_id
|
|
641
|
+
stmt = select(self.table).where(self.table.c.content_id == content_id)
|
|
642
|
+
result = sess.execute(stmt)
|
|
643
|
+
|
|
644
|
+
updated_count = 0
|
|
645
|
+
for row in result:
|
|
646
|
+
# Parse existing metadata
|
|
647
|
+
current_metadata = json.loads(row.meta_data) if row.meta_data else {}
|
|
648
|
+
|
|
649
|
+
# Merge existing metadata with new metadata
|
|
650
|
+
updated_metadata = current_metadata.copy()
|
|
651
|
+
updated_metadata.update(metadata)
|
|
652
|
+
|
|
653
|
+
# Also update filters field within the metadata JSON
|
|
654
|
+
if "filters" not in updated_metadata:
|
|
655
|
+
updated_metadata["filters"] = {}
|
|
656
|
+
if isinstance(updated_metadata["filters"], dict):
|
|
657
|
+
updated_metadata["filters"].update(metadata)
|
|
658
|
+
else:
|
|
659
|
+
updated_metadata["filters"] = metadata
|
|
660
|
+
|
|
661
|
+
# Update the document (only meta_data column exists)
|
|
662
|
+
update_stmt = (
|
|
663
|
+
update(self.table)
|
|
664
|
+
.where(self.table.c.id == row.id)
|
|
665
|
+
.values(meta_data=json.dumps(updated_metadata))
|
|
666
|
+
)
|
|
667
|
+
sess.execute(update_stmt)
|
|
668
|
+
updated_count += 1
|
|
669
|
+
|
|
670
|
+
if updated_count == 0:
|
|
671
|
+
log_debug(f"No documents found with content_id: {content_id}")
|
|
672
|
+
else:
|
|
673
|
+
log_debug(f"Updated metadata for {updated_count} documents with content_id: {content_id}")
|
|
674
|
+
|
|
675
|
+
except Exception as e:
|
|
676
|
+
log_error(f"Error updating metadata for content_id '{content_id}': {e}")
|
|
677
|
+
raise
|