agno 1.8.1__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.
Files changed (580) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2778 -4123
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +9 -64
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1749 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1438 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +888 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1051 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1417 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +10 -10
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +129 -82
  141. agno/models/aws/bedrock.py +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +38 -144
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +84 -46
  158. agno/models/openai/chat.py +121 -23
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +14 -8
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +393 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +65 -28
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +33 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  184. agno/os/router.py +843 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +204 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +413 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +179 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +58 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +163 -0
  201. agno/os/schema.py +892 -0
  202. agno/{app/playground → os}/settings.py +8 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/{response.py → agent.py} +144 -72
  212. agno/run/base.py +44 -58
  213. agno/run/cancel.py +83 -0
  214. agno/run/team.py +133 -77
  215. agno/run/workflow.py +537 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +2961 -4253
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +42 -22
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +18 -13
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +18 -11
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +16 -7
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +61 -61
  252. agno/tools/eleven_labs.py +35 -28
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +29 -29
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +22 -22
  260. agno/tools/function.py +68 -17
  261. agno/tools/giphy.py +22 -10
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +31 -19
  276. agno/tools/mem0.py +18 -12
  277. agno/tools/memori.py +14 -10
  278. agno/tools/mlx_transcribe.py +3 -2
  279. agno/tools/models/azure_openai.py +32 -14
  280. agno/tools/models/gemini.py +58 -31
  281. agno/tools/models/groq.py +29 -20
  282. agno/tools/models/nebius.py +27 -11
  283. agno/tools/models_labs.py +39 -15
  284. agno/tools/moviepy_video.py +7 -6
  285. agno/tools/neo4j.py +10 -8
  286. agno/tools/newspaper.py +7 -2
  287. agno/tools/newspaper4k.py +8 -3
  288. agno/tools/openai.py +57 -26
  289. agno/tools/openbb.py +12 -11
  290. agno/tools/opencv.py +62 -46
  291. agno/tools/openweather.py +14 -12
  292. agno/tools/pandas.py +11 -3
  293. agno/tools/postgres.py +4 -12
  294. agno/tools/pubmed.py +4 -1
  295. agno/tools/python.py +9 -22
  296. agno/tools/reasoning.py +35 -27
  297. agno/tools/reddit.py +11 -26
  298. agno/tools/replicate.py +54 -41
  299. agno/tools/resend.py +4 -1
  300. agno/tools/scrapegraph.py +15 -14
  301. agno/tools/searxng.py +10 -23
  302. agno/tools/serpapi.py +6 -3
  303. agno/tools/serper.py +13 -4
  304. agno/tools/shell.py +9 -2
  305. agno/tools/slack.py +12 -11
  306. agno/tools/sleep.py +3 -2
  307. agno/tools/spider.py +24 -4
  308. agno/tools/sql.py +7 -6
  309. agno/tools/tavily.py +6 -4
  310. agno/tools/telegram.py +12 -4
  311. agno/tools/todoist.py +11 -31
  312. agno/tools/toolkit.py +1 -1
  313. agno/tools/trafilatura.py +22 -6
  314. agno/tools/trello.py +9 -22
  315. agno/tools/twilio.py +10 -3
  316. agno/tools/user_control_flow.py +6 -1
  317. agno/tools/valyu.py +34 -5
  318. agno/tools/visualization.py +19 -28
  319. agno/tools/webbrowser.py +4 -3
  320. agno/tools/webex.py +11 -7
  321. agno/tools/website.py +15 -46
  322. agno/tools/webtools.py +12 -4
  323. agno/tools/whatsapp.py +5 -9
  324. agno/tools/wikipedia.py +20 -13
  325. agno/tools/x.py +14 -13
  326. agno/tools/yfinance.py +13 -40
  327. agno/tools/youtube.py +26 -20
  328. agno/tools/zendesk.py +7 -2
  329. agno/tools/zep.py +10 -7
  330. agno/tools/zoom.py +10 -9
  331. agno/utils/common.py +1 -19
  332. agno/utils/events.py +95 -118
  333. agno/utils/knowledge.py +29 -0
  334. agno/utils/log.py +2 -2
  335. agno/utils/mcp.py +11 -5
  336. agno/utils/media.py +39 -0
  337. agno/utils/message.py +12 -1
  338. agno/utils/models/claude.py +6 -4
  339. agno/utils/models/mistral.py +8 -7
  340. agno/utils/models/schema_utils.py +3 -3
  341. agno/utils/pprint.py +33 -32
  342. agno/utils/print_response/agent.py +779 -0
  343. agno/utils/print_response/team.py +1565 -0
  344. agno/utils/print_response/workflow.py +1451 -0
  345. agno/utils/prompts.py +14 -14
  346. agno/utils/reasoning.py +87 -0
  347. agno/utils/response.py +42 -42
  348. agno/utils/string.py +8 -22
  349. agno/utils/team.py +50 -0
  350. agno/utils/timer.py +2 -2
  351. agno/vectordb/base.py +33 -21
  352. agno/vectordb/cassandra/cassandra.py +287 -23
  353. agno/vectordb/chroma/chromadb.py +482 -59
  354. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  355. agno/vectordb/couchbase/couchbase.py +309 -29
  356. agno/vectordb/lancedb/lance_db.py +360 -21
  357. agno/vectordb/langchaindb/__init__.py +5 -0
  358. agno/vectordb/langchaindb/langchaindb.py +145 -0
  359. agno/vectordb/lightrag/__init__.py +5 -0
  360. agno/vectordb/lightrag/lightrag.py +374 -0
  361. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  362. agno/vectordb/milvus/milvus.py +242 -32
  363. agno/vectordb/mongodb/mongodb.py +200 -24
  364. agno/vectordb/pgvector/pgvector.py +319 -37
  365. agno/vectordb/pineconedb/pineconedb.py +221 -27
  366. agno/vectordb/qdrant/qdrant.py +334 -14
  367. agno/vectordb/singlestore/singlestore.py +286 -29
  368. agno/vectordb/surrealdb/surrealdb.py +187 -7
  369. agno/vectordb/upstashdb/upstashdb.py +342 -26
  370. agno/vectordb/weaviate/weaviate.py +227 -165
  371. agno/workflow/__init__.py +17 -13
  372. agno/workflow/{v2/condition.py → condition.py} +135 -32
  373. agno/workflow/{v2/loop.py → loop.py} +115 -28
  374. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  375. agno/workflow/{v2/router.py → router.py} +133 -32
  376. agno/workflow/{v2/step.py → step.py} +200 -42
  377. agno/workflow/{v2/steps.py → steps.py} +147 -66
  378. agno/workflow/types.py +482 -0
  379. agno/workflow/workflow.py +2394 -696
  380. agno-2.0.0a1.dist-info/METADATA +355 -0
  381. agno-2.0.0a1.dist-info/RECORD +514 -0
  382. agno/agent/metrics.py +0 -107
  383. agno/api/app.py +0 -35
  384. agno/api/playground.py +0 -92
  385. agno/api/schemas/app.py +0 -12
  386. agno/api/schemas/playground.py +0 -22
  387. agno/api/schemas/user.py +0 -35
  388. agno/api/schemas/workspace.py +0 -46
  389. agno/api/user.py +0 -160
  390. agno/api/workflows.py +0 -33
  391. agno/api/workspace.py +0 -175
  392. agno/app/agui/__init__.py +0 -3
  393. agno/app/agui/app.py +0 -17
  394. agno/app/agui/sync_router.py +0 -120
  395. agno/app/base.py +0 -186
  396. agno/app/discord/__init__.py +0 -3
  397. agno/app/fastapi/__init__.py +0 -3
  398. agno/app/fastapi/app.py +0 -107
  399. agno/app/fastapi/async_router.py +0 -457
  400. agno/app/fastapi/sync_router.py +0 -448
  401. agno/app/playground/app.py +0 -228
  402. agno/app/playground/async_router.py +0 -1050
  403. agno/app/playground/deploy.py +0 -249
  404. agno/app/playground/operator.py +0 -183
  405. agno/app/playground/schemas.py +0 -220
  406. agno/app/playground/serve.py +0 -55
  407. agno/app/playground/sync_router.py +0 -1042
  408. agno/app/playground/utils.py +0 -46
  409. agno/app/settings.py +0 -15
  410. agno/app/slack/__init__.py +0 -3
  411. agno/app/slack/app.py +0 -19
  412. agno/app/slack/sync_router.py +0 -92
  413. agno/app/utils.py +0 -54
  414. agno/app/whatsapp/__init__.py +0 -3
  415. agno/app/whatsapp/app.py +0 -15
  416. agno/app/whatsapp/sync_router.py +0 -197
  417. agno/cli/auth_server.py +0 -249
  418. agno/cli/config.py +0 -274
  419. agno/cli/console.py +0 -88
  420. agno/cli/credentials.py +0 -23
  421. agno/cli/entrypoint.py +0 -571
  422. agno/cli/operator.py +0 -357
  423. agno/cli/settings.py +0 -96
  424. agno/cli/ws/ws_cli.py +0 -817
  425. agno/constants.py +0 -13
  426. agno/document/__init__.py +0 -5
  427. agno/document/chunking/semantic.py +0 -45
  428. agno/document/chunking/strategy.py +0 -31
  429. agno/document/reader/__init__.py +0 -5
  430. agno/document/reader/base.py +0 -47
  431. agno/document/reader/docx_reader.py +0 -60
  432. agno/document/reader/gcs/pdf_reader.py +0 -44
  433. agno/document/reader/s3/pdf_reader.py +0 -59
  434. agno/document/reader/s3/text_reader.py +0 -63
  435. agno/document/reader/url_reader.py +0 -59
  436. agno/document/reader/youtube_reader.py +0 -58
  437. agno/embedder/__init__.py +0 -5
  438. agno/embedder/langdb.py +0 -80
  439. agno/embedder/mistral.py +0 -82
  440. agno/embedder/openai.py +0 -78
  441. agno/file/__init__.py +0 -5
  442. agno/file/file.py +0 -16
  443. agno/file/local/csv.py +0 -32
  444. agno/file/local/txt.py +0 -19
  445. agno/infra/app.py +0 -240
  446. agno/infra/base.py +0 -144
  447. agno/infra/context.py +0 -20
  448. agno/infra/db_app.py +0 -52
  449. agno/infra/resource.py +0 -205
  450. agno/infra/resources.py +0 -55
  451. agno/knowledge/agent.py +0 -702
  452. agno/knowledge/arxiv.py +0 -33
  453. agno/knowledge/combined.py +0 -36
  454. agno/knowledge/csv.py +0 -144
  455. agno/knowledge/csv_url.py +0 -124
  456. agno/knowledge/document.py +0 -223
  457. agno/knowledge/docx.py +0 -137
  458. agno/knowledge/firecrawl.py +0 -34
  459. agno/knowledge/gcs/__init__.py +0 -0
  460. agno/knowledge/gcs/base.py +0 -39
  461. agno/knowledge/gcs/pdf.py +0 -125
  462. agno/knowledge/json.py +0 -137
  463. agno/knowledge/langchain.py +0 -71
  464. agno/knowledge/light_rag.py +0 -273
  465. agno/knowledge/llamaindex.py +0 -66
  466. agno/knowledge/markdown.py +0 -154
  467. agno/knowledge/pdf.py +0 -164
  468. agno/knowledge/pdf_bytes.py +0 -42
  469. agno/knowledge/pdf_url.py +0 -148
  470. agno/knowledge/s3/__init__.py +0 -0
  471. agno/knowledge/s3/base.py +0 -64
  472. agno/knowledge/s3/pdf.py +0 -33
  473. agno/knowledge/s3/text.py +0 -34
  474. agno/knowledge/text.py +0 -141
  475. agno/knowledge/url.py +0 -46
  476. agno/knowledge/website.py +0 -179
  477. agno/knowledge/wikipedia.py +0 -32
  478. agno/knowledge/youtube.py +0 -35
  479. agno/memory/agent.py +0 -423
  480. agno/memory/classifier.py +0 -104
  481. agno/memory/db/__init__.py +0 -5
  482. agno/memory/db/base.py +0 -42
  483. agno/memory/db/mongodb.py +0 -189
  484. agno/memory/db/postgres.py +0 -203
  485. agno/memory/db/sqlite.py +0 -193
  486. agno/memory/memory.py +0 -22
  487. agno/memory/row.py +0 -36
  488. agno/memory/summarizer.py +0 -201
  489. agno/memory/summary.py +0 -19
  490. agno/memory/team.py +0 -415
  491. agno/memory/v2/__init__.py +0 -2
  492. agno/memory/v2/db/__init__.py +0 -1
  493. agno/memory/v2/db/base.py +0 -42
  494. agno/memory/v2/db/firestore.py +0 -339
  495. agno/memory/v2/db/mongodb.py +0 -196
  496. agno/memory/v2/db/postgres.py +0 -214
  497. agno/memory/v2/db/redis.py +0 -187
  498. agno/memory/v2/db/schema.py +0 -54
  499. agno/memory/v2/db/sqlite.py +0 -209
  500. agno/memory/v2/manager.py +0 -437
  501. agno/memory/v2/memory.py +0 -1097
  502. agno/memory/v2/schema.py +0 -55
  503. agno/memory/v2/summarizer.py +0 -215
  504. agno/memory/workflow.py +0 -38
  505. agno/models/ollama/tools.py +0 -430
  506. agno/models/qwen/__init__.py +0 -5
  507. agno/playground/__init__.py +0 -10
  508. agno/playground/deploy.py +0 -3
  509. agno/playground/playground.py +0 -3
  510. agno/playground/serve.py +0 -3
  511. agno/playground/settings.py +0 -3
  512. agno/reranker/__init__.py +0 -0
  513. agno/run/v2/__init__.py +0 -0
  514. agno/run/v2/workflow.py +0 -567
  515. agno/storage/__init__.py +0 -0
  516. agno/storage/agent/__init__.py +0 -0
  517. agno/storage/agent/dynamodb.py +0 -1
  518. agno/storage/agent/json.py +0 -1
  519. agno/storage/agent/mongodb.py +0 -1
  520. agno/storage/agent/postgres.py +0 -1
  521. agno/storage/agent/singlestore.py +0 -1
  522. agno/storage/agent/sqlite.py +0 -1
  523. agno/storage/agent/yaml.py +0 -1
  524. agno/storage/base.py +0 -60
  525. agno/storage/dynamodb.py +0 -673
  526. agno/storage/firestore.py +0 -297
  527. agno/storage/gcs_json.py +0 -261
  528. agno/storage/in_memory.py +0 -234
  529. agno/storage/json.py +0 -237
  530. agno/storage/mongodb.py +0 -328
  531. agno/storage/mysql.py +0 -685
  532. agno/storage/postgres.py +0 -682
  533. agno/storage/redis.py +0 -336
  534. agno/storage/session/__init__.py +0 -16
  535. agno/storage/session/agent.py +0 -64
  536. agno/storage/session/team.py +0 -63
  537. agno/storage/session/v2/__init__.py +0 -5
  538. agno/storage/session/workflow.py +0 -61
  539. agno/storage/singlestore.py +0 -606
  540. agno/storage/sqlite.py +0 -646
  541. agno/storage/workflow/__init__.py +0 -0
  542. agno/storage/workflow/mongodb.py +0 -1
  543. agno/storage/workflow/postgres.py +0 -1
  544. agno/storage/workflow/sqlite.py +0 -1
  545. agno/storage/yaml.py +0 -241
  546. agno/tools/thinking.py +0 -73
  547. agno/utils/defaults.py +0 -57
  548. agno/utils/filesystem.py +0 -39
  549. agno/utils/git.py +0 -52
  550. agno/utils/json_io.py +0 -30
  551. agno/utils/load_env.py +0 -19
  552. agno/utils/py_io.py +0 -19
  553. agno/utils/pyproject.py +0 -18
  554. agno/utils/resource_filter.py +0 -31
  555. agno/workflow/v2/__init__.py +0 -21
  556. agno/workflow/v2/types.py +0 -357
  557. agno/workflow/v2/workflow.py +0 -3312
  558. agno/workspace/__init__.py +0 -0
  559. agno/workspace/config.py +0 -325
  560. agno/workspace/enums.py +0 -6
  561. agno/workspace/helpers.py +0 -52
  562. agno/workspace/operator.py +0 -757
  563. agno/workspace/settings.py +0 -158
  564. agno-1.8.1.dist-info/METADATA +0 -982
  565. agno-1.8.1.dist-info/RECORD +0 -566
  566. agno-1.8.1.dist-info/entry_points.txt +0 -3
  567. /agno/{app → db/migrations}/__init__.py +0 -0
  568. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  569. /agno/{cli → integrations}/__init__.py +0 -0
  570. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  571. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  572. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  573. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  574. /agno/{app → os/interfaces}/slack/security.py +0 -0
  575. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  576. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  577. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  578. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  579. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  580. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
