agno 1.8.0__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 (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2781 -4126
  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/media.py +2 -2
  137. agno/memory/__init__.py +2 -10
  138. agno/memory/manager.py +1003 -148
  139. agno/models/aimlapi/__init__.py +2 -2
  140. agno/models/aimlapi/aimlapi.py +6 -6
  141. agno/models/anthropic/claude.py +129 -82
  142. agno/models/aws/bedrock.py +107 -175
  143. agno/models/aws/claude.py +64 -18
  144. agno/models/azure/ai_foundry.py +73 -23
  145. agno/models/base.py +347 -287
  146. agno/models/cerebras/cerebras.py +84 -27
  147. agno/models/cohere/chat.py +106 -98
  148. agno/models/dashscope/dashscope.py +14 -5
  149. agno/models/google/gemini.py +123 -53
  150. agno/models/groq/groq.py +97 -35
  151. agno/models/huggingface/huggingface.py +92 -27
  152. agno/models/ibm/watsonx.py +72 -13
  153. agno/models/litellm/chat.py +85 -13
  154. agno/models/message.py +38 -144
  155. agno/models/meta/llama.py +85 -49
  156. agno/models/metrics.py +120 -0
  157. agno/models/mistral/mistral.py +90 -21
  158. agno/models/ollama/__init__.py +0 -2
  159. agno/models/ollama/chat.py +84 -46
  160. agno/models/openai/chat.py +135 -27
  161. agno/models/openai/responses.py +233 -115
  162. agno/models/perplexity/perplexity.py +26 -2
  163. agno/models/portkey/portkey.py +0 -7
  164. agno/models/response.py +14 -8
  165. agno/models/utils.py +20 -0
  166. agno/models/vercel/__init__.py +2 -2
  167. agno/models/vercel/v0.py +1 -1
  168. agno/models/vllm/__init__.py +2 -2
  169. agno/models/vllm/vllm.py +3 -3
  170. agno/models/xai/xai.py +10 -10
  171. agno/os/__init__.py +3 -0
  172. agno/os/app.py +393 -0
  173. agno/os/auth.py +47 -0
  174. agno/os/config.py +103 -0
  175. agno/os/interfaces/agui/__init__.py +3 -0
  176. agno/os/interfaces/agui/agui.py +31 -0
  177. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  178. agno/{app → os/interfaces}/agui/utils.py +65 -28
  179. agno/os/interfaces/base.py +21 -0
  180. agno/os/interfaces/slack/__init__.py +3 -0
  181. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  182. agno/os/interfaces/slack/slack.py +33 -0
  183. agno/os/interfaces/whatsapp/__init__.py +3 -0
  184. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  185. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  186. agno/os/router.py +843 -0
  187. agno/os/routers/__init__.py +3 -0
  188. agno/os/routers/evals/__init__.py +3 -0
  189. agno/os/routers/evals/evals.py +204 -0
  190. agno/os/routers/evals/schemas.py +142 -0
  191. agno/os/routers/evals/utils.py +161 -0
  192. agno/os/routers/knowledge/__init__.py +3 -0
  193. agno/os/routers/knowledge/knowledge.py +413 -0
  194. agno/os/routers/knowledge/schemas.py +118 -0
  195. agno/os/routers/memory/__init__.py +3 -0
  196. agno/os/routers/memory/memory.py +179 -0
  197. agno/os/routers/memory/schemas.py +58 -0
  198. agno/os/routers/metrics/__init__.py +3 -0
  199. agno/os/routers/metrics/metrics.py +58 -0
  200. agno/os/routers/metrics/schemas.py +47 -0
  201. agno/os/routers/session/__init__.py +3 -0
  202. agno/os/routers/session/session.py +163 -0
  203. agno/os/schema.py +892 -0
  204. agno/{app/playground → os}/settings.py +8 -15
  205. agno/os/utils.py +270 -0
  206. agno/reasoning/azure_ai_foundry.py +4 -4
  207. agno/reasoning/deepseek.py +4 -4
  208. agno/reasoning/default.py +6 -11
  209. agno/reasoning/groq.py +4 -4
  210. agno/reasoning/helpers.py +4 -6
  211. agno/reasoning/ollama.py +4 -4
  212. agno/reasoning/openai.py +4 -4
  213. agno/run/{response.py → agent.py} +144 -72
  214. agno/run/base.py +44 -58
  215. agno/run/cancel.py +83 -0
  216. agno/run/team.py +133 -77
  217. agno/run/workflow.py +537 -12
  218. agno/session/__init__.py +10 -0
  219. agno/session/agent.py +244 -0
  220. agno/session/summary.py +225 -0
  221. agno/session/team.py +262 -0
  222. agno/{storage/session/v2 → session}/workflow.py +47 -24
  223. agno/team/__init__.py +15 -16
  224. agno/team/team.py +2967 -4243
  225. agno/tools/agentql.py +14 -5
  226. agno/tools/airflow.py +9 -4
  227. agno/tools/api.py +7 -3
  228. agno/tools/apify.py +2 -46
  229. agno/tools/arxiv.py +8 -3
  230. agno/tools/aws_lambda.py +7 -5
  231. agno/tools/aws_ses.py +7 -1
  232. agno/tools/baidusearch.py +4 -1
  233. agno/tools/bitbucket.py +4 -4
  234. agno/tools/brandfetch.py +14 -11
  235. agno/tools/bravesearch.py +4 -1
  236. agno/tools/brightdata.py +42 -22
  237. agno/tools/browserbase.py +13 -4
  238. agno/tools/calcom.py +12 -10
  239. agno/tools/calculator.py +10 -27
  240. agno/tools/cartesia.py +18 -13
  241. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  242. agno/tools/confluence.py +71 -18
  243. agno/tools/crawl4ai.py +7 -1
  244. agno/tools/csv_toolkit.py +9 -8
  245. agno/tools/dalle.py +18 -11
  246. agno/tools/daytona.py +13 -16
  247. agno/tools/decorator.py +6 -3
  248. agno/tools/desi_vocal.py +16 -7
  249. agno/tools/discord.py +11 -8
  250. agno/tools/docker.py +30 -42
  251. agno/tools/duckdb.py +34 -53
  252. agno/tools/duckduckgo.py +8 -7
  253. agno/tools/e2b.py +62 -62
  254. agno/tools/eleven_labs.py +35 -28
  255. agno/tools/email.py +4 -1
  256. agno/tools/evm.py +7 -1
  257. agno/tools/exa.py +19 -14
  258. agno/tools/fal.py +29 -29
  259. agno/tools/file.py +9 -8
  260. agno/tools/financial_datasets.py +25 -44
  261. agno/tools/firecrawl.py +22 -22
  262. agno/tools/function.py +68 -17
  263. agno/tools/giphy.py +22 -10
  264. agno/tools/github.py +48 -126
  265. agno/tools/gmail.py +46 -62
  266. agno/tools/google_bigquery.py +7 -6
  267. agno/tools/google_maps.py +11 -26
  268. agno/tools/googlesearch.py +7 -2
  269. agno/tools/googlesheets.py +21 -17
  270. agno/tools/hackernews.py +9 -5
  271. agno/tools/jina.py +5 -4
  272. agno/tools/jira.py +18 -9
  273. agno/tools/knowledge.py +31 -32
  274. agno/tools/linear.py +18 -33
  275. agno/tools/linkup.py +5 -1
  276. agno/tools/local_file_system.py +8 -5
  277. agno/tools/lumalab.py +31 -19
  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 +32 -14
  282. agno/tools/models/gemini.py +58 -31
  283. agno/tools/models/groq.py +29 -20
  284. agno/tools/models/nebius.py +27 -11
  285. agno/tools/models_labs.py +39 -15
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +134 -0
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +57 -26
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +62 -46
  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 +54 -41
  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 +95 -118
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/location.py +2 -2
  337. agno/utils/log.py +2 -2
  338. agno/utils/mcp.py +11 -5
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/claude.py +6 -4
  342. agno/utils/models/mistral.py +8 -7
  343. agno/utils/models/schema_utils.py +3 -3
  344. agno/utils/pprint.py +33 -32
  345. agno/utils/print_response/agent.py +779 -0
  346. agno/utils/print_response/team.py +1565 -0
  347. agno/utils/print_response/workflow.py +1451 -0
  348. agno/utils/prompts.py +14 -14
  349. agno/utils/reasoning.py +87 -0
  350. agno/utils/response.py +42 -42
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +356 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2394 -696
  383. agno-2.0.0a1.dist-info/METADATA +355 -0
  384. agno-2.0.0a1.dist-info/RECORD +514 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -698
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.0.dist-info/METADATA +0 -979
  568. agno-1.8.0.dist-info/RECORD +0 -565
  569. agno-1.8.0.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.0.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