agno 1.8.1__py3-none-any.whl → 2.0.0__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 (590) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +3143 -4170
  4. agno/api/agent.py +11 -67
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +8 -19
  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 +11 -66
  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 +1743 -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 +1432 -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 +882 -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 +1045 -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 +1416 -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 +297 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1710 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +280 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1367 -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 +1712 -0
  67. agno/db/singlestore/utils.py +326 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1676 -0
  71. agno/db/sqlite/utils.py +268 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +154 -48
  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 +15 -11
  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 +1551 -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 +47 -65
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/{document → knowledge}/reader/json_reader.py +30 -9
  118. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  119. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  120. agno/knowledge/reader/reader_factory.py +268 -0
  121. agno/knowledge/reader/s3_reader.py +101 -0
  122. agno/{document → knowledge}/reader/text_reader.py +31 -10
  123. agno/knowledge/reader/url_reader.py +128 -0
  124. agno/knowledge/reader/web_search_reader.py +366 -0
  125. agno/{document → knowledge}/reader/website_reader.py +37 -10
  126. agno/knowledge/reader/wikipedia_reader.py +59 -0
  127. agno/knowledge/reader/youtube_reader.py +78 -0
  128. agno/knowledge/remote_content/remote_content.py +88 -0
  129. agno/{reranker → knowledge/reranker}/base.py +1 -1
  130. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  131. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  132. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  133. agno/knowledge/types.py +30 -0
  134. agno/knowledge/utils.py +169 -0
  135. agno/media.py +269 -268
  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 +131 -131
  141. agno/models/aws/bedrock.py +110 -182
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +346 -290
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +105 -46
  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 +46 -151
  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 +85 -47
  158. agno/models/openai/chat.py +154 -37
  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 +15 -9
  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 +497 -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 +77 -33
  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 +32 -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 +29 -0
  184. agno/os/mcp.py +235 -0
  185. agno/os/router.py +1400 -0
  186. agno/os/routers/__init__.py +3 -0
  187. agno/os/routers/evals/__init__.py +3 -0
  188. agno/os/routers/evals/evals.py +393 -0
  189. agno/os/routers/evals/schemas.py +142 -0
  190. agno/os/routers/evals/utils.py +161 -0
  191. agno/os/routers/knowledge/__init__.py +3 -0
  192. agno/os/routers/knowledge/knowledge.py +850 -0
  193. agno/os/routers/knowledge/schemas.py +118 -0
  194. agno/os/routers/memory/__init__.py +3 -0
  195. agno/os/routers/memory/memory.py +410 -0
  196. agno/os/routers/memory/schemas.py +58 -0
  197. agno/os/routers/metrics/__init__.py +3 -0
  198. agno/os/routers/metrics/metrics.py +178 -0
  199. agno/os/routers/metrics/schemas.py +47 -0
  200. agno/os/routers/session/__init__.py +3 -0
  201. agno/os/routers/session/session.py +536 -0
  202. agno/os/schema.py +945 -0
  203. agno/{app/playground → os}/settings.py +7 -15
  204. agno/os/utils.py +270 -0
  205. agno/reasoning/azure_ai_foundry.py +4 -4
  206. agno/reasoning/deepseek.py +4 -4
  207. agno/reasoning/default.py +6 -11
  208. agno/reasoning/groq.py +4 -4
  209. agno/reasoning/helpers.py +4 -6
  210. agno/reasoning/ollama.py +4 -4
  211. agno/reasoning/openai.py +4 -4
  212. agno/run/agent.py +633 -0
  213. agno/run/base.py +53 -77
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +243 -96
  216. agno/run/workflow.py +550 -12
  217. agno/session/__init__.py +10 -0
  218. agno/session/agent.py +244 -0
  219. agno/session/summary.py +225 -0
  220. agno/session/team.py +262 -0
  221. agno/{storage/session/v2 → session}/workflow.py +47 -24
  222. agno/team/__init__.py +15 -16
  223. agno/team/team.py +3260 -4824
  224. agno/tools/agentql.py +14 -5
  225. agno/tools/airflow.py +9 -4
  226. agno/tools/api.py +7 -3
  227. agno/tools/apify.py +2 -46
  228. agno/tools/arxiv.py +8 -3
  229. agno/tools/aws_lambda.py +7 -5
  230. agno/tools/aws_ses.py +7 -1
  231. agno/tools/baidusearch.py +4 -1
  232. agno/tools/bitbucket.py +4 -4
  233. agno/tools/brandfetch.py +14 -11
  234. agno/tools/bravesearch.py +4 -1
  235. agno/tools/brightdata.py +43 -23
  236. agno/tools/browserbase.py +13 -4
  237. agno/tools/calcom.py +12 -10
  238. agno/tools/calculator.py +10 -27
  239. agno/tools/cartesia.py +20 -17
  240. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  241. agno/tools/confluence.py +8 -8
  242. agno/tools/crawl4ai.py +7 -1
  243. agno/tools/csv_toolkit.py +9 -8
  244. agno/tools/dalle.py +22 -12
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +17 -8
  248. agno/tools/discord.py +11 -8
  249. agno/tools/docker.py +30 -42
  250. agno/tools/duckdb.py +34 -53
  251. agno/tools/duckduckgo.py +8 -7
  252. agno/tools/e2b.py +62 -62
  253. agno/tools/eleven_labs.py +36 -29
  254. agno/tools/email.py +4 -1
  255. agno/tools/evm.py +7 -1
  256. agno/tools/exa.py +19 -14
  257. agno/tools/fal.py +30 -30
  258. agno/tools/file.py +9 -8
  259. agno/tools/financial_datasets.py +25 -44
  260. agno/tools/firecrawl.py +22 -22
  261. agno/tools/function.py +127 -18
  262. agno/tools/giphy.py +23 -11
  263. agno/tools/github.py +48 -126
  264. agno/tools/gmail.py +45 -61
  265. agno/tools/google_bigquery.py +7 -6
  266. agno/tools/google_maps.py +11 -26
  267. agno/tools/googlesearch.py +7 -2
  268. agno/tools/googlesheets.py +21 -17
  269. agno/tools/hackernews.py +9 -5
  270. agno/tools/jina.py +5 -4
  271. agno/tools/jira.py +18 -9
  272. agno/tools/knowledge.py +31 -32
  273. agno/tools/linear.py +19 -34
  274. agno/tools/linkup.py +5 -1
  275. agno/tools/local_file_system.py +8 -5
  276. agno/tools/lumalab.py +32 -20
  277. agno/tools/mcp.py +1 -2
  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 +33 -15
  282. agno/tools/models/gemini.py +59 -32
  283. agno/tools/models/groq.py +30 -23
  284. agno/tools/models/nebius.py +28 -12
  285. agno/tools/models_labs.py +40 -16
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +10 -8
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +58 -32
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +63 -47
  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 +55 -42
  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 +100 -123
  335. agno/utils/gemini.py +32 -2
  336. agno/utils/knowledge.py +29 -0
  337. agno/utils/log.py +54 -4
  338. agno/utils/mcp.py +68 -10
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/aws_claude.py +1 -1
  342. agno/utils/models/claude.py +47 -4
  343. agno/utils/models/cohere.py +1 -1
  344. agno/utils/models/mistral.py +8 -7
  345. agno/utils/models/schema_utils.py +3 -3
  346. agno/utils/models/watsonx.py +1 -1
  347. agno/utils/openai.py +1 -1
  348. agno/utils/pprint.py +33 -32
  349. agno/utils/print_response/agent.py +779 -0
  350. agno/utils/print_response/team.py +1669 -0
  351. agno/utils/print_response/workflow.py +1451 -0
  352. agno/utils/prompts.py +14 -14
  353. agno/utils/reasoning.py +87 -0
  354. agno/utils/response.py +42 -42
  355. agno/utils/streamlit.py +481 -0
  356. agno/utils/string.py +8 -22
  357. agno/utils/team.py +50 -0
  358. agno/utils/timer.py +2 -2
  359. agno/vectordb/base.py +33 -21
  360. agno/vectordb/cassandra/cassandra.py +287 -23
  361. agno/vectordb/chroma/chromadb.py +482 -59
  362. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  363. agno/vectordb/couchbase/couchbase.py +309 -29
  364. agno/vectordb/lancedb/lance_db.py +360 -21
  365. agno/vectordb/langchaindb/__init__.py +5 -0
  366. agno/vectordb/langchaindb/langchaindb.py +145 -0
  367. agno/vectordb/lightrag/__init__.py +5 -0
  368. agno/vectordb/lightrag/lightrag.py +374 -0
  369. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  370. agno/vectordb/milvus/milvus.py +242 -32
  371. agno/vectordb/mongodb/mongodb.py +200 -24
  372. agno/vectordb/pgvector/pgvector.py +319 -37
  373. agno/vectordb/pineconedb/pineconedb.py +221 -27
  374. agno/vectordb/qdrant/qdrant.py +334 -14
  375. agno/vectordb/singlestore/singlestore.py +286 -29
  376. agno/vectordb/surrealdb/surrealdb.py +187 -7
  377. agno/vectordb/upstashdb/upstashdb.py +342 -26
  378. agno/vectordb/weaviate/weaviate.py +227 -165
  379. agno/workflow/__init__.py +17 -13
  380. agno/workflow/{v2/condition.py → condition.py} +135 -32
  381. agno/workflow/{v2/loop.py → loop.py} +115 -28
  382. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  383. agno/workflow/{v2/router.py → router.py} +133 -32
  384. agno/workflow/{v2/step.py → step.py} +207 -49
  385. agno/workflow/{v2/steps.py → steps.py} +147 -66
  386. agno/workflow/types.py +482 -0
  387. agno/workflow/workflow.py +2410 -696
  388. agno-2.0.0.dist-info/METADATA +494 -0
  389. agno-2.0.0.dist-info/RECORD +515 -0
  390. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  391. agno/agent/metrics.py +0 -107
  392. agno/api/app.py +0 -35
  393. agno/api/playground.py +0 -92
  394. agno/api/schemas/app.py +0 -12
  395. agno/api/schemas/playground.py +0 -22
  396. agno/api/schemas/user.py +0 -35
  397. agno/api/schemas/workspace.py +0 -46
  398. agno/api/user.py +0 -160
  399. agno/api/workflows.py +0 -33
  400. agno/api/workspace.py +0 -175
  401. agno/app/agui/__init__.py +0 -3
  402. agno/app/agui/app.py +0 -17
  403. agno/app/agui/sync_router.py +0 -120
  404. agno/app/base.py +0 -186
  405. agno/app/discord/__init__.py +0 -3
  406. agno/app/fastapi/__init__.py +0 -3
  407. agno/app/fastapi/app.py +0 -107
  408. agno/app/fastapi/async_router.py +0 -457
  409. agno/app/fastapi/sync_router.py +0 -448
  410. agno/app/playground/app.py +0 -228
  411. agno/app/playground/async_router.py +0 -1050
  412. agno/app/playground/deploy.py +0 -249
  413. agno/app/playground/operator.py +0 -183
  414. agno/app/playground/schemas.py +0 -220
  415. agno/app/playground/serve.py +0 -55
  416. agno/app/playground/sync_router.py +0 -1042
  417. agno/app/playground/utils.py +0 -46
  418. agno/app/settings.py +0 -15
  419. agno/app/slack/__init__.py +0 -3
  420. agno/app/slack/app.py +0 -19
  421. agno/app/slack/sync_router.py +0 -92
  422. agno/app/utils.py +0 -54
  423. agno/app/whatsapp/__init__.py +0 -3
  424. agno/app/whatsapp/app.py +0 -15
  425. agno/app/whatsapp/sync_router.py +0 -197
  426. agno/cli/auth_server.py +0 -249
  427. agno/cli/config.py +0 -274
  428. agno/cli/console.py +0 -88
  429. agno/cli/credentials.py +0 -23
  430. agno/cli/entrypoint.py +0 -571
  431. agno/cli/operator.py +0 -357
  432. agno/cli/settings.py +0 -96
  433. agno/cli/ws/ws_cli.py +0 -817
  434. agno/constants.py +0 -13
  435. agno/document/__init__.py +0 -5
  436. agno/document/chunking/semantic.py +0 -45
  437. agno/document/chunking/strategy.py +0 -31
  438. agno/document/reader/__init__.py +0 -5
  439. agno/document/reader/base.py +0 -47
  440. agno/document/reader/docx_reader.py +0 -60
  441. agno/document/reader/gcs/pdf_reader.py +0 -44
  442. agno/document/reader/s3/pdf_reader.py +0 -59
  443. agno/document/reader/s3/text_reader.py +0 -63
  444. agno/document/reader/url_reader.py +0 -59
  445. agno/document/reader/youtube_reader.py +0 -58
  446. agno/embedder/__init__.py +0 -5
  447. agno/embedder/langdb.py +0 -80
  448. agno/embedder/mistral.py +0 -82
  449. agno/embedder/openai.py +0 -78
  450. agno/file/__init__.py +0 -5
  451. agno/file/file.py +0 -16
  452. agno/file/local/csv.py +0 -32
  453. agno/file/local/txt.py +0 -19
  454. agno/infra/app.py +0 -240
  455. agno/infra/base.py +0 -144
  456. agno/infra/context.py +0 -20
  457. agno/infra/db_app.py +0 -52
  458. agno/infra/resource.py +0 -205
  459. agno/infra/resources.py +0 -55
  460. agno/knowledge/agent.py +0 -702
  461. agno/knowledge/arxiv.py +0 -33
  462. agno/knowledge/combined.py +0 -36
  463. agno/knowledge/csv.py +0 -144
  464. agno/knowledge/csv_url.py +0 -124
  465. agno/knowledge/document.py +0 -223
  466. agno/knowledge/docx.py +0 -137
  467. agno/knowledge/firecrawl.py +0 -34
  468. agno/knowledge/gcs/__init__.py +0 -0
  469. agno/knowledge/gcs/base.py +0 -39
  470. agno/knowledge/gcs/pdf.py +0 -125
  471. agno/knowledge/json.py +0 -137
  472. agno/knowledge/langchain.py +0 -71
  473. agno/knowledge/light_rag.py +0 -273
  474. agno/knowledge/llamaindex.py +0 -66
  475. agno/knowledge/markdown.py +0 -154
  476. agno/knowledge/pdf.py +0 -164
  477. agno/knowledge/pdf_bytes.py +0 -42
  478. agno/knowledge/pdf_url.py +0 -148
  479. agno/knowledge/s3/__init__.py +0 -0
  480. agno/knowledge/s3/base.py +0 -64
  481. agno/knowledge/s3/pdf.py +0 -33
  482. agno/knowledge/s3/text.py +0 -34
  483. agno/knowledge/text.py +0 -141
  484. agno/knowledge/url.py +0 -46
  485. agno/knowledge/website.py +0 -179
  486. agno/knowledge/wikipedia.py +0 -32
  487. agno/knowledge/youtube.py +0 -35
  488. agno/memory/agent.py +0 -423
  489. agno/memory/classifier.py +0 -104
  490. agno/memory/db/__init__.py +0 -5
  491. agno/memory/db/base.py +0 -42
  492. agno/memory/db/mongodb.py +0 -189
  493. agno/memory/db/postgres.py +0 -203
  494. agno/memory/db/sqlite.py +0 -193
  495. agno/memory/memory.py +0 -22
  496. agno/memory/row.py +0 -36
  497. agno/memory/summarizer.py +0 -201
  498. agno/memory/summary.py +0 -19
  499. agno/memory/team.py +0 -415
  500. agno/memory/v2/__init__.py +0 -2
  501. agno/memory/v2/db/__init__.py +0 -1
  502. agno/memory/v2/db/base.py +0 -42
  503. agno/memory/v2/db/firestore.py +0 -339
  504. agno/memory/v2/db/mongodb.py +0 -196
  505. agno/memory/v2/db/postgres.py +0 -214
  506. agno/memory/v2/db/redis.py +0 -187
  507. agno/memory/v2/db/schema.py +0 -54
  508. agno/memory/v2/db/sqlite.py +0 -209
  509. agno/memory/v2/manager.py +0 -437
  510. agno/memory/v2/memory.py +0 -1097
  511. agno/memory/v2/schema.py +0 -55
  512. agno/memory/v2/summarizer.py +0 -215
  513. agno/memory/workflow.py +0 -38
  514. agno/models/ollama/tools.py +0 -430
  515. agno/models/qwen/__init__.py +0 -5
  516. agno/playground/__init__.py +0 -10
  517. agno/playground/deploy.py +0 -3
  518. agno/playground/playground.py +0 -3
  519. agno/playground/serve.py +0 -3
  520. agno/playground/settings.py +0 -3
  521. agno/reranker/__init__.py +0 -0
  522. agno/run/response.py +0 -467
  523. agno/run/v2/__init__.py +0 -0
  524. agno/run/v2/workflow.py +0 -567
  525. agno/storage/__init__.py +0 -0
  526. agno/storage/agent/__init__.py +0 -0
  527. agno/storage/agent/dynamodb.py +0 -1
  528. agno/storage/agent/json.py +0 -1
  529. agno/storage/agent/mongodb.py +0 -1
  530. agno/storage/agent/postgres.py +0 -1
  531. agno/storage/agent/singlestore.py +0 -1
  532. agno/storage/agent/sqlite.py +0 -1
  533. agno/storage/agent/yaml.py +0 -1
  534. agno/storage/base.py +0 -60
  535. agno/storage/dynamodb.py +0 -673
  536. agno/storage/firestore.py +0 -297
  537. agno/storage/gcs_json.py +0 -261
  538. agno/storage/in_memory.py +0 -234
  539. agno/storage/json.py +0 -237
  540. agno/storage/mongodb.py +0 -328
  541. agno/storage/mysql.py +0 -685
  542. agno/storage/postgres.py +0 -682
  543. agno/storage/redis.py +0 -336
  544. agno/storage/session/__init__.py +0 -16
  545. agno/storage/session/agent.py +0 -64
  546. agno/storage/session/team.py +0 -63
  547. agno/storage/session/v2/__init__.py +0 -5
  548. agno/storage/session/workflow.py +0 -61
  549. agno/storage/singlestore.py +0 -606
  550. agno/storage/sqlite.py +0 -646
  551. agno/storage/workflow/__init__.py +0 -0
  552. agno/storage/workflow/mongodb.py +0 -1
  553. agno/storage/workflow/postgres.py +0 -1
  554. agno/storage/workflow/sqlite.py +0 -1
  555. agno/storage/yaml.py +0 -241
  556. agno/tools/thinking.py +0 -73
  557. agno/utils/defaults.py +0 -57
  558. agno/utils/filesystem.py +0 -39
  559. agno/utils/git.py +0 -52
  560. agno/utils/json_io.py +0 -30
  561. agno/utils/load_env.py +0 -19
  562. agno/utils/py_io.py +0 -19
  563. agno/utils/pyproject.py +0 -18
  564. agno/utils/resource_filter.py +0 -31
  565. agno/workflow/v2/__init__.py +0 -21
  566. agno/workflow/v2/types.py +0 -357
  567. agno/workflow/v2/workflow.py +0 -3312
  568. agno/workspace/__init__.py +0 -0
  569. agno/workspace/config.py +0 -325
  570. agno/workspace/enums.py +0 -6
  571. agno/workspace/helpers.py +0 -52
  572. agno/workspace/operator.py +0 -757
  573. agno/workspace/settings.py +0 -158
  574. agno-1.8.1.dist-info/METADATA +0 -982
  575. agno-1.8.1.dist-info/RECORD +0 -566
  576. agno-1.8.1.dist-info/entry_points.txt +0 -3
  577. agno-1.8.1.dist-info/licenses/LICENSE +0 -375
  578. /agno/{app → db/migrations}/__init__.py +0 -0
  579. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  580. /agno/{cli → integrations}/__init__.py +0 -0
  581. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  582. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  583. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  584. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  585. /agno/{app → os/interfaces}/slack/security.py +0 -0
  586. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  587. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  588. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  589. {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  590. {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
@@ -4,8 +4,8 @@ from typing import Any, Dict, List, Optional
4
4
 
5
5
  from bson import ObjectId
6
6
 
7
- from agno.document import Document
8
- from agno.embedder import Embedder
7
+ from agno.knowledge.document import Document
8
+ from agno.knowledge.embedder import Embedder
9
9
  from agno.utils.log import log_debug, log_info, log_warning, logger
10
10
  from agno.vectordb.base import VectorDb
11
11
  from agno.vectordb.distance import Distance
@@ -88,7 +88,7 @@ class MongoDb(VectorDb):
88
88
  self.hybrid_rank_constant = hybrid_rank_constant
89
89
 
90
90
  if embedder is None:
91
- from agno.embedder.openai import OpenAIEmbedder
91
+ from agno.knowledge.embedder.openai import OpenAIEmbedder
92
92
 
93
93
  embedder = OpenAIEmbedder()
94
94
  log_info("Embedder not provided, using OpenAIEmbedder as default.")
@@ -374,10 +374,13 @@ class MongoDb(VectorDb):
374
374
  for idx_name, idx_info in indexes.items():
375
375
  if idx_name == index_name:
376
376
  key_info = idx_info.get("key", [])
377
- for key, value in key_info:
378
- if key == "embedding" and value == "cosmosSearch":
379
- log_debug(f"Found existing vector search index: {index_name}")
380
- return True
377
+ for key_value_pair in key_info:
378
+ # Ensure we have a tuple/list with exactly 2 elements
379
+ if isinstance(key_value_pair, (tuple, list)) and len(key_value_pair) == 2:
380
+ key, value = key_value_pair
381
+ if key == "embedding" and value == "cosmosSearch":
382
+ log_debug(f"Found existing vector search index: {index_name}")
383
+ return True
381
384
 
382
385
  log_debug(f"Vector search index '{index_name}' not found")
383
386
  return False
@@ -475,17 +478,44 @@ class MongoDb(VectorDb):
475
478
  return False
476
479
 
477
480
  def id_exists(self, id: str) -> bool:
478
- """Check if a document with a given ID exists in the collection."""
481
+ """Check if a document with the given ID exists in the collection.
482
+
483
+ Args:
484
+ id (str): The document ID to check.
485
+
486
+ Returns:
487
+ bool: True if the document exists, False otherwise.
488
+ """
479
489
  try:
480
490
  collection = self._get_collection()
481
- exists = collection.find_one({"_id": id}) is not None
491
+ result = collection.find_one({"_id": id})
492
+ exists = result is not None
482
493
  log_debug(f"Document with ID '{id}' {'exists' if exists else 'does not exist'}")
483
494
  return exists
484
495
  except Exception as e:
485
496
  logger.error(f"Error checking document ID existence: {e}")
486
497
  return False
487
498
 
488
- def insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
499
+ def content_hash_exists(self, content_hash: str) -> bool:
500
+ """Check if documents with the given content hash exist in the collection.
501
+
502
+ Args:
503
+ content_hash (str): The content hash to check.
504
+
505
+ Returns:
506
+ bool: True if documents with the content hash exist, False otherwise.
507
+ """
508
+ try:
509
+ collection = self._get_collection()
510
+ result = collection.find_one({"content_hash": content_hash})
511
+ exists = result is not None
512
+ log_debug(f"Document with content_hash '{content_hash}' {'exists' if exists else 'does not exist'}")
513
+ return exists
514
+ except Exception as e:
515
+ logger.error(f"Error checking content_hash existence: {e}")
516
+ return False
517
+
518
+ def insert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
489
519
  """Insert documents into the MongoDB collection."""
490
520
  log_debug(f"Inserting {len(documents)} documents")
491
521
  collection = self._get_collection()
@@ -493,7 +523,10 @@ class MongoDb(VectorDb):
493
523
  prepared_docs = []
494
524
  for document in documents:
495
525
  try:
496
- doc_data = self.prepare_doc(document, filters)
526
+ document.embed(embedder=self.embedder)
527
+ if document.embedding is None:
528
+ raise ValueError(f"Failed to generate embedding for document: {document.id}")
529
+ doc_data = self.prepare_doc(content_hash, document, filters)
497
530
  prepared_docs.append(doc_data)
498
531
  except ValueError as e:
499
532
  logger.error(f"Error preparing document '{document.name}': {e}")
@@ -509,14 +542,17 @@ class MongoDb(VectorDb):
509
542
  except Exception as e:
510
543
  logger.error(f"Error inserting documents: {e}")
511
544
 
512
- def upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
545
+ def upsert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
513
546
  """Upsert documents into the MongoDB collection."""
514
547
  log_info(f"Upserting {len(documents)} documents")
515
548
  collection = self._get_collection()
516
549
 
517
550
  for document in documents:
518
551
  try:
519
- doc_data = self.prepare_doc(document)
552
+ document.embed(embedder=self.embedder)
553
+ if document.embedding is None:
554
+ raise ValueError(f"Failed to generate embedding for document: {document.id}")
555
+ doc_data = self.prepare_doc(content_hash, document, filters)
520
556
  collection.update_one(
521
557
  {"_id": doc_data["_id"]},
522
558
  {"$set": doc_data},
@@ -575,6 +611,7 @@ class MongoDb(VectorDb):
575
611
  name=doc.get("name"),
576
612
  content=doc["content"],
577
613
  meta_data={**doc.get("meta_data", {}), "score": doc.get("similarityScore", 0.0)},
614
+ content_id=doc.get("content_id"),
578
615
  )
579
616
  for doc in results
580
617
  ]
@@ -635,6 +672,7 @@ class MongoDb(VectorDb):
635
672
  name=clean_doc.get("name"),
636
673
  content=clean_doc["content"],
637
674
  meta_data={**clean_doc.get("meta_data", {}), "score": clean_doc.get("score", 0.0)},
675
+ content_id=clean_doc.get("content_id"),
638
676
  )