@@ -9,10 +9,10 @@ except ImportError:
9
9
  "The `qdrant-client` package is not installed. Please install it via `pip install qdrant-client`."
10
10
  )
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, log_info
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, log_warning
16
16
  from agno.vectordb.base import VectorDb
17
17
  from agno.vectordb.distance import Distance
18
18
  from agno.vectordb.search import SearchType
@@ -78,7 +78,7 @@ class Qdrant(VectorDb):
78
78
 
79
79
  # Embedder for embedding the document contents
80
80
  if embedder is None:
81
- from agno.embedder.openai import OpenAIEmbedder
81
+ from agno.knowledge.embedder.openai import OpenAIEmbedder
82
82
 
83
83
  embedder = OpenAIEmbedder()
84
84
  log_info("Embedder not provided, using OpenAIEmbedder as default.")
@@ -302,7 +302,13 @@ class Qdrant(VectorDb):
302
302
  return len(scroll_result[0]) > 0
303
303
  return False
304
304
 
305
- def insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None, batch_size: int = 10) -> None:
305
+ def insert(
306
+ self,
307
+ content_hash: str,
308
+ documents: List[Document],
309
+ filters: Optional[Dict[str, Any]] = None,
310
+ batch_size: int = 10,
311
+ ) -> None:
306
312
  """
307
313
  Insert documents into the database.
308
314
 
@@ -343,6 +349,8 @@ class Qdrant(VectorDb):
343
349
  "meta_data": document.meta_data,
344
350
  "content": cleaned_content,
345
351
  "usage": document.usage,
352
+ "content_id": document.content_id,
353
+ "content_hash": content_hash,
346
354
  }
347
355
 
348
356
  # Add filters as metadata if provided
@@ -364,7 +372,9 @@ class Qdrant(VectorDb):
364
372
  self.client.upsert(collection_name=self.collection, wait=False, points=points)
365
373
  log_debug(f"Upsert {len(points)} documents")
366
374
 
367
- async def async_insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
375
+ async def async_insert(
376
+ self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
377
+ ) -> None:
368
378
  """
