agno 1.8.1__py3-none-any.whl → 2.0.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (580) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2778 -4123
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +9 -64
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1749 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1438 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +888 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1051 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1417 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +10 -10
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +129 -82
  141. agno/models/aws/bedrock.py +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +38 -144
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +84 -46
  158. agno/models/openai/chat.py +121 -23
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +14 -8
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +393 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +65 -28
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +33 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  184. agno/os/router.py +843 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +204 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +413 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +179 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +58 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +163 -0
  201. agno/os/schema.py +892 -0
  202. agno/{app/playground → os}/settings.py +8 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/{response.py → agent.py} +144 -72
  212. agno/run/base.py +44 -58
  213. agno/run/cancel.py +83 -0
  214. agno/run/team.py +133 -77
  215. agno/run/workflow.py +537 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +2961 -4253
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +42 -22
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +18 -13
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +18 -11
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +16 -7
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +61 -61
  252. agno/tools/eleven_labs.py +35 -28
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +29 -29
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +22 -22
  260. agno/tools/function.py +68 -17
  261. agno/tools/giphy.py +22 -10
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +31 -19
  276. agno/tools/mem0.py +18 -12
  277. agno/tools/memori.py +14 -10
  278. agno/tools/mlx_transcribe.py +3 -2
  279. agno/tools/models/azure_openai.py +32 -14
  280. agno/tools/models/gemini.py +58 -31
  281. agno/tools/models/groq.py +29 -20
  282. agno/tools/models/nebius.py +27 -11
  283. agno/tools/models_labs.py +39 -15
  284. agno/tools/moviepy_video.py +7 -6
  285. agno/tools/neo4j.py +10 -8
  286. agno/tools/newspaper.py +7 -2
  287. agno/tools/newspaper4k.py +8 -3
  288. agno/tools/openai.py +57 -26
  289. agno/tools/openbb.py +12 -11
  290. agno/tools/opencv.py +62 -46
  291. agno/tools/openweather.py +14 -12
  292. agno/tools/pandas.py +11 -3
  293. agno/tools/postgres.py +4 -12
  294. agno/tools/pubmed.py +4 -1
  295. agno/tools/python.py +9 -22
  296. agno/tools/reasoning.py +35 -27
  297. agno/tools/reddit.py +11 -26
  298. agno/tools/replicate.py +54 -41
  299. agno/tools/resend.py +4 -1
  300. agno/tools/scrapegraph.py +15 -14
  301. agno/tools/searxng.py +10 -23
  302. agno/tools/serpapi.py +6 -3
  303. agno/tools/serper.py +13 -4
  304. agno/tools/shell.py +9 -2
  305. agno/tools/slack.py +12 -11
  306. agno/tools/sleep.py +3 -2
  307. agno/tools/spider.py +24 -4
  308. agno/tools/sql.py +7 -6
  309. agno/tools/tavily.py +6 -4
  310. agno/tools/telegram.py +12 -4
  311. agno/tools/todoist.py +11 -31
  312. agno/tools/toolkit.py +1 -1
  313. agno/tools/trafilatura.py +22 -6
  314. agno/tools/trello.py +9 -22
  315. agno/tools/twilio.py +10 -3
  316. agno/tools/user_control_flow.py +6 -1
  317. agno/tools/valyu.py +34 -5
  318. agno/tools/visualization.py +19 -28
  319. agno/tools/webbrowser.py +4 -3
  320. agno/tools/webex.py +11 -7
  321. agno/tools/website.py +15 -46
  322. agno/tools/webtools.py +12 -4
  323. agno/tools/whatsapp.py +5 -9
  324. agno/tools/wikipedia.py +20 -13
  325. agno/tools/x.py +14 -13
  326. agno/tools/yfinance.py +13 -40
  327. agno/tools/youtube.py +26 -20
  328. agno/tools/zendesk.py +7 -2
  329. agno/tools/zep.py +10 -7
  330. agno/tools/zoom.py +10 -9
  331. agno/utils/common.py +1 -19
  332. agno/utils/events.py +95 -118
  333. agno/utils/knowledge.py +29 -0
  334. agno/utils/log.py +2 -2
  335. agno/utils/mcp.py +11 -5
  336. agno/utils/media.py +39 -0
  337. agno/utils/message.py +12 -1
  338. agno/utils/models/claude.py +6 -4
  339. agno/utils/models/mistral.py +8 -7
  340. agno/utils/models/schema_utils.py +3 -3
  341. agno/utils/pprint.py +33 -32
  342. agno/utils/print_response/agent.py +779 -0
  343. agno/utils/print_response/team.py +1565 -0
  344. agno/utils/print_response/workflow.py +1451 -0
  345. agno/utils/prompts.py +14 -14
  346. agno/utils/reasoning.py +87 -0
  347. agno/utils/response.py +42 -42
  348. agno/utils/string.py +8 -22
  349. agno/utils/team.py +50 -0
  350. agno/utils/timer.py +2 -2
  351. agno/vectordb/base.py +33 -21
  352. agno/vectordb/cassandra/cassandra.py +287 -23
  353. agno/vectordb/chroma/chromadb.py +482 -59
  354. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  355. agno/vectordb/couchbase/couchbase.py +309 -29
  356. agno/vectordb/lancedb/lance_db.py +360 -21
  357. agno/vectordb/langchaindb/__init__.py +5 -0
  358. agno/vectordb/langchaindb/langchaindb.py +145 -0
  359. agno/vectordb/lightrag/__init__.py +5 -0
  360. agno/vectordb/lightrag/lightrag.py +374 -0
  361. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  362. agno/vectordb/milvus/milvus.py +242 -32
  363. agno/vectordb/mongodb/mongodb.py +200 -24
  364. agno/vectordb/pgvector/pgvector.py +319 -37
  365. agno/vectordb/pineconedb/pineconedb.py +221 -27
  366. agno/vectordb/qdrant/qdrant.py +334 -14
  367. agno/vectordb/singlestore/singlestore.py +286 -29
  368. agno/vectordb/surrealdb/surrealdb.py +187 -7
  369. agno/vectordb/upstashdb/upstashdb.py +342 -26
  370. agno/vectordb/weaviate/weaviate.py +227 -165
  371. agno/workflow/__init__.py +17 -13
  372. agno/workflow/{v2/condition.py → condition.py} +135 -32
  373. agno/workflow/{v2/loop.py → loop.py} +115 -28
  374. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  375. agno/workflow/{v2/router.py → router.py} +133 -32
  376. agno/workflow/{v2/step.py → step.py} +200 -42
  377. agno/workflow/{v2/steps.py → steps.py} +147 -66
  378. agno/workflow/types.py +482 -0
  379. agno/workflow/workflow.py +2394 -696
  380. agno-2.0.0a1.dist-info/METADATA +355 -0
  381. agno-2.0.0a1.dist-info/RECORD +514 -0
  382. agno/agent/metrics.py +0 -107
  383. agno/api/app.py +0 -35
  384. agno/api/playground.py +0 -92
  385. agno/api/schemas/app.py +0 -12
  386. agno/api/schemas/playground.py +0 -22
  387. agno/api/schemas/user.py +0 -35
  388. agno/api/schemas/workspace.py +0 -46
  389. agno/api/user.py +0 -160
  390. agno/api/workflows.py +0 -33
  391. agno/api/workspace.py +0 -175
  392. agno/app/agui/__init__.py +0 -3
  393. agno/app/agui/app.py +0 -17
  394. agno/app/agui/sync_router.py +0 -120
  395. agno/app/base.py +0 -186
  396. agno/app/discord/__init__.py +0 -3
  397. agno/app/fastapi/__init__.py +0 -3
  398. agno/app/fastapi/app.py +0 -107
  399. agno/app/fastapi/async_router.py +0 -457
  400. agno/app/fastapi/sync_router.py +0 -448
  401. agno/app/playground/app.py +0 -228
  402. agno/app/playground/async_router.py +0 -1050
  403. agno/app/playground/deploy.py +0 -249
  404. agno/app/playground/operator.py +0 -183
  405. agno/app/playground/schemas.py +0 -220
  406. agno/app/playground/serve.py +0 -55
  407. agno/app/playground/sync_router.py +0 -1042
  408. agno/app/playground/utils.py +0 -46
  409. agno/app/settings.py +0 -15
  410. agno/app/slack/__init__.py +0 -3
  411. agno/app/slack/app.py +0 -19
  412. agno/app/slack/sync_router.py +0 -92
  413. agno/app/utils.py +0 -54
  414. agno/app/whatsapp/__init__.py +0 -3
  415. agno/app/whatsapp/app.py +0 -15
  416. agno/app/whatsapp/sync_router.py +0 -197
  417. agno/cli/auth_server.py +0 -249
  418. agno/cli/config.py +0 -274
  419. agno/cli/console.py +0 -88
  420. agno/cli/credentials.py +0 -23
  421. agno/cli/entrypoint.py +0 -571
  422. agno/cli/operator.py +0 -357
  423. agno/cli/settings.py +0 -96
  424. agno/cli/ws/ws_cli.py +0 -817
  425. agno/constants.py +0 -13
  426. agno/document/__init__.py +0 -5
  427. agno/document/chunking/semantic.py +0 -45
  428. agno/document/chunking/strategy.py +0 -31
  429. agno/document/reader/__init__.py +0 -5
  430. agno/document/reader/base.py +0 -47
  431. agno/document/reader/docx_reader.py +0 -60
  432. agno/document/reader/gcs/pdf_reader.py +0 -44
  433. agno/document/reader/s3/pdf_reader.py +0 -59
  434. agno/document/reader/s3/text_reader.py +0 -63
  435. agno/document/reader/url_reader.py +0 -59
  436. agno/document/reader/youtube_reader.py +0 -58
  437. agno/embedder/__init__.py +0 -5
  438. agno/embedder/langdb.py +0 -80
  439. agno/embedder/mistral.py +0 -82
  440. agno/embedder/openai.py +0 -78
  441. agno/file/__init__.py +0 -5
  442. agno/file/file.py +0 -16
  443. agno/file/local/csv.py +0 -32
  444. agno/file/local/txt.py +0 -19
  445. agno/infra/app.py +0 -240
  446. agno/infra/base.py +0 -144
  447. agno/infra/context.py +0 -20
  448. agno/infra/db_app.py +0 -52
  449. agno/infra/resource.py +0 -205
  450. agno/infra/resources.py +0 -55
  451. agno/knowledge/agent.py +0 -702
  452. agno/knowledge/arxiv.py +0 -33
  453. agno/knowledge/combined.py +0 -36
  454. agno/knowledge/csv.py +0 -144
  455. agno/knowledge/csv_url.py +0 -124
  456. agno/knowledge/document.py +0 -223
  457. agno/knowledge/docx.py +0 -137
  458. agno/knowledge/firecrawl.py +0 -34
  459. agno/knowledge/gcs/__init__.py +0 -0
  460. agno/knowledge/gcs/base.py +0 -39
  461. agno/knowledge/gcs/pdf.py +0 -125
  462. agno/knowledge/json.py +0 -137
  463. agno/knowledge/langchain.py +0 -71
  464. agno/knowledge/light_rag.py +0 -273
  465. agno/knowledge/llamaindex.py +0 -66
  466. agno/knowledge/markdown.py +0 -154
  467. agno/knowledge/pdf.py +0 -164
  468. agno/knowledge/pdf_bytes.py +0 -42
  469. agno/knowledge/pdf_url.py +0 -148
  470. agno/knowledge/s3/__init__.py +0 -0
  471. agno/knowledge/s3/base.py +0 -64
  472. agno/knowledge/s3/pdf.py +0 -33
  473. agno/knowledge/s3/text.py +0 -34
  474. agno/knowledge/text.py +0 -141
  475. agno/knowledge/url.py +0 -46
  476. agno/knowledge/website.py +0 -179
  477. agno/knowledge/wikipedia.py +0 -32
  478. agno/knowledge/youtube.py +0 -35
  479. agno/memory/agent.py +0 -423
  480. agno/memory/classifier.py +0 -104
  481. agno/memory/db/__init__.py +0 -5
  482. agno/memory/db/base.py +0 -42
  483. agno/memory/db/mongodb.py +0 -189
  484. agno/memory/db/postgres.py +0 -203
  485. agno/memory/db/sqlite.py +0 -193
  486. agno/memory/memory.py +0 -22
  487. agno/memory/row.py +0 -36
  488. agno/memory/summarizer.py +0 -201
  489. agno/memory/summary.py +0 -19
  490. agno/memory/team.py +0 -415
  491. agno/memory/v2/__init__.py +0 -2
  492. agno/memory/v2/db/__init__.py +0 -1
  493. agno/memory/v2/db/base.py +0 -42
  494. agno/memory/v2/db/firestore.py +0 -339
  495. agno/memory/v2/db/mongodb.py +0 -196
  496. agno/memory/v2/db/postgres.py +0 -214
  497. agno/memory/v2/db/redis.py +0 -187
  498. agno/memory/v2/db/schema.py +0 -54
  499. agno/memory/v2/db/sqlite.py +0 -209
  500. agno/memory/v2/manager.py +0 -437
  501. agno/memory/v2/memory.py +0 -1097
  502. agno/memory/v2/schema.py +0 -55
  503. agno/memory/v2/summarizer.py +0 -215
  504. agno/memory/workflow.py +0 -38
  505. agno/models/ollama/tools.py +0 -430
  506. agno/models/qwen/__init__.py +0 -5
  507. agno/playground/__init__.py +0 -10
  508. agno/playground/deploy.py +0 -3
  509. agno/playground/playground.py +0 -3
  510. agno/playground/serve.py +0 -3
  511. agno/playground/settings.py +0 -3
  512. agno/reranker/__init__.py +0 -0
  513. agno/run/v2/__init__.py +0 -0
  514. agno/run/v2/workflow.py +0 -567
  515. agno/storage/__init__.py +0 -0
  516. agno/storage/agent/__init__.py +0 -0
  517. agno/storage/agent/dynamodb.py +0 -1
  518. agno/storage/agent/json.py +0 -1
  519. agno/storage/agent/mongodb.py +0 -1
  520. agno/storage/agent/postgres.py +0 -1
  521. agno/storage/agent/singlestore.py +0 -1
  522. agno/storage/agent/sqlite.py +0 -1
  523. agno/storage/agent/yaml.py +0 -1
  524. agno/storage/base.py +0 -60
  525. agno/storage/dynamodb.py +0 -673
  526. agno/storage/firestore.py +0 -297
  527. agno/storage/gcs_json.py +0 -261
  528. agno/storage/in_memory.py +0 -234
  529. agno/storage/json.py +0 -237
  530. agno/storage/mongodb.py +0 -328
  531. agno/storage/mysql.py +0 -685
  532. agno/storage/postgres.py +0 -682
  533. agno/storage/redis.py +0 -336
  534. agno/storage/session/__init__.py +0 -16
  535. agno/storage/session/agent.py +0 -64
  536. agno/storage/session/team.py +0 -63
  537. agno/storage/session/v2/__init__.py +0 -5
  538. agno/storage/session/workflow.py +0 -61
  539. agno/storage/singlestore.py +0 -606
  540. agno/storage/sqlite.py +0 -646
  541. agno/storage/workflow/__init__.py +0 -0
  542. agno/storage/workflow/mongodb.py +0 -1
  543. agno/storage/workflow/postgres.py +0 -1
  544. agno/storage/workflow/sqlite.py +0 -1
  545. agno/storage/yaml.py +0 -241
  546. agno/tools/thinking.py +0 -73
  547. agno/utils/defaults.py +0 -57
  548. agno/utils/filesystem.py +0 -39
  549. agno/utils/git.py +0 -52
  550. agno/utils/json_io.py +0 -30
  551. agno/utils/load_env.py +0 -19
  552. agno/utils/py_io.py +0 -19
  553. agno/utils/pyproject.py +0 -18
  554. agno/utils/resource_filter.py +0 -31
  555. agno/workflow/v2/__init__.py +0 -21
  556. agno/workflow/v2/types.py +0 -357
  557. agno/workflow/v2/workflow.py +0 -3312
  558. agno/workspace/__init__.py +0 -0
  559. agno/workspace/config.py +0 -325
  560. agno/workspace/enums.py +0 -6
  561. agno/workspace/helpers.py +0 -52
  562. agno/workspace/operator.py +0 -757
  563. agno/workspace/settings.py +0 -158
  564. agno-1.8.1.dist-info/METADATA +0 -982
  565. agno-1.8.1.dist-info/RECORD +0 -566
  566. agno-1.8.1.dist-info/entry_points.txt +0 -3
  567. /agno/{app → db/migrations}/__init__.py +0 -0
  568. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  569. /agno/{cli → integrations}/__init__.py +0 -0
  570. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  571. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  572. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  573. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  574. /agno/{app → os/interfaces}/slack/security.py +0 -0
  575. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  576. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  577. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  578. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  579. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  580. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,15 @@
1
1
  from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Any, Dict, Iterator, List, Optional, Type, Union
3
+ from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Type, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
7
  from agno.exceptions import ModelProviderError
8
8
  from agno.models.base import Model
9
9
  from agno.models.message import Message
10
+ from agno.models.metrics import Metrics
10
11
  from agno.models.response import ModelResponse
12
+ from agno.run.agent import RunOutput
11
13
  from agno.utils.log import log_debug, log_error
12
14
  from agno.utils.models.mistral import format_messages
13
15
 
@@ -24,7 +26,9 @@ try:
24
26
  ToolMessage,
25
27
  UserMessage,
26
28
  )
27
- from mistralai.models.chatcompletionresponse import ChatCompletionResponse
29
+ from mistralai.models.chatcompletionresponse import (
30
+ ChatCompletionResponse,
31
+ )
28
32
  from mistralai.models.deltamessage import DeltaMessage
29
33
  from mistralai.types.basemodel import Unset
30
34
 
@@ -165,10 +169,12 @@ class MistralChat(Model):
165
169
  def invoke(
166
170
  self,
167
171
  messages: List[Message],
172
+ assistant_message: Message,
168
173
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
169
174
  tools: Optional[List[Dict[str, Any]]] = None,
170
175
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
171
- ) -> Union[ChatCompletionResponse, ParsedChatCompletionResponse]:
176
+ run_response: Optional[RunOutput] = None,
177
+ ) -> ModelResponse:
172
178
  """
173
179
  Send a chat completion request to the Mistral model.
174
180
  """
@@ -180,6 +186,11 @@ class MistralChat(Model):
180
186
  and isinstance(response_format, type)
181
187
  and issubclass(response_format, BaseModel)
182
188
  ):
189
+ if run_response and run_response.metrics:
190
+ run_response.metrics.set_time_to_first_token()
191
+
192
+ assistant_message.metrics.start_timer()
193
+
183
194
  response = self.get_client().chat.complete(
184
195
  model=self.id,
185
196
  messages=mistral_messages,
@@ -187,12 +198,21 @@ class MistralChat(Model):
187
198
  **self.get_request_params(tools=tools, tool_choice=tool_choice),
188
199
  )
189
200
  else:
201
+ if run_response and run_response.metrics:
202
+ run_response.metrics.set_time_to_first_token()
203
+
204
+ assistant_message.metrics.start_timer()
190
205
  response = self.get_client().chat.complete(
191
206
  model=self.id,
192
207
  messages=mistral_messages,
193
208
  **self.get_request_params(tools=tools, tool_choice=tool_choice),
194
209
  )
195
- return response
210
+
211
+ assistant_message.metrics.stop_timer()
212
+
213
+ model_response = self._parse_provider_response(response, response_format=response_format)
214
+
215
+ return model_response
196
216
 
197
217
  except HTTPValidationError as e:
198
218
  log_error(f"HTTPValidationError from Mistral: {e}")
@@ -204,21 +224,32 @@ class MistralChat(Model):
204
224
  def invoke_stream(
205
225
  self,
206
226
  messages: List[Message],
227
+ assistant_message: Message,
207
228
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
208
229
  tools: Optional[List[Dict[str, Any]]] = None,
209
230
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
210
- ) -> Iterator[Any]:
231
+ run_response: Optional[RunOutput] = None,
232
+ ) -> Iterator[ModelResponse]:
211
233
  """
212
234
  Stream the response from the Mistral model.
213
235
  """
214
236
  mistral_messages = format_messages(messages)
237
+
238
+ if run_response and run_response.metrics:
239
+ run_response.metrics.set_time_to_first_token()
240
+
241
+ assistant_message.metrics.start_timer()
242
+
215
243
  try:
216
- stream = self.get_client().chat.stream(
244
+ for chunk in self.get_client().chat.stream(
217
245
  model=self.id,
218
246
  messages=mistral_messages,
219
247
  **self.get_request_params(tools=tools, tool_choice=tool_choice),
220
- )
221
- return stream
248
+ ):
249
+ yield self._parse_provider_response_delta(chunk)
250
+
251
+ assistant_message.metrics.stop_timer()
252
+
222
253
  except HTTPValidationError as e:
223
254
  log_error(f"HTTPValidationError from Mistral: {e}")
224
255
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -229,10 +260,12 @@ class MistralChat(Model):
229
260
  async def ainvoke(
230
261
  self,
231
262
  messages: List[Message],
263
+ assistant_message: Message,
232
264
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
233
265
  tools: Optional[List[Dict[str, Any]]] = None,
234
266
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
235
- ) -> Union[ChatCompletionResponse, ParsedChatCompletionResponse]:
267
+ run_response: Optional[RunOutput] = None,
268
+ ) -> ModelResponse:
236
269
  """
237
270
  Send an asynchronous chat completion request to the Mistral API.
238
271
  """
@@ -244,6 +277,9 @@ class MistralChat(Model):
244
277
  and isinstance(response_format, type)
245
278
  and issubclass(response_format, BaseModel)
246
279
  ):
280
+ if run_response and run_response.metrics:
281
+ run_response.metrics.set_time_to_first_token()
282
+ assistant_message.metrics.start_timer()
247
283
  response = await self.get_client().chat.complete_async(
248
284
  model=self.id,
249
285
  messages=mistral_messages,
@@ -251,12 +287,20 @@ class MistralChat(Model):
251
287
  **self.get_request_params(tools=tools, tool_choice=tool_choice),
252
288
  )
253
289
  else:
290
+ if run_response and run_response.metrics:
291
+ run_response.metrics.set_time_to_first_token()
292
+ assistant_message.metrics.start_timer()
254
293
  response = await self.get_client().chat.complete_async(
255
294
  model=self.id,
256
295
  messages=mistral_messages,
257
296
  **self.get_request_params(tools=tools, tool_choice=tool_choice),
258
297
  )
259
- return response
298
+
299
+ assistant_message.metrics.stop_timer()
300
+
301
+ model_response = self._parse_provider_response(response, response_format=response_format)
302
+
303
+ return model_response
260
304
  except HTTPValidationError as e:
261
305
  log_error(f"HTTPValidationError from Mistral: {e}")
262
306
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -267,24 +311,31 @@ class MistralChat(Model):
267
311
  async def ainvoke_stream(
268
312
  self,
269
313
  messages: List[Message],
314
+ assistant_message: Message,
270
315
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
271
316
  tools: Optional[List[Dict[str, Any]]] = None,
272
317
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
273
- ) -> Any:
318
+ run_response: Optional[RunOutput] = None,
319
+ ) -> AsyncIterator[ModelResponse]:
274
320
  """
275
321
  Stream an asynchronous response from the Mistral API.
276
322
  """
277
323
  mistral_messages = format_messages(messages)
278
324
  try:
279
- stream = await self.get_client().chat.stream_async(
325
+ if run_response and run_response.metrics:
326
+ run_response.metrics.set_time_to_first_token()
327
+
328
+ assistant_message.metrics.start_timer()
329
+
330
+ async for chunk in await self.get_client().chat.stream_async(
280
331
  model=self.id,
281
332
  messages=mistral_messages,
282
333
  **self.get_request_params(tools=tools, tool_choice=tool_choice),
283
- )
284
- if stream is None:
285
- raise ValueError("Chat stream returned None")
286
- async for chunk in stream:
287
- yield chunk
334
+ ):
335
+ yield self._parse_provider_response_delta(chunk)
336
+
337
+ assistant_message.metrics.stop_timer()
338
+
288
339
  except HTTPValidationError as e:
289
340
  log_error(f"HTTPValidationError from Mistral: {e}")
290
341
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -292,7 +343,7 @@ class MistralChat(Model):
292
343
  log_error(f"SDKError from Mistral: {e}")
293
344
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
294
345
 
295
- def parse_provider_response(self, response: ChatCompletionResponse, **kwargs) -> ModelResponse:
346
+ def _parse_provider_response(self, response: ChatCompletionResponse, **kwargs) -> ModelResponse:
296
347
  """
297
348
  Parse the response from the Mistral model.
298
349
 
@@ -322,11 +373,11 @@ class MistralChat(Model):
322
373
  )
323
374
 
324
375
  if response.usage is not None:
325
- model_response.response_usage = response.usage
376
+ model_response.response_usage = self._get_metrics(response.usage)
326
377
 
327
378
  return model_response
328
379
 
329
- def parse_provider_response_delta(self, response_delta: CompletionEvent) -> Optional[ModelResponse]:
380
+ def _parse_provider_response_delta(self, response_delta: CompletionEvent) -> ModelResponse:
330
381
  """
331
382
  Parse the response delta from the Mistral model.
332
383
  """
@@ -358,6 +409,24 @@ class MistralChat(Model):
358
409
  )
359
410
 
360
411
  if response_delta.data.usage is not None:
361
- model_response.response_usage = response_delta.data.usage
412
+ model_response.response_usage = self._get_metrics(response_delta.data.usage)
362
413
 
363
414
  return model_response
415
+
416
+ def _get_metrics(self, response_usage: Any) -> Metrics:
417
+ """
418
+ Parse the given Mistral usage into an Agno Metrics object.
419
+
420
+ Args:
421
+ response_usage: Usage data from Mistral
422
+
423
+ Returns:
424
+ Metrics: Parsed metrics data
425
+ """
426
+ metrics = Metrics()
427
+
428
+ metrics.input_tokens = response_usage.prompt_tokens or 0
429
+ metrics.output_tokens = response_usage.completion_tokens or 0
430
+ metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
431
+
432
+ return metrics
@@ -1,7 +1,5 @@
1
1
  from agno.models.ollama.chat import Ollama
2
- from agno.models.ollama.tools import OllamaTools
3
2
 
4
3
  __all__ = [
5
4
  "Ollama",
6
- "OllamaTools",
7
5
  ]
@@ -1,11 +1,13 @@
1
1
  import json
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, Iterator, List, Mapping, Optional, Type, Union
3
+ from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Type, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
+ from agno.agent import RunOutput
7
8
  from agno.models.base import Model
8
9
  from agno.models.message import Message
10
+ from agno.models.metrics import Metrics
9
11
  from agno.models.response import ModelResponse
10
12
  from agno.utils.log import log_debug, log_warning
11
13
 
@@ -182,86 +184,124 @@ class Ollama(Model):
182
184
  def invoke(
183
185
  self,
184
186
  messages: List[Message],
187
+ assistant_message: Message,
185
188
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
186
189
  tools: Optional[List[Dict[str, Any]]] = None,
187
190
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
188
- ) -> Mapping[str, Any]:
191
+ run_response: Optional[RunOutput] = None,
192
+ ) -> ModelResponse:
189
193
  """
190
194
  Send a chat request to the Ollama API.
191
195
  """
192
196
  request_kwargs = self._prepare_request_kwargs_for_invoke(response_format=response_format, tools=tools)
193
197
 
194
- return self.get_client().chat(
198
+ if run_response and run_response.metrics:
199
+ run_response.metrics.set_time_to_first_token()
200
+
201
+ assistant_message.metrics.start_timer()
202
+
203
+ provider_response = self.get_client().chat(
195
204
  model=self.id.strip(),
196
205
  messages=[self._format_message(m) for m in messages], # type: ignore
197
206
  **request_kwargs,
198
207
  ) # type: ignore
199
208
 
209
+ assistant_message.metrics.stop_timer()
210
+
211
+ model_response = self._parse_provider_response(provider_response) # type: ignore
212
+ return model_response
213
+
200
214
  async def ainvoke(
201
215
  self,
202
216
  messages: List[Message],
217
+ assistant_message: Message,
203
218
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
204
219
  tools: Optional[List[Dict[str, Any]]] = None,
205
220
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
206
- ) -> Mapping[str, Any]:
221
+ run_response: Optional[RunOutput] = None,
222
+ ) -> ModelResponse:
207
223
  """
208
224
  Sends an asynchronous chat request to the Ollama API.
209
225
  """
210
226
  request_kwargs = self._prepare_request_kwargs_for_invoke(response_format=response_format, tools=tools)
211
227
 
212
- return await self.get_async_client().chat(
228
+ if run_response and run_response.metrics:
229
+ run_response.metrics.set_time_to_first_token()
230
+
231
+ assistant_message.metrics.start_timer()
232
+
233
+ provider_response = await self.get_async_client().chat(
213
234
  model=self.id.strip(),
214
235
  messages=[self._format_message(m) for m in messages], # type: ignore
215
236
  **request_kwargs,
216
237
  ) # type: ignore
217
238
 
239
+ assistant_message.metrics.stop_timer()
240
+
241
+ model_response = self._parse_provider_response(provider_response) # type: ignore
242
+ return model_response
243
+
218
244
  def invoke_stream(
219
245
  self,
220
246
  messages: List[Message],
247
+ assistant_message: Message,
221
248
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
222
249
  tools: Optional[List[Dict[str, Any]]] = None,
223
250
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
224
- ) -> Iterator[Mapping[str, Any]]:
251
+ run_response: Optional[RunOutput] = None,
252
+ ) -> Iterator[ModelResponse]:
225
253
  """
226
254
  Sends a streaming chat request to the Ollama API.
227
255
  """
228
- yield from self.get_client().chat(
256
+ if run_response and run_response.metrics:
257
+ run_response.metrics.set_time_to_first_token()
258
+
259
+ assistant_message.metrics.start_timer()
260
+
261
+ for chunk in self.get_client().chat(
229
262
  model=self.id,
230
263
  messages=[self._format_message(m) for m in messages], # type: ignore
231
264
  stream=True,
232
265
  **self.get_request_params(tools=tools),
233
- ) # type: ignore
266
+ ):
267
+ yield self._parse_provider_response_delta(chunk)
268
+
269
+ assistant_message.metrics.stop_timer()
234
270
 
235
271
  async def ainvoke_stream(
236
272
  self,
237
273
  messages: List[Message],
274
+ assistant_message: Message,
238
275
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
239
276
  tools: Optional[List[Dict[str, Any]]] = None,
240
277
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
241
- ) -> Any:
278
+ run_response: Optional[RunOutput] = None,
279
+ ) -> AsyncIterator[ModelResponse]:
242
280
  """
243
281
  Sends an asynchronous streaming chat completion request to the Ollama API.
244
282
  """
245
- async_stream = await self.get_async_client().chat(
283
+ if run_response and run_response.metrics:
284
+ run_response.metrics.set_time_to_first_token()
285
+
286
+ assistant_message.metrics.start_timer()
287
+
288
+ async for chunk in await self.get_async_client().chat(
246
289
  model=self.id.strip(),
247
290
  messages=[self._format_message(m) for m in messages], # type: ignore
248
291
  stream=True,
249
292
  **self.get_request_params(tools=tools),
250
- )
251
- async for chunk in async_stream: # type: ignore
252
- yield chunk
293
+ ):
294
+ yield self._parse_provider_response_delta(chunk)
253
295
 
254
- def parse_provider_response(
255
- self,
256
- response: ChatResponse,
257
- response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
258
- ) -> ModelResponse:
296
+ assistant_message.metrics.stop_timer()
297
+
298
+ def _parse_provider_response(self, response: dict) -> ModelResponse:
259
299
  """
260
300
  Parse the provider response.
261
301
  """
262
302
  model_response = ModelResponse()
263
303
  # Get response message
264
- response_message: OllamaMessage = response.get("message")
304
+ response_message: OllamaMessage = response.get("message") # type: ignore
265
305
 
266
306
  if response_message.get("role") is not None:
267
307
  model_response.role = response_message.get("role")
@@ -272,7 +312,7 @@ class Ollama(Model):
272
312
  if response_message.get("tool_calls") is not None:
273
313
  if model_response.tool_calls is None:
274
314
  model_response.tool_calls = []
275
- for block in response_message.get("tool_calls"):
315
+ for block in response_message.get("tool_calls", []):
276
316
  tool_call = block.get("function")
277
317
  tool_name = tool_call.get("name")
278
318
  tool_args = tool_call.get("arguments")
@@ -288,33 +328,23 @@ class Ollama(Model):
288
328
 
289
329
  # Get response usage
290
330
  if response.get("done"):
291
- model_response.response_usage = {
292
- "input_tokens": response.get("prompt_eval_count", 0),
293
- "output_tokens": response.get("eval_count", 0),
294
- "total_tokens": response.get("prompt_eval_count", 0) + response.get("eval_count", 0),
295
- "additional_metrics": {
296
- "total_duration": response.get("total_duration", 0),
297
- "load_duration": response.get("load_duration", 0),
298
- "prompt_eval_duration": response.get("prompt_eval_duration", 0),
299
- "eval_duration": response.get("eval_duration", 0),
300
- },
301
- }
331
+ model_response.response_usage = self._get_metrics(response)
302
332
 
303
333
  return model_response
304
334
 
305
- def parse_provider_response_delta(self, response_delta: ChatResponse) -> ModelResponse:
335
+ def _parse_provider_response_delta(self, response: ChatResponse) -> ModelResponse:
306
336
  """
307
337
  Parse the provider response delta.
308
338
 
309
339
  Args:
310
- response_delta (ChatResponse): The response from the provider.
340
+ response (ChatResponse): The response from the provider.
311
341
 
312
342
  Returns:
313
343
  Iterator[ModelResponse]: An iterator of the model response.
314
344
  """
315
345
  model_response = ModelResponse()
316
346
 
317
- response_message = response_delta.get("message")
347
+ response_message = response.get("message")
318
348
 
319
349
  if response_message is not None:
320
350
  content_delta = response_message.get("content")
@@ -333,17 +363,25 @@ class Ollama(Model):
333
363
  }
334
364
  model_response.tool_calls.append({"type": "function", "function": function_def})
335
365
 
336
- if response_delta.get("done"):
337
- model_response.response_usage = {
338
- "input_tokens": response_delta.get("prompt_eval_count", 0),
339
- "output_tokens": response_delta.get("eval_count", 0),
340
- "total_tokens": response_delta.get("prompt_eval_count", 0) + response_delta.get("eval_count", 0),
341
- "additional_metrics": {
342
- "total_duration": response_delta.get("total_duration", 0),
343
- "load_duration": response_delta.get("load_duration", 0),
344
- "prompt_eval_duration": response_delta.get("prompt_eval_duration", 0),
345
- "eval_duration": response_delta.get("eval_duration", 0),
346
- },
347
- }
366
+ if response.get("done"):
367
+ model_response.response_usage = self._get_metrics(response)
348
368
 
349
369
  return model_response
370
+
371
+ def _get_metrics(self, response: Union[dict, ChatResponse]) -> Metrics:
372
+ """
373
+ Parse the given Ollama usage into an Agno Metrics object.
374
+
375
+ Args:
376
+ response: The response from the provider.
377
+
378
+ Returns:
379
+ Metrics: Parsed metrics data
380
+ """
381
+ metrics = Metrics()
382
+
383
+ metrics.input_tokens = response.get("prompt_eval_count", 0)
384
+ metrics.output_tokens = response.get("eval_count", 0)
385
+ metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
386
+
387
+ return metrics