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.
Files changed (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2781 -4126
  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/media.py +2 -2
  137. agno/memory/__init__.py +2 -10
  138. agno/memory/manager.py +1003 -148
  139. agno/models/aimlapi/__init__.py +2 -2
  140. agno/models/aimlapi/aimlapi.py +6 -6
  141. agno/models/anthropic/claude.py +129 -82
  142. agno/models/aws/bedrock.py +107 -175
  143. agno/models/aws/claude.py +64 -18
  144. agno/models/azure/ai_foundry.py +73 -23
  145. agno/models/base.py +347 -287
  146. agno/models/cerebras/cerebras.py +84 -27
  147. agno/models/cohere/chat.py +106 -98
  148. agno/models/dashscope/dashscope.py +14 -5
  149. agno/models/google/gemini.py +123 -53
  150. agno/models/groq/groq.py +97 -35
  151. agno/models/huggingface/huggingface.py +92 -27
  152. agno/models/ibm/watsonx.py +72 -13
  153. agno/models/litellm/chat.py +85 -13
  154. agno/models/message.py +38 -144
  155. agno/models/meta/llama.py +85 -49
  156. agno/models/metrics.py +120 -0
  157. agno/models/mistral/mistral.py +90 -21
  158. agno/models/ollama/__init__.py +0 -2
  159. agno/models/ollama/chat.py +84 -46
  160. agno/models/openai/chat.py +135 -27
  161. agno/models/openai/responses.py +233 -115
  162. agno/models/perplexity/perplexity.py +26 -2
  163. agno/models/portkey/portkey.py +0 -7
  164. agno/models/response.py +14 -8
  165. agno/models/utils.py +20 -0
  166. agno/models/vercel/__init__.py +2 -2
  167. agno/models/vercel/v0.py +1 -1
  168. agno/models/vllm/__init__.py +2 -2
  169. agno/models/vllm/vllm.py +3 -3
  170. agno/models/xai/xai.py +10 -10
  171. agno/os/__init__.py +3 -0
  172. agno/os/app.py +393 -0
  173. agno/os/auth.py +47 -0
  174. agno/os/config.py +103 -0
  175. agno/os/interfaces/agui/__init__.py +3 -0
  176. agno/os/interfaces/agui/agui.py +31 -0
  177. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  178. agno/{app → os/interfaces}/agui/utils.py +65 -28
  179. agno/os/interfaces/base.py +21 -0
  180. agno/os/interfaces/slack/__init__.py +3 -0
  181. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  182. agno/os/interfaces/slack/slack.py +33 -0
  183. agno/os/interfaces/whatsapp/__init__.py +3 -0
  184. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  185. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  186. agno/os/router.py +843 -0
  187. agno/os/routers/__init__.py +3 -0
  188. agno/os/routers/evals/__init__.py +3 -0
  189. agno/os/routers/evals/evals.py +204 -0
  190. agno/os/routers/evals/schemas.py +142 -0
  191. agno/os/routers/evals/utils.py +161 -0
  192. agno/os/routers/knowledge/__init__.py +3 -0
  193. agno/os/routers/knowledge/knowledge.py +413 -0
  194. agno/os/routers/knowledge/schemas.py +118 -0
  195. agno/os/routers/memory/__init__.py +3 -0
  196. agno/os/routers/memory/memory.py +179 -0
  197. agno/os/routers/memory/schemas.py +58 -0
  198. agno/os/routers/metrics/__init__.py +3 -0
  199. agno/os/routers/metrics/metrics.py +58 -0
  200. agno/os/routers/metrics/schemas.py +47 -0
  201. agno/os/routers/session/__init__.py +3 -0
  202. agno/os/routers/session/session.py +163 -0
  203. agno/os/schema.py +892 -0
  204. agno/{app/playground → os}/settings.py +8 -15
  205. agno/os/utils.py +270 -0
  206. agno/reasoning/azure_ai_foundry.py +4 -4
  207. agno/reasoning/deepseek.py +4 -4
  208. agno/reasoning/default.py +6 -11
  209. agno/reasoning/groq.py +4 -4
  210. agno/reasoning/helpers.py +4 -6
  211. agno/reasoning/ollama.py +4 -4
  212. agno/reasoning/openai.py +4 -4
  213. agno/run/{response.py → agent.py} +144 -72
  214. agno/run/base.py +44 -58
  215. agno/run/cancel.py +83 -0
  216. agno/run/team.py +133 -77
  217. agno/run/workflow.py +537 -12
  218. agno/session/__init__.py +10 -0
  219. agno/session/agent.py +244 -0
  220. agno/session/summary.py +225 -0
  221. agno/session/team.py +262 -0
  222. agno/{storage/session/v2 → session}/workflow.py +47 -24
  223. agno/team/__init__.py +15 -16
  224. agno/team/team.py +2967 -4243
  225. agno/tools/agentql.py +14 -5
  226. agno/tools/airflow.py +9 -4
  227. agno/tools/api.py +7 -3
  228. agno/tools/apify.py +2 -46
  229. agno/tools/arxiv.py +8 -3
  230. agno/tools/aws_lambda.py +7 -5
  231. agno/tools/aws_ses.py +7 -1
  232. agno/tools/baidusearch.py +4 -1
  233. agno/tools/bitbucket.py +4 -4
  234. agno/tools/brandfetch.py +14 -11
  235. agno/tools/bravesearch.py +4 -1
  236. agno/tools/brightdata.py +42 -22
  237. agno/tools/browserbase.py +13 -4
  238. agno/tools/calcom.py +12 -10
  239. agno/tools/calculator.py +10 -27
  240. agno/tools/cartesia.py +18 -13
  241. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  242. agno/tools/confluence.py +71 -18
  243. agno/tools/crawl4ai.py +7 -1
  244. agno/tools/csv_toolkit.py +9 -8
  245. agno/tools/dalle.py +18 -11
  246. agno/tools/daytona.py +13 -16
  247. agno/tools/decorator.py +6 -3
  248. agno/tools/desi_vocal.py +16 -7
  249. agno/tools/discord.py +11 -8
  250. agno/tools/docker.py +30 -42
  251. agno/tools/duckdb.py +34 -53
  252. agno/tools/duckduckgo.py +8 -7
  253. agno/tools/e2b.py +62 -62
  254. agno/tools/eleven_labs.py +35 -28
  255. agno/tools/email.py +4 -1
  256. agno/tools/evm.py +7 -1
  257. agno/tools/exa.py +19 -14
  258. agno/tools/fal.py +29 -29
  259. agno/tools/file.py +9 -8
  260. agno/tools/financial_datasets.py +25 -44
  261. agno/tools/firecrawl.py +22 -22
  262. agno/tools/function.py +68 -17
  263. agno/tools/giphy.py +22 -10
  264. agno/tools/github.py +48 -126
  265. agno/tools/gmail.py +46 -62
  266. agno/tools/google_bigquery.py +7 -6
  267. agno/tools/google_maps.py +11 -26
  268. agno/tools/googlesearch.py +7 -2
  269. agno/tools/googlesheets.py +21 -17
  270. agno/tools/hackernews.py +9 -5
  271. agno/tools/jina.py +5 -4
  272. agno/tools/jira.py +18 -9
  273. agno/tools/knowledge.py +31 -32
  274. agno/tools/linear.py +18 -33
  275. agno/tools/linkup.py +5 -1
  276. agno/tools/local_file_system.py +8 -5
  277. agno/tools/lumalab.py +31 -19
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +32 -14
  282. agno/tools/models/gemini.py +58 -31
  283. agno/tools/models/groq.py +29 -20
  284. agno/tools/models/nebius.py +27 -11
  285. agno/tools/models_labs.py +39 -15
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +134 -0
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +57 -26
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +62 -46
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +54 -41
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +95 -118
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/location.py +2 -2
  337. agno/utils/log.py +2 -2
  338. agno/utils/mcp.py +11 -5
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/claude.py +6 -4
  342. agno/utils/models/mistral.py +8 -7
  343. agno/utils/models/schema_utils.py +3 -3
  344. agno/utils/pprint.py +33 -32
  345. agno/utils/print_response/agent.py +779 -0
  346. agno/utils/print_response/team.py +1565 -0
  347. agno/utils/print_response/workflow.py +1451 -0
  348. agno/utils/prompts.py +14 -14
  349. agno/utils/reasoning.py +87 -0
  350. agno/utils/response.py +42 -42
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +356 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2394 -696
  383. agno-2.0.0a1.dist-info/METADATA +355 -0
  384. agno-2.0.0a1.dist-info/RECORD +514 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -698
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.0.dist-info/METADATA +0 -979
  568. agno-1.8.0.dist-info/RECORD +0 -565
  569. agno-1.8.0.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
@@ -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, log_info, logger
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 _insert_hybrid_document(self, document: Document) -> None:
361
- """Insert a document with both dense and sparse vectors."""
362
- data = self._prepare_document_data(document, include_vectors=True)
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(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
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
- log_debug(f"Inserting {len(documents)} documents asynchronously")
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(*[self._async_insert_hybrid_document(doc) for doc in documents])
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(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
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
- logger.error(f"Error getting embedding for Query: {query}")
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
- logger.error(f"Error getting embedding for Query: {query}")
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
- logger.error(f"Error getting dense embedding for Query: {query}")
685
+ log_error(f"Error getting dense embedding for Query: {query}")
624
686
  return []
625
687
 
626
688
  if self._client is None:
627
- logger.error("Milvus client not initialized")
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
- logger.error(f"Error during hybrid search: {e}")
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
- logger.error(f"Error getting dense embedding for Query: {query}")
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
- logger.error(f"Error during async hybrid search: {e}")
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