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
@@ -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