agno 1.8.2__py3-none-any.whl → 2.0.0__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 (589) hide show
  1. agno/agent/__init__.py +19 -27
  2. agno/agent/agent.py +3143 -4170
  3. agno/api/agent.py +11 -67
  4. agno/api/api.py +5 -46
  5. agno/api/evals.py +8 -19
  6. agno/api/os.py +17 -0
  7. agno/api/routes.py +6 -41
  8. agno/api/schemas/__init__.py +9 -0
  9. agno/api/schemas/agent.py +5 -21
  10. agno/api/schemas/evals.py +7 -16
  11. agno/api/schemas/os.py +14 -0
  12. agno/api/schemas/team.py +5 -21
  13. agno/api/schemas/utils.py +21 -0
  14. agno/api/schemas/workflows.py +11 -7
  15. agno/api/settings.py +53 -0
  16. agno/api/team.py +11 -66
  17. agno/api/workflow.py +28 -0
  18. agno/cloud/aws/base.py +214 -0
  19. agno/cloud/aws/s3/__init__.py +2 -0
  20. agno/cloud/aws/s3/api_client.py +43 -0
  21. agno/cloud/aws/s3/bucket.py +195 -0
  22. agno/cloud/aws/s3/object.py +57 -0
  23. agno/db/__init__.py +24 -0
  24. agno/db/base.py +245 -0
  25. agno/db/dynamo/__init__.py +3 -0
  26. agno/db/dynamo/dynamo.py +1743 -0
  27. agno/db/dynamo/schemas.py +278 -0
  28. agno/db/dynamo/utils.py +684 -0
  29. agno/db/firestore/__init__.py +3 -0
  30. agno/db/firestore/firestore.py +1432 -0
  31. agno/db/firestore/schemas.py +130 -0
  32. agno/db/firestore/utils.py +278 -0
  33. agno/db/gcs_json/__init__.py +3 -0
  34. agno/db/gcs_json/gcs_json_db.py +1001 -0
  35. agno/db/gcs_json/utils.py +194 -0
  36. agno/db/in_memory/__init__.py +3 -0
  37. agno/db/in_memory/in_memory_db.py +882 -0
  38. agno/db/in_memory/utils.py +172 -0
  39. agno/db/json/__init__.py +3 -0
  40. agno/db/json/json_db.py +1045 -0
  41. agno/db/json/utils.py +196 -0
  42. agno/db/migrations/v1_to_v2.py +162 -0
  43. agno/db/mongo/__init__.py +3 -0
  44. agno/db/mongo/mongo.py +1416 -0
  45. agno/db/mongo/schemas.py +77 -0
  46. agno/db/mongo/utils.py +204 -0
  47. agno/db/mysql/__init__.py +3 -0
  48. agno/db/mysql/mysql.py +1719 -0
  49. agno/db/mysql/schemas.py +124 -0
  50. agno/db/mysql/utils.py +297 -0
  51. agno/db/postgres/__init__.py +3 -0
  52. agno/db/postgres/postgres.py +1710 -0
  53. agno/db/postgres/schemas.py +124 -0
  54. agno/db/postgres/utils.py +280 -0
  55. agno/db/redis/__init__.py +3 -0
  56. agno/db/redis/redis.py +1367 -0
  57. agno/db/redis/schemas.py +109 -0
  58. agno/db/redis/utils.py +288 -0
  59. agno/db/schemas/__init__.py +3 -0
  60. agno/db/schemas/evals.py +33 -0
  61. agno/db/schemas/knowledge.py +40 -0
  62. agno/db/schemas/memory.py +46 -0
  63. agno/db/singlestore/__init__.py +3 -0
  64. agno/db/singlestore/schemas.py +116 -0
  65. agno/db/singlestore/singlestore.py +1712 -0
  66. agno/db/singlestore/utils.py +326 -0
  67. agno/db/sqlite/__init__.py +3 -0
  68. agno/db/sqlite/schemas.py +119 -0
  69. agno/db/sqlite/sqlite.py +1676 -0
  70. agno/db/sqlite/utils.py +268 -0
  71. agno/db/utils.py +88 -0
  72. agno/eval/__init__.py +14 -0
  73. agno/eval/accuracy.py +154 -48
  74. agno/eval/performance.py +88 -23
  75. agno/eval/reliability.py +73 -20
  76. agno/eval/utils.py +23 -13
  77. agno/integrations/discord/__init__.py +3 -0
  78. agno/{app → integrations}/discord/client.py +10 -10
  79. agno/knowledge/__init__.py +2 -2
  80. agno/{document → knowledge}/chunking/agentic.py +2 -2
  81. agno/{document → knowledge}/chunking/document.py +2 -2
  82. agno/{document → knowledge}/chunking/fixed.py +3 -3
  83. agno/{document → knowledge}/chunking/markdown.py +2 -2
  84. agno/{document → knowledge}/chunking/recursive.py +2 -2
  85. agno/{document → knowledge}/chunking/row.py +2 -2
  86. agno/knowledge/chunking/semantic.py +59 -0
  87. agno/knowledge/chunking/strategy.py +121 -0
  88. agno/knowledge/content.py +74 -0
  89. agno/knowledge/document/__init__.py +5 -0
  90. agno/{document → knowledge/document}/base.py +12 -2
  91. agno/knowledge/embedder/__init__.py +5 -0
  92. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  93. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  94. agno/{embedder → knowledge/embedder}/base.py +6 -0
  95. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  96. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  97. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  98. agno/{embedder → knowledge/embedder}/google.py +74 -1
  99. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  100. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  101. agno/knowledge/embedder/langdb.py +22 -0
  102. agno/knowledge/embedder/mistral.py +139 -0
  103. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  104. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  105. agno/knowledge/embedder/openai.py +223 -0
  106. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  107. agno/{embedder → knowledge/embedder}/together.py +1 -1
  108. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  109. agno/knowledge/knowledge.py +1551 -0
  110. agno/knowledge/reader/__init__.py +7 -0
  111. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  112. agno/knowledge/reader/base.py +88 -0
  113. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  114. agno/knowledge/reader/docx_reader.py +83 -0
  115. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  116. agno/{document → knowledge}/reader/json_reader.py +30 -9
  117. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  118. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  119. agno/knowledge/reader/reader_factory.py +268 -0
  120. agno/knowledge/reader/s3_reader.py +101 -0
  121. agno/{document → knowledge}/reader/text_reader.py +31 -10
  122. agno/knowledge/reader/url_reader.py +128 -0
  123. agno/knowledge/reader/web_search_reader.py +366 -0
  124. agno/{document → knowledge}/reader/website_reader.py +37 -10
  125. agno/knowledge/reader/wikipedia_reader.py +59 -0
  126. agno/knowledge/reader/youtube_reader.py +78 -0
  127. agno/knowledge/remote_content/remote_content.py +88 -0
  128. agno/{reranker → knowledge/reranker}/base.py +1 -1
  129. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  130. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  131. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  132. agno/knowledge/types.py +30 -0
  133. agno/knowledge/utils.py +169 -0
  134. agno/media.py +269 -268
  135. agno/memory/__init__.py +2 -10
  136. agno/memory/manager.py +1003 -148
  137. agno/models/aimlapi/__init__.py +2 -2
  138. agno/models/aimlapi/aimlapi.py +6 -6
  139. agno/models/anthropic/claude.py +128 -72
  140. agno/models/aws/bedrock.py +107 -175
  141. agno/models/aws/claude.py +64 -18
  142. agno/models/azure/ai_foundry.py +73 -23
  143. agno/models/base.py +346 -290
  144. agno/models/cerebras/cerebras.py +84 -27
  145. agno/models/cohere/chat.py +106 -98
  146. agno/models/google/gemini.py +105 -46
  147. agno/models/groq/groq.py +97 -35
  148. agno/models/huggingface/huggingface.py +92 -27
  149. agno/models/ibm/watsonx.py +72 -13
  150. agno/models/litellm/chat.py +85 -13
  151. agno/models/message.py +46 -151
  152. agno/models/meta/llama.py +85 -49
  153. agno/models/metrics.py +120 -0
  154. agno/models/mistral/mistral.py +90 -21
  155. agno/models/ollama/__init__.py +0 -2
  156. agno/models/ollama/chat.py +85 -47
  157. agno/models/openai/chat.py +154 -37
  158. agno/models/openai/responses.py +178 -105
  159. agno/models/perplexity/perplexity.py +26 -2
  160. agno/models/portkey/portkey.py +0 -7
  161. agno/models/response.py +15 -9
  162. agno/models/utils.py +20 -0
  163. agno/models/vercel/__init__.py +2 -2
  164. agno/models/vercel/v0.py +1 -1
  165. agno/models/vllm/__init__.py +2 -2
  166. agno/models/vllm/vllm.py +3 -3
  167. agno/models/xai/xai.py +10 -10
  168. agno/os/__init__.py +3 -0
  169. agno/os/app.py +497 -0
  170. agno/os/auth.py +47 -0
  171. agno/os/config.py +103 -0
  172. agno/os/interfaces/agui/__init__.py +3 -0
  173. agno/os/interfaces/agui/agui.py +31 -0
  174. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  175. agno/{app → os/interfaces}/agui/utils.py +65 -28
  176. agno/os/interfaces/base.py +21 -0
  177. agno/os/interfaces/slack/__init__.py +3 -0
  178. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  179. agno/os/interfaces/slack/slack.py +32 -0
  180. agno/os/interfaces/whatsapp/__init__.py +3 -0
  181. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  182. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  183. agno/os/mcp.py +235 -0
  184. agno/os/router.py +1400 -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 +393 -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 +850 -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 +410 -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 +178 -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 +536 -0
  201. agno/os/schema.py +945 -0
  202. agno/{app/playground → os}/settings.py +7 -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/agent.py +633 -0
  212. agno/run/base.py +53 -77
  213. agno/run/cancel.py +81 -0
  214. agno/run/team.py +243 -96
  215. agno/run/workflow.py +550 -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 +3260 -4824
  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 +43 -23
  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 +20 -17
  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 +22 -12
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +17 -8
  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 +62 -62
  252. agno/tools/eleven_labs.py +36 -29
  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 +30 -30
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +17 -18
  260. agno/tools/function.py +127 -18
  261. agno/tools/giphy.py +23 -11
  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 +32 -20
  276. agno/tools/mcp.py +1 -2
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +33 -15
  281. agno/tools/models/gemini.py +59 -32
  282. agno/tools/models/groq.py +30 -23
  283. agno/tools/models/nebius.py +28 -12
  284. agno/tools/models_labs.py +40 -16
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +58 -32
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +63 -47
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +55 -42
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +100 -123
  334. agno/utils/gemini.py +1 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +54 -4
  337. agno/utils/mcp.py +68 -10
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/aws_claude.py +1 -1
  341. agno/utils/models/claude.py +6 -12
  342. agno/utils/models/cohere.py +1 -1
  343. agno/utils/models/mistral.py +8 -7
  344. agno/utils/models/schema_utils.py +3 -3
  345. agno/utils/models/watsonx.py +1 -1
  346. agno/utils/openai.py +1 -1
  347. agno/utils/pprint.py +33 -32
  348. agno/utils/print_response/agent.py +779 -0
  349. agno/utils/print_response/team.py +1669 -0
  350. agno/utils/print_response/workflow.py +1451 -0
  351. agno/utils/prompts.py +14 -14
  352. agno/utils/reasoning.py +87 -0
  353. agno/utils/response.py +42 -42
  354. agno/utils/streamlit.py +481 -0
  355. agno/utils/string.py +8 -22
  356. agno/utils/team.py +50 -0
  357. agno/utils/timer.py +2 -2
  358. agno/vectordb/base.py +33 -21
  359. agno/vectordb/cassandra/cassandra.py +287 -23
  360. agno/vectordb/chroma/chromadb.py +482 -59
  361. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  362. agno/vectordb/couchbase/couchbase.py +309 -29
  363. agno/vectordb/lancedb/lance_db.py +360 -21
  364. agno/vectordb/langchaindb/__init__.py +5 -0
  365. agno/vectordb/langchaindb/langchaindb.py +145 -0
  366. agno/vectordb/lightrag/__init__.py +5 -0
  367. agno/vectordb/lightrag/lightrag.py +374 -0
  368. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  369. agno/vectordb/milvus/milvus.py +242 -32
  370. agno/vectordb/mongodb/mongodb.py +200 -24
  371. agno/vectordb/pgvector/pgvector.py +319 -37
  372. agno/vectordb/pineconedb/pineconedb.py +221 -27
  373. agno/vectordb/qdrant/qdrant.py +334 -14
  374. agno/vectordb/singlestore/singlestore.py +286 -29
  375. agno/vectordb/surrealdb/surrealdb.py +187 -7
  376. agno/vectordb/upstashdb/upstashdb.py +342 -26
  377. agno/vectordb/weaviate/weaviate.py +227 -165
  378. agno/workflow/__init__.py +17 -13
  379. agno/workflow/{v2/condition.py → condition.py} +135 -32
  380. agno/workflow/{v2/loop.py → loop.py} +115 -28
  381. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  382. agno/workflow/{v2/router.py → router.py} +133 -32
  383. agno/workflow/{v2/step.py → step.py} +207 -49
  384. agno/workflow/{v2/steps.py → steps.py} +147 -66
  385. agno/workflow/types.py +482 -0
  386. agno/workflow/workflow.py +2410 -696
  387. agno-2.0.0.dist-info/METADATA +494 -0
  388. agno-2.0.0.dist-info/RECORD +515 -0
  389. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  390. agno/agent/metrics.py +0 -110
  391. agno/api/app.py +0 -35
  392. agno/api/playground.py +0 -92
  393. agno/api/schemas/app.py +0 -12
  394. agno/api/schemas/playground.py +0 -22
  395. agno/api/schemas/user.py +0 -35
  396. agno/api/schemas/workspace.py +0 -46
  397. agno/api/user.py +0 -160
  398. agno/api/workflows.py +0 -33
  399. agno/api/workspace.py +0 -175
  400. agno/app/agui/__init__.py +0 -3
  401. agno/app/agui/app.py +0 -17
  402. agno/app/agui/sync_router.py +0 -120
  403. agno/app/base.py +0 -186
  404. agno/app/discord/__init__.py +0 -3
  405. agno/app/fastapi/__init__.py +0 -3
  406. agno/app/fastapi/app.py +0 -107
  407. agno/app/fastapi/async_router.py +0 -457
  408. agno/app/fastapi/sync_router.py +0 -448
  409. agno/app/playground/app.py +0 -228
  410. agno/app/playground/async_router.py +0 -1053
  411. agno/app/playground/deploy.py +0 -249
  412. agno/app/playground/operator.py +0 -183
  413. agno/app/playground/schemas.py +0 -223
  414. agno/app/playground/serve.py +0 -55
  415. agno/app/playground/sync_router.py +0 -1045
  416. agno/app/playground/utils.py +0 -46
  417. agno/app/settings.py +0 -15
  418. agno/app/slack/__init__.py +0 -3
  419. agno/app/slack/app.py +0 -19
  420. agno/app/slack/sync_router.py +0 -92
  421. agno/app/utils.py +0 -54
  422. agno/app/whatsapp/__init__.py +0 -3
  423. agno/app/whatsapp/app.py +0 -15
  424. agno/app/whatsapp/sync_router.py +0 -197
  425. agno/cli/auth_server.py +0 -249
  426. agno/cli/config.py +0 -274
  427. agno/cli/console.py +0 -88
  428. agno/cli/credentials.py +0 -23
  429. agno/cli/entrypoint.py +0 -571
  430. agno/cli/operator.py +0 -357
  431. agno/cli/settings.py +0 -96
  432. agno/cli/ws/ws_cli.py +0 -817
  433. agno/constants.py +0 -13
  434. agno/document/__init__.py +0 -5
  435. agno/document/chunking/semantic.py +0 -45
  436. agno/document/chunking/strategy.py +0 -31
  437. agno/document/reader/__init__.py +0 -5
  438. agno/document/reader/base.py +0 -47
  439. agno/document/reader/docx_reader.py +0 -60
  440. agno/document/reader/gcs/pdf_reader.py +0 -44
  441. agno/document/reader/s3/pdf_reader.py +0 -59
  442. agno/document/reader/s3/text_reader.py +0 -63
  443. agno/document/reader/url_reader.py +0 -59
  444. agno/document/reader/youtube_reader.py +0 -58
  445. agno/embedder/__init__.py +0 -5
  446. agno/embedder/langdb.py +0 -80
  447. agno/embedder/mistral.py +0 -82
  448. agno/embedder/openai.py +0 -78
  449. agno/file/__init__.py +0 -5
  450. agno/file/file.py +0 -16
  451. agno/file/local/csv.py +0 -32
  452. agno/file/local/txt.py +0 -19
  453. agno/infra/app.py +0 -240
  454. agno/infra/base.py +0 -144
  455. agno/infra/context.py +0 -20
  456. agno/infra/db_app.py +0 -52
  457. agno/infra/resource.py +0 -205
  458. agno/infra/resources.py +0 -55
  459. agno/knowledge/agent.py +0 -702
  460. agno/knowledge/arxiv.py +0 -33
  461. agno/knowledge/combined.py +0 -36
  462. agno/knowledge/csv.py +0 -144
  463. agno/knowledge/csv_url.py +0 -124
  464. agno/knowledge/document.py +0 -223
  465. agno/knowledge/docx.py +0 -137
  466. agno/knowledge/firecrawl.py +0 -34
  467. agno/knowledge/gcs/__init__.py +0 -0
  468. agno/knowledge/gcs/base.py +0 -39
  469. agno/knowledge/gcs/pdf.py +0 -125
  470. agno/knowledge/json.py +0 -137
  471. agno/knowledge/langchain.py +0 -71
  472. agno/knowledge/light_rag.py +0 -273
  473. agno/knowledge/llamaindex.py +0 -66
  474. agno/knowledge/markdown.py +0 -154
  475. agno/knowledge/pdf.py +0 -164
  476. agno/knowledge/pdf_bytes.py +0 -42
  477. agno/knowledge/pdf_url.py +0 -148
  478. agno/knowledge/s3/__init__.py +0 -0
  479. agno/knowledge/s3/base.py +0 -64
  480. agno/knowledge/s3/pdf.py +0 -33
  481. agno/knowledge/s3/text.py +0 -34
  482. agno/knowledge/text.py +0 -141
  483. agno/knowledge/url.py +0 -46
  484. agno/knowledge/website.py +0 -179
  485. agno/knowledge/wikipedia.py +0 -32
  486. agno/knowledge/youtube.py +0 -35
  487. agno/memory/agent.py +0 -423
  488. agno/memory/classifier.py +0 -104
  489. agno/memory/db/__init__.py +0 -5
  490. agno/memory/db/base.py +0 -42
  491. agno/memory/db/mongodb.py +0 -189
  492. agno/memory/db/postgres.py +0 -203
  493. agno/memory/db/sqlite.py +0 -193
  494. agno/memory/memory.py +0 -22
  495. agno/memory/row.py +0 -36
  496. agno/memory/summarizer.py +0 -201
  497. agno/memory/summary.py +0 -19
  498. agno/memory/team.py +0 -415
  499. agno/memory/v2/__init__.py +0 -2
  500. agno/memory/v2/db/__init__.py +0 -1
  501. agno/memory/v2/db/base.py +0 -42
  502. agno/memory/v2/db/firestore.py +0 -339
  503. agno/memory/v2/db/mongodb.py +0 -196
  504. agno/memory/v2/db/postgres.py +0 -214
  505. agno/memory/v2/db/redis.py +0 -187
  506. agno/memory/v2/db/schema.py +0 -54
  507. agno/memory/v2/db/sqlite.py +0 -209
  508. agno/memory/v2/manager.py +0 -437
  509. agno/memory/v2/memory.py +0 -1097
  510. agno/memory/v2/schema.py +0 -55
  511. agno/memory/v2/summarizer.py +0 -215
  512. agno/memory/workflow.py +0 -38
  513. agno/models/ollama/tools.py +0 -430
  514. agno/models/qwen/__init__.py +0 -5
  515. agno/playground/__init__.py +0 -10
  516. agno/playground/deploy.py +0 -3
  517. agno/playground/playground.py +0 -3
  518. agno/playground/serve.py +0 -3
  519. agno/playground/settings.py +0 -3
  520. agno/reranker/__init__.py +0 -0
  521. agno/run/response.py +0 -467
  522. agno/run/v2/__init__.py +0 -0
  523. agno/run/v2/workflow.py +0 -567
  524. agno/storage/__init__.py +0 -0
  525. agno/storage/agent/__init__.py +0 -0
  526. agno/storage/agent/dynamodb.py +0 -1
  527. agno/storage/agent/json.py +0 -1
  528. agno/storage/agent/mongodb.py +0 -1
  529. agno/storage/agent/postgres.py +0 -1
  530. agno/storage/agent/singlestore.py +0 -1
  531. agno/storage/agent/sqlite.py +0 -1
  532. agno/storage/agent/yaml.py +0 -1
  533. agno/storage/base.py +0 -60
  534. agno/storage/dynamodb.py +0 -673
  535. agno/storage/firestore.py +0 -297
  536. agno/storage/gcs_json.py +0 -261
  537. agno/storage/in_memory.py +0 -234
  538. agno/storage/json.py +0 -237
  539. agno/storage/mongodb.py +0 -328
  540. agno/storage/mysql.py +0 -685
  541. agno/storage/postgres.py +0 -682
  542. agno/storage/redis.py +0 -336
  543. agno/storage/session/__init__.py +0 -16
  544. agno/storage/session/agent.py +0 -64
  545. agno/storage/session/team.py +0 -63
  546. agno/storage/session/v2/__init__.py +0 -5
  547. agno/storage/session/workflow.py +0 -61
  548. agno/storage/singlestore.py +0 -606
  549. agno/storage/sqlite.py +0 -646
  550. agno/storage/workflow/__init__.py +0 -0
  551. agno/storage/workflow/mongodb.py +0 -1
  552. agno/storage/workflow/postgres.py +0 -1
  553. agno/storage/workflow/sqlite.py +0 -1
  554. agno/storage/yaml.py +0 -241
  555. agno/tools/thinking.py +0 -73
  556. agno/utils/defaults.py +0 -57
  557. agno/utils/filesystem.py +0 -39
  558. agno/utils/git.py +0 -52
  559. agno/utils/json_io.py +0 -30
  560. agno/utils/load_env.py +0 -19
  561. agno/utils/py_io.py +0 -19
  562. agno/utils/pyproject.py +0 -18
  563. agno/utils/resource_filter.py +0 -31
  564. agno/workflow/v2/__init__.py +0 -21
  565. agno/workflow/v2/types.py +0 -357
  566. agno/workflow/v2/workflow.py +0 -3313
  567. agno/workspace/__init__.py +0 -0
  568. agno/workspace/config.py +0 -325
  569. agno/workspace/enums.py +0 -6
  570. agno/workspace/helpers.py +0 -52
  571. agno/workspace/operator.py +0 -757
  572. agno/workspace/settings.py +0 -158
  573. agno-1.8.2.dist-info/METADATA +0 -982
  574. agno-1.8.2.dist-info/RECORD +0 -566
  575. agno-1.8.2.dist-info/entry_points.txt +0 -3
  576. agno-1.8.2.dist-info/licenses/LICENSE +0 -375
  577. /agno/{app → db/migrations}/__init__.py +0 -0
  578. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  579. /agno/{cli → integrations}/__init__.py +0 -0
  580. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  581. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  582. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  583. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  584. /agno/{app → os/interfaces}/slack/security.py +0 -0
  585. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  586. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  587. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  588. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  589. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
@@ -2,15 +2,18 @@ from collections.abc import AsyncIterator
2
2
  from dataclasses import dataclass
3
3
  from os import getenv
4
4
  from typing import Any, Dict, Iterator, List, Literal, Optional, Type, Union
5
+ from uuid import uuid4
5
6
 
6
7
  import httpx
7
8
  from pydantic import BaseModel
8
9
 
9
10
  from agno.exceptions import ModelProviderError
10
- from agno.media import AudioResponse
11
+ from agno.media import Audio
11
12
  from agno.models.base import Model
12
13
  from agno.models.message import Message
14
+ from agno.models.metrics import Metrics
13
15
  from agno.models.response import ModelResponse
16
+ from agno.run.agent import RunOutput
14
17
  from agno.utils.log import log_debug, log_error, log_warning
15
18
  from agno.utils.openai import _format_file_for_message, audio_to_message, images_to_message
16
19
 
@@ -18,6 +21,7 @@ try:
18
21
  from openai import APIConnectionError, APIStatusError, RateLimitError
19
22
  from openai import AsyncOpenAI as AsyncOpenAIClient
20
23
  from openai import OpenAI as OpenAIClient
24
+ from openai.types import CompletionUsage
21
25
  from openai.types.chat import ChatCompletionAudio
22
26
  from openai.types.chat.chat_completion import ChatCompletion
23
27
  from openai.types.chat.chat_completion_chunk import (
@@ -215,6 +219,15 @@ class OpenAIChat(Model):
215
219
 
216
220
  # Add tools
217
221
  if tools is not None and len(tools) > 0:
222
+ # Remove unsupported fields for OpenAILike models
223
+ if self.provider in ["AIMLAPI", "Fireworks", "Nvidia"]:
224
+ for tool in tools:
225
+ if tool.get("type") == "function":
226
+ if tool["function"].get("requires_confirmation") is not None:
227
+ del tool["function"]["requires_confirmation"]
228
+ if tool["function"].get("external_execution") is not None:
229
+ del tool["function"]["external_execution"]
230
+
218
231
  request_params["tools"] = tools
219
232
 
220
233
  if tool_choice is not None:
@@ -330,25 +343,43 @@ class OpenAIChat(Model):
330
343
  def invoke(
331
344
  self,
332
345
  messages: List[Message],
346
+ assistant_message: Message,
333
347
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
334
348
  tools: Optional[List[Dict[str, Any]]] = None,
335
349
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
336
- ) -> ChatCompletion:
350
+ run_response: Optional[RunOutput] = None,
351
+ ) -> ModelResponse:
337
352
  """
338
- Send a chat completion request to the OpenAI API.
353
+ Send a chat completion request to the OpenAI API and parse the response.
339
354
 
340
355
  Args:
341
356
  messages (List[Message]): A list of messages to send to the model.
357
+ assistant_message (Message): The assistant message to populate.
358
+ response_format (Optional[Union[Dict, Type[BaseModel]]]): The response format to use.
359
+ tools (Optional[List[Dict[str, Any]]]): The tools to use.
360
+ tool_choice (Optional[Union[str, Dict[str, Any]]]): The tool choice to use.
342
361
 
343
362
  Returns:
344
- ChatCompletion: The chat completion response from the API.
363
+ ModelResponse: The chat completion response from the API.
345
364
  """
346
365
  try:
347
- return self.get_client().chat.completions.create(
366
+ if run_response and run_response.metrics:
367
+ run_response.metrics.set_time_to_first_token()
368
+
369
+ assistant_message.metrics.start_timer()
370
+
371
+ provider_response = self.get_client().chat.completions.create(
348
372
  model=self.id,
349
373
  messages=[self._format_message(m) for m in messages], # type: ignore
350
374
  **self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
351
375
  )
376
+ assistant_message.metrics.stop_timer()
377
+
378
+ # Parse the response into an Agno ModelResponse object
379
+ model_response = self._parse_provider_response(provider_response, response_format=response_format)
380
+
381
+ return model_response
382
+
352
383
  except RateLimitError as e:
353
384
  log_error(f"Rate limit error from OpenAI API: {e}")
354
385
  error_message = e.response.json().get("error", {})
@@ -390,25 +421,42 @@ class OpenAIChat(Model):
390
421
  async def ainvoke(
391
422
  self,
392
423
  messages: List[Message],
424
+ assistant_message: Message,
393
425
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
394
426
  tools: Optional[List[Dict[str, Any]]] = None,
395
427
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
396
- ) -> ChatCompletion:
428
+ run_response: Optional[RunOutput] = None,
429
+ ) -> ModelResponse:
397
430
  """
398
431
  Sends an asynchronous chat completion request to the OpenAI API.
399
432
 
400
433
  Args:
401
434
  messages (List[Message]): A list of messages to send to the model.
435
+ assistant_message (Message): The assistant message to populate.
436
+ response_format (Optional[Union[Dict, Type[BaseModel]]]): The response format to use.
437
+ tools (Optional[List[Dict[str, Any]]]): The tools to use.
438
+ tool_choice (Optional[Union[str, Dict[str, Any]]]): The tool choice to use.
402
439
 
403
440
  Returns:
404
- ChatCompletion: The chat completion response from the API.
441
+ ModelResponse: The chat completion response from the API.
405
442
  """
406
443
  try:
407
- return await self.get_async_client().chat.completions.create(
444
+ if run_response and run_response.metrics:
445
+ run_response.metrics.set_time_to_first_token()
446
+
447
+ assistant_message.metrics.start_timer()
448
+ response = await self.get_async_client().chat.completions.create(
408
449
  model=self.id,
409
450
  messages=[self._format_message(m) for m in messages], # type: ignore
410
451
  **self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
411
452
  )
453
+ assistant_message.metrics.stop_timer()
454
+
455
+ # Parse the response into an Agno ModelResponse object
456
+ provider_response: ModelResponse = self._parse_provider_response(response, response_format=response_format)
457
+
458
+ return provider_response
459
+
412
460
  except RateLimitError as e:
413
461
  log_error(f"Rate limit error from OpenAI API: {e}")
414
462
  error_message = e.response.json().get("error", {})
@@ -450,10 +498,12 @@ class OpenAIChat(Model):
450
498
  def invoke_stream(
451
499
  self,
452
500
  messages: List[Message],
501
+ assistant_message: Message,
453
502
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
454
503
  tools: Optional[List[Dict[str, Any]]] = None,
455
504
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
456
- ) -> Iterator[ChatCompletionChunk]:
505
+ run_response: Optional[RunOutput] = None,
506
+ ) -> Iterator[ModelResponse]:
457
507
  """
458
508
  Send a streaming chat completion request to the OpenAI API.
459
509
 
@@ -461,17 +511,26 @@ class OpenAIChat(Model):
461
511
  messages (List[Message]): A list of messages to send to the model.
462
512
 
463
513
  Returns:
464
- Iterator[ChatCompletionChunk]: An iterator of chat completion chunks.
514
+ Iterator[ModelResponse]: An iterator of model responses.
465
515
  """
466
516
 
467
517
  try:
468
- yield from self.get_client().chat.completions.create(
518
+ if run_response and run_response.metrics:
519
+ run_response.metrics.set_time_to_first_token()
520
+
521
+ assistant_message.metrics.start_timer()
522
+
523
+ for chunk in self.get_client().chat.completions.create(
469
524
  model=self.id,
470
525
  messages=[self._format_message(m) for m in messages], # type: ignore
471
526
  stream=True,
472
527
  stream_options={"include_usage": True},
473
528
  **self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
474
- ) # type: ignore
529
+ ):
530
+ yield self._parse_provider_response_delta(chunk)
531
+
532
+ assistant_message.metrics.stop_timer()
533
+
475
534
  except RateLimitError as e:
476
535
  log_error(f"Rate limit error from OpenAI API: {e}")
477
536
  error_message = e.response.json().get("error", {})
@@ -513,10 +572,12 @@ class OpenAIChat(Model):
513
572
  async def ainvoke_stream(
514
573
  self,
515
574
  messages: List[Message],
575
+ assistant_message: Message,
516
576
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
517
577
  tools: Optional[List[Dict[str, Any]]] = None,
518
578
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
519
- ) -> AsyncIterator[ChatCompletionChunk]:
579
+ run_response: Optional[RunOutput] = None,
580
+ ) -> AsyncIterator[ModelResponse]:
520
581
  """
521
582
  Sends an asynchronous streaming chat completion request to the OpenAI API.
522
583
 
@@ -524,10 +585,15 @@ class OpenAIChat(Model):
524
585
  messages (List[Message]): A list of messages to send to the model.
525
586
 
526
587
  Returns:
527
- Any: An asynchronous iterator of chat completion chunks.
588
+ Any: An asynchronous iterator of model responses.
528
589
  """
529
590
 
530
591
  try:
592
+ if run_response and run_response.metrics:
593
+ run_response.metrics.set_time_to_first_token()
594
+
595
+ assistant_message.metrics.start_timer()
596
+
531
597
  async_stream = await self.get_async_client().chat.completions.create(
532
598
  model=self.id,
533
599
  messages=[self._format_message(m) for m in messages], # type: ignore
@@ -535,8 +601,12 @@ class OpenAIChat(Model):
535
601
  stream_options={"include_usage": True},
536
602
  **self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
537
603
  )
604
+
538
605
  async for chunk in async_stream:
539
- yield chunk
606
+ yield self._parse_provider_response_delta(chunk)
607
+
608
+ assistant_message.metrics.stop_timer()
609
+
540
610
  except RateLimitError as e:
541
611
  log_error(f"Rate limit error from OpenAI API: {e}")
542
612
  error_message = e.response.json().get("error", {})
@@ -575,7 +645,6 @@ class OpenAIChat(Model):
575
645
  log_error(f"Error from OpenAI API: {e}")
576
646
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
577
647
 
578
- # Override base method
579
648
  @staticmethod
580
649
  def parse_tool_calls(tool_calls_data: List[ChoiceDeltaToolCall]) -> List[Dict[str, Any]]:
581
650
  """
@@ -616,7 +685,7 @@ class OpenAIChat(Model):
616
685
  tool_call_entry["type"] = _tool_call_type
617
686
  return tool_calls
618
687
 
619
- def parse_provider_response(
688
+ def _parse_provider_response(
620
689
  self,
621
690
  response: ChatCompletion,
622
691
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
@@ -626,9 +695,9 @@ class OpenAIChat(Model):
626
695
  """
627
696
  model_response = ModelResponse()
628
697
 
629
- if hasattr(response, "error") and response.error:
698
+ if hasattr(response, "error") and response.error: # type: ignore
630
699
  raise ModelProviderError(
631
- message=response.error.get("message", "Unknown model error"),
700
+ message=response.error.get("message", "Unknown model error"), # type: ignore
632
701
  model_name=self.name,
633
702
  model_id=self.id,
634
703
  )
@@ -661,14 +730,14 @@ class OpenAIChat(Model):
661
730
  # If the audio output modality is requested, we can extract an audio response
662
731
  try:
663
732
  if isinstance(response_message.audio, dict):
664
- model_response.audio = AudioResponse(
733
+ model_response.audio = Audio(
665
734
  id=response_message.audio.get("id"),
666
735
  content=response_message.audio.get("data"),
667
736
  expires_at=response_message.audio.get("expires_at"),
668
737
  transcript=response_message.audio.get("transcript"),
669
738
  )
670
739
  else:
671
- model_response.audio = AudioResponse(
740
+ model_response.audio = Audio(
672
741
  id=response_message.audio.id,
673
742
  content=response_message.audio.data,
674
743
  expires_at=response_message.audio.expires_at,
@@ -677,15 +746,15 @@ class OpenAIChat(Model):
677
746
  except Exception as e:
678
747
  log_warning(f"Error processing audio: {e}")
679
748
 
680
- if hasattr(response_message, "reasoning_content") and response_message.reasoning_content is not None:
681
- model_response.reasoning_content = response_message.reasoning_content
749
+ if hasattr(response_message, "reasoning_content") and response_message.reasoning_content is not None: # type: ignore
750
+ model_response.reasoning_content = response_message.reasoning_content # type: ignore
682
751
 
683
752
  if response.usage is not None:
684
- model_response.response_usage = response.usage
753
+ model_response.response_usage = self._get_metrics(response.usage)
685
754
 
686
755
  return model_response
687
756
 
688
- def parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
757
+ def _parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
689
758
  """
690
759
  Parse the OpenAI streaming response into a ModelResponse.
691
760
 
@@ -696,6 +765,7 @@ class OpenAIChat(Model):
696
765
  ModelResponse: Parsed response data
697
766
  """
698
767
  model_response = ModelResponse()
768
+
699
769
  if response_delta.choices and len(response_delta.choices) > 0:
700
770
  choice_delta: ChoiceDelta = response_delta.choices[0].delta
701
771
 
@@ -714,21 +784,39 @@ class OpenAIChat(Model):
714
784
  # Add audio if present
715
785
  if hasattr(choice_delta, "audio") and choice_delta.audio is not None:
716
786
  try:
787
+ audio_data = None
788
+ audio_id = None
789
+ audio_expires_at = None
790
+ audio_transcript = None
791
+
717
792
  if isinstance(choice_delta.audio, dict):
718
- model_response.audio = AudioResponse(
719
- id=choice_delta.audio.get("id"),
720
- content=choice_delta.audio.get("data"),
721
- expires_at=choice_delta.audio.get("expires_at"),
722
- transcript=choice_delta.audio.get("transcript"),
793
+ audio_data = choice_delta.audio.get("data")
794
+ audio_id = choice_delta.audio.get("id")
795
+ audio_expires_at = choice_delta.audio.get("expires_at")
796
+ audio_transcript = choice_delta.audio.get("transcript")
797
+ else:
798
+ audio_data = choice_delta.audio.data
799
+ audio_id = choice_delta.audio.id
800
+ audio_expires_at = choice_delta.audio.expires_at
801
+ audio_transcript = choice_delta.audio.transcript
802
+
803
+ # Only create Audio object if there's actual content
804
+ if audio_data is not None:
805
+ model_response.audio = Audio(
806
+ id=audio_id,
807
+ content=audio_data,
808
+ expires_at=audio_expires_at,
809
+ transcript=audio_transcript,
723
810
  sample_rate=24000,
724
811
  mime_type="pcm16",
725
812
  )
726
- else:
727
- model_response.audio = AudioResponse(
728
- id=choice_delta.audio.id,
729
- content=choice_delta.audio.data,
730
- expires_at=choice_delta.audio.expires_at,
731
- transcript=choice_delta.audio.transcript,
813
+ # If no content but there's transcript/metadata, create minimal Audio object
814
+ elif audio_transcript is not None or audio_id is not None:
815
+ model_response.audio = Audio(
816
+ id=audio_id or str(uuid4()),
817
+ content=b"",
818
+ expires_at=audio_expires_at,
819
+ transcript=audio_transcript,
732
820
  sample_rate=24000,
733
821
  mime_type="pcm16",
734
822
  )
@@ -737,6 +825,35 @@ class OpenAIChat(Model):
737
825
 
738
826
  # Add usage metrics if present
739
827
  if response_delta.usage is not None:
740
- model_response.response_usage = response_delta.usage
828
+ model_response.response_usage = self._get_metrics(response_delta.usage)
741
829
 
742
830
  return model_response
831
+
832
+ def _get_metrics(self, response_usage: CompletionUsage) -> Metrics:
833
+ """
834
+ Parse the given OpenAI-specific usage into an Agno Metrics object.
835
+
836
+ Args:
837
+ response_usage: Usage data from OpenAI
838
+
839
+ Returns:
840
+ Metrics: Parsed metrics data
841
+ """
842
+
843
+ metrics = Metrics()
844
+
845
+ metrics.input_tokens = response_usage.prompt_tokens or 0
846
+ metrics.output_tokens = response_usage.completion_tokens or 0
847
+ metrics.total_tokens = response_usage.total_tokens or 0
848
+
849
+ # Add the prompt_tokens_details field
850
+ if prompt_token_details := response_usage.prompt_tokens_details:
851
+ metrics.audio_input_tokens = prompt_token_details.audio_tokens or 0
852
+ metrics.cache_read_tokens = prompt_token_details.cached_tokens or 0
853
+
854
+ # Add the completion_tokens_details field
855
+ if completion_tokens_details := response_usage.completion_tokens_details:
856
+ metrics.audio_output_tokens = completion_tokens_details.audio_tokens or 0
857
+ metrics.reasoning_tokens = completion_tokens_details.reasoning_tokens or 0
858
+
859
+ return metrics