agno 2.3.0__tar.gz → 2.3.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 (584) hide show
  1. {agno-2.3.0 → agno-2.3.2}/PKG-INFO +1 -1
  2. {agno-2.3.0 → agno-2.3.2}/agno/agent/agent.py +1 -1
  3. {agno-2.3.0 → agno-2.3.2}/agno/db/schemas/memory.py +7 -5
  4. {agno-2.3.0 → agno-2.3.2}/agno/db/sqlite/async_sqlite.py +3 -3
  5. {agno-2.3.0 → agno-2.3.2}/agno/db/sqlite/sqlite.py +4 -4
  6. {agno-2.3.0 → agno-2.3.2}/agno/memory/manager.py +6 -4
  7. {agno-2.3.0 → agno-2.3.2}/agno/models/anthropic/claude.py +281 -24
  8. {agno-2.3.0 → agno-2.3.2}/agno/os/app.py +6 -6
  9. {agno-2.3.0 → agno-2.3.2}/agno/os/router.py +0 -1
  10. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/memory/memory.py +3 -0
  11. {agno-2.3.0 → agno-2.3.2}/agno/session/workflow.py +1 -2
  12. {agno-2.3.0 → agno-2.3.2}/agno/team/team.py +6 -6
  13. agno-2.3.2/agno/tools/nano_banana.py +151 -0
  14. agno-2.3.2/agno/utils/dttm.py +46 -0
  15. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/claude.py +8 -0
  16. {agno-2.3.0 → agno-2.3.2}/agno/workflow/workflow.py +1 -1
  17. {agno-2.3.0 → agno-2.3.2}/agno.egg-info/PKG-INFO +1 -1
  18. {agno-2.3.0 → agno-2.3.2}/agno.egg-info/SOURCES.txt +1 -0
  19. {agno-2.3.0 → agno-2.3.2}/pyproject.toml +1 -1
  20. agno-2.3.0/agno/utils/dttm.py +0 -13
  21. {agno-2.3.0 → agno-2.3.2}/LICENSE +0 -0
  22. {agno-2.3.0 → agno-2.3.2}/README.md +0 -0
  23. {agno-2.3.0 → agno-2.3.2}/agno/__init__.py +0 -0
  24. {agno-2.3.0 → agno-2.3.2}/agno/agent/__init__.py +0 -0
  25. {agno-2.3.0 → agno-2.3.2}/agno/api/__init__.py +0 -0
  26. {agno-2.3.0 → agno-2.3.2}/agno/api/agent.py +0 -0
  27. {agno-2.3.0 → agno-2.3.2}/agno/api/api.py +0 -0
  28. {agno-2.3.0 → agno-2.3.2}/agno/api/evals.py +0 -0
  29. {agno-2.3.0 → agno-2.3.2}/agno/api/os.py +0 -0
  30. {agno-2.3.0 → agno-2.3.2}/agno/api/routes.py +0 -0
  31. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/__init__.py +0 -0
  32. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/agent.py +0 -0
  33. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/evals.py +0 -0
  34. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/os.py +0 -0
  35. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/response.py +0 -0
  36. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/team.py +0 -0
  37. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/utils.py +0 -0
  38. {agno-2.3.0 → agno-2.3.2}/agno/api/schemas/workflows.py +0 -0
  39. {agno-2.3.0 → agno-2.3.2}/agno/api/settings.py +0 -0
  40. {agno-2.3.0 → agno-2.3.2}/agno/api/team.py +0 -0
  41. {agno-2.3.0 → agno-2.3.2}/agno/api/workflow.py +0 -0
  42. {agno-2.3.0 → agno-2.3.2}/agno/cloud/aws/base.py +0 -0
  43. {agno-2.3.0 → agno-2.3.2}/agno/cloud/aws/s3/__init__.py +0 -0
  44. {agno-2.3.0 → agno-2.3.2}/agno/cloud/aws/s3/api_client.py +0 -0
  45. {agno-2.3.0 → agno-2.3.2}/agno/cloud/aws/s3/bucket.py +0 -0
  46. {agno-2.3.0 → agno-2.3.2}/agno/cloud/aws/s3/object.py +0 -0
  47. {agno-2.3.0 → agno-2.3.2}/agno/culture/__init__.py +0 -0
  48. {agno-2.3.0 → agno-2.3.2}/agno/culture/manager.py +0 -0
  49. {agno-2.3.0 → agno-2.3.2}/agno/db/__init__.py +0 -0
  50. {agno-2.3.0 → agno-2.3.2}/agno/db/async_postgres/__init__.py +0 -0
  51. {agno-2.3.0 → agno-2.3.2}/agno/db/base.py +0 -0
  52. {agno-2.3.0 → agno-2.3.2}/agno/db/dynamo/__init__.py +0 -0
  53. {agno-2.3.0 → agno-2.3.2}/agno/db/dynamo/dynamo.py +0 -0
  54. {agno-2.3.0 → agno-2.3.2}/agno/db/dynamo/schemas.py +0 -0
  55. {agno-2.3.0 → agno-2.3.2}/agno/db/dynamo/utils.py +0 -0
  56. {agno-2.3.0 → agno-2.3.2}/agno/db/firestore/__init__.py +0 -0
  57. {agno-2.3.0 → agno-2.3.2}/agno/db/firestore/firestore.py +0 -0
  58. {agno-2.3.0 → agno-2.3.2}/agno/db/firestore/schemas.py +0 -0
  59. {agno-2.3.0 → agno-2.3.2}/agno/db/firestore/utils.py +0 -0
  60. {agno-2.3.0 → agno-2.3.2}/agno/db/gcs_json/__init__.py +0 -0
  61. {agno-2.3.0 → agno-2.3.2}/agno/db/gcs_json/gcs_json_db.py +0 -0
  62. {agno-2.3.0 → agno-2.3.2}/agno/db/gcs_json/utils.py +0 -0
  63. {agno-2.3.0 → agno-2.3.2}/agno/db/in_memory/__init__.py +0 -0
  64. {agno-2.3.0 → agno-2.3.2}/agno/db/in_memory/in_memory_db.py +0 -0
  65. {agno-2.3.0 → agno-2.3.2}/agno/db/in_memory/utils.py +0 -0
  66. {agno-2.3.0 → agno-2.3.2}/agno/db/json/__init__.py +0 -0
  67. {agno-2.3.0 → agno-2.3.2}/agno/db/json/json_db.py +0 -0
  68. {agno-2.3.0 → agno-2.3.2}/agno/db/json/utils.py +0 -0
  69. {agno-2.3.0 → agno-2.3.2}/agno/db/migrations/__init__.py +0 -0
  70. {agno-2.3.0 → agno-2.3.2}/agno/db/migrations/manager.py +0 -0
  71. {agno-2.3.0 → agno-2.3.2}/agno/db/migrations/v1_to_v2.py +0 -0
  72. {agno-2.3.0 → agno-2.3.2}/agno/db/migrations/versions/__init__.py +0 -0
  73. {agno-2.3.0 → agno-2.3.2}/agno/db/migrations/versions/v2_3_0.py +0 -0
  74. {agno-2.3.0 → agno-2.3.2}/agno/db/mongo/__init__.py +0 -0
  75. {agno-2.3.0 → agno-2.3.2}/agno/db/mongo/async_mongo.py +0 -0
  76. {agno-2.3.0 → agno-2.3.2}/agno/db/mongo/mongo.py +0 -0
  77. {agno-2.3.0 → agno-2.3.2}/agno/db/mongo/schemas.py +0 -0
  78. {agno-2.3.0 → agno-2.3.2}/agno/db/mongo/utils.py +0 -0
  79. {agno-2.3.0 → agno-2.3.2}/agno/db/mysql/__init__.py +0 -0
  80. {agno-2.3.0 → agno-2.3.2}/agno/db/mysql/mysql.py +0 -0
  81. {agno-2.3.0 → agno-2.3.2}/agno/db/mysql/schemas.py +0 -0
  82. {agno-2.3.0 → agno-2.3.2}/agno/db/mysql/utils.py +0 -0
  83. {agno-2.3.0 → agno-2.3.2}/agno/db/postgres/__init__.py +0 -0
  84. {agno-2.3.0 → agno-2.3.2}/agno/db/postgres/async_postgres.py +0 -0
  85. {agno-2.3.0 → agno-2.3.2}/agno/db/postgres/postgres.py +0 -0
  86. {agno-2.3.0 → agno-2.3.2}/agno/db/postgres/schemas.py +0 -0
  87. {agno-2.3.0 → agno-2.3.2}/agno/db/postgres/utils.py +0 -0
  88. {agno-2.3.0 → agno-2.3.2}/agno/db/redis/__init__.py +0 -0
  89. {agno-2.3.0 → agno-2.3.2}/agno/db/redis/redis.py +0 -0
  90. {agno-2.3.0 → agno-2.3.2}/agno/db/redis/schemas.py +0 -0
  91. {agno-2.3.0 → agno-2.3.2}/agno/db/redis/utils.py +0 -0
  92. {agno-2.3.0 → agno-2.3.2}/agno/db/schemas/__init__.py +0 -0
  93. {agno-2.3.0 → agno-2.3.2}/agno/db/schemas/culture.py +0 -0
  94. {agno-2.3.0 → agno-2.3.2}/agno/db/schemas/evals.py +0 -0
  95. {agno-2.3.0 → agno-2.3.2}/agno/db/schemas/knowledge.py +0 -0
  96. {agno-2.3.0 → agno-2.3.2}/agno/db/schemas/metrics.py +0 -0
  97. {agno-2.3.0 → agno-2.3.2}/agno/db/singlestore/__init__.py +0 -0
  98. {agno-2.3.0 → agno-2.3.2}/agno/db/singlestore/schemas.py +0 -0
  99. {agno-2.3.0 → agno-2.3.2}/agno/db/singlestore/singlestore.py +0 -0
  100. {agno-2.3.0 → agno-2.3.2}/agno/db/singlestore/utils.py +0 -0
  101. {agno-2.3.0 → agno-2.3.2}/agno/db/sqlite/__init__.py +0 -0
  102. {agno-2.3.0 → agno-2.3.2}/agno/db/sqlite/schemas.py +0 -0
  103. {agno-2.3.0 → agno-2.3.2}/agno/db/sqlite/utils.py +0 -0
  104. {agno-2.3.0 → agno-2.3.2}/agno/db/surrealdb/__init__.py +0 -0
  105. {agno-2.3.0 → agno-2.3.2}/agno/db/surrealdb/metrics.py +0 -0
  106. {agno-2.3.0 → agno-2.3.2}/agno/db/surrealdb/models.py +0 -0
  107. {agno-2.3.0 → agno-2.3.2}/agno/db/surrealdb/queries.py +0 -0
  108. {agno-2.3.0 → agno-2.3.2}/agno/db/surrealdb/surrealdb.py +0 -0
  109. {agno-2.3.0 → agno-2.3.2}/agno/db/surrealdb/utils.py +0 -0
  110. {agno-2.3.0 → agno-2.3.2}/agno/db/utils.py +0 -0
  111. {agno-2.3.0 → agno-2.3.2}/agno/debug.py +0 -0
  112. {agno-2.3.0 → agno-2.3.2}/agno/eval/__init__.py +0 -0
  113. {agno-2.3.0 → agno-2.3.2}/agno/eval/accuracy.py +0 -0
  114. {agno-2.3.0 → agno-2.3.2}/agno/eval/performance.py +0 -0
  115. {agno-2.3.0 → agno-2.3.2}/agno/eval/reliability.py +0 -0
  116. {agno-2.3.0 → agno-2.3.2}/agno/eval/utils.py +0 -0
  117. {agno-2.3.0 → agno-2.3.2}/agno/exceptions.py +0 -0
  118. {agno-2.3.0 → agno-2.3.2}/agno/filters.py +0 -0
  119. {agno-2.3.0 → agno-2.3.2}/agno/guardrails/__init__.py +0 -0
  120. {agno-2.3.0 → agno-2.3.2}/agno/guardrails/base.py +0 -0
  121. {agno-2.3.0 → agno-2.3.2}/agno/guardrails/openai.py +0 -0
  122. {agno-2.3.0 → agno-2.3.2}/agno/guardrails/pii.py +0 -0
  123. {agno-2.3.0 → agno-2.3.2}/agno/guardrails/prompt_injection.py +0 -0
  124. {agno-2.3.0 → agno-2.3.2}/agno/integrations/__init__.py +0 -0
  125. {agno-2.3.0 → agno-2.3.2}/agno/integrations/discord/__init__.py +0 -0
  126. {agno-2.3.0 → agno-2.3.2}/agno/integrations/discord/client.py +0 -0
  127. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/__init__.py +0 -0
  128. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/__init__.py +0 -0
  129. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/agentic.py +0 -0
  130. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/document.py +0 -0
  131. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/fixed.py +0 -0
  132. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/markdown.py +0 -0
  133. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/recursive.py +0 -0
  134. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/row.py +0 -0
  135. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/semantic.py +0 -0
  136. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/chunking/strategy.py +0 -0
  137. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/content.py +0 -0
  138. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/document/__init__.py +0 -0
  139. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/document/base.py +0 -0
  140. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/__init__.py +0 -0
  141. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/aws_bedrock.py +0 -0
  142. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/azure_openai.py +0 -0
  143. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/base.py +0 -0
  144. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/cohere.py +0 -0
  145. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/fastembed.py +0 -0
  146. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/fireworks.py +0 -0
  147. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/google.py +0 -0
  148. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/huggingface.py +0 -0
  149. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/jina.py +0 -0
  150. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/langdb.py +0 -0
  151. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/mistral.py +0 -0
  152. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/nebius.py +0 -0
  153. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/ollama.py +0 -0
  154. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/openai.py +0 -0
  155. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/sentence_transformer.py +0 -0
  156. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/together.py +0 -0
  157. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/vllm.py +0 -0
  158. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/embedder/voyageai.py +0 -0
  159. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/knowledge.py +0 -0
  160. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/__init__.py +0 -0
  161. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/arxiv_reader.py +0 -0
  162. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/base.py +0 -0
  163. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/csv_reader.py +0 -0
  164. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/docx_reader.py +0 -0
  165. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/field_labeled_csv_reader.py +0 -0
  166. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/firecrawl_reader.py +0 -0
  167. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/json_reader.py +0 -0
  168. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/markdown_reader.py +0 -0
  169. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/pdf_reader.py +0 -0
  170. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/pptx_reader.py +0 -0
  171. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/reader_factory.py +0 -0
  172. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/s3_reader.py +0 -0
  173. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/tavily_reader.py +0 -0
  174. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/text_reader.py +0 -0
  175. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/web_search_reader.py +0 -0
  176. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/website_reader.py +0 -0
  177. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/wikipedia_reader.py +0 -0
  178. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reader/youtube_reader.py +0 -0
  179. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/remote_content/__init__.py +0 -0
  180. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/remote_content/remote_content.py +0 -0
  181. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reranker/__init__.py +0 -0
  182. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reranker/base.py +0 -0
  183. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reranker/cohere.py +0 -0
  184. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reranker/infinity.py +0 -0
  185. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/reranker/sentence_transformer.py +0 -0
  186. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/types.py +0 -0
  187. {agno-2.3.0 → agno-2.3.2}/agno/knowledge/utils.py +0 -0
  188. {agno-2.3.0 → agno-2.3.2}/agno/media.py +0 -0
  189. {agno-2.3.0 → agno-2.3.2}/agno/memory/__init__.py +0 -0
  190. {agno-2.3.0 → agno-2.3.2}/agno/models/__init__.py +0 -0
  191. {agno-2.3.0 → agno-2.3.2}/agno/models/aimlapi/__init__.py +0 -0
  192. {agno-2.3.0 → agno-2.3.2}/agno/models/aimlapi/aimlapi.py +0 -0
  193. {agno-2.3.0 → agno-2.3.2}/agno/models/anthropic/__init__.py +0 -0
  194. {agno-2.3.0 → agno-2.3.2}/agno/models/aws/__init__.py +0 -0
  195. {agno-2.3.0 → agno-2.3.2}/agno/models/aws/bedrock.py +0 -0
  196. {agno-2.3.0 → agno-2.3.2}/agno/models/aws/claude.py +0 -0
  197. {agno-2.3.0 → agno-2.3.2}/agno/models/azure/__init__.py +0 -0
  198. {agno-2.3.0 → agno-2.3.2}/agno/models/azure/ai_foundry.py +0 -0
  199. {agno-2.3.0 → agno-2.3.2}/agno/models/azure/openai_chat.py +0 -0
  200. {agno-2.3.0 → agno-2.3.2}/agno/models/base.py +0 -0
  201. {agno-2.3.0 → agno-2.3.2}/agno/models/cerebras/__init__.py +0 -0
  202. {agno-2.3.0 → agno-2.3.2}/agno/models/cerebras/cerebras.py +0 -0
  203. {agno-2.3.0 → agno-2.3.2}/agno/models/cerebras/cerebras_openai.py +0 -0
  204. {agno-2.3.0 → agno-2.3.2}/agno/models/cohere/__init__.py +0 -0
  205. {agno-2.3.0 → agno-2.3.2}/agno/models/cohere/chat.py +0 -0
  206. {agno-2.3.0 → agno-2.3.2}/agno/models/cometapi/__init__.py +0 -0
  207. {agno-2.3.0 → agno-2.3.2}/agno/models/cometapi/cometapi.py +0 -0
  208. {agno-2.3.0 → agno-2.3.2}/agno/models/dashscope/__init__.py +0 -0
  209. {agno-2.3.0 → agno-2.3.2}/agno/models/dashscope/dashscope.py +0 -0
  210. {agno-2.3.0 → agno-2.3.2}/agno/models/deepinfra/__init__.py +0 -0
  211. {agno-2.3.0 → agno-2.3.2}/agno/models/deepinfra/deepinfra.py +0 -0
  212. {agno-2.3.0 → agno-2.3.2}/agno/models/deepseek/__init__.py +0 -0
  213. {agno-2.3.0 → agno-2.3.2}/agno/models/deepseek/deepseek.py +0 -0
  214. {agno-2.3.0 → agno-2.3.2}/agno/models/defaults.py +0 -0
  215. {agno-2.3.0 → agno-2.3.2}/agno/models/fireworks/__init__.py +0 -0
  216. {agno-2.3.0 → agno-2.3.2}/agno/models/fireworks/fireworks.py +0 -0
  217. {agno-2.3.0 → agno-2.3.2}/agno/models/google/__init__.py +0 -0
  218. {agno-2.3.0 → agno-2.3.2}/agno/models/google/gemini.py +0 -0
  219. {agno-2.3.0 → agno-2.3.2}/agno/models/groq/__init__.py +0 -0
  220. {agno-2.3.0 → agno-2.3.2}/agno/models/groq/groq.py +0 -0
  221. {agno-2.3.0 → agno-2.3.2}/agno/models/huggingface/__init__.py +0 -0
  222. {agno-2.3.0 → agno-2.3.2}/agno/models/huggingface/huggingface.py +0 -0
  223. {agno-2.3.0 → agno-2.3.2}/agno/models/ibm/__init__.py +0 -0
  224. {agno-2.3.0 → agno-2.3.2}/agno/models/ibm/watsonx.py +0 -0
  225. {agno-2.3.0 → agno-2.3.2}/agno/models/internlm/__init__.py +0 -0
  226. {agno-2.3.0 → agno-2.3.2}/agno/models/internlm/internlm.py +0 -0
  227. {agno-2.3.0 → agno-2.3.2}/agno/models/langdb/__init__.py +0 -0
  228. {agno-2.3.0 → agno-2.3.2}/agno/models/langdb/langdb.py +0 -0
  229. {agno-2.3.0 → agno-2.3.2}/agno/models/litellm/__init__.py +0 -0
  230. {agno-2.3.0 → agno-2.3.2}/agno/models/litellm/chat.py +0 -0
  231. {agno-2.3.0 → agno-2.3.2}/agno/models/litellm/litellm_openai.py +0 -0
  232. {agno-2.3.0 → agno-2.3.2}/agno/models/llama_cpp/__init__.py +0 -0
  233. {agno-2.3.0 → agno-2.3.2}/agno/models/llama_cpp/llama_cpp.py +0 -0
  234. {agno-2.3.0 → agno-2.3.2}/agno/models/lmstudio/__init__.py +0 -0
  235. {agno-2.3.0 → agno-2.3.2}/agno/models/lmstudio/lmstudio.py +0 -0
  236. {agno-2.3.0 → agno-2.3.2}/agno/models/message.py +0 -0
  237. {agno-2.3.0 → agno-2.3.2}/agno/models/meta/__init__.py +0 -0
  238. {agno-2.3.0 → agno-2.3.2}/agno/models/meta/llama.py +0 -0
  239. {agno-2.3.0 → agno-2.3.2}/agno/models/meta/llama_openai.py +0 -0
  240. {agno-2.3.0 → agno-2.3.2}/agno/models/metrics.py +0 -0
  241. {agno-2.3.0 → agno-2.3.2}/agno/models/mistral/__init__.py +0 -0
  242. {agno-2.3.0 → agno-2.3.2}/agno/models/mistral/mistral.py +0 -0
  243. {agno-2.3.0 → agno-2.3.2}/agno/models/nebius/__init__.py +0 -0
  244. {agno-2.3.0 → agno-2.3.2}/agno/models/nebius/nebius.py +0 -0
  245. {agno-2.3.0 → agno-2.3.2}/agno/models/nexus/__init__.py +0 -0
  246. {agno-2.3.0 → agno-2.3.2}/agno/models/nexus/nexus.py +0 -0
  247. {agno-2.3.0 → agno-2.3.2}/agno/models/nvidia/__init__.py +0 -0
  248. {agno-2.3.0 → agno-2.3.2}/agno/models/nvidia/nvidia.py +0 -0
  249. {agno-2.3.0 → agno-2.3.2}/agno/models/ollama/__init__.py +0 -0
  250. {agno-2.3.0 → agno-2.3.2}/agno/models/ollama/chat.py +0 -0
  251. {agno-2.3.0 → agno-2.3.2}/agno/models/openai/__init__.py +0 -0
  252. {agno-2.3.0 → agno-2.3.2}/agno/models/openai/chat.py +0 -0
  253. {agno-2.3.0 → agno-2.3.2}/agno/models/openai/like.py +0 -0
  254. {agno-2.3.0 → agno-2.3.2}/agno/models/openai/responses.py +0 -0
  255. {agno-2.3.0 → agno-2.3.2}/agno/models/openrouter/__init__.py +0 -0
  256. {agno-2.3.0 → agno-2.3.2}/agno/models/openrouter/openrouter.py +0 -0
  257. {agno-2.3.0 → agno-2.3.2}/agno/models/perplexity/__init__.py +0 -0
  258. {agno-2.3.0 → agno-2.3.2}/agno/models/perplexity/perplexity.py +0 -0
  259. {agno-2.3.0 → agno-2.3.2}/agno/models/portkey/__init__.py +0 -0
  260. {agno-2.3.0 → agno-2.3.2}/agno/models/portkey/portkey.py +0 -0
  261. {agno-2.3.0 → agno-2.3.2}/agno/models/requesty/__init__.py +0 -0
  262. {agno-2.3.0 → agno-2.3.2}/agno/models/requesty/requesty.py +0 -0
  263. {agno-2.3.0 → agno-2.3.2}/agno/models/response.py +0 -0
  264. {agno-2.3.0 → agno-2.3.2}/agno/models/sambanova/__init__.py +0 -0
  265. {agno-2.3.0 → agno-2.3.2}/agno/models/sambanova/sambanova.py +0 -0
  266. {agno-2.3.0 → agno-2.3.2}/agno/models/siliconflow/__init__.py +0 -0
  267. {agno-2.3.0 → agno-2.3.2}/agno/models/siliconflow/siliconflow.py +0 -0
  268. {agno-2.3.0 → agno-2.3.2}/agno/models/together/__init__.py +0 -0
  269. {agno-2.3.0 → agno-2.3.2}/agno/models/together/together.py +0 -0
  270. {agno-2.3.0 → agno-2.3.2}/agno/models/utils.py +0 -0
  271. {agno-2.3.0 → agno-2.3.2}/agno/models/vercel/__init__.py +0 -0
  272. {agno-2.3.0 → agno-2.3.2}/agno/models/vercel/v0.py +0 -0
  273. {agno-2.3.0 → agno-2.3.2}/agno/models/vertexai/__init__.py +0 -0
  274. {agno-2.3.0 → agno-2.3.2}/agno/models/vertexai/claude.py +0 -0
  275. {agno-2.3.0 → agno-2.3.2}/agno/models/vllm/__init__.py +0 -0
  276. {agno-2.3.0 → agno-2.3.2}/agno/models/vllm/vllm.py +0 -0
  277. {agno-2.3.0 → agno-2.3.2}/agno/models/xai/__init__.py +0 -0
  278. {agno-2.3.0 → agno-2.3.2}/agno/models/xai/xai.py +0 -0
  279. {agno-2.3.0 → agno-2.3.2}/agno/os/__init__.py +0 -0
  280. {agno-2.3.0 → agno-2.3.2}/agno/os/auth.py +0 -0
  281. {agno-2.3.0 → agno-2.3.2}/agno/os/config.py +0 -0
  282. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/__init__.py +0 -0
  283. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/a2a/__init__.py +0 -0
  284. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/a2a/a2a.py +0 -0
  285. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/a2a/router.py +0 -0
  286. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/a2a/utils.py +0 -0
  287. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/agui/__init__.py +0 -0
  288. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/agui/agui.py +0 -0
  289. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/agui/router.py +0 -0
  290. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/agui/utils.py +0 -0
  291. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/base.py +0 -0
  292. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/slack/__init__.py +0 -0
  293. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/slack/router.py +0 -0
  294. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/slack/security.py +0 -0
  295. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/slack/slack.py +0 -0
  296. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/whatsapp/__init__.py +0 -0
  297. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/whatsapp/router.py +0 -0
  298. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/whatsapp/security.py +0 -0
  299. {agno-2.3.0 → agno-2.3.2}/agno/os/interfaces/whatsapp/whatsapp.py +0 -0
  300. {agno-2.3.0 → agno-2.3.2}/agno/os/mcp.py +0 -0
  301. {agno-2.3.0 → agno-2.3.2}/agno/os/middleware/__init__.py +0 -0
  302. {agno-2.3.0 → agno-2.3.2}/agno/os/middleware/jwt.py +0 -0
  303. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/__init__.py +0 -0
  304. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/evals/__init__.py +0 -0
  305. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/evals/evals.py +0 -0
  306. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/evals/schemas.py +0 -0
  307. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/evals/utils.py +0 -0
  308. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/health.py +0 -0
  309. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/home.py +0 -0
  310. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/knowledge/__init__.py +0 -0
  311. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/knowledge/knowledge.py +0 -0
  312. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/knowledge/schemas.py +0 -0
  313. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/memory/__init__.py +0 -0
  314. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/memory/schemas.py +0 -0
  315. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/metrics/__init__.py +0 -0
  316. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/metrics/metrics.py +0 -0
  317. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/metrics/schemas.py +0 -0
  318. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/session/__init__.py +0 -0
  319. {agno-2.3.0 → agno-2.3.2}/agno/os/routers/session/session.py +0 -0
  320. {agno-2.3.0 → agno-2.3.2}/agno/os/schema.py +0 -0
  321. {agno-2.3.0 → agno-2.3.2}/agno/os/settings.py +0 -0
  322. {agno-2.3.0 → agno-2.3.2}/agno/os/utils.py +0 -0
  323. {agno-2.3.0 → agno-2.3.2}/agno/py.typed +0 -0
  324. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/__init__.py +0 -0
  325. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/anthropic.py +0 -0
  326. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/azure_ai_foundry.py +0 -0
  327. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/deepseek.py +0 -0
  328. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/default.py +0 -0
  329. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/gemini.py +0 -0
  330. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/groq.py +0 -0
  331. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/helpers.py +0 -0
  332. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/ollama.py +0 -0
  333. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/openai.py +0 -0
  334. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/step.py +0 -0
  335. {agno-2.3.0 → agno-2.3.2}/agno/reasoning/vertexai.py +0 -0
  336. {agno-2.3.0 → agno-2.3.2}/agno/run/__init__.py +0 -0
  337. {agno-2.3.0 → agno-2.3.2}/agno/run/agent.py +0 -0
  338. {agno-2.3.0 → agno-2.3.2}/agno/run/base.py +0 -0
  339. {agno-2.3.0 → agno-2.3.2}/agno/run/cancel.py +0 -0
  340. {agno-2.3.0 → agno-2.3.2}/agno/run/messages.py +0 -0
  341. {agno-2.3.0 → agno-2.3.2}/agno/run/team.py +0 -0
  342. {agno-2.3.0 → agno-2.3.2}/agno/run/workflow.py +0 -0
  343. {agno-2.3.0 → agno-2.3.2}/agno/session/__init__.py +0 -0
  344. {agno-2.3.0 → agno-2.3.2}/agno/session/agent.py +0 -0
  345. {agno-2.3.0 → agno-2.3.2}/agno/session/summary.py +0 -0
  346. {agno-2.3.0 → agno-2.3.2}/agno/session/team.py +0 -0
  347. {agno-2.3.0 → agno-2.3.2}/agno/team/__init__.py +0 -0
  348. {agno-2.3.0 → agno-2.3.2}/agno/tools/__init__.py +0 -0
  349. {agno-2.3.0 → agno-2.3.2}/agno/tools/agentql.py +0 -0
  350. {agno-2.3.0 → agno-2.3.2}/agno/tools/airflow.py +0 -0
  351. {agno-2.3.0 → agno-2.3.2}/agno/tools/api.py +0 -0
  352. {agno-2.3.0 → agno-2.3.2}/agno/tools/apify.py +0 -0
  353. {agno-2.3.0 → agno-2.3.2}/agno/tools/arxiv.py +0 -0
  354. {agno-2.3.0 → agno-2.3.2}/agno/tools/aws_lambda.py +0 -0
  355. {agno-2.3.0 → agno-2.3.2}/agno/tools/aws_ses.py +0 -0
  356. {agno-2.3.0 → agno-2.3.2}/agno/tools/baidusearch.py +0 -0
  357. {agno-2.3.0 → agno-2.3.2}/agno/tools/bitbucket.py +0 -0
  358. {agno-2.3.0 → agno-2.3.2}/agno/tools/brandfetch.py +0 -0
  359. {agno-2.3.0 → agno-2.3.2}/agno/tools/bravesearch.py +0 -0
  360. {agno-2.3.0 → agno-2.3.2}/agno/tools/brightdata.py +0 -0
  361. {agno-2.3.0 → agno-2.3.2}/agno/tools/browserbase.py +0 -0
  362. {agno-2.3.0 → agno-2.3.2}/agno/tools/calcom.py +0 -0
  363. {agno-2.3.0 → agno-2.3.2}/agno/tools/calculator.py +0 -0
  364. {agno-2.3.0 → agno-2.3.2}/agno/tools/cartesia.py +0 -0
  365. {agno-2.3.0 → agno-2.3.2}/agno/tools/clickup.py +0 -0
  366. {agno-2.3.0 → agno-2.3.2}/agno/tools/confluence.py +0 -0
  367. {agno-2.3.0 → agno-2.3.2}/agno/tools/crawl4ai.py +0 -0
  368. {agno-2.3.0 → agno-2.3.2}/agno/tools/csv_toolkit.py +0 -0
  369. {agno-2.3.0 → agno-2.3.2}/agno/tools/dalle.py +0 -0
  370. {agno-2.3.0 → agno-2.3.2}/agno/tools/daytona.py +0 -0
  371. {agno-2.3.0 → agno-2.3.2}/agno/tools/decorator.py +0 -0
  372. {agno-2.3.0 → agno-2.3.2}/agno/tools/desi_vocal.py +0 -0
  373. {agno-2.3.0 → agno-2.3.2}/agno/tools/discord.py +0 -0
  374. {agno-2.3.0 → agno-2.3.2}/agno/tools/docker.py +0 -0
  375. {agno-2.3.0 → agno-2.3.2}/agno/tools/duckdb.py +0 -0
  376. {agno-2.3.0 → agno-2.3.2}/agno/tools/duckduckgo.py +0 -0
  377. {agno-2.3.0 → agno-2.3.2}/agno/tools/e2b.py +0 -0
  378. {agno-2.3.0 → agno-2.3.2}/agno/tools/eleven_labs.py +0 -0
  379. {agno-2.3.0 → agno-2.3.2}/agno/tools/email.py +0 -0
  380. {agno-2.3.0 → agno-2.3.2}/agno/tools/evm.py +0 -0
  381. {agno-2.3.0 → agno-2.3.2}/agno/tools/exa.py +0 -0
  382. {agno-2.3.0 → agno-2.3.2}/agno/tools/fal.py +0 -0
  383. {agno-2.3.0 → agno-2.3.2}/agno/tools/file.py +0 -0
  384. {agno-2.3.0 → agno-2.3.2}/agno/tools/file_generation.py +0 -0
  385. {agno-2.3.0 → agno-2.3.2}/agno/tools/financial_datasets.py +0 -0
  386. {agno-2.3.0 → agno-2.3.2}/agno/tools/firecrawl.py +0 -0
  387. {agno-2.3.0 → agno-2.3.2}/agno/tools/function.py +0 -0
  388. {agno-2.3.0 → agno-2.3.2}/agno/tools/giphy.py +0 -0
  389. {agno-2.3.0 → agno-2.3.2}/agno/tools/github.py +0 -0
  390. {agno-2.3.0 → agno-2.3.2}/agno/tools/gmail.py +0 -0
  391. {agno-2.3.0 → agno-2.3.2}/agno/tools/google_bigquery.py +0 -0
  392. {agno-2.3.0 → agno-2.3.2}/agno/tools/google_drive.py +0 -0
  393. {agno-2.3.0 → agno-2.3.2}/agno/tools/google_maps.py +0 -0
  394. {agno-2.3.0 → agno-2.3.2}/agno/tools/googlecalendar.py +0 -0
  395. {agno-2.3.0 → agno-2.3.2}/agno/tools/googlesheets.py +0 -0
  396. {agno-2.3.0 → agno-2.3.2}/agno/tools/hackernews.py +0 -0
  397. {agno-2.3.0 → agno-2.3.2}/agno/tools/jina.py +0 -0
  398. {agno-2.3.0 → agno-2.3.2}/agno/tools/jira.py +0 -0
  399. {agno-2.3.0 → agno-2.3.2}/agno/tools/knowledge.py +0 -0
  400. {agno-2.3.0 → agno-2.3.2}/agno/tools/linear.py +0 -0
  401. {agno-2.3.0 → agno-2.3.2}/agno/tools/linkup.py +0 -0
  402. {agno-2.3.0 → agno-2.3.2}/agno/tools/local_file_system.py +0 -0
  403. {agno-2.3.0 → agno-2.3.2}/agno/tools/lumalab.py +0 -0
  404. {agno-2.3.0 → agno-2.3.2}/agno/tools/mcp/__init__.py +0 -0
  405. {agno-2.3.0 → agno-2.3.2}/agno/tools/mcp/mcp.py +0 -0
  406. {agno-2.3.0 → agno-2.3.2}/agno/tools/mcp/multi_mcp.py +0 -0
  407. {agno-2.3.0 → agno-2.3.2}/agno/tools/mcp/params.py +0 -0
  408. {agno-2.3.0 → agno-2.3.2}/agno/tools/mcp_toolbox.py +0 -0
  409. {agno-2.3.0 → agno-2.3.2}/agno/tools/mem0.py +0 -0
  410. {agno-2.3.0 → agno-2.3.2}/agno/tools/memori.py +0 -0
  411. {agno-2.3.0 → agno-2.3.2}/agno/tools/memory.py +0 -0
  412. {agno-2.3.0 → agno-2.3.2}/agno/tools/mlx_transcribe.py +0 -0
  413. {agno-2.3.0 → agno-2.3.2}/agno/tools/models/__init__.py +0 -0
  414. {agno-2.3.0 → agno-2.3.2}/agno/tools/models/azure_openai.py +0 -0
  415. {agno-2.3.0 → agno-2.3.2}/agno/tools/models/gemini.py +0 -0
  416. {agno-2.3.0 → agno-2.3.2}/agno/tools/models/groq.py +0 -0
  417. {agno-2.3.0 → agno-2.3.2}/agno/tools/models/morph.py +0 -0
  418. {agno-2.3.0 → agno-2.3.2}/agno/tools/models/nebius.py +0 -0
  419. {agno-2.3.0 → agno-2.3.2}/agno/tools/models_labs.py +0 -0
  420. {agno-2.3.0 → agno-2.3.2}/agno/tools/moviepy_video.py +0 -0
  421. {agno-2.3.0 → agno-2.3.2}/agno/tools/neo4j.py +0 -0
  422. {agno-2.3.0 → agno-2.3.2}/agno/tools/newspaper.py +0 -0
  423. {agno-2.3.0 → agno-2.3.2}/agno/tools/newspaper4k.py +0 -0
  424. {agno-2.3.0 → agno-2.3.2}/agno/tools/notion.py +0 -0
  425. {agno-2.3.0 → agno-2.3.2}/agno/tools/openai.py +0 -0
  426. {agno-2.3.0 → agno-2.3.2}/agno/tools/openbb.py +0 -0
  427. {agno-2.3.0 → agno-2.3.2}/agno/tools/opencv.py +0 -0
  428. {agno-2.3.0 → agno-2.3.2}/agno/tools/openweather.py +0 -0
  429. {agno-2.3.0 → agno-2.3.2}/agno/tools/oxylabs.py +0 -0
  430. {agno-2.3.0 → agno-2.3.2}/agno/tools/pandas.py +0 -0
  431. {agno-2.3.0 → agno-2.3.2}/agno/tools/parallel.py +0 -0
  432. {agno-2.3.0 → agno-2.3.2}/agno/tools/postgres.py +0 -0
  433. {agno-2.3.0 → agno-2.3.2}/agno/tools/pubmed.py +0 -0
  434. {agno-2.3.0 → agno-2.3.2}/agno/tools/python.py +0 -0
  435. {agno-2.3.0 → agno-2.3.2}/agno/tools/reasoning.py +0 -0
  436. {agno-2.3.0 → agno-2.3.2}/agno/tools/reddit.py +0 -0
  437. {agno-2.3.0 → agno-2.3.2}/agno/tools/replicate.py +0 -0
  438. {agno-2.3.0 → agno-2.3.2}/agno/tools/resend.py +0 -0
  439. {agno-2.3.0 → agno-2.3.2}/agno/tools/scrapegraph.py +0 -0
  440. {agno-2.3.0 → agno-2.3.2}/agno/tools/searxng.py +0 -0
  441. {agno-2.3.0 → agno-2.3.2}/agno/tools/serpapi.py +0 -0
  442. {agno-2.3.0 → agno-2.3.2}/agno/tools/serper.py +0 -0
  443. {agno-2.3.0 → agno-2.3.2}/agno/tools/shell.py +0 -0
  444. {agno-2.3.0 → agno-2.3.2}/agno/tools/slack.py +0 -0
  445. {agno-2.3.0 → agno-2.3.2}/agno/tools/sleep.py +0 -0
  446. {agno-2.3.0 → agno-2.3.2}/agno/tools/spider.py +0 -0
  447. {agno-2.3.0 → agno-2.3.2}/agno/tools/sql.py +0 -0
  448. {agno-2.3.0 → agno-2.3.2}/agno/tools/streamlit/__init__.py +0 -0
  449. {agno-2.3.0 → agno-2.3.2}/agno/tools/streamlit/components.py +0 -0
  450. {agno-2.3.0 → agno-2.3.2}/agno/tools/tavily.py +0 -0
  451. {agno-2.3.0 → agno-2.3.2}/agno/tools/telegram.py +0 -0
  452. {agno-2.3.0 → agno-2.3.2}/agno/tools/todoist.py +0 -0
  453. {agno-2.3.0 → agno-2.3.2}/agno/tools/tool_registry.py +0 -0
  454. {agno-2.3.0 → agno-2.3.2}/agno/tools/toolkit.py +0 -0
  455. {agno-2.3.0 → agno-2.3.2}/agno/tools/trafilatura.py +0 -0
  456. {agno-2.3.0 → agno-2.3.2}/agno/tools/trello.py +0 -0
  457. {agno-2.3.0 → agno-2.3.2}/agno/tools/twilio.py +0 -0
  458. {agno-2.3.0 → agno-2.3.2}/agno/tools/user_control_flow.py +0 -0
  459. {agno-2.3.0 → agno-2.3.2}/agno/tools/valyu.py +0 -0
  460. {agno-2.3.0 → agno-2.3.2}/agno/tools/visualization.py +0 -0
  461. {agno-2.3.0 → agno-2.3.2}/agno/tools/webbrowser.py +0 -0
  462. {agno-2.3.0 → agno-2.3.2}/agno/tools/webex.py +0 -0
  463. {agno-2.3.0 → agno-2.3.2}/agno/tools/website.py +0 -0
  464. {agno-2.3.0 → agno-2.3.2}/agno/tools/webtools.py +0 -0
  465. {agno-2.3.0 → agno-2.3.2}/agno/tools/whatsapp.py +0 -0
  466. {agno-2.3.0 → agno-2.3.2}/agno/tools/wikipedia.py +0 -0
  467. {agno-2.3.0 → agno-2.3.2}/agno/tools/workflow.py +0 -0
  468. {agno-2.3.0 → agno-2.3.2}/agno/tools/x.py +0 -0
  469. {agno-2.3.0 → agno-2.3.2}/agno/tools/yfinance.py +0 -0
  470. {agno-2.3.0 → agno-2.3.2}/agno/tools/youtube.py +0 -0
  471. {agno-2.3.0 → agno-2.3.2}/agno/tools/zendesk.py +0 -0
  472. {agno-2.3.0 → agno-2.3.2}/agno/tools/zep.py +0 -0
  473. {agno-2.3.0 → agno-2.3.2}/agno/tools/zoom.py +0 -0
  474. {agno-2.3.0 → agno-2.3.2}/agno/utils/__init__.py +0 -0
  475. {agno-2.3.0 → agno-2.3.2}/agno/utils/agent.py +0 -0
  476. {agno-2.3.0 → agno-2.3.2}/agno/utils/audio.py +0 -0
  477. {agno-2.3.0 → agno-2.3.2}/agno/utils/certs.py +0 -0
  478. {agno-2.3.0 → agno-2.3.2}/agno/utils/code_execution.py +0 -0
  479. {agno-2.3.0 → agno-2.3.2}/agno/utils/common.py +0 -0
  480. {agno-2.3.0 → agno-2.3.2}/agno/utils/enum.py +0 -0
  481. {agno-2.3.0 → agno-2.3.2}/agno/utils/env.py +0 -0
  482. {agno-2.3.0 → agno-2.3.2}/agno/utils/events.py +0 -0
  483. {agno-2.3.0 → agno-2.3.2}/agno/utils/format_str.py +0 -0
  484. {agno-2.3.0 → agno-2.3.2}/agno/utils/functions.py +0 -0
  485. {agno-2.3.0 → agno-2.3.2}/agno/utils/gemini.py +0 -0
  486. {agno-2.3.0 → agno-2.3.2}/agno/utils/hooks.py +0 -0
  487. {agno-2.3.0 → agno-2.3.2}/agno/utils/http.py +0 -0
  488. {agno-2.3.0 → agno-2.3.2}/agno/utils/json_schema.py +0 -0
  489. {agno-2.3.0 → agno-2.3.2}/agno/utils/knowledge.py +0 -0
  490. {agno-2.3.0 → agno-2.3.2}/agno/utils/location.py +0 -0
  491. {agno-2.3.0 → agno-2.3.2}/agno/utils/log.py +0 -0
  492. {agno-2.3.0 → agno-2.3.2}/agno/utils/mcp.py +0 -0
  493. {agno-2.3.0 → agno-2.3.2}/agno/utils/media.py +0 -0
  494. {agno-2.3.0 → agno-2.3.2}/agno/utils/merge_dict.py +0 -0
  495. {agno-2.3.0 → agno-2.3.2}/agno/utils/message.py +0 -0
  496. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/__init__.py +0 -0
  497. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/ai_foundry.py +0 -0
  498. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/cohere.py +0 -0
  499. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/llama.py +0 -0
  500. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/mistral.py +0 -0
  501. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/openai_responses.py +0 -0
  502. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/schema_utils.py +0 -0
  503. {agno-2.3.0 → agno-2.3.2}/agno/utils/models/watsonx.py +0 -0
  504. {agno-2.3.0 → agno-2.3.2}/agno/utils/openai.py +0 -0
  505. {agno-2.3.0 → agno-2.3.2}/agno/utils/pickle.py +0 -0
  506. {agno-2.3.0 → agno-2.3.2}/agno/utils/pprint.py +0 -0
  507. {agno-2.3.0 → agno-2.3.2}/agno/utils/print_response/__init__.py +0 -0
  508. {agno-2.3.0 → agno-2.3.2}/agno/utils/print_response/agent.py +0 -0
  509. {agno-2.3.0 → agno-2.3.2}/agno/utils/print_response/team.py +0 -0
  510. {agno-2.3.0 → agno-2.3.2}/agno/utils/print_response/workflow.py +0 -0
  511. {agno-2.3.0 → agno-2.3.2}/agno/utils/prompts.py +0 -0
  512. {agno-2.3.0 → agno-2.3.2}/agno/utils/reasoning.py +0 -0
  513. {agno-2.3.0 → agno-2.3.2}/agno/utils/response.py +0 -0
  514. {agno-2.3.0 → agno-2.3.2}/agno/utils/response_iterator.py +0 -0
  515. {agno-2.3.0 → agno-2.3.2}/agno/utils/safe_formatter.py +0 -0
  516. {agno-2.3.0 → agno-2.3.2}/agno/utils/serialize.py +0 -0
  517. {agno-2.3.0 → agno-2.3.2}/agno/utils/shell.py +0 -0
  518. {agno-2.3.0 → agno-2.3.2}/agno/utils/streamlit.py +0 -0
  519. {agno-2.3.0 → agno-2.3.2}/agno/utils/string.py +0 -0
  520. {agno-2.3.0 → agno-2.3.2}/agno/utils/team.py +0 -0
  521. {agno-2.3.0 → agno-2.3.2}/agno/utils/timer.py +0 -0
  522. {agno-2.3.0 → agno-2.3.2}/agno/utils/tools.py +0 -0
  523. {agno-2.3.0 → agno-2.3.2}/agno/utils/web.py +0 -0
  524. {agno-2.3.0 → agno-2.3.2}/agno/utils/whatsapp.py +0 -0
  525. {agno-2.3.0 → agno-2.3.2}/agno/utils/yaml_io.py +0 -0
  526. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/__init__.py +0 -0
  527. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/base.py +0 -0
  528. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/cassandra/__init__.py +0 -0
  529. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/cassandra/cassandra.py +0 -0
  530. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
  531. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/cassandra/index.py +0 -0
  532. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/chroma/__init__.py +0 -0
  533. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/chroma/chromadb.py +0 -0
  534. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/clickhouse/__init__.py +0 -0
  535. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
  536. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/clickhouse/index.py +0 -0
  537. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/couchbase/__init__.py +0 -0
  538. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/couchbase/couchbase.py +0 -0
  539. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/distance.py +0 -0
  540. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/lancedb/__init__.py +0 -0
  541. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/lancedb/lance_db.py +0 -0
  542. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/langchaindb/__init__.py +0 -0
  543. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/langchaindb/langchaindb.py +0 -0
  544. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/lightrag/__init__.py +0 -0
  545. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/lightrag/lightrag.py +0 -0
  546. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/llamaindex/__init__.py +0 -0
  547. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/llamaindex/llamaindexdb.py +0 -0
  548. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/milvus/__init__.py +0 -0
  549. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/milvus/milvus.py +0 -0
  550. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/mongodb/__init__.py +0 -0
  551. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/mongodb/mongodb.py +0 -0
  552. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/pgvector/__init__.py +0 -0
  553. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/pgvector/index.py +0 -0
  554. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/pgvector/pgvector.py +0 -0
  555. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/pineconedb/__init__.py +0 -0
  556. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/pineconedb/pineconedb.py +0 -0
  557. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/qdrant/__init__.py +0 -0
  558. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/qdrant/qdrant.py +0 -0
  559. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/redis/__init__.py +0 -0
  560. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/redis/redisdb.py +0 -0
  561. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/search.py +0 -0
  562. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/singlestore/__init__.py +0 -0
  563. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/singlestore/index.py +0 -0
  564. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/singlestore/singlestore.py +0 -0
  565. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/surrealdb/__init__.py +0 -0
  566. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/surrealdb/surrealdb.py +0 -0
  567. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/upstashdb/__init__.py +0 -0
  568. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/upstashdb/upstashdb.py +0 -0
  569. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/weaviate/__init__.py +0 -0
  570. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/weaviate/index.py +0 -0
  571. {agno-2.3.0 → agno-2.3.2}/agno/vectordb/weaviate/weaviate.py +0 -0
  572. {agno-2.3.0 → agno-2.3.2}/agno/workflow/__init__.py +0 -0
  573. {agno-2.3.0 → agno-2.3.2}/agno/workflow/agent.py +0 -0
  574. {agno-2.3.0 → agno-2.3.2}/agno/workflow/condition.py +0 -0
  575. {agno-2.3.0 → agno-2.3.2}/agno/workflow/loop.py +0 -0
  576. {agno-2.3.0 → agno-2.3.2}/agno/workflow/parallel.py +0 -0
  577. {agno-2.3.0 → agno-2.3.2}/agno/workflow/router.py +0 -0
  578. {agno-2.3.0 → agno-2.3.2}/agno/workflow/step.py +0 -0
  579. {agno-2.3.0 → agno-2.3.2}/agno/workflow/steps.py +0 -0
  580. {agno-2.3.0 → agno-2.3.2}/agno/workflow/types.py +0 -0
  581. {agno-2.3.0 → agno-2.3.2}/agno.egg-info/dependency_links.txt +0 -0
  582. {agno-2.3.0 → agno-2.3.2}/agno.egg-info/requires.txt +0 -0
  583. {agno-2.3.0 → agno-2.3.2}/agno.egg-info/top_level.txt +0 -0
  584. {agno-2.3.0 → agno-2.3.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.3.0
3
+ Version: 2.3.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
@@ -1501,7 +1501,7 @@ class Agent:
1501
1501
  add_session_state_to_context: Optional[bool] = None,
1502
1502
  dependencies: Optional[Dict[str, Any]] = None,
1503
1503
  metadata: Optional[Dict[str, Any]] = None,
1504
- yield_run_response: bool = False, # To be deprecated: use yield_run_output instead
1504
+ yield_run_response: Optional[bool] = None, # To be deprecated: use yield_run_output instead
1505
1505
  yield_run_output: bool = False,
1506
1506
  debug_mode: Optional[bool] = None,
1507
1507
  **kwargs: Any,
@@ -2,6 +2,8 @@ from dataclasses import dataclass
2
2
  from datetime import datetime, timezone
3
3
  from typing import Any, Dict, List, Optional
4
4
 
5
+ from agno.utils.dttm import now_epoch_s
6
+
5
7
 
6
8
  @dataclass
7
9
  class UserMemory:
@@ -12,8 +14,8 @@ class UserMemory:
12
14
  topics: Optional[List[str]] = None
13
15
  user_id: Optional[str] = None
14
16
  input: Optional[str] = None
15
- created_at: Optional[datetime] = None
16
- updated_at: Optional[datetime] = None
17
+ created_at: Optional[int] = None
18
+ updated_at: Optional[int] = None
17
19
  feedback: Optional[str] = None
18
20
 
19
21
  agent_id: Optional[str] = None
@@ -22,15 +24,15 @@ class UserMemory:
22
24
  def __post_init__(self) -> None:
23
25
  """Automatically set created_at if not provided."""
24
26
  if self.created_at is None:
25
- self.created_at = datetime.now(timezone.utc)
27
+ self.created_at = now_epoch_s()
26
28
 
27
29
  def to_dict(self) -> Dict[str, Any]:
28
30
  _dict = {
29
31
  "memory_id": self.memory_id,
30
32
  "memory": self.memory,
31
33
  "topics": self.topics,
32
- "created_at": self.created_at.isoformat() if self.created_at else None,
33
- "updated_at": self.updated_at.isoformat() if self.updated_at else None,
34
+ "created_at": datetime.fromtimestamp(self.created_at).isoformat() if self.created_at else None,
35
+ "updated_at": datetime.fromtimestamp(self.updated_at).isoformat() if self.updated_at else None,
34
36
  "input": self.input,
35
37
  "user_id": self.user_id,
36
38
  "agent_id": self.agent_id,
@@ -28,7 +28,7 @@ from agno.utils.log import log_debug, log_error, log_info, log_warning
28
28
  from agno.utils.string import generate_id
29
29
 
30
30
  try:
31
- from sqlalchemy import Column, MetaData, Table, and_, func, select, text
31
+ from sqlalchemy import Column, MetaData, String, Table, func, select, text
32
32
  from sqlalchemy.dialects import sqlite
33
33
  from sqlalchemy.ext.asyncio import AsyncEngine, async_sessionmaker, create_async_engine
34
34
  from sqlalchemy.schema import Index, UniqueConstraint
@@ -1182,8 +1182,8 @@ class AsyncSqliteDb(AsyncBaseDb):
1182
1182
  if team_id is not None:
1183
1183
  stmt = stmt.where(table.c.team_id == team_id)
1184
1184
  if topics is not None:
1185
- topic_conditions = [text(f"topics::text LIKE '%\"{topic}\"%'") for topic in topics]
1186
- stmt = stmt.where(and_(*topic_conditions))
1185
+ for topic in topics:
1186
+ stmt = stmt.where(func.cast(table.c.topics, String).like(f'%"{topic}"%'))
1187
1187
  if search_content is not None:
1188
1188
  stmt = stmt.where(table.c.memory.ilike(f"%{search_content}%"))
1189
1189
 
@@ -28,7 +28,7 @@ from agno.utils.log import log_debug, log_error, log_info, log_warning
28
28
  from agno.utils.string import generate_id
29
29
 
30
30
  try:
31
- from sqlalchemy import Column, MetaData, Table, and_, func, select, text
31
+ from sqlalchemy import Column, MetaData, String, Table, func, select, text
32
32
  from sqlalchemy.dialects import sqlite
33
33
  from sqlalchemy.engine import Engine, create_engine
34
34
  from sqlalchemy.orm import scoped_session, sessionmaker
@@ -1176,8 +1176,8 @@ class SqliteDb(BaseDb):
1176
1176
  if team_id is not None:
1177
1177
  stmt = stmt.where(table.c.team_id == team_id)
1178
1178
  if topics is not None:
1179
- topic_conditions = [text(f"topics::text LIKE '%\"{topic}\"%'") for topic in topics]
1180
- stmt = stmt.where(and_(*topic_conditions))
1179
+ for topic in topics:
1180
+ stmt = stmt.where(func.cast(table.c.topics, String).like(f'%"{topic}"%'))
1181
1181
  if search_content is not None:
1182
1182
  stmt = stmt.where(table.c.memory.ilike(f"%{search_content}%"))
1183
1183
 
@@ -1252,7 +1252,7 @@ class SqliteDb(BaseDb):
1252
1252
  )
1253
1253
 
1254
1254
  count_stmt = select(func.count()).select_from(stmt.alias())
1255
- total_count = sess.execute(count_stmt).scalar()
1255
+ total_count = sess.execute(count_stmt).scalar() or 0
1256
1256
 
1257
1257
  # Pagination
1258
1258
  if limit is not None:
@@ -13,6 +13,7 @@ from agno.models.base import Model
13
13
  from agno.models.message import Message
14
14
  from agno.models.utils import get_model
15
15
  from agno.tools.function import Function
16
+ from agno.utils.dttm import now_epoch_s
16
17
  from agno.utils.log import (
17
18
  log_debug,
18
19
  log_error,
@@ -227,7 +228,7 @@ class MemoryManager:
227
228
  memory.user_id = user_id
228
229
 
229
230
  if not memory.updated_at:
230
- memory.updated_at = datetime.now()
231
+ memory.updated_at = now_epoch_s()
231
232
 
232
233
  self._upsert_db_memory(memory=memory)
233
234
  return memory.memory_id
@@ -255,7 +256,7 @@ class MemoryManager:
255
256
  user_id = "default"
256
257
 
257
258
  if not memory.updated_at:
258
- memory.updated_at = datetime.now()
259
+ memory.updated_at = now_epoch_s()
259
260
 
260
261
  memory.memory_id = memory_id
261
262
  memory.user_id = user_id
@@ -671,7 +672,7 @@ class MemoryManager:
671
672
  # If updated_at is None, place at the beginning of the list
672
673
  sorted_memories_list = sorted(
673
674
  memories_list,
674
- key=lambda memory: memory.updated_at or datetime.min,
675
+ key=lambda m: m.updated_at if m.updated_at is not None else 0,
675
676
  )
676
677
  else:
677
678
  sorted_memories_list = []
@@ -694,6 +695,7 @@ class MemoryManager:
694
695
  if memories is None:
695
696
  memories = {}
696
697
 
698
+ MAX_UNIX_TS = 2**63 - 1
697
699
  memories_list = memories.get(user_id, [])
698
700
  # Sort memories by updated_at timestamp if available
699
701
  if memories_list:
@@ -701,7 +703,7 @@ class MemoryManager:
701
703
  # If updated_at is None, place at the end of the list
702
704
  sorted_memories_list = sorted(
703
705
  memories_list,
704
- key=lambda memory: memory.updated_at or datetime.max,
706
+ key=lambda m: m.updated_at if m.updated_at is not None else MAX_UNIX_TS,
705
707
  )
706
708
 
707
709
  else:
@@ -5,7 +5,7 @@ from os import getenv
5
5
  from typing import Any, Dict, List, Optional, Type, Union
6
6
 
7
7
  import httpx
8
- from pydantic import BaseModel
8
+ from pydantic import BaseModel, ValidationError
9
9
 
10
10
  from agno.exceptions import ModelProviderError, ModelRateLimitError
11
11
  from agno.models.base import Model
@@ -80,6 +80,30 @@ class Claude(Model):
80
80
  "claude-3-5-haiku-latest",
81
81
  }
82
82
 
83
+ # Models that DO NOT support native structured outputs
84
+ # All future models are assumed to support structured outputs
85
+ NON_STRUCTURED_OUTPUT_MODELS = {
86
+ # Claude 3.x family (all versions)
87
+ "claude-3-opus-20240229",
88
+ "claude-3-sonnet-20240229",
89
+ "claude-3-haiku-20240307",
90
+ "claude-3-opus",
91
+ "claude-3-sonnet",
92
+ "claude-3-haiku",
93
+ # Claude 3.5 family (all versions except Sonnet 4.5)
94
+ "claude-3-5-sonnet-20240620",
95
+ "claude-3-5-sonnet-20241022",
96
+ "claude-3-5-sonnet",
97
+ "claude-3-5-haiku-20241022",
98
+ "claude-3-5-haiku-latest",
99
+ "claude-3-5-haiku",
100
+ # Claude Sonnet 4.x family (versions before 4.5)
101
+ "claude-sonnet-4-20250514",
102
+ "claude-sonnet-4",
103
+ # Claude Opus 4.x family (versions before 4.1)
104
+ # (Add any Opus 4.x models released before 4.1 if they exist)
105
+ }
106
+
83
107
  id: str = "claude-sonnet-4-5-20250929"
84
108
  name: str = "Claude"
85
109
  provider: str = "Anthropic"
@@ -118,6 +142,9 @@ class Claude(Model):
118
142
  # Validate thinking support immediately at model creation
119
143
  if self.thinking:
120
144
  self._validate_thinking_support()
145
+ # Set structured outputs capability flag for supported models
146
+ if self._supports_structured_outputs():
147
+ self.supports_native_structured_outputs = True
121
148
  # Set up skills configuration if skills are enabled
122
149
  if self.skills:
123
150
  self._setup_skills_configuration()
@@ -141,13 +168,72 @@ class Claude(Model):
141
168
  client_params["default_headers"] = self.default_headers
142
169
  return client_params
143
170
 
144
- def _has_beta_features(self) -> bool:
171
+ def _supports_structured_outputs(self) -> bool:
172
+ """
173
+ Check if the current model supports native structured outputs.
174
+
175
+ Returns:
176
+ bool: True if model supports structured outputs
177
+ """
178
+ # If model is in blacklist, it doesn't support structured outputs
179
+ if self.id in self.NON_STRUCTURED_OUTPUT_MODELS:
180
+ log_warning(
181
+ f"Model '{self.id}' does not support structured outputs. "
182
+ "Structured output features will not be available for this model."
183
+ )
184
+ return False
185
+
186
+ # Check for legacy model patterns that don't support structured outputs
187
+ if self.id.startswith("claude-3-"):
188
+ return False
189
+ if self.id.startswith("claude-sonnet-4-") and not self.id.startswith("claude-sonnet-4-5"):
190
+ return False
191
+ if self.id.startswith("claude-opus-4-") and not self.id.startswith("claude-opus-4-1"):
192
+ return False
193
+
194
+ return True
195
+
196
+ def _using_structured_outputs(
197
+ self,
198
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
199
+ tools: Optional[List[Dict[str, Any]]] = None,
200
+ ) -> bool:
201
+ """
202
+ Check if structured outputs are being used in this request.
203
+
204
+ Args:
205
+ response_format: Response format parameter
206
+ tools: Tools list to check for strict mode
207
+
208
+ Returns:
209
+ bool: True if structured outputs are in use
210
+ """
211
+ # Check for output_format usage
212
+ if response_format is not None and self._supports_structured_outputs():
213
+ return True
214
+
215
+ # Check for strict tools
216
+ if tools:
217
+ for tool in tools:
218
+ if tool.get("type") == "function":
219
+ func_def = tool.get("function", {})
220
+ if func_def.get("strict") is True:
221
+ return True
222
+
223
+ return False
224
+
225
+ def _has_beta_features(
226
+ self,
227
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
228
+ tools: Optional[List[Dict[str, Any]]] = None,
229
+ ) -> bool:
145
230
  """Check if the model has any Anthropic beta features enabled."""
146
231
  return (
147
232
  self.mcp_servers is not None
148
233
  or self.context_management is not None
149
234
  or self.skills is not None
150
235
  or self.betas is not None
236
+ or self._using_structured_outputs(response_format, tools)
151
237
  )
152
238
 
153
239
  def get_client(self) -> AnthropicClient:
@@ -230,7 +316,70 @@ class Claude(Model):
230
316
  if beta not in self.betas:
231
317
  self.betas.append(beta)
232
318
 
233
- def get_request_params(self) -> Dict[str, Any]:
319
+ def _ensure_additional_properties_false(self, schema: Dict[str, Any]) -> None:
320
+ """
321
+ Recursively ensure all object types have additionalProperties: false.
322
+ """
323
+ if isinstance(schema, dict):
324
+ if schema.get("type") == "object":
325
+ schema["additionalProperties"] = False
326
+
327
+ # Recursively process nested schemas
328
+ for key, value in schema.items():
329
+ if key in ["properties", "items", "allOf", "anyOf", "oneOf"]:
330
+ if isinstance(value, dict):
331
+ self._ensure_additional_properties_false(value)
332
+ elif isinstance(value, list):
333
+ for item in value:
334
+ if isinstance(item, dict):
335
+ self._ensure_additional_properties_false(item)
336
+
337
+ def _build_output_format(self, response_format: Optional[Union[Dict, Type[BaseModel]]]) -> Optional[Dict[str, Any]]:
338
+ """
339
+ Build Anthropic output_format parameter from response_format.
340
+
341
+ Args:
342
+ response_format: Pydantic model or dict format
343
+
344
+ Returns:
345
+ Dict with output_format structure or None
346
+ """
347
+ if response_format is None:
348
+ return None
349
+
350
+ if not self._supports_structured_outputs():
351
+ return None
352
+
353
+ # Handle Pydantic BaseModel
354
+ if isinstance(response_format, type) and issubclass(response_format, BaseModel):
355
+ try:
356
+ # Try to use Anthropic SDK's transform_schema helper if available
357
+ from anthropic import transform_schema
358
+
359
+ schema = transform_schema(response_format.model_json_schema())
360
+ except (ImportError, AttributeError):
361
+ # Fallback to direct schema conversion
362
+ schema = response_format.model_json_schema()
363
+ # Ensure additionalProperties is False
364
+ if isinstance(schema, dict):
365
+ if "additionalProperties" not in schema:
366
+ schema["additionalProperties"] = False
367
+ # Recursively ensure all object types have additionalProperties: false
368
+ self._ensure_additional_properties_false(schema)
369
+
370
+ return {"type": "json_schema", "schema": schema}
371
+
372
+ # Handle dict format (already in correct structure)
373
+ elif isinstance(response_format, dict):
374
+ return response_format
375
+
376
+ return None
377
+
378
+ def get_request_params(
379
+ self,
380
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
381
+ tools: Optional[List[Dict[str, Any]]] = None,
382
+ ) -> Dict[str, Any]:
234
383
  """
235
384
  Generate keyword arguments for API requests.
236
385
  """
@@ -251,8 +400,20 @@ class Claude(Model):
251
400
  _request_params["top_p"] = self.top_p
252
401
  if self.top_k:
253
402
  _request_params["top_k"] = self.top_k
254
- if self.betas:
255
- _request_params["betas"] = self.betas
403
+
404
+ # Build betas list - include existing betas and add new one if needed
405
+ betas_list = list(self.betas) if self.betas else []
406
+
407
+ # Add structured outputs beta header if using structured outputs
408
+ if self._using_structured_outputs(response_format, tools):
409
+ beta_header = "structured-outputs-2025-11-13"
410
+ if beta_header not in betas_list:
411
+ betas_list.append(beta_header)
412
+
413
+ # Include betas if any are present
414
+ if betas_list:
415
+ _request_params["betas"] = betas_list
416
+
256
417
  if self.context_management:
257
418
  _request_params["context_management"] = self.context_management
258
419
  if self.mcp_servers:
@@ -260,26 +421,51 @@ class Claude(Model):
260
421
  {k: v for k, v in asdict(server).items() if v is not None} for server in self.mcp_servers
261
422
  ]
262
423
  if self.skills:
263
- _request_params["betas"] = self.betas
264
424
  _request_params["container"] = {"skills": self.skills}
265
425
  if self.request_params:
266
426
  _request_params.update(self.request_params)
267
427
 
268
428
  return _request_params
269
429
 
430
+ def _validate_structured_outputs_usage(
431
+ self,
432
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
433
+ tools: Optional[List[Dict[str, Any]]] = None,
434
+ ) -> None:
435
+ """
436
+ Validate that structured outputs are only used with supported models.
437
+
438
+ Raises:
439
+ ValueError: If structured outputs are used with unsupported model
440
+ """
441
+ if not self._using_structured_outputs(response_format, tools):
442
+ return
443
+
444
+ if not self._supports_structured_outputs():
445
+ raise ValueError(f"Model '{self.id}' does not support structured outputs.\n\n")
446
+
270
447
  def _prepare_request_kwargs(
271
- self, system_message: str, tools: Optional[List[Dict[str, Any]]] = None
448
+ self,
449
+ system_message: str,
450
+ tools: Optional[List[Dict[str, Any]]] = None,
451
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
272
452
  ) -> Dict[str, Any]:
273
453
  """
274
454
  Prepare the request keyword arguments for the API call.
275
455
 
276
456
  Args:
277
457
  system_message (str): The concatenated system messages.
458
+ tools: Optional list of tools
459
+ response_format: Optional response format (Pydantic model or dict)
278
460
 
279
461
  Returns:
280
462
  Dict[str, Any]: The request keyword arguments.
281
463
  """
282
- request_kwargs = self.get_request_params().copy()
464
+ # Validate structured outputs usage
465
+ self._validate_structured_outputs_usage(response_format, tools)
466
+
467
+ # Pass response_format and tools to get_request_params for beta header handling
468
+ request_kwargs = self.get_request_params(response_format=response_format, tools=tools).copy()
283
469
  if system_message:
284
470
  if self.cache_system_prompt:
285
471
  cache_control = (
@@ -300,9 +486,15 @@ class Claude(Model):
300
486
  else:
301
487
  tools = [code_execution_tool]
302
488
 
489
+ # Format tools (this will handle strict mode)
303
490
  if tools:
304
491
  request_kwargs["tools"] = format_tools_for_model(tools)
305
492
 
493
+ # Build output_format if response_format is provided
494
+ output_format = self._build_output_format(response_format)
495
+ if output_format:
496
+ request_kwargs["output_format"] = output_format
497
+
306
498
  if request_kwargs:
307
499
  log_debug(f"Calling {self.provider} with request parameters: {request_kwargs}", log_level=2)
308
500
  return request_kwargs
@@ -324,9 +516,9 @@ class Claude(Model):
324
516
  run_response.metrics.set_time_to_first_token()
325
517
 
326
518
  chat_messages, system_message = format_messages(messages)
327
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
519
+ request_kwargs = self._prepare_request_kwargs(system_message, tools=tools, response_format=response_format)
328
520
 
329
- if self._has_beta_features():
521
+ if self._has_beta_features(response_format=response_format, tools=tools):
330
522
  assistant_message.metrics.start_timer()
331
523
  provider_response = self.get_client().beta.messages.create(
332
524
  model=self.id,
@@ -387,14 +579,14 @@ class Claude(Model):
387
579
  APIStatusError: For other API-related errors
388
580
  """
389
581
  chat_messages, system_message = format_messages(messages)
390
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
582
+ request_kwargs = self._prepare_request_kwargs(system_message, tools=tools, response_format=response_format)
391
583
 
392
584
  try:
393
585
  if run_response and run_response.metrics:
394
586
  run_response.metrics.set_time_to_first_token()
395
587
 
396
588
  # Beta features
397
- if self._has_beta_features():
589
+ if self._has_beta_features(response_format=response_format, tools=tools):
398
590
  assistant_message.metrics.start_timer()
399
591
  with self.get_client().beta.messages.stream(
400
592
  model=self.id,
@@ -402,7 +594,7 @@ class Claude(Model):
402
594
  **request_kwargs,
403
595
  ) as stream:
404
596
  for chunk in stream:
405
- yield self._parse_provider_response_delta(chunk) # type: ignore
597
+ yield self._parse_provider_response_delta(chunk, response_format=response_format) # type: ignore
406
598
  else:
407
599
  assistant_message.metrics.start_timer()
408
600
  with self.get_client().messages.stream(
@@ -411,7 +603,7 @@ class Claude(Model):
411
603
  **request_kwargs,
412
604
  ) as stream:
413
605
  for chunk in stream: # type: ignore
414
- yield self._parse_provider_response_delta(chunk) # type: ignore
606
+ yield self._parse_provider_response_delta(chunk, response_format=response_format) # type: ignore
415
607
 
416
608
  assistant_message.metrics.stop_timer()
417
609
 
@@ -447,10 +639,10 @@ class Claude(Model):
447
639
  run_response.metrics.set_time_to_first_token()
448
640
 
449
641
  chat_messages, system_message = format_messages(messages)
450
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
642
+ request_kwargs = self._prepare_request_kwargs(system_message, tools=tools, response_format=response_format)
451
643
 
452
644
  # Beta features
453
- if self._has_beta_features():
645
+ if self._has_beta_features(response_format=response_format, tools=tools):
454
646
  assistant_message.metrics.start_timer()
455
647
  provider_response = await self.get_async_client().beta.messages.create(
456
648
  model=self.id,
@@ -512,9 +704,9 @@ class Claude(Model):
512
704
  run_response.metrics.set_time_to_first_token()
513
705
 
514
706
  chat_messages, system_message = format_messages(messages)
515
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
707
+ request_kwargs = self._prepare_request_kwargs(system_message, tools=tools, response_format=response_format)
516
708
 
517
- if self._has_beta_features():
709
+ if self._has_beta_features(response_format=response_format, tools=tools):
518
710
  assistant_message.metrics.start_timer()
519
711
  async with self.get_async_client().beta.messages.stream(
520
712
  model=self.id,
@@ -522,7 +714,7 @@ class Claude(Model):
522
714
  **request_kwargs,
523
715
  ) as stream:
524
716
  async for chunk in stream:
525
- yield self._parse_provider_response_delta(chunk) # type: ignore
717
+ yield self._parse_provider_response_delta(chunk, response_format=response_format) # type: ignore
526
718
  else:
527
719
  assistant_message.metrics.start_timer()
528
720
  async with self.get_async_client().messages.stream(
@@ -531,7 +723,7 @@ class Claude(Model):
531
723
  **request_kwargs,
532
724
  ) as stream:
533
725
  async for chunk in stream: # type: ignore
534
- yield self._parse_provider_response_delta(chunk) # type: ignore
726
+ yield self._parse_provider_response_delta(chunk, response_format=response_format) # type: ignore
535
727
 
536
728
  assistant_message.metrics.stop_timer()
537
729
 
@@ -556,12 +748,18 @@ class Claude(Model):
556
748
  return tool_call_prompt
557
749
  return None
558
750
 
559
- def _parse_provider_response(self, response: Union[AnthropicMessage, BetaMessage], **kwargs) -> ModelResponse:
751
+ def _parse_provider_response(
752
+ self,
753
+ response: Union[AnthropicMessage, BetaMessage],
754
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
755
+ **kwargs,
756
+ ) -> ModelResponse:
560
757
  """
561
758
  Parse the Claude response into a ModelResponse.
562
759
 
563
760
  Args:
564
761
  response: Raw response from Anthropic
762
+ response_format: Optional response format for structured output parsing
565
763
 
566
764
  Returns:
567
765
  ModelResponse: Parsed response data
@@ -574,10 +772,32 @@ class Claude(Model):
574
772
  if response.content:
575
773
  for block in response.content:
576
774
  if block.type == "text":
775
+ text_content = block.text
776
+
577
777
  if model_response.content is None:
578
- model_response.content = block.text
778
+ model_response.content = text_content
579
779
  else:
580
- model_response.content += block.text
780
+ model_response.content += text_content
781
+
782
+ # Handle structured outputs (JSON outputs)
783
+ if (
784
+ response_format is not None
785
+ and isinstance(response_format, type)
786
+ and issubclass(response_format, BaseModel)
787
+ ):
788
+ if text_content:
789
+ try:
790
+ # Parse JSON from text content
791
+ parsed_data = json.loads(text_content)
792
+ # Validate against Pydantic model
793
+ model_response.parsed = response_format.model_validate(parsed_data)
794
+ log_debug(f"Successfully parsed structured output: {model_response.parsed}")
795
+ except json.JSONDecodeError as e:
796
+ log_warning(f"Failed to parse JSON from structured output: {e}")
797
+ except ValidationError as e:
798
+ log_warning(f"Failed to validate structured output against schema: {e}")
799
+ except Exception as e:
800
+ log_warning(f"Unexpected error parsing structured output: {e}")
581
801
 
582
802
  # Capture citations from the response
583
803
  if block.citations is not None:
@@ -669,12 +889,14 @@ class Claude(Model):
669
889
  ParsedBetaContentBlockStopEvent,
670
890
  ParsedBetaMessageStopEvent,
671
891
  ],
892
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
672
893
  ) -> ModelResponse:
673
894
  """
674
895
  Parse the Claude streaming response into ModelProviderResponse objects.
675
896
 
676
897
  Args:
677
898
  response: Raw response chunk from Anthropic
899
+ response_format: Optional response format for structured output parsing
678
900
 
679
901
  Returns:
680
902
  ModelResponse: Iterator of parsed response data
@@ -717,11 +939,24 @@ class Claude(Model):
717
939
  }
718
940
  ]
719
941
 
720
- # Capture citations from the final response
942
+ # Capture citations from the final response and handle structured outputs
721
943
  elif isinstance(response, (MessageStopEvent, ParsedBetaMessageStopEvent)):
944
+ # In streaming mode, content has already been emitted via ContentBlockDeltaEvent chunks
945
+ # Setting content here would cause duplication since _populate_stream_data accumulates with +=
946
+ # Keep content empty to avoid duplication
722
947
  model_response.content = ""
723
948
  model_response.citations = Citations(raw=[], urls=[], documents=[])
949
+
950
+ # Accumulate text content for structured output parsing (but don't set model_response.content)
951
+ # The text was already streamed via ContentBlockDeltaEvent chunks
952
+ accumulated_text = ""
953
+
724
954
  for block in response.message.content: # type: ignore
955
+ # Handle text blocks for structured output parsing
956
+ if block.type == "text":
957
+ accumulated_text += block.text
958
+
959
+ # Handle citations
725
960
  citations = getattr(block, "citations", None)
726
961
  if not citations:
727
962
  continue
@@ -736,6 +971,28 @@ class Claude(Model):
736
971
  DocumentCitation(document_title=citation.document_title, cited_text=citation.cited_text)
737
972
  )
738
973
 
974
+ # Handle structured outputs (JSON outputs) from accumulated text
975
+ # Note: We parse from accumulated_text but don't set model_response.content to avoid duplication
976
+ # The content was already streamed via ContentBlockDeltaEvent chunks
977
+ if (
978
+ response_format is not None
979
+ and isinstance(response_format, type)
980
+ and issubclass(response_format, BaseModel)
981
+ ):
982
+ if accumulated_text:
983
+ try:
984
+ # Parse JSON from accumulated text content
985
+ parsed_data = json.loads(accumulated_text)
986
+ # Validate against Pydantic model
987
+ model_response.parsed = response_format.model_validate(parsed_data)
988
+ log_debug(f"Successfully parsed structured output from stream: {model_response.parsed}")
989
+ except json.JSONDecodeError as e:
990
+ log_warning(f"Failed to parse JSON from structured output in stream: {e}")
991
+ except ValidationError as e:
992
+ log_warning(f"Failed to validate structured output against schema in stream: {e}")
993
+ except Exception as e:
994
+ log_warning(f"Unexpected error parsing structured output in stream: {e}")
995
+
739
996
  # Capture context management information if present
740
997
  if self.context_management is not None and hasattr(response.message, "context_management"): # type: ignore
741
998
  context_mgmt = response.message.context_management # type: ignore