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

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