639
677
  docs.append(document)
640
678
 
@@ -656,7 +694,7 @@ class MongoDb(VectorDb):
656
694
  collection = self._get_collection()
657
695
  cursor = collection.find(
658
696
  {"content": {"$regex": query, "$options": "i"}},
659
- {"_id": 1, "name": 1, "content": 1, "meta_data": 1},
697
+ {"_id": 1, "name": 1, "content": 1, "meta_data": 1, "content_id": 1},
660
698
  ).limit(limit)
661
699
  results = [
662
700
  Document(
@@ -664,6 +702,7 @@ class MongoDb(VectorDb):
664
702
  name=doc.get("name"),
665
703
  content=doc["content"],
666
704
  meta_data=doc.get("meta_data", {}),
705
+ content_id=doc.get("content_id"),
667
706
  )
668
707
  for doc in cursor
669
708
  ]
@@ -731,6 +770,7 @@ class MongoDb(VectorDb):
731
770
  "name": "$docs.name",
732
771
  "content": "$docs.content",
733
772
  "meta_data": "$docs.meta_data",
773
+ "content_id": "$docs.content_id",
734
774
  "vs_score": {
735
775
  "$divide": [
736
776
  self.hybrid_vector_weight,
@@ -746,6 +786,7 @@ class MongoDb(VectorDb):
746
786
  "name": 1,
747
787
  "content": 1,
748
788
  "meta_data": 1,
789
+ "content_id": 1,
749
790
  "vs_score": 1,
750
791
  # Now fts_score is included with its value (0.0 here)
751
792
  "fts_score": 1,
@@ -771,6 +812,7 @@ class MongoDb(VectorDb):
771
812
  "name": "$docs.name",
772
813
  "content": "$docs.content",
773
814
  "meta_data": "$docs.meta_data",
815
+ "content_id": "$docs.content_id",
774
816
  "vs_score": 0.0,
775
817
  "fts_score": {
776
818
  "$divide": [
@@ -786,6 +828,7 @@ class MongoDb(VectorDb):
786
828
  "name": 1,
787
829
  "content": 1,
788
830
  "meta_data": 1,
831
+ "content_id": 1,
789
832
  "vs_score": 1,
790
833
  "fts_score": 1,
791
834
  }
@@ -800,6 +843,7 @@ class MongoDb(VectorDb):
800
843
  "name": {"$first": "$name"},
801
844
  "content": {"$first": "$content"},
802
845
  "meta_data": {"$first": "$meta_data"},
846
+ "content_id": {"$first": "$content_id"},
803
847
  "vs_score": {"$sum": "$vs_score"},
804
848
  "fts_score": {"$sum": "$fts_score"},
805
849
  }
@@ -810,6 +854,7 @@ class MongoDb(VectorDb):
810
854
  "name": 1,
811
855
  "content": 1,
812
856
  "meta_data": 1,
857
+ "content_id": 1,
813
858
  "score": {"$add": ["$vs_score", "$fts_score"]},
814
859
  }
815
860
  },
