agno 2.3.10__tar.gz → 2.3.12__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 (618) hide show
  1. {agno-2.3.10 → agno-2.3.12}/PKG-INFO +4 -1
  2. {agno-2.3.10 → agno-2.3.12}/agno/compression/manager.py +87 -16
  3. {agno-2.3.10 → agno-2.3.12}/agno/db/base.py +5 -5
  4. {agno-2.3.10 → agno-2.3.12}/agno/db/dynamo/dynamo.py +2 -2
  5. {agno-2.3.10 → agno-2.3.12}/agno/db/firestore/firestore.py +2 -2
  6. {agno-2.3.10 → agno-2.3.12}/agno/db/gcs_json/gcs_json_db.py +2 -2
  7. {agno-2.3.10 → agno-2.3.12}/agno/db/in_memory/in_memory_db.py +2 -2
  8. {agno-2.3.10 → agno-2.3.12}/agno/db/json/json_db.py +2 -2
  9. {agno-2.3.10 → agno-2.3.12}/agno/db/mongo/async_mongo.py +170 -68
  10. {agno-2.3.10 → agno-2.3.12}/agno/db/mongo/mongo.py +170 -76
  11. {agno-2.3.10 → agno-2.3.12}/agno/db/mysql/async_mysql.py +93 -69
  12. {agno-2.3.10 → agno-2.3.12}/agno/db/mysql/mysql.py +93 -68
  13. {agno-2.3.10 → agno-2.3.12}/agno/db/postgres/async_postgres.py +104 -78
  14. {agno-2.3.10 → agno-2.3.12}/agno/db/postgres/postgres.py +97 -69
  15. {agno-2.3.10 → agno-2.3.12}/agno/db/redis/redis.py +2 -2
  16. {agno-2.3.10 → agno-2.3.12}/agno/db/singlestore/singlestore.py +91 -66
  17. {agno-2.3.10 → agno-2.3.12}/agno/db/sqlite/async_sqlite.py +101 -78
  18. {agno-2.3.10 → agno-2.3.12}/agno/db/sqlite/sqlite.py +97 -69
  19. {agno-2.3.10 → agno-2.3.12}/agno/db/surrealdb/surrealdb.py +2 -2
  20. {agno-2.3.10 → agno-2.3.12}/agno/exceptions.py +1 -0
  21. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/fixed.py +4 -1
  22. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/knowledge.py +105 -24
  23. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/csv_reader.py +2 -2
  24. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/text_reader.py +15 -3
  25. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/wikipedia_reader.py +33 -1
  26. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/utils.py +52 -7
  27. {agno-2.3.10 → agno-2.3.12}/agno/memory/strategies/base.py +3 -4
  28. {agno-2.3.10 → agno-2.3.12}/agno/models/anthropic/claude.py +44 -0
  29. {agno-2.3.10 → agno-2.3.12}/agno/models/aws/bedrock.py +60 -0
  30. {agno-2.3.10 → agno-2.3.12}/agno/models/base.py +124 -30
  31. {agno-2.3.10 → agno-2.3.12}/agno/models/google/gemini.py +141 -23
  32. {agno-2.3.10 → agno-2.3.12}/agno/models/litellm/chat.py +25 -0
  33. {agno-2.3.10 → agno-2.3.12}/agno/models/openai/chat.py +21 -0
  34. {agno-2.3.10 → agno-2.3.12}/agno/models/openai/responses.py +44 -0
  35. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/knowledge/knowledge.py +20 -9
  36. {agno-2.3.10 → agno-2.3.12}/agno/run/agent.py +17 -0
  37. agno-2.3.12/agno/run/requirement.py +181 -0
  38. {agno-2.3.10 → agno-2.3.12}/agno/tracing/exporter.py +2 -2
  39. {agno-2.3.10 → agno-2.3.12}/agno/utils/print_response/agent.py +4 -4
  40. {agno-2.3.10 → agno-2.3.12}/agno/utils/print_response/team.py +12 -12
  41. agno-2.3.12/agno/utils/tokens.py +657 -0
  42. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/base.py +15 -2
  43. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/chroma/chromadb.py +6 -2
  44. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/lancedb/lance_db.py +3 -37
  45. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/milvus/milvus.py +6 -32
  46. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/mongodb/mongodb.py +0 -27
  47. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/pgvector/pgvector.py +21 -11
  48. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/pineconedb/pineconedb.py +0 -17
  49. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/qdrant/qdrant.py +6 -29
  50. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/redis/redisdb.py +0 -26
  51. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/singlestore/singlestore.py +16 -8
  52. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/surrealdb/surrealdb.py +0 -36
  53. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/weaviate/weaviate.py +6 -2
  54. {agno-2.3.10 → agno-2.3.12}/agno.egg-info/PKG-INFO +4 -1
  55. {agno-2.3.10 → agno-2.3.12}/agno.egg-info/requires.txt +4 -0
  56. {agno-2.3.10 → agno-2.3.12}/pyproject.toml +5 -1
  57. agno-2.3.10/agno/run/requirement.py +0 -98
  58. agno-2.3.10/agno/utils/tokens.py +0 -41
  59. {agno-2.3.10 → agno-2.3.12}/LICENSE +0 -0
  60. {agno-2.3.10 → agno-2.3.12}/README.md +0 -0
  61. {agno-2.3.10 → agno-2.3.12}/agno/__init__.py +0 -0
  62. {agno-2.3.10 → agno-2.3.12}/agno/agent/__init__.py +0 -0
  63. {agno-2.3.10 → agno-2.3.12}/agno/agent/agent.py +0 -0
  64. {agno-2.3.10 → agno-2.3.12}/agno/api/__init__.py +0 -0
  65. {agno-2.3.10 → agno-2.3.12}/agno/api/agent.py +0 -0
  66. {agno-2.3.10 → agno-2.3.12}/agno/api/api.py +0 -0
  67. {agno-2.3.10 → agno-2.3.12}/agno/api/evals.py +0 -0
  68. {agno-2.3.10 → agno-2.3.12}/agno/api/os.py +0 -0
  69. {agno-2.3.10 → agno-2.3.12}/agno/api/routes.py +0 -0
  70. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/__init__.py +0 -0
  71. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/agent.py +0 -0
  72. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/evals.py +0 -0
  73. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/os.py +0 -0
  74. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/response.py +0 -0
  75. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/team.py +0 -0
  76. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/utils.py +0 -0
  77. {agno-2.3.10 → agno-2.3.12}/agno/api/schemas/workflows.py +0 -0
  78. {agno-2.3.10 → agno-2.3.12}/agno/api/settings.py +0 -0
  79. {agno-2.3.10 → agno-2.3.12}/agno/api/team.py +0 -0
  80. {agno-2.3.10 → agno-2.3.12}/agno/api/workflow.py +0 -0
  81. {agno-2.3.10 → agno-2.3.12}/agno/cloud/aws/base.py +0 -0
  82. {agno-2.3.10 → agno-2.3.12}/agno/cloud/aws/s3/__init__.py +0 -0
  83. {agno-2.3.10 → agno-2.3.12}/agno/cloud/aws/s3/api_client.py +0 -0
  84. {agno-2.3.10 → agno-2.3.12}/agno/cloud/aws/s3/bucket.py +0 -0
  85. {agno-2.3.10 → agno-2.3.12}/agno/cloud/aws/s3/object.py +0 -0
  86. {agno-2.3.10 → agno-2.3.12}/agno/compression/__init__.py +0 -0
  87. {agno-2.3.10 → agno-2.3.12}/agno/culture/__init__.py +0 -0
  88. {agno-2.3.10 → agno-2.3.12}/agno/culture/manager.py +0 -0
  89. {agno-2.3.10 → agno-2.3.12}/agno/db/__init__.py +0 -0
  90. {agno-2.3.10 → agno-2.3.12}/agno/db/async_postgres/__init__.py +0 -0
  91. {agno-2.3.10 → agno-2.3.12}/agno/db/dynamo/__init__.py +0 -0
  92. {agno-2.3.10 → agno-2.3.12}/agno/db/dynamo/schemas.py +0 -0
  93. {agno-2.3.10 → agno-2.3.12}/agno/db/dynamo/utils.py +0 -0
  94. {agno-2.3.10 → agno-2.3.12}/agno/db/firestore/__init__.py +0 -0
  95. {agno-2.3.10 → agno-2.3.12}/agno/db/firestore/schemas.py +0 -0
  96. {agno-2.3.10 → agno-2.3.12}/agno/db/firestore/utils.py +0 -0
  97. {agno-2.3.10 → agno-2.3.12}/agno/db/gcs_json/__init__.py +0 -0
  98. {agno-2.3.10 → agno-2.3.12}/agno/db/gcs_json/utils.py +0 -0
  99. {agno-2.3.10 → agno-2.3.12}/agno/db/in_memory/__init__.py +0 -0
  100. {agno-2.3.10 → agno-2.3.12}/agno/db/in_memory/utils.py +0 -0
  101. {agno-2.3.10 → agno-2.3.12}/agno/db/json/__init__.py +0 -0
  102. {agno-2.3.10 → agno-2.3.12}/agno/db/json/utils.py +0 -0
  103. {agno-2.3.10 → agno-2.3.12}/agno/db/migrations/__init__.py +0 -0
  104. {agno-2.3.10 → agno-2.3.12}/agno/db/migrations/manager.py +0 -0
  105. {agno-2.3.10 → agno-2.3.12}/agno/db/migrations/v1_to_v2.py +0 -0
  106. {agno-2.3.10 → agno-2.3.12}/agno/db/migrations/versions/__init__.py +0 -0
  107. {agno-2.3.10 → agno-2.3.12}/agno/db/migrations/versions/v2_3_0.py +0 -0
  108. {agno-2.3.10 → agno-2.3.12}/agno/db/mongo/__init__.py +0 -0
  109. {agno-2.3.10 → agno-2.3.12}/agno/db/mongo/schemas.py +0 -0
  110. {agno-2.3.10 → agno-2.3.12}/agno/db/mongo/utils.py +0 -0
  111. {agno-2.3.10 → agno-2.3.12}/agno/db/mysql/__init__.py +0 -0
  112. {agno-2.3.10 → agno-2.3.12}/agno/db/mysql/schemas.py +0 -0
  113. {agno-2.3.10 → agno-2.3.12}/agno/db/mysql/utils.py +0 -0
  114. {agno-2.3.10 → agno-2.3.12}/agno/db/postgres/__init__.py +0 -0
  115. {agno-2.3.10 → agno-2.3.12}/agno/db/postgres/schemas.py +0 -0
  116. {agno-2.3.10 → agno-2.3.12}/agno/db/postgres/utils.py +0 -0
  117. {agno-2.3.10 → agno-2.3.12}/agno/db/redis/__init__.py +0 -0
  118. {agno-2.3.10 → agno-2.3.12}/agno/db/redis/schemas.py +0 -0
  119. {agno-2.3.10 → agno-2.3.12}/agno/db/redis/utils.py +0 -0
  120. {agno-2.3.10 → agno-2.3.12}/agno/db/schemas/__init__.py +0 -0
  121. {agno-2.3.10 → agno-2.3.12}/agno/db/schemas/culture.py +0 -0
  122. {agno-2.3.10 → agno-2.3.12}/agno/db/schemas/evals.py +0 -0
  123. {agno-2.3.10 → agno-2.3.12}/agno/db/schemas/knowledge.py +0 -0
  124. {agno-2.3.10 → agno-2.3.12}/agno/db/schemas/memory.py +0 -0
  125. {agno-2.3.10 → agno-2.3.12}/agno/db/schemas/metrics.py +0 -0
  126. {agno-2.3.10 → agno-2.3.12}/agno/db/singlestore/__init__.py +0 -0
  127. {agno-2.3.10 → agno-2.3.12}/agno/db/singlestore/schemas.py +0 -0
  128. {agno-2.3.10 → agno-2.3.12}/agno/db/singlestore/utils.py +0 -0
  129. {agno-2.3.10 → agno-2.3.12}/agno/db/sqlite/__init__.py +0 -0
  130. {agno-2.3.10 → agno-2.3.12}/agno/db/sqlite/schemas.py +0 -0
  131. {agno-2.3.10 → agno-2.3.12}/agno/db/sqlite/utils.py +0 -0
  132. {agno-2.3.10 → agno-2.3.12}/agno/db/surrealdb/__init__.py +0 -0
  133. {agno-2.3.10 → agno-2.3.12}/agno/db/surrealdb/metrics.py +0 -0
  134. {agno-2.3.10 → agno-2.3.12}/agno/db/surrealdb/models.py +0 -0
  135. {agno-2.3.10 → agno-2.3.12}/agno/db/surrealdb/queries.py +0 -0
  136. {agno-2.3.10 → agno-2.3.12}/agno/db/surrealdb/utils.py +0 -0
  137. {agno-2.3.10 → agno-2.3.12}/agno/db/utils.py +0 -0
  138. {agno-2.3.10 → agno-2.3.12}/agno/debug.py +0 -0
  139. {agno-2.3.10 → agno-2.3.12}/agno/eval/__init__.py +0 -0
  140. {agno-2.3.10 → agno-2.3.12}/agno/eval/accuracy.py +0 -0
  141. {agno-2.3.10 → agno-2.3.12}/agno/eval/agent_as_judge.py +0 -0
  142. {agno-2.3.10 → agno-2.3.12}/agno/eval/base.py +0 -0
  143. {agno-2.3.10 → agno-2.3.12}/agno/eval/performance.py +0 -0
  144. {agno-2.3.10 → agno-2.3.12}/agno/eval/reliability.py +0 -0
  145. {agno-2.3.10 → agno-2.3.12}/agno/eval/utils.py +0 -0
  146. {agno-2.3.10 → agno-2.3.12}/agno/filters.py +0 -0
  147. {agno-2.3.10 → agno-2.3.12}/agno/guardrails/__init__.py +0 -0
  148. {agno-2.3.10 → agno-2.3.12}/agno/guardrails/base.py +0 -0
  149. {agno-2.3.10 → agno-2.3.12}/agno/guardrails/openai.py +0 -0
  150. {agno-2.3.10 → agno-2.3.12}/agno/guardrails/pii.py +0 -0
  151. {agno-2.3.10 → agno-2.3.12}/agno/guardrails/prompt_injection.py +0 -0
  152. {agno-2.3.10 → agno-2.3.12}/agno/hooks/__init__.py +0 -0
  153. {agno-2.3.10 → agno-2.3.12}/agno/hooks/decorator.py +0 -0
  154. {agno-2.3.10 → agno-2.3.12}/agno/integrations/__init__.py +0 -0
  155. {agno-2.3.10 → agno-2.3.12}/agno/integrations/discord/__init__.py +0 -0
  156. {agno-2.3.10 → agno-2.3.12}/agno/integrations/discord/client.py +0 -0
  157. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/__init__.py +0 -0
  158. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/__init__.py +0 -0
  159. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/agentic.py +0 -0
  160. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/document.py +0 -0
  161. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/markdown.py +0 -0
  162. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/recursive.py +0 -0
  163. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/row.py +0 -0
  164. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/semantic.py +0 -0
  165. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/chunking/strategy.py +0 -0
  166. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/content.py +0 -0
  167. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/document/__init__.py +0 -0
  168. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/document/base.py +0 -0
  169. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/__init__.py +0 -0
  170. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/aws_bedrock.py +0 -0
  171. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/azure_openai.py +0 -0
  172. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/base.py +0 -0
  173. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/cohere.py +0 -0
  174. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/fastembed.py +0 -0
  175. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/fireworks.py +0 -0
  176. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/google.py +0 -0
  177. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/huggingface.py +0 -0
  178. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/jina.py +0 -0
  179. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/langdb.py +0 -0
  180. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/mistral.py +0 -0
  181. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/nebius.py +0 -0
  182. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/ollama.py +0 -0
  183. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/openai.py +0 -0
  184. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/sentence_transformer.py +0 -0
  185. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/together.py +0 -0
  186. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/vllm.py +0 -0
  187. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/embedder/voyageai.py +0 -0
  188. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/__init__.py +0 -0
  189. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/arxiv_reader.py +0 -0
  190. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/base.py +0 -0
  191. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/docx_reader.py +0 -0
  192. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/field_labeled_csv_reader.py +0 -0
  193. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/firecrawl_reader.py +0 -0
  194. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/json_reader.py +0 -0
  195. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/markdown_reader.py +0 -0
  196. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/pdf_reader.py +0 -0
  197. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/pptx_reader.py +0 -0
  198. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/reader_factory.py +0 -0
  199. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/s3_reader.py +0 -0
  200. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/tavily_reader.py +0 -0
  201. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/web_search_reader.py +0 -0
  202. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/website_reader.py +0 -0
  203. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reader/youtube_reader.py +0 -0
  204. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/remote_content/__init__.py +0 -0
  205. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/remote_content/remote_content.py +0 -0
  206. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reranker/__init__.py +0 -0
  207. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reranker/base.py +0 -0
  208. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reranker/cohere.py +0 -0
  209. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reranker/infinity.py +0 -0
  210. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/reranker/sentence_transformer.py +0 -0
  211. {agno-2.3.10 → agno-2.3.12}/agno/knowledge/types.py +0 -0
  212. {agno-2.3.10 → agno-2.3.12}/agno/media.py +0 -0
  213. {agno-2.3.10 → agno-2.3.12}/agno/memory/__init__.py +0 -0
  214. {agno-2.3.10 → agno-2.3.12}/agno/memory/manager.py +0 -0
  215. {agno-2.3.10 → agno-2.3.12}/agno/memory/strategies/__init__.py +0 -0
  216. {agno-2.3.10 → agno-2.3.12}/agno/memory/strategies/summarize.py +0 -0
  217. {agno-2.3.10 → agno-2.3.12}/agno/memory/strategies/types.py +0 -0
  218. {agno-2.3.10 → agno-2.3.12}/agno/models/__init__.py +0 -0
  219. {agno-2.3.10 → agno-2.3.12}/agno/models/aimlapi/__init__.py +0 -0
  220. {agno-2.3.10 → agno-2.3.12}/agno/models/aimlapi/aimlapi.py +0 -0
  221. {agno-2.3.10 → agno-2.3.12}/agno/models/anthropic/__init__.py +0 -0
  222. {agno-2.3.10 → agno-2.3.12}/agno/models/aws/__init__.py +0 -0
  223. {agno-2.3.10 → agno-2.3.12}/agno/models/aws/claude.py +0 -0
  224. {agno-2.3.10 → agno-2.3.12}/agno/models/azure/__init__.py +0 -0
  225. {agno-2.3.10 → agno-2.3.12}/agno/models/azure/ai_foundry.py +0 -0
  226. {agno-2.3.10 → agno-2.3.12}/agno/models/azure/openai_chat.py +0 -0
  227. {agno-2.3.10 → agno-2.3.12}/agno/models/cerebras/__init__.py +0 -0
  228. {agno-2.3.10 → agno-2.3.12}/agno/models/cerebras/cerebras.py +0 -0
  229. {agno-2.3.10 → agno-2.3.12}/agno/models/cerebras/cerebras_openai.py +0 -0
  230. {agno-2.3.10 → agno-2.3.12}/agno/models/cohere/__init__.py +0 -0
  231. {agno-2.3.10 → agno-2.3.12}/agno/models/cohere/chat.py +0 -0
  232. {agno-2.3.10 → agno-2.3.12}/agno/models/cometapi/__init__.py +0 -0
  233. {agno-2.3.10 → agno-2.3.12}/agno/models/cometapi/cometapi.py +0 -0
  234. {agno-2.3.10 → agno-2.3.12}/agno/models/dashscope/__init__.py +0 -0
  235. {agno-2.3.10 → agno-2.3.12}/agno/models/dashscope/dashscope.py +0 -0
  236. {agno-2.3.10 → agno-2.3.12}/agno/models/deepinfra/__init__.py +0 -0
  237. {agno-2.3.10 → agno-2.3.12}/agno/models/deepinfra/deepinfra.py +0 -0
  238. {agno-2.3.10 → agno-2.3.12}/agno/models/deepseek/__init__.py +0 -0
  239. {agno-2.3.10 → agno-2.3.12}/agno/models/deepseek/deepseek.py +0 -0
  240. {agno-2.3.10 → agno-2.3.12}/agno/models/defaults.py +0 -0
  241. {agno-2.3.10 → agno-2.3.12}/agno/models/fireworks/__init__.py +0 -0
  242. {agno-2.3.10 → agno-2.3.12}/agno/models/fireworks/fireworks.py +0 -0
  243. {agno-2.3.10 → agno-2.3.12}/agno/models/google/__init__.py +0 -0
  244. {agno-2.3.10 → agno-2.3.12}/agno/models/google/utils.py +0 -0
  245. {agno-2.3.10 → agno-2.3.12}/agno/models/groq/__init__.py +0 -0
  246. {agno-2.3.10 → agno-2.3.12}/agno/models/groq/groq.py +0 -0
  247. {agno-2.3.10 → agno-2.3.12}/agno/models/huggingface/__init__.py +0 -0
  248. {agno-2.3.10 → agno-2.3.12}/agno/models/huggingface/huggingface.py +0 -0
  249. {agno-2.3.10 → agno-2.3.12}/agno/models/ibm/__init__.py +0 -0
  250. {agno-2.3.10 → agno-2.3.12}/agno/models/ibm/watsonx.py +0 -0
  251. {agno-2.3.10 → agno-2.3.12}/agno/models/internlm/__init__.py +0 -0
  252. {agno-2.3.10 → agno-2.3.12}/agno/models/internlm/internlm.py +0 -0
  253. {agno-2.3.10 → agno-2.3.12}/agno/models/langdb/__init__.py +0 -0
  254. {agno-2.3.10 → agno-2.3.12}/agno/models/langdb/langdb.py +0 -0
  255. {agno-2.3.10 → agno-2.3.12}/agno/models/litellm/__init__.py +0 -0
  256. {agno-2.3.10 → agno-2.3.12}/agno/models/litellm/litellm_openai.py +0 -0
  257. {agno-2.3.10 → agno-2.3.12}/agno/models/llama_cpp/__init__.py +0 -0
  258. {agno-2.3.10 → agno-2.3.12}/agno/models/llama_cpp/llama_cpp.py +0 -0
  259. {agno-2.3.10 → agno-2.3.12}/agno/models/lmstudio/__init__.py +0 -0
  260. {agno-2.3.10 → agno-2.3.12}/agno/models/lmstudio/lmstudio.py +0 -0
  261. {agno-2.3.10 → agno-2.3.12}/agno/models/message.py +0 -0
  262. {agno-2.3.10 → agno-2.3.12}/agno/models/meta/__init__.py +0 -0
  263. {agno-2.3.10 → agno-2.3.12}/agno/models/meta/llama.py +0 -0
  264. {agno-2.3.10 → agno-2.3.12}/agno/models/meta/llama_openai.py +0 -0
  265. {agno-2.3.10 → agno-2.3.12}/agno/models/metrics.py +0 -0
  266. {agno-2.3.10 → agno-2.3.12}/agno/models/mistral/__init__.py +0 -0
  267. {agno-2.3.10 → agno-2.3.12}/agno/models/mistral/mistral.py +0 -0
  268. {agno-2.3.10 → agno-2.3.12}/agno/models/nebius/__init__.py +0 -0
  269. {agno-2.3.10 → agno-2.3.12}/agno/models/nebius/nebius.py +0 -0
  270. {agno-2.3.10 → agno-2.3.12}/agno/models/nexus/__init__.py +0 -0
  271. {agno-2.3.10 → agno-2.3.12}/agno/models/nexus/nexus.py +0 -0
  272. {agno-2.3.10 → agno-2.3.12}/agno/models/nvidia/__init__.py +0 -0
  273. {agno-2.3.10 → agno-2.3.12}/agno/models/nvidia/nvidia.py +0 -0
  274. {agno-2.3.10 → agno-2.3.12}/agno/models/ollama/__init__.py +0 -0
  275. {agno-2.3.10 → agno-2.3.12}/agno/models/ollama/chat.py +0 -0
  276. {agno-2.3.10 → agno-2.3.12}/agno/models/openai/__init__.py +0 -0
  277. {agno-2.3.10 → agno-2.3.12}/agno/models/openai/like.py +0 -0
  278. {agno-2.3.10 → agno-2.3.12}/agno/models/openrouter/__init__.py +0 -0
  279. {agno-2.3.10 → agno-2.3.12}/agno/models/openrouter/openrouter.py +0 -0
  280. {agno-2.3.10 → agno-2.3.12}/agno/models/perplexity/__init__.py +0 -0
  281. {agno-2.3.10 → agno-2.3.12}/agno/models/perplexity/perplexity.py +0 -0
  282. {agno-2.3.10 → agno-2.3.12}/agno/models/portkey/__init__.py +0 -0
  283. {agno-2.3.10 → agno-2.3.12}/agno/models/portkey/portkey.py +0 -0
  284. {agno-2.3.10 → agno-2.3.12}/agno/models/requesty/__init__.py +0 -0
  285. {agno-2.3.10 → agno-2.3.12}/agno/models/requesty/requesty.py +0 -0
  286. {agno-2.3.10 → agno-2.3.12}/agno/models/response.py +0 -0
  287. {agno-2.3.10 → agno-2.3.12}/agno/models/sambanova/__init__.py +0 -0
  288. {agno-2.3.10 → agno-2.3.12}/agno/models/sambanova/sambanova.py +0 -0
  289. {agno-2.3.10 → agno-2.3.12}/agno/models/siliconflow/__init__.py +0 -0
  290. {agno-2.3.10 → agno-2.3.12}/agno/models/siliconflow/siliconflow.py +0 -0
  291. {agno-2.3.10 → agno-2.3.12}/agno/models/together/__init__.py +0 -0
  292. {agno-2.3.10 → agno-2.3.12}/agno/models/together/together.py +0 -0
  293. {agno-2.3.10 → agno-2.3.12}/agno/models/utils.py +0 -0
  294. {agno-2.3.10 → agno-2.3.12}/agno/models/vercel/__init__.py +0 -0
  295. {agno-2.3.10 → agno-2.3.12}/agno/models/vercel/v0.py +0 -0
  296. {agno-2.3.10 → agno-2.3.12}/agno/models/vertexai/__init__.py +0 -0
  297. {agno-2.3.10 → agno-2.3.12}/agno/models/vertexai/claude.py +0 -0
  298. {agno-2.3.10 → agno-2.3.12}/agno/models/vllm/__init__.py +0 -0
  299. {agno-2.3.10 → agno-2.3.12}/agno/models/vllm/vllm.py +0 -0
  300. {agno-2.3.10 → agno-2.3.12}/agno/models/xai/__init__.py +0 -0
  301. {agno-2.3.10 → agno-2.3.12}/agno/models/xai/xai.py +0 -0
  302. {agno-2.3.10 → agno-2.3.12}/agno/os/__init__.py +0 -0
  303. {agno-2.3.10 → agno-2.3.12}/agno/os/app.py +0 -0
  304. {agno-2.3.10 → agno-2.3.12}/agno/os/auth.py +0 -0
  305. {agno-2.3.10 → agno-2.3.12}/agno/os/config.py +0 -0
  306. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/__init__.py +0 -0
  307. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/a2a/__init__.py +0 -0
  308. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/a2a/a2a.py +0 -0
  309. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/a2a/router.py +0 -0
  310. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/a2a/utils.py +0 -0
  311. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/agui/__init__.py +0 -0
  312. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/agui/agui.py +0 -0
  313. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/agui/router.py +0 -0
  314. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/agui/utils.py +0 -0
  315. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/base.py +0 -0
  316. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/slack/__init__.py +0 -0
  317. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/slack/router.py +0 -0
  318. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/slack/security.py +0 -0
  319. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/slack/slack.py +0 -0
  320. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/whatsapp/__init__.py +0 -0
  321. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/whatsapp/router.py +0 -0
  322. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/whatsapp/security.py +0 -0
  323. {agno-2.3.10 → agno-2.3.12}/agno/os/interfaces/whatsapp/whatsapp.py +0 -0
  324. {agno-2.3.10 → agno-2.3.12}/agno/os/mcp.py +0 -0
  325. {agno-2.3.10 → agno-2.3.12}/agno/os/middleware/__init__.py +0 -0
  326. {agno-2.3.10 → agno-2.3.12}/agno/os/middleware/jwt.py +0 -0
  327. {agno-2.3.10 → agno-2.3.12}/agno/os/router.py +0 -0
  328. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/__init__.py +0 -0
  329. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/agents/__init__.py +0 -0
  330. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/agents/router.py +0 -0
  331. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/agents/schema.py +0 -0
  332. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/evals/__init__.py +0 -0
  333. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/evals/evals.py +0 -0
  334. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/evals/schemas.py +0 -0
  335. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/evals/utils.py +0 -0
  336. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/health.py +0 -0
  337. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/home.py +0 -0
  338. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/knowledge/__init__.py +0 -0
  339. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/knowledge/schemas.py +0 -0
  340. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/memory/__init__.py +0 -0
  341. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/memory/memory.py +0 -0
  342. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/memory/schemas.py +0 -0
  343. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/metrics/__init__.py +0 -0
  344. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/metrics/metrics.py +0 -0
  345. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/metrics/schemas.py +0 -0
  346. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/session/__init__.py +0 -0
  347. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/session/session.py +0 -0
  348. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/teams/__init__.py +0 -0
  349. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/teams/router.py +0 -0
  350. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/teams/schema.py +0 -0
  351. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/traces/__init__.py +0 -0
  352. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/traces/schemas.py +0 -0
  353. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/traces/traces.py +0 -0
  354. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/workflows/__init__.py +0 -0
  355. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/workflows/router.py +0 -0
  356. {agno-2.3.10 → agno-2.3.12}/agno/os/routers/workflows/schema.py +0 -0
  357. {agno-2.3.10 → agno-2.3.12}/agno/os/schema.py +0 -0
  358. {agno-2.3.10 → agno-2.3.12}/agno/os/settings.py +0 -0
  359. {agno-2.3.10 → agno-2.3.12}/agno/os/utils.py +0 -0
  360. {agno-2.3.10 → agno-2.3.12}/agno/py.typed +0 -0
  361. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/__init__.py +0 -0
  362. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/anthropic.py +0 -0
  363. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/azure_ai_foundry.py +0 -0
  364. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/deepseek.py +0 -0
  365. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/default.py +0 -0
  366. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/gemini.py +0 -0
  367. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/groq.py +0 -0
  368. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/helpers.py +0 -0
  369. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/ollama.py +0 -0
  370. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/openai.py +0 -0
  371. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/step.py +0 -0
  372. {agno-2.3.10 → agno-2.3.12}/agno/reasoning/vertexai.py +0 -0
  373. {agno-2.3.10 → agno-2.3.12}/agno/run/__init__.py +0 -0
  374. {agno-2.3.10 → agno-2.3.12}/agno/run/base.py +0 -0
  375. {agno-2.3.10 → agno-2.3.12}/agno/run/cancel.py +0 -0
  376. {agno-2.3.10 → agno-2.3.12}/agno/run/messages.py +0 -0
  377. {agno-2.3.10 → agno-2.3.12}/agno/run/team.py +0 -0
  378. {agno-2.3.10 → agno-2.3.12}/agno/run/workflow.py +0 -0
  379. {agno-2.3.10 → agno-2.3.12}/agno/session/__init__.py +0 -0
  380. {agno-2.3.10 → agno-2.3.12}/agno/session/agent.py +0 -0
  381. {agno-2.3.10 → agno-2.3.12}/agno/session/summary.py +0 -0
  382. {agno-2.3.10 → agno-2.3.12}/agno/session/team.py +0 -0
  383. {agno-2.3.10 → agno-2.3.12}/agno/session/workflow.py +0 -0
  384. {agno-2.3.10 → agno-2.3.12}/agno/table.py +0 -0
  385. {agno-2.3.10 → agno-2.3.12}/agno/team/__init__.py +0 -0
  386. {agno-2.3.10 → agno-2.3.12}/agno/team/team.py +0 -0
  387. {agno-2.3.10 → agno-2.3.12}/agno/tools/__init__.py +0 -0
  388. {agno-2.3.10 → agno-2.3.12}/agno/tools/agentql.py +0 -0
  389. {agno-2.3.10 → agno-2.3.12}/agno/tools/airflow.py +0 -0
  390. {agno-2.3.10 → agno-2.3.12}/agno/tools/api.py +0 -0
  391. {agno-2.3.10 → agno-2.3.12}/agno/tools/apify.py +0 -0
  392. {agno-2.3.10 → agno-2.3.12}/agno/tools/arxiv.py +0 -0
  393. {agno-2.3.10 → agno-2.3.12}/agno/tools/aws_lambda.py +0 -0
  394. {agno-2.3.10 → agno-2.3.12}/agno/tools/aws_ses.py +0 -0
  395. {agno-2.3.10 → agno-2.3.12}/agno/tools/baidusearch.py +0 -0
  396. {agno-2.3.10 → agno-2.3.12}/agno/tools/bitbucket.py +0 -0
  397. {agno-2.3.10 → agno-2.3.12}/agno/tools/brandfetch.py +0 -0
  398. {agno-2.3.10 → agno-2.3.12}/agno/tools/bravesearch.py +0 -0
  399. {agno-2.3.10 → agno-2.3.12}/agno/tools/brightdata.py +0 -0
  400. {agno-2.3.10 → agno-2.3.12}/agno/tools/browserbase.py +0 -0
  401. {agno-2.3.10 → agno-2.3.12}/agno/tools/calcom.py +0 -0
  402. {agno-2.3.10 → agno-2.3.12}/agno/tools/calculator.py +0 -0
  403. {agno-2.3.10 → agno-2.3.12}/agno/tools/cartesia.py +0 -0
  404. {agno-2.3.10 → agno-2.3.12}/agno/tools/clickup.py +0 -0
  405. {agno-2.3.10 → agno-2.3.12}/agno/tools/confluence.py +0 -0
  406. {agno-2.3.10 → agno-2.3.12}/agno/tools/crawl4ai.py +0 -0
  407. {agno-2.3.10 → agno-2.3.12}/agno/tools/csv_toolkit.py +0 -0
  408. {agno-2.3.10 → agno-2.3.12}/agno/tools/dalle.py +0 -0
  409. {agno-2.3.10 → agno-2.3.12}/agno/tools/daytona.py +0 -0
  410. {agno-2.3.10 → agno-2.3.12}/agno/tools/decorator.py +0 -0
  411. {agno-2.3.10 → agno-2.3.12}/agno/tools/desi_vocal.py +0 -0
  412. {agno-2.3.10 → agno-2.3.12}/agno/tools/discord.py +0 -0
  413. {agno-2.3.10 → agno-2.3.12}/agno/tools/docker.py +0 -0
  414. {agno-2.3.10 → agno-2.3.12}/agno/tools/duckdb.py +0 -0
  415. {agno-2.3.10 → agno-2.3.12}/agno/tools/duckduckgo.py +0 -0
  416. {agno-2.3.10 → agno-2.3.12}/agno/tools/e2b.py +0 -0
  417. {agno-2.3.10 → agno-2.3.12}/agno/tools/eleven_labs.py +0 -0
  418. {agno-2.3.10 → agno-2.3.12}/agno/tools/email.py +0 -0
  419. {agno-2.3.10 → agno-2.3.12}/agno/tools/evm.py +0 -0
  420. {agno-2.3.10 → agno-2.3.12}/agno/tools/exa.py +0 -0
  421. {agno-2.3.10 → agno-2.3.12}/agno/tools/fal.py +0 -0
  422. {agno-2.3.10 → agno-2.3.12}/agno/tools/file.py +0 -0
  423. {agno-2.3.10 → agno-2.3.12}/agno/tools/file_generation.py +0 -0
  424. {agno-2.3.10 → agno-2.3.12}/agno/tools/financial_datasets.py +0 -0
  425. {agno-2.3.10 → agno-2.3.12}/agno/tools/firecrawl.py +0 -0
  426. {agno-2.3.10 → agno-2.3.12}/agno/tools/function.py +0 -0
  427. {agno-2.3.10 → agno-2.3.12}/agno/tools/giphy.py +0 -0
  428. {agno-2.3.10 → agno-2.3.12}/agno/tools/github.py +0 -0
  429. {agno-2.3.10 → agno-2.3.12}/agno/tools/gmail.py +0 -0
  430. {agno-2.3.10 → agno-2.3.12}/agno/tools/google_bigquery.py +0 -0
  431. {agno-2.3.10 → agno-2.3.12}/agno/tools/google_drive.py +0 -0
  432. {agno-2.3.10 → agno-2.3.12}/agno/tools/google_maps.py +0 -0
  433. {agno-2.3.10 → agno-2.3.12}/agno/tools/googlecalendar.py +0 -0
  434. {agno-2.3.10 → agno-2.3.12}/agno/tools/googlesheets.py +0 -0
  435. {agno-2.3.10 → agno-2.3.12}/agno/tools/hackernews.py +0 -0
  436. {agno-2.3.10 → agno-2.3.12}/agno/tools/jina.py +0 -0
  437. {agno-2.3.10 → agno-2.3.12}/agno/tools/jira.py +0 -0
  438. {agno-2.3.10 → agno-2.3.12}/agno/tools/knowledge.py +0 -0
  439. {agno-2.3.10 → agno-2.3.12}/agno/tools/linear.py +0 -0
  440. {agno-2.3.10 → agno-2.3.12}/agno/tools/linkup.py +0 -0
  441. {agno-2.3.10 → agno-2.3.12}/agno/tools/local_file_system.py +0 -0
  442. {agno-2.3.10 → agno-2.3.12}/agno/tools/lumalab.py +0 -0
  443. {agno-2.3.10 → agno-2.3.12}/agno/tools/mcp/__init__.py +0 -0
  444. {agno-2.3.10 → agno-2.3.12}/agno/tools/mcp/mcp.py +0 -0
  445. {agno-2.3.10 → agno-2.3.12}/agno/tools/mcp/multi_mcp.py +0 -0
  446. {agno-2.3.10 → agno-2.3.12}/agno/tools/mcp/params.py +0 -0
  447. {agno-2.3.10 → agno-2.3.12}/agno/tools/mcp_toolbox.py +0 -0
  448. {agno-2.3.10 → agno-2.3.12}/agno/tools/mem0.py +0 -0
  449. {agno-2.3.10 → agno-2.3.12}/agno/tools/memory.py +0 -0
  450. {agno-2.3.10 → agno-2.3.12}/agno/tools/mlx_transcribe.py +0 -0
  451. {agno-2.3.10 → agno-2.3.12}/agno/tools/models/__init__.py +0 -0
  452. {agno-2.3.10 → agno-2.3.12}/agno/tools/models/azure_openai.py +0 -0
  453. {agno-2.3.10 → agno-2.3.12}/agno/tools/models/gemini.py +0 -0
  454. {agno-2.3.10 → agno-2.3.12}/agno/tools/models/groq.py +0 -0
  455. {agno-2.3.10 → agno-2.3.12}/agno/tools/models/morph.py +0 -0
  456. {agno-2.3.10 → agno-2.3.12}/agno/tools/models/nebius.py +0 -0
  457. {agno-2.3.10 → agno-2.3.12}/agno/tools/models_labs.py +0 -0
  458. {agno-2.3.10 → agno-2.3.12}/agno/tools/moviepy_video.py +0 -0
  459. {agno-2.3.10 → agno-2.3.12}/agno/tools/nano_banana.py +0 -0
  460. {agno-2.3.10 → agno-2.3.12}/agno/tools/neo4j.py +0 -0
  461. {agno-2.3.10 → agno-2.3.12}/agno/tools/newspaper.py +0 -0
  462. {agno-2.3.10 → agno-2.3.12}/agno/tools/newspaper4k.py +0 -0
  463. {agno-2.3.10 → agno-2.3.12}/agno/tools/notion.py +0 -0
  464. {agno-2.3.10 → agno-2.3.12}/agno/tools/openai.py +0 -0
  465. {agno-2.3.10 → agno-2.3.12}/agno/tools/openbb.py +0 -0
  466. {agno-2.3.10 → agno-2.3.12}/agno/tools/opencv.py +0 -0
  467. {agno-2.3.10 → agno-2.3.12}/agno/tools/openweather.py +0 -0
  468. {agno-2.3.10 → agno-2.3.12}/agno/tools/oxylabs.py +0 -0
  469. {agno-2.3.10 → agno-2.3.12}/agno/tools/pandas.py +0 -0
  470. {agno-2.3.10 → agno-2.3.12}/agno/tools/parallel.py +0 -0
  471. {agno-2.3.10 → agno-2.3.12}/agno/tools/postgres.py +0 -0
  472. {agno-2.3.10 → agno-2.3.12}/agno/tools/pubmed.py +0 -0
  473. {agno-2.3.10 → agno-2.3.12}/agno/tools/python.py +0 -0
  474. {agno-2.3.10 → agno-2.3.12}/agno/tools/reasoning.py +0 -0
  475. {agno-2.3.10 → agno-2.3.12}/agno/tools/reddit.py +0 -0
  476. {agno-2.3.10 → agno-2.3.12}/agno/tools/redshift.py +0 -0
  477. {agno-2.3.10 → agno-2.3.12}/agno/tools/replicate.py +0 -0
  478. {agno-2.3.10 → agno-2.3.12}/agno/tools/resend.py +0 -0
  479. {agno-2.3.10 → agno-2.3.12}/agno/tools/scrapegraph.py +0 -0
  480. {agno-2.3.10 → agno-2.3.12}/agno/tools/searxng.py +0 -0
  481. {agno-2.3.10 → agno-2.3.12}/agno/tools/serpapi.py +0 -0
  482. {agno-2.3.10 → agno-2.3.12}/agno/tools/serper.py +0 -0
  483. {agno-2.3.10 → agno-2.3.12}/agno/tools/shell.py +0 -0
  484. {agno-2.3.10 → agno-2.3.12}/agno/tools/shopify.py +0 -0
  485. {agno-2.3.10 → agno-2.3.12}/agno/tools/slack.py +0 -0
  486. {agno-2.3.10 → agno-2.3.12}/agno/tools/sleep.py +0 -0
  487. {agno-2.3.10 → agno-2.3.12}/agno/tools/spider.py +0 -0
  488. {agno-2.3.10 → agno-2.3.12}/agno/tools/spotify.py +0 -0
  489. {agno-2.3.10 → agno-2.3.12}/agno/tools/sql.py +0 -0
  490. {agno-2.3.10 → agno-2.3.12}/agno/tools/streamlit/__init__.py +0 -0
  491. {agno-2.3.10 → agno-2.3.12}/agno/tools/streamlit/components.py +0 -0
  492. {agno-2.3.10 → agno-2.3.12}/agno/tools/tavily.py +0 -0
  493. {agno-2.3.10 → agno-2.3.12}/agno/tools/telegram.py +0 -0
  494. {agno-2.3.10 → agno-2.3.12}/agno/tools/todoist.py +0 -0
  495. {agno-2.3.10 → agno-2.3.12}/agno/tools/tool_registry.py +0 -0
  496. {agno-2.3.10 → agno-2.3.12}/agno/tools/toolkit.py +0 -0
  497. {agno-2.3.10 → agno-2.3.12}/agno/tools/trafilatura.py +0 -0
  498. {agno-2.3.10 → agno-2.3.12}/agno/tools/trello.py +0 -0
  499. {agno-2.3.10 → agno-2.3.12}/agno/tools/twilio.py +0 -0
  500. {agno-2.3.10 → agno-2.3.12}/agno/tools/user_control_flow.py +0 -0
  501. {agno-2.3.10 → agno-2.3.12}/agno/tools/valyu.py +0 -0
  502. {agno-2.3.10 → agno-2.3.12}/agno/tools/visualization.py +0 -0
  503. {agno-2.3.10 → agno-2.3.12}/agno/tools/webbrowser.py +0 -0
  504. {agno-2.3.10 → agno-2.3.12}/agno/tools/webex.py +0 -0
  505. {agno-2.3.10 → agno-2.3.12}/agno/tools/website.py +0 -0
  506. {agno-2.3.10 → agno-2.3.12}/agno/tools/webtools.py +0 -0
  507. {agno-2.3.10 → agno-2.3.12}/agno/tools/whatsapp.py +0 -0
  508. {agno-2.3.10 → agno-2.3.12}/agno/tools/wikipedia.py +0 -0
  509. {agno-2.3.10 → agno-2.3.12}/agno/tools/workflow.py +0 -0
  510. {agno-2.3.10 → agno-2.3.12}/agno/tools/x.py +0 -0
  511. {agno-2.3.10 → agno-2.3.12}/agno/tools/yfinance.py +0 -0
  512. {agno-2.3.10 → agno-2.3.12}/agno/tools/youtube.py +0 -0
  513. {agno-2.3.10 → agno-2.3.12}/agno/tools/zendesk.py +0 -0
  514. {agno-2.3.10 → agno-2.3.12}/agno/tools/zep.py +0 -0
  515. {agno-2.3.10 → agno-2.3.12}/agno/tools/zoom.py +0 -0
  516. {agno-2.3.10 → agno-2.3.12}/agno/tracing/__init__.py +0 -0
  517. {agno-2.3.10 → agno-2.3.12}/agno/tracing/schemas.py +0 -0
  518. {agno-2.3.10 → agno-2.3.12}/agno/tracing/setup.py +0 -0
  519. {agno-2.3.10 → agno-2.3.12}/agno/utils/__init__.py +0 -0
  520. {agno-2.3.10 → agno-2.3.12}/agno/utils/agent.py +0 -0
  521. {agno-2.3.10 → agno-2.3.12}/agno/utils/audio.py +0 -0
  522. {agno-2.3.10 → agno-2.3.12}/agno/utils/certs.py +0 -0
  523. {agno-2.3.10 → agno-2.3.12}/agno/utils/code_execution.py +0 -0
  524. {agno-2.3.10 → agno-2.3.12}/agno/utils/common.py +0 -0
  525. {agno-2.3.10 → agno-2.3.12}/agno/utils/dttm.py +0 -0
  526. {agno-2.3.10 → agno-2.3.12}/agno/utils/enum.py +0 -0
  527. {agno-2.3.10 → agno-2.3.12}/agno/utils/env.py +0 -0
  528. {agno-2.3.10 → agno-2.3.12}/agno/utils/events.py +0 -0
  529. {agno-2.3.10 → agno-2.3.12}/agno/utils/format_str.py +0 -0
  530. {agno-2.3.10 → agno-2.3.12}/agno/utils/functions.py +0 -0
  531. {agno-2.3.10 → agno-2.3.12}/agno/utils/gemini.py +0 -0
  532. {agno-2.3.10 → agno-2.3.12}/agno/utils/hooks.py +0 -0
  533. {agno-2.3.10 → agno-2.3.12}/agno/utils/http.py +0 -0
  534. {agno-2.3.10 → agno-2.3.12}/agno/utils/json_schema.py +0 -0
  535. {agno-2.3.10 → agno-2.3.12}/agno/utils/knowledge.py +0 -0
  536. {agno-2.3.10 → agno-2.3.12}/agno/utils/location.py +0 -0
  537. {agno-2.3.10 → agno-2.3.12}/agno/utils/log.py +0 -0
  538. {agno-2.3.10 → agno-2.3.12}/agno/utils/mcp.py +0 -0
  539. {agno-2.3.10 → agno-2.3.12}/agno/utils/media.py +0 -0
  540. {agno-2.3.10 → agno-2.3.12}/agno/utils/merge_dict.py +0 -0
  541. {agno-2.3.10 → agno-2.3.12}/agno/utils/message.py +0 -0
  542. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/__init__.py +0 -0
  543. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/ai_foundry.py +0 -0
  544. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/claude.py +0 -0
  545. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/cohere.py +0 -0
  546. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/llama.py +0 -0
  547. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/mistral.py +0 -0
  548. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/openai_responses.py +0 -0
  549. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/schema_utils.py +0 -0
  550. {agno-2.3.10 → agno-2.3.12}/agno/utils/models/watsonx.py +0 -0
  551. {agno-2.3.10 → agno-2.3.12}/agno/utils/openai.py +0 -0
  552. {agno-2.3.10 → agno-2.3.12}/agno/utils/pickle.py +0 -0
  553. {agno-2.3.10 → agno-2.3.12}/agno/utils/pprint.py +0 -0
  554. {agno-2.3.10 → agno-2.3.12}/agno/utils/print_response/__init__.py +0 -0
  555. {agno-2.3.10 → agno-2.3.12}/agno/utils/print_response/workflow.py +0 -0
  556. {agno-2.3.10 → agno-2.3.12}/agno/utils/prompts.py +0 -0
  557. {agno-2.3.10 → agno-2.3.12}/agno/utils/reasoning.py +0 -0
  558. {agno-2.3.10 → agno-2.3.12}/agno/utils/response.py +0 -0
  559. {agno-2.3.10 → agno-2.3.12}/agno/utils/response_iterator.py +0 -0
  560. {agno-2.3.10 → agno-2.3.12}/agno/utils/safe_formatter.py +0 -0
  561. {agno-2.3.10 → agno-2.3.12}/agno/utils/serialize.py +0 -0
  562. {agno-2.3.10 → agno-2.3.12}/agno/utils/shell.py +0 -0
  563. {agno-2.3.10 → agno-2.3.12}/agno/utils/streamlit.py +0 -0
  564. {agno-2.3.10 → agno-2.3.12}/agno/utils/string.py +0 -0
  565. {agno-2.3.10 → agno-2.3.12}/agno/utils/team.py +0 -0
  566. {agno-2.3.10 → agno-2.3.12}/agno/utils/timer.py +0 -0
  567. {agno-2.3.10 → agno-2.3.12}/agno/utils/tools.py +0 -0
  568. {agno-2.3.10 → agno-2.3.12}/agno/utils/web.py +0 -0
  569. {agno-2.3.10 → agno-2.3.12}/agno/utils/whatsapp.py +0 -0
  570. {agno-2.3.10 → agno-2.3.12}/agno/utils/yaml_io.py +0 -0
  571. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/__init__.py +0 -0
  572. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/cassandra/__init__.py +0 -0
  573. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/cassandra/cassandra.py +0 -0
  574. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
  575. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/cassandra/index.py +0 -0
  576. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/chroma/__init__.py +0 -0
  577. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/clickhouse/__init__.py +0 -0
  578. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
  579. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/clickhouse/index.py +0 -0
  580. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/couchbase/__init__.py +0 -0
  581. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/couchbase/couchbase.py +0 -0
  582. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/distance.py +0 -0
  583. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/lancedb/__init__.py +0 -0
  584. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/langchaindb/__init__.py +0 -0
  585. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/langchaindb/langchaindb.py +0 -0
  586. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/lightrag/__init__.py +0 -0
  587. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/lightrag/lightrag.py +0 -0
  588. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/llamaindex/__init__.py +0 -0
  589. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/llamaindex/llamaindexdb.py +0 -0
  590. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/milvus/__init__.py +0 -0
  591. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/mongodb/__init__.py +0 -0
  592. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/pgvector/__init__.py +0 -0
  593. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/pgvector/index.py +0 -0
  594. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/pineconedb/__init__.py +0 -0
  595. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/qdrant/__init__.py +0 -0
  596. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/redis/__init__.py +0 -0
  597. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/search.py +0 -0
  598. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/singlestore/__init__.py +0 -0
  599. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/singlestore/index.py +0 -0
  600. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/surrealdb/__init__.py +0 -0
  601. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/upstashdb/__init__.py +0 -0
  602. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/upstashdb/upstashdb.py +0 -0
  603. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/weaviate/__init__.py +0 -0
  604. {agno-2.3.10 → agno-2.3.12}/agno/vectordb/weaviate/index.py +0 -0
  605. {agno-2.3.10 → agno-2.3.12}/agno/workflow/__init__.py +0 -0
  606. {agno-2.3.10 → agno-2.3.12}/agno/workflow/agent.py +0 -0
  607. {agno-2.3.10 → agno-2.3.12}/agno/workflow/condition.py +0 -0
  608. {agno-2.3.10 → agno-2.3.12}/agno/workflow/loop.py +0 -0
  609. {agno-2.3.10 → agno-2.3.12}/agno/workflow/parallel.py +0 -0
  610. {agno-2.3.10 → agno-2.3.12}/agno/workflow/router.py +0 -0
  611. {agno-2.3.10 → agno-2.3.12}/agno/workflow/step.py +0 -0
  612. {agno-2.3.10 → agno-2.3.12}/agno/workflow/steps.py +0 -0
  613. {agno-2.3.10 → agno-2.3.12}/agno/workflow/types.py +0 -0
  614. {agno-2.3.10 → agno-2.3.12}/agno/workflow/workflow.py +0 -0
  615. {agno-2.3.10 → agno-2.3.12}/agno.egg-info/SOURCES.txt +0 -0
  616. {agno-2.3.10 → agno-2.3.12}/agno.egg-info/dependency_links.txt +0 -0
  617. {agno-2.3.10 → agno-2.3.12}/agno.egg-info/top_level.txt +0 -0
  618. {agno-2.3.10 → agno-2.3.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.3.10
3
+ Version: 2.3.12
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
@@ -102,6 +102,9 @@ Provides-Extra: openai
102
102
  Requires-Dist: openai; extra == "openai"
103
103
  Provides-Extra: portkey
104
104
  Requires-Dist: portkey-ai; extra == "portkey"
105
+ Provides-Extra: tokenizers
106
+ Requires-Dist: tiktoken; extra == "tokenizers"
107
+ Requires-Dist: tokenizers; extra == "tokenizers"
105
108
  Provides-Extra: agentql
106
109
  Requires-Dist: agentql; extra == "agentql"
107
110
  Provides-Extra: apify
@@ -1,7 +1,9 @@
1
1
  import asyncio
2
2
  from dataclasses import dataclass, field
3
3
  from textwrap import dedent
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Any, Dict, List, Optional, Type, Union
5
+
6
+ from pydantic import BaseModel
5
7
 
6
8
  from agno.models.base import Model
7
9
  from agno.models.message import Message
@@ -46,29 +48,56 @@ DEFAULT_COMPRESSION_PROMPT = dedent("""\
46
48
 
47
49
  @dataclass
48
50
  class CompressionManager:
49
- model: Optional[Model] = None
51
+ model: Optional[Model] = None # model used for compression
50
52
  compress_tool_results: bool = True
51
- compress_tool_results_limit: int = 3
53
+ compress_tool_results_limit: Optional[int] = None
54
+ compress_token_limit: Optional[int] = None
52
55
  compress_tool_call_instructions: Optional[str] = None
53
56
 
54
57
  stats: Dict[str, Any] = field(default_factory=dict)
55
58
 
59
+ def __post_init__(self):
60
+ if self.compress_tool_results_limit is None and self.compress_token_limit is None:
61
+ self.compress_tool_results_limit = 3
62
+
56
63
  def _is_tool_result_message(self, msg: Message) -> bool:
57
64
  return msg.role == "tool"
58
65
 
59
- def should_compress(self, messages: List[Message]) -> bool:
66
+ def should_compress(
67
+ self,
68
+ messages: List[Message],
69
+ tools: Optional[List] = None,
70
+ model: Optional[Model] = None,
71
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
72
+ ) -> bool:
73
+ """Check if tool results should be compressed.
74
+
75
+ Args:
76
+ messages: List of messages to check.
77
+ tools: List of tools for token counting.
78
+ model: The Agent / Team model.
79
+ response_format: Output schema for accurate token counting.
80
+ """
60
81
  if not self.compress_tool_results:
61
82
  return False
62
83
 
63
- uncompressed_tools_count = len(
64
- [m for m in messages if self._is_tool_result_message(m) and m.compressed_content is None]
65
- )
66
- should_compress = uncompressed_tools_count >= self.compress_tool_results_limit
67
-
68
- if should_compress:
69
- log_info(f"Tool call compression threshold hit. Compressing {uncompressed_tools_count} tool results")
84
+ # Token-based threshold check
85
+ if self.compress_token_limit is not None and model is not None:
86
+ tokens = model.count_tokens(messages, tools, response_format)
87
+ if tokens >= self.compress_token_limit:
88
+ log_info(f"Token limit hit: {tokens} >= {self.compress_token_limit}")
89
+ return True
90
+
91
+ # Count-based threshold check
92
+ if self.compress_tool_results_limit is not None:
93
+ uncompressed_tools_count = len(
94
+ [m for m in messages if self._is_tool_result_message(m) and m.compressed_content is None]
95
+ )
96
+ if uncompressed_tools_count >= self.compress_tool_results_limit:
97
+ log_info(f"Tool count limit hit: {uncompressed_tools_count} >= {self.compress_tool_results_limit}")
98
+ return True
70
99
 
71
- return should_compress
100
+ return False
72
101
 
73
102
  def _compress_tool_result(self, tool_result: Message) -> Optional[str]:
74
103
  if not tool_result:
@@ -112,14 +141,53 @@ class CompressionManager:
112
141
  compressed = self._compress_tool_result(tool_msg)
113
142
  if compressed:
114
143
  tool_msg.compressed_content = compressed
115
- # Track stats
116
- self.stats["messages_compressed"] = self.stats.get("messages_compressed", 0) + 1
144
+ # Count actual tool results (Gemini combines multiple in one message)
145
+ tool_results_count = len(tool_msg.tool_calls) if tool_msg.tool_calls else 1
146
+ self.stats["tool_results_compressed"] = (
147
+ self.stats.get("tool_results_compressed", 0) + tool_results_count
148
+ )
117
149
  self.stats["original_size"] = self.stats.get("original_size", 0) + original_len
118
150
  self.stats["compressed_size"] = self.stats.get("compressed_size", 0) + len(compressed)
119
151
  else:
120
152
  log_warning(f"Compression failed for {tool_msg.tool_name}")
121
153
 
122
154
  # * Async methods *#
155
+ async def ashould_compress(
156
+ self,
157
+ messages: List[Message],
158
+ tools: Optional[List] = None,
159
+ model: Optional[Model] = None,
160
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
161
+ ) -> bool:
162
+ """Async check if tool results should be compressed.
163
+
164
+ Args:
165
+ messages: List of messages to check.
166
+ tools: List of tools for token counting.
167
+ model: The Agent / Team model.
168
+ response_format: Output schema for accurate token counting.
169
+ """
170
+ if not self.compress_tool_results:
171
+ return False
172
+
173
+ # Token-based threshold check
174
+ if self.compress_token_limit is not None and model is not None:
175
+ tokens = await model.acount_tokens(messages, tools, response_format)
176
+ if tokens >= self.compress_token_limit:
177
+ log_info(f"Token limit hit: {tokens} >= {self.compress_token_limit}")
178
+ return True
179
+
180
+ # Count-based threshold check
181
+ if self.compress_tool_results_limit is not None:
182
+ uncompressed_tools_count = len(
183
+ [m for m in messages if self._is_tool_result_message(m) and m.compressed_content is None]
184
+ )
185
+ if uncompressed_tools_count >= self.compress_tool_results_limit:
186
+ log_info(f"Tool count limit hit: {uncompressed_tools_count} >= {self.compress_tool_results_limit}")
187
+ return True
188
+
189
+ return False
190
+
123
191
  async def _acompress_tool_result(self, tool_result: Message) -> Optional[str]:
124
192
  """Async compress a single tool result"""
125
193
  if not tool_result:
@@ -168,8 +236,11 @@ class CompressionManager:
168
236
  for msg, compressed, original_len in zip(uncompressed_tools, results, original_sizes):
169
237
  if compressed:
170
238
  msg.compressed_content = compressed
171
- # Track stats
172
- self.stats["messages_compressed"] = self.stats.get("messages_compressed", 0) + 1
239
+ # Count actual tool results (Gemini combines multiple in one message)
240
+ tool_results_count = len(msg.tool_calls) if msg.tool_calls else 1
241
+ self.stats["tool_results_compressed"] = (
242
+ self.stats.get("tool_results_compressed", 0) + tool_results_count
243
+ )
173
244
  self.stats["original_size"] = self.stats.get("original_size", 0) + original_len
174
245
  self.stats["compressed_size"] = self.stats.get("compressed_size", 0) + len(compressed)
175
246
  else:
@@ -308,8 +308,8 @@ class BaseDb(ABC):
308
308
 
309
309
  # --- Traces ---
310
310
  @abstractmethod
311
- def create_trace(self, trace: "Trace") -> None:
312
- """Create a single trace record in the database.
311
+ def upsert_trace(self, trace: "Trace") -> None:
312
+ """Create or update a single trace record in the database.
313
313
 
314
314
  Args:
315
315
  trace: The Trace object to store (one per trace_id).
@@ -759,11 +759,11 @@ class AsyncBaseDb(ABC):
759
759
 
760
760
  # --- Traces ---
761
761
  @abstractmethod
762
- async def create_trace(self, trace) -> None:
763
- """Create a single trace record in the database.
762
+ async def upsert_trace(self, trace) -> None:
763
+ """Create or update a single trace record in the database.
764
764
 
765
765
  Args:
766
- trace: The Trace object to store (one per trace_id).
766
+ trace: The Trace object to update (one per trace_id).
767
767
  """
768
768
  raise NotImplementedError
769
769
 
@@ -2076,8 +2076,8 @@ class DynamoDb(BaseDb):
2076
2076
  raise e
2077
2077
 
2078
2078
  # --- Traces ---
2079
- def create_trace(self, trace: "Trace") -> None:
2080
- """Create a single trace record in the database.
2079
+ def upsert_trace(self, trace: "Trace") -> None:
2080
+ """Create or update a single trace record in the database.
2081
2081
 
2082
2082
  Args:
2083
2083
  trace: The Trace object to store (one per trace_id).
@@ -1841,8 +1841,8 @@ class FirestoreDb(BaseDb):
1841
1841
  raise e
1842
1842
 
1843
1843
  # --- Traces ---
1844
- def create_trace(self, trace: "Trace") -> None:
1845
- """Create a single trace record in the database.
1844
+ def upsert_trace(self, trace: "Trace") -> None:
1845
+ """Create or update a single trace record in the database.
1846
1846
 
1847
1847
  Args:
1848
1848
  trace: The Trace object to store (one per trace_id).
@@ -1355,8 +1355,8 @@ class GcsJsonDb(BaseDb):
1355
1355
  raise e
1356
1356
 
1357
1357
  # --- Traces ---
1358
- def create_trace(self, trace: "Trace") -> None:
1359
- """Create a single trace record in the database.
1358
+ def upsert_trace(self, trace: "Trace") -> None:
1359
+ """Create or update a single trace record in the database.
1360
1360
 
1361
1361
  Args:
1362
1362
  trace: The Trace object to store (one per trace_id).
@@ -1173,8 +1173,8 @@ class InMemoryDb(BaseDb):
1173
1173
  raise e
1174
1174
 
1175
1175
  # --- Traces ---
1176
- def create_trace(self, trace: "Trace") -> None:
1177
- """Create a single trace record in the database.
1176
+ def upsert_trace(self, trace: "Trace") -> None:
1177
+ """Create or update a single trace record in the database.
1178
1178
 
1179
1179
  Args:
1180
1180
  trace: The Trace object to store (one per trace_id).
@@ -1349,8 +1349,8 @@ class JsonDb(BaseDb):
1349
1349
  raise e
1350
1350
 
1351
1351
  # --- Traces ---
1352
- def create_trace(self, trace: "Trace") -> None:
1353
- """Create a single trace record in the database.
1352
+ def upsert_trace(self, trace: "Trace") -> None:
1353
+ """Create or update a single trace record in the database.
1354
1354
 
1355
1355
  Args:
1356
1356
  trace: The Trace object to store (one per trace_id).
@@ -2191,8 +2191,45 @@ class AsyncMongoDb(AsyncBaseDb):
2191
2191
  raise e
2192
2192
 
2193
2193
  # --- Traces ---
2194
- async def create_trace(self, trace: "Trace") -> None:
2195
- """Create a single trace record in the database.
2194
+ def _get_component_level(
2195
+ self, workflow_id: Optional[str], team_id: Optional[str], agent_id: Optional[str], name: str
2196
+ ) -> int:
2197
+ """Get the component level for a trace based on its context.
2198
+
2199
+ Component levels (higher = more important):
2200
+ - 3: Workflow root (.run or .arun with workflow_id)
2201
+ - 2: Team root (.run or .arun with team_id)
2202
+ - 1: Agent root (.run or .arun with agent_id)
2203
+ - 0: Child span (not a root)
2204
+
2205
+ Args:
2206
+ workflow_id: The workflow ID of the trace.
2207
+ team_id: The team ID of the trace.
2208
+ agent_id: The agent ID of the trace.
2209
+ name: The name of the trace.
2210
+
2211
+ Returns:
2212
+ int: The component level (0-3).
2213
+ """
2214
+ # Check if name indicates a root span
2215
+ is_root_name = ".run" in name or ".arun" in name
2216
+
2217
+ if not is_root_name:
2218
+ return 0 # Child span (not a root)
2219
+ elif workflow_id:
2220
+ return 3 # Workflow root
2221
+ elif team_id:
2222
+ return 2 # Team root
2223
+ elif agent_id:
2224
+ return 1 # Agent root
2225
+ else:
2226
+ return 0 # Unknown
2227
+
2228
+ async def upsert_trace(self, trace: "Trace") -> None:
2229
+ """Create or update a single trace record in the database.
2230
+
2231
+ Uses MongoDB's update_one with upsert=True and aggregation pipeline
2232
+ to handle concurrent inserts atomically and avoid race conditions.
2196
2233
 
2197
2234
  Args:
2198
2235
  trace: The Trace object to store (one per trace_id).
@@ -2202,75 +2239,140 @@ class AsyncMongoDb(AsyncBaseDb):
2202
2239
  if collection is None:
2203
2240
  return
2204
2241
 
2205
- # Check if trace already exists
2206
- existing = await collection.find_one({"trace_id": trace.trace_id})
2207
-
2208
- if existing:
2209
- # workflow (level 3) > team (level 2) > agent (level 1) > child/unknown (level 0)
2210
- def get_component_level(
2211
- workflow_id: Optional[str], team_id: Optional[str], agent_id: Optional[str], name: str
2212
- ) -> int:
2213
- # Check if name indicates a root span
2214
- is_root_name = ".run" in name or ".arun" in name
2215
-
2216
- if not is_root_name:
2217
- return 0 # Child span (not a root)
2218
- elif workflow_id:
2219
- return 3 # Workflow root
2220
- elif team_id:
2221
- return 2 # Team root
2222
- elif agent_id:
2223
- return 1 # Agent root
2224
- else:
2225
- return 0 # Unknown
2226
-
2227
- existing_level = get_component_level(
2228
- existing.get("workflow_id"),
2229
- existing.get("team_id"),
2230
- existing.get("agent_id"),
2231
- existing.get("name", ""),
2232
- )
2233
- new_level = get_component_level(trace.workflow_id, trace.team_id, trace.agent_id, trace.name)
2234
-
2235
- # Only update name if new trace is from a higher or equal level
2236
- should_update_name = new_level > existing_level
2242
+ trace_dict = trace.to_dict()
2243
+ trace_dict.pop("total_spans", None)
2244
+ trace_dict.pop("error_count", None)
2237
2245
 
2238
- # Parse existing start_time to calculate correct duration
2239
- existing_start_time_str = existing.get("start_time")
2240
- if isinstance(existing_start_time_str, str):
2241
- existing_start_time = datetime.fromisoformat(existing_start_time_str.replace("Z", "+00:00"))
2242
- else:
2243
- existing_start_time = trace.start_time
2244
-
2245
- recalculated_duration_ms = int((trace.end_time - existing_start_time).total_seconds() * 1000)
2246
+ # Calculate the component level for the new trace
2247
+ new_level = self._get_component_level(trace.workflow_id, trace.team_id, trace.agent_id, trace.name)
2246
2248
 
2247
- update_values: Dict[str, Any] = {
2248
- "end_time": trace.end_time.isoformat(),
2249
- "duration_ms": recalculated_duration_ms,
2250
- "status": trace.status,
2251
- "name": trace.name if should_update_name else existing.get("name"),
2252
- }
2249
+ # Use MongoDB aggregation pipeline update for atomic upsert
2250
+ # This allows conditional logic within a single atomic operation
2251
+ pipeline: List[Dict[str, Any]] = [
2252
+ {
2253
+ "$set": {
2254
+ # Always update these fields
2255
+ "status": trace.status,
2256
+ "created_at": {"$ifNull": ["$created_at", trace_dict.get("created_at")]},
2257
+ # Use $min for start_time (keep earliest)
2258
+ "start_time": {
2259
+ "$cond": {
2260
+ "if": {"$eq": [{"$type": "$start_time"}, "missing"]},
2261
+ "then": trace_dict.get("start_time"),
2262
+ "else": {"$min": ["$start_time", trace_dict.get("start_time")]},
2263
+ }
2264
+ },
2265
+ # Use $max for end_time (keep latest)
2266
+ "end_time": {
2267
+ "$cond": {
2268
+ "if": {"$eq": [{"$type": "$end_time"}, "missing"]},
2269
+ "then": trace_dict.get("end_time"),
2270
+ "else": {"$max": ["$end_time", trace_dict.get("end_time")]},
2271
+ }
2272
+ },
2273
+ # Preserve existing non-null context values using $ifNull
2274
+ "run_id": {"$ifNull": [trace.run_id, "$run_id"]},
2275
+ "session_id": {"$ifNull": [trace.session_id, "$session_id"]},
2276
+ "user_id": {"$ifNull": [trace.user_id, "$user_id"]},
2277
+ "agent_id": {"$ifNull": [trace.agent_id, "$agent_id"]},
2278
+ "team_id": {"$ifNull": [trace.team_id, "$team_id"]},
2279
+ "workflow_id": {"$ifNull": [trace.workflow_id, "$workflow_id"]},
2280
+ }
2281
+ },
2282
+ {
2283
+ "$set": {
2284
+ # Calculate duration_ms from the (potentially updated) start_time and end_time
2285
+ # MongoDB stores dates as strings in ISO format, so we need to parse them
2286
+ "duration_ms": {
2287
+ "$cond": {
2288
+ "if": {
2289
+ "$and": [
2290
+ {"$ne": [{"$type": "$start_time"}, "missing"]},
2291
+ {"$ne": [{"$type": "$end_time"}, "missing"]},
2292
+ ]
2293
+ },
2294
+ "then": {
2295
+ "$subtract": [
2296
+ {"$toLong": {"$toDate": "$end_time"}},
2297
+ {"$toLong": {"$toDate": "$start_time"}},
2298
+ ]
2299
+ },
2300
+ "else": trace_dict.get("duration_ms", 0),
2301
+ }
2302
+ },
2303
+ # Update name based on component level priority
2304
+ # Only update if new trace is from a higher-level component
2305
+ "name": {
2306
+ "$cond": {
2307
+ "if": {"$eq": [{"$type": "$name"}, "missing"]},
2308
+ "then": trace.name,
2309
+ "else": {
2310
+ "$cond": {
2311
+ "if": {
2312
+ "$gt": [
2313
+ new_level,
2314
+ {
2315
+ "$switch": {
2316
+ "branches": [
2317
+ # Check if existing name is a root span
2318
+ {
2319
+ "case": {
2320
+ "$not": {
2321
+ "$or": [
2322
+ {
2323
+ "$regexMatch": {
2324
+ "input": {"$ifNull": ["$name", ""]},
2325
+ "regex": "\\.run",
2326
+ }
2327
+ },
2328
+ {
2329
+ "$regexMatch": {
2330
+ "input": {"$ifNull": ["$name", ""]},
2331
+ "regex": "\\.arun",
2332
+ }
2333
+ },
2334
+ ]
2335
+ }
2336
+ },
2337
+ "then": 0,
2338
+ },
2339
+ # Workflow root (level 3)
2340
+ {
2341
+ "case": {"$ne": ["$workflow_id", None]},
2342
+ "then": 3,
2343
+ },
2344
+ # Team root (level 2)
2345
+ {
2346
+ "case": {"$ne": ["$team_id", None]},
2347
+ "then": 2,
2348
+ },
2349
+ # Agent root (level 1)
2350
+ {
2351
+ "case": {"$ne": ["$agent_id", None]},
2352
+ "then": 1,
2353
+ },
2354
+ ],
2355
+ "default": 0,
2356
+ }
2357
+ },
2358
+ ]
2359
+ },
2360
+ "then": trace.name,
2361
+ "else": "$name",
2362
+ }
2363
+ },
2364
+ }
2365
+ },
2366
+ }
2367
+ },
2368
+ ]
2253
2369
 
2254
- # Update context fields ONLY if new value is not None (preserve non-null values)
2255
- if trace.run_id is not None:
2256
- update_values["run_id"] = trace.run_id
2257
- if trace.session_id is not None:
2258
- update_values["session_id"] = trace.session_id
2259
- if trace.user_id is not None:
2260
- update_values["user_id"] = trace.user_id
2261
- if trace.agent_id is not None:
2262
- update_values["agent_id"] = trace.agent_id
2263
- if trace.team_id is not None:
2264
- update_values["team_id"] = trace.team_id
2265
- if trace.workflow_id is not None:
2266
- update_values["workflow_id"] = trace.workflow_id
2267
-
2268
- await collection.update_one({"trace_id": trace.trace_id}, {"$set": update_values})
2269
- else:
2270
- trace_dict = trace.to_dict()
2271
- trace_dict.pop("total_spans", None)
2272
- trace_dict.pop("error_count", None)
2273
- await collection.insert_one(trace_dict)
2370
+ # Perform atomic upsert using aggregation pipeline
2371
+ await collection.update_one(
2372
+ {"trace_id": trace.trace_id},
2373
+ pipeline,
2374
+ upsert=True,
2375
+ )
2274
2376
 
2275
2377
  except Exception as e:
2276
2378
  log_error(f"Error creating trace: {e}")