agno 2.1.2__py3-none-any.whl → 2.3.13__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 (314) hide show
  1. agno/agent/agent.py +5540 -2273
  2. agno/api/api.py +2 -0
  3. agno/api/os.py +1 -1
  4. agno/compression/__init__.py +3 -0
  5. agno/compression/manager.py +247 -0
  6. agno/culture/__init__.py +3 -0
  7. agno/culture/manager.py +956 -0
  8. agno/db/async_postgres/__init__.py +3 -0
  9. agno/db/base.py +689 -6
  10. agno/db/dynamo/dynamo.py +933 -37
  11. agno/db/dynamo/schemas.py +174 -10
  12. agno/db/dynamo/utils.py +63 -4
  13. agno/db/firestore/firestore.py +831 -9
  14. agno/db/firestore/schemas.py +51 -0
  15. agno/db/firestore/utils.py +102 -4
  16. agno/db/gcs_json/gcs_json_db.py +660 -12
  17. agno/db/gcs_json/utils.py +60 -26
  18. agno/db/in_memory/in_memory_db.py +287 -14
  19. agno/db/in_memory/utils.py +60 -2
  20. agno/db/json/json_db.py +590 -14
  21. agno/db/json/utils.py +60 -26
  22. agno/db/migrations/manager.py +199 -0
  23. agno/db/migrations/v1_to_v2.py +43 -13
  24. agno/db/migrations/versions/__init__.py +0 -0
  25. agno/db/migrations/versions/v2_3_0.py +938 -0
  26. agno/db/mongo/__init__.py +15 -1
  27. agno/db/mongo/async_mongo.py +2760 -0
  28. agno/db/mongo/mongo.py +879 -11
  29. agno/db/mongo/schemas.py +42 -0
  30. agno/db/mongo/utils.py +80 -8
  31. agno/db/mysql/__init__.py +2 -1
  32. agno/db/mysql/async_mysql.py +2912 -0
  33. agno/db/mysql/mysql.py +946 -68
  34. agno/db/mysql/schemas.py +72 -10
  35. agno/db/mysql/utils.py +198 -7
  36. agno/db/postgres/__init__.py +2 -1
  37. agno/db/postgres/async_postgres.py +2579 -0
  38. agno/db/postgres/postgres.py +942 -57
  39. agno/db/postgres/schemas.py +81 -18
  40. agno/db/postgres/utils.py +164 -2
  41. agno/db/redis/redis.py +671 -7
  42. agno/db/redis/schemas.py +50 -0
  43. agno/db/redis/utils.py +65 -7
  44. agno/db/schemas/__init__.py +2 -1
  45. agno/db/schemas/culture.py +120 -0
  46. agno/db/schemas/evals.py +1 -0
  47. agno/db/schemas/memory.py +17 -2
  48. agno/db/singlestore/schemas.py +63 -0
  49. agno/db/singlestore/singlestore.py +949 -83
  50. agno/db/singlestore/utils.py +60 -2
  51. agno/db/sqlite/__init__.py +2 -1
  52. agno/db/sqlite/async_sqlite.py +2911 -0
  53. agno/db/sqlite/schemas.py +62 -0
  54. agno/db/sqlite/sqlite.py +965 -46
  55. agno/db/sqlite/utils.py +169 -8
  56. agno/db/surrealdb/__init__.py +3 -0
  57. agno/db/surrealdb/metrics.py +292 -0
  58. agno/db/surrealdb/models.py +334 -0
  59. agno/db/surrealdb/queries.py +71 -0
  60. agno/db/surrealdb/surrealdb.py +1908 -0
  61. agno/db/surrealdb/utils.py +147 -0
  62. agno/db/utils.py +2 -0
  63. agno/eval/__init__.py +10 -0
  64. agno/eval/accuracy.py +75 -55
  65. agno/eval/agent_as_judge.py +861 -0
  66. agno/eval/base.py +29 -0
  67. agno/eval/performance.py +16 -7
  68. agno/eval/reliability.py +28 -16
  69. agno/eval/utils.py +35 -17
  70. agno/exceptions.py +27 -2
  71. agno/filters.py +354 -0
  72. agno/guardrails/prompt_injection.py +1 -0
  73. agno/hooks/__init__.py +3 -0
  74. agno/hooks/decorator.py +164 -0
  75. agno/integrations/discord/client.py +1 -1
  76. agno/knowledge/chunking/agentic.py +13 -10
  77. agno/knowledge/chunking/fixed.py +4 -1
  78. agno/knowledge/chunking/semantic.py +9 -4
  79. agno/knowledge/chunking/strategy.py +59 -15
  80. agno/knowledge/embedder/fastembed.py +1 -1
  81. agno/knowledge/embedder/nebius.py +1 -1
  82. agno/knowledge/embedder/ollama.py +8 -0
  83. agno/knowledge/embedder/openai.py +8 -8
  84. agno/knowledge/embedder/sentence_transformer.py +6 -2
  85. agno/knowledge/embedder/vllm.py +262 -0
  86. agno/knowledge/knowledge.py +1618 -318
  87. agno/knowledge/reader/base.py +6 -2
  88. agno/knowledge/reader/csv_reader.py +8 -10
  89. agno/knowledge/reader/docx_reader.py +5 -6
  90. agno/knowledge/reader/field_labeled_csv_reader.py +16 -20
  91. agno/knowledge/reader/json_reader.py +5 -4
  92. agno/knowledge/reader/markdown_reader.py +8 -8
  93. agno/knowledge/reader/pdf_reader.py +17 -19
  94. agno/knowledge/reader/pptx_reader.py +101 -0
  95. agno/knowledge/reader/reader_factory.py +32 -3
  96. agno/knowledge/reader/s3_reader.py +3 -3
  97. agno/knowledge/reader/tavily_reader.py +193 -0
  98. agno/knowledge/reader/text_reader.py +22 -10
  99. agno/knowledge/reader/web_search_reader.py +1 -48
  100. agno/knowledge/reader/website_reader.py +10 -10
  101. agno/knowledge/reader/wikipedia_reader.py +33 -1
  102. agno/knowledge/types.py +1 -0
  103. agno/knowledge/utils.py +72 -7
  104. agno/media.py +22 -6
  105. agno/memory/__init__.py +14 -1
  106. agno/memory/manager.py +544 -83
  107. agno/memory/strategies/__init__.py +15 -0
  108. agno/memory/strategies/base.py +66 -0
  109. agno/memory/strategies/summarize.py +196 -0
  110. agno/memory/strategies/types.py +37 -0
  111. agno/models/aimlapi/aimlapi.py +17 -0
  112. agno/models/anthropic/claude.py +515 -40
  113. agno/models/aws/bedrock.py +102 -21
  114. agno/models/aws/claude.py +131 -274
  115. agno/models/azure/ai_foundry.py +41 -19
  116. agno/models/azure/openai_chat.py +39 -8
  117. agno/models/base.py +1249 -525
  118. agno/models/cerebras/cerebras.py +91 -21
  119. agno/models/cerebras/cerebras_openai.py +21 -2
  120. agno/models/cohere/chat.py +40 -6
  121. agno/models/cometapi/cometapi.py +18 -1
  122. agno/models/dashscope/dashscope.py +2 -3
  123. agno/models/deepinfra/deepinfra.py +18 -1
  124. agno/models/deepseek/deepseek.py +69 -3
  125. agno/models/fireworks/fireworks.py +18 -1
  126. agno/models/google/gemini.py +877 -80
  127. agno/models/google/utils.py +22 -0
  128. agno/models/groq/groq.py +51 -18
  129. agno/models/huggingface/huggingface.py +17 -6
  130. agno/models/ibm/watsonx.py +16 -6
  131. agno/models/internlm/internlm.py +18 -1
  132. agno/models/langdb/langdb.py +13 -1
  133. agno/models/litellm/chat.py +44 -9
  134. agno/models/litellm/litellm_openai.py +18 -1
  135. agno/models/message.py +28 -5
  136. agno/models/meta/llama.py +47 -14
  137. agno/models/meta/llama_openai.py +22 -17
  138. agno/models/mistral/mistral.py +8 -4
  139. agno/models/nebius/nebius.py +6 -7
  140. agno/models/nvidia/nvidia.py +20 -3
  141. agno/models/ollama/chat.py +24 -8
  142. agno/models/openai/chat.py +104 -29
  143. agno/models/openai/responses.py +101 -81
  144. agno/models/openrouter/openrouter.py +60 -3
  145. agno/models/perplexity/perplexity.py +17 -1
  146. agno/models/portkey/portkey.py +7 -6
  147. agno/models/requesty/requesty.py +24 -4
  148. agno/models/response.py +73 -2
  149. agno/models/sambanova/sambanova.py +20 -3
  150. agno/models/siliconflow/siliconflow.py +19 -2
  151. agno/models/together/together.py +20 -3
  152. agno/models/utils.py +254 -8
  153. agno/models/vercel/v0.py +20 -3
  154. agno/models/vertexai/__init__.py +0 -0
  155. agno/models/vertexai/claude.py +190 -0
  156. agno/models/vllm/vllm.py +19 -14
  157. agno/models/xai/xai.py +19 -2
  158. agno/os/app.py +549 -152
  159. agno/os/auth.py +190 -3
  160. agno/os/config.py +23 -0
  161. agno/os/interfaces/a2a/router.py +8 -11
  162. agno/os/interfaces/a2a/utils.py +1 -1
  163. agno/os/interfaces/agui/router.py +18 -3
  164. agno/os/interfaces/agui/utils.py +152 -39
  165. agno/os/interfaces/slack/router.py +55 -37
  166. agno/os/interfaces/slack/slack.py +9 -1
  167. agno/os/interfaces/whatsapp/router.py +0 -1
  168. agno/os/interfaces/whatsapp/security.py +3 -1
  169. agno/os/mcp.py +110 -52
  170. agno/os/middleware/__init__.py +2 -0
  171. agno/os/middleware/jwt.py +676 -112
  172. agno/os/router.py +40 -1478
  173. agno/os/routers/agents/__init__.py +3 -0
  174. agno/os/routers/agents/router.py +599 -0
  175. agno/os/routers/agents/schema.py +261 -0
  176. agno/os/routers/evals/evals.py +96 -39
  177. agno/os/routers/evals/schemas.py +65 -33
  178. agno/os/routers/evals/utils.py +80 -10
  179. agno/os/routers/health.py +10 -4
  180. agno/os/routers/knowledge/knowledge.py +196 -38
  181. agno/os/routers/knowledge/schemas.py +82 -22
  182. agno/os/routers/memory/memory.py +279 -52
  183. agno/os/routers/memory/schemas.py +46 -17
  184. agno/os/routers/metrics/metrics.py +20 -8
  185. agno/os/routers/metrics/schemas.py +16 -16
  186. agno/os/routers/session/session.py +462 -34
  187. agno/os/routers/teams/__init__.py +3 -0
  188. agno/os/routers/teams/router.py +512 -0
  189. agno/os/routers/teams/schema.py +257 -0
  190. agno/os/routers/traces/__init__.py +3 -0
  191. agno/os/routers/traces/schemas.py +414 -0
  192. agno/os/routers/traces/traces.py +499 -0
  193. agno/os/routers/workflows/__init__.py +3 -0
  194. agno/os/routers/workflows/router.py +624 -0
  195. agno/os/routers/workflows/schema.py +75 -0
  196. agno/os/schema.py +256 -693
  197. agno/os/scopes.py +469 -0
  198. agno/os/utils.py +514 -36
  199. agno/reasoning/anthropic.py +80 -0
  200. agno/reasoning/gemini.py +73 -0
  201. agno/reasoning/openai.py +5 -0
  202. agno/reasoning/vertexai.py +76 -0
  203. agno/run/__init__.py +6 -0
  204. agno/run/agent.py +155 -32
  205. agno/run/base.py +55 -3
  206. agno/run/requirement.py +181 -0
  207. agno/run/team.py +125 -38
  208. agno/run/workflow.py +72 -18
  209. agno/session/agent.py +102 -89
  210. agno/session/summary.py +56 -15
  211. agno/session/team.py +164 -90
  212. agno/session/workflow.py +405 -40
  213. agno/table.py +10 -0
  214. agno/team/team.py +3974 -1903
  215. agno/tools/dalle.py +2 -4
  216. agno/tools/eleven_labs.py +23 -25
  217. agno/tools/exa.py +21 -16
  218. agno/tools/file.py +153 -23
  219. agno/tools/file_generation.py +16 -10
  220. agno/tools/firecrawl.py +15 -7
  221. agno/tools/function.py +193 -38
  222. agno/tools/gmail.py +238 -14
  223. agno/tools/google_drive.py +271 -0
  224. agno/tools/googlecalendar.py +36 -8
  225. agno/tools/googlesheets.py +20 -5
  226. agno/tools/jira.py +20 -0
  227. agno/tools/mcp/__init__.py +10 -0
  228. agno/tools/mcp/mcp.py +331 -0
  229. agno/tools/mcp/multi_mcp.py +347 -0
  230. agno/tools/mcp/params.py +24 -0
  231. agno/tools/mcp_toolbox.py +3 -3
  232. agno/tools/models/nebius.py +5 -5
  233. agno/tools/models_labs.py +20 -10
  234. agno/tools/nano_banana.py +151 -0
  235. agno/tools/notion.py +204 -0
  236. agno/tools/parallel.py +314 -0
  237. agno/tools/postgres.py +76 -36
  238. agno/tools/redshift.py +406 -0
  239. agno/tools/scrapegraph.py +1 -1
  240. agno/tools/shopify.py +1519 -0
  241. agno/tools/slack.py +18 -3
  242. agno/tools/spotify.py +919 -0
  243. agno/tools/tavily.py +146 -0
  244. agno/tools/toolkit.py +25 -0
  245. agno/tools/workflow.py +8 -1
  246. agno/tools/yfinance.py +12 -11
  247. agno/tracing/__init__.py +12 -0
  248. agno/tracing/exporter.py +157 -0
  249. agno/tracing/schemas.py +276 -0
  250. agno/tracing/setup.py +111 -0
  251. agno/utils/agent.py +938 -0
  252. agno/utils/cryptography.py +22 -0
  253. agno/utils/dttm.py +33 -0
  254. agno/utils/events.py +151 -3
  255. agno/utils/gemini.py +15 -5
  256. agno/utils/hooks.py +118 -4
  257. agno/utils/http.py +113 -2
  258. agno/utils/knowledge.py +12 -5
  259. agno/utils/log.py +1 -0
  260. agno/utils/mcp.py +92 -2
  261. agno/utils/media.py +187 -1
  262. agno/utils/merge_dict.py +3 -3
  263. agno/utils/message.py +60 -0
  264. agno/utils/models/ai_foundry.py +9 -2
  265. agno/utils/models/claude.py +49 -14
  266. agno/utils/models/cohere.py +9 -2
  267. agno/utils/models/llama.py +9 -2
  268. agno/utils/models/mistral.py +4 -2
  269. agno/utils/print_response/agent.py +109 -16
  270. agno/utils/print_response/team.py +223 -30
  271. agno/utils/print_response/workflow.py +251 -34
  272. agno/utils/streamlit.py +1 -1
  273. agno/utils/team.py +98 -9
  274. agno/utils/tokens.py +657 -0
  275. agno/vectordb/base.py +39 -7
  276. agno/vectordb/cassandra/cassandra.py +21 -5
  277. agno/vectordb/chroma/chromadb.py +43 -12
  278. agno/vectordb/clickhouse/clickhousedb.py +21 -5
  279. agno/vectordb/couchbase/couchbase.py +29 -5
  280. agno/vectordb/lancedb/lance_db.py +92 -181
  281. agno/vectordb/langchaindb/langchaindb.py +24 -4
  282. agno/vectordb/lightrag/lightrag.py +17 -3
  283. agno/vectordb/llamaindex/llamaindexdb.py +25 -5
  284. agno/vectordb/milvus/milvus.py +50 -37
  285. agno/vectordb/mongodb/__init__.py +7 -1
  286. agno/vectordb/mongodb/mongodb.py +36 -30
  287. agno/vectordb/pgvector/pgvector.py +201 -77
  288. agno/vectordb/pineconedb/pineconedb.py +41 -23
  289. agno/vectordb/qdrant/qdrant.py +67 -54
  290. agno/vectordb/redis/__init__.py +9 -0
  291. agno/vectordb/redis/redisdb.py +682 -0
  292. agno/vectordb/singlestore/singlestore.py +50 -29
  293. agno/vectordb/surrealdb/surrealdb.py +31 -41
  294. agno/vectordb/upstashdb/upstashdb.py +34 -6
  295. agno/vectordb/weaviate/weaviate.py +53 -14
  296. agno/workflow/__init__.py +2 -0
  297. agno/workflow/agent.py +299 -0
  298. agno/workflow/condition.py +120 -18
  299. agno/workflow/loop.py +77 -10
  300. agno/workflow/parallel.py +231 -143
  301. agno/workflow/router.py +118 -17
  302. agno/workflow/step.py +609 -170
  303. agno/workflow/steps.py +73 -6
  304. agno/workflow/types.py +96 -21
  305. agno/workflow/workflow.py +2039 -262
  306. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/METADATA +201 -66
  307. agno-2.3.13.dist-info/RECORD +613 -0
  308. agno/tools/googlesearch.py +0 -98
  309. agno/tools/mcp.py +0 -679
  310. agno/tools/memori.py +0 -339
  311. agno-2.1.2.dist-info/RECORD +0 -543
  312. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +0 -0
  313. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/licenses/LICENSE +0 -0
  314. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -9,10 +9,11 @@ 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.filters import FilterExpr