@@ -822,7 +867,9 @@ class MongoDb(VectorDb):
822
867
  pipeline.append({"$match": mongo_filters})
823
868
 
824
869
  try:
825
- results = list(collection.aggregate(pipeline))
870
+ from typing import Mapping, Sequence, cast
871
+
872
+ results = list(collection.aggregate(cast(Sequence[Mapping[str, Any]], pipeline)))
826
873
 
827
874
  docs = []
828
875
  for doc in results:
@@ -833,6 +880,7 @@ class MongoDb(VectorDb):
833
880
  name=clean_doc.get("name"),
834
881
  content=clean_doc["content"],
835
882
  meta_data={**clean_doc.get("meta_data", {}), "score": clean_doc.get("score", 0.0)},
883
+ content_id=clean_doc.get("content_id"),
836
884
  )
837
885
  docs.append(document)
838
886
 
@@ -914,11 +962,10 @@ class MongoDb(VectorDb):
914
962
  # Return True if collection doesn't exist (nothing to delete)
915
963
  return True
916
964
 
917
- def prepare_doc(self, document: Document, filters: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
965
+ def prepare_doc(
966
+ self, content_hash: str, document: Document, filters: Optional[Dict[str, Any]] = None
967
+ ) -> Dict[str, Any]:
918
968
  """Prepare a document for insertion or upsertion into MongoDB."""
919
- document.embed(embedder=self.embedder)
920
- if document.embedding is None:
921
- raise ValueError(f"Failed to generate embedding for document: {document.id}")
922
969
 
923
970
  # Add filters to document metadata if provided
924
971
  if filters:
@@ -934,6 +981,8 @@ class MongoDb(VectorDb):
934
981
  "content": cleaned_content,
935
982
  "meta_data": document.meta_data,
936
983
  "embedding": document.embedding,
984
+ "content_id": document.content_id,
985
+ "content_hash": content_hash,
937
986
  }