369
379
  Insert documents asynchronously.
370
380
 
@@ -401,6 +411,8 @@ class Qdrant(VectorDb):
401
411
  "meta_data": document.meta_data,
402
412
  "content": cleaned_content,
403
413
  "usage": document.usage,
414
+ "content_id": document.content_id,
415
+ "content_hash": content_hash,
404
416
  }
405
417
 
406
418
  # Add filters as metadata if provided
@@ -426,7 +438,7 @@ class Qdrant(VectorDb):
426
438
  await self.async_client.upsert(collection_name=self.collection, wait=False, points=points)
427
439
  log_debug(f"Upserted {len(points)} documents asynchronously")
428
440
 
429
- def upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
441
+ def upsert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
430
442
  """
431
443
  Upsert documents into the database.
432
444
 
@@ -435,12 +447,16 @@ class Qdrant(VectorDb):
435
447
  filters (Optional[Dict[str, Any]]): Filters to apply while upserting
436
448
  """
437
449
  log_debug("Redirecting the request to insert")
438
- self.insert(documents, filters)
450
+ if self.content_hash_exists(content_hash):
451
+ self._delete_by_content_hash(content_hash)
452
+ self.insert(content_hash=content_hash, documents=documents, filters=filters)
439
453
 
440
- async def async_upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
454
+ async def async_upsert(
455
+ self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
456
+ ) -> None:
441
457
  """Upsert documents asynchronously."""