12
13
  from agno.knowledge.document import Document
13
14
  from agno.knowledge.embedder import Embedder
14
15
  from agno.knowledge.reranker.base import Reranker
15
- from agno.utils.log import log_debug, log_error, log_info
16
+ from agno.utils.log import log_debug, log_error, log_info, log_warning
16
17
  from agno.vectordb.base import VectorDb
17
18
  from agno.vectordb.distance import Distance
18
19
  from agno.vectordb.search import SearchType
@@ -28,6 +29,9 @@ class Milvus(VectorDb):
28
29
  def __init__(
29
30
  self,
30
31
  collection: str,
32
+ name: Optional[str] = None,
33
+ description: Optional[str] = None,
34
+ id: Optional[str] = None,
31
35
  embedder: Optional[Embedder] = None,
32
36
  distance: Distance = Distance.cosine,
33
37
  uri: str = "http://localhost:19530",
@@ -42,6 +46,8 @@ class Milvus(VectorDb):
42
46
 
43
47
  Args:
44
48
  collection (str): Name of the Milvus collection.
49
+ name (Optional[str]): Name of the vector database.
50
+ description (Optional[str]): Description of the vector database.
45
51
  embedder (Embedder): Embedder to use for embedding documents.
46
52
  distance (Distance): Distance metric to use for vector similarity.
47
53
  uri (Optional[str]): URI of the Milvus server.
@@ -63,6 +69,20 @@ class Milvus(VectorDb):
63
69
  reranker (Optional[Reranker]): Reranker to use for hybrid search results
64
70
  **kwargs: Additional keyword arguments to pass to the MilvusClient.
65
71
  """
72
+ # Validate required parameters
73
+ if not collection:
74
+ raise ValueError("Collection name must be provided.")
75
+
76
+ # Dynamic ID generation based on unique identifiers
77
+ if id is None:
78
+ from agno.utils.string import generate_id
79
+
80
+ seed = f"{uri or 'milvus'}#{collection}"
81
+ id = generate_id(seed)
82
+
83
+ # Initialize base class with name, description, and generated ID
84
+ super().__init__(id=id, name=name, description=description)
85
+
66
86
  self.collection: str = collection
67
87
 
68
88
  if embedder is None:
@@ -209,7 +229,9 @@ class Milvus(VectorDb):
209
229
  """
210
230
 
211
231
  cleaned_content = document.content.replace("\x00", "\ufffd")
212
- doc_id = md5(cleaned_content.encode()).hexdigest()
232
+ # Include content_hash in ID to ensure uniqueness across different content hashes
233
+ base_id = document.id or md5(cleaned_content.encode()).hexdigest()
234
+ doc_id = md5(f"{base_id}_{content_hash}".encode()).hexdigest()
213
235
 
214
236
  # Convert dictionary fields to JSON strings
215
237
  meta_data_str = json.dumps(document.meta_data) if document.meta_data else "{}"
@@ -297,36 +319,6 @@ class Milvus(VectorDb):
297
319
  max_length=65_535,
298
320
  )
299
321
 
300
- def doc_exists(self, document: Document) -> bool:
301
- """
302
- Validating if the document exists or not
303
-
304
- Args:
305
- document (Document): Document to validate
306
- """
307
- if self.client:
308
- cleaned_content = document.content.replace("\x00", "\ufffd")
309
- doc_id = md5(cleaned_content.encode()).hexdigest()
310
- collection_points = self.client.get(
311
- collection_name=self.collection,
312
- ids=[doc_id],
313
- )
314
- return len(collection_points) > 0
315
- return False
316
-
317
- async def async_doc_exists(self, document: Document) -> bool:
318
- """
319
- Check if document exists asynchronously.
320
- AsyncMilvusClient supports get().
321
- """
322
- cleaned_content = document.content.replace("\x00", "\ufffd")
323
- doc_id = md5(cleaned_content.encode()).hexdigest()
324
- collection_points = await self.async_client.get(
325
- collection_name=self.collection,
326
- ids=[doc_id],
327
- )
328
- return len(collection_points) > 0
329
-
330
322
  def name_exists(self, name: str) -> bool:
331
323
  """
332
324
  Validates if a document with the given name exists in the collection.
@@ -508,7 +500,9 @@ class Milvus(VectorDb):
508
500
  log_debug(f"Skipping document without embedding: {document.name} ({document.meta_data})")
509
501
  return None
510
502
  cleaned_content = document.content.replace("\x00", "\ufffd")
511
- doc_id = md5(cleaned_content.encode()).hexdigest()
503
+ # Include content_hash in ID to ensure uniqueness across different content hashes
504
+ base_id = document.id or md5(cleaned_content.encode()).hexdigest()
505
+ doc_id = md5(f"{base_id}_{content_hash}".encode()).hexdigest()
512
506
 
513
507
  meta_data = document.meta_data or {}
514
508
  if filters:
@@ -656,7 +650,9 @@ class Milvus(VectorDb):
656
650
  """
657
651
  return MILVUS_DISTANCE_MAP.get(self.distance, "COSINE")
658
652
 
659
- def search(self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None) -> List[Document]:
653
+ def search(
654
+ self, query: str, limit: int = 5, filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
655
+ ) -> List[Document]:
660
656
  """
661
657
  Search for documents matching the query.
662
658
 
@@ -668,6 +664,9 @@ class Milvus(VectorDb):
668
664
  Returns:
669
665
  List[Document]: List of matching documents
670
666
  """
667
+ if isinstance(filters, List):
668
+ log_warning("Filters Expressions are not supported in Milvus. No filters will be applied.")
669
+ filters = None
671
670
  if self.search_type == SearchType.hybrid:
672
671
  return self.hybrid_search(query, limit)
673
672
 
@@ -700,12 +699,20 @@ class Milvus(VectorDb):
700
699
  )
701
700
  )
702
701
 
702
+ # Apply reranker if available
703
+ if self.reranker and search_results:
704
+ search_results = self.reranker.rerank(query=query, documents=search_results)
705
+ search_results = search_results[:limit]
706
+
703
707
  log_info(f"Found {len(search_results)} documents")
704
708
  return search_results
705
709
 
706
710
  async def async_search(
707
- self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None
711
+ self, query: str, limit: int = 5, filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
708
712
  ) -> List[Document]:
713
+ if isinstance(filters, List):
714
+ log_warning("Filters Expressions are not supported in Milvus. No filters will be applied.")
715
+ filters = None
709
716
  if self.search_type == SearchType.hybrid:
710
717
  return await self.async_hybrid_search(query, limit, filters)
711
718
 
@@ -741,7 +748,9 @@ class Milvus(VectorDb):
741
748
  log_info(f"Found {len(search_results)} documents")
742
749
  return search_results
743
750
 
744
- def hybrid_search(self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None) -> List[Document]:
751
+ def hybrid_search(
752
+ self, query: str, limit: int = 5, filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
753
+ ) -> List[Document]:
745
754
  """
746
755
  Perform a hybrid search combining dense and sparse vector similarity.
747
756
 
@@ -833,7 +842,7 @@ class Milvus(VectorDb):
833
842
  return []
834
843
 
835
844
  async def async_hybrid_search(
836
- self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None
845
+ self, query: str, limit: int = 5, filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
837
846
  ) -> List[Document]:
838
847
  """
839
848
  Perform an asynchronous hybrid search combining dense and sparse vector similarity.
@@ -1141,3 +1150,7 @@ class Milvus(VectorDb):
1141
1150
  except Exception as e:
1142
1151
  log_error(f"Error updating metadata for content_id '{content_id}': {e}")
1143
1152
  raise
1153
+
1154
+ def get_supported_search_types(self) -> List[str]:
1155
+ """Get the supported search types for this vector database."""
1156
+ return [SearchType.vector, SearchType.hybrid]
@@ -1,3 +1,9 @@
1
1
  from agno.vectordb.mongodb.mongodb import MongoDb
2
2
 
3
- __all__ = ["MongoDb"]
3
+ # Alias to avoid name collision with the main MongoDb class
4
+ MongoVectorDb = MongoDb
5
+
6
+ __all__ = [
7
+ "MongoVectorDb",
8
+ "MongoDb",
9
+ ]
@@ -1,9 +1,10 @@
1
1
  import asyncio
2
2
  import time
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any, Dict, List, Optional, Union
4
4
 
5
5
  from bson import ObjectId
6
6
 
7
+ from agno.filters import FilterExpr
7
8
  from agno.knowledge.document import Document
8
9
  from agno.knowledge.embedder import Embedder
9
10
  from agno.utils.log import log_debug, log_info, log_warning, logger
@@ -33,6 +34,9 @@ class MongoDb(VectorDb):
33
34
  def __init__(
34
35
  self,
35
36
  collection_name: str,
37
+ name: Optional[str] = None,
38
+ description: Optional[str] = None,
39
+ id: Optional[str] = None,
36
40
  db_url: Optional[str] = "mongodb://localhost:27017/",
37
41
  database: str = "agno",
38
42
  embedder: Optional[Embedder] = None,
@@ -56,6 +60,8 @@ class MongoDb(VectorDb):
56
60
 
57
61
  Args:
58
62
  collection_name (str): Name of the MongoDB collection.
63
+ name (Optional[str]): Name of the vector database.
64
+ description (Optional[str]): Description of the vector database.
59
65
  db_url (Optional[str]): MongoDB connection string.
60
66
  database (str): Database name.
61
67
  embedder (Embedder): Embedder instance for generating embeddings.
@@ -74,11 +80,24 @@ class MongoDb(VectorDb):
74
80
  hybrid_rank_constant (int): Default rank constant (k) for Reciprocal Rank Fusion in hybrid search. This constant is added to the rank before taking the reciprocal, helping to smooth scores. A common value is 60.
75
81
  **kwargs: Additional arguments for MongoClient.
76
82
  """
83
+ # Validate required parameters
77
84
  if not collection_name:
78
85
  raise ValueError("Collection name must not be empty.")
79
86
  if not database:
80
87
  raise ValueError("Database name must not be empty.")
88
+
89
+ # Dynamic ID generation based on unique identifiers
90
+ if id is None:
91
+ from agno.utils.string import generate_id
92
+
93
+ connection_identifier = db_url or "mongodb://localhost:27017/"
94
+ seed = f"{connection_identifier}#{database}#{collection_name}"
95
+ id = generate_id(seed)
96
+
81
97
  self.collection_name = collection_name
98
+ # Initialize base class with name, description, and generated ID
99
+ super().__init__(id=id, name=name, description=description)
100
+
82
101
  self.database = database
83
102
  self.search_index_name = search_index_name
84
103
  self.cosmos_compatibility = cosmos_compatibility
@@ -452,20 +471,6 @@ class MongoDb(VectorDb):
452
471
  if self.wait_until_index_ready_in_seconds:
453
472
  await self._wait_for_index_ready_async()
454
473
 
455
- def doc_exists(self, document: Document) -> bool:
456
- """Check if a document exists in the MongoDB collection based on its content."""
457
- try:
458
- collection = self._get_collection()
459
- # Use content hash as document ID
460
- doc_id = md5(document.content.encode("utf-8")).hexdigest()
461
- result = collection.find_one({"_id": doc_id})
462
- exists = result is not None
463
- log_debug(f"Document {'exists' if exists else 'does not exist'}: {doc_id}")
464
- return exists
465
- except Exception as e:
466
- logger.error(f"Error checking document existence: {e}")
467
- return False
468
-
469
474
  def name_exists(self, name: str) -> bool:
470
475
  """Check if a document with a given name exists in the collection."""
471
476
  try:
@@ -567,9 +572,16 @@ class MongoDb(VectorDb):
567
572
  return True
568
573
 
569
574
  def search(
570
- self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None, min_score: float = 0.0
575
+ self,
576
+ query: str,
577
+ limit: int = 5,
578
+ filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
579
+ min_score: float = 0.0,
571
580
  ) -> List[Document]:
572
581
  """Search for documents using vector similarity."""
582
+ if isinstance(filters, List):
583
+ log_warning("Filters Expressions are not supported in MongoDB. No filters will be applied.")
584
+ filters = None
573
585
  if self.search_type == SearchType.hybrid:
574
586
  return self.hybrid_search(query, limit=limit, filters=filters)
575
587
 
@@ -998,19 +1010,6 @@ class MongoDb(VectorDb):
998
1010
  logger.error(f"Error getting document count: {e}")
999
1011
  return 0
1000
1012
 
1001
- async def async_doc_exists(self, document: Document) -> bool:
1002
- """Check if a document exists asynchronously."""
1003
- try:
1004
- collection = await self._get_async_collection()
1005
- doc_id = md5(document.content.encode("utf-8")).hexdigest()
1006
- result = await collection.find_one({"_id": doc_id})
1007
- exists = result is not None
1008
- log_debug(f"Document {'exists' if exists else 'does not exist'}: {doc_id}")
1009
- return exists
1010
- except Exception as e:
1011
- logger.error(f"Error checking document existence asynchronously: {e}")
1012
- return False
1013
-
1014
1013
  async def async_insert(
1015
1014
  self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
1016
1015
  ) -> None:
@@ -1135,9 +1134,12 @@ class MongoDb(VectorDb):
1135
1134
  logger.error(f"Error upserting document '{document.name}' asynchronously: {e}")
1136
1135
 
1137
1136
  async def async_search(
1138
- self, query: str, limit: int = 5, filters: Optional[Dict[str, Any]] = None
1137
+ self, query: str, limit: int = 5, filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
1139
1138
  ) -> List[Document]:
1140
1139
  """Search for documents asynchronously."""
1140
+ if isinstance(filters, List):
1141
+ log_warning("Filters Expressions are not supported in MongoDB. No filters will be applied.")
1142
+ filters = None
1141
1143
  query_embedding = self.embedder.get_embedding(query)
1142
1144
  if query_embedding is None:
1143
1145
  logger.error(f"Failed to generate embedding for query: {query}")
@@ -1382,3 +1384,7 @@ class MongoDb(VectorDb):
1382
1384
  except Exception as e:
1383
1385
  logger.error(f"Error updating metadata for content_id '{content_id}': {e}")
1384
1386
  raise
1387
+
1388
+ def get_supported_search_types(self) -> List[str]:
1389
+ """Get the supported search types for this vector database."""
1390
+ return [SearchType.vector, SearchType.hybrid]