938
987
  log_debug(f"Prepared document: {doc_data['_id']}")
939
988
  return doc_data
@@ -962,15 +1011,20 @@ class MongoDb(VectorDb):
962
1011
  logger.error(f"Error checking document existence asynchronously: {e}")
963
1012
  return False
964
1013
 
965
- async def async_insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
1014
+ async def async_insert(
1015
+ self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
1016
+ ) -> None:
966
1017
  """Insert documents asynchronously."""
967
1018
  log_debug(f"Inserting {len(documents)} documents asynchronously")
968
1019
  collection = await self._get_async_collection()
969
1020
 
1021
+ embed_tasks = [document.async_embed(embedder=self.embedder) for document in documents]
1022
+ await asyncio.gather(*embed_tasks, return_exceptions=True)
1023
+
970
1024
  prepared_docs = []
971
1025
  for document in documents:
972
1026
  try:
973
- doc_data = self.prepare_doc(document, filters)
1027
+ doc_data = self.prepare_doc(content_hash, document, filters)
974
1028
  prepared_docs.append(doc_data)
975
1029
  except ValueError as e:
976
1030
  logger.error(f"Error preparing document '{document.name}': {e}")
@@ -986,14 +1040,19 @@ class MongoDb(VectorDb):
986
1040
  except Exception as e:
987
1041
  logger.error(f"Error inserting documents asynchronously: {e}")
988
1042
 
989
- async def async_upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
1043
+ async def async_upsert(
1044
+ self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
1045
+ ) -> None:
990
1046
  """Upsert documents asynchronously."""
991
1047
  log_info(f"Upserting {len(documents)} documents asynchronously")
992
1048
  collection = await self._get_async_collection()
993
1049
 
1050
+ embed_tasks = [document.async_embed(embedder=self.embedder) for document in documents]
1051
+ await asyncio.gather(*embed_tasks, return_exceptions=True)
1052
+
994
1053
  for document in documents:
995
1054
  try:
996
- doc_data = self.prepare_doc(document)
1055
+ doc_data = self.prepare_doc(content_hash, document, filters)
997
1056
  await collection.update_one(
998
1057
  {"_id": doc_data["_id"]},
999
1058
  {"$set": doc_data},
@@ -1059,6 +1118,7 @@ class MongoDb(VectorDb):
1059
1118
  name=doc.get("name"),
1060
1119
  content=doc["content"],
1061
1120
  meta_data={**doc.get("meta_data", {}), "score": doc.get("score", 0.0)},
1121
+ content_id=doc.get("content_id"),
1062
1122
  )
1063
1123
  for doc in results
