agno 2.4.2__tar.gz → 2.4.4__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 (686) hide show
  1. {agno-2.4.2 → agno-2.4.4}/PKG-INFO +7 -5
  2. {agno-2.4.2 → agno-2.4.4}/README.md +2 -2
  3. {agno-2.4.2 → agno-2.4.4}/agno/agent/agent.py +13 -0
  4. {agno-2.4.2 → agno-2.4.4}/agno/db/firestore/firestore.py +53 -30
  5. {agno-2.4.2 → agno-2.4.4}/agno/db/surrealdb/models.py +5 -5
  6. {agno-2.4.2 → agno-2.4.4}/agno/db/surrealdb/surrealdb.py +13 -1
  7. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/markdown.py +112 -11
  8. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/openai.py +8 -4
  9. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/knowledge.py +59 -6
  10. agno-2.4.4/agno/knowledge/reader/csv_reader.py +215 -0
  11. agno-2.4.4/agno/knowledge/reader/excel_reader.py +225 -0
  12. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/field_labeled_csv_reader.py +13 -179
  13. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/reader_factory.py +22 -5
  14. agno-2.4.4/agno/knowledge/reader/utils/__init__.py +17 -0
  15. agno-2.4.4/agno/knowledge/reader/utils/spreadsheet.py +114 -0
  16. {agno-2.4.2 → agno-2.4.4}/agno/models/base.py +6 -0
  17. agno-2.4.4/agno/models/moonshot/__init__.py +3 -0
  18. agno-2.4.4/agno/models/moonshot/moonshot.py +57 -0
  19. {agno-2.4.2 → agno-2.4.4}/agno/models/openrouter/responses.py +2 -2
  20. {agno-2.4.2 → agno-2.4.4}/agno/models/response.py +4 -0
  21. {agno-2.4.2 → agno-2.4.4}/agno/models/utils.py +5 -0
  22. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/knowledge/knowledge.py +5 -3
  23. {agno-2.4.2 → agno-2.4.4}/agno/run/base.py +4 -0
  24. {agno-2.4.2 → agno-2.4.4}/agno/tools/decorator.py +3 -0
  25. {agno-2.4.2 → agno-2.4.4}/agno/tools/function.py +3 -0
  26. agno-2.4.4/agno/tools/unsplash.py +341 -0
  27. {agno-2.4.2 → agno-2.4.4}/agno/utils/print_response/agent.py +8 -5
  28. {agno-2.4.2 → agno-2.4.4}/agno/utils/response.py +38 -28
  29. {agno-2.4.2 → agno-2.4.4}/agno/utils/string.py +2 -1
  30. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/lancedb/lance_db.py +29 -7
  31. {agno-2.4.2 → agno-2.4.4}/agno/workflow/workflow.py +16 -6
  32. {agno-2.4.2 → agno-2.4.4}/agno.egg-info/PKG-INFO +7 -5
  33. {agno-2.4.2 → agno-2.4.4}/agno.egg-info/SOURCES.txt +6 -0
  34. {agno-2.4.2 → agno-2.4.4}/agno.egg-info/requires.txt +5 -2
  35. {agno-2.4.2 → agno-2.4.4}/pyproject.toml +5 -2
  36. agno-2.4.2/agno/knowledge/reader/csv_reader.py +0 -383
  37. {agno-2.4.2 → agno-2.4.4}/LICENSE +0 -0
  38. {agno-2.4.2 → agno-2.4.4}/agno/__init__.py +0 -0
  39. {agno-2.4.2 → agno-2.4.4}/agno/agent/__init__.py +0 -0
  40. {agno-2.4.2 → agno-2.4.4}/agno/agent/remote.py +0 -0
  41. {agno-2.4.2 → agno-2.4.4}/agno/api/__init__.py +0 -0
  42. {agno-2.4.2 → agno-2.4.4}/agno/api/agent.py +0 -0
  43. {agno-2.4.2 → agno-2.4.4}/agno/api/api.py +0 -0
  44. {agno-2.4.2 → agno-2.4.4}/agno/api/evals.py +0 -0
  45. {agno-2.4.2 → agno-2.4.4}/agno/api/os.py +0 -0
  46. {agno-2.4.2 → agno-2.4.4}/agno/api/routes.py +0 -0
  47. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/__init__.py +0 -0
  48. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/agent.py +0 -0
  49. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/evals.py +0 -0
  50. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/os.py +0 -0
  51. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/response.py +0 -0
  52. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/team.py +0 -0
  53. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/utils.py +0 -0
  54. {agno-2.4.2 → agno-2.4.4}/agno/api/schemas/workflows.py +0 -0
  55. {agno-2.4.2 → agno-2.4.4}/agno/api/settings.py +0 -0
  56. {agno-2.4.2 → agno-2.4.4}/agno/api/team.py +0 -0
  57. {agno-2.4.2 → agno-2.4.4}/agno/api/workflow.py +0 -0
  58. {agno-2.4.2 → agno-2.4.4}/agno/client/__init__.py +0 -0
  59. {agno-2.4.2 → agno-2.4.4}/agno/client/a2a/__init__.py +0 -0
  60. {agno-2.4.2 → agno-2.4.4}/agno/client/a2a/client.py +0 -0
  61. {agno-2.4.2 → agno-2.4.4}/agno/client/a2a/schemas.py +0 -0
  62. {agno-2.4.2 → agno-2.4.4}/agno/client/a2a/utils.py +0 -0
  63. {agno-2.4.2 → agno-2.4.4}/agno/client/os.py +0 -0
  64. {agno-2.4.2 → agno-2.4.4}/agno/cloud/aws/base.py +0 -0
  65. {agno-2.4.2 → agno-2.4.4}/agno/cloud/aws/s3/__init__.py +0 -0
  66. {agno-2.4.2 → agno-2.4.4}/agno/cloud/aws/s3/api_client.py +0 -0
  67. {agno-2.4.2 → agno-2.4.4}/agno/cloud/aws/s3/bucket.py +0 -0
  68. {agno-2.4.2 → agno-2.4.4}/agno/cloud/aws/s3/object.py +0 -0
  69. {agno-2.4.2 → agno-2.4.4}/agno/compression/__init__.py +0 -0
  70. {agno-2.4.2 → agno-2.4.4}/agno/compression/manager.py +0 -0
  71. {agno-2.4.2 → agno-2.4.4}/agno/culture/__init__.py +0 -0
  72. {agno-2.4.2 → agno-2.4.4}/agno/culture/manager.py +0 -0
  73. {agno-2.4.2 → agno-2.4.4}/agno/db/__init__.py +0 -0
  74. {agno-2.4.2 → agno-2.4.4}/agno/db/async_postgres/__init__.py +0 -0
  75. {agno-2.4.2 → agno-2.4.4}/agno/db/base.py +0 -0
  76. {agno-2.4.2 → agno-2.4.4}/agno/db/dynamo/__init__.py +0 -0
  77. {agno-2.4.2 → agno-2.4.4}/agno/db/dynamo/dynamo.py +0 -0
  78. {agno-2.4.2 → agno-2.4.4}/agno/db/dynamo/schemas.py +0 -0
  79. {agno-2.4.2 → agno-2.4.4}/agno/db/dynamo/utils.py +0 -0
  80. {agno-2.4.2 → agno-2.4.4}/agno/db/firestore/__init__.py +0 -0
  81. {agno-2.4.2 → agno-2.4.4}/agno/db/firestore/schemas.py +0 -0
  82. {agno-2.4.2 → agno-2.4.4}/agno/db/firestore/utils.py +0 -0
  83. {agno-2.4.2 → agno-2.4.4}/agno/db/gcs_json/__init__.py +0 -0
  84. {agno-2.4.2 → agno-2.4.4}/agno/db/gcs_json/gcs_json_db.py +0 -0
  85. {agno-2.4.2 → agno-2.4.4}/agno/db/gcs_json/utils.py +0 -0
  86. {agno-2.4.2 → agno-2.4.4}/agno/db/in_memory/__init__.py +0 -0
  87. {agno-2.4.2 → agno-2.4.4}/agno/db/in_memory/in_memory_db.py +0 -0
  88. {agno-2.4.2 → agno-2.4.4}/agno/db/in_memory/utils.py +0 -0
  89. {agno-2.4.2 → agno-2.4.4}/agno/db/json/__init__.py +0 -0
  90. {agno-2.4.2 → agno-2.4.4}/agno/db/json/json_db.py +0 -0
  91. {agno-2.4.2 → agno-2.4.4}/agno/db/json/utils.py +0 -0
  92. {agno-2.4.2 → agno-2.4.4}/agno/db/migrations/__init__.py +0 -0
  93. {agno-2.4.2 → agno-2.4.4}/agno/db/migrations/manager.py +0 -0
  94. {agno-2.4.2 → agno-2.4.4}/agno/db/migrations/utils.py +0 -0
  95. {agno-2.4.2 → agno-2.4.4}/agno/db/migrations/v1_to_v2.py +0 -0
  96. {agno-2.4.2 → agno-2.4.4}/agno/db/migrations/versions/__init__.py +0 -0
  97. {agno-2.4.2 → agno-2.4.4}/agno/db/migrations/versions/v2_3_0.py +0 -0
  98. {agno-2.4.2 → agno-2.4.4}/agno/db/mongo/__init__.py +0 -0
  99. {agno-2.4.2 → agno-2.4.4}/agno/db/mongo/async_mongo.py +0 -0
  100. {agno-2.4.2 → agno-2.4.4}/agno/db/mongo/mongo.py +0 -0
  101. {agno-2.4.2 → agno-2.4.4}/agno/db/mongo/schemas.py +0 -0
  102. {agno-2.4.2 → agno-2.4.4}/agno/db/mongo/utils.py +0 -0
  103. {agno-2.4.2 → agno-2.4.4}/agno/db/mysql/__init__.py +0 -0
  104. {agno-2.4.2 → agno-2.4.4}/agno/db/mysql/async_mysql.py +0 -0
  105. {agno-2.4.2 → agno-2.4.4}/agno/db/mysql/mysql.py +0 -0
  106. {agno-2.4.2 → agno-2.4.4}/agno/db/mysql/schemas.py +0 -0
  107. {agno-2.4.2 → agno-2.4.4}/agno/db/mysql/utils.py +0 -0
  108. {agno-2.4.2 → agno-2.4.4}/agno/db/postgres/__init__.py +0 -0
  109. {agno-2.4.2 → agno-2.4.4}/agno/db/postgres/async_postgres.py +0 -0
  110. {agno-2.4.2 → agno-2.4.4}/agno/db/postgres/postgres.py +0 -0
  111. {agno-2.4.2 → agno-2.4.4}/agno/db/postgres/schemas.py +0 -0
  112. {agno-2.4.2 → agno-2.4.4}/agno/db/postgres/utils.py +0 -0
  113. {agno-2.4.2 → agno-2.4.4}/agno/db/redis/__init__.py +0 -0
  114. {agno-2.4.2 → agno-2.4.4}/agno/db/redis/redis.py +0 -0
  115. {agno-2.4.2 → agno-2.4.4}/agno/db/redis/schemas.py +0 -0
  116. {agno-2.4.2 → agno-2.4.4}/agno/db/redis/utils.py +0 -0
  117. {agno-2.4.2 → agno-2.4.4}/agno/db/schemas/__init__.py +0 -0
  118. {agno-2.4.2 → agno-2.4.4}/agno/db/schemas/culture.py +0 -0
  119. {agno-2.4.2 → agno-2.4.4}/agno/db/schemas/evals.py +0 -0
  120. {agno-2.4.2 → agno-2.4.4}/agno/db/schemas/knowledge.py +0 -0
  121. {agno-2.4.2 → agno-2.4.4}/agno/db/schemas/memory.py +0 -0
  122. {agno-2.4.2 → agno-2.4.4}/agno/db/schemas/metrics.py +0 -0
  123. {agno-2.4.2 → agno-2.4.4}/agno/db/singlestore/__init__.py +0 -0
  124. {agno-2.4.2 → agno-2.4.4}/agno/db/singlestore/schemas.py +0 -0
  125. {agno-2.4.2 → agno-2.4.4}/agno/db/singlestore/singlestore.py +0 -0
  126. {agno-2.4.2 → agno-2.4.4}/agno/db/singlestore/utils.py +0 -0
  127. {agno-2.4.2 → agno-2.4.4}/agno/db/sqlite/__init__.py +0 -0
  128. {agno-2.4.2 → agno-2.4.4}/agno/db/sqlite/async_sqlite.py +0 -0
  129. {agno-2.4.2 → agno-2.4.4}/agno/db/sqlite/schemas.py +0 -0
  130. {agno-2.4.2 → agno-2.4.4}/agno/db/sqlite/sqlite.py +0 -0
  131. {agno-2.4.2 → agno-2.4.4}/agno/db/sqlite/utils.py +0 -0
  132. {agno-2.4.2 → agno-2.4.4}/agno/db/surrealdb/__init__.py +0 -0
  133. {agno-2.4.2 → agno-2.4.4}/agno/db/surrealdb/metrics.py +0 -0
  134. {agno-2.4.2 → agno-2.4.4}/agno/db/surrealdb/queries.py +0 -0
  135. {agno-2.4.2 → agno-2.4.4}/agno/db/surrealdb/utils.py +0 -0
  136. {agno-2.4.2 → agno-2.4.4}/agno/db/utils.py +0 -0
  137. {agno-2.4.2 → agno-2.4.4}/agno/debug.py +0 -0
  138. {agno-2.4.2 → agno-2.4.4}/agno/eval/__init__.py +0 -0
  139. {agno-2.4.2 → agno-2.4.4}/agno/eval/accuracy.py +0 -0
  140. {agno-2.4.2 → agno-2.4.4}/agno/eval/agent_as_judge.py +0 -0
  141. {agno-2.4.2 → agno-2.4.4}/agno/eval/base.py +0 -0
  142. {agno-2.4.2 → agno-2.4.4}/agno/eval/performance.py +0 -0
  143. {agno-2.4.2 → agno-2.4.4}/agno/eval/reliability.py +0 -0
  144. {agno-2.4.2 → agno-2.4.4}/agno/eval/utils.py +0 -0
  145. {agno-2.4.2 → agno-2.4.4}/agno/exceptions.py +0 -0
  146. {agno-2.4.2 → agno-2.4.4}/agno/filters.py +0 -0
  147. {agno-2.4.2 → agno-2.4.4}/agno/guardrails/__init__.py +0 -0
  148. {agno-2.4.2 → agno-2.4.4}/agno/guardrails/base.py +0 -0
  149. {agno-2.4.2 → agno-2.4.4}/agno/guardrails/openai.py +0 -0
  150. {agno-2.4.2 → agno-2.4.4}/agno/guardrails/pii.py +0 -0
  151. {agno-2.4.2 → agno-2.4.4}/agno/guardrails/prompt_injection.py +0 -0
  152. {agno-2.4.2 → agno-2.4.4}/agno/hooks/__init__.py +0 -0
  153. {agno-2.4.2 → agno-2.4.4}/agno/hooks/decorator.py +0 -0
  154. {agno-2.4.2 → agno-2.4.4}/agno/integrations/__init__.py +0 -0
  155. {agno-2.4.2 → agno-2.4.4}/agno/integrations/discord/__init__.py +0 -0
  156. {agno-2.4.2 → agno-2.4.4}/agno/integrations/discord/client.py +0 -0
  157. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/__init__.py +0 -0
  158. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/__init__.py +0 -0
  159. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/agentic.py +0 -0
  160. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/code.py +0 -0
  161. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/document.py +0 -0
  162. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/fixed.py +0 -0
  163. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/recursive.py +0 -0
  164. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/row.py +0 -0
  165. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/semantic.py +0 -0
  166. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/chunking/strategy.py +0 -0
  167. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/content.py +0 -0
  168. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/document/__init__.py +0 -0
  169. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/document/base.py +0 -0
  170. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/__init__.py +0 -0
  171. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/aws_bedrock.py +0 -0
  172. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/azure_openai.py +0 -0
  173. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/base.py +0 -0
  174. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/cohere.py +0 -0
  175. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/fastembed.py +0 -0
  176. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/fireworks.py +0 -0
  177. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/google.py +0 -0
  178. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/huggingface.py +0 -0
  179. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/jina.py +0 -0
  180. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/langdb.py +0 -0
  181. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/mistral.py +0 -0
  182. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/nebius.py +0 -0
  183. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/ollama.py +0 -0
  184. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/sentence_transformer.py +0 -0
  185. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/together.py +0 -0
  186. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/vllm.py +0 -0
  187. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/embedder/voyageai.py +0 -0
  188. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/filesystem.py +0 -0
  189. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/protocol.py +0 -0
  190. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/__init__.py +0 -0
  191. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/arxiv_reader.py +0 -0
  192. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/base.py +0 -0
  193. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/docx_reader.py +0 -0
  194. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/firecrawl_reader.py +0 -0
  195. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/json_reader.py +0 -0
  196. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/markdown_reader.py +0 -0
  197. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/pdf_reader.py +0 -0
  198. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/pptx_reader.py +0 -0
  199. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/s3_reader.py +0 -0
  200. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/tavily_reader.py +0 -0
  201. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/text_reader.py +0 -0
  202. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/web_search_reader.py +0 -0
  203. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/website_reader.py +0 -0
  204. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/wikipedia_reader.py +0 -0
  205. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reader/youtube_reader.py +0 -0
  206. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/remote_content/__init__.py +0 -0
  207. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/remote_content/config.py +0 -0
  208. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/remote_content/remote_content.py +0 -0
  209. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reranker/__init__.py +0 -0
  210. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reranker/base.py +0 -0
  211. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reranker/cohere.py +0 -0
  212. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reranker/infinity.py +0 -0
  213. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/reranker/sentence_transformer.py +0 -0
  214. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/types.py +0 -0
  215. {agno-2.4.2 → agno-2.4.4}/agno/knowledge/utils.py +0 -0
  216. {agno-2.4.2 → agno-2.4.4}/agno/learn/__init__.py +0 -0
  217. {agno-2.4.2 → agno-2.4.4}/agno/learn/config.py +0 -0
  218. {agno-2.4.2 → agno-2.4.4}/agno/learn/curate.py +0 -0
  219. {agno-2.4.2 → agno-2.4.4}/agno/learn/machine.py +0 -0
  220. {agno-2.4.2 → agno-2.4.4}/agno/learn/schemas.py +0 -0
  221. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/__init__.py +0 -0
  222. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/decision_log.py +0 -0
  223. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/entity_memory.py +0 -0
  224. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/learned_knowledge.py +0 -0
  225. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/protocol.py +0 -0
  226. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/session_context.py +0 -0
  227. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/user_memory.py +0 -0
  228. {agno-2.4.2 → agno-2.4.4}/agno/learn/stores/user_profile.py +0 -0
  229. {agno-2.4.2 → agno-2.4.4}/agno/learn/utils.py +0 -0
  230. {agno-2.4.2 → agno-2.4.4}/agno/media.py +0 -0
  231. {agno-2.4.2 → agno-2.4.4}/agno/memory/__init__.py +0 -0
  232. {agno-2.4.2 → agno-2.4.4}/agno/memory/manager.py +0 -0
  233. {agno-2.4.2 → agno-2.4.4}/agno/memory/strategies/__init__.py +0 -0
  234. {agno-2.4.2 → agno-2.4.4}/agno/memory/strategies/base.py +0 -0
  235. {agno-2.4.2 → agno-2.4.4}/agno/memory/strategies/summarize.py +0 -0
  236. {agno-2.4.2 → agno-2.4.4}/agno/memory/strategies/types.py +0 -0
  237. {agno-2.4.2 → agno-2.4.4}/agno/models/__init__.py +0 -0
  238. {agno-2.4.2 → agno-2.4.4}/agno/models/aimlapi/__init__.py +0 -0
  239. {agno-2.4.2 → agno-2.4.4}/agno/models/aimlapi/aimlapi.py +0 -0
  240. {agno-2.4.2 → agno-2.4.4}/agno/models/anthropic/__init__.py +0 -0
  241. {agno-2.4.2 → agno-2.4.4}/agno/models/anthropic/claude.py +0 -0
  242. {agno-2.4.2 → agno-2.4.4}/agno/models/aws/__init__.py +0 -0
  243. {agno-2.4.2 → agno-2.4.4}/agno/models/aws/bedrock.py +0 -0
  244. {agno-2.4.2 → agno-2.4.4}/agno/models/aws/claude.py +0 -0
  245. {agno-2.4.2 → agno-2.4.4}/agno/models/azure/__init__.py +0 -0
  246. {agno-2.4.2 → agno-2.4.4}/agno/models/azure/ai_foundry.py +0 -0
  247. {agno-2.4.2 → agno-2.4.4}/agno/models/azure/openai_chat.py +0 -0
  248. {agno-2.4.2 → agno-2.4.4}/agno/models/cerebras/__init__.py +0 -0
  249. {agno-2.4.2 → agno-2.4.4}/agno/models/cerebras/cerebras.py +0 -0
  250. {agno-2.4.2 → agno-2.4.4}/agno/models/cerebras/cerebras_openai.py +0 -0
  251. {agno-2.4.2 → agno-2.4.4}/agno/models/cohere/__init__.py +0 -0
  252. {agno-2.4.2 → agno-2.4.4}/agno/models/cohere/chat.py +0 -0
  253. {agno-2.4.2 → agno-2.4.4}/agno/models/cometapi/__init__.py +0 -0
  254. {agno-2.4.2 → agno-2.4.4}/agno/models/cometapi/cometapi.py +0 -0
  255. {agno-2.4.2 → agno-2.4.4}/agno/models/dashscope/__init__.py +0 -0
  256. {agno-2.4.2 → agno-2.4.4}/agno/models/dashscope/dashscope.py +0 -0
  257. {agno-2.4.2 → agno-2.4.4}/agno/models/deepinfra/__init__.py +0 -0
  258. {agno-2.4.2 → agno-2.4.4}/agno/models/deepinfra/deepinfra.py +0 -0
  259. {agno-2.4.2 → agno-2.4.4}/agno/models/deepseek/__init__.py +0 -0
  260. {agno-2.4.2 → agno-2.4.4}/agno/models/deepseek/deepseek.py +0 -0
  261. {agno-2.4.2 → agno-2.4.4}/agno/models/defaults.py +0 -0
  262. {agno-2.4.2 → agno-2.4.4}/agno/models/fireworks/__init__.py +0 -0
  263. {agno-2.4.2 → agno-2.4.4}/agno/models/fireworks/fireworks.py +0 -0
  264. {agno-2.4.2 → agno-2.4.4}/agno/models/google/__init__.py +0 -0
  265. {agno-2.4.2 → agno-2.4.4}/agno/models/google/gemini.py +0 -0
  266. {agno-2.4.2 → agno-2.4.4}/agno/models/google/utils.py +0 -0
  267. {agno-2.4.2 → agno-2.4.4}/agno/models/groq/__init__.py +0 -0
  268. {agno-2.4.2 → agno-2.4.4}/agno/models/groq/groq.py +0 -0
  269. {agno-2.4.2 → agno-2.4.4}/agno/models/huggingface/__init__.py +0 -0
  270. {agno-2.4.2 → agno-2.4.4}/agno/models/huggingface/huggingface.py +0 -0
  271. {agno-2.4.2 → agno-2.4.4}/agno/models/ibm/__init__.py +0 -0
  272. {agno-2.4.2 → agno-2.4.4}/agno/models/ibm/watsonx.py +0 -0
  273. {agno-2.4.2 → agno-2.4.4}/agno/models/internlm/__init__.py +0 -0
  274. {agno-2.4.2 → agno-2.4.4}/agno/models/internlm/internlm.py +0 -0
  275. {agno-2.4.2 → agno-2.4.4}/agno/models/langdb/__init__.py +0 -0
  276. {agno-2.4.2 → agno-2.4.4}/agno/models/langdb/langdb.py +0 -0
  277. {agno-2.4.2 → agno-2.4.4}/agno/models/litellm/__init__.py +0 -0
  278. {agno-2.4.2 → agno-2.4.4}/agno/models/litellm/chat.py +0 -0
  279. {agno-2.4.2 → agno-2.4.4}/agno/models/litellm/litellm_openai.py +0 -0
  280. {agno-2.4.2 → agno-2.4.4}/agno/models/llama_cpp/__init__.py +0 -0
  281. {agno-2.4.2 → agno-2.4.4}/agno/models/llama_cpp/llama_cpp.py +0 -0
  282. {agno-2.4.2 → agno-2.4.4}/agno/models/lmstudio/__init__.py +0 -0
  283. {agno-2.4.2 → agno-2.4.4}/agno/models/lmstudio/lmstudio.py +0 -0
  284. {agno-2.4.2 → agno-2.4.4}/agno/models/message.py +0 -0
  285. {agno-2.4.2 → agno-2.4.4}/agno/models/meta/__init__.py +0 -0
  286. {agno-2.4.2 → agno-2.4.4}/agno/models/meta/llama.py +0 -0
  287. {agno-2.4.2 → agno-2.4.4}/agno/models/meta/llama_openai.py +0 -0
  288. {agno-2.4.2 → agno-2.4.4}/agno/models/metrics.py +0 -0
  289. {agno-2.4.2 → agno-2.4.4}/agno/models/mistral/__init__.py +0 -0
  290. {agno-2.4.2 → agno-2.4.4}/agno/models/mistral/mistral.py +0 -0
  291. {agno-2.4.2 → agno-2.4.4}/agno/models/n1n/__init__.py +0 -0
  292. {agno-2.4.2 → agno-2.4.4}/agno/models/n1n/n1n.py +0 -0
  293. {agno-2.4.2 → agno-2.4.4}/agno/models/nebius/__init__.py +0 -0
  294. {agno-2.4.2 → agno-2.4.4}/agno/models/nebius/nebius.py +0 -0
  295. {agno-2.4.2 → agno-2.4.4}/agno/models/nexus/__init__.py +0 -0
  296. {agno-2.4.2 → agno-2.4.4}/agno/models/nexus/nexus.py +0 -0
  297. {agno-2.4.2 → agno-2.4.4}/agno/models/nvidia/__init__.py +0 -0
  298. {agno-2.4.2 → agno-2.4.4}/agno/models/nvidia/nvidia.py +0 -0
  299. {agno-2.4.2 → agno-2.4.4}/agno/models/ollama/__init__.py +0 -0
  300. {agno-2.4.2 → agno-2.4.4}/agno/models/ollama/chat.py +0 -0
  301. {agno-2.4.2 → agno-2.4.4}/agno/models/ollama/responses.py +0 -0
  302. {agno-2.4.2 → agno-2.4.4}/agno/models/openai/__init__.py +0 -0
  303. {agno-2.4.2 → agno-2.4.4}/agno/models/openai/chat.py +0 -0
  304. {agno-2.4.2 → agno-2.4.4}/agno/models/openai/like.py +0 -0
  305. {agno-2.4.2 → agno-2.4.4}/agno/models/openai/open_responses.py +0 -0
  306. {agno-2.4.2 → agno-2.4.4}/agno/models/openai/responses.py +0 -0
  307. {agno-2.4.2 → agno-2.4.4}/agno/models/openrouter/__init__.py +0 -0
  308. {agno-2.4.2 → agno-2.4.4}/agno/models/openrouter/openrouter.py +0 -0
  309. {agno-2.4.2 → agno-2.4.4}/agno/models/perplexity/__init__.py +0 -0
  310. {agno-2.4.2 → agno-2.4.4}/agno/models/perplexity/perplexity.py +0 -0
  311. {agno-2.4.2 → agno-2.4.4}/agno/models/portkey/__init__.py +0 -0
  312. {agno-2.4.2 → agno-2.4.4}/agno/models/portkey/portkey.py +0 -0
  313. {agno-2.4.2 → agno-2.4.4}/agno/models/requesty/__init__.py +0 -0
  314. {agno-2.4.2 → agno-2.4.4}/agno/models/requesty/requesty.py +0 -0
  315. {agno-2.4.2 → agno-2.4.4}/agno/models/sambanova/__init__.py +0 -0
  316. {agno-2.4.2 → agno-2.4.4}/agno/models/sambanova/sambanova.py +0 -0
  317. {agno-2.4.2 → agno-2.4.4}/agno/models/siliconflow/__init__.py +0 -0
  318. {agno-2.4.2 → agno-2.4.4}/agno/models/siliconflow/siliconflow.py +0 -0
  319. {agno-2.4.2 → agno-2.4.4}/agno/models/together/__init__.py +0 -0
  320. {agno-2.4.2 → agno-2.4.4}/agno/models/together/together.py +0 -0
  321. {agno-2.4.2 → agno-2.4.4}/agno/models/vercel/__init__.py +0 -0
  322. {agno-2.4.2 → agno-2.4.4}/agno/models/vercel/v0.py +0 -0
  323. {agno-2.4.2 → agno-2.4.4}/agno/models/vertexai/__init__.py +0 -0
  324. {agno-2.4.2 → agno-2.4.4}/agno/models/vertexai/claude.py +0 -0
  325. {agno-2.4.2 → agno-2.4.4}/agno/models/vllm/__init__.py +0 -0
  326. {agno-2.4.2 → agno-2.4.4}/agno/models/vllm/vllm.py +0 -0
  327. {agno-2.4.2 → agno-2.4.4}/agno/models/xai/__init__.py +0 -0
  328. {agno-2.4.2 → agno-2.4.4}/agno/models/xai/xai.py +0 -0
  329. {agno-2.4.2 → agno-2.4.4}/agno/os/__init__.py +0 -0
  330. {agno-2.4.2 → agno-2.4.4}/agno/os/app.py +0 -0
  331. {agno-2.4.2 → agno-2.4.4}/agno/os/auth.py +0 -0
  332. {agno-2.4.2 → agno-2.4.4}/agno/os/config.py +0 -0
  333. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/__init__.py +0 -0
  334. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/a2a/__init__.py +0 -0
  335. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/a2a/a2a.py +0 -0
  336. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/a2a/router.py +0 -0
  337. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/a2a/utils.py +0 -0
  338. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/agui/__init__.py +0 -0
  339. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/agui/agui.py +0 -0
  340. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/agui/router.py +0 -0
  341. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/agui/utils.py +0 -0
  342. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/base.py +0 -0
  343. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/slack/__init__.py +0 -0
  344. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/slack/router.py +0 -0
  345. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/slack/security.py +0 -0
  346. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/slack/slack.py +0 -0
  347. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/whatsapp/__init__.py +0 -0
  348. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/whatsapp/router.py +0 -0
  349. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/whatsapp/security.py +0 -0
  350. {agno-2.4.2 → agno-2.4.4}/agno/os/interfaces/whatsapp/whatsapp.py +0 -0
  351. {agno-2.4.2 → agno-2.4.4}/agno/os/managers.py +0 -0
  352. {agno-2.4.2 → agno-2.4.4}/agno/os/mcp.py +0 -0
  353. {agno-2.4.2 → agno-2.4.4}/agno/os/middleware/__init__.py +0 -0
  354. {agno-2.4.2 → agno-2.4.4}/agno/os/middleware/jwt.py +0 -0
  355. {agno-2.4.2 → agno-2.4.4}/agno/os/middleware/trailing_slash.py +0 -0
  356. {agno-2.4.2 → agno-2.4.4}/agno/os/router.py +0 -0
  357. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/__init__.py +0 -0
  358. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/agents/__init__.py +0 -0
  359. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/agents/router.py +0 -0
  360. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/agents/schema.py +0 -0
  361. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/components/__init__.py +0 -0
  362. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/components/components.py +0 -0
  363. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/database.py +0 -0
  364. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/evals/__init__.py +0 -0
  365. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/evals/evals.py +0 -0
  366. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/evals/schemas.py +0 -0
  367. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/evals/utils.py +0 -0
  368. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/health.py +0 -0
  369. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/home.py +0 -0
  370. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/knowledge/__init__.py +0 -0
  371. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/knowledge/schemas.py +0 -0
  372. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/memory/__init__.py +0 -0
  373. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/memory/memory.py +0 -0
  374. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/memory/schemas.py +0 -0
  375. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/metrics/__init__.py +0 -0
  376. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/metrics/metrics.py +0 -0
  377. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/metrics/schemas.py +0 -0
  378. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/registry/__init__.py +0 -0
  379. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/registry/registry.py +0 -0
  380. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/session/__init__.py +0 -0
  381. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/session/session.py +0 -0
  382. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/teams/__init__.py +0 -0
  383. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/teams/router.py +0 -0
  384. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/teams/schema.py +0 -0
  385. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/traces/__init__.py +0 -0
  386. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/traces/schemas.py +0 -0
  387. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/traces/traces.py +0 -0
  388. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/workflows/__init__.py +0 -0
  389. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/workflows/router.py +0 -0
  390. {agno-2.4.2 → agno-2.4.4}/agno/os/routers/workflows/schema.py +0 -0
  391. {agno-2.4.2 → agno-2.4.4}/agno/os/schema.py +0 -0
  392. {agno-2.4.2 → agno-2.4.4}/agno/os/scopes.py +0 -0
  393. {agno-2.4.2 → agno-2.4.4}/agno/os/settings.py +0 -0
  394. {agno-2.4.2 → agno-2.4.4}/agno/os/utils.py +0 -0
  395. {agno-2.4.2 → agno-2.4.4}/agno/py.typed +0 -0
  396. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/__init__.py +0 -0
  397. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/anthropic.py +0 -0
  398. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/azure_ai_foundry.py +0 -0
  399. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/deepseek.py +0 -0
  400. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/default.py +0 -0
  401. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/gemini.py +0 -0
  402. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/groq.py +0 -0
  403. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/helpers.py +0 -0
  404. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/manager.py +0 -0
  405. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/ollama.py +0 -0
  406. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/openai.py +0 -0
  407. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/step.py +0 -0
  408. {agno-2.4.2 → agno-2.4.4}/agno/reasoning/vertexai.py +0 -0
  409. {agno-2.4.2 → agno-2.4.4}/agno/registry/__init__.py +0 -0
  410. {agno-2.4.2 → agno-2.4.4}/agno/registry/registry.py +0 -0
  411. {agno-2.4.2 → agno-2.4.4}/agno/remote/__init__.py +0 -0
  412. {agno-2.4.2 → agno-2.4.4}/agno/remote/base.py +0 -0
  413. {agno-2.4.2 → agno-2.4.4}/agno/run/__init__.py +0 -0
  414. {agno-2.4.2 → agno-2.4.4}/agno/run/agent.py +0 -0
  415. {agno-2.4.2 → agno-2.4.4}/agno/run/cancel.py +0 -0
  416. {agno-2.4.2 → agno-2.4.4}/agno/run/cancellation_management/__init__.py +0 -0
  417. {agno-2.4.2 → agno-2.4.4}/agno/run/cancellation_management/base.py +0 -0
  418. {agno-2.4.2 → agno-2.4.4}/agno/run/cancellation_management/in_memory_cancellation_manager.py +0 -0
  419. {agno-2.4.2 → agno-2.4.4}/agno/run/cancellation_management/redis_cancellation_manager.py +0 -0
  420. {agno-2.4.2 → agno-2.4.4}/agno/run/messages.py +0 -0
  421. {agno-2.4.2 → agno-2.4.4}/agno/run/requirement.py +0 -0
  422. {agno-2.4.2 → agno-2.4.4}/agno/run/team.py +0 -0
  423. {agno-2.4.2 → agno-2.4.4}/agno/run/workflow.py +0 -0
  424. {agno-2.4.2 → agno-2.4.4}/agno/session/__init__.py +0 -0
  425. {agno-2.4.2 → agno-2.4.4}/agno/session/agent.py +0 -0
  426. {agno-2.4.2 → agno-2.4.4}/agno/session/summary.py +0 -0
  427. {agno-2.4.2 → agno-2.4.4}/agno/session/team.py +0 -0
  428. {agno-2.4.2 → agno-2.4.4}/agno/session/workflow.py +0 -0
  429. {agno-2.4.2 → agno-2.4.4}/agno/skills/__init__.py +0 -0
  430. {agno-2.4.2 → agno-2.4.4}/agno/skills/agent_skills.py +0 -0
  431. {agno-2.4.2 → agno-2.4.4}/agno/skills/errors.py +0 -0
  432. {agno-2.4.2 → agno-2.4.4}/agno/skills/loaders/__init__.py +0 -0
  433. {agno-2.4.2 → agno-2.4.4}/agno/skills/loaders/base.py +0 -0
  434. {agno-2.4.2 → agno-2.4.4}/agno/skills/loaders/local.py +0 -0
  435. {agno-2.4.2 → agno-2.4.4}/agno/skills/skill.py +0 -0
  436. {agno-2.4.2 → agno-2.4.4}/agno/skills/utils.py +0 -0
  437. {agno-2.4.2 → agno-2.4.4}/agno/skills/validator.py +0 -0
  438. {agno-2.4.2 → agno-2.4.4}/agno/table.py +0 -0
  439. {agno-2.4.2 → agno-2.4.4}/agno/team/__init__.py +0 -0
  440. {agno-2.4.2 → agno-2.4.4}/agno/team/remote.py +0 -0
  441. {agno-2.4.2 → agno-2.4.4}/agno/team/team.py +0 -0
  442. {agno-2.4.2 → agno-2.4.4}/agno/tools/__init__.py +0 -0
  443. {agno-2.4.2 → agno-2.4.4}/agno/tools/agentql.py +0 -0
  444. {agno-2.4.2 → agno-2.4.4}/agno/tools/airflow.py +0 -0
  445. {agno-2.4.2 → agno-2.4.4}/agno/tools/api.py +0 -0
  446. {agno-2.4.2 → agno-2.4.4}/agno/tools/apify.py +0 -0
  447. {agno-2.4.2 → agno-2.4.4}/agno/tools/arxiv.py +0 -0
  448. {agno-2.4.2 → agno-2.4.4}/agno/tools/aws_lambda.py +0 -0
  449. {agno-2.4.2 → agno-2.4.4}/agno/tools/aws_ses.py +0 -0
  450. {agno-2.4.2 → agno-2.4.4}/agno/tools/baidusearch.py +0 -0
  451. {agno-2.4.2 → agno-2.4.4}/agno/tools/bitbucket.py +0 -0
  452. {agno-2.4.2 → agno-2.4.4}/agno/tools/brandfetch.py +0 -0
  453. {agno-2.4.2 → agno-2.4.4}/agno/tools/bravesearch.py +0 -0
  454. {agno-2.4.2 → agno-2.4.4}/agno/tools/brightdata.py +0 -0
  455. {agno-2.4.2 → agno-2.4.4}/agno/tools/browserbase.py +0 -0
  456. {agno-2.4.2 → agno-2.4.4}/agno/tools/calcom.py +0 -0
  457. {agno-2.4.2 → agno-2.4.4}/agno/tools/calculator.py +0 -0
  458. {agno-2.4.2 → agno-2.4.4}/agno/tools/cartesia.py +0 -0
  459. {agno-2.4.2 → agno-2.4.4}/agno/tools/clickup.py +0 -0
  460. {agno-2.4.2 → agno-2.4.4}/agno/tools/confluence.py +0 -0
  461. {agno-2.4.2 → agno-2.4.4}/agno/tools/crawl4ai.py +0 -0
  462. {agno-2.4.2 → agno-2.4.4}/agno/tools/csv_toolkit.py +0 -0
  463. {agno-2.4.2 → agno-2.4.4}/agno/tools/dalle.py +0 -0
  464. {agno-2.4.2 → agno-2.4.4}/agno/tools/daytona.py +0 -0
  465. {agno-2.4.2 → agno-2.4.4}/agno/tools/desi_vocal.py +0 -0
  466. {agno-2.4.2 → agno-2.4.4}/agno/tools/discord.py +0 -0
  467. {agno-2.4.2 → agno-2.4.4}/agno/tools/docker.py +0 -0
  468. {agno-2.4.2 → agno-2.4.4}/agno/tools/duckdb.py +0 -0
  469. {agno-2.4.2 → agno-2.4.4}/agno/tools/duckduckgo.py +0 -0
  470. {agno-2.4.2 → agno-2.4.4}/agno/tools/e2b.py +0 -0
  471. {agno-2.4.2 → agno-2.4.4}/agno/tools/eleven_labs.py +0 -0
  472. {agno-2.4.2 → agno-2.4.4}/agno/tools/email.py +0 -0
  473. {agno-2.4.2 → agno-2.4.4}/agno/tools/evm.py +0 -0
  474. {agno-2.4.2 → agno-2.4.4}/agno/tools/exa.py +0 -0
  475. {agno-2.4.2 → agno-2.4.4}/agno/tools/fal.py +0 -0
  476. {agno-2.4.2 → agno-2.4.4}/agno/tools/file.py +0 -0
  477. {agno-2.4.2 → agno-2.4.4}/agno/tools/file_generation.py +0 -0
  478. {agno-2.4.2 → agno-2.4.4}/agno/tools/financial_datasets.py +0 -0
  479. {agno-2.4.2 → agno-2.4.4}/agno/tools/firecrawl.py +0 -0
  480. {agno-2.4.2 → agno-2.4.4}/agno/tools/giphy.py +0 -0
  481. {agno-2.4.2 → agno-2.4.4}/agno/tools/github.py +0 -0
  482. {agno-2.4.2 → agno-2.4.4}/agno/tools/gmail.py +0 -0
  483. {agno-2.4.2 → agno-2.4.4}/agno/tools/google_bigquery.py +0 -0
  484. {agno-2.4.2 → agno-2.4.4}/agno/tools/google_drive.py +0 -0
  485. {agno-2.4.2 → agno-2.4.4}/agno/tools/google_maps.py +0 -0
  486. {agno-2.4.2 → agno-2.4.4}/agno/tools/googlecalendar.py +0 -0
  487. {agno-2.4.2 → agno-2.4.4}/agno/tools/googlesheets.py +0 -0
  488. {agno-2.4.2 → agno-2.4.4}/agno/tools/hackernews.py +0 -0
  489. {agno-2.4.2 → agno-2.4.4}/agno/tools/jina.py +0 -0
  490. {agno-2.4.2 → agno-2.4.4}/agno/tools/jira.py +0 -0
  491. {agno-2.4.2 → agno-2.4.4}/agno/tools/knowledge.py +0 -0
  492. {agno-2.4.2 → agno-2.4.4}/agno/tools/linear.py +0 -0
  493. {agno-2.4.2 → agno-2.4.4}/agno/tools/linkup.py +0 -0
  494. {agno-2.4.2 → agno-2.4.4}/agno/tools/local_file_system.py +0 -0
  495. {agno-2.4.2 → agno-2.4.4}/agno/tools/lumalab.py +0 -0
  496. {agno-2.4.2 → agno-2.4.4}/agno/tools/mcp/__init__.py +0 -0
  497. {agno-2.4.2 → agno-2.4.4}/agno/tools/mcp/mcp.py +0 -0
  498. {agno-2.4.2 → agno-2.4.4}/agno/tools/mcp/multi_mcp.py +0 -0
  499. {agno-2.4.2 → agno-2.4.4}/agno/tools/mcp/params.py +0 -0
  500. {agno-2.4.2 → agno-2.4.4}/agno/tools/mcp_toolbox.py +0 -0
  501. {agno-2.4.2 → agno-2.4.4}/agno/tools/mem0.py +0 -0
  502. {agno-2.4.2 → agno-2.4.4}/agno/tools/memory.py +0 -0
  503. {agno-2.4.2 → agno-2.4.4}/agno/tools/mlx_transcribe.py +0 -0
  504. {agno-2.4.2 → agno-2.4.4}/agno/tools/models/__init__.py +0 -0
  505. {agno-2.4.2 → agno-2.4.4}/agno/tools/models/azure_openai.py +0 -0
  506. {agno-2.4.2 → agno-2.4.4}/agno/tools/models/gemini.py +0 -0
  507. {agno-2.4.2 → agno-2.4.4}/agno/tools/models/groq.py +0 -0
  508. {agno-2.4.2 → agno-2.4.4}/agno/tools/models/morph.py +0 -0
  509. {agno-2.4.2 → agno-2.4.4}/agno/tools/models/nebius.py +0 -0
  510. {agno-2.4.2 → agno-2.4.4}/agno/tools/models_labs.py +0 -0
  511. {agno-2.4.2 → agno-2.4.4}/agno/tools/moviepy_video.py +0 -0
  512. {agno-2.4.2 → agno-2.4.4}/agno/tools/nano_banana.py +0 -0
  513. {agno-2.4.2 → agno-2.4.4}/agno/tools/neo4j.py +0 -0
  514. {agno-2.4.2 → agno-2.4.4}/agno/tools/newspaper.py +0 -0
  515. {agno-2.4.2 → agno-2.4.4}/agno/tools/newspaper4k.py +0 -0
  516. {agno-2.4.2 → agno-2.4.4}/agno/tools/notion.py +0 -0
  517. {agno-2.4.2 → agno-2.4.4}/agno/tools/openai.py +0 -0
  518. {agno-2.4.2 → agno-2.4.4}/agno/tools/openbb.py +0 -0
  519. {agno-2.4.2 → agno-2.4.4}/agno/tools/opencv.py +0 -0
  520. {agno-2.4.2 → agno-2.4.4}/agno/tools/openweather.py +0 -0
  521. {agno-2.4.2 → agno-2.4.4}/agno/tools/oxylabs.py +0 -0
  522. {agno-2.4.2 → agno-2.4.4}/agno/tools/pandas.py +0 -0
  523. {agno-2.4.2 → agno-2.4.4}/agno/tools/parallel.py +0 -0
  524. {agno-2.4.2 → agno-2.4.4}/agno/tools/postgres.py +0 -0
  525. {agno-2.4.2 → agno-2.4.4}/agno/tools/pubmed.py +0 -0
  526. {agno-2.4.2 → agno-2.4.4}/agno/tools/python.py +0 -0
  527. {agno-2.4.2 → agno-2.4.4}/agno/tools/reasoning.py +0 -0
  528. {agno-2.4.2 → agno-2.4.4}/agno/tools/reddit.py +0 -0
  529. {agno-2.4.2 → agno-2.4.4}/agno/tools/redshift.py +0 -0
  530. {agno-2.4.2 → agno-2.4.4}/agno/tools/replicate.py +0 -0
  531. {agno-2.4.2 → agno-2.4.4}/agno/tools/resend.py +0 -0
  532. {agno-2.4.2 → agno-2.4.4}/agno/tools/scrapegraph.py +0 -0
  533. {agno-2.4.2 → agno-2.4.4}/agno/tools/searxng.py +0 -0
  534. {agno-2.4.2 → agno-2.4.4}/agno/tools/serpapi.py +0 -0
  535. {agno-2.4.2 → agno-2.4.4}/agno/tools/serper.py +0 -0
  536. {agno-2.4.2 → agno-2.4.4}/agno/tools/shell.py +0 -0
  537. {agno-2.4.2 → agno-2.4.4}/agno/tools/shopify.py +0 -0
  538. {agno-2.4.2 → agno-2.4.4}/agno/tools/slack.py +0 -0
  539. {agno-2.4.2 → agno-2.4.4}/agno/tools/sleep.py +0 -0
  540. {agno-2.4.2 → agno-2.4.4}/agno/tools/spider.py +0 -0
  541. {agno-2.4.2 → agno-2.4.4}/agno/tools/spotify.py +0 -0
  542. {agno-2.4.2 → agno-2.4.4}/agno/tools/sql.py +0 -0
  543. {agno-2.4.2 → agno-2.4.4}/agno/tools/streamlit/__init__.py +0 -0
  544. {agno-2.4.2 → agno-2.4.4}/agno/tools/streamlit/components.py +0 -0
  545. {agno-2.4.2 → agno-2.4.4}/agno/tools/tavily.py +0 -0
  546. {agno-2.4.2 → agno-2.4.4}/agno/tools/telegram.py +0 -0
  547. {agno-2.4.2 → agno-2.4.4}/agno/tools/todoist.py +0 -0
  548. {agno-2.4.2 → agno-2.4.4}/agno/tools/tool_registry.py +0 -0
  549. {agno-2.4.2 → agno-2.4.4}/agno/tools/toolkit.py +0 -0
  550. {agno-2.4.2 → agno-2.4.4}/agno/tools/trafilatura.py +0 -0
  551. {agno-2.4.2 → agno-2.4.4}/agno/tools/trello.py +0 -0
  552. {agno-2.4.2 → agno-2.4.4}/agno/tools/twilio.py +0 -0
  553. {agno-2.4.2 → agno-2.4.4}/agno/tools/user_control_flow.py +0 -0
  554. {agno-2.4.2 → agno-2.4.4}/agno/tools/valyu.py +0 -0
  555. {agno-2.4.2 → agno-2.4.4}/agno/tools/visualization.py +0 -0
  556. {agno-2.4.2 → agno-2.4.4}/agno/tools/webbrowser.py +0 -0
  557. {agno-2.4.2 → agno-2.4.4}/agno/tools/webex.py +0 -0
  558. {agno-2.4.2 → agno-2.4.4}/agno/tools/websearch.py +0 -0
  559. {agno-2.4.2 → agno-2.4.4}/agno/tools/website.py +0 -0
  560. {agno-2.4.2 → agno-2.4.4}/agno/tools/webtools.py +0 -0
  561. {agno-2.4.2 → agno-2.4.4}/agno/tools/whatsapp.py +0 -0
  562. {agno-2.4.2 → agno-2.4.4}/agno/tools/wikipedia.py +0 -0
  563. {agno-2.4.2 → agno-2.4.4}/agno/tools/workflow.py +0 -0
  564. {agno-2.4.2 → agno-2.4.4}/agno/tools/x.py +0 -0
  565. {agno-2.4.2 → agno-2.4.4}/agno/tools/yfinance.py +0 -0
  566. {agno-2.4.2 → agno-2.4.4}/agno/tools/youtube.py +0 -0
  567. {agno-2.4.2 → agno-2.4.4}/agno/tools/zendesk.py +0 -0
  568. {agno-2.4.2 → agno-2.4.4}/agno/tools/zep.py +0 -0
  569. {agno-2.4.2 → agno-2.4.4}/agno/tools/zoom.py +0 -0
  570. {agno-2.4.2 → agno-2.4.4}/agno/tracing/__init__.py +0 -0
  571. {agno-2.4.2 → agno-2.4.4}/agno/tracing/exporter.py +0 -0
  572. {agno-2.4.2 → agno-2.4.4}/agno/tracing/schemas.py +0 -0
  573. {agno-2.4.2 → agno-2.4.4}/agno/tracing/setup.py +0 -0
  574. {agno-2.4.2 → agno-2.4.4}/agno/utils/__init__.py +0 -0
  575. {agno-2.4.2 → agno-2.4.4}/agno/utils/agent.py +0 -0
  576. {agno-2.4.2 → agno-2.4.4}/agno/utils/audio.py +0 -0
  577. {agno-2.4.2 → agno-2.4.4}/agno/utils/certs.py +0 -0
  578. {agno-2.4.2 → agno-2.4.4}/agno/utils/code_execution.py +0 -0
  579. {agno-2.4.2 → agno-2.4.4}/agno/utils/common.py +0 -0
  580. {agno-2.4.2 → agno-2.4.4}/agno/utils/cryptography.py +0 -0
  581. {agno-2.4.2 → agno-2.4.4}/agno/utils/dttm.py +0 -0
  582. {agno-2.4.2 → agno-2.4.4}/agno/utils/enum.py +0 -0
  583. {agno-2.4.2 → agno-2.4.4}/agno/utils/env.py +0 -0
  584. {agno-2.4.2 → agno-2.4.4}/agno/utils/events.py +0 -0
  585. {agno-2.4.2 → agno-2.4.4}/agno/utils/format_str.py +0 -0
  586. {agno-2.4.2 → agno-2.4.4}/agno/utils/functions.py +0 -0
  587. {agno-2.4.2 → agno-2.4.4}/agno/utils/gemini.py +0 -0
  588. {agno-2.4.2 → agno-2.4.4}/agno/utils/hooks.py +0 -0
  589. {agno-2.4.2 → agno-2.4.4}/agno/utils/http.py +0 -0
  590. {agno-2.4.2 → agno-2.4.4}/agno/utils/json_schema.py +0 -0
  591. {agno-2.4.2 → agno-2.4.4}/agno/utils/knowledge.py +0 -0
  592. {agno-2.4.2 → agno-2.4.4}/agno/utils/location.py +0 -0
  593. {agno-2.4.2 → agno-2.4.4}/agno/utils/log.py +0 -0
  594. {agno-2.4.2 → agno-2.4.4}/agno/utils/mcp.py +0 -0
  595. {agno-2.4.2 → agno-2.4.4}/agno/utils/media.py +0 -0
  596. {agno-2.4.2 → agno-2.4.4}/agno/utils/merge_dict.py +0 -0
  597. {agno-2.4.2 → agno-2.4.4}/agno/utils/message.py +0 -0
  598. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/__init__.py +0 -0
  599. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/ai_foundry.py +0 -0
  600. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/claude.py +0 -0
  601. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/cohere.py +0 -0
  602. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/llama.py +0 -0
  603. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/mistral.py +0 -0
  604. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/openai_responses.py +0 -0
  605. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/schema_utils.py +0 -0
  606. {agno-2.4.2 → agno-2.4.4}/agno/utils/models/watsonx.py +0 -0
  607. {agno-2.4.2 → agno-2.4.4}/agno/utils/openai.py +0 -0
  608. {agno-2.4.2 → agno-2.4.4}/agno/utils/os.py +0 -0
  609. {agno-2.4.2 → agno-2.4.4}/agno/utils/pickle.py +0 -0
  610. {agno-2.4.2 → agno-2.4.4}/agno/utils/pprint.py +0 -0
  611. {agno-2.4.2 → agno-2.4.4}/agno/utils/print_response/__init__.py +0 -0
  612. {agno-2.4.2 → agno-2.4.4}/agno/utils/print_response/team.py +0 -0
  613. {agno-2.4.2 → agno-2.4.4}/agno/utils/print_response/workflow.py +0 -0
  614. {agno-2.4.2 → agno-2.4.4}/agno/utils/prompts.py +0 -0
  615. {agno-2.4.2 → agno-2.4.4}/agno/utils/reasoning.py +0 -0
  616. {agno-2.4.2 → agno-2.4.4}/agno/utils/remote.py +0 -0
  617. {agno-2.4.2 → agno-2.4.4}/agno/utils/response_iterator.py +0 -0
  618. {agno-2.4.2 → agno-2.4.4}/agno/utils/safe_formatter.py +0 -0
  619. {agno-2.4.2 → agno-2.4.4}/agno/utils/serialize.py +0 -0
  620. {agno-2.4.2 → agno-2.4.4}/agno/utils/shell.py +0 -0
  621. {agno-2.4.2 → agno-2.4.4}/agno/utils/streamlit.py +0 -0
  622. {agno-2.4.2 → agno-2.4.4}/agno/utils/team.py +0 -0
  623. {agno-2.4.2 → agno-2.4.4}/agno/utils/timer.py +0 -0
  624. {agno-2.4.2 → agno-2.4.4}/agno/utils/tokens.py +0 -0
  625. {agno-2.4.2 → agno-2.4.4}/agno/utils/tools.py +0 -0
  626. {agno-2.4.2 → agno-2.4.4}/agno/utils/web.py +0 -0
  627. {agno-2.4.2 → agno-2.4.4}/agno/utils/whatsapp.py +0 -0
  628. {agno-2.4.2 → agno-2.4.4}/agno/utils/yaml_io.py +0 -0
  629. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/__init__.py +0 -0
  630. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/base.py +0 -0
  631. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/cassandra/__init__.py +0 -0
  632. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/cassandra/cassandra.py +0 -0
  633. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
  634. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/cassandra/index.py +0 -0
  635. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/chroma/__init__.py +0 -0
  636. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/chroma/chromadb.py +0 -0
  637. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/clickhouse/__init__.py +0 -0
  638. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
  639. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/clickhouse/index.py +0 -0
  640. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/couchbase/__init__.py +0 -0
  641. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/couchbase/couchbase.py +0 -0
  642. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/distance.py +0 -0
  643. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/lancedb/__init__.py +0 -0
  644. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/langchaindb/__init__.py +0 -0
  645. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/langchaindb/langchaindb.py +0 -0
  646. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/lightrag/__init__.py +0 -0
  647. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/lightrag/lightrag.py +0 -0
  648. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/llamaindex/__init__.py +0 -0
  649. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/llamaindex/llamaindexdb.py +0 -0
  650. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/milvus/__init__.py +0 -0
  651. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/milvus/milvus.py +0 -0
  652. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/mongodb/__init__.py +0 -0
  653. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/mongodb/mongodb.py +0 -0
  654. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/pgvector/__init__.py +0 -0
  655. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/pgvector/index.py +0 -0
  656. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/pgvector/pgvector.py +0 -0
  657. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/pineconedb/__init__.py +0 -0
  658. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/pineconedb/pineconedb.py +0 -0
  659. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/qdrant/__init__.py +0 -0
  660. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/qdrant/qdrant.py +0 -0
  661. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/redis/__init__.py +0 -0
  662. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/redis/redisdb.py +0 -0
  663. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/search.py +0 -0
  664. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/singlestore/__init__.py +0 -0
  665. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/singlestore/index.py +0 -0
  666. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/singlestore/singlestore.py +0 -0
  667. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/surrealdb/__init__.py +0 -0
  668. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/surrealdb/surrealdb.py +0 -0
  669. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/upstashdb/__init__.py +0 -0
  670. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/upstashdb/upstashdb.py +0 -0
  671. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/weaviate/__init__.py +0 -0
  672. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/weaviate/index.py +0 -0
  673. {agno-2.4.2 → agno-2.4.4}/agno/vectordb/weaviate/weaviate.py +0 -0
  674. {agno-2.4.2 → agno-2.4.4}/agno/workflow/__init__.py +0 -0
  675. {agno-2.4.2 → agno-2.4.4}/agno/workflow/agent.py +0 -0
  676. {agno-2.4.2 → agno-2.4.4}/agno/workflow/condition.py +0 -0
  677. {agno-2.4.2 → agno-2.4.4}/agno/workflow/loop.py +0 -0
  678. {agno-2.4.2 → agno-2.4.4}/agno/workflow/parallel.py +0 -0
  679. {agno-2.4.2 → agno-2.4.4}/agno/workflow/remote.py +0 -0
  680. {agno-2.4.2 → agno-2.4.4}/agno/workflow/router.py +0 -0
  681. {agno-2.4.2 → agno-2.4.4}/agno/workflow/step.py +0 -0
  682. {agno-2.4.2 → agno-2.4.4}/agno/workflow/steps.py +0 -0
  683. {agno-2.4.2 → agno-2.4.4}/agno/workflow/types.py +0 -0
  684. {agno-2.4.2 → agno-2.4.4}/agno.egg-info/dependency_links.txt +0 -0
  685. {agno-2.4.2 → agno-2.4.4}/agno.egg-info/top_level.txt +0 -0
  686. {agno-2.4.2 → agno-2.4.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.4.2
3
+ Version: 2.4.4
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
@@ -260,8 +260,9 @@ Provides-Extra: text
260
260
  Requires-Dist: aiofiles; extra == "text"
261
261
  Provides-Extra: csv
262
262
  Requires-Dist: aiofiles; extra == "csv"
263
- Requires-Dist: openpyxl; extra == "csv"
264
- Requires-Dist: xlrd; extra == "csv"
263
+ Provides-Extra: excel
264
+ Requires-Dist: openpyxl; extra == "excel"
265
+ Requires-Dist: xlrd; extra == "excel"
265
266
  Provides-Extra: markdown
266
267
  Requires-Dist: unstructured; extra == "markdown"
267
268
  Requires-Dist: markdown; extra == "markdown"
@@ -376,6 +377,7 @@ Requires-Dist: agno[docx]; extra == "knowledge"
376
377
  Requires-Dist: agno[pptx]; extra == "knowledge"
377
378
  Requires-Dist: agno[text]; extra == "knowledge"
378
379
  Requires-Dist: agno[csv]; extra == "knowledge"
380
+ Requires-Dist: agno[excel]; extra == "knowledge"
379
381
  Requires-Dist: agno[markdown]; extra == "knowledge"
380
382
  Requires-Dist: agno[chonkie]; extra == "knowledge"
381
383
  Provides-Extra: embedders
@@ -450,7 +452,7 @@ Dynamic: license-file
450
452
  <span>&nbsp;•&nbsp;</span>
451
453
  <a href="https://community.agno.com/">Community</a>
452
454
  <span>&nbsp;•&nbsp;</span>
453
- <a href="https://discord.gg/4MtYHHrgA8">Discord</a>
455
+ <a href="https://www.agno.com/discord">Discord</a>
454
456
  </div>
455
457
 
456
458
  ## What is Agno?
@@ -529,7 +531,7 @@ https://github.com/user-attachments/assets/feb23db8-15cc-4e88-be7c-01a21a03ebf6
529
531
 
530
532
  ## Getting Started
531
533
 
532
- 1. Follow the [getting started guide](https://github.com/agno-agi/agno/tree/main/cookbook/00_getting_started)
534
+ 1. Follow the [quickstart guide](https://github.com/agno-agi/agno/tree/main/cookbook/00_quickstart)
533
535
  2. Browse the [cookbook](https://github.com/agno-agi/agno/tree/main/cookbook) for real-world examples
534
536
  3. Read the [docs](https://docs.agno.com) to go deeper
535
537
 
@@ -19,7 +19,7 @@
19
19
  <span>&nbsp;•&nbsp;</span>
20
20
  <a href="https://community.agno.com/">Community</a>
21
21
  <span>&nbsp;•&nbsp;</span>
22
- <a href="https://discord.gg/4MtYHHrgA8">Discord</a>
22
+ <a href="https://www.agno.com/discord">Discord</a>
23
23
  </div>
24
24
 
25
25
  ## What is Agno?
@@ -98,7 +98,7 @@ https://github.com/user-attachments/assets/feb23db8-15cc-4e88-be7c-01a21a03ebf6
98
98
 
99
99
  ## Getting Started
100
100
 
101
- 1. Follow the [getting started guide](https://github.com/agno-agi/agno/tree/main/cookbook/00_getting_started)
101
+ 1. Follow the [quickstart guide](https://github.com/agno-agi/agno/tree/main/cookbook/00_quickstart)
102
102
  2. Browse the [cookbook](https://github.com/agno-agi/agno/tree/main/cookbook) for real-world examples
103
103
  3. Read the [docs](https://docs.agno.com) to go deeper
104
104
 
@@ -5181,6 +5181,8 @@ class Agent:
5181
5181
  functions: Optional[Dict[str, Function]] = None,
5182
5182
  stream_events: bool = False,
5183
5183
  ) -> Iterator[RunOutputEvent]:
5184
+ from agno.run.agent import CustomEvent
5185
+
5184
5186
  self.model = cast(Model, self.model)
5185
5187
  # Execute the tool
5186
5188
  function_call = self.model.get_function_call_to_run_from_tool_execution(tool, functions)
@@ -5222,6 +5224,10 @@ class Agent:
5222
5224
  events_to_skip=self.events_to_skip, # type: ignore
5223
5225
  store_events=self.store_events,
5224
5226
  )
5227
+ # Yield CustomEvent instances from sync tool generators
5228
+ elif isinstance(call_result, CustomEvent):
5229
+ if stream_events:
5230
+ yield call_result # type: ignore
5225
5231
 
5226
5232
  if len(function_call_results) > 0:
5227
5233
  run_messages.messages.extend(function_call_results)
@@ -5246,6 +5252,8 @@ class Agent:
5246
5252
  functions: Optional[Dict[str, Function]] = None,
5247
5253
  stream_events: bool = False,
5248
5254
  ) -> AsyncIterator[RunOutputEvent]:
5255
+ from agno.run.agent import CustomEvent
5256
+
5249
5257
  self.model = cast(Model, self.model)
5250
5258
 
5251
5259
  # Execute the tool
@@ -5288,6 +5296,11 @@ class Agent:
5288
5296
  events_to_skip=self.events_to_skip, # type: ignore
5289
5297
  store_events=self.store_events,
5290
5298
  )
5299
+ # Yield CustomEvent instances from async tool generators
5300
+ elif isinstance(call_result, CustomEvent):
5301
+ if stream_events:
5302
+ yield call_result # type: ignore
5303
+
5291
5304
  if len(function_call_results) > 0:
5292
5305
  run_messages.messages.extend(function_call_results)
5293
5306
 
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import time
3
3
  from datetime import date, datetime, timedelta, timezone
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
4
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union, cast
5
5
  from uuid import uuid4
6
6
 
7
7
  if TYPE_CHECKING:
@@ -25,7 +25,7 @@ from agno.db.schemas.culture import CulturalKnowledge
25
25
  from agno.db.schemas.evals import EvalFilterType, EvalRunRecord, EvalType
26
26
  from agno.db.schemas.knowledge import KnowledgeRow
27
27
  from agno.db.schemas.memory import UserMemory
28
- from agno.db.utils import deserialize_session_json_fields, serialize_session_json_fields
28
+ from agno.db.utils import deserialize_session_json_fields
29
29
  from agno.session import AgentSession, Session, TeamSession, WorkflowSession
30
30
  from agno.utils.log import log_debug, log_error, log_info
31
31
  from agno.utils.string import generate_id
@@ -496,6 +496,29 @@ class FirestoreDb(BaseDb):
496
496
  if doc_ref is None:
497
497
  return None
498
498
 
499
+ # Check if session_data is stored as JSON string (legacy) or native map.
500
+ # Legacy sessions stored session_data as a JSON string, but Firestore's dot notation
501
+ # (e.g., "session_data.session_name") only works with native maps. Using dot notation
502
+ # on a JSON string overwrites the entire field, causing data loss.
503
+ # For legacy sessions, we use read-modify-write which also migrates them to native maps.
504
+ current_doc = doc_ref.get()
505
+ if not current_doc.exists:
506
+ return None
507
+
508
+ current_data = current_doc.to_dict()
509
+ session_data = current_data.get("session_data") if current_data else None
510
+
511
+ if session_data is None or isinstance(session_data, str):
512
+ existing_session = self.get_session(session_id, session_type, deserialize=True)
513
+ if existing_session is None:
514
+ return None
515
+ existing_session = cast(Session, existing_session)
516
+ if existing_session.session_data is None:
517
+ existing_session.session_data = {}
518
+ existing_session.session_data["session_name"] = session_name
519
+ return self.upsert_session(existing_session, deserialize=deserialize)
520
+
521
+ # Native map format - use efficient dot notation update
499
522
  doc_ref.update({"session_data.session_name": session_name, "updated_at": int(time.time())})
500
523
 
501
524
  updated_doc = doc_ref.get()
@@ -539,50 +562,50 @@ class FirestoreDb(BaseDb):
539
562
  """
540
563
  try:
541
564
  collection_ref = self._get_collection(table_type="sessions", create_collection_if_not_found=True)
542
- serialized_session_dict = serialize_session_json_fields(session.to_dict())
565
+ session_dict = session.to_dict()
543
566
 
544
567
  if isinstance(session, AgentSession):
545
568
  record = {
546
- "session_id": serialized_session_dict.get("session_id"),
569
+ "session_id": session_dict.get("session_id"),
547
570
  "session_type": SessionType.AGENT.value,
548
- "agent_id": serialized_session_dict.get("agent_id"),
549
- "user_id": serialized_session_dict.get("user_id"),
550
- "runs": serialized_session_dict.get("runs"),
551
- "agent_data": serialized_session_dict.get("agent_data"),
552
- "session_data": serialized_session_dict.get("session_data"),
553
- "summary": serialized_session_dict.get("summary"),
554
- "metadata": serialized_session_dict.get("metadata"),
555
- "created_at": serialized_session_dict.get("created_at"),
571
+ "agent_id": session_dict.get("agent_id"),
572
+ "user_id": session_dict.get("user_id"),
573
+ "runs": session_dict.get("runs"),
574
+ "agent_data": session_dict.get("agent_data"),
575
+ "session_data": session_dict.get("session_data"),
576
+ "summary": session_dict.get("summary"),
577
+ "metadata": session_dict.get("metadata"),
578
+ "created_at": session_dict.get("created_at"),
556
579
  "updated_at": int(time.time()),
557
580
  }
558
581
 
559
582
  elif isinstance(session, TeamSession):
560
583
  record = {
561
- "session_id": serialized_session_dict.get("session_id"),
584
+ "session_id": session_dict.get("session_id"),
562
585
  "session_type": SessionType.TEAM.value,
563
- "team_id": serialized_session_dict.get("team_id"),
564
- "user_id": serialized_session_dict.get("user_id"),
565
- "runs": serialized_session_dict.get("runs"),
566
- "team_data": serialized_session_dict.get("team_data"),
567
- "session_data": serialized_session_dict.get("session_data"),
568
- "summary": serialized_session_dict.get("summary"),
569
- "metadata": serialized_session_dict.get("metadata"),
570
- "created_at": serialized_session_dict.get("created_at"),
586
+ "team_id": session_dict.get("team_id"),
587
+ "user_id": session_dict.get("user_id"),
588
+ "runs": session_dict.get("runs"),
589
+ "team_data": session_dict.get("team_data"),
590
+ "session_data": session_dict.get("session_data"),
591
+ "summary": session_dict.get("summary"),
592
+ "metadata": session_dict.get("metadata"),
593
+ "created_at": session_dict.get("created_at"),
571
594
  "updated_at": int(time.time()),
572
595
  }
573
596
 
574
597
  elif isinstance(session, WorkflowSession):
575
598
  record = {
576
- "session_id": serialized_session_dict.get("session_id"),
599
+ "session_id": session_dict.get("session_id"),
577
600
  "session_type": SessionType.WORKFLOW.value,
578
- "workflow_id": serialized_session_dict.get("workflow_id"),
579
- "user_id": serialized_session_dict.get("user_id"),
580
- "runs": serialized_session_dict.get("runs"),
581
- "workflow_data": serialized_session_dict.get("workflow_data"),
582
- "session_data": serialized_session_dict.get("session_data"),
583
- "summary": serialized_session_dict.get("summary"),
584
- "metadata": serialized_session_dict.get("metadata"),
585
- "created_at": serialized_session_dict.get("created_at"),
601
+ "workflow_id": session_dict.get("workflow_id"),
602
+ "user_id": session_dict.get("user_id"),
603
+ "runs": session_dict.get("runs"),
604
+ "workflow_data": session_dict.get("workflow_data"),
605
+ "session_data": session_dict.get("session_data"),
606
+ "summary": session_dict.get("summary"),
607
+ "metadata": session_dict.get("metadata"),
608
+ "created_at": session_dict.get("created_at"),
586
609
  "updated_at": int(time.time()),
587
610
  }
588
611
 
@@ -292,25 +292,25 @@ def get_schema(table_type: TableType, table_name: str) -> str:
292
292
  elif table_type == "knowledge":
293
293
  return dedent(f"""
294
294
  {define_table}
295
- DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime VALUE time::now();
295
+ DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime DEFAULT time::now();
296
296
  DEFINE FIELD OVERWRITE updated_at ON {table_name} TYPE datetime VALUE time::now();
297
297
  """)
298
298
  elif table_type == "culture":
299
299
  return dedent(f"""
300
300
  {define_table}
301
- DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime VALUE time::now();
301
+ DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime DEFAULT time::now();
302
302
  DEFINE FIELD OVERWRITE updated_at ON {table_name} TYPE datetime VALUE time::now();
303
303
  """)
304
304
  elif table_type == "sessions":
305
305
  return dedent(f"""
306
306
  {define_table}
307
- DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime VALUE time::now();
307
+ DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime DEFAULT time::now();
308
308
  DEFINE FIELD OVERWRITE updated_at ON {table_name} TYPE datetime VALUE time::now();
309
309
  """)
310
310
  elif table_type == "traces":
311
311
  return dedent(f"""
312
312
  {define_table}
313
- DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime VALUE time::now();
313
+ DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime DEFAULT time::now();
314
314
  DEFINE INDEX idx_trace_id ON {table_name} FIELDS trace_id UNIQUE;
315
315
  DEFINE INDEX idx_run_id ON {table_name} FIELDS run_id;
316
316
  DEFINE INDEX idx_session_id ON {table_name} FIELDS session_id;
@@ -324,7 +324,7 @@ def get_schema(table_type: TableType, table_name: str) -> str:
324
324
  elif table_type == "spans":
325
325
  return dedent(f"""
326
326
  {define_table}
327
- DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime VALUE time::now();
327
+ DEFINE FIELD OVERWRITE created_at ON {table_name} TYPE datetime DEFAULT time::now();
328
328
  DEFINE INDEX idx_span_id ON {table_name} FIELDS span_id UNIQUE;
329
329
  DEFINE INDEX idx_trace_id ON {table_name} FIELDS trace_id;
330
330
  DEFINE INDEX idx_parent_span_id ON {table_name} FIELDS parent_span_id;
@@ -287,6 +287,7 @@ class SurrealDb(BaseDb):
287
287
  where = WhereClause()
288
288
  if user_id is not None:
289
289
  where = where.and_("user_id", user_id)
290
+
290
291
  where_clause, where_vars = where.build()
291
292
  query = dedent(f"""
292
293
  SELECT *
@@ -295,7 +296,18 @@ class SurrealDb(BaseDb):
295
296
  """)
296
297
  vars = {"record": record, **where_vars}
297
298
  raw = self._query_one(query, vars, dict)
298
- if raw is None or not deserialize:
299
+ if raw is None:
300
+ return None
301
+
302
+ # Verify session type matches
303
+ if session_type == SessionType.AGENT and raw.get("agent") is None:
304
+ return None
305
+ elif session_type == SessionType.TEAM and raw.get("team") is None:
306
+ return None
307
+ elif session_type == SessionType.WORKFLOW and raw.get("workflow") is None:
308
+ return None
309
+
310
+ if not deserialize:
299
311
  return raw
300
312
 
301
313
  return deserialize_session(session_type, raw)
@@ -37,6 +37,103 @@ class MarkdownChunking(ChunkingStrategy):
37
37
  if not (1 <= split_on_headings <= 6):
38
38
  raise ValueError("split_on_headings must be between 1 and 6 when using integer value")
39
39
 
40
+ def _split_large_section(self, section: str) -> List[str]:
41
+ """
42
+ Split a large section into smaller chunks while preserving the heading context.
43
+ Each sub-chunk will include the original heading for context.
44
+
45
+ Args:
46
+ section: The section content to split (may start with a heading)
47
+
48
+ Returns:
49
+ List of chunks, each respecting chunk_size
50
+ """
51
+ if len(section) <= self.chunk_size:
52
+ return [section]
53
+
54
+ # Extract heading and content from the section
55
+ lines = section.split("\n")
56
+ if lines and re.match(r"^#{1,6}\s+", lines[0]):
57
+ heading = lines[0]
58
+ content_lines = lines[1:]
59
+ else:
60
+ heading = ""
61
+ content_lines = lines
62
+
63
+ content = "\n".join(content_lines).strip()
64
+
65
+ # If just heading and small content, return as-is
66
+ if not content or len(section) <= self.chunk_size:
67
+ return [section]
68
+
69
+ # Split content by paragraphs
70
+ paragraphs = re.split(r"\n\n+", content)
71
+
72
+ chunks: List[str] = []
73
+ current_chunk_content: List[str] = []
74
+ # Account for heading size in each chunk
75
+ heading_size = len(heading) + 2 if heading else 0 # +2 for "\n\n"
76
+
77
+ for para in paragraphs:
78
+ para = para.strip()
79
+ if not para:
80
+ continue
81
+
82
+ current_size = sum(len(p) for p in current_chunk_content) + len(current_chunk_content) * 2 # \n\n
83
+ para_size = len(para)
84
+
85
+ # Check if adding this paragraph would exceed chunk_size
86
+ if current_chunk_content and (heading_size + current_size + para_size + 2) > self.chunk_size:
87
+ # Save current chunk
88
+ chunk_text = (
89
+ heading + "\n\n" + "\n\n".join(current_chunk_content)
90
+ if heading
91
+ else "\n\n".join(current_chunk_content)
92
+ )
93
+ chunks.append(chunk_text.strip())
94
+ current_chunk_content = []
95
+
96
+ # If single paragraph exceeds chunk_size, split it further
97
+ if para_size + heading_size > self.chunk_size:
98
+ # Save any accumulated content first
99
+ if current_chunk_content:
100
+ chunk_text = (
101
+ heading + "\n\n" + "\n\n".join(current_chunk_content)
102
+ if heading
103
+ else "\n\n".join(current_chunk_content)
104
+ )
105
+ chunks.append(chunk_text.strip())
106
+ current_chunk_content = []
107
+
108
+ # Split the large paragraph by sentences or fixed size
109
+ available_size = self.chunk_size - heading_size
110
+ words = para.split()
111
+ current_words: List[str] = []
112
+ current_word_len = 0
113
+
114
+ for word in words:
115
+ if current_word_len + len(word) + 1 > available_size and current_words:
116
+ chunk_text = heading + "\n\n" + " ".join(current_words) if heading else " ".join(current_words)
117
+ chunks.append(chunk_text.strip())
118
+ current_words = []
119
+ current_word_len = 0
120
+ current_words.append(word)
121
+ current_word_len += len(word) + 1
122
+
123
+ if current_words:
124
+ current_chunk_content.append(" ".join(current_words))
125
+ else:
126
+ current_chunk_content.append(para)
127
+
128
+ # add the remaining content
129
+ if current_chunk_content:
130
+ chunk_text = (
131
+ heading + "\n\n" + "\n\n".join(current_chunk_content) if heading else "\n\n".join(current_chunk_content)
132
+ )
133
+ chunks.append(chunk_text.strip())
134
+
135
+ return chunks if chunks else [section]
136
+
40
137
  def _split_by_headings(self, content: str) -> List[str]:
41
138
  """
42
139
  Split markdown content by headings, keeping each heading with its content.
@@ -163,18 +260,22 @@ class MarkdownChunking(ChunkingStrategy):
163
260
  section_size = len(section)
164
261
 
165
262
  # When split_on_headings is True or an int, each section becomes its own chunk
263
+ # But if section exceeds chunk_size, split it further
166
264
  if self.split_on_headings:
167
- meta_data = chunk_meta_data.copy()
168
- meta_data["chunk"] = chunk_number
169
- chunk_id = None
170
- if document.id:
171
- chunk_id = f"{document.id}_{chunk_number}"
172
- elif document.name:
173
- chunk_id = f"{document.name}_{chunk_number}"
174
- meta_data["chunk_size"] = section_size
175
-
176
- chunks.append(Document(id=chunk_id, name=document.name, meta_data=meta_data, content=section))
177
- chunk_number += 1
265
+ # Split large sections to respect chunk_size
266
+ sub_chunks = self._split_large_section(section)
267
+ for sub_chunk in sub_chunks:
268
+ meta_data = chunk_meta_data.copy()
269
+ meta_data["chunk"] = chunk_number
270
+ chunk_id = None
271
+ if document.id:
272
+ chunk_id = f"{document.id}_{chunk_number}"
273
+ elif document.name:
274
+ chunk_id = f"{document.name}_{chunk_number}"
275
+ meta_data["chunk_size"] = len(sub_chunk)
276
+
277
+ chunks.append(Document(id=chunk_id, name=document.name, meta_data=meta_data, content=sub_chunk))
278
+ chunk_number += 1
178
279
  elif current_size + section_size <= self.chunk_size:
179
280
  current_chunk.append(section)
180
281
  current_size += section_size
@@ -71,7 +71,8 @@ class OpenAIEmbedder(Embedder):
71
71
  }
72
72
  if self.user is not None:
73
73
  _request_params["user"] = self.user
74
- if self.id.startswith("text-embedding-3"):
74
+ # Pass dimensions for text-embedding-3 models or when using custom base_url (third-party APIs)
75
+ if self.id.startswith("text-embedding-3") or self.base_url is not None:
75
76
  _request_params["dimensions"] = self.dimensions
76
77
  if self.request_params:
77
78
  _request_params.update(self.request_params)
@@ -106,7 +107,8 @@ class OpenAIEmbedder(Embedder):
106
107
  }
107
108
  if self.user is not None:
108
109
  req["user"] = self.user
109
- if self.id.startswith("text-embedding-3"):
110
+ # Pass dimensions for text-embedding-3 models or when using custom base_url (third-party APIs)
111
+ if self.id.startswith("text-embedding-3") or self.base_url is not None:
110
112
  req["dimensions"] = self.dimensions
111
113
  if self.request_params:
112
114
  req.update(self.request_params)
@@ -126,7 +128,8 @@ class OpenAIEmbedder(Embedder):
126
128
  }
127
129
  if self.user is not None:
128
130
  req["user"] = self.user
129
- if self.id.startswith("text-embedding-3"):
131
+ # Pass dimensions for text-embedding-3 models or when using custom base_url (third-party APIs)
132
+ if self.id.startswith("text-embedding-3") or self.base_url is not None:
130
133
  req["dimensions"] = self.dimensions
131
134
  if self.request_params:
132
135
  req.update(self.request_params)
@@ -166,7 +169,8 @@ class OpenAIEmbedder(Embedder):
166
169
  }
167
170
  if self.user is not None:
168
171
  req["user"] = self.user
169
- if self.id.startswith("text-embedding-3"):
172
+ # Pass dimensions for text-embedding-3 models or when using custom base_url (third-party APIs)
173
+ if self.id.startswith("text-embedding-3") or self.base_url is not None:
170
174
  req["dimensions"] = self.dimensions
171
175
  if self.request_params:
172
176
  req.update(self.request_params)
@@ -983,6 +983,11 @@ class Knowledge:
983
983
  """CSV reader - lazy loaded via factory."""
984
984
  return self._get_reader("csv")
985
985
 
986
+ @property
987
+ def excel_reader(self) -> Optional[Reader]:
988
+ """Excel reader - lazy loaded via factory."""
989
+ return self._get_reader("excel")
990
+
986
991
  @property
987
992
  def docx_reader(self) -> Optional[Reader]:
988
993
  """Docx reader - lazy loaded via factory."""
@@ -1123,6 +1128,8 @@ class Knowledge:
1123
1128
  return self.json_reader, ""
1124
1129
  elif file_extension == ".markdown":
1125
1130
  return self.markdown_reader, ""
1131
+ elif file_extension in [".xlsx", ".xls"]:
1132
+ return self.excel_reader, ""
1126
1133
  else:
1127
1134
  return self.text_reader, ""
1128
1135
 
@@ -1153,6 +1160,8 @@ class Knowledge:
1153
1160
  return self.json_reader
1154
1161
  elif uri_lower.endswith(".markdown"):
1155
1162
  return self.markdown_reader
1163
+ elif uri_lower.endswith(".xlsx") or uri_lower.endswith(".xls"):
1164
+ return self.excel_reader
1156
1165
  else:
1157
1166
  return self.text_reader
1158
1167
 
@@ -1284,6 +1293,10 @@ class Knowledge:
1284
1293
  if self._should_include_file(str(path), include, exclude):
1285
1294
  log_debug(f"Adding file {path} due to include/exclude filters")
1286
1295
 
1296
+ # Set name from path if not provided
1297
+ if not content.name:
1298
+ content.name = path.name
1299
+
1287
1300
  await self._ainsert_contents_db(content)
1288
1301
  if self._should_skip(content.content_hash, skip_if_exists): # type: ignore[arg-type]
1289
1302
  content.status = ContentStatus.COMPLETED
@@ -1365,6 +1378,10 @@ class Knowledge:
1365
1378
  if self._should_include_file(str(path), include, exclude):
1366
1379
  log_debug(f"Adding file {path} due to include/exclude filters")
1367
1380
 
1381
+ # Set name from path if not provided
1382
+ if not content.name:
1383
+ content.name = path.name
1384
+
1368
1385
  self._insert_contents_db(content)
1369
1386
  if self._should_skip(content.content_hash, skip_if_exists): # type: ignore[arg-type]
1370
1387
  content.status = ContentStatus.COMPLETED
@@ -1450,6 +1467,14 @@ class Knowledge:
1450
1467
  if not content.url:
1451
1468
  raise ValueError("No url provided")
1452
1469
 
1470
+ # Set name from URL if not provided
1471
+ if not content.name and content.url:
1472
+ from urllib.parse import urlparse
1473
+
1474
+ parsed = urlparse(content.url)
1475
+ url_path = Path(parsed.path)
1476
+ content.name = url_path.name if url_path.name else content.url
1477
+
1453
1478
  # 1. Add content to contents database
1454
1479
  await self._ainsert_contents_db(content)
1455
1480
  if self._should_skip(content.content_hash, skip_if_exists): # type: ignore[arg-type]
@@ -1547,6 +1572,14 @@ class Knowledge:
1547
1572
  if not content.url:
1548
1573
  raise ValueError("No url provided")
1549
1574
 
1575
+ # Set name from URL if not provided
1576
+ if not content.name and content.url:
1577
+ from urllib.parse import urlparse
1578
+
1579
+ parsed = urlparse(content.url)
1580
+ url_path = Path(parsed.path)
1581
+ content.name = url_path.name if url_path.name else content.url
1582
+
1550
1583
  # 1. Add content to contents database
1551
1584
  self._insert_contents_db(content)
1552
1585
  if self._should_skip(content.content_hash, skip_if_exists): # type: ignore[arg-type]
@@ -1633,6 +1666,8 @@ class Knowledge:
1633
1666
 
1634
1667
  if content.name:
1635
1668
  name = content.name
1669
+ elif content.file_data and content.file_data.filename:
1670
+ name = content.file_data.filename
1636
1671
  elif content.file_data and content.file_data.content:
1637
1672
  if isinstance(content.file_data.content, bytes):
1638
1673
  name = content.file_data.content[:10].decode("utf-8", errors="ignore")
@@ -1696,9 +1731,17 @@ class Knowledge:
1696
1731
  log_debug(f"Using reader: {content.reader.__class__.__name__} to read content")
1697
1732
  reader = content.reader
1698
1733
  else:
1699
- reader = self._select_reader(content.file_data.type)
1700
- name = content.name if content.name else f"content_{content.file_data.type}"
1701
- read_documents = await reader.async_read(content_io, name=name)
1734
+ # Prefer filename extension over MIME type for reader selection
1735
+ # (browsers often send wrong MIME types for Excel files)
1736
+ reader_hint = content.file_data.type
1737
+ if content.file_data.filename:
1738
+ ext = Path(content.file_data.filename).suffix.lower()
1739
+ if ext:
1740
+ reader_hint = ext
1741
+ reader = self._select_reader(reader_hint)
1742
+ # Use file_data.filename for reader (preserves extension for format detection)
1743
+ reader_name = content.file_data.filename or content.name or f"content_{content.file_data.type}"
1744
+ read_documents = await reader.async_read(content_io, name=reader_name)
1702
1745
  if not content.id:
1703
1746
  content.id = generate_id(content.content_hash or "")
1704
1747
  self._prepare_documents_for_insert(read_documents, content.id, metadata=content.metadata)
@@ -1730,6 +1773,8 @@ class Knowledge:
1730
1773
 
1731
1774
  if content.name:
1732
1775
  name = content.name
1776
+ elif content.file_data and content.file_data.filename:
1777
+ name = content.file_data.filename
1733
1778
  elif content.file_data and content.file_data.content:
1734
1779
  if isinstance(content.file_data.content, bytes):
1735
1780
  name = content.file_data.content[:10].decode("utf-8", errors="ignore")
@@ -1793,9 +1838,17 @@ class Knowledge:
1793
1838
  log_debug(f"Using reader: {content.reader.__class__.__name__} to read content")
1794
1839
  reader = content.reader
1795
1840
  else:
1796
- reader = self._select_reader(content.file_data.type)
1797
- name = content.name if content.name else f"content_{content.file_data.type}"
1798
- read_documents = reader.read(content_io, name=name)
1841
+ # Prefer filename extension over MIME type for reader selection
1842
+ # (browsers often send wrong MIME types for Excel files)
1843
+ reader_hint = content.file_data.type
1844
+ if content.file_data.filename:
1845
+ ext = Path(content.file_data.filename).suffix.lower()
1846
+ if ext:
1847
+ reader_hint = ext
1848
+ reader = self._select_reader(reader_hint)
1849
+ # Use file_data.filename for reader (preserves extension for format detection)
1850
+ reader_name = content.file_data.filename or content.name or f"content_{content.file_data.type}"
1851
+ read_documents = reader.read(content_io, name=reader_name)
1799
1852
  if not content.id:
1800
1853
  content.id = generate_id(content.content_hash or "")
1801
1854
  self._prepare_documents_for_insert(read_documents, content.id, metadata=content.metadata)