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
@@ -6,9 +6,11 @@ from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Tuple, Ty
6
6
  from pydantic import BaseModel
7
7
 
8
8
  from agno.exceptions import AgnoError, ModelProviderError
9
- from agno.models.base import MessageData, Model, _add_usage_metrics_to_assistant_message
9
+ from agno.models.base import MessageData, Model
10
10
  from agno.models.message import Message
11
+ from agno.models.metrics import Metrics
11
12
  from agno.models.response import ModelResponse
13
+ from agno.run.agent import RunOutput
12
14
  from agno.utils.log import log_debug, log_error, log_warning
13
15
 
14
16
  try:
@@ -179,14 +181,10 @@ class AwsBedrock(Model):
179
181
  required = []
180
182
 
181
183
  for param_name, param_info in func_def.get("parameters", {}).get("properties", {}).items():
182
- param_type = param_info.get("type")
183
- if isinstance(param_type, list):
184
- param_type = [t for t in param_type if t != "null"][0]
184
+ properties[param_name] = param_info.copy()
185
185
 
186
- properties[param_name] = {
187
- "type": param_type or "string",
188
- "description": param_info.get("description") or "",
189
- }
186
+ if "description" not in properties[param_name]:
187
+ properties[param_name]["description"] = ""
190
188
 
191
189
  if "null" not in (
192
190
  param_info.get("type") if isinstance(param_info.get("type"), list) else [param_info.get("type")]
@@ -349,10 +347,12 @@ class AwsBedrock(Model):
349
347
  def invoke(
350
348
  self,
351
349
  messages: List[Message],
350
+ assistant_message: Message,
352
351
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
353
352
  tools: Optional[List[Dict[str, Any]]] = None,
354
353
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
355
- ) -> Dict[str, Any]:
354
+ run_response: Optional[RunOutput] = None,
355
+ ) -> ModelResponse:
356
356
  """
357
357
  Invoke the Bedrock API.
358
358
  """
@@ -374,7 +374,17 @@ class AwsBedrock(Model):
374
374
  log_debug(f"Calling {self.provider} with request parameters: {self.request_params}", log_level=2)
375
375
  body.update(**self.request_params)
376
376
 
377
- return self.get_client().converse(modelId=self.id, messages=formatted_messages, **body)
377
+ if run_response and run_response.metrics:
378
+ run_response.metrics.set_time_to_first_token()
379
+
380
+ assistant_message.metrics.start_timer()
381
+ response = self.get_client().converse(modelId=self.id, messages=formatted_messages, **body)
382
+ assistant_message.metrics.stop_timer()
383
+
384
+ model_response = self._parse_provider_response(response, response_format=response_format)
385
+
386
+ return model_response
387
+
378
388
  except ClientError as e:
379
389
  log_error(f"Unexpected error calling Bedrock API: {str(e)}")
380
390
  raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
@@ -385,10 +395,12 @@ class AwsBedrock(Model):
385
395
  def invoke_stream(
386
396
  self,
387
397
  messages: List[Message],
398
+ assistant_message: Message,
388
399
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
389
400
  tools: Optional[List[Dict[str, Any]]] = None,
390
401
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
391
- ) -> Iterator[Dict[str, Any]]:
402
+ run_response: Optional[RunOutput] = None,
403
+ ) -> Iterator[ModelResponse]:
392
404
  """
393
405
  Invoke the Bedrock API with streaming.
394
406
  """
@@ -409,7 +421,18 @@ class AwsBedrock(Model):
409
421
  if self.request_params:
410
422
  body.update(**self.request_params)
411
423
 
412
- return self.get_client().converse_stream(modelId=self.id, messages=formatted_messages, **body)["stream"]
424
+ if run_response and run_response.metrics:
425
+ run_response.metrics.set_time_to_first_token()
426
+
427
+ assistant_message.metrics.start_timer()
428
+
429
+ for chunk in self.get_client().converse_stream(modelId=self.id, messages=formatted_messages, **body)[
430
+ "stream"
431
+ ]:
432
+ yield self._parse_provider_response_delta(chunk)
433
+
434
+ assistant_message.metrics.stop_timer()
435
+
413
436
  except ClientError as e:
414
437
  log_error(f"Unexpected error calling Bedrock API: {str(e)}")
415
438
  raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
@@ -420,10 +443,12 @@ class AwsBedrock(Model):
420
443
  async def ainvoke(
421
444
  self,
422
445
  messages: List[Message],
446
+ assistant_message: Message,
423
447
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
424
448
  tools: Optional[List[Dict[str, Any]]] = None,
425
449
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
426
- ) -> Dict[str, Any]:
450
+ run_response: Optional[RunOutput] = None,
451
+ ) -> ModelResponse:
427
452
  """
428
453
  Async invoke the Bedrock API.
429
454
  """
@@ -445,8 +470,20 @@ class AwsBedrock(Model):
445
470
  log_debug(f"Calling {self.provider} with request parameters: {self.request_params}", log_level=2)
446
471
  body.update(**self.request_params)
447
472
 
473
+ if run_response and run_response.metrics:
474
+ run_response.metrics.set_time_to_first_token()
475
+
476
+ assistant_message.metrics.start_timer()
477
+
448
478
  async with self.get_async_client() as client:
449
- return await client.converse(modelId=self.id, messages=formatted_messages, **body)
479
+ response = await client.converse(modelId=self.id, messages=formatted_messages, **body)
480
+
481
+ assistant_message.metrics.stop_timer()
482
+
483
+ model_response = self._parse_provider_response(response, response_format=response_format)
484
+
485
+ return model_response
486
+
450
487
  except ClientError as e:
451
488
  log_error(f"Unexpected error calling Bedrock API: {str(e)}")
452
489
  raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
@@ -457,10 +494,12 @@ class AwsBedrock(Model):
457
494
  async def ainvoke_stream(
458
495
  self,
459
496
  messages: List[Message],
497
+ assistant_message: Message,
460
498
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
461
499
  tools: Optional[List[Dict[str, Any]]] = None,
462
500
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
463
- ):
501
+ run_response: Optional[RunOutput] = None,
502
+ ) -> AsyncIterator[ModelResponse]:
464
503
  """
465
504
  Async invoke the Bedrock API with streaming.
466
505
  """
@@ -481,10 +520,18 @@ class AwsBedrock(Model):
481
520
  if self.request_params:
482
521
  body.update(**self.request_params)
483
522
 
523
+ if run_response and run_response.metrics:
524
+ run_response.metrics.set_time_to_first_token()
525
+
526
+ assistant_message.metrics.start_timer()
527
+
484
528
  async with self.get_async_client() as client:
485
529
  response = await client.converse_stream(modelId=self.id, messages=formatted_messages, **body)
486
530
  async for chunk in response["stream"]:
487
- yield chunk
531
+ yield self._parse_provider_response_delta(chunk)
532
+
533
+ assistant_message.metrics.stop_timer()
534
+
488
535
  except ClientError as e:
489
536
  log_error(f"Unexpected error calling Bedrock API: {str(e)}")
490
537
  raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
@@ -519,7 +566,7 @@ class AwsBedrock(Model):
519
566
 
520
567
  messages.append(Message(role="user", content=tool_result_content))
521
568
 
522
- def parse_provider_response(self, response: Dict[str, Any], **kwargs) -> ModelResponse:
569
+ def _parse_provider_response(self, response: Dict[str, Any], **kwargs) -> ModelResponse:
523
570
  """
524
571
  Parse the provider response.
525
572
 
@@ -566,11 +613,7 @@ class AwsBedrock(Model):
566
613
  model_response.content = content
567
614
 
568
615
  if "usage" in response:
569
- model_response.response_usage = {
570
- "input_tokens": response["usage"]["inputTokens"],
571
- "output_tokens": response["usage"]["outputTokens"],
572
- "total_tokens": response["usage"]["totalTokens"],
573
- }
616
+ model_response.response_usage = self._get_metrics(response["usage"])
574
617
 
575
618
  return model_response
576
619
 
@@ -582,6 +625,7 @@ class AwsBedrock(Model):
582
625
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
583
626
  tools: Optional[List[Dict[str, Any]]] = None,
584
627
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
628
+ run_response: Optional[RunOutput] = None,
585
629
  ) -> Iterator[ModelResponse]:
586
630
  """
587
631
  Process the synchronous response stream.
@@ -591,94 +635,28 @@ class AwsBedrock(Model):
591
635
  assistant_message (Message): The assistant message.
592
636
  stream_data (MessageData): The stream data.
593
637
  """
594
- tool_use: Dict[str, Any] = {}
595
- content = []
596
- tool_ids = []
597
-
598
638
  for response_delta in self.invoke_stream(
599
- messages=messages, response_format=response_format, tools=tools, tool_choice=tool_choice
639
+ messages=messages,
640
+ assistant_message=assistant_message,
641
+ response_format=response_format,
642
+ tools=tools,
643
+ tool_choice=tool_choice,
644
+ run_response=run_response,
600
645
  ):
601
- model_response = ModelResponse(role="assistant")
602
646
  should_yield = False
603
- if "contentBlockStart" in response_delta:
604
- # Handle tool use requests
605
- tool = response_delta["contentBlockStart"]["start"].get("toolUse")
606
- if tool:
607
- tool_use["toolUseId"] = tool["toolUseId"]
608
- tool_use["name"] = tool["name"]
609
-
610
- elif "contentBlockDelta" in response_delta:
611
- delta = response_delta["contentBlockDelta"]["delta"]
612
- if "toolUse" in delta:
613
- if "input" not in tool_use:
614
- tool_use["input"] = ""
615
- tool_use["input"] += delta["toolUse"]["input"]
616
- elif "text" in delta:
617
- model_response.content = delta["text"]
618
-
619
- elif "contentBlockStop" in response_delta:
620
- if "input" in tool_use:
621
- # Finish collecting tool use input
622
- try:
623
- tool_use["input"] = json.loads(tool_use["input"])
624
- except json.JSONDecodeError as e:
625
- log_error(f"Failed to parse tool input as JSON: {e}")
626
- tool_use["input"] = {}
627
- content.append({"toolUse": tool_use})
628
- tool_ids.append(tool_use["toolUseId"])
629
- # Prepare the tool call
630
- tool_call = {
631
- "id": tool_use["toolUseId"],
632
- "type": "function",
633
- "function": {
634
- "name": tool_use["name"],
635
- "arguments": json.dumps(tool_use["input"]),
636
- },
637
- }
638
- # Append the tool call to the list of "done" tool calls
639
- model_response.tool_calls.append(tool_call)
640
- # Reset the tool use
641
- tool_use = {}
642
- else:
643
- # Finish collecting text content
644
- content.append({"text": stream_data.response_content})
645
-
646
- elif "messageStop" in response_delta or "metadata" in response_delta:
647
- body = response_delta.get("metadata") or response_delta.get("messageStop") or {}
648
- if "usage" in body:
649
- usage = body["usage"]
650
- model_response.response_usage = {
651
- "input_tokens": usage.get("inputTokens", 0),
652
- "output_tokens": usage.get("outputTokens", 0),
653
- "total_tokens": usage.get("totalTokens", 0),
654
- }
655
647
 
656
- # Update metrics
657
- if not assistant_message.metrics.time_to_first_token:
658
- assistant_message.metrics.set_time_to_first_token()
659
-
660
- if model_response.content:
661
- stream_data.response_content += model_response.content
648
+ if response_delta.content:
649
+ stream_data.response_content += response_delta.content
662
650
  should_yield = True
663
651
 
664
- if model_response.tool_calls:
652
+ if response_delta.tool_calls:
665
653
  if stream_data.response_tool_calls is None:
666
654
  stream_data.response_tool_calls = []
667
- stream_data.response_tool_calls.extend(model_response.tool_calls)
655
+ stream_data.response_tool_calls.extend(response_delta.tool_calls)
668
656
  should_yield = True
669
657
 
670
- if model_response.response_usage is not None:
671
- _add_usage_metrics_to_assistant_message(
672
- assistant_message=assistant_message, response_usage=model_response.response_usage
673
- )
674
-
675
658
  if should_yield:
676
- yield model_response
677
-
678
- if tool_ids:
679
- if stream_data.extra is None:
680
- stream_data.extra = {}
681
- stream_data.extra["tool_ids"] = tool_ids
659
+ yield response_delta
682
660
 
683
661
  async def aprocess_response_stream(
684
662
  self,
@@ -688,6 +666,7 @@ class AwsBedrock(Model):
688
666
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
689
667
  tools: Optional[List[Dict[str, Any]]] = None,
690
668
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
669
+ run_response: Optional[RunOutput] = None,
691
670
  ) -> AsyncIterator[ModelResponse]:
692
671
  """
693
672
  Process the asynchronous response stream.
@@ -697,96 +676,32 @@ class AwsBedrock(Model):
697
676
  assistant_message (Message): The assistant message.
698
677
  stream_data (MessageData): The stream data.
699
678
  """
700
- tool_use: Dict[str, Any] = {}
701
- content = []
702
- tool_ids = []
703
-
704
679
  async for response_delta in self.ainvoke_stream(
705
- messages=messages, response_format=response_format, tools=tools, tool_choice=tool_choice
680
+ messages=messages,
681
+ assistant_message=assistant_message,
682
+ response_format=response_format,
683
+ tools=tools,
684
+ tool_choice=tool_choice,
685
+ run_response=run_response,
706
686
  ):
707
- model_response = ModelResponse(role="assistant")
708
687
  should_yield = False
709
- if "contentBlockStart" in response_delta:
710
- # Handle tool use requests
711
- tool = response_delta["contentBlockStart"]["start"].get("toolUse")
712
- if tool:
713
- tool_use["toolUseId"] = tool["toolUseId"]
714
- tool_use["name"] = tool["name"]
715
-
716
- elif "contentBlockDelta" in response_delta:
717
- delta = response_delta["contentBlockDelta"]["delta"]
718
- if "toolUse" in delta:
719
- if "input" not in tool_use:
720
- tool_use["input"] = ""
721
- tool_use["input"] += delta["toolUse"]["input"]
722
- elif "text" in delta:
723
- model_response.content = delta["text"]
724
-
725
- elif "contentBlockStop" in response_delta:
726
- if "input" in tool_use:
727
- # Finish collecting tool use input
728
- try:
729
- tool_use["input"] = json.loads(tool_use["input"])
730
- except json.JSONDecodeError as e:
731
- log_error(f"Failed to parse tool input as JSON: {e}")
732
- tool_use["input"] = {}
733
- content.append({"toolUse": tool_use})
734
- tool_ids.append(tool_use["toolUseId"])
735
- # Prepare the tool call
736
- tool_call = {
737
- "id": tool_use["toolUseId"],
738
- "type": "function",
739
- "function": {
740
- "name": tool_use["name"],
741
- "arguments": json.dumps(tool_use["input"]),
742
- },
743
- }
744
- # Append the tool call to the list of "done" tool calls
745
- model_response.tool_calls.append(tool_call)
746
- # Reset the tool use
747
- tool_use = {}
748
- else:
749
- # Finish collecting text content
750
- content.append({"text": stream_data.response_content})
751
-
752
- elif "messageStop" in response_delta or "metadata" in response_delta:
753
- body = response_delta.get("metadata") or response_delta.get("messageStop") or {}
754
- if "usage" in body:
755
- usage = body["usage"]
756
- model_response.response_usage = {
757
- "input_tokens": usage.get("inputTokens", 0),
758
- "output_tokens": usage.get("outputTokens", 0),
759
- "total_tokens": usage.get("totalTokens", 0),
760
- }
761
-
762
- # Update metrics
763
- if not assistant_message.metrics.time_to_first_token:
764
- assistant_message.metrics.set_time_to_first_token()
765
688
 
766
- if model_response.content:
767
- stream_data.response_content += model_response.content
689
+ if response_delta.content:
690
+ stream_data.response_content += response_delta.content
768
691
  should_yield = True
769
692
 
770
- if model_response.tool_calls:
693
+ if response_delta.tool_calls:
771
694
  if stream_data.response_tool_calls is None:
772
695
  stream_data.response_tool_calls = []
773
- stream_data.response_tool_calls.extend(model_response.tool_calls)
696
+ stream_data.response_tool_calls.extend(response_delta.tool_calls)
774
697
  should_yield = True
775
698
 
776
- if model_response.response_usage is not None:
777
- _add_usage_metrics_to_assistant_message(
778
- assistant_message=assistant_message, response_usage=model_response.response_usage
779
- )
780
-
781
699
  if should_yield:
782
- yield model_response
700
+ yield response_delta
783
701
 
784
- if tool_ids:
785
- if stream_data.extra is None:
786
- stream_data.extra = {}
787
- stream_data.extra["tool_ids"] = tool_ids
702
+ self._populate_assistant_message(assistant_message=assistant_message, provider_response=response_delta)
788
703
 
789
- def parse_provider_response_delta(self, response_delta: Dict[str, Any]) -> ModelResponse: # type: ignore
704
+ def _parse_provider_response_delta(self, response_delta: Dict[str, Any]) -> ModelResponse: # type: ignore
790
705
  """Parse the provider response delta for streaming.
791
706
 
792
707
  Args:
@@ -823,11 +738,24 @@ class AwsBedrock(Model):
823
738
  elif "metadata" in response_delta or "messageStop" in response_delta:
824
739
  body = response_delta.get("metadata") or response_delta.get("messageStop") or {}
825
740
  if "usage" in body:
826
- usage = body["usage"]
827
- model_response.response_usage = {
828
- "input_tokens": usage.get("inputTokens", 0),
829
- "output_tokens": usage.get("outputTokens", 0),
830
- "total_tokens": usage.get("totalTokens", 0),
831
- }
741
+ model_response.response_usage = self._get_metrics(body["usage"])
832
742
 
833
743
  return model_response
744
+
745
+ def _get_metrics(self, response_usage: Dict[str, Any]) -> Metrics:
746
+ """
747
+ Parse the given AWS Bedrock usage into an Agno Metrics object.
748
+
749
+ Args:
750
+ response_usage: Usage data from AWS Bedrock
751
+
752
+ Returns:
753
+ Metrics: Parsed metrics data
754
+ """
755
+ metrics = Metrics()
756
+
757
+ metrics.input_tokens = response_usage.get("inputTokens", 0) or 0
758
+ metrics.output_tokens = response_usage.get("outputTokens", 0) or 0
759
+ metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
760
+
761
+ return metrics
agno/models/aws/claude.py CHANGED
@@ -1,18 +1,19 @@
1
1
  from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Any, AsyncIterator, Dict, 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, ModelRateLimitError
8
8
  from agno.models.anthropic import Claude as AnthropicClaude
9
9
  from agno.models.message import Message
10
+ from agno.models.response import ModelResponse
11
+ from agno.run.agent import RunOutput
10
12
  from agno.utils.log import log_debug, log_error, log_warning
11
13
  from agno.utils.models.aws_claude import format_messages
12
14
 
13
15
  try:
14
16
  from anthropic import AnthropicBedrock, APIConnectionError, APIStatusError, AsyncAnthropicBedrock, RateLimitError
15
- from anthropic.types import Message as AnthropicMessage
16
17
  except ImportError:
17
18
  raise ImportError("`anthropic[bedrock]` not installed. Please install using `pip install anthropic[bedrock]`")
18
19
 
@@ -167,10 +168,12 @@ class Claude(AnthropicClaude):
167
168
  def invoke(
168
169
  self,
169
170
  messages: List[Message],
171
+ assistant_message: Message,
170
172
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
171
173
  tools: Optional[List[Dict[str, Any]]] = None,
172
174
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
173
- ) -> AnthropicMessage:
175
+ run_response: Optional[RunOutput] = None,
176
+ ) -> ModelResponse:
174
177
  """
175
178
  Send a request to the Anthropic API to generate a response.
176
179
  """
@@ -179,11 +182,21 @@ class Claude(AnthropicClaude):
179
182
  chat_messages, system_message = format_messages(messages)
180
183
  request_kwargs = self._prepare_request_kwargs(system_message, tools)
181
184
 
182
- return self.get_client().messages.create(
185
+ if run_response and run_response.metrics:
186
+ run_response.metrics.set_time_to_first_token()
187
+
188
+ assistant_message.metrics.start_timer()
189
+ response = self.get_client().messages.create(
183
190
  model=self.id,
184
191
  messages=chat_messages, # type: ignore
185
192
  **request_kwargs,
186
193
  )
194
+ assistant_message.metrics.stop_timer()
195
+
196
+ model_response = self._parse_provider_response(response, response_format=response_format)
197
+
198
+ return model_response
199
+
187
200
  except APIConnectionError as e:
188
201
  log_error(f"Connection error while calling Claude API: {str(e)}")
189
202
  raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
@@ -202,10 +215,12 @@ class Claude(AnthropicClaude):
202
215
  def invoke_stream(
203
216
  self,
204
217
  messages: List[Message],
218
+ assistant_message: Message,
205
219
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
206
220
  tools: Optional[List[Dict[str, Any]]] = None,
207
221
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
208
- ) -> Any:
222
+ run_response: Optional[RunOutput] = None,
223
+ ) -> Iterator[ModelResponse]:
209
224
  """
210
225
  Stream a response from the Anthropic API.
211
226
 
@@ -225,15 +240,21 @@ class Claude(AnthropicClaude):
225
240
  request_kwargs = self._prepare_request_kwargs(system_message, tools)
226
241
 
227
242
  try:
228
- return (
229
- self.get_client()
230
- .messages.stream(
231
- model=self.id,
232
- messages=chat_messages, # type: ignore
233
- **request_kwargs,
234
- )
235
- .__enter__()
236
- )
243
+ if run_response and run_response.metrics:
244
+ run_response.metrics.set_time_to_first_token()
245
+
246
+ assistant_message.metrics.start_timer()
247
+
248
+ with self.get_client().messages.stream(
249
+ model=self.id,
250
+ messages=chat_messages, # type: ignore
251
+ **request_kwargs,
252
+ ) as stream:
253
+ for chunk in stream:
254
+ yield self._parse_provider_response_delta(chunk)
255
+
256
+ assistant_message.metrics.stop_timer()
257
+
237
258
  except APIConnectionError as e:
238
259
  log_error(f"Connection error while calling Claude API: {str(e)}")
239
260
  raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
@@ -252,10 +273,12 @@ class Claude(AnthropicClaude):
252
273
  async def ainvoke(
253
274
  self,
254
275
  messages: List[Message],
276
+ assistant_message: Message,
255
277
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
256
278
  tools: Optional[List[Dict[str, Any]]] = None,
257
279
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
258
- ) -> AnthropicMessage:
280
+ run_response: Optional[RunOutput] = None,
281
+ ) -> ModelResponse:
259
282
  """
260
283
  Send an asynchronous request to the Anthropic API to generate a response.
261
284
  """
@@ -264,11 +287,23 @@ class Claude(AnthropicClaude):
264
287
  chat_messages, system_message = format_messages(messages)
265
288
  request_kwargs = self._prepare_request_kwargs(system_message, tools)
266
289
 
267
- return await self.get_async_client().messages.create(
290
+ if run_response and run_response.metrics:
291
+ run_response.metrics.set_time_to_first_token()
292
+
293
+ assistant_message.metrics.start_timer()
294
+
295
+ response = await self.get_async_client().messages.create(
268
296
  model=self.id,
269
297
  messages=chat_messages, # type: ignore
270
298
  **request_kwargs,
271
299
  )
300
+
301
+ assistant_message.metrics.stop_timer()
302
+
303
+ model_response = self._parse_provider_response(response, response_format=response_format)
304
+
305
+ return model_response
306
+
272
307
  except APIConnectionError as e:
273
308
  log_error(f"Connection error while calling Claude API: {str(e)}")
274
309
  raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
@@ -287,10 +322,12 @@ class Claude(AnthropicClaude):
287
322
  async def ainvoke_stream(
288
323
  self,
289
324
  messages: List[Message],
325
+ assistant_message: Message,
290
326
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
291
327
  tools: Optional[List[Dict[str, Any]]] = None,
292
328
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
293
- ) -> AsyncIterator[Any]:
329
+ run_response: Optional[RunOutput] = None,
330
+ ) -> AsyncIterator[ModelResponse]:
294
331
  """
295
332
  Stream an asynchronous response from the Anthropic API.
296
333
 
@@ -309,13 +346,22 @@ class Claude(AnthropicClaude):
309
346
  try:
310
347
  chat_messages, system_message = format_messages(messages)
311
348
  request_kwargs = self._prepare_request_kwargs(system_message, tools)
349
+
350
+ if run_response and run_response.metrics:
351
+ run_response.metrics.set_time_to_first_token()
352
+
353
+ assistant_message.metrics.start_timer()
354
+
312
355
  async with self.get_async_client().messages.stream(
313
356
  model=self.id,
314
357
  messages=chat_messages, # type: ignore
315
358
  **request_kwargs,
316
359
  ) as stream:
317
360
  async for chunk in stream:
318
- yield chunk
361
+ yield self._parse_provider_response_delta(chunk)
362
+
363
+ assistant_message.metrics.stop_timer()
364
+
319
365
  except APIConnectionError as e:
320
366
  log_error(f"Connection error while calling Claude API: {str(e)}")
321
367
  raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e