442
458
  log_debug("Redirecting the async request to async_insert")
443
- await self.async_insert(documents, filters)
459
+ await self.async_insert(content_hash=content_hash, documents=documents, filters=filters)
444
460
 
445
461
  def search(self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None) -> List[Document]:
446
462
  """
@@ -641,7 +657,8 @@ class Qdrant(VectorDb):
641
657
  content=result.payload["content"],
642
658
  embedder=self.embedder,
643
659
  embedding=result.vector, # type: ignore
644
- usage=result.payload["usage"],
660
+ usage=result.payload.get("usage"),
661
+ content_id=result.payload.get("content_id"),
645
662
  )
646
663
  )
647
664
 
@@ -676,6 +693,9 @@ class Qdrant(VectorDb):
676
693
 
677
694
  return None
678
695
 
696
+ def optimize(self) -> None:
697
+ pass
698
+
679
699
  def drop(self) -> None:
680
700
  if self.exists():
681
701
  log_debug(f"Deleting collection: {self.collection}")
@@ -699,12 +719,312 @@ class Qdrant(VectorDb):
699
719
  count_result: models.CountResult = self.client.count(collection_name=self.collection, exact=True)
700
720
  return count_result.count
701
721
 
702
- def optimize(self) -> None:
703
- pass
722
+ def point_exists(self, id: str) -> bool:
723
+ """Check if a point with the given ID exists in the collection."""
724
+ try:
725
+ log_info(f"Checking if point with ID '{id}' (type: {type(id)}) exists in collection '{self.collection}'")
726
+ points = self.client.retrieve(
727
+ collection_name=self.collection, ids=[id], with_payload=False, with_vectors=False
728
+ )
729
+ log_info(f"Retrieved {len(points)} points for ID '{id}'")
730
+ if len(points) > 0:
731
+ log_info(f"Found point with ID: {points[0].id} (type: {type(points[0].id)})")
732
+ return len(points) > 0
733
+ except Exception as e:
734
+ log_info(f"Error checking if point {id} exists: {e}")
735
+ return False
704
736
 
705
737
  def delete(self) -> bool:
706
738
  return self.client.delete_collection(collection_name=self.collection)
707
739
 
740
+ def delete_by_id(self, id: str) -> bool:
741
+ try:
742
+ # Check if point exists before deletion
743
+ if not self.point_exists(id):
744
+ log_warning(f"Point with ID {id} does not exist")
745
+ return True
746
+
747
+ self.client.delete(
748
+ collection_name=self.collection,
749
+ points_selector=models.PointIdsList(points=[id]),
750
+ wait=True, # Wait for the operation to complete
751
+ )
752
+ return True
753
+
754
+ except Exception as e:
755
+ log_info(f"Error deleting point with ID {id}: {e}")
756
+ return False
757
+
758
+ def delete_by_name(self, name: str) -> bool:
759
+ """Delete all points that have the specified name in their payload (precise match)."""
760
+ try:
761
+ log_info(f"Attempting to delete all points with name: {name}")
762
+
763
+ # Create a filter to find all points with the specified name (precise match)
764
+ filter_condition = models.Filter(
765
+ must=[models.FieldCondition(key="name", match=models.MatchValue(value=name))]
766
+ )
767
+
768
+ # First, count how many points will be deleted
769
+ count_result = self.client.count(collection_name=self.collection, count_filter=filter_condition, exact=True)
770
+
771
+ if count_result.count == 0:
772
+ log_warning(f"No points found with name: {name}")
773
+ return True
774
+
775
+ log_info(f"Found {count_result.count} points to delete with name: {name}")
776
+
777
+ # Delete all points matching the filter
778
+ result = self.client.delete(
779
+ collection_name=self.collection,
780
+ points_selector=filter_condition,
781
+ wait=True, # Wait for the operation to complete
782
+ )
783
+
784
+ # Check if the deletion was successful
785
+ if result.status == models.UpdateStatus.COMPLETED:
786
+ log_info(f"Successfully deleted {count_result.count} points with name: {name}")
787
+ return True
788
+ else:
789
+ log_warning(f"Deletion failed for name {name}. Status: {result.status}")
790
+ return False
791
+
792
+ except Exception as e:
793
+ log_warning(f"Error deleting points with name {name}: {e}")
794
+ return False
795
+
796
+ def delete_by_metadata(self, metadata: Dict[str, Any]) -> bool:
797
+ """Delete all points where the given metadata is contained in the meta_data payload field."""
798
+ try:
799
+ log_info(f"Attempting to delete all points with metadata: {metadata}")
800
+
801
+ # Create filter conditions for each metadata key-value pair
802
+ filter_conditions = []
803
+ for key, value in metadata.items():
804
+ # Use the meta_data prefix since that's how metadata is stored in the payload
805
+ filter_conditions.append(
806
+ models.FieldCondition(key=f"meta_data.{key}", match=models.MatchValue(value=value))
807
+ )
808
+
809
+ # Create a filter that requires ALL metadata conditions to match
810
+ filter_condition = models.Filter(must=filter_conditions)
811
+
812
+ # First, count how many points will be deleted
813
+ count_result = self.client.count(collection_name=self.collection, count_filter=filter_condition, exact=True)
814
+
815
+ if count_result.count == 0:
816
+ log_warning(f"No points found with metadata: {metadata}")
817
+ return True
818
+
819
+ log_info(f"Found {count_result.count} points to delete with metadata: {metadata}")
820
+
821
+ # Delete all points matching the filter
822
+ result = self.client.delete(
823
+ collection_name=self.collection,
824
+ points_selector=filter_condition,
825
+ wait=True, # Wait for the operation to complete
826
+ )
827
+
828
+ # Check if the deletion was successful
829
+ if result.status == models.UpdateStatus.COMPLETED:
830
+ log_info(f"Successfully deleted {count_result.count} points with metadata: {metadata}")
831
+ return True
832
+ else:
833
+ log_warning(f"Deletion failed for metadata {metadata}. Status: {result.status}")
834
+ return False
835
+
836
+ except Exception as e:
837
+ log_warning(f"Error deleting points with metadata {metadata}: {e}")
838
+ return False
839
+
840
+ def delete_by_content_id(self, content_id: str) -> bool:
841
+ """Delete all points that have the specified content_id in their payload."""
842
+ try:
843
+ log_info(f"Attempting to delete all points with content_id: {content_id}")
844
+
845
+ # Create a filter to find all points with the specified content_id
846
+ filter_condition = models.Filter(
847
+ must=[models.FieldCondition(key="content_id", match=models.MatchValue(value=content_id))]
848
+ )
849
+
850
+ # First, count how many points will be deleted
851
+ count_result = self.client.count(collection_name=self.collection, count_filter=filter_condition, exact=True)
852
+
853
+ if count_result.count == 0:
854
+ log_warning(f"No points found with content_id: {content_id}")
855
+ return True
856
+
857
+ log_info(f"Found {count_result.count} points to delete with content_id: {content_id}")
858
+
859
+ # Delete all points matching the filter
860
+ result = self.client.delete(
861
+ collection_name=self.collection,
862
+ points_selector=filter_condition,
863
+ wait=True, # Wait for the operation to complete
864
+ )
865
+
866
+ # Check if the deletion was successful
867
+ if result.status == models.UpdateStatus.COMPLETED:
868
+ log_info(f"Successfully deleted {count_result.count} points with content_id: {content_id}")
869
+ return True
870
+ else:
871
+ log_warning(f"Deletion failed for content_id {content_id}. Status: {result.status}")
872
+ return False
873
+
874
+ except Exception as e:
875
+ log_warning(f"Error deleting points with content_id {content_id}: {e}")
876
+ return False
877
+
878
+ def id_exists(self, id: str) -> bool:
879
+ """Check if a point with the given ID exists in the collection.
880
+
881
+ Args:
882
+ id (str): The ID to check.
883
+
884
+ Returns:
885
+ bool: True if the point exists, False otherwise.
886
+ """
887
+ try:
888
+ points = self.client.retrieve(
889
+ collection_name=self.collection, ids=[id], with_payload=False, with_vectors=False
890
+ )
891
+ return len(points) > 0
892
+ except Exception as e:
893
+ log_info(f"Error checking if point {id} exists: {e}")
894
+ return False
895
+
896
+ def content_hash_exists(self, content_hash: str) -> bool:
897
+ """Check if any points with the given content hash exist in the collection.
898
+
899
+ Args:
900
+ content_hash (str): The content hash to check.
901
+
902
+ Returns:
903
+ bool: True if points with the content hash exist, False otherwise.
904
+ """
905
+ try:
906
+ # Create a filter to find points with the specified content_hash
907
+ filter_condition = models.Filter(
908
+ must=[models.FieldCondition(key="content_hash", match=models.MatchValue(value=content_hash))]
909
+ )
910
+
911
+ # Count how many points match the filter
912
+ count_result = self.client.count(collection_name=self.collection, count_filter=filter_condition, exact=True)
913
+ return count_result.count > 0
914
+ except Exception as e:
915
+ log_info(f"Error checking if content_hash {content_hash} exists: {e}")
916
+ return False
917
+
918
+ def _delete_by_content_hash(self, content_hash: str) -> bool:
919
+ """Delete all points that have the specified content_hash in their payload.
920
+
921
+ Args:
922
+ content_hash (str): The content hash to delete.
923
+
924
+ Returns:
925
+ bool: True if points were deleted successfully, False otherwise.
926
+ """
927
+ try:
928
+ log_info(f"Attempting to delete all points with content_hash: {content_hash}")
929
+
930
+ # Create a filter to find all points with the specified content_hash
931
+ filter_condition = models.Filter(
932
+ must=[models.FieldCondition(key="content_hash", match=models.MatchValue(value=content_hash))]
933
+ )
934
+
935
+ # First, count how many points will be deleted
936
+ count_result = self.client.count(collection_name=self.collection, count_filter=filter_condition, exact=True)
937
+
938
+ if count_result.count == 0:
939
+ log_warning(f"No points found with content_hash: {content_hash}")
940
+ return True
941
+
942
+ log_info(f"Found {count_result.count} points to delete with content_hash: {content_hash}")
943
+
944
+ # Delete all points matching the filter
945
+ result = self.client.delete(
946
+ collection_name=self.collection,
947
+ points_selector=filter_condition,
948
+ wait=True, # Wait for the operation to complete
949
+ )
950
+
951
+ # Check if the deletion was successful
952
+ if result.status == models.UpdateStatus.COMPLETED:
953
+ log_info(f"Successfully deleted {count_result.count} points with content_hash: {content_hash}")
954
+ return True
955
+ else:
956
+ log_warning(f"Deletion failed for content_hash {content_hash}. Status: {result.status}")
957
+ return False
958
+
959
+ except Exception as e:
960
+ log_warning(f"Error deleting points with content_hash {content_hash}: {e}")
961
+ return False
962
+
963
+ def update_metadata(self, content_id: str, metadata: Dict[str, Any]) -> None:
964
+ """
965
+ Update the metadata for documents with the given content_id.
966
+
967
+ Args:
968
+ content_id (str): The content ID to update
969
+ metadata (Dict[str, Any]): The metadata to update
970
+ """
971
+ try:
972
+ if not self.client:
973
+ log_error("Client not initialized")
974
+ return
975
+
976
+ # Create filter for content_id
977
+ filter_condition = models.Filter(
978
+ must=[models.FieldCondition(key="content_id", match=models.MatchValue(value=content_id))]
979
+ )
980
+
981
+ # Search for points with the given content_id
982
+ search_result = self.client.scroll(
983
+ collection_name=self.collection,
984
+ scroll_filter=filter_condition,
985
+ limit=10000, # Get all matching points
986
+ with_payload=True,
987
+ with_vectors=False,
988
+ )
989
+
990
+ if not search_result[0]: # search_result is a tuple (points, next_page_offset)
991
+ log_error(f"No documents found with content_id: {content_id}")
992
+ return
993
+
994
+ points = search_result[0]
995
+ update_operations = []
996
+
997
+ # Prepare update operations for each point
998
+ for point in points:
999
+ point_id = point.id
1000
+ current_payload = point.payload or {}
1001
+
1002
+ # Merge existing metadata with new metadata
1003
+ updated_payload = current_payload.copy()
1004
+ updated_payload.update(metadata)
1005
+
1006
+ if "filters" not in updated_payload:
1007
+ updated_payload["filters"] = {}
1008
+ if isinstance(updated_payload["filters"], dict):
1009
+ updated_payload["filters"].update(metadata)
1010
+ else:
1011
+ updated_payload["filters"] = metadata
1012
+
1013
+ # Create set payload operation
1014
+ update_operations.append(models.SetPayload(payload=updated_payload, points=[point_id]))
1015
+
1016
+ # Execute all updates
1017
+ for operation in update_operations:
1018
+ self.client.set_payload(
1019
+ collection_name=self.collection, payload=operation.payload, points=operation.points
1020
+ )
1021
+
1022
+ log_debug(f"Updated metadata for {len(update_operations)} documents with content_id: {content_id}")
1023
+
1024
+ except Exception as e:
1025
+ log_error(f"Error updating metadata for content_id '{content_id}': {e}")
1026
+ raise
1027
+
708
1028
  def close(self) -> None:
709
1029
  """Close the Qdrant client connections."""
710
1030
  if self._client is not None: