agno 1.8.1__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 (590) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +3143 -4170
  4. agno/api/agent.py +11 -67
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +8 -19
  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 +11 -66
  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 +1743 -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 +1432 -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 +882 -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 +1045 -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 +1416 -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 +297 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1710 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +280 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1367 -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 +1712 -0
  67. agno/db/singlestore/utils.py +326 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1676 -0
  71. agno/db/sqlite/utils.py +268 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +154 -48
  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 +15 -11
  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 +1551 -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 +47 -65
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/{document → knowledge}/reader/json_reader.py +30 -9
  118. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  119. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  120. agno/knowledge/reader/reader_factory.py +268 -0
  121. agno/knowledge/reader/s3_reader.py +101 -0
  122. agno/{document → knowledge}/reader/text_reader.py +31 -10
  123. agno/knowledge/reader/url_reader.py +128 -0
  124. agno/knowledge/reader/web_search_reader.py +366 -0
  125. agno/{document → knowledge}/reader/website_reader.py +37 -10
  126. agno/knowledge/reader/wikipedia_reader.py +59 -0
  127. agno/knowledge/reader/youtube_reader.py +78 -0
  128. agno/knowledge/remote_content/remote_content.py +88 -0
  129. agno/{reranker → knowledge/reranker}/base.py +1 -1
  130. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  131. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  132. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  133. agno/knowledge/types.py +30 -0
  134. agno/knowledge/utils.py +169 -0
  135. agno/media.py +269 -268
  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 +131 -131
  141. agno/models/aws/bedrock.py +110 -182
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +346 -290
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +105 -46
  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 +46 -151
  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 +85 -47
  158. agno/models/openai/chat.py +154 -37
  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 +15 -9
  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 +497 -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 +77 -33
  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 +32 -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 +29 -0
  184. agno/os/mcp.py +235 -0
  185. agno/os/router.py +1400 -0
  186. agno/os/routers/__init__.py +3 -0
  187. agno/os/routers/evals/__init__.py +3 -0
  188. agno/os/routers/evals/evals.py +393 -0
  189. agno/os/routers/evals/schemas.py +142 -0
  190. agno/os/routers/evals/utils.py +161 -0
  191. agno/os/routers/knowledge/__init__.py +3 -0
  192. agno/os/routers/knowledge/knowledge.py +850 -0
  193. agno/os/routers/knowledge/schemas.py +118 -0
  194. agno/os/routers/memory/__init__.py +3 -0
  195. agno/os/routers/memory/memory.py +410 -0
  196. agno/os/routers/memory/schemas.py +58 -0
  197. agno/os/routers/metrics/__init__.py +3 -0
  198. agno/os/routers/metrics/metrics.py +178 -0
  199. agno/os/routers/metrics/schemas.py +47 -0
  200. agno/os/routers/session/__init__.py +3 -0
  201. agno/os/routers/session/session.py +536 -0
  202. agno/os/schema.py +945 -0
  203. agno/{app/playground → os}/settings.py +7 -15
  204. agno/os/utils.py +270 -0
  205. agno/reasoning/azure_ai_foundry.py +4 -4
  206. agno/reasoning/deepseek.py +4 -4
  207. agno/reasoning/default.py +6 -11
  208. agno/reasoning/groq.py +4 -4
  209. agno/reasoning/helpers.py +4 -6
  210. agno/reasoning/ollama.py +4 -4
  211. agno/reasoning/openai.py +4 -4
  212. agno/run/agent.py +633 -0
  213. agno/run/base.py +53 -77
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +243 -96
  216. agno/run/workflow.py +550 -12
  217. agno/session/__init__.py +10 -0
  218. agno/session/agent.py +244 -0
  219. agno/session/summary.py +225 -0
  220. agno/session/team.py +262 -0
  221. agno/{storage/session/v2 → session}/workflow.py +47 -24
  222. agno/team/__init__.py +15 -16
  223. agno/team/team.py +3260 -4824
  224. agno/tools/agentql.py +14 -5
  225. agno/tools/airflow.py +9 -4
  226. agno/tools/api.py +7 -3
  227. agno/tools/apify.py +2 -46
  228. agno/tools/arxiv.py +8 -3
  229. agno/tools/aws_lambda.py +7 -5
  230. agno/tools/aws_ses.py +7 -1
  231. agno/tools/baidusearch.py +4 -1
  232. agno/tools/bitbucket.py +4 -4
  233. agno/tools/brandfetch.py +14 -11
  234. agno/tools/bravesearch.py +4 -1
  235. agno/tools/brightdata.py +43 -23
  236. agno/tools/browserbase.py +13 -4
  237. agno/tools/calcom.py +12 -10
  238. agno/tools/calculator.py +10 -27
  239. agno/tools/cartesia.py +20 -17
  240. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  241. agno/tools/confluence.py +8 -8
  242. agno/tools/crawl4ai.py +7 -1
  243. agno/tools/csv_toolkit.py +9 -8
  244. agno/tools/dalle.py +22 -12
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +17 -8
  248. agno/tools/discord.py +11 -8
  249. agno/tools/docker.py +30 -42
  250. agno/tools/duckdb.py +34 -53
  251. agno/tools/duckduckgo.py +8 -7
  252. agno/tools/e2b.py +62 -62
  253. agno/tools/eleven_labs.py +36 -29
  254. agno/tools/email.py +4 -1
  255. agno/tools/evm.py +7 -1
  256. agno/tools/exa.py +19 -14
  257. agno/tools/fal.py +30 -30
  258. agno/tools/file.py +9 -8
  259. agno/tools/financial_datasets.py +25 -44
  260. agno/tools/firecrawl.py +22 -22
  261. agno/tools/function.py +127 -18
  262. agno/tools/giphy.py +23 -11
  263. agno/tools/github.py +48 -126
  264. agno/tools/gmail.py +45 -61
  265. agno/tools/google_bigquery.py +7 -6
  266. agno/tools/google_maps.py +11 -26
  267. agno/tools/googlesearch.py +7 -2
  268. agno/tools/googlesheets.py +21 -17
  269. agno/tools/hackernews.py +9 -5
  270. agno/tools/jina.py +5 -4
  271. agno/tools/jira.py +18 -9
  272. agno/tools/knowledge.py +31 -32
  273. agno/tools/linear.py +19 -34
  274. agno/tools/linkup.py +5 -1
  275. agno/tools/local_file_system.py +8 -5
  276. agno/tools/lumalab.py +32 -20
  277. agno/tools/mcp.py +1 -2
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +33 -15
  282. agno/tools/models/gemini.py +59 -32
  283. agno/tools/models/groq.py +30 -23
  284. agno/tools/models/nebius.py +28 -12
  285. agno/tools/models_labs.py +40 -16
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +10 -8
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +58 -32
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +63 -47
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +55 -42
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +100 -123
  335. agno/utils/gemini.py +32 -2
  336. agno/utils/knowledge.py +29 -0
  337. agno/utils/log.py +54 -4
  338. agno/utils/mcp.py +68 -10
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/aws_claude.py +1 -1
  342. agno/utils/models/claude.py +47 -4
  343. agno/utils/models/cohere.py +1 -1
  344. agno/utils/models/mistral.py +8 -7
  345. agno/utils/models/schema_utils.py +3 -3
  346. agno/utils/models/watsonx.py +1 -1
  347. agno/utils/openai.py +1 -1
  348. agno/utils/pprint.py +33 -32
  349. agno/utils/print_response/agent.py +779 -0
  350. agno/utils/print_response/team.py +1669 -0
  351. agno/utils/print_response/workflow.py +1451 -0
  352. agno/utils/prompts.py +14 -14
  353. agno/utils/reasoning.py +87 -0
  354. agno/utils/response.py +42 -42
  355. agno/utils/streamlit.py +481 -0
  356. agno/utils/string.py +8 -22
  357. agno/utils/team.py +50 -0
  358. agno/utils/timer.py +2 -2
  359. agno/vectordb/base.py +33 -21
  360. agno/vectordb/cassandra/cassandra.py +287 -23
  361. agno/vectordb/chroma/chromadb.py +482 -59
  362. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  363. agno/vectordb/couchbase/couchbase.py +309 -29
  364. agno/vectordb/lancedb/lance_db.py +360 -21
  365. agno/vectordb/langchaindb/__init__.py +5 -0
  366. agno/vectordb/langchaindb/langchaindb.py +145 -0
  367. agno/vectordb/lightrag/__init__.py +5 -0
  368. agno/vectordb/lightrag/lightrag.py +374 -0
  369. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  370. agno/vectordb/milvus/milvus.py +242 -32
  371. agno/vectordb/mongodb/mongodb.py +200 -24
  372. agno/vectordb/pgvector/pgvector.py +319 -37
  373. agno/vectordb/pineconedb/pineconedb.py +221 -27
  374. agno/vectordb/qdrant/qdrant.py +334 -14
  375. agno/vectordb/singlestore/singlestore.py +286 -29
  376. agno/vectordb/surrealdb/surrealdb.py +187 -7
  377. agno/vectordb/upstashdb/upstashdb.py +342 -26
  378. agno/vectordb/weaviate/weaviate.py +227 -165
  379. agno/workflow/__init__.py +17 -13
  380. agno/workflow/{v2/condition.py → condition.py} +135 -32
  381. agno/workflow/{v2/loop.py → loop.py} +115 -28
  382. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  383. agno/workflow/{v2/router.py → router.py} +133 -32
  384. agno/workflow/{v2/step.py → step.py} +207 -49
  385. agno/workflow/{v2/steps.py → steps.py} +147 -66
  386. agno/workflow/types.py +482 -0
  387. agno/workflow/workflow.py +2410 -696
  388. agno-2.0.0.dist-info/METADATA +494 -0
  389. agno-2.0.0.dist-info/RECORD +515 -0
  390. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  391. agno/agent/metrics.py +0 -107
  392. agno/api/app.py +0 -35
  393. agno/api/playground.py +0 -92
  394. agno/api/schemas/app.py +0 -12
  395. agno/api/schemas/playground.py +0 -22
  396. agno/api/schemas/user.py +0 -35
  397. agno/api/schemas/workspace.py +0 -46
  398. agno/api/user.py +0 -160
  399. agno/api/workflows.py +0 -33
  400. agno/api/workspace.py +0 -175
  401. agno/app/agui/__init__.py +0 -3
  402. agno/app/agui/app.py +0 -17
  403. agno/app/agui/sync_router.py +0 -120
  404. agno/app/base.py +0 -186
  405. agno/app/discord/__init__.py +0 -3
  406. agno/app/fastapi/__init__.py +0 -3
  407. agno/app/fastapi/app.py +0 -107
  408. agno/app/fastapi/async_router.py +0 -457
  409. agno/app/fastapi/sync_router.py +0 -448
  410. agno/app/playground/app.py +0 -228
  411. agno/app/playground/async_router.py +0 -1050
  412. agno/app/playground/deploy.py +0 -249
  413. agno/app/playground/operator.py +0 -183
  414. agno/app/playground/schemas.py +0 -220
  415. agno/app/playground/serve.py +0 -55
  416. agno/app/playground/sync_router.py +0 -1042
  417. agno/app/playground/utils.py +0 -46
  418. agno/app/settings.py +0 -15
  419. agno/app/slack/__init__.py +0 -3
  420. agno/app/slack/app.py +0 -19
  421. agno/app/slack/sync_router.py +0 -92
  422. agno/app/utils.py +0 -54
  423. agno/app/whatsapp/__init__.py +0 -3
  424. agno/app/whatsapp/app.py +0 -15
  425. agno/app/whatsapp/sync_router.py +0 -197
  426. agno/cli/auth_server.py +0 -249
  427. agno/cli/config.py +0 -274
  428. agno/cli/console.py +0 -88
  429. agno/cli/credentials.py +0 -23
  430. agno/cli/entrypoint.py +0 -571
  431. agno/cli/operator.py +0 -357
  432. agno/cli/settings.py +0 -96
  433. agno/cli/ws/ws_cli.py +0 -817
  434. agno/constants.py +0 -13
  435. agno/document/__init__.py +0 -5
  436. agno/document/chunking/semantic.py +0 -45
  437. agno/document/chunking/strategy.py +0 -31
  438. agno/document/reader/__init__.py +0 -5
  439. agno/document/reader/base.py +0 -47
  440. agno/document/reader/docx_reader.py +0 -60
  441. agno/document/reader/gcs/pdf_reader.py +0 -44
  442. agno/document/reader/s3/pdf_reader.py +0 -59
  443. agno/document/reader/s3/text_reader.py +0 -63
  444. agno/document/reader/url_reader.py +0 -59
  445. agno/document/reader/youtube_reader.py +0 -58
  446. agno/embedder/__init__.py +0 -5
  447. agno/embedder/langdb.py +0 -80
  448. agno/embedder/mistral.py +0 -82
  449. agno/embedder/openai.py +0 -78
  450. agno/file/__init__.py +0 -5
  451. agno/file/file.py +0 -16
  452. agno/file/local/csv.py +0 -32
  453. agno/file/local/txt.py +0 -19
  454. agno/infra/app.py +0 -240
  455. agno/infra/base.py +0 -144
  456. agno/infra/context.py +0 -20
  457. agno/infra/db_app.py +0 -52
  458. agno/infra/resource.py +0 -205
  459. agno/infra/resources.py +0 -55
  460. agno/knowledge/agent.py +0 -702
  461. agno/knowledge/arxiv.py +0 -33
  462. agno/knowledge/combined.py +0 -36
  463. agno/knowledge/csv.py +0 -144
  464. agno/knowledge/csv_url.py +0 -124
  465. agno/knowledge/document.py +0 -223
  466. agno/knowledge/docx.py +0 -137
  467. agno/knowledge/firecrawl.py +0 -34
  468. agno/knowledge/gcs/__init__.py +0 -0
  469. agno/knowledge/gcs/base.py +0 -39
  470. agno/knowledge/gcs/pdf.py +0 -125
  471. agno/knowledge/json.py +0 -137
  472. agno/knowledge/langchain.py +0 -71
  473. agno/knowledge/light_rag.py +0 -273
  474. agno/knowledge/llamaindex.py +0 -66
  475. agno/knowledge/markdown.py +0 -154
  476. agno/knowledge/pdf.py +0 -164
  477. agno/knowledge/pdf_bytes.py +0 -42
  478. agno/knowledge/pdf_url.py +0 -148
  479. agno/knowledge/s3/__init__.py +0 -0
  480. agno/knowledge/s3/base.py +0 -64
  481. agno/knowledge/s3/pdf.py +0 -33
  482. agno/knowledge/s3/text.py +0 -34
  483. agno/knowledge/text.py +0 -141
  484. agno/knowledge/url.py +0 -46
  485. agno/knowledge/website.py +0 -179
  486. agno/knowledge/wikipedia.py +0 -32
  487. agno/knowledge/youtube.py +0 -35
  488. agno/memory/agent.py +0 -423
  489. agno/memory/classifier.py +0 -104
  490. agno/memory/db/__init__.py +0 -5
  491. agno/memory/db/base.py +0 -42
  492. agno/memory/db/mongodb.py +0 -189
  493. agno/memory/db/postgres.py +0 -203
  494. agno/memory/db/sqlite.py +0 -193
  495. agno/memory/memory.py +0 -22
  496. agno/memory/row.py +0 -36
  497. agno/memory/summarizer.py +0 -201
  498. agno/memory/summary.py +0 -19
  499. agno/memory/team.py +0 -415
  500. agno/memory/v2/__init__.py +0 -2
  501. agno/memory/v2/db/__init__.py +0 -1
  502. agno/memory/v2/db/base.py +0 -42
  503. agno/memory/v2/db/firestore.py +0 -339
  504. agno/memory/v2/db/mongodb.py +0 -196
  505. agno/memory/v2/db/postgres.py +0 -214
  506. agno/memory/v2/db/redis.py +0 -187
  507. agno/memory/v2/db/schema.py +0 -54
  508. agno/memory/v2/db/sqlite.py +0 -209
  509. agno/memory/v2/manager.py +0 -437
  510. agno/memory/v2/memory.py +0 -1097
  511. agno/memory/v2/schema.py +0 -55
  512. agno/memory/v2/summarizer.py +0 -215
  513. agno/memory/workflow.py +0 -38
  514. agno/models/ollama/tools.py +0 -430
  515. agno/models/qwen/__init__.py +0 -5
  516. agno/playground/__init__.py +0 -10
  517. agno/playground/deploy.py +0 -3
  518. agno/playground/playground.py +0 -3
  519. agno/playground/serve.py +0 -3
  520. agno/playground/settings.py +0 -3
  521. agno/reranker/__init__.py +0 -0
  522. agno/run/response.py +0 -467
  523. agno/run/v2/__init__.py +0 -0
  524. agno/run/v2/workflow.py +0 -567
  525. agno/storage/__init__.py +0 -0
  526. agno/storage/agent/__init__.py +0 -0
  527. agno/storage/agent/dynamodb.py +0 -1
  528. agno/storage/agent/json.py +0 -1
  529. agno/storage/agent/mongodb.py +0 -1
  530. agno/storage/agent/postgres.py +0 -1
  531. agno/storage/agent/singlestore.py +0 -1
  532. agno/storage/agent/sqlite.py +0 -1
  533. agno/storage/agent/yaml.py +0 -1
  534. agno/storage/base.py +0 -60
  535. agno/storage/dynamodb.py +0 -673
  536. agno/storage/firestore.py +0 -297
  537. agno/storage/gcs_json.py +0 -261
  538. agno/storage/in_memory.py +0 -234
  539. agno/storage/json.py +0 -237
  540. agno/storage/mongodb.py +0 -328
  541. agno/storage/mysql.py +0 -685
  542. agno/storage/postgres.py +0 -682
  543. agno/storage/redis.py +0 -336
  544. agno/storage/session/__init__.py +0 -16
  545. agno/storage/session/agent.py +0 -64
  546. agno/storage/session/team.py +0 -63
  547. agno/storage/session/v2/__init__.py +0 -5
  548. agno/storage/session/workflow.py +0 -61
  549. agno/storage/singlestore.py +0 -606
  550. agno/storage/sqlite.py +0 -646
  551. agno/storage/workflow/__init__.py +0 -0
  552. agno/storage/workflow/mongodb.py +0 -1
  553. agno/storage/workflow/postgres.py +0 -1
  554. agno/storage/workflow/sqlite.py +0 -1
  555. agno/storage/yaml.py +0 -241
  556. agno/tools/thinking.py +0 -73
  557. agno/utils/defaults.py +0 -57
  558. agno/utils/filesystem.py +0 -39
  559. agno/utils/git.py +0 -52
  560. agno/utils/json_io.py +0 -30
  561. agno/utils/load_env.py +0 -19
  562. agno/utils/py_io.py +0 -19
  563. agno/utils/pyproject.py +0 -18
  564. agno/utils/resource_filter.py +0 -31
  565. agno/workflow/v2/__init__.py +0 -21
  566. agno/workflow/v2/types.py +0 -357
  567. agno/workflow/v2/workflow.py +0 -3312
  568. agno/workspace/__init__.py +0 -0
  569. agno/workspace/config.py +0 -325
  570. agno/workspace/enums.py +0 -6
  571. agno/workspace/helpers.py +0 -52
  572. agno/workspace/operator.py +0 -757
  573. agno/workspace/settings.py +0 -158
  574. agno-1.8.1.dist-info/METADATA +0 -982
  575. agno-1.8.1.dist-info/RECORD +0 -566
  576. agno-1.8.1.dist-info/entry_points.txt +0 -3
  577. agno-1.8.1.dist-info/licenses/LICENSE +0 -375
  578. /agno/{app → db/migrations}/__init__.py +0 -0
  579. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  580. /agno/{cli → integrations}/__init__.py +0 -0
  581. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  582. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  583. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  584. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  585. /agno/{app → os/interfaces}/slack/security.py +0 -0
  586. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  587. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  588. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  589. {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  590. {agno-1.8.1.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