1064
1124
  ]
@@ -1124,7 +1184,7 @@ class MongoDb(VectorDb):
1124
1184
  Returns:
1125
1185
  The same object with ObjectIds converted to strings
1126
1186
  """
1127
- if ObjectId and isinstance(obj, ObjectId):
1187
+ if isinstance(obj, ObjectId):
1128
1188
  return str(obj)
1129
1189
  elif isinstance(obj, dict):
1130
1190
  return {key: self._convert_objectids_to_strings(value) for key, value in obj.items()}
@@ -1134,3 +1194,119 @@ class MongoDb(VectorDb):
1134
1194
  return tuple(self._convert_objectids_to_strings(item) for item in obj)
1135
1195
  else:
1136
1196
  return obj
1197
+
1198
+ def delete_by_id(self, id: str) -> bool:
1199
+ """Delete document by ID."""
1200
+ try:
1201
+ collection = self._get_collection()
1202
+ result = collection.delete_one({"_id": id})
1203
+
1204
+ if result.deleted_count > 0:
1205
+ log_info(
1206
+ f"Deleted {result.deleted_count} document(s) with ID '{id}' from collection '{self.collection_name}'."
1207
+ )
1208
+ return True
1209
+ else:
1210
+ log_info(f"No documents found with ID '{id}' to delete.")
1211
+ return True
1212
+ except Exception as e:
1213
+ logger.error(f"Error deleting document with ID '{id}': {e}")
1214
+ return False
1215
+
1216
+ def delete_by_name(self, name: str) -> bool:
1217
+ """Delete documents by name."""
1218
+ try:
1219
+ collection = self._get_collection()
1220
+ result = collection.delete_many({"name": name})
1221
+
1222
+ log_info(
1223
+ f"Deleted {result.deleted_count} document(s) with name '{name}' from collection '{self.collection_name}'."
1224
+ )
1225
+ return True
1226
+ except Exception as e:
1227
+ logger.error(f"Error deleting documents with name '{name}': {e}")
1228
+ return False
1229
+
1230
+ def delete_by_metadata(self, metadata: Dict[str, Any]) -> bool:
1231
+ """Delete documents by metadata."""
1232
+ try:
1233
+ collection = self._get_collection()
1234
+
1235
+ # Build MongoDB query for metadata matching
1236
+ mongo_filters = {}
1237
+ for key, value in metadata.items():
1238
+ # Use dot notation for nested metadata fields
1239
+ mongo_filters[f"meta_data.{key}"] = value
1240
+
1241
+ result = collection.delete_many(mongo_filters)
1242
+
1243
+ log_info(
1244
+ f"Deleted {result.deleted_count} document(s) with metadata '{metadata}' from collection '{self.collection_name}'."
1245
+ )
1246
+ return True
1247
+ except Exception as e:
1248
+ logger.error(f"Error deleting documents with metadata '{metadata}': {e}")
1249
+ return False
1250
+
1251
+ def _delete_by_content_hash(self, content_hash: str) -> bool:
1252
+ """Delete documents by content hash.
1253
+
1254
+ Args:
1255
+ content_hash (str): The content hash to delete.
1256
+
1257
+ Returns:
1258
+ bool: True if documents were deleted successfully, False otherwise.
1259
+ """
1260
+ try:
1261
+ collection = self._get_collection()
1262
+ result = collection.delete_many({"content_hash": content_hash})
1263
+ log_info(f"Deleted {result.deleted_count} documents with content_hash '{content_hash}'")
1264
+ return True
1265
+ except Exception as e:
1266
+ logger.error(f"Error deleting documents by content_hash '{content_hash}': {e}")
1267
+ return False
1268
+
1269
+ def delete_by_content_id(self, content_id: str) -> bool:
1270
+ """Delete documents by content ID."""
1271
+ try:
1272
+ collection = self._get_collection()
1273
+ result = collection.delete_many({"content_id": content_id})
1274
+
1275
+ log_info(
1276
+ f"Deleted {result.deleted_count} document(s) with content_id '{content_id}' from collection '{self.collection_name}'."
1277
+ )
1278
+ return True
1279
+ except Exception as e:
1280
+ logger.error(f"Error deleting documents with content_id '{content_id}': {e}")
1281
+ return False
1282
+
1283
+ def update_metadata(self, content_id: str, metadata: Dict[str, Any]) -> None:
1284
+ """
1285
+ Update the metadata for documents with the given content_id.
1286
+
1287
+ Args:
1288
+ content_id (str): The content ID to update
1289
+ metadata (Dict[str, Any]): The metadata to update
1290
+ """
1291
+ try:
1292
+ collection = self._client[self.database][self.collection_name] # type: ignore
1293
+
1294
+ # Create query filter for content_id
1295
+ filter_query = {"content_id": content_id}
1296
+
1297
+ update_operations = {}
1298
+ for key, value in metadata.items():
1299
+ update_operations[f"meta_data.{key}"] = value
1300
+ update_operations[f"filters.{key}"] = value
1301
+
1302
+ # Update documents
1303
+ result = collection.update_many(filter_query, {"$set": update_operations})
1304
+
1305
+ if result.matched_count == 0:
1306
+ logger.debug(f"No documents found with content_id: {content_id}")
1307
+ else:
1308
+ logger.debug(f"Updated metadata for {result.matched_count} documents with content_id: {content_id}")
1309
+
1310
+ except Exception as e:
1311
+ logger.error(f"Error updating metadata for content_id '{content_id}': {e}")
1312
+ raise