agno 2.1.0__tar.gz → 2.1.2__tar.gz

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 (552) hide show
  1. {agno-2.1.0 → agno-2.1.2}/PKG-INFO +16 -14
  2. {agno-2.1.0 → agno-2.1.2}/README.md +12 -12
  3. {agno-2.1.0 → agno-2.1.2}/agno/agent/agent.py +13 -1
  4. {agno-2.1.0 → agno-2.1.2}/agno/db/base.py +8 -4
  5. {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/dynamo.py +69 -17
  6. {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/firestore.py +68 -29
  7. {agno-2.1.0 → agno-2.1.2}/agno/db/gcs_json/gcs_json_db.py +68 -17
  8. {agno-2.1.0 → agno-2.1.2}/agno/db/in_memory/in_memory_db.py +83 -14
  9. {agno-2.1.0 → agno-2.1.2}/agno/db/json/json_db.py +79 -15
  10. {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/mongo.py +92 -74
  11. {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/mysql.py +17 -3
  12. {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/postgres.py +21 -3
  13. {agno-2.1.0 → agno-2.1.2}/agno/db/redis/redis.py +38 -11
  14. {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/singlestore.py +14 -3
  15. {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/sqlite.py +34 -46
  16. agno-2.1.2/agno/db/utils.py +116 -0
  17. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/knowledge.py +6 -0
  18. agno-2.1.2/agno/knowledge/reader/field_labeled_csv_reader.py +294 -0
  19. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/pdf_reader.py +28 -52
  20. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/reader_factory.py +12 -0
  21. {agno-2.1.0 → agno-2.1.2}/agno/memory/manager.py +12 -4
  22. {agno-2.1.0 → agno-2.1.2}/agno/models/anthropic/claude.py +4 -1
  23. {agno-2.1.0 → agno-2.1.2}/agno/models/aws/bedrock.py +52 -112
  24. {agno-2.1.0 → agno-2.1.2}/agno/models/openai/responses.py +1 -1
  25. {agno-2.1.0 → agno-2.1.2}/agno/os/app.py +24 -30
  26. agno-2.1.2/agno/os/interfaces/__init__.py +1 -0
  27. agno-2.1.2/agno/os/interfaces/a2a/__init__.py +3 -0
  28. agno-2.1.2/agno/os/interfaces/a2a/a2a.py +42 -0
  29. agno-2.1.2/agno/os/interfaces/a2a/router.py +252 -0
  30. agno-2.1.2/agno/os/interfaces/a2a/utils.py +924 -0
  31. agno-2.1.2/agno/os/interfaces/agui/agui.py +47 -0
  32. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/agui/router.py +12 -0
  33. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/base.py +4 -2
  34. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/slack.py +13 -8
  35. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/whatsapp.py +12 -5
  36. {agno-2.1.0 → agno-2.1.2}/agno/os/mcp.py +1 -1
  37. {agno-2.1.0 → agno-2.1.2}/agno/os/router.py +39 -9
  38. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/memory/memory.py +5 -3
  39. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/memory/schemas.py +1 -0
  40. {agno-2.1.0 → agno-2.1.2}/agno/os/utils.py +36 -10
  41. {agno-2.1.0 → agno-2.1.2}/agno/run/base.py +2 -13
  42. {agno-2.1.0 → agno-2.1.2}/agno/team/team.py +13 -1
  43. {agno-2.1.0 → agno-2.1.2}/agno/tools/mcp.py +46 -1
  44. agno-2.1.2/agno/utils/merge_dict.py +41 -0
  45. agno-2.1.2/agno/utils/serialize.py +32 -0
  46. {agno-2.1.0 → agno-2.1.2}/agno/utils/streamlit.py +1 -1
  47. {agno-2.1.0 → agno-2.1.2}/agno/workflow/parallel.py +90 -14
  48. {agno-2.1.0 → agno-2.1.2}/agno/workflow/step.py +30 -27
  49. {agno-2.1.0 → agno-2.1.2}/agno/workflow/types.py +4 -6
  50. {agno-2.1.0 → agno-2.1.2}/agno/workflow/workflow.py +5 -3
  51. {agno-2.1.0 → agno-2.1.2}/agno.egg-info/PKG-INFO +16 -14
  52. {agno-2.1.0 → agno-2.1.2}/agno.egg-info/SOURCES.txt +6 -0
  53. {agno-2.1.0 → agno-2.1.2}/agno.egg-info/requires.txt +5 -1
  54. {agno-2.1.0 → agno-2.1.2}/pyproject.toml +6 -2
  55. agno-2.1.0/agno/db/utils.py +0 -88
  56. agno-2.1.0/agno/os/interfaces/agui/agui.py +0 -31
  57. agno-2.1.0/agno/utils/merge_dict.py +0 -20
  58. agno-2.1.0/agno/utils/print_response/__init__.py +0 -0
  59. {agno-2.1.0 → agno-2.1.2}/LICENSE +0 -0
  60. {agno-2.1.0 → agno-2.1.2}/agno/__init__.py +0 -0
  61. {agno-2.1.0 → agno-2.1.2}/agno/agent/__init__.py +0 -0
  62. {agno-2.1.0 → agno-2.1.2}/agno/api/__init__.py +0 -0
  63. {agno-2.1.0 → agno-2.1.2}/agno/api/agent.py +0 -0
  64. {agno-2.1.0 → agno-2.1.2}/agno/api/api.py +0 -0
  65. {agno-2.1.0 → agno-2.1.2}/agno/api/evals.py +0 -0
  66. {agno-2.1.0 → agno-2.1.2}/agno/api/os.py +0 -0
  67. {agno-2.1.0 → agno-2.1.2}/agno/api/routes.py +0 -0
  68. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/__init__.py +0 -0
  69. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/agent.py +0 -0
  70. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/evals.py +0 -0
  71. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/os.py +0 -0
  72. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/response.py +0 -0
  73. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/team.py +0 -0
  74. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/utils.py +0 -0
  75. {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/workflows.py +0 -0
  76. {agno-2.1.0 → agno-2.1.2}/agno/api/settings.py +0 -0
  77. {agno-2.1.0 → agno-2.1.2}/agno/api/team.py +0 -0
  78. {agno-2.1.0 → agno-2.1.2}/agno/api/workflow.py +0 -0
  79. {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/base.py +0 -0
  80. {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/__init__.py +0 -0
  81. {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/api_client.py +0 -0
  82. {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/bucket.py +0 -0
  83. {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/object.py +0 -0
  84. {agno-2.1.0 → agno-2.1.2}/agno/db/__init__.py +0 -0
  85. {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/__init__.py +0 -0
  86. {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/schemas.py +0 -0
  87. {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/utils.py +0 -0
  88. {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/__init__.py +0 -0
  89. {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/schemas.py +0 -0
  90. {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/utils.py +0 -0
  91. {agno-2.1.0 → agno-2.1.2}/agno/db/gcs_json/__init__.py +0 -0
  92. {agno-2.1.0 → agno-2.1.2}/agno/db/gcs_json/utils.py +0 -0
  93. {agno-2.1.0 → agno-2.1.2}/agno/db/in_memory/__init__.py +0 -0
  94. {agno-2.1.0 → agno-2.1.2}/agno/db/in_memory/utils.py +0 -0
  95. {agno-2.1.0 → agno-2.1.2}/agno/db/json/__init__.py +0 -0
  96. {agno-2.1.0 → agno-2.1.2}/agno/db/json/utils.py +0 -0
  97. {agno-2.1.0 → agno-2.1.2}/agno/db/migrations/__init__.py +0 -0
  98. {agno-2.1.0 → agno-2.1.2}/agno/db/migrations/v1_to_v2.py +0 -0
  99. {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/__init__.py +0 -0
  100. {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/schemas.py +0 -0
  101. {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/utils.py +0 -0
  102. {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/__init__.py +0 -0
  103. {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/schemas.py +0 -0
  104. {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/utils.py +0 -0
  105. {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/__init__.py +0 -0
  106. {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/schemas.py +0 -0
  107. {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/utils.py +0 -0
  108. {agno-2.1.0 → agno-2.1.2}/agno/db/redis/__init__.py +0 -0
  109. {agno-2.1.0 → agno-2.1.2}/agno/db/redis/schemas.py +0 -0
  110. {agno-2.1.0 → agno-2.1.2}/agno/db/redis/utils.py +0 -0
  111. {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/__init__.py +0 -0
  112. {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/evals.py +0 -0
  113. {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/knowledge.py +0 -0
  114. {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/memory.py +0 -0
  115. {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/metrics.py +0 -0
  116. {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/__init__.py +0 -0
  117. {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/schemas.py +0 -0
  118. {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/utils.py +0 -0
  119. {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/__init__.py +0 -0
  120. {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/schemas.py +0 -0
  121. {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/utils.py +0 -0
  122. {agno-2.1.0 → agno-2.1.2}/agno/debug.py +0 -0
  123. {agno-2.1.0 → agno-2.1.2}/agno/eval/__init__.py +0 -0
  124. {agno-2.1.0 → agno-2.1.2}/agno/eval/accuracy.py +0 -0
  125. {agno-2.1.0 → agno-2.1.2}/agno/eval/performance.py +0 -0
  126. {agno-2.1.0 → agno-2.1.2}/agno/eval/reliability.py +0 -0
  127. {agno-2.1.0 → agno-2.1.2}/agno/eval/utils.py +0 -0
  128. {agno-2.1.0 → agno-2.1.2}/agno/exceptions.py +0 -0
  129. {agno-2.1.0 → agno-2.1.2}/agno/guardrails/__init__.py +0 -0
  130. {agno-2.1.0 → agno-2.1.2}/agno/guardrails/base.py +0 -0
  131. {agno-2.1.0 → agno-2.1.2}/agno/guardrails/openai.py +0 -0
  132. {agno-2.1.0 → agno-2.1.2}/agno/guardrails/pii.py +0 -0
  133. {agno-2.1.0 → agno-2.1.2}/agno/guardrails/prompt_injection.py +0 -0
  134. {agno-2.1.0 → agno-2.1.2}/agno/integrations/__init__.py +0 -0
  135. {agno-2.1.0 → agno-2.1.2}/agno/integrations/discord/__init__.py +0 -0
  136. {agno-2.1.0 → agno-2.1.2}/agno/integrations/discord/client.py +0 -0
  137. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/__init__.py +0 -0
  138. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/__init__.py +0 -0
  139. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/agentic.py +0 -0
  140. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/document.py +0 -0
  141. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/fixed.py +0 -0
  142. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/markdown.py +0 -0
  143. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/recursive.py +0 -0
  144. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/row.py +0 -0
  145. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/semantic.py +0 -0
  146. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/strategy.py +0 -0
  147. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/content.py +0 -0
  148. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/document/__init__.py +0 -0
  149. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/document/base.py +0 -0
  150. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/__init__.py +0 -0
  151. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/aws_bedrock.py +0 -0
  152. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/azure_openai.py +0 -0
  153. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/base.py +0 -0
  154. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/cohere.py +0 -0
  155. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/fastembed.py +0 -0
  156. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/fireworks.py +0 -0
  157. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/google.py +0 -0
  158. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/huggingface.py +0 -0
  159. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/jina.py +0 -0
  160. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/langdb.py +0 -0
  161. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/mistral.py +0 -0
  162. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/nebius.py +0 -0
  163. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/ollama.py +0 -0
  164. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/openai.py +0 -0
  165. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/sentence_transformer.py +0 -0
  166. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/together.py +0 -0
  167. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/voyageai.py +0 -0
  168. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/__init__.py +0 -0
  169. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/arxiv_reader.py +0 -0
  170. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/base.py +0 -0
  171. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/csv_reader.py +0 -0
  172. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/docx_reader.py +0 -0
  173. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/firecrawl_reader.py +0 -0
  174. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/json_reader.py +0 -0
  175. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/markdown_reader.py +0 -0
  176. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/s3_reader.py +0 -0
  177. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/text_reader.py +0 -0
  178. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/web_search_reader.py +0 -0
  179. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/website_reader.py +0 -0
  180. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/wikipedia_reader.py +0 -0
  181. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/youtube_reader.py +0 -0
  182. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/remote_content/__init__.py +0 -0
  183. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/remote_content/remote_content.py +0 -0
  184. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/__init__.py +0 -0
  185. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/base.py +0 -0
  186. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/cohere.py +0 -0
  187. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/infinity.py +0 -0
  188. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/sentence_transformer.py +0 -0
  189. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/types.py +0 -0
  190. {agno-2.1.0 → agno-2.1.2}/agno/knowledge/utils.py +0 -0
  191. {agno-2.1.0 → agno-2.1.2}/agno/media.py +0 -0
  192. {agno-2.1.0 → agno-2.1.2}/agno/memory/__init__.py +0 -0
  193. {agno-2.1.0 → agno-2.1.2}/agno/models/__init__.py +0 -0
  194. {agno-2.1.0 → agno-2.1.2}/agno/models/aimlapi/__init__.py +0 -0
  195. {agno-2.1.0 → agno-2.1.2}/agno/models/aimlapi/aimlapi.py +0 -0
  196. {agno-2.1.0 → agno-2.1.2}/agno/models/anthropic/__init__.py +0 -0
  197. {agno-2.1.0 → agno-2.1.2}/agno/models/aws/__init__.py +0 -0
  198. {agno-2.1.0 → agno-2.1.2}/agno/models/aws/claude.py +0 -0
  199. {agno-2.1.0 → agno-2.1.2}/agno/models/azure/__init__.py +0 -0
  200. {agno-2.1.0 → agno-2.1.2}/agno/models/azure/ai_foundry.py +0 -0
  201. {agno-2.1.0 → agno-2.1.2}/agno/models/azure/openai_chat.py +0 -0
  202. {agno-2.1.0 → agno-2.1.2}/agno/models/base.py +0 -0
  203. {agno-2.1.0 → agno-2.1.2}/agno/models/cerebras/__init__.py +0 -0
  204. {agno-2.1.0 → agno-2.1.2}/agno/models/cerebras/cerebras.py +0 -0
  205. {agno-2.1.0 → agno-2.1.2}/agno/models/cerebras/cerebras_openai.py +0 -0
  206. {agno-2.1.0 → agno-2.1.2}/agno/models/cohere/__init__.py +0 -0
  207. {agno-2.1.0 → agno-2.1.2}/agno/models/cohere/chat.py +0 -0
  208. {agno-2.1.0 → agno-2.1.2}/agno/models/cometapi/__init__.py +0 -0
  209. {agno-2.1.0 → agno-2.1.2}/agno/models/cometapi/cometapi.py +0 -0
  210. {agno-2.1.0 → agno-2.1.2}/agno/models/dashscope/__init__.py +0 -0
  211. {agno-2.1.0 → agno-2.1.2}/agno/models/dashscope/dashscope.py +0 -0
  212. {agno-2.1.0 → agno-2.1.2}/agno/models/deepinfra/__init__.py +0 -0
  213. {agno-2.1.0 → agno-2.1.2}/agno/models/deepinfra/deepinfra.py +0 -0
  214. {agno-2.1.0 → agno-2.1.2}/agno/models/deepseek/__init__.py +0 -0
  215. {agno-2.1.0 → agno-2.1.2}/agno/models/deepseek/deepseek.py +0 -0
  216. {agno-2.1.0 → agno-2.1.2}/agno/models/defaults.py +0 -0
  217. {agno-2.1.0 → agno-2.1.2}/agno/models/fireworks/__init__.py +0 -0
  218. {agno-2.1.0 → agno-2.1.2}/agno/models/fireworks/fireworks.py +0 -0
  219. {agno-2.1.0 → agno-2.1.2}/agno/models/google/__init__.py +0 -0
  220. {agno-2.1.0 → agno-2.1.2}/agno/models/google/gemini.py +0 -0
  221. {agno-2.1.0 → agno-2.1.2}/agno/models/groq/__init__.py +0 -0
  222. {agno-2.1.0 → agno-2.1.2}/agno/models/groq/groq.py +0 -0
  223. {agno-2.1.0 → agno-2.1.2}/agno/models/huggingface/__init__.py +0 -0
  224. {agno-2.1.0 → agno-2.1.2}/agno/models/huggingface/huggingface.py +0 -0
  225. {agno-2.1.0 → agno-2.1.2}/agno/models/ibm/__init__.py +0 -0
  226. {agno-2.1.0 → agno-2.1.2}/agno/models/ibm/watsonx.py +0 -0
  227. {agno-2.1.0 → agno-2.1.2}/agno/models/internlm/__init__.py +0 -0
  228. {agno-2.1.0 → agno-2.1.2}/agno/models/internlm/internlm.py +0 -0
  229. {agno-2.1.0 → agno-2.1.2}/agno/models/langdb/__init__.py +0 -0
  230. {agno-2.1.0 → agno-2.1.2}/agno/models/langdb/langdb.py +0 -0
  231. {agno-2.1.0 → agno-2.1.2}/agno/models/litellm/__init__.py +0 -0
  232. {agno-2.1.0 → agno-2.1.2}/agno/models/litellm/chat.py +0 -0
  233. {agno-2.1.0 → agno-2.1.2}/agno/models/litellm/litellm_openai.py +0 -0
  234. {agno-2.1.0 → agno-2.1.2}/agno/models/llama_cpp/__init__.py +0 -0
  235. {agno-2.1.0 → agno-2.1.2}/agno/models/llama_cpp/llama_cpp.py +0 -0
  236. {agno-2.1.0 → agno-2.1.2}/agno/models/lmstudio/__init__.py +0 -0
  237. {agno-2.1.0 → agno-2.1.2}/agno/models/lmstudio/lmstudio.py +0 -0
  238. {agno-2.1.0 → agno-2.1.2}/agno/models/message.py +0 -0
  239. {agno-2.1.0 → agno-2.1.2}/agno/models/meta/__init__.py +0 -0
  240. {agno-2.1.0 → agno-2.1.2}/agno/models/meta/llama.py +0 -0
  241. {agno-2.1.0 → agno-2.1.2}/agno/models/meta/llama_openai.py +0 -0
  242. {agno-2.1.0 → agno-2.1.2}/agno/models/metrics.py +0 -0
  243. {agno-2.1.0 → agno-2.1.2}/agno/models/mistral/__init__.py +0 -0
  244. {agno-2.1.0 → agno-2.1.2}/agno/models/mistral/mistral.py +0 -0
  245. {agno-2.1.0 → agno-2.1.2}/agno/models/nebius/__init__.py +0 -0
  246. {agno-2.1.0 → agno-2.1.2}/agno/models/nebius/nebius.py +0 -0
  247. {agno-2.1.0 → agno-2.1.2}/agno/models/nexus/__init__.py +0 -0
  248. {agno-2.1.0 → agno-2.1.2}/agno/models/nexus/nexus.py +0 -0
  249. {agno-2.1.0 → agno-2.1.2}/agno/models/nvidia/__init__.py +0 -0
  250. {agno-2.1.0 → agno-2.1.2}/agno/models/nvidia/nvidia.py +0 -0
  251. {agno-2.1.0 → agno-2.1.2}/agno/models/ollama/__init__.py +0 -0
  252. {agno-2.1.0 → agno-2.1.2}/agno/models/ollama/chat.py +0 -0
  253. {agno-2.1.0 → agno-2.1.2}/agno/models/openai/__init__.py +0 -0
  254. {agno-2.1.0 → agno-2.1.2}/agno/models/openai/chat.py +0 -0
  255. {agno-2.1.0 → agno-2.1.2}/agno/models/openai/like.py +0 -0
  256. {agno-2.1.0 → agno-2.1.2}/agno/models/openrouter/__init__.py +0 -0
  257. {agno-2.1.0 → agno-2.1.2}/agno/models/openrouter/openrouter.py +0 -0
  258. {agno-2.1.0 → agno-2.1.2}/agno/models/perplexity/__init__.py +0 -0
  259. {agno-2.1.0 → agno-2.1.2}/agno/models/perplexity/perplexity.py +0 -0
  260. {agno-2.1.0 → agno-2.1.2}/agno/models/portkey/__init__.py +0 -0
  261. {agno-2.1.0 → agno-2.1.2}/agno/models/portkey/portkey.py +0 -0
  262. {agno-2.1.0 → agno-2.1.2}/agno/models/requesty/__init__.py +0 -0
  263. {agno-2.1.0 → agno-2.1.2}/agno/models/requesty/requesty.py +0 -0
  264. {agno-2.1.0 → agno-2.1.2}/agno/models/response.py +0 -0
  265. {agno-2.1.0 → agno-2.1.2}/agno/models/sambanova/__init__.py +0 -0
  266. {agno-2.1.0 → agno-2.1.2}/agno/models/sambanova/sambanova.py +0 -0
  267. {agno-2.1.0 → agno-2.1.2}/agno/models/siliconflow/__init__.py +0 -0
  268. {agno-2.1.0 → agno-2.1.2}/agno/models/siliconflow/siliconflow.py +0 -0
  269. {agno-2.1.0 → agno-2.1.2}/agno/models/together/__init__.py +0 -0
  270. {agno-2.1.0 → agno-2.1.2}/agno/models/together/together.py +0 -0
  271. {agno-2.1.0 → agno-2.1.2}/agno/models/utils.py +0 -0
  272. {agno-2.1.0 → agno-2.1.2}/agno/models/vercel/__init__.py +0 -0
  273. {agno-2.1.0 → agno-2.1.2}/agno/models/vercel/v0.py +0 -0
  274. {agno-2.1.0 → agno-2.1.2}/agno/models/vllm/__init__.py +0 -0
  275. {agno-2.1.0 → agno-2.1.2}/agno/models/vllm/vllm.py +0 -0
  276. {agno-2.1.0 → agno-2.1.2}/agno/models/xai/__init__.py +0 -0
  277. {agno-2.1.0 → agno-2.1.2}/agno/models/xai/xai.py +0 -0
  278. {agno-2.1.0 → agno-2.1.2}/agno/os/__init__.py +0 -0
  279. {agno-2.1.0 → agno-2.1.2}/agno/os/auth.py +0 -0
  280. {agno-2.1.0 → agno-2.1.2}/agno/os/config.py +0 -0
  281. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/agui/__init__.py +0 -0
  282. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/agui/utils.py +0 -0
  283. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/__init__.py +0 -0
  284. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/router.py +0 -0
  285. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/security.py +0 -0
  286. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/__init__.py +0 -0
  287. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/router.py +0 -0
  288. {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/security.py +0 -0
  289. {agno-2.1.0 → agno-2.1.2}/agno/os/middleware/__init__.py +0 -0
  290. {agno-2.1.0 → agno-2.1.2}/agno/os/middleware/jwt.py +0 -0
  291. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/__init__.py +0 -0
  292. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/__init__.py +0 -0
  293. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/evals.py +0 -0
  294. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/schemas.py +0 -0
  295. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/utils.py +0 -0
  296. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/health.py +0 -0
  297. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/home.py +0 -0
  298. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/knowledge/__init__.py +0 -0
  299. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/knowledge/knowledge.py +0 -0
  300. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/knowledge/schemas.py +0 -0
  301. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/memory/__init__.py +0 -0
  302. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/metrics/__init__.py +0 -0
  303. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/metrics/metrics.py +0 -0
  304. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/metrics/schemas.py +0 -0
  305. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/session/__init__.py +0 -0
  306. {agno-2.1.0 → agno-2.1.2}/agno/os/routers/session/session.py +0 -0
  307. {agno-2.1.0 → agno-2.1.2}/agno/os/schema.py +0 -0
  308. {agno-2.1.0 → agno-2.1.2}/agno/os/settings.py +0 -0
  309. {agno-2.1.0 → agno-2.1.2}/agno/py.typed +0 -0
  310. {agno-2.1.0/agno/os/interfaces → agno-2.1.2/agno/reasoning}/__init__.py +0 -0
  311. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/azure_ai_foundry.py +0 -0
  312. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/deepseek.py +0 -0
  313. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/default.py +0 -0
  314. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/groq.py +0 -0
  315. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/helpers.py +0 -0
  316. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/ollama.py +0 -0
  317. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/openai.py +0 -0
  318. {agno-2.1.0 → agno-2.1.2}/agno/reasoning/step.py +0 -0
  319. {agno-2.1.0/agno/reasoning → agno-2.1.2/agno/run}/__init__.py +0 -0
  320. {agno-2.1.0 → agno-2.1.2}/agno/run/agent.py +0 -0
  321. {agno-2.1.0 → agno-2.1.2}/agno/run/cancel.py +0 -0
  322. {agno-2.1.0 → agno-2.1.2}/agno/run/messages.py +0 -0
  323. {agno-2.1.0 → agno-2.1.2}/agno/run/team.py +0 -0
  324. {agno-2.1.0 → agno-2.1.2}/agno/run/workflow.py +0 -0
  325. {agno-2.1.0 → agno-2.1.2}/agno/session/__init__.py +0 -0
  326. {agno-2.1.0 → agno-2.1.2}/agno/session/agent.py +0 -0
  327. {agno-2.1.0 → agno-2.1.2}/agno/session/summary.py +0 -0
  328. {agno-2.1.0 → agno-2.1.2}/agno/session/team.py +0 -0
  329. {agno-2.1.0 → agno-2.1.2}/agno/session/workflow.py +0 -0
  330. {agno-2.1.0 → agno-2.1.2}/agno/team/__init__.py +0 -0
  331. {agno-2.1.0 → agno-2.1.2}/agno/tools/__init__.py +0 -0
  332. {agno-2.1.0 → agno-2.1.2}/agno/tools/agentql.py +0 -0
  333. {agno-2.1.0 → agno-2.1.2}/agno/tools/airflow.py +0 -0
  334. {agno-2.1.0 → agno-2.1.2}/agno/tools/api.py +0 -0
  335. {agno-2.1.0 → agno-2.1.2}/agno/tools/apify.py +0 -0
  336. {agno-2.1.0 → agno-2.1.2}/agno/tools/arxiv.py +0 -0
  337. {agno-2.1.0 → agno-2.1.2}/agno/tools/aws_lambda.py +0 -0
  338. {agno-2.1.0 → agno-2.1.2}/agno/tools/aws_ses.py +0 -0
  339. {agno-2.1.0 → agno-2.1.2}/agno/tools/baidusearch.py +0 -0
  340. {agno-2.1.0 → agno-2.1.2}/agno/tools/bitbucket.py +0 -0
  341. {agno-2.1.0 → agno-2.1.2}/agno/tools/brandfetch.py +0 -0
  342. {agno-2.1.0 → agno-2.1.2}/agno/tools/bravesearch.py +0 -0
  343. {agno-2.1.0 → agno-2.1.2}/agno/tools/brightdata.py +0 -0
  344. {agno-2.1.0 → agno-2.1.2}/agno/tools/browserbase.py +0 -0
  345. {agno-2.1.0 → agno-2.1.2}/agno/tools/calcom.py +0 -0
  346. {agno-2.1.0 → agno-2.1.2}/agno/tools/calculator.py +0 -0
  347. {agno-2.1.0 → agno-2.1.2}/agno/tools/cartesia.py +0 -0
  348. {agno-2.1.0 → agno-2.1.2}/agno/tools/clickup.py +0 -0
  349. {agno-2.1.0 → agno-2.1.2}/agno/tools/confluence.py +0 -0
  350. {agno-2.1.0 → agno-2.1.2}/agno/tools/crawl4ai.py +0 -0
  351. {agno-2.1.0 → agno-2.1.2}/agno/tools/csv_toolkit.py +0 -0
  352. {agno-2.1.0 → agno-2.1.2}/agno/tools/dalle.py +0 -0
  353. {agno-2.1.0 → agno-2.1.2}/agno/tools/daytona.py +0 -0
  354. {agno-2.1.0 → agno-2.1.2}/agno/tools/decorator.py +0 -0
  355. {agno-2.1.0 → agno-2.1.2}/agno/tools/desi_vocal.py +0 -0
  356. {agno-2.1.0 → agno-2.1.2}/agno/tools/discord.py +0 -0
  357. {agno-2.1.0 → agno-2.1.2}/agno/tools/docker.py +0 -0
  358. {agno-2.1.0 → agno-2.1.2}/agno/tools/duckdb.py +0 -0
  359. {agno-2.1.0 → agno-2.1.2}/agno/tools/duckduckgo.py +0 -0
  360. {agno-2.1.0 → agno-2.1.2}/agno/tools/e2b.py +0 -0
  361. {agno-2.1.0 → agno-2.1.2}/agno/tools/eleven_labs.py +0 -0
  362. {agno-2.1.0 → agno-2.1.2}/agno/tools/email.py +0 -0
  363. {agno-2.1.0 → agno-2.1.2}/agno/tools/evm.py +0 -0
  364. {agno-2.1.0 → agno-2.1.2}/agno/tools/exa.py +0 -0
  365. {agno-2.1.0 → agno-2.1.2}/agno/tools/fal.py +0 -0
  366. {agno-2.1.0 → agno-2.1.2}/agno/tools/file.py +0 -0
  367. {agno-2.1.0 → agno-2.1.2}/agno/tools/file_generation.py +0 -0
  368. {agno-2.1.0 → agno-2.1.2}/agno/tools/financial_datasets.py +0 -0
  369. {agno-2.1.0 → agno-2.1.2}/agno/tools/firecrawl.py +0 -0
  370. {agno-2.1.0 → agno-2.1.2}/agno/tools/function.py +0 -0
  371. {agno-2.1.0 → agno-2.1.2}/agno/tools/giphy.py +0 -0
  372. {agno-2.1.0 → agno-2.1.2}/agno/tools/github.py +0 -0
  373. {agno-2.1.0 → agno-2.1.2}/agno/tools/gmail.py +0 -0
  374. {agno-2.1.0 → agno-2.1.2}/agno/tools/google_bigquery.py +0 -0
  375. {agno-2.1.0 → agno-2.1.2}/agno/tools/google_maps.py +0 -0
  376. {agno-2.1.0 → agno-2.1.2}/agno/tools/googlecalendar.py +0 -0
  377. {agno-2.1.0 → agno-2.1.2}/agno/tools/googlesearch.py +0 -0
  378. {agno-2.1.0 → agno-2.1.2}/agno/tools/googlesheets.py +0 -0
  379. {agno-2.1.0 → agno-2.1.2}/agno/tools/hackernews.py +0 -0
  380. {agno-2.1.0 → agno-2.1.2}/agno/tools/jina.py +0 -0
  381. {agno-2.1.0 → agno-2.1.2}/agno/tools/jira.py +0 -0
  382. {agno-2.1.0 → agno-2.1.2}/agno/tools/knowledge.py +0 -0
  383. {agno-2.1.0 → agno-2.1.2}/agno/tools/linear.py +0 -0
  384. {agno-2.1.0 → agno-2.1.2}/agno/tools/linkup.py +0 -0
  385. {agno-2.1.0 → agno-2.1.2}/agno/tools/local_file_system.py +0 -0
  386. {agno-2.1.0 → agno-2.1.2}/agno/tools/lumalab.py +0 -0
  387. {agno-2.1.0 → agno-2.1.2}/agno/tools/mcp_toolbox.py +0 -0
  388. {agno-2.1.0 → agno-2.1.2}/agno/tools/mem0.py +0 -0
  389. {agno-2.1.0 → agno-2.1.2}/agno/tools/memori.py +0 -0
  390. {agno-2.1.0 → agno-2.1.2}/agno/tools/memory.py +0 -0
  391. {agno-2.1.0 → agno-2.1.2}/agno/tools/mlx_transcribe.py +0 -0
  392. {agno-2.1.0/agno/run → agno-2.1.2/agno/tools/models}/__init__.py +0 -0
  393. {agno-2.1.0 → agno-2.1.2}/agno/tools/models/azure_openai.py +0 -0
  394. {agno-2.1.0 → agno-2.1.2}/agno/tools/models/gemini.py +0 -0
  395. {agno-2.1.0 → agno-2.1.2}/agno/tools/models/groq.py +0 -0
  396. {agno-2.1.0 → agno-2.1.2}/agno/tools/models/morph.py +0 -0
  397. {agno-2.1.0 → agno-2.1.2}/agno/tools/models/nebius.py +0 -0
  398. {agno-2.1.0 → agno-2.1.2}/agno/tools/models_labs.py +0 -0
  399. {agno-2.1.0 → agno-2.1.2}/agno/tools/moviepy_video.py +0 -0
  400. {agno-2.1.0 → agno-2.1.2}/agno/tools/neo4j.py +0 -0
  401. {agno-2.1.0 → agno-2.1.2}/agno/tools/newspaper.py +0 -0
  402. {agno-2.1.0 → agno-2.1.2}/agno/tools/newspaper4k.py +0 -0
  403. {agno-2.1.0 → agno-2.1.2}/agno/tools/openai.py +0 -0
  404. {agno-2.1.0 → agno-2.1.2}/agno/tools/openbb.py +0 -0
  405. {agno-2.1.0 → agno-2.1.2}/agno/tools/opencv.py +0 -0
  406. {agno-2.1.0 → agno-2.1.2}/agno/tools/openweather.py +0 -0
  407. {agno-2.1.0 → agno-2.1.2}/agno/tools/oxylabs.py +0 -0
  408. {agno-2.1.0 → agno-2.1.2}/agno/tools/pandas.py +0 -0
  409. {agno-2.1.0 → agno-2.1.2}/agno/tools/postgres.py +0 -0
  410. {agno-2.1.0 → agno-2.1.2}/agno/tools/pubmed.py +0 -0
  411. {agno-2.1.0 → agno-2.1.2}/agno/tools/python.py +0 -0
  412. {agno-2.1.0 → agno-2.1.2}/agno/tools/reasoning.py +0 -0
  413. {agno-2.1.0 → agno-2.1.2}/agno/tools/reddit.py +0 -0
  414. {agno-2.1.0 → agno-2.1.2}/agno/tools/replicate.py +0 -0
  415. {agno-2.1.0 → agno-2.1.2}/agno/tools/resend.py +0 -0
  416. {agno-2.1.0 → agno-2.1.2}/agno/tools/scrapegraph.py +0 -0
  417. {agno-2.1.0 → agno-2.1.2}/agno/tools/searxng.py +0 -0
  418. {agno-2.1.0 → agno-2.1.2}/agno/tools/serpapi.py +0 -0
  419. {agno-2.1.0 → agno-2.1.2}/agno/tools/serper.py +0 -0
  420. {agno-2.1.0 → agno-2.1.2}/agno/tools/shell.py +0 -0
  421. {agno-2.1.0 → agno-2.1.2}/agno/tools/slack.py +0 -0
  422. {agno-2.1.0 → agno-2.1.2}/agno/tools/sleep.py +0 -0
  423. {agno-2.1.0 → agno-2.1.2}/agno/tools/spider.py +0 -0
  424. {agno-2.1.0 → agno-2.1.2}/agno/tools/sql.py +0 -0
  425. {agno-2.1.0/agno/tools/models → agno-2.1.2/agno/tools/streamlit}/__init__.py +0 -0
  426. {agno-2.1.0 → agno-2.1.2}/agno/tools/streamlit/components.py +0 -0
  427. {agno-2.1.0 → agno-2.1.2}/agno/tools/tavily.py +0 -0
  428. {agno-2.1.0 → agno-2.1.2}/agno/tools/telegram.py +0 -0
  429. {agno-2.1.0 → agno-2.1.2}/agno/tools/todoist.py +0 -0
  430. {agno-2.1.0 → agno-2.1.2}/agno/tools/tool_registry.py +0 -0
  431. {agno-2.1.0 → agno-2.1.2}/agno/tools/toolkit.py +0 -0
  432. {agno-2.1.0 → agno-2.1.2}/agno/tools/trafilatura.py +0 -0
  433. {agno-2.1.0 → agno-2.1.2}/agno/tools/trello.py +0 -0
  434. {agno-2.1.0 → agno-2.1.2}/agno/tools/twilio.py +0 -0
  435. {agno-2.1.0 → agno-2.1.2}/agno/tools/user_control_flow.py +0 -0
  436. {agno-2.1.0 → agno-2.1.2}/agno/tools/valyu.py +0 -0
  437. {agno-2.1.0 → agno-2.1.2}/agno/tools/visualization.py +0 -0
  438. {agno-2.1.0 → agno-2.1.2}/agno/tools/webbrowser.py +0 -0
  439. {agno-2.1.0 → agno-2.1.2}/agno/tools/webex.py +0 -0
  440. {agno-2.1.0 → agno-2.1.2}/agno/tools/website.py +0 -0
  441. {agno-2.1.0 → agno-2.1.2}/agno/tools/webtools.py +0 -0
  442. {agno-2.1.0 → agno-2.1.2}/agno/tools/whatsapp.py +0 -0
  443. {agno-2.1.0 → agno-2.1.2}/agno/tools/wikipedia.py +0 -0
  444. {agno-2.1.0 → agno-2.1.2}/agno/tools/workflow.py +0 -0
  445. {agno-2.1.0 → agno-2.1.2}/agno/tools/x.py +0 -0
  446. {agno-2.1.0 → agno-2.1.2}/agno/tools/yfinance.py +0 -0
  447. {agno-2.1.0 → agno-2.1.2}/agno/tools/youtube.py +0 -0
  448. {agno-2.1.0 → agno-2.1.2}/agno/tools/zendesk.py +0 -0
  449. {agno-2.1.0 → agno-2.1.2}/agno/tools/zep.py +0 -0
  450. {agno-2.1.0 → agno-2.1.2}/agno/tools/zoom.py +0 -0
  451. {agno-2.1.0/agno/tools/streamlit → agno-2.1.2/agno/utils}/__init__.py +0 -0
  452. {agno-2.1.0 → agno-2.1.2}/agno/utils/audio.py +0 -0
  453. {agno-2.1.0 → agno-2.1.2}/agno/utils/certs.py +0 -0
  454. {agno-2.1.0 → agno-2.1.2}/agno/utils/code_execution.py +0 -0
  455. {agno-2.1.0 → agno-2.1.2}/agno/utils/common.py +0 -0
  456. {agno-2.1.0 → agno-2.1.2}/agno/utils/dttm.py +0 -0
  457. {agno-2.1.0 → agno-2.1.2}/agno/utils/enum.py +0 -0
  458. {agno-2.1.0 → agno-2.1.2}/agno/utils/env.py +0 -0
  459. {agno-2.1.0 → agno-2.1.2}/agno/utils/events.py +0 -0
  460. {agno-2.1.0 → agno-2.1.2}/agno/utils/format_str.py +0 -0
  461. {agno-2.1.0 → agno-2.1.2}/agno/utils/functions.py +0 -0
  462. {agno-2.1.0 → agno-2.1.2}/agno/utils/gemini.py +0 -0
  463. {agno-2.1.0 → agno-2.1.2}/agno/utils/hooks.py +0 -0
  464. {agno-2.1.0 → agno-2.1.2}/agno/utils/http.py +0 -0
  465. {agno-2.1.0 → agno-2.1.2}/agno/utils/json_schema.py +0 -0
  466. {agno-2.1.0 → agno-2.1.2}/agno/utils/knowledge.py +0 -0
  467. {agno-2.1.0 → agno-2.1.2}/agno/utils/location.py +0 -0
  468. {agno-2.1.0 → agno-2.1.2}/agno/utils/log.py +0 -0
  469. {agno-2.1.0 → agno-2.1.2}/agno/utils/mcp.py +0 -0
  470. {agno-2.1.0 → agno-2.1.2}/agno/utils/media.py +0 -0
  471. {agno-2.1.0 → agno-2.1.2}/agno/utils/message.py +0 -0
  472. {agno-2.1.0/agno/utils → agno-2.1.2/agno/utils/models}/__init__.py +0 -0
  473. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/ai_foundry.py +0 -0
  474. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/claude.py +0 -0
  475. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/cohere.py +0 -0
  476. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/llama.py +0 -0
  477. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/mistral.py +0 -0
  478. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/openai_responses.py +0 -0
  479. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/schema_utils.py +0 -0
  480. {agno-2.1.0 → agno-2.1.2}/agno/utils/models/watsonx.py +0 -0
  481. {agno-2.1.0 → agno-2.1.2}/agno/utils/openai.py +0 -0
  482. {agno-2.1.0 → agno-2.1.2}/agno/utils/pickle.py +0 -0
  483. {agno-2.1.0 → agno-2.1.2}/agno/utils/pprint.py +0 -0
  484. {agno-2.1.0/agno/utils/models → agno-2.1.2/agno/utils/print_response}/__init__.py +0 -0
  485. {agno-2.1.0 → agno-2.1.2}/agno/utils/print_response/agent.py +0 -0
  486. {agno-2.1.0 → agno-2.1.2}/agno/utils/print_response/team.py +0 -0
  487. {agno-2.1.0 → agno-2.1.2}/agno/utils/print_response/workflow.py +0 -0
  488. {agno-2.1.0 → agno-2.1.2}/agno/utils/prompts.py +0 -0
  489. {agno-2.1.0 → agno-2.1.2}/agno/utils/reasoning.py +0 -0
  490. {agno-2.1.0 → agno-2.1.2}/agno/utils/response.py +0 -0
  491. {agno-2.1.0 → agno-2.1.2}/agno/utils/response_iterator.py +0 -0
  492. {agno-2.1.0 → agno-2.1.2}/agno/utils/safe_formatter.py +0 -0
  493. {agno-2.1.0 → agno-2.1.2}/agno/utils/shell.py +0 -0
  494. {agno-2.1.0 → agno-2.1.2}/agno/utils/string.py +0 -0
  495. {agno-2.1.0 → agno-2.1.2}/agno/utils/team.py +0 -0
  496. {agno-2.1.0 → agno-2.1.2}/agno/utils/timer.py +0 -0
  497. {agno-2.1.0 → agno-2.1.2}/agno/utils/tools.py +0 -0
  498. {agno-2.1.0 → agno-2.1.2}/agno/utils/web.py +0 -0
  499. {agno-2.1.0 → agno-2.1.2}/agno/utils/whatsapp.py +0 -0
  500. {agno-2.1.0 → agno-2.1.2}/agno/utils/yaml_io.py +0 -0
  501. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/__init__.py +0 -0
  502. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/base.py +0 -0
  503. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/__init__.py +0 -0
  504. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/cassandra.py +0 -0
  505. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
  506. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/index.py +0 -0
  507. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/chroma/__init__.py +0 -0
  508. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/chroma/chromadb.py +0 -0
  509. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/clickhouse/__init__.py +0 -0
  510. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
  511. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/clickhouse/index.py +0 -0
  512. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/couchbase/__init__.py +0 -0
  513. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/couchbase/couchbase.py +0 -0
  514. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/distance.py +0 -0
  515. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lancedb/__init__.py +0 -0
  516. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lancedb/lance_db.py +0 -0
  517. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/langchaindb/__init__.py +0 -0
  518. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/langchaindb/langchaindb.py +0 -0
  519. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lightrag/__init__.py +0 -0
  520. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lightrag/lightrag.py +0 -0
  521. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/llamaindex/__init__.py +0 -0
  522. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/llamaindex/llamaindexdb.py +0 -0
  523. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/milvus/__init__.py +0 -0
  524. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/milvus/milvus.py +0 -0
  525. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/mongodb/__init__.py +0 -0
  526. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/mongodb/mongodb.py +0 -0
  527. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pgvector/__init__.py +0 -0
  528. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pgvector/index.py +0 -0
  529. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pgvector/pgvector.py +0 -0
  530. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pineconedb/__init__.py +0 -0
  531. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pineconedb/pineconedb.py +0 -0
  532. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/qdrant/__init__.py +0 -0
  533. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/qdrant/qdrant.py +0 -0
  534. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/search.py +0 -0
  535. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/singlestore/__init__.py +0 -0
  536. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/singlestore/index.py +0 -0
  537. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/singlestore/singlestore.py +0 -0
  538. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/surrealdb/__init__.py +0 -0
  539. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/surrealdb/surrealdb.py +0 -0
  540. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/upstashdb/__init__.py +0 -0
  541. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/upstashdb/upstashdb.py +0 -0
  542. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/weaviate/__init__.py +0 -0
  543. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/weaviate/index.py +0 -0
  544. {agno-2.1.0 → agno-2.1.2}/agno/vectordb/weaviate/weaviate.py +0 -0
  545. {agno-2.1.0 → agno-2.1.2}/agno/workflow/__init__.py +0 -0
  546. {agno-2.1.0 → agno-2.1.2}/agno/workflow/condition.py +0 -0
  547. {agno-2.1.0 → agno-2.1.2}/agno/workflow/loop.py +0 -0
  548. {agno-2.1.0 → agno-2.1.2}/agno/workflow/router.py +0 -0
  549. {agno-2.1.0 → agno-2.1.2}/agno/workflow/steps.py +0 -0
  550. {agno-2.1.0 → agno-2.1.2}/agno.egg-info/dependency_links.txt +0 -0
  551. {agno-2.1.0 → agno-2.1.2}/agno.egg-info/top_level.txt +0 -0
  552. {agno-2.1.0 → agno-2.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.1.0
3
+ Version: 2.1.2
4
4
  Summary: Agno: a lightweight library for building Multi-Agent Systems
5
5
  Author-email: Ashpreet Bedi <ashpreet@agno.com>
6
6
  Project-URL: homepage, https://agno.com
@@ -23,6 +23,7 @@ Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: docstring-parser
25
25
  Requires-Dist: gitpython
26
+ Requires-Dist: h11>=0.16.0
26
27
  Requires-Dist: httpx
27
28
  Requires-Dist: packaging
28
29
  Requires-Dist: pydantic-settings
@@ -247,6 +248,8 @@ Requires-Dist: chonkie[st]; extra == "chonkie"
247
248
  Requires-Dist: chonkie; extra == "chonkie"
248
249
  Provides-Extra: agui
249
250
  Requires-Dist: ag-ui-protocol; extra == "agui"
251
+ Provides-Extra: a2a
252
+ Requires-Dist: a2a-sdk; extra == "a2a"
250
253
  Provides-Extra: huggingface
251
254
  Requires-Dist: huggingface-hub; extra == "huggingface"
252
255
  Provides-Extra: performance
@@ -267,7 +270,6 @@ Requires-Dist: agno[anthropic]; extra == "models"
267
270
  Requires-Dist: agno[azure]; extra == "models"
268
271
  Requires-Dist: agno[cerebras]; extra == "models"
269
272
  Requires-Dist: agno[cohere]; extra == "models"
270
- Requires-Dist: agno[infinity]; extra == "models"
271
273
  Requires-Dist: agno[google]; extra == "models"
272
274
  Requires-Dist: agno[groq]; extra == "models"
273
275
  Requires-Dist: agno[ibm]; extra == "models"
@@ -379,11 +381,11 @@ Dynamic: license-file
379
381
 
380
382
  ## What is Agno?
381
383
 
382
- [Agno](https://docs.agno.com) is a high-performance runtime for multi-agent systems. Use it to build, run and manage secure multi-agent systems in your cloud.
384
+ [Agno](https://docs.agno.com) is a high-performance SDK and runtime for multi-agent systems. Use it to build, run and manage multi-agent systems in your cloud.
383
385
 
384
- Agno gives you the fastest framework for building agents with session management, memory, knowledge, human in the loop and MCP support. You can put agents together as an autonomous multi-agent team, or build step-based agentic workflows for full control over complex multi-step processes.
386
+ Agno is the fastest framework for building agents with built-in memory, knowledge, session management, human in the loop and best-in-class MCP support. You can put agents together as multi-agent teams or step-based agentic workflows.
385
387
 
386
- In 10 lines of code, we can build an Agent that will fetch the top stories from HackerNews and summarize them.
388
+ In 10 lines of code, we can build an Agent that uses tools to achieve a task.
387
389
 
388
390
  ```python hackernews_agent.py
389
391
  from agno.agent import Agent
@@ -391,22 +393,22 @@ from agno.models.anthropic import Claude
391
393
  from agno.tools.hackernews import HackerNewsTools
392
394
 
393
395
  agent = Agent(
394
- model=Claude(id="claude-sonnet-4-0"),
396
+ model=Claude(id="claude-sonnet-4-5"),
395
397
  tools=[HackerNewsTools()],
396
398
  markdown=True,
397
399
  )
398
- agent.print_response("Summarize the top 5 stories on hackernews", stream=True)
400
+ agent.print_response("Write a report on trending startups and products.", stream=True)
399
401
  ```
400
402
 
401
403
  But the real advantage of Agno is its [AgentOS](https://docs.agno.com/agent-os/introduction) runtime:
402
404
 
403
- 1. You get a pre-built FastAPI app for running your agentic system, meaning you start building your product on day one. This is a remarkable advantage over other solutions or rolling your own.
404
- 2. You also get a control plane which connects directly to your AgentOS for testing, monitoring and managing your system. This gives you unmatched visibility and control over your system.
405
- 3. Your AgentOS runs in your cloud and you get complete data privacy because no data ever leaves your system. This is incredible for security conscious enterprises that can't send traces to external services.
405
+ 1. You get a pre-built FastAPI app for serving your agents, teams and workflows, meaning you start building your AI product on day one. This is a remarkable advantage over other solutions.
406
+ 2. You also get a UI that connects directly to the pre-built FastAPI app. Use it to test, monitor and manage your system. This gives you unmatched visibility and control.
407
+ 3. Your AgentOS runs in your cloud and you get complete privacy because no data ever leaves your system. This is incredible for security conscious enterprises that can't send data to external services.
406
408
 
407
- For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that lets you build your product on day one, and a control plane for managing your system.
409
+ For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that get you building product on day one, and a control plane for managing your system.
408
410
 
409
- We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to external services or pay retention costs, you get complete privacy and control.
411
+ We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to any external services or pay retention costs, you get complete privacy and control.
410
412
 
411
413
  ## Getting started
412
414
 
@@ -463,10 +465,10 @@ source .venvs/perfenv/bin/activate
463
465
  # pip install openai agno langgraph langchain_openai
464
466
 
465
467
  # Agno
466
- python evals/performance/instantiation_with_tool.py
468
+ python cookbook/evals/performance/instantiate_agent_with_tool.py
467
469
 
468
470
  # LangGraph
469
- python evals/performance/other/langgraph_instantiation.py
471
+ python cookbook/evals/performance/comparison/langgraph_instantiation.py
470
472
  ```
471
473
 
472
474
  > The following evaluation is run on an Apple M4 MacBook Pro. It also runs as a Github action on this repo.
@@ -16,11 +16,11 @@
16
16
 
17
17
  ## What is Agno?
18
18
 
19
- [Agno](https://docs.agno.com) is a high-performance runtime for multi-agent systems. Use it to build, run and manage secure multi-agent systems in your cloud.
19
+ [Agno](https://docs.agno.com) is a high-performance SDK and runtime for multi-agent systems. Use it to build, run and manage multi-agent systems in your cloud.
20
20
 
21
- Agno gives you the fastest framework for building agents with session management, memory, knowledge, human in the loop and MCP support. You can put agents together as an autonomous multi-agent team, or build step-based agentic workflows for full control over complex multi-step processes.
21
+ Agno is the fastest framework for building agents with built-in memory, knowledge, session management, human in the loop and best-in-class MCP support. You can put agents together as multi-agent teams or step-based agentic workflows.
22
22
 
23
- In 10 lines of code, we can build an Agent that will fetch the top stories from HackerNews and summarize them.
23
+ In 10 lines of code, we can build an Agent that uses tools to achieve a task.
24
24
 
25
25
  ```python hackernews_agent.py
26
26
  from agno.agent import Agent
@@ -28,22 +28,22 @@ from agno.models.anthropic import Claude
28
28
  from agno.tools.hackernews import HackerNewsTools
29
29
 
30
30
  agent = Agent(
31
- model=Claude(id="claude-sonnet-4-0"),
31
+ model=Claude(id="claude-sonnet-4-5"),
32
32
  tools=[HackerNewsTools()],
33
33
  markdown=True,
34
34
  )
35
- agent.print_response("Summarize the top 5 stories on hackernews", stream=True)
35
+ agent.print_response("Write a report on trending startups and products.", stream=True)
36
36
  ```
37
37
 
38
38
  But the real advantage of Agno is its [AgentOS](https://docs.agno.com/agent-os/introduction) runtime:
39
39
 
40
- 1. You get a pre-built FastAPI app for running your agentic system, meaning you start building your product on day one. This is a remarkable advantage over other solutions or rolling your own.
41
- 2. You also get a control plane which connects directly to your AgentOS for testing, monitoring and managing your system. This gives you unmatched visibility and control over your system.
42
- 3. Your AgentOS runs in your cloud and you get complete data privacy because no data ever leaves your system. This is incredible for security conscious enterprises that can't send traces to external services.
40
+ 1. You get a pre-built FastAPI app for serving your agents, teams and workflows, meaning you start building your AI product on day one. This is a remarkable advantage over other solutions.
41
+ 2. You also get a UI that connects directly to the pre-built FastAPI app. Use it to test, monitor and manage your system. This gives you unmatched visibility and control.
42
+ 3. Your AgentOS runs in your cloud and you get complete privacy because no data ever leaves your system. This is incredible for security conscious enterprises that can't send data to external services.
43
43
 
44
- For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that lets you build your product on day one, and a control plane for managing your system.
44
+ For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that get you building product on day one, and a control plane for managing your system.
45
45
 
46
- We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to external services or pay retention costs, you get complete privacy and control.
46
+ We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to any external services or pay retention costs, you get complete privacy and control.
47
47
 
48
48
  ## Getting started
49
49
 
@@ -100,10 +100,10 @@ source .venvs/perfenv/bin/activate
100
100
  # pip install openai agno langgraph langchain_openai
101
101
 
102
102
  # Agno
103
- python evals/performance/instantiation_with_tool.py
103
+ python cookbook/evals/performance/instantiate_agent_with_tool.py
104
104
 
105
105
  # LangGraph
106
- python evals/performance/other/langgraph_instantiation.py
106
+ python cookbook/evals/performance/comparison/langgraph_instantiation.py
107
107
  ```
108
108
 
109
109
  > The following evaluation is run on an Apple M4 MacBook Pro. It also runs as a Github action on this repo.
@@ -5244,7 +5244,7 @@ class Agent:
5244
5244
 
5245
5245
  # 3.2.5 Add information about agentic filters if enabled
5246
5246
  if self.knowledge is not None and self.enable_agentic_knowledge_filters:
5247
- valid_filters = getattr(self.knowledge, "valid_metadata_filters", None)
5247
+ valid_filters = self.knowledge.get_valid_filters()
5248
5248
  if valid_filters:
5249
5249
  valid_filters_str = ", ".join(valid_filters)
5250
5250
  additional_information.append(
@@ -6420,6 +6420,12 @@ class Agent:
6420
6420
  log_warning("Reasoning error. Reasoning response is empty, continuing regular session...")
6421
6421
  break
6422
6422
 
6423
+ if isinstance(reasoning_agent_response.content, str):
6424
+ log_warning(
6425
+ "Reasoning error. Content is a string, not structured output. Continuing regular session..."
6426
+ )
6427
+ break
6428
+
6423
6429
  if (
6424
6430
  reasoning_agent_response.content.reasoning_steps is None
6425
6431
  or len(reasoning_agent_response.content.reasoning_steps) == 0
@@ -6649,6 +6655,12 @@ class Agent:
6649
6655
  log_warning("Reasoning error. Reasoning response is empty, continuing regular session...")
6650
6656
  break
6651
6657
 
6658
+ if isinstance(reasoning_agent_response.content, str):
6659
+ log_warning(
6660
+ "Reasoning error. Content is a string, not structured output. Continuing regular session..."
6661
+ )
6662
+ break
6663
+
6652
6664
  if reasoning_agent_response.content.reasoning_steps is None:
6653
6665
  log_warning("Reasoning error. Reasoning steps are empty, continuing regular session...")
6654
6666
  break
@@ -95,20 +95,23 @@ class BaseDb(ABC):
95
95
  raise NotImplementedError
96
96
 
97
97
  @abstractmethod
98
- def delete_user_memory(self, memory_id: str) -> None:
98
+ def delete_user_memory(self, memory_id: str, user_id: Optional[str] = None) -> None:
99
99
  raise NotImplementedError
100
100
 
101
101
  @abstractmethod
102
- def delete_user_memories(self, memory_ids: List[str]) -> None:
102
+ def delete_user_memories(self, memory_ids: List[str], user_id: Optional[str] = None) -> None:
103
103
  raise NotImplementedError
104
104
 
105
105
  @abstractmethod
106
- def get_all_memory_topics(self) -> List[str]:
106
+ def get_all_memory_topics(self, user_id: Optional[str] = None) -> List[str]:
107
107
  raise NotImplementedError
108
108
 
109
109
  @abstractmethod
110
110
  def get_user_memory(
111
- self, memory_id: str, deserialize: Optional[bool] = True
111
+ self,
112
+ memory_id: str,
113
+ deserialize: Optional[bool] = True,
114
+ user_id: Optional[str] = None,
112
115
  ) -> Optional[Union[UserMemory, Dict[str, Any]]]:
113
116
  raise NotImplementedError
114
117
 
@@ -133,6 +136,7 @@ class BaseDb(ABC):
133
136
  self,
134
137
  limit: Optional[int] = None,
135
138
  page: Optional[int] = None,
139
+ user_id: Optional[str] = None,
136
140
  ) -> Tuple[List[Dict[str, Any]], int]:
137
141
  raise NotImplementedError
138
142
 
@@ -562,17 +562,31 @@ class DynamoDb(BaseDb):
562
562
 
563
563
  # --- User Memory ---
564
564
 
565
- def delete_user_memory(self, memory_id: str) -> None:
565
+ def delete_user_memory(self, memory_id: str, user_id: Optional[str] = None) -> None:
566
566
  """
567
567
  Delete a user memory from the database.
568
568
 
569
569
  Args:
570
570
  memory_id: The ID of the memory to delete.
571
+ user_id: The ID of the user (optional, for filtering).
571
572
 
572
573
  Raises:
573
574
  Exception: If any error occurs while deleting the user memory.
574
575
  """
575
576
  try:
577
+ # If user_id is provided, verify the memory belongs to the user before deleting
578
+ if user_id:
579
+ response = self.client.get_item(
580
+ TableName=self.memory_table_name,
581
+ Key={"memory_id": {"S": memory_id}},
582
+ )
583
+ item = response.get("Item")
584
+ if item:
585
+ memory_data = deserialize_from_dynamodb_item(item)
586
+ if memory_data.get("user_id") != user_id:
587
+ log_debug(f"Memory {memory_id} does not belong to user {user_id}")
588
+ return
589
+
576
590
  self.client.delete_item(
577
591
  TableName=self.memory_table_name,
578
592
  Key={"memory_id": {"S": memory_id}},
@@ -583,18 +597,34 @@ class DynamoDb(BaseDb):
583
597
  log_error(f"Failed to delete user memory {memory_id}: {e}")
584
598
  raise e
585
599
 
586
- def delete_user_memories(self, memory_ids: List[str]) -> None:
600
+ def delete_user_memories(self, memory_ids: List[str], user_id: Optional[str] = None) -> None:
587
601
  """
588
602
  Delete user memories from the database in batches.
589
603
 
590
604
  Args:
591
605
  memory_ids: List of memory IDs to delete
606
+ user_id: The ID of the user (optional, for filtering).
592
607
 
593
608
  Raises:
594
609
  Exception: If any error occurs while deleting the user memories.
595
610
  """
596
611
 
597
612
  try:
613
+ # If user_id is provided, filter memory_ids to only those belonging to the user
614
+ if user_id:
615
+ filtered_memory_ids = []
616
+ for memory_id in memory_ids:
617
+ response = self.client.get_item(
618
+ TableName=self.memory_table_name,
619
+ Key={"memory_id": {"S": memory_id}},
620
+ )
621
+ item = response.get("Item")
622
+ if item:
623
+ memory_data = deserialize_from_dynamodb_item(item)
624
+ if memory_data.get("user_id") == user_id:
625
+ filtered_memory_ids.append(memory_id)
626
+ memory_ids = filtered_memory_ids
627
+
598
628
  for i in range(0, len(memory_ids), DYNAMO_BATCH_SIZE_LIMIT):
599
629
  batch = memory_ids[i : i + DYNAMO_BATCH_SIZE_LIMIT]
600
630
 
@@ -611,6 +641,9 @@ class DynamoDb(BaseDb):
611
641
  def get_all_memory_topics(self) -> List[str]:
612
642
  """Get all memory topics from the database.
613
643
 
644
+ Args:
645
+ user_id: The ID of the user (optional, for filtering).
646
+
614
647
  Returns:
615
648
  List[str]: List of unique memory topics.
616
649
  """
@@ -619,13 +652,17 @@ class DynamoDb(BaseDb):
619
652
  if table_name is None:
620
653
  return []
621
654
 
622
- # Scan the entire table to get all memories
623
- response = self.client.scan(TableName=table_name)
655
+ # Build filter expression for user_id if provided
656
+ scan_kwargs = {"TableName": table_name}
657
+
658
+ # Scan the table to get memories
659
+ response = self.client.scan(**scan_kwargs)
624
660
  items = response.get("Items", [])
625
661
 
626
662
  # Handle pagination
627
663
  while "LastEvaluatedKey" in response:
628
- response = self.client.scan(TableName=table_name, ExclusiveStartKey=response["LastEvaluatedKey"])
664
+ scan_kwargs["ExclusiveStartKey"] = response["LastEvaluatedKey"]
665
+ response = self.client.scan(**scan_kwargs)
629
666
  items.extend(response.get("Items", []))
630
667
 
631
668
  # Extract topics from all memories
@@ -642,13 +679,18 @@ class DynamoDb(BaseDb):
642
679
  raise e
643
680
 
644
681
  def get_user_memory(
645
- self, memory_id: str, deserialize: Optional[bool] = True
682
+ self,
683
+ memory_id: str,
684
+ deserialize: Optional[bool] = True,
685
+ user_id: Optional[str] = None,
646
686
  ) -> Optional[Union[UserMemory, Dict[str, Any]]]:
647
687
  """
648
688
  Get a user memory from the database as a UserMemory object.
649
689
 
650
690
  Args:
651
691
  memory_id: The ID of the memory to get.
692
+ deserialize: Whether to deserialize the memory.
693
+ user_id: The ID of the user (optional, for filtering).
652
694
 
653
695
  Returns:
654
696
  Optional[UserMemory]: The user memory data if found, None otherwise.
@@ -665,6 +707,11 @@ class DynamoDb(BaseDb):
665
707
  return None
666
708
 
667
709
  item = deserialize_from_dynamodb_item(item)
710
+
711
+ # Filter by user_id if provided
712
+ if user_id and item.get("user_id") != user_id:
713
+ return None
714
+
668
715
  if not deserialize:
669
716
  return item
670
717
 
@@ -804,6 +851,7 @@ class DynamoDb(BaseDb):
804
851
  Args:
805
852
  limit (Optional[int]): The maximum number of user stats to return.
806
853
  page (Optional[int]): The page number.
854
+ user_id (Optional[str]): The ID of the user (optional, for filtering).
807
855
 
808
856
  Returns:
809
857
  Tuple[List[Dict[str, Any]], int]: A list of dictionaries containing user stats and total count.
@@ -823,29 +871,33 @@ class DynamoDb(BaseDb):
823
871
  try:
824
872
  table_name = self._get_table("memories")
825
873
 
826
- response = self.client.scan(TableName=table_name)
874
+ # Build filter expression for user_id if provided
875
+ scan_kwargs = {"TableName": table_name}
876
+
877
+ response = self.client.scan(**scan_kwargs)
827
878
  items = response.get("Items", [])
828
879
 
829
880
  # Handle pagination
830
881
  while "LastEvaluatedKey" in response:
831
- response = self.client.scan(TableName=table_name, ExclusiveStartKey=response["LastEvaluatedKey"])
882
+ scan_kwargs["ExclusiveStartKey"] = response["LastEvaluatedKey"]
883
+ response = self.client.scan(**scan_kwargs)
832
884
  items.extend(response.get("Items", []))
833
885
 
834
886
  # Aggregate stats by user_id
835
887
  user_stats = {}
836
888
  for item in items:
837
889
  memory_data = deserialize_from_dynamodb_item(item)
838
- user_id = memory_data.get("user_id")
890
+ current_user_id = memory_data.get("user_id")
839
891
 
840
- if user_id:
841
- if user_id not in user_stats:
842
- user_stats[user_id] = {
843
- "user_id": user_id,
892
+ if current_user_id:
893
+ if current_user_id not in user_stats:
894
+ user_stats[current_user_id] = {
895
+ "user_id": current_user_id,
844
896
  "total_memories": 0,
845
897
  "last_memory_updated_at": None,
846
898
  }
847
899
 
848
- user_stats[user_id]["total_memories"] += 1
900
+ user_stats[current_user_id]["total_memories"] += 1
849
901
 
850
902
  updated_at = memory_data.get("updated_at")
851
903
  if updated_at:
@@ -853,10 +905,10 @@ class DynamoDb(BaseDb):
853
905
  updated_at_timestamp = int(updated_at_dt.timestamp())
854
906
 
855
907
  if updated_at_timestamp and (
856
- user_stats[user_id]["last_memory_updated_at"] is None
857
- or updated_at_timestamp > user_stats[user_id]["last_memory_updated_at"]
908
+ user_stats[current_user_id]["last_memory_updated_at"] is None
909
+ or updated_at_timestamp > user_stats[current_user_id]["last_memory_updated_at"]
858
910
  ):
859
- user_stats[user_id]["last_memory_updated_at"] = updated_at_timestamp
911
+ user_stats[current_user_id]["last_memory_updated_at"] = updated_at_timestamp
860
912
 
861
913
  # Convert to list and apply sorting
862
914
  stats_list = list(user_stats.values())
@@ -596,11 +596,12 @@ class FirestoreDb(BaseDb):
596
596
 
597
597
  # -- Memory methods --
598
598
 
599
- def delete_user_memory(self, memory_id: str):
599
+ def delete_user_memory(self, memory_id: str, user_id: Optional[str] = None):
600
600
  """Delete a user memory from the database.
601
601
 
602
602
  Args:
603
603
  memory_id (str): The ID of the memory to delete.
604
+ user_id (Optional[str]): The ID of the user (optional, for filtering).
604
605
 
605
606
  Returns:
606
607
  bool: True if the memory was deleted, False otherwise.
@@ -610,28 +611,41 @@ class FirestoreDb(BaseDb):
610
611
  """
611
612
  try:
612
613
  collection_ref = self._get_collection(table_type="memories")
613
- docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
614
614
 
615
- deleted_count = 0
616
- for doc in docs:
617
- doc.reference.delete()
618
- deleted_count += 1
619
-
620
- success = deleted_count > 0
621
- if success:
622
- log_debug(f"Successfully deleted user memory id: {memory_id}")
615
+ # If user_id is provided, verify the memory belongs to the user before deleting
616
+ if user_id:
617
+ docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
618
+ for doc in docs:
619
+ data = doc.to_dict()
620
+ if data.get("user_id") != user_id:
621
+ log_debug(f"Memory {memory_id} does not belong to user {user_id}")
622
+ return
623
+ doc.reference.delete()
624
+ log_debug(f"Successfully deleted user memory id: {memory_id}")
625
+ return
623
626
  else:
624
- log_debug(f"No user memory found with id: {memory_id}")
627
+ docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
628
+ deleted_count = 0
629
+ for doc in docs:
630
+ doc.reference.delete()
631
+ deleted_count += 1
632
+
633
+ success = deleted_count > 0
634
+ if success:
635
+ log_debug(f"Successfully deleted user memory id: {memory_id}")
636
+ else:
637
+ log_debug(f"No user memory found with id: {memory_id}")
625
638
 
626
639
  except Exception as e:
627
640
  log_error(f"Error deleting user memory: {e}")
628
641
  raise e
629
642
 
630
- def delete_user_memories(self, memory_ids: List[str]) -> None:
643
+ def delete_user_memories(self, memory_ids: List[str], user_id: Optional[str] = None) -> None:
631
644
  """Delete user memories from the database.
632
645
 
633
646
  Args:
634
647
  memory_ids (List[str]): The IDs of the memories to delete.
648
+ user_id (Optional[str]): The ID of the user (optional, for filtering).
635
649
 
636
650
  Raises:
637
651
  Exception: If there is an error deleting the memories.
@@ -641,11 +655,21 @@ class FirestoreDb(BaseDb):
641
655
  batch = self.db_client.batch()
642
656
  deleted_count = 0
643
657
 
644
- for memory_id in memory_ids:
645
- docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
646
- for doc in docs:
647
- batch.delete(doc.reference)
648
- deleted_count += 1
658
+ # If user_id is provided, filter memory_ids to only those belonging to the user
659
+ if user_id:
660
+ for memory_id in memory_ids:
661
+ docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
662
+ for doc in docs:
663
+ data = doc.to_dict()
664
+ if data.get("user_id") == user_id:
665
+ batch.delete(doc.reference)
666
+ deleted_count += 1
667
+ else:
668
+ for memory_id in memory_ids:
669
+ docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
670
+ for doc in docs:
671
+ batch.delete(doc.reference)
672
+ deleted_count += 1
649
673
 
650
674
  batch.commit()
651
675
 
@@ -658,7 +682,9 @@ class FirestoreDb(BaseDb):
658
682
  log_error(f"Error deleting memories: {e}")
659
683
  raise e
660
684
 
661
- def get_all_memory_topics(self, create_collection_if_not_found: Optional[bool] = True) -> List[str]:
685
+ def get_all_memory_topics(
686
+ self, create_collection_if_not_found: Optional[bool] = True
687
+ ) -> List[str]:
662
688
  """Get all memory topics from the database.
663
689
 
664
690
  Returns:
@@ -687,12 +713,15 @@ class FirestoreDb(BaseDb):
687
713
  log_error(f"Exception getting all memory topics: {e}")
688
714
  raise e
689
715
 
690
- def get_user_memory(self, memory_id: str, deserialize: Optional[bool] = True) -> Optional[UserMemory]:
716
+ def get_user_memory(
717
+ self, memory_id: str, deserialize: Optional[bool] = True, user_id: Optional[str] = None
718
+ ) -> Optional[UserMemory]:
691
719
  """Get a memory from the database.
692
720
 
693
721
  Args:
694
722
  memory_id (str): The ID of the memory to get.
695
723
  deserialize (Optional[bool]): Whether to serialize the memory. Defaults to True.
724
+ user_id (Optional[str]): The ID of the user (optional, for filtering).
696
725
 
697
726
  Returns:
698
727
  Optional[UserMemory]:
@@ -711,7 +740,14 @@ class FirestoreDb(BaseDb):
711
740
  result = doc.to_dict()
712
741
  break
713
742
 
714
- if result is None or not deserialize:
743
+ if result is None:
744
+ return None
745
+
746
+ # Filter by user_id if provided
747
+ if user_id and result.get("user_id") != user_id:
748
+ return None
749
+
750
+ if not deserialize:
715
751
  return result
716
752
 
717
753
  return UserMemory.from_dict(result)
@@ -818,23 +854,26 @@ class FirestoreDb(BaseDb):
818
854
  """
819
855
  try:
820
856
  collection_ref = self._get_collection(table_type="memories")
821
- docs = collection_ref.where(filter=FieldFilter("user_id", "!=", None)).stream()
857
+
858
+ query = collection_ref.where(filter=FieldFilter("user_id", "!=", None))
859
+
860
+ docs = query.stream()
822
861
 
823
862
  user_stats = {}
824
863
  for doc in docs:
825
864
  data = doc.to_dict()
826
- user_id = data.get("user_id")
827
- if user_id:
828
- if user_id not in user_stats:
829
- user_stats[user_id] = {
830
- "user_id": user_id,
865
+ current_user_id = data.get("user_id")
866
+ if current_user_id:
867
+ if current_user_id not in user_stats:
868
+ user_stats[current_user_id] = {
869
+ "user_id": current_user_id,
831
870
  "total_memories": 0,
832
871
  "last_memory_updated_at": 0,
833
872
  }
834
- user_stats[user_id]["total_memories"] += 1
873
+ user_stats[current_user_id]["total_memories"] += 1
835
874
  updated_at = data.get("updated_at", 0)
836
- if updated_at > user_stats[user_id]["last_memory_updated_at"]:
837
- user_stats[user_id]["last_memory_updated_at"] = updated_at
875
+ if updated_at > user_stats[current_user_id]["last_memory_updated_at"]:
876
+ user_stats[current_user_id]["last_memory_updated_at"] = updated_at
838
877
 
839
878
  # Convert to list and sort
840
879
  formatted_results = list(user_stats.values())