agno 2.2.13__py3-none-any.whl → 2.4.3__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 (383) hide show
  1. agno/agent/__init__.py +6 -0
  2. agno/agent/agent.py +5252 -3145
  3. agno/agent/remote.py +525 -0
  4. agno/api/api.py +2 -0
  5. agno/client/__init__.py +3 -0
  6. agno/client/a2a/__init__.py +10 -0
  7. agno/client/a2a/client.py +554 -0
  8. agno/client/a2a/schemas.py +112 -0
  9. agno/client/a2a/utils.py +369 -0
  10. agno/client/os.py +2669 -0
  11. agno/compression/__init__.py +3 -0
  12. agno/compression/manager.py +247 -0
  13. agno/culture/manager.py +2 -2
  14. agno/db/base.py +927 -6
  15. agno/db/dynamo/dynamo.py +788 -2
  16. agno/db/dynamo/schemas.py +128 -0
  17. agno/db/dynamo/utils.py +26 -3
  18. agno/db/firestore/firestore.py +674 -50
  19. agno/db/firestore/schemas.py +41 -0
  20. agno/db/firestore/utils.py +25 -10
  21. agno/db/gcs_json/gcs_json_db.py +506 -3
  22. agno/db/gcs_json/utils.py +14 -2
  23. agno/db/in_memory/in_memory_db.py +203 -4
  24. agno/db/in_memory/utils.py +14 -2
  25. agno/db/json/json_db.py +498 -2
  26. agno/db/json/utils.py +14 -2
  27. agno/db/migrations/manager.py +199 -0
  28. agno/db/migrations/utils.py +19 -0
  29. agno/db/migrations/v1_to_v2.py +54 -16
  30. agno/db/migrations/versions/__init__.py +0 -0
  31. agno/db/migrations/versions/v2_3_0.py +977 -0
  32. agno/db/mongo/async_mongo.py +1013 -39
  33. agno/db/mongo/mongo.py +684 -4
  34. agno/db/mongo/schemas.py +48 -0
  35. agno/db/mongo/utils.py +17 -0
  36. agno/db/mysql/__init__.py +2 -1
  37. agno/db/mysql/async_mysql.py +2958 -0
  38. agno/db/mysql/mysql.py +722 -53
  39. agno/db/mysql/schemas.py +77 -11
  40. agno/db/mysql/utils.py +151 -8
  41. agno/db/postgres/async_postgres.py +1254 -137
  42. agno/db/postgres/postgres.py +2316 -93
  43. agno/db/postgres/schemas.py +153 -21
  44. agno/db/postgres/utils.py +22 -7
  45. agno/db/redis/redis.py +531 -3
  46. agno/db/redis/schemas.py +36 -0
  47. agno/db/redis/utils.py +31 -15
  48. agno/db/schemas/evals.py +1 -0
  49. agno/db/schemas/memory.py +20 -9
  50. agno/db/singlestore/schemas.py +70 -1
  51. agno/db/singlestore/singlestore.py +737 -74
  52. agno/db/singlestore/utils.py +13 -3
  53. agno/db/sqlite/async_sqlite.py +1069 -89
  54. agno/db/sqlite/schemas.py +133 -1
  55. agno/db/sqlite/sqlite.py +2203 -165
  56. agno/db/sqlite/utils.py +21 -11
  57. agno/db/surrealdb/models.py +25 -0
  58. agno/db/surrealdb/surrealdb.py +603 -1
  59. agno/db/utils.py +60 -0
  60. agno/eval/__init__.py +26 -3
  61. agno/eval/accuracy.py +25 -12
  62. agno/eval/agent_as_judge.py +871 -0
  63. agno/eval/base.py +29 -0
  64. agno/eval/performance.py +10 -4
  65. agno/eval/reliability.py +22 -13
  66. agno/eval/utils.py +2 -1
  67. agno/exceptions.py +42 -0
  68. agno/hooks/__init__.py +3 -0
  69. agno/hooks/decorator.py +164 -0
  70. agno/integrations/discord/client.py +13 -2
  71. agno/knowledge/__init__.py +4 -0
  72. agno/knowledge/chunking/code.py +90 -0
  73. agno/knowledge/chunking/document.py +65 -4
  74. agno/knowledge/chunking/fixed.py +4 -1
  75. agno/knowledge/chunking/markdown.py +102 -11
  76. agno/knowledge/chunking/recursive.py +2 -2
  77. agno/knowledge/chunking/semantic.py +130 -48
  78. agno/knowledge/chunking/strategy.py +18 -0
  79. agno/knowledge/embedder/azure_openai.py +0 -1
  80. agno/knowledge/embedder/google.py +1 -1
  81. agno/knowledge/embedder/mistral.py +1 -1
  82. agno/knowledge/embedder/nebius.py +1 -1
  83. agno/knowledge/embedder/openai.py +16 -12
  84. agno/knowledge/filesystem.py +412 -0
  85. agno/knowledge/knowledge.py +4261 -1199
  86. agno/knowledge/protocol.py +134 -0
  87. agno/knowledge/reader/arxiv_reader.py +3 -2
  88. agno/knowledge/reader/base.py +9 -7
  89. agno/knowledge/reader/csv_reader.py +91 -42
  90. agno/knowledge/reader/docx_reader.py +9 -10
  91. agno/knowledge/reader/excel_reader.py +225 -0
  92. agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
  93. agno/knowledge/reader/firecrawl_reader.py +3 -2
  94. agno/knowledge/reader/json_reader.py +16 -22
  95. agno/knowledge/reader/markdown_reader.py +15 -14
  96. agno/knowledge/reader/pdf_reader.py +33 -28
  97. agno/knowledge/reader/pptx_reader.py +9 -10
  98. agno/knowledge/reader/reader_factory.py +135 -1
  99. agno/knowledge/reader/s3_reader.py +8 -16
  100. agno/knowledge/reader/tavily_reader.py +3 -3
  101. agno/knowledge/reader/text_reader.py +15 -14
  102. agno/knowledge/reader/utils/__init__.py +17 -0
  103. agno/knowledge/reader/utils/spreadsheet.py +114 -0
  104. agno/knowledge/reader/web_search_reader.py +8 -65
  105. agno/knowledge/reader/website_reader.py +16 -13
  106. agno/knowledge/reader/wikipedia_reader.py +36 -3
  107. agno/knowledge/reader/youtube_reader.py +3 -2
  108. agno/knowledge/remote_content/__init__.py +33 -0
  109. agno/knowledge/remote_content/config.py +266 -0
  110. agno/knowledge/remote_content/remote_content.py +105 -17
  111. agno/knowledge/utils.py +76 -22
  112. agno/learn/__init__.py +71 -0
  113. agno/learn/config.py +463 -0
  114. agno/learn/curate.py +185 -0
  115. agno/learn/machine.py +725 -0
  116. agno/learn/schemas.py +1114 -0
  117. agno/learn/stores/__init__.py +38 -0
  118. agno/learn/stores/decision_log.py +1156 -0
  119. agno/learn/stores/entity_memory.py +3275 -0
  120. agno/learn/stores/learned_knowledge.py +1583 -0
  121. agno/learn/stores/protocol.py +117 -0
  122. agno/learn/stores/session_context.py +1217 -0
  123. agno/learn/stores/user_memory.py +1495 -0
  124. agno/learn/stores/user_profile.py +1220 -0
  125. agno/learn/utils.py +209 -0
  126. agno/media.py +22 -6
  127. agno/memory/__init__.py +14 -1
  128. agno/memory/manager.py +223 -8
  129. agno/memory/strategies/__init__.py +15 -0
  130. agno/memory/strategies/base.py +66 -0
  131. agno/memory/strategies/summarize.py +196 -0
  132. agno/memory/strategies/types.py +37 -0
  133. agno/models/aimlapi/aimlapi.py +17 -0
  134. agno/models/anthropic/claude.py +434 -59
  135. agno/models/aws/bedrock.py +121 -20
  136. agno/models/aws/claude.py +131 -274
  137. agno/models/azure/ai_foundry.py +10 -6
  138. agno/models/azure/openai_chat.py +33 -10
  139. agno/models/base.py +1162 -561
  140. agno/models/cerebras/cerebras.py +120 -24
  141. agno/models/cerebras/cerebras_openai.py +21 -2
  142. agno/models/cohere/chat.py +65 -6
  143. agno/models/cometapi/cometapi.py +18 -1
  144. agno/models/dashscope/dashscope.py +2 -3
  145. agno/models/deepinfra/deepinfra.py +18 -1
  146. agno/models/deepseek/deepseek.py +69 -3
  147. agno/models/fireworks/fireworks.py +18 -1
  148. agno/models/google/gemini.py +959 -89
  149. agno/models/google/utils.py +22 -0
  150. agno/models/groq/groq.py +48 -18
  151. agno/models/huggingface/huggingface.py +17 -6
  152. agno/models/ibm/watsonx.py +16 -6
  153. agno/models/internlm/internlm.py +18 -1
  154. agno/models/langdb/langdb.py +13 -1
  155. agno/models/litellm/chat.py +88 -9
  156. agno/models/litellm/litellm_openai.py +18 -1
  157. agno/models/message.py +24 -5
  158. agno/models/meta/llama.py +40 -13
  159. agno/models/meta/llama_openai.py +22 -21
  160. agno/models/metrics.py +12 -0
  161. agno/models/mistral/mistral.py +8 -4
  162. agno/models/n1n/__init__.py +3 -0
  163. agno/models/n1n/n1n.py +57 -0
  164. agno/models/nebius/nebius.py +6 -7
  165. agno/models/nvidia/nvidia.py +20 -3
  166. agno/models/ollama/__init__.py +2 -0
  167. agno/models/ollama/chat.py +17 -6
  168. agno/models/ollama/responses.py +100 -0
  169. agno/models/openai/__init__.py +2 -0
  170. agno/models/openai/chat.py +117 -26
  171. agno/models/openai/open_responses.py +46 -0
  172. agno/models/openai/responses.py +110 -32
  173. agno/models/openrouter/__init__.py +2 -0
  174. agno/models/openrouter/openrouter.py +67 -2
  175. agno/models/openrouter/responses.py +146 -0
  176. agno/models/perplexity/perplexity.py +19 -1
  177. agno/models/portkey/portkey.py +7 -6
  178. agno/models/requesty/requesty.py +19 -2
  179. agno/models/response.py +20 -2
  180. agno/models/sambanova/sambanova.py +20 -3
  181. agno/models/siliconflow/siliconflow.py +19 -2
  182. agno/models/together/together.py +20 -3
  183. agno/models/vercel/v0.py +20 -3
  184. agno/models/vertexai/claude.py +124 -4
  185. agno/models/vllm/vllm.py +19 -14
  186. agno/models/xai/xai.py +19 -2
  187. agno/os/app.py +467 -137
  188. agno/os/auth.py +253 -5
  189. agno/os/config.py +22 -0
  190. agno/os/interfaces/a2a/a2a.py +7 -6
  191. agno/os/interfaces/a2a/router.py +635 -26
  192. agno/os/interfaces/a2a/utils.py +32 -33
  193. agno/os/interfaces/agui/agui.py +5 -3
  194. agno/os/interfaces/agui/router.py +26 -16
  195. agno/os/interfaces/agui/utils.py +97 -57
  196. agno/os/interfaces/base.py +7 -7
  197. agno/os/interfaces/slack/router.py +16 -7
  198. agno/os/interfaces/slack/slack.py +7 -7
  199. agno/os/interfaces/whatsapp/router.py +35 -7
  200. agno/os/interfaces/whatsapp/security.py +3 -1
  201. agno/os/interfaces/whatsapp/whatsapp.py +11 -8
  202. agno/os/managers.py +326 -0
  203. agno/os/mcp.py +652 -79
  204. agno/os/middleware/__init__.py +4 -0
  205. agno/os/middleware/jwt.py +718 -115
  206. agno/os/middleware/trailing_slash.py +27 -0
  207. agno/os/router.py +105 -1558
  208. agno/os/routers/agents/__init__.py +3 -0
  209. agno/os/routers/agents/router.py +655 -0
  210. agno/os/routers/agents/schema.py +288 -0
  211. agno/os/routers/components/__init__.py +3 -0
  212. agno/os/routers/components/components.py +475 -0
  213. agno/os/routers/database.py +155 -0
  214. agno/os/routers/evals/evals.py +111 -18
  215. agno/os/routers/evals/schemas.py +38 -5
  216. agno/os/routers/evals/utils.py +80 -11
  217. agno/os/routers/health.py +3 -3
  218. agno/os/routers/knowledge/knowledge.py +284 -35
  219. agno/os/routers/knowledge/schemas.py +14 -2
  220. agno/os/routers/memory/memory.py +274 -11
  221. agno/os/routers/memory/schemas.py +44 -3
  222. agno/os/routers/metrics/metrics.py +30 -15
  223. agno/os/routers/metrics/schemas.py +10 -6
  224. agno/os/routers/registry/__init__.py +3 -0
  225. agno/os/routers/registry/registry.py +337 -0
  226. agno/os/routers/session/session.py +143 -14
  227. agno/os/routers/teams/__init__.py +3 -0
  228. agno/os/routers/teams/router.py +550 -0
  229. agno/os/routers/teams/schema.py +280 -0
  230. agno/os/routers/traces/__init__.py +3 -0
  231. agno/os/routers/traces/schemas.py +414 -0
  232. agno/os/routers/traces/traces.py +549 -0
  233. agno/os/routers/workflows/__init__.py +3 -0
  234. agno/os/routers/workflows/router.py +757 -0
  235. agno/os/routers/workflows/schema.py +139 -0
  236. agno/os/schema.py +157 -584
  237. agno/os/scopes.py +469 -0
  238. agno/os/settings.py +3 -0
  239. agno/os/utils.py +574 -185
  240. agno/reasoning/anthropic.py +85 -1
  241. agno/reasoning/azure_ai_foundry.py +93 -1
  242. agno/reasoning/deepseek.py +102 -2
  243. agno/reasoning/default.py +6 -7
  244. agno/reasoning/gemini.py +87 -3
  245. agno/reasoning/groq.py +109 -2
  246. agno/reasoning/helpers.py +6 -7
  247. agno/reasoning/manager.py +1238 -0
  248. agno/reasoning/ollama.py +93 -1
  249. agno/reasoning/openai.py +115 -1
  250. agno/reasoning/vertexai.py +85 -1
  251. agno/registry/__init__.py +3 -0
  252. agno/registry/registry.py +68 -0
  253. agno/remote/__init__.py +3 -0
  254. agno/remote/base.py +581 -0
  255. agno/run/__init__.py +2 -4
  256. agno/run/agent.py +134 -19
  257. agno/run/base.py +49 -1
  258. agno/run/cancel.py +65 -52
  259. agno/run/cancellation_management/__init__.py +9 -0
  260. agno/run/cancellation_management/base.py +78 -0
  261. agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
  262. agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
  263. agno/run/requirement.py +181 -0
  264. agno/run/team.py +111 -19
  265. agno/run/workflow.py +2 -1
  266. agno/session/agent.py +57 -92
  267. agno/session/summary.py +1 -1
  268. agno/session/team.py +62 -115
  269. agno/session/workflow.py +353 -57
  270. agno/skills/__init__.py +17 -0
  271. agno/skills/agent_skills.py +377 -0
  272. agno/skills/errors.py +32 -0
  273. agno/skills/loaders/__init__.py +4 -0
  274. agno/skills/loaders/base.py +27 -0
  275. agno/skills/loaders/local.py +216 -0
  276. agno/skills/skill.py +65 -0
  277. agno/skills/utils.py +107 -0
  278. agno/skills/validator.py +277 -0
  279. agno/table.py +10 -0
  280. agno/team/__init__.py +5 -1
  281. agno/team/remote.py +447 -0
  282. agno/team/team.py +3769 -2202
  283. agno/tools/brandfetch.py +27 -18
  284. agno/tools/browserbase.py +225 -16
  285. agno/tools/crawl4ai.py +3 -0
  286. agno/tools/duckduckgo.py +25 -71
  287. agno/tools/exa.py +0 -21
  288. agno/tools/file.py +14 -13
  289. agno/tools/file_generation.py +12 -6
  290. agno/tools/firecrawl.py +15 -7
  291. agno/tools/function.py +94 -113
  292. agno/tools/google_bigquery.py +11 -2
  293. agno/tools/google_drive.py +4 -3
  294. agno/tools/knowledge.py +9 -4
  295. agno/tools/mcp/mcp.py +301 -18
  296. agno/tools/mcp/multi_mcp.py +269 -14
  297. agno/tools/mem0.py +11 -10
  298. agno/tools/memory.py +47 -46
  299. agno/tools/mlx_transcribe.py +10 -7
  300. agno/tools/models/nebius.py +5 -5
  301. agno/tools/models_labs.py +20 -10
  302. agno/tools/nano_banana.py +151 -0
  303. agno/tools/parallel.py +0 -7
  304. agno/tools/postgres.py +76 -36
  305. agno/tools/python.py +14 -6
  306. agno/tools/reasoning.py +30 -23
  307. agno/tools/redshift.py +406 -0
  308. agno/tools/shopify.py +1519 -0
  309. agno/tools/spotify.py +919 -0
  310. agno/tools/tavily.py +4 -1
  311. agno/tools/toolkit.py +253 -18
  312. agno/tools/websearch.py +93 -0
  313. agno/tools/website.py +1 -1
  314. agno/tools/wikipedia.py +1 -1
  315. agno/tools/workflow.py +56 -48
  316. agno/tools/yfinance.py +12 -11
  317. agno/tracing/__init__.py +12 -0
  318. agno/tracing/exporter.py +161 -0
  319. agno/tracing/schemas.py +276 -0
  320. agno/tracing/setup.py +112 -0
  321. agno/utils/agent.py +251 -10
  322. agno/utils/cryptography.py +22 -0
  323. agno/utils/dttm.py +33 -0
  324. agno/utils/events.py +264 -7
  325. agno/utils/hooks.py +111 -3
  326. agno/utils/http.py +161 -2
  327. agno/utils/mcp.py +49 -8
  328. agno/utils/media.py +22 -1
  329. agno/utils/models/ai_foundry.py +9 -2
  330. agno/utils/models/claude.py +20 -5
  331. agno/utils/models/cohere.py +9 -2
  332. agno/utils/models/llama.py +9 -2
  333. agno/utils/models/mistral.py +4 -2
  334. agno/utils/os.py +0 -0
  335. agno/utils/print_response/agent.py +99 -16
  336. agno/utils/print_response/team.py +223 -24
  337. agno/utils/print_response/workflow.py +0 -2
  338. agno/utils/prompts.py +8 -6
  339. agno/utils/remote.py +23 -0
  340. agno/utils/response.py +1 -13
  341. agno/utils/string.py +91 -2
  342. agno/utils/team.py +62 -12
  343. agno/utils/tokens.py +657 -0
  344. agno/vectordb/base.py +15 -2
  345. agno/vectordb/cassandra/cassandra.py +1 -1
  346. agno/vectordb/chroma/__init__.py +2 -1
  347. agno/vectordb/chroma/chromadb.py +468 -23
  348. agno/vectordb/clickhouse/clickhousedb.py +1 -1
  349. agno/vectordb/couchbase/couchbase.py +6 -2
  350. agno/vectordb/lancedb/lance_db.py +7 -38
  351. agno/vectordb/lightrag/lightrag.py +7 -6
  352. agno/vectordb/milvus/milvus.py +118 -84
  353. agno/vectordb/mongodb/__init__.py +2 -1
  354. agno/vectordb/mongodb/mongodb.py +14 -31
  355. agno/vectordb/pgvector/pgvector.py +120 -66
  356. agno/vectordb/pineconedb/pineconedb.py +2 -19
  357. agno/vectordb/qdrant/__init__.py +2 -1
  358. agno/vectordb/qdrant/qdrant.py +33 -56
  359. agno/vectordb/redis/__init__.py +2 -1
  360. agno/vectordb/redis/redisdb.py +19 -31
  361. agno/vectordb/singlestore/singlestore.py +17 -9
  362. agno/vectordb/surrealdb/surrealdb.py +2 -38
  363. agno/vectordb/weaviate/__init__.py +2 -1
  364. agno/vectordb/weaviate/weaviate.py +7 -3
  365. agno/workflow/__init__.py +5 -1
  366. agno/workflow/agent.py +2 -2
  367. agno/workflow/condition.py +12 -10
  368. agno/workflow/loop.py +28 -9
  369. agno/workflow/parallel.py +21 -13
  370. agno/workflow/remote.py +362 -0
  371. agno/workflow/router.py +12 -9
  372. agno/workflow/step.py +261 -36
  373. agno/workflow/steps.py +12 -8
  374. agno/workflow/types.py +40 -77
  375. agno/workflow/workflow.py +939 -213
  376. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
  377. agno-2.4.3.dist-info/RECORD +677 -0
  378. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
  379. agno/tools/googlesearch.py +0 -98
  380. agno/tools/memori.py +0 -339
  381. agno-2.2.13.dist-info/RECORD +0 -575
  382. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
  383. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
@@ -5,13 +5,14 @@ from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Tuple, Ty
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
8
- from agno.exceptions import AgnoError, ModelProviderError
8
+ from agno.exceptions import ModelProviderError
9
9
  from agno.models.base import Model
10
10
  from agno.models.message import Message
11
11
  from agno.models.metrics import Metrics
12
12
  from agno.models.response import ModelResponse
13
13
  from agno.run.agent import RunOutput
14
14
  from agno.utils.log import log_debug, log_error, log_warning
15
+ from agno.utils.tokens import count_schema_tokens
15
16
 
16
17
  try:
17
18
  from boto3 import client as AwsClient
@@ -102,9 +103,8 @@ class AwsBedrock(Model):
102
103
  self.client = AwsClient(service_name="bedrock-runtime", region_name=self.aws_region)
103
104
  else:
104
105
  if not self.aws_access_key_id or not self.aws_secret_access_key:
105
- raise AgnoError(
106
- message="AWS credentials not found. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or provide a boto3 session.",
107
- status_code=400,
106
+ log_error(
107
+ "AWS credentials not found. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or provide a boto3 session."
108
108
  )
109
109
 
110
110
  self.client = AwsClient(
@@ -166,6 +166,26 @@ class AwsBedrock(Model):
166
166
 
167
167
  return self.async_session.client(**client_kwargs)
168
168
 
169
+ def to_dict(self) -> Dict[str, Any]:
170
+ """
171
+ Convert the model to a dictionary.
172
+
173
+ Returns:
174
+ Dict[str, Any]: The dictionary representation of the model.
175
+ """
176
+ model_dict = super().to_dict()
177
+ model_dict.update(
178
+ {
179
+ "aws_region": self.aws_region,
180
+ "max_tokens": self.max_tokens,
181
+ "temperature": self.temperature,
182
+ "top_p": self.top_p,
183
+ "stop_sequences": self.stop_sequences,
184
+ }
185
+ )
186
+ cleaned_dict = {k: v for k, v in model_dict.items() if v is not None}
187
+ return cleaned_dict
188
+
169
189
  def _format_tools_for_request(self, tools: Optional[List[Dict[str, Any]]]) -> List[Dict[str, Any]]:
170
190
  """
171
191
  Format the tools for the request.
@@ -219,21 +239,35 @@ class AwsBedrock(Model):
219
239
 
220
240
  return {k: v for k, v in request_kwargs.items() if v is not None}
221
241
 
222
- def _format_messages(self, messages: List[Message]) -> Tuple[List[Dict[str, Any]], Optional[List[Dict[str, Any]]]]:
242
+ def _format_messages(
243
+ self, messages: List[Message], compress_tool_results: bool = False
244
+ ) -> Tuple[List[Dict[str, Any]], Optional[List[Dict[str, Any]]]]:
223
245
  """
224
246
  Format the messages for the request.
225
247
 
248
+ Args:
249
+ messages: List of messages to format
250
+ compress_tool_results: Whether to compress tool results
251
+
226
252
  Returns:
227
253
  Tuple[List[Dict[str, Any]], Optional[List[Dict[str, Any]]]]: The formatted messages.
228
254
  """
255
+
229
256
  formatted_messages: List[Dict[str, Any]] = []
230
257
  system_message = None
231
258
  for message in messages:
232
259
  if message.role == "system":
233
260
  system_message = [{"text": message.content}]
261
+ elif message.role == "tool":
262
+ content = message.get_content(use_compressed_content=compress_tool_results)
263
+ tool_result = {
264
+ "toolUseId": message.tool_call_id,
265
+ "content": [{"json": {"result": content}}],
266
+ }
267
+ formatted_message: Dict[str, Any] = {"role": "user", "content": [{"toolResult": tool_result}]}
268
+ formatted_messages.append(formatted_message)
234
269
  else:
235
- formatted_message: Dict[str, Any] = {"role": message.role, "content": []}
236
- # Handle tool results
270
+ formatted_message = {"role": message.role, "content": []}
237
271
  if isinstance(message.content, list):
238
272
  formatted_message["content"].extend(message.content)
239
273
  elif message.tool_calls:
@@ -344,6 +378,65 @@ class AwsBedrock(Model):
344
378
  # TODO: Add caching: https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-call.html
345
379
  return formatted_messages, system_message
346
380
 
381
+ def count_tokens(
382
+ self,
383
+ messages: List[Message],
384
+ tools: Optional[List[Dict[str, Any]]] = None,
385
+ output_schema: Optional[Union[Dict, Type[BaseModel]]] = None,
386
+ ) -> int:
387
+ try:
388
+ formatted_messages, system_message = self._format_messages(messages, compress_tool_results=True)
389
+ converse_input: Dict[str, Any] = {"messages": formatted_messages}
390
+ if system_message:
391
+ converse_input["system"] = system_message
392
+
393
+ response = self.get_client().count_tokens(modelId=self.id, input={"converse": converse_input})
394
+ tokens = response.get("inputTokens", 0)
395
+
396
+ # Count tool tokens
397
+ if tools:
398
+ from agno.utils.tokens import count_tool_tokens
399
+
400
+ tokens += count_tool_tokens(tools, self.id)
401
+
402
+ # Count schema tokens
403
+ tokens += count_schema_tokens(output_schema, self.id)
404
+
405
+ return tokens
406
+ except Exception as e:
407
+ log_warning(f"Failed to count tokens via Bedrock API: {e}")
408
+ return super().count_tokens(messages, tools, output_schema)
409
+
410
+ async def acount_tokens(
411
+ self,
412
+ messages: List[Message],
413
+ tools: Optional[List[Dict[str, Any]]] = None,
414
+ output_schema: Optional[Union[Dict, Type[BaseModel]]] = None,
415
+ ) -> int:
416
+ try:
417
+ formatted_messages, system_message = self._format_messages(messages, compress_tool_results=True)
418
+ converse_input: Dict[str, Any] = {"messages": formatted_messages}
419
+ if system_message:
420
+ converse_input["system"] = system_message
421
+
422
+ async with self.get_async_client() as client:
423
+ response = await client.count_tokens(modelId=self.id, input={"converse": converse_input})
424
+ tokens = response.get("inputTokens", 0)
425
+
426
+ # Count tool tokens
427
+ if tools:
428
+ from agno.utils.tokens import count_tool_tokens
429
+
430
+ tokens += count_tool_tokens(tools, self.id)
431
+
432
+ # Count schema tokens
433
+ tokens += count_schema_tokens(output_schema, self.id)
434
+
435
+ return tokens
436
+ except Exception as e:
437
+ log_warning(f"Failed to count tokens via Bedrock API: {e}")
438
+ return await super().acount_tokens(messages, tools, output_schema)
439
+
347
440
  def invoke(
348
441
  self,
349
442
  messages: List[Message],
@@ -352,12 +445,13 @@ class AwsBedrock(Model):
352
445
  tools: Optional[List[Dict[str, Any]]] = None,
353
446
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
354
447
  run_response: Optional[RunOutput] = None,
448
+ compress_tool_results: bool = False,
355
449
  ) -> ModelResponse:
356
450
  """
357
451
  Invoke the Bedrock API.
358
452
  """
359
453
  try:
360
- formatted_messages, system_message = self._format_messages(messages)
454
+ formatted_messages, system_message = self._format_messages(messages, compress_tool_results)
361
455
 
362
456
  tool_config = None
363
457
  if tools:
@@ -400,12 +494,13 @@ class AwsBedrock(Model):
400
494
  tools: Optional[List[Dict[str, Any]]] = None,
401
495
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
402
496
  run_response: Optional[RunOutput] = None,
497
+ compress_tool_results: bool = False,
403
498
  ) -> Iterator[ModelResponse]:
404
499
  """
405
500
  Invoke the Bedrock API with streaming.
406
501
  """
407
502
  try:
408
- formatted_messages, system_message = self._format_messages(messages)
503
+ formatted_messages, system_message = self._format_messages(messages, compress_tool_results)
409
504
 
410
505
  tool_config = None
411
506
  if tools:
@@ -452,12 +547,13 @@ class AwsBedrock(Model):
452
547
  tools: Optional[List[Dict[str, Any]]] = None,
453
548
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
454
549
  run_response: Optional[RunOutput] = None,
550
+ compress_tool_results: bool = False,
455
551
  ) -> ModelResponse:
456
552
  """
457
553
  Async invoke the Bedrock API.
458
554
  """
459
555
  try:
460
- formatted_messages, system_message = self._format_messages(messages)
556
+ formatted_messages, system_message = self._format_messages(messages, compress_tool_results)
461
557
 
462
558
  tool_config = None
463
559
  if tools:
@@ -503,12 +599,13 @@ class AwsBedrock(Model):
503
599
  tools: Optional[List[Dict[str, Any]]] = None,
504
600
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
505
601
  run_response: Optional[RunOutput] = None,
602
+ compress_tool_results: bool = False,
506
603
  ) -> AsyncIterator[ModelResponse]:
507
604
  """
508
605
  Async invoke the Bedrock API with streaming.
509
606
  """
510
607
  try:
511
- formatted_messages, system_message = self._format_messages(messages)
608
+ formatted_messages, system_message = self._format_messages(messages, compress_tool_results)
512
609
 
513
610
  tool_config = None
514
611
  if tools:
@@ -549,30 +646,34 @@ class AwsBedrock(Model):
549
646
 
550
647
  # Overwrite the default from the base model
551
648
  def format_function_call_results(
552
- self, messages: List[Message], function_call_results: List[Message], **kwargs
649
+ self,
650
+ messages: List[Message],
651
+ function_call_results: List[Message],
652
+ compress_tool_results: bool = False,
653
+ **kwargs,
553
654
  ) -> None:
554
655
  """
555
- Handle the results of function calls.
656
+ Handle the results of function calls for Bedrock.
657
+ Uses compressed_content if compress_tool_results is True.
556
658
 
557
659
  Args:
558
660
  messages (List[Message]): The list of conversation messages.
559
661
  function_call_results (List[Message]): The results of the function calls.
662
+ compress_tool_results: Whether to compress tool results.
560
663
  **kwargs: Additional arguments including tool_ids.
561
664
  """
665
+
562
666
  if function_call_results:
563
667
  tool_ids = kwargs.get("tool_ids", [])
564
- tool_result_content: List = []
565
668
 
566
669
  for _fc_message_index, _fc_message in enumerate(function_call_results):
567
670
  # Use tool_call_id from message if tool_ids list is insufficient
568
671
  tool_id = tool_ids[_fc_message_index] if _fc_message_index < len(tool_ids) else _fc_message.tool_call_id
569
- tool_result = {
570
- "toolUseId": tool_id,
571
- "content": [{"json": {"result": _fc_message.content}}],
572
- }
573
- tool_result_content.append({"toolResult": tool_result})
672
+ if not _fc_message.tool_call_id:
673
+ _fc_message.tool_call_id = tool_id
574
674
 
575
- messages.append(Message(role="user", content=tool_result_content))
675
+ # Append as standard role="tool" message
676
+ messages.append(_fc_message)
576
677
 
577
678
  def _parse_provider_response(self, response: Dict[str, Any], **kwargs) -> ModelResponse:
578
679
  """