@strands-agents/sdk 0.6.0 → 1.0.0-rc.0

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 (487) hide show
  1. package/README.md +71 -7
  2. package/dist/src/__fixtures__/agent-helpers.d.ts +81 -4
  3. package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -1
  4. package/dist/src/__fixtures__/agent-helpers.js +76 -4
  5. package/dist/src/__fixtures__/agent-helpers.js.map +1 -1
  6. package/dist/src/__fixtures__/metrics-helpers.d.ts +30 -0
  7. package/dist/src/__fixtures__/metrics-helpers.d.ts.map +1 -1
  8. package/dist/src/__fixtures__/metrics-helpers.js +29 -6
  9. package/dist/src/__fixtures__/metrics-helpers.js.map +1 -1
  10. package/dist/src/__fixtures__/mock-message-model.d.ts +8 -4
  11. package/dist/src/__fixtures__/mock-message-model.d.ts.map +1 -1
  12. package/dist/src/__fixtures__/mock-message-model.js +13 -7
  13. package/dist/src/__fixtures__/mock-message-model.js.map +1 -1
  14. package/dist/src/__fixtures__/mock-meter.d.ts +32 -0
  15. package/dist/src/__fixtures__/mock-meter.d.ts.map +1 -0
  16. package/dist/src/__fixtures__/mock-meter.js +47 -0
  17. package/dist/src/__fixtures__/mock-meter.js.map +1 -0
  18. package/dist/src/__fixtures__/mock-plugin.d.ts +13 -0
  19. package/dist/src/__fixtures__/mock-plugin.d.ts.map +1 -0
  20. package/dist/src/__fixtures__/{mock-hook-provider.js → mock-plugin.js} +11 -6
  21. package/dist/src/__fixtures__/mock-plugin.js.map +1 -0
  22. package/dist/src/__fixtures__/tool-helpers.d.ts.map +1 -1
  23. package/dist/src/__fixtures__/tool-helpers.js +6 -2
  24. package/dist/src/__fixtures__/tool-helpers.js.map +1 -1
  25. package/dist/src/__tests__/index.test.js +21 -0
  26. package/dist/src/__tests__/index.test.js.map +1 -1
  27. package/dist/src/__tests__/mcp.test.js.map +1 -1
  28. package/dist/src/__tests__/mime.test.d.ts +2 -0
  29. package/dist/src/__tests__/mime.test.d.ts.map +1 -0
  30. package/dist/src/__tests__/mime.test.js +83 -0
  31. package/dist/src/__tests__/mime.test.js.map +1 -0
  32. package/dist/src/__tests__/state-store.test.d.ts +2 -0
  33. package/dist/src/__tests__/state-store.test.d.ts.map +1 -0
  34. package/dist/src/__tests__/{app-state.test.js → state-store.test.js} +86 -51
  35. package/dist/src/__tests__/state-store.test.js.map +1 -0
  36. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts +2 -0
  37. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts.map +1 -0
  38. package/dist/src/a2a/__tests__/a2a-agent.test.js +364 -0
  39. package/dist/src/a2a/__tests__/a2a-agent.test.js.map +1 -0
  40. package/dist/src/a2a/__tests__/adapters.test.d.ts +2 -0
  41. package/dist/src/a2a/__tests__/adapters.test.d.ts.map +1 -0
  42. package/dist/src/a2a/__tests__/adapters.test.js +151 -0
  43. package/dist/src/a2a/__tests__/adapters.test.js.map +1 -0
  44. package/dist/src/a2a/__tests__/events.test.d.ts +2 -0
  45. package/dist/src/a2a/__tests__/events.test.d.ts.map +1 -0
  46. package/dist/src/a2a/__tests__/events.test.js +66 -0
  47. package/dist/src/a2a/__tests__/events.test.js.map +1 -0
  48. package/dist/src/a2a/__tests__/executor.test.d.ts +2 -0
  49. package/dist/src/a2a/__tests__/executor.test.d.ts.map +1 -0
  50. package/dist/src/a2a/__tests__/executor.test.js +196 -0
  51. package/dist/src/a2a/__tests__/executor.test.js.map +1 -0
  52. package/dist/src/a2a/__tests__/server.test.d.ts +2 -0
  53. package/dist/src/a2a/__tests__/server.test.d.ts.map +1 -0
  54. package/dist/src/a2a/__tests__/server.test.js +51 -0
  55. package/dist/src/a2a/__tests__/server.test.js.map +1 -0
  56. package/dist/src/a2a/__tests__/server.test.node.d.ts +2 -0
  57. package/dist/src/a2a/__tests__/server.test.node.d.ts.map +1 -0
  58. package/dist/src/a2a/__tests__/server.test.node.js +110 -0
  59. package/dist/src/a2a/__tests__/server.test.node.js.map +1 -0
  60. package/dist/src/a2a/a2a-agent.d.ts +132 -0
  61. package/dist/src/a2a/a2a-agent.d.ts.map +1 -0
  62. package/dist/src/a2a/a2a-agent.js +255 -0
  63. package/dist/src/a2a/a2a-agent.js.map +1 -0
  64. package/dist/src/a2a/adapters.d.ts +27 -0
  65. package/dist/src/a2a/adapters.d.ts.map +1 -0
  66. package/dist/src/a2a/adapters.js +175 -0
  67. package/dist/src/a2a/adapters.js.map +1 -0
  68. package/dist/src/a2a/events.d.ts +44 -0
  69. package/dist/src/a2a/events.d.ts.map +1 -0
  70. package/dist/src/a2a/events.js +41 -0
  71. package/dist/src/a2a/events.js.map +1 -0
  72. package/dist/src/a2a/executor.d.ts +57 -0
  73. package/dist/src/a2a/executor.d.ts.map +1 -0
  74. package/dist/src/a2a/executor.js +130 -0
  75. package/dist/src/a2a/executor.js.map +1 -0
  76. package/dist/src/a2a/express-server.d.ts +67 -0
  77. package/dist/src/a2a/express-server.d.ts.map +1 -0
  78. package/dist/src/a2a/express-server.js +95 -0
  79. package/dist/src/a2a/express-server.js.map +1 -0
  80. package/dist/src/a2a/index.d.ts +15 -0
  81. package/dist/src/a2a/index.d.ts.map +1 -0
  82. package/dist/src/a2a/index.js +15 -0
  83. package/dist/src/a2a/index.js.map +1 -0
  84. package/dist/src/a2a/logging.d.ts +8 -0
  85. package/dist/src/a2a/logging.d.ts.map +1 -0
  86. package/dist/src/a2a/logging.js +15 -0
  87. package/dist/src/a2a/logging.js.map +1 -0
  88. package/dist/src/a2a/server.d.ts +67 -0
  89. package/dist/src/a2a/server.d.ts.map +1 -0
  90. package/dist/src/a2a/server.js +67 -0
  91. package/dist/src/a2a/server.js.map +1 -0
  92. package/dist/src/agent/__tests__/agent.hook.test.js +315 -51
  93. package/dist/src/agent/__tests__/agent.hook.test.js.map +1 -1
  94. package/dist/src/agent/__tests__/agent.test.js +298 -48
  95. package/dist/src/agent/__tests__/agent.test.js.map +1 -1
  96. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts +2 -0
  97. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts.map +1 -0
  98. package/dist/src/agent/__tests__/{agent.tracer.test.js → agent.tracer.test.node.js} +62 -50
  99. package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +1 -0
  100. package/dist/src/agent/__tests__/printer.test.js +7 -7
  101. package/dist/src/agent/__tests__/printer.test.js.map +1 -1
  102. package/dist/src/agent/__tests__/snapshot.test.js +50 -13
  103. package/dist/src/agent/__tests__/snapshot.test.js.map +1 -1
  104. package/dist/src/agent/agent.d.ts +55 -44
  105. package/dist/src/agent/agent.d.ts.map +1 -1
  106. package/dist/src/agent/agent.js +230 -128
  107. package/dist/src/agent/agent.js.map +1 -1
  108. package/dist/src/agent/printer.d.ts.map +1 -1
  109. package/dist/src/agent/printer.js +3 -0
  110. package/dist/src/agent/printer.js.map +1 -1
  111. package/dist/src/agent/snapshot.d.ts +3 -3
  112. package/dist/src/agent/snapshot.d.ts.map +1 -1
  113. package/dist/src/agent/snapshot.js +16 -8
  114. package/dist/src/agent/snapshot.js.map +1 -1
  115. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts +2 -0
  116. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts.map +1 -0
  117. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +100 -0
  118. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +1 -0
  119. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +26 -10
  120. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +1 -1
  121. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +153 -64
  122. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +1 -1
  123. package/dist/src/conversation-manager/conversation-manager.d.ts +87 -0
  124. package/dist/src/conversation-manager/conversation-manager.d.ts.map +1 -0
  125. package/dist/src/conversation-manager/conversation-manager.js +59 -0
  126. package/dist/src/conversation-manager/conversation-manager.js.map +1 -0
  127. package/dist/src/conversation-manager/index.d.ts +1 -0
  128. package/dist/src/conversation-manager/index.d.ts.map +1 -1
  129. package/dist/src/conversation-manager/index.js +1 -0
  130. package/dist/src/conversation-manager/index.js.map +1 -1
  131. package/dist/src/conversation-manager/null-conversation-manager.d.ts +12 -8
  132. package/dist/src/conversation-manager/null-conversation-manager.d.ts.map +1 -1
  133. package/dist/src/conversation-manager/null-conversation-manager.js +13 -7
  134. package/dist/src/conversation-manager/null-conversation-manager.js.map +1 -1
  135. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts +28 -19
  136. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
  137. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +57 -42
  138. package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
  139. package/dist/src/errors.d.ts +8 -0
  140. package/dist/src/errors.d.ts.map +1 -1
  141. package/dist/src/errors.js +11 -0
  142. package/dist/src/errors.js.map +1 -1
  143. package/dist/src/hooks/__tests__/events.test.js +387 -0
  144. package/dist/src/hooks/__tests__/events.test.js.map +1 -1
  145. package/dist/src/hooks/__tests__/registry.test.js +10 -154
  146. package/dist/src/hooks/__tests__/registry.test.js.map +1 -1
  147. package/dist/src/hooks/events.d.ts +148 -44
  148. package/dist/src/hooks/events.d.ts.map +1 -1
  149. package/dist/src/hooks/events.js +148 -11
  150. package/dist/src/hooks/events.js.map +1 -1
  151. package/dist/src/hooks/index.d.ts +3 -3
  152. package/dist/src/hooks/index.d.ts.map +1 -1
  153. package/dist/src/hooks/index.js +2 -2
  154. package/dist/src/hooks/registry.d.ts +1 -32
  155. package/dist/src/hooks/registry.d.ts.map +1 -1
  156. package/dist/src/hooks/registry.js +1 -47
  157. package/dist/src/hooks/registry.js.map +1 -1
  158. package/dist/src/hooks/types.d.ts +0 -31
  159. package/dist/src/hooks/types.d.ts.map +1 -1
  160. package/dist/src/index.d.ts +14 -13
  161. package/dist/src/index.d.ts.map +1 -1
  162. package/dist/src/index.js +11 -9
  163. package/dist/src/index.js.map +1 -1
  164. package/dist/src/mime.d.ts +24 -0
  165. package/dist/src/mime.d.ts.map +1 -0
  166. package/dist/src/mime.js +82 -0
  167. package/dist/src/mime.js.map +1 -0
  168. package/dist/src/models/__tests__/anthropic.test.js +79 -3
  169. package/dist/src/models/__tests__/anthropic.test.js.map +1 -1
  170. package/dist/src/models/__tests__/bedrock.test.js +1858 -627
  171. package/dist/src/models/__tests__/bedrock.test.js.map +1 -1
  172. package/dist/src/models/__tests__/google.test.d.ts +2 -0
  173. package/dist/src/models/__tests__/google.test.d.ts.map +1 -0
  174. package/dist/src/models/__tests__/{gemini.test.js → google.test.js} +155 -22
  175. package/dist/src/models/__tests__/google.test.js.map +1 -0
  176. package/dist/src/models/__tests__/model.test.js +25 -0
  177. package/dist/src/models/__tests__/model.test.js.map +1 -1
  178. package/dist/src/models/__tests__/openai.test.js +255 -96
  179. package/dist/src/models/__tests__/openai.test.js.map +1 -1
  180. package/dist/src/models/anthropic.d.ts.map +1 -1
  181. package/dist/src/models/anthropic.js +14 -14
  182. package/dist/src/models/anthropic.js.map +1 -1
  183. package/dist/src/models/bedrock.d.ts +67 -13
  184. package/dist/src/models/bedrock.d.ts.map +1 -1
  185. package/dist/src/models/bedrock.js +207 -28
  186. package/dist/src/models/bedrock.js.map +1 -1
  187. package/dist/src/models/{gemini → google}/adapters.d.ts +3 -3
  188. package/dist/src/models/{gemini → google}/adapters.d.ts.map +1 -1
  189. package/dist/src/models/{gemini → google}/adapters.js +66 -15
  190. package/dist/src/models/google/adapters.js.map +1 -0
  191. package/dist/src/models/{gemini → google}/errors.d.ts +7 -7
  192. package/dist/src/models/google/errors.d.ts.map +1 -0
  193. package/dist/src/models/{gemini → google}/errors.js +11 -5
  194. package/dist/src/models/google/errors.js.map +1 -0
  195. package/dist/src/models/google/index.d.ts +15 -0
  196. package/dist/src/models/google/index.d.ts.map +1 -0
  197. package/dist/src/models/google/index.js +15 -0
  198. package/dist/src/models/google/index.js.map +1 -0
  199. package/dist/src/models/{gemini → google}/model.d.ts +18 -18
  200. package/dist/src/models/{gemini → google}/model.d.ts.map +1 -1
  201. package/dist/src/models/{gemini → google}/model.js +22 -19
  202. package/dist/src/models/google/model.js.map +1 -0
  203. package/dist/src/models/{gemini → google}/types.d.ts +9 -9
  204. package/dist/src/models/{gemini → google}/types.d.ts.map +1 -1
  205. package/dist/src/models/google/types.js +5 -0
  206. package/dist/src/models/google/types.js.map +1 -0
  207. package/dist/src/models/model.d.ts +12 -0
  208. package/dist/src/models/model.d.ts.map +1 -1
  209. package/dist/src/models/model.js +6 -10
  210. package/dist/src/models/model.js.map +1 -1
  211. package/dist/src/models/openai.d.ts +44 -11
  212. package/dist/src/models/openai.d.ts.map +1 -1
  213. package/dist/src/models/openai.js +133 -79
  214. package/dist/src/models/openai.js.map +1 -1
  215. package/dist/src/models/streaming.d.ts +18 -0
  216. package/dist/src/models/streaming.d.ts.map +1 -1
  217. package/dist/src/models/streaming.js +29 -0
  218. package/dist/src/models/streaming.js.map +1 -1
  219. package/dist/src/multiagent/__tests__/events.test.js +201 -7
  220. package/dist/src/multiagent/__tests__/events.test.js.map +1 -1
  221. package/dist/src/multiagent/__tests__/graph.test.js +28 -13
  222. package/dist/src/multiagent/__tests__/graph.test.js.map +1 -1
  223. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts +2 -0
  224. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts.map +1 -0
  225. package/dist/src/multiagent/__tests__/graph.tracer.test.js +204 -0
  226. package/dist/src/multiagent/__tests__/graph.tracer.test.js.map +1 -0
  227. package/dist/src/multiagent/__tests__/nodes.test.js +76 -15
  228. package/dist/src/multiagent/__tests__/nodes.test.js.map +1 -1
  229. package/dist/src/multiagent/__tests__/swarm.test.js +67 -16
  230. package/dist/src/multiagent/__tests__/swarm.test.js.map +1 -1
  231. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts +2 -0
  232. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts.map +1 -0
  233. package/dist/src/multiagent/__tests__/swarm.tracer.test.js +235 -0
  234. package/dist/src/multiagent/__tests__/swarm.tracer.test.js.map +1 -0
  235. package/dist/src/multiagent/events.d.ts +62 -14
  236. package/dist/src/multiagent/events.d.ts.map +1 -1
  237. package/dist/src/multiagent/events.js +45 -3
  238. package/dist/src/multiagent/events.js.map +1 -1
  239. package/dist/src/multiagent/graph.d.ts +25 -11
  240. package/dist/src/multiagent/graph.d.ts.map +1 -1
  241. package/dist/src/multiagent/graph.js +76 -44
  242. package/dist/src/multiagent/graph.js.map +1 -1
  243. package/dist/src/multiagent/index.d.ts +4 -3
  244. package/dist/src/multiagent/index.d.ts.map +1 -1
  245. package/dist/src/multiagent/index.js.map +1 -1
  246. package/dist/src/multiagent/multiagent.d.ts +41 -0
  247. package/dist/src/multiagent/multiagent.d.ts.map +1 -0
  248. package/dist/src/multiagent/multiagent.js +2 -0
  249. package/dist/src/multiagent/multiagent.js.map +1 -0
  250. package/dist/src/multiagent/nodes.d.ts +35 -24
  251. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  252. package/dist/src/multiagent/nodes.js +50 -23
  253. package/dist/src/multiagent/nodes.js.map +1 -1
  254. package/dist/src/multiagent/plugins.d.ts +70 -0
  255. package/dist/src/multiagent/plugins.d.ts.map +1 -0
  256. package/dist/src/multiagent/plugins.js +70 -0
  257. package/dist/src/multiagent/plugins.js.map +1 -0
  258. package/dist/src/multiagent/state.d.ts +10 -5
  259. package/dist/src/multiagent/state.d.ts.map +1 -1
  260. package/dist/src/multiagent/state.js +20 -6
  261. package/dist/src/multiagent/state.js.map +1 -1
  262. package/dist/src/multiagent/swarm.d.ts +41 -17
  263. package/dist/src/multiagent/swarm.d.ts.map +1 -1
  264. package/dist/src/multiagent/swarm.js +101 -42
  265. package/dist/src/multiagent/swarm.js.map +1 -1
  266. package/dist/src/plugins/__tests__/plugin.test.d.ts +2 -0
  267. package/dist/src/plugins/__tests__/plugin.test.d.ts.map +1 -0
  268. package/dist/src/plugins/__tests__/plugin.test.js +114 -0
  269. package/dist/src/plugins/__tests__/plugin.test.js.map +1 -0
  270. package/dist/src/plugins/__tests__/registry.test.d.ts +2 -0
  271. package/dist/src/plugins/__tests__/registry.test.d.ts.map +1 -0
  272. package/dist/src/plugins/__tests__/registry.test.js +147 -0
  273. package/dist/src/plugins/__tests__/registry.test.js.map +1 -0
  274. package/dist/src/plugins/index.d.ts +30 -0
  275. package/dist/src/plugins/index.d.ts.map +1 -0
  276. package/dist/src/plugins/index.js +30 -0
  277. package/dist/src/plugins/index.js.map +1 -0
  278. package/dist/src/plugins/plugin.d.ts +74 -0
  279. package/dist/src/plugins/plugin.d.ts.map +1 -0
  280. package/dist/src/plugins/plugin.js +8 -0
  281. package/dist/src/plugins/plugin.js.map +1 -0
  282. package/dist/src/plugins/registry.d.ts +25 -0
  283. package/dist/src/plugins/registry.d.ts.map +1 -0
  284. package/dist/src/plugins/registry.js +41 -0
  285. package/dist/src/plugins/registry.js.map +1 -0
  286. package/dist/src/session/__tests__/session-manager.test.js +110 -92
  287. package/dist/src/session/__tests__/session-manager.test.js.map +1 -1
  288. package/dist/src/session/index.d.ts +0 -1
  289. package/dist/src/session/index.d.ts.map +1 -1
  290. package/dist/src/session/index.js +0 -1
  291. package/dist/src/session/index.js.map +1 -1
  292. package/dist/src/session/session-manager.d.ts +11 -8
  293. package/dist/src/session/session-manager.d.ts.map +1 -1
  294. package/dist/src/session/session-manager.js +24 -16
  295. package/dist/src/session/session-manager.js.map +1 -1
  296. package/dist/src/session/storage.d.ts +1 -1
  297. package/dist/src/session/storage.d.ts.map +1 -1
  298. package/dist/src/session/types.d.ts +2 -2
  299. package/dist/src/session/types.d.ts.map +1 -1
  300. package/dist/src/{app-state.d.ts → state-store.d.ts} +11 -11
  301. package/dist/src/state-store.d.ts.map +1 -0
  302. package/dist/src/{app-state.js → state-store.js} +8 -7
  303. package/dist/src/state-store.js.map +1 -0
  304. package/dist/src/telemetry/__tests__/config.test.js +24 -0
  305. package/dist/src/telemetry/__tests__/config.test.js.map +1 -1
  306. package/dist/src/telemetry/__tests__/config.test.node.js +56 -0
  307. package/dist/src/telemetry/__tests__/config.test.node.js.map +1 -1
  308. package/dist/src/telemetry/__tests__/local-trace.test.d.ts +2 -0
  309. package/dist/src/telemetry/__tests__/local-trace.test.d.ts.map +1 -0
  310. package/dist/src/telemetry/__tests__/local-trace.test.js +158 -0
  311. package/dist/src/telemetry/__tests__/local-trace.test.js.map +1 -0
  312. package/dist/src/telemetry/__tests__/meter.test.js +176 -9
  313. package/dist/src/telemetry/__tests__/meter.test.js.map +1 -1
  314. package/dist/src/telemetry/__tests__/tracer.test.node.js +151 -2
  315. package/dist/src/telemetry/__tests__/tracer.test.node.js.map +1 -1
  316. package/dist/src/telemetry/config.d.ts +72 -12
  317. package/dist/src/telemetry/config.d.ts.map +1 -1
  318. package/dist/src/telemetry/config.js +102 -25
  319. package/dist/src/telemetry/config.js.map +1 -1
  320. package/dist/src/telemetry/index.d.ts +10 -7
  321. package/dist/src/telemetry/index.d.ts.map +1 -1
  322. package/dist/src/telemetry/index.js +9 -6
  323. package/dist/src/telemetry/index.js.map +1 -1
  324. package/dist/src/telemetry/meter.d.ts +23 -17
  325. package/dist/src/telemetry/meter.d.ts.map +1 -1
  326. package/dist/src/telemetry/meter.js +86 -41
  327. package/dist/src/telemetry/meter.js.map +1 -1
  328. package/dist/src/telemetry/tracer.d.ts +134 -18
  329. package/dist/src/telemetry/tracer.d.ts.map +1 -1
  330. package/dist/src/telemetry/tracer.js +325 -38
  331. package/dist/src/telemetry/tracer.js.map +1 -1
  332. package/dist/src/telemetry/types.d.ts +51 -0
  333. package/dist/src/telemetry/types.d.ts.map +1 -1
  334. package/dist/src/telemetry/utils.d.ts +10 -0
  335. package/dist/src/telemetry/utils.d.ts.map +1 -0
  336. package/dist/src/telemetry/utils.js +13 -0
  337. package/dist/src/telemetry/utils.js.map +1 -0
  338. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts +2 -0
  339. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts.map +1 -0
  340. package/dist/src/tools/__tests__/structured-output-tool.test.js +84 -0
  341. package/dist/src/tools/__tests__/structured-output-tool.test.js.map +1 -0
  342. package/dist/src/tools/__tests__/tool.test.js +22 -1
  343. package/dist/src/tools/__tests__/tool.test.js.map +1 -1
  344. package/dist/src/tools/function-tool.d.ts +11 -1
  345. package/dist/src/tools/function-tool.d.ts.map +1 -1
  346. package/dist/src/tools/function-tool.js +64 -3
  347. package/dist/src/tools/function-tool.js.map +1 -1
  348. package/dist/src/tools/structured-output-tool.d.ts +41 -0
  349. package/dist/src/tools/structured-output-tool.d.ts.map +1 -0
  350. package/dist/src/tools/structured-output-tool.js +82 -0
  351. package/dist/src/tools/structured-output-tool.js.map +1 -0
  352. package/dist/src/tools/tool.d.ts +2 -2
  353. package/dist/src/tools/tool.d.ts.map +1 -1
  354. package/dist/src/tools/zod-tool.js +1 -1
  355. package/dist/src/tools/zod-tool.js.map +1 -1
  356. package/dist/src/{utils/zod.d.ts → tools/zod-utils.d.ts} +1 -1
  357. package/dist/src/tools/zod-utils.d.ts.map +1 -0
  358. package/dist/src/{utils/zod.js → tools/zod-utils.js} +1 -1
  359. package/dist/src/tools/zod-utils.js.map +1 -0
  360. package/dist/src/tsconfig.tsbuildinfo +1 -1
  361. package/dist/src/types/__tests__/agent.test.js +127 -0
  362. package/dist/src/types/__tests__/agent.test.js.map +1 -1
  363. package/dist/src/types/__tests__/media.test.js +22 -16
  364. package/dist/src/types/__tests__/media.test.js.map +1 -1
  365. package/dist/src/types/agent.d.ts +101 -7
  366. package/dist/src/types/agent.d.ts.map +1 -1
  367. package/dist/src/types/agent.js +26 -0
  368. package/dist/src/types/agent.js.map +1 -1
  369. package/dist/src/types/media.d.ts +27 -30
  370. package/dist/src/types/media.d.ts.map +1 -1
  371. package/dist/src/types/media.js +15 -56
  372. package/dist/src/types/media.js.map +1 -1
  373. package/dist/src/types/messages.d.ts +18 -4
  374. package/dist/src/types/messages.d.ts.map +1 -1
  375. package/dist/src/types/messages.js +22 -26
  376. package/dist/src/types/messages.js.map +1 -1
  377. package/dist/src/types/serializable.d.ts +34 -4
  378. package/dist/src/types/serializable.d.ts.map +1 -1
  379. package/dist/src/types/serializable.js +31 -2
  380. package/dist/src/types/serializable.js.map +1 -1
  381. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +17 -4
  382. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +1 -1
  383. package/dist/src/vended-tools/bash/bash.d.ts.map +1 -1
  384. package/dist/src/vended-tools/bash/bash.js +16 -14
  385. package/dist/src/vended-tools/bash/bash.js.map +1 -1
  386. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts.map +1 -0
  387. package/dist/src/vended-tools/{file_editor → file-editor}/__tests__/file-editor.test.node.js +11 -4
  388. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +1 -0
  389. package/dist/src/vended-tools/{file_editor → file-editor}/file-editor.d.ts +1 -1
  390. package/dist/src/vended-tools/{file_editor → file-editor}/file-editor.d.ts.map +1 -1
  391. package/dist/src/vended-tools/{file_editor → file-editor}/file-editor.js +2 -2
  392. package/dist/src/vended-tools/{file_editor → file-editor}/file-editor.js.map +1 -1
  393. package/dist/src/vended-tools/{file_editor → file-editor}/index.d.ts.map +1 -1
  394. package/dist/src/vended-tools/file-editor/index.js.map +1 -0
  395. package/dist/src/vended-tools/{file_editor → file-editor}/types.d.ts.map +1 -1
  396. package/dist/src/vended-tools/file-editor/types.js.map +1 -0
  397. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts.map +1 -0
  398. package/dist/src/vended-tools/{http_request → http-request}/__tests__/http-request.test.js.map +1 -1
  399. package/dist/src/vended-tools/{http_request → http-request}/http-request.d.ts.map +1 -1
  400. package/dist/src/vended-tools/{http_request → http-request}/http-request.js.map +1 -1
  401. package/dist/src/vended-tools/{http_request → http-request}/index.d.ts.map +1 -1
  402. package/dist/src/vended-tools/http-request/index.js.map +1 -0
  403. package/dist/src/vended-tools/{http_request → http-request}/types.d.ts.map +1 -1
  404. package/dist/src/vended-tools/http-request/types.js.map +1 -0
  405. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +5 -4
  406. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js.map +1 -1
  407. package/dist/src/vended-tools/notebook/notebook.js +2 -2
  408. package/dist/src/vended-tools/notebook/notebook.js.map +1 -1
  409. package/package.json +63 -17
  410. package/dist/src/__fixtures__/mock-hook-provider.d.ts +0 -10
  411. package/dist/src/__fixtures__/mock-hook-provider.d.ts.map +0 -1
  412. package/dist/src/__fixtures__/mock-hook-provider.js.map +0 -1
  413. package/dist/src/__tests__/app-state.test.d.ts +0 -2
  414. package/dist/src/__tests__/app-state.test.d.ts.map +0 -1
  415. package/dist/src/__tests__/app-state.test.js.map +0 -1
  416. package/dist/src/agent/__tests__/agent.tracer.test.d.ts +0 -2
  417. package/dist/src/agent/__tests__/agent.tracer.test.d.ts.map +0 -1
  418. package/dist/src/agent/__tests__/agent.tracer.test.js.map +0 -1
  419. package/dist/src/app-state.d.ts.map +0 -1
  420. package/dist/src/app-state.js.map +0 -1
  421. package/dist/src/models/__tests__/gemini.test.d.ts +0 -2
  422. package/dist/src/models/__tests__/gemini.test.d.ts.map +0 -1
  423. package/dist/src/models/__tests__/gemini.test.js.map +0 -1
  424. package/dist/src/models/gemini/adapters.js.map +0 -1
  425. package/dist/src/models/gemini/errors.d.ts.map +0 -1
  426. package/dist/src/models/gemini/errors.js.map +0 -1
  427. package/dist/src/models/gemini/model.js.map +0 -1
  428. package/dist/src/models/gemini/types.js +0 -5
  429. package/dist/src/models/gemini/types.js.map +0 -1
  430. package/dist/src/multiagent/base.d.ts +0 -25
  431. package/dist/src/multiagent/base.d.ts.map +0 -1
  432. package/dist/src/multiagent/base.js +0 -2
  433. package/dist/src/multiagent/base.js.map +0 -1
  434. package/dist/src/structured-output/__tests__/context.test.d.ts +0 -2
  435. package/dist/src/structured-output/__tests__/context.test.d.ts.map +0 -1
  436. package/dist/src/structured-output/__tests__/context.test.js +0 -201
  437. package/dist/src/structured-output/__tests__/context.test.js.map +0 -1
  438. package/dist/src/structured-output/__tests__/exceptions.test.d.ts +0 -2
  439. package/dist/src/structured-output/__tests__/exceptions.test.d.ts.map +0 -1
  440. package/dist/src/structured-output/__tests__/exceptions.test.js +0 -103
  441. package/dist/src/structured-output/__tests__/exceptions.test.js.map +0 -1
  442. package/dist/src/structured-output/__tests__/tool.test.d.ts +0 -2
  443. package/dist/src/structured-output/__tests__/tool.test.d.ts.map +0 -1
  444. package/dist/src/structured-output/__tests__/tool.test.js +0 -256
  445. package/dist/src/structured-output/__tests__/tool.test.js.map +0 -1
  446. package/dist/src/structured-output/__tests__/utils.test.d.ts +0 -2
  447. package/dist/src/structured-output/__tests__/utils.test.d.ts.map +0 -1
  448. package/dist/src/structured-output/__tests__/utils.test.js +0 -183
  449. package/dist/src/structured-output/__tests__/utils.test.js.map +0 -1
  450. package/dist/src/structured-output/context.d.ts +0 -91
  451. package/dist/src/structured-output/context.d.ts.map +0 -1
  452. package/dist/src/structured-output/context.js +0 -112
  453. package/dist/src/structured-output/context.js.map +0 -1
  454. package/dist/src/structured-output/exceptions.d.ts +0 -18
  455. package/dist/src/structured-output/exceptions.d.ts.map +0 -1
  456. package/dist/src/structured-output/exceptions.js +0 -28
  457. package/dist/src/structured-output/exceptions.js.map +0 -1
  458. package/dist/src/structured-output/tool.d.ts +0 -33
  459. package/dist/src/structured-output/tool.d.ts.map +0 -1
  460. package/dist/src/structured-output/tool.js +0 -73
  461. package/dist/src/structured-output/tool.js.map +0 -1
  462. package/dist/src/structured-output/utils.d.ts +0 -23
  463. package/dist/src/structured-output/utils.d.ts.map +0 -1
  464. package/dist/src/structured-output/utils.js +0 -104
  465. package/dist/src/structured-output/utils.js.map +0 -1
  466. package/dist/src/utils/zod.d.ts.map +0 -1
  467. package/dist/src/utils/zod.js.map +0 -1
  468. package/dist/src/vended-tools/file_editor/__tests__/file-editor.test.node.d.ts.map +0 -1
  469. package/dist/src/vended-tools/file_editor/__tests__/file-editor.test.node.js.map +0 -1
  470. package/dist/src/vended-tools/file_editor/index.js.map +0 -1
  471. package/dist/src/vended-tools/file_editor/types.js.map +0 -1
  472. package/dist/src/vended-tools/http_request/__tests__/http-request.test.d.ts.map +0 -1
  473. package/dist/src/vended-tools/http_request/index.js.map +0 -1
  474. package/dist/src/vended-tools/http_request/types.js.map +0 -1
  475. /package/dist/src/vended-tools/{file_editor → file-editor}/__tests__/file-editor.test.node.d.ts +0 -0
  476. /package/dist/src/vended-tools/{file_editor → file-editor}/index.d.ts +0 -0
  477. /package/dist/src/vended-tools/{file_editor → file-editor}/index.js +0 -0
  478. /package/dist/src/vended-tools/{file_editor → file-editor}/types.d.ts +0 -0
  479. /package/dist/src/vended-tools/{file_editor → file-editor}/types.js +0 -0
  480. /package/dist/src/vended-tools/{http_request → http-request}/__tests__/http-request.test.d.ts +0 -0
  481. /package/dist/src/vended-tools/{http_request → http-request}/__tests__/http-request.test.js +0 -0
  482. /package/dist/src/vended-tools/{http_request → http-request}/http-request.d.ts +0 -0
  483. /package/dist/src/vended-tools/{http_request → http-request}/http-request.js +0 -0
  484. /package/dist/src/vended-tools/{http_request → http-request}/index.d.ts +0 -0
  485. /package/dist/src/vended-tools/{http_request → http-request}/index.js +0 -0
  486. /package/dist/src/vended-tools/{http_request → http-request}/types.d.ts +0 -0
  487. /package/dist/src/vended-tools/{http_request → http-request}/types.js +0 -0
@@ -50,30 +50,31 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
50
50
  var e = new Error(message);
51
51
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
52
  });
53
- import { AgentResult } from '../types/agent.js';
53
+ import { AgentResult, } from '../types/agent.js';
54
54
  import { BedrockModel } from '../models/bedrock.js';
55
55
  import { contentBlockFromData, Message, TextBlock, ToolResultBlock, ToolUseBlock, } from '../types/messages.js';
56
56
  import { McpClient } from '../mcp.js';
57
57
  import {} from '../tools/tool.js';
58
58
  import { systemPromptFromData } from '../types/messages.js';
59
- import { normalizeError, ConcurrentInvocationError, MaxTokensError } from '../errors.js';
59
+ import { normalizeError, ConcurrentInvocationError, StructuredOutputError } from '../errors.js';
60
60
  import { Model } from '../models/model.js';
61
61
  import { isModelStreamEvent } from '../models/streaming.js';
62
62
  import { ToolRegistry } from '../registry/tool-registry.js';
63
- import { AppState } from '../app-state.js';
63
+ import { StateStore } from '../state-store.js';
64
64
  import { AgentPrinter, getDefaultAppender } from './printer.js';
65
+ import { PluginRegistry } from '../plugins/registry.js';
65
66
  import { SlidingWindowConversationManager } from '../conversation-manager/sliding-window-conversation-manager.js';
67
+ import { ConversationManager } from '../conversation-manager/conversation-manager.js';
66
68
  import { HookRegistryImplementation } from '../hooks/registry.js';
67
69
  import { InitializedEvent, AfterInvocationEvent, AfterModelCallEvent, AfterToolCallEvent, AfterToolsEvent, BeforeInvocationEvent, BeforeModelCallEvent, BeforeToolCallEvent, BeforeToolsEvent, HookableEvent, MessageAddedEvent, ModelStreamUpdateEvent, ContentBlockEvent, ModelMessageEvent, ToolResultEvent, AgentResultEvent, ToolStreamUpdateEvent, } from '../hooks/events.js';
68
- import { createStructuredOutputContext } from '../structured-output/context.js';
69
- import { StructuredOutputException } from '../structured-output/exceptions.js';
70
+ import { StructuredOutputTool, STRUCTURED_OUTPUT_TOOL_NAME } from '../tools/structured-output-tool.js';
70
71
  import { Tracer } from '../telemetry/tracer.js';
71
72
  import { Meter } from '../telemetry/meter.js';
72
73
  import { logger } from '../logging/logger.js';
73
- /** Fallback name used when no agent name is provided in the config. */
74
+ /** Default name assigned to agents when none is provided. */
74
75
  const DEFAULT_AGENT_NAME = 'Strands Agent';
75
- /** Fallback agent ID used when no agent ID is provided in the config. */
76
- const DEFAULT_AGENT_ID = 'default';
76
+ /** Default identifier assigned to agents when none is provided. */
77
+ const DEFAULT_AGENT_ID = 'agent';
77
78
  /**
78
79
  * Orchestrates the interaction between a model, a set of tools, and MCP clients.
79
80
  * The Agent is responsible for managing the lifecycle of tools and clients
@@ -88,16 +89,8 @@ export class Agent {
88
89
  * App state storage accessible to tools and application logic.
89
90
  * State is not passed to the model during inference.
90
91
  */
91
- state;
92
- /**
93
- * Conversation manager for handling message history and context overflow.
94
- */
95
- conversationManager;
96
- /**
97
- * Hook registry for managing event callbacks.
98
- * Hooks enable observing and extending agent behavior.
99
- */
100
- hooks;
92
+ appState;
93
+ _conversationManager;
101
94
  /**
102
95
  * The model provider used by the agent for inference.
103
96
  */
@@ -113,11 +106,13 @@ export class Agent {
113
106
  /**
114
107
  * The unique identifier of the agent instance.
115
108
  */
116
- agentId;
109
+ id;
117
110
  /**
118
111
  * Optional description of what the agent does.
119
112
  */
120
113
  description;
114
+ _hooksRegistry;
115
+ _pluginRegistry;
121
116
  _toolRegistry;
122
117
  _mcpClients;
123
118
  _initialized;
@@ -135,16 +130,12 @@ export class Agent {
135
130
  constructor(config) {
136
131
  // Initialize public fields
137
132
  this.messages = (config?.messages ?? []).map((msg) => (msg instanceof Message ? msg : Message.fromMessageData(msg)));
138
- this.state = new AppState(config?.state);
139
- this.conversationManager = config?.conversationManager ?? new SlidingWindowConversationManager({ windowSize: 40 });
133
+ this.appState = new StateStore(config?.appState);
134
+ this._conversationManager = config?.conversationManager ?? new SlidingWindowConversationManager({ windowSize: 40 });
140
135
  this.name = config?.name ?? DEFAULT_AGENT_NAME;
141
- this.agentId = config?.agentId ?? DEFAULT_AGENT_ID;
136
+ this.id = config?.id ?? DEFAULT_AGENT_ID;
142
137
  if (config?.description !== undefined)
143
138
  this.description = config.description;
144
- // Initialize hooks and register conversation manager hooks
145
- this.hooks = new HookRegistryImplementation();
146
- this.hooks.addHook(this.conversationManager);
147
- this.hooks.addAllHooks(config?.hooks ?? []);
148
139
  if (typeof config?.model === 'string') {
149
140
  this.model = new BedrockModel({ modelId: config.model });
150
141
  }
@@ -154,6 +145,14 @@ export class Agent {
154
145
  const { tools, mcpClients } = flattenTools(config?.tools ?? []);
155
146
  this._toolRegistry = new ToolRegistry(tools);
156
147
  this._mcpClients = mcpClients;
148
+ // Initialize hooks registry
149
+ this._hooksRegistry = new HookRegistryImplementation();
150
+ // Initialize plugin registry with all plugins to be initialized during initialize()
151
+ this._pluginRegistry = new PluginRegistry([
152
+ this._conversationManager,
153
+ ...(config?.plugins ?? []),
154
+ ...(config?.sessionManager ? [config.sessionManager] : []),
155
+ ]);
157
156
  if (config?.systemPrompt !== undefined) {
158
157
  this.systemPrompt = systemPromptFromData(config.systemPrompt);
159
158
  }
@@ -168,20 +167,41 @@ export class Agent {
168
167
  this._tracer = new Tracer(config?.traceAttributes);
169
168
  // Initialize meter for local metrics accumulation
170
169
  this._meter = new Meter();
171
- if (config?.sessionManager) {
172
- this.hooks.addHook(config.sessionManager);
173
- }
174
170
  this._initialized = false;
175
171
  }
172
+ /**
173
+ * Register a hook callback for a specific event type.
174
+ *
175
+ * @param eventType - The event class constructor to register the callback for
176
+ * @param callback - The callback function to invoke when the event occurs
177
+ * @returns Cleanup function that removes the callback when invoked
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * const agent = new Agent({ model })
182
+ *
183
+ * const cleanup = agent.addHook(BeforeInvocationEvent, (event) => {
184
+ * console.log('Invocation started')
185
+ * })
186
+ *
187
+ * // Later, to remove the hook:
188
+ * cleanup()
189
+ * ```
190
+ */
191
+ addHook(eventType, callback) {
192
+ return this._hooksRegistry.addCallback(eventType, callback);
193
+ }
176
194
  async initialize() {
177
195
  if (this._initialized) {
178
196
  return;
179
197
  }
198
+ // Initialize MCP clients and register their tools
180
199
  await Promise.all(this._mcpClients.map(async (client) => {
181
200
  const tools = await client.listTools();
182
201
  this._toolRegistry.add(tools);
183
202
  }));
184
- await this.hooks.invokeCallbacks(new InitializedEvent({ agent: this }));
203
+ await this._pluginRegistry.initialize(this);
204
+ await this._hooksRegistry.invokeCallbacks(new InitializedEvent({ agent: this }));
185
205
  this._initialized = true;
186
206
  }
187
207
  /**
@@ -274,24 +294,29 @@ export class Agent {
274
294
  await this.initialize();
275
295
  // Delegate to _stream and process events through printer and hooks
276
296
  const streamGenerator = this._stream(args, options);
277
- let result = await streamGenerator.next();
278
- while (!result.done) {
279
- const event = result.value;
280
- // Invoke hook callbacks for hookable events (all current events are hookable;
281
- // the guard exists for future StreamEvent subclasses that may not be)
282
- if (event instanceof HookableEvent) {
283
- await this.hooks.invokeCallbacks(event);
297
+ try {
298
+ let result = await streamGenerator.next();
299
+ while (!result.done) {
300
+ yield await this._invokeCallbacks(result.value);
301
+ result = await streamGenerator.next();
302
+ }
303
+ yield await this._invokeCallbacks(new AgentResultEvent({ agent: this, result: result.value }));
304
+ return result.value;
305
+ }
306
+ finally {
307
+ // Drain remaining events from _stream() so cleanup events (after events
308
+ // from finally blocks) still get their hooks and printer invoked.
309
+ let result = await streamGenerator.return(undefined);
310
+ while (!result.done) {
311
+ try {
312
+ yield await this._invokeCallbacks(result.value);
313
+ }
314
+ catch (error) {
315
+ logger.warn(`event_type=<${result.value.type}>, error=<${error}> | error invoking callbacks during cleanup`);
316
+ }
317
+ result = await streamGenerator.next();
284
318
  }
285
- this._printer?.processEvent(event);
286
- yield event;
287
- result = await streamGenerator.next();
288
319
  }
289
- // Yield final result as last event
290
- const agentResultEvent = new AgentResultEvent({ agent: this, result: result.value });
291
- await this.hooks.invokeCallbacks(agentResultEvent);
292
- this._printer?.processEvent(agentResultEvent);
293
- yield agentResultEvent;
294
- return result.value;
295
320
  }
296
321
  catch (e_1) {
297
322
  env_1.error = e_1;
@@ -301,6 +326,19 @@ export class Agent {
301
326
  __disposeResources(env_1);
302
327
  }
303
328
  }
329
+ /**
330
+ * Invokes hook callbacks and printer for a stream event.
331
+ *
332
+ * @param event - The event to process
333
+ * @returns The event after processing
334
+ */
335
+ async _invokeCallbacks(event) {
336
+ if (event instanceof HookableEvent) {
337
+ await this._hooksRegistry.invokeCallbacks(event);
338
+ }
339
+ this._printer?.processEvent(event);
340
+ return event;
341
+ }
304
342
  /**
305
343
  * Internal implementation of the agent streaming logic.
306
344
  * Separated to centralize printer event processing in the public stream method.
@@ -311,11 +349,11 @@ export class Agent {
311
349
  */
312
350
  async *_stream(args, options) {
313
351
  let currentArgs = args;
314
- let forcedToolChoice = undefined;
315
352
  let result;
316
- // Create structured output context (uses null object pattern when no schema)
317
- const schema = options?.structuredOutputSchema ?? this._structuredOutputSchema;
318
- const context = createStructuredOutputContext(schema);
353
+ // Resolve structured output schema from per-invocation options or constructor config
354
+ const structuredOutputSchema = options?.structuredOutputSchema ?? this._structuredOutputSchema;
355
+ const structuredOutputTool = structuredOutputSchema ? new StructuredOutputTool(structuredOutputSchema) : undefined;
356
+ let structuredOutputChoice;
319
357
  // Emit event before the try block
320
358
  yield new BeforeInvocationEvent({ agent: this });
321
359
  // Normalize input to get the user messages for telemetry
@@ -326,18 +364,20 @@ export class Agent {
326
364
  const agentSpanOptions = {
327
365
  messages: inputMessages,
328
366
  agentName: this.name,
329
- agentId: this.agentId,
367
+ agentId: this.id,
330
368
  tools: this.tools,
331
369
  };
332
370
  if (agentModelId)
333
371
  agentSpanOptions.modelId = agentModelId;
334
- if (this.systemPrompt)
372
+ if (this.systemPrompt !== undefined)
335
373
  agentSpanOptions.systemPrompt = this.systemPrompt;
336
374
  const agentSpan = this._tracer.startAgentSpan(agentSpanOptions);
337
375
  let caughtError;
338
376
  try {
339
- // Register structured output tool
340
- context.registerTool(this._toolRegistry);
377
+ // Register structured output tool if schema provided
378
+ if (structuredOutputTool) {
379
+ this._toolRegistry.add(structuredOutputTool);
380
+ }
341
381
  // Main agent loop - continues until model stops without requesting tools
342
382
  while (true) {
343
383
  // Start metrics cycle tracking
@@ -348,69 +388,65 @@ export class Agent {
348
388
  messages: this.messages,
349
389
  });
350
390
  try {
351
- const modelResult = yield* this.invokeModel(currentArgs, forcedToolChoice);
352
- currentArgs = undefined; // Only pass args on first invocation
353
- const wasForced = forcedToolChoice !== undefined;
354
- forcedToolChoice = undefined; // Clear after use
355
- if (modelResult.stopReason !== 'toolUse') {
356
- // Special handling for maxTokens - always fail regardless of whether we have structured output
357
- if (modelResult.stopReason === 'maxTokens') {
358
- throw new MaxTokensError('The model reached maxTokens before producing structured output. Consider increasing maxTokens in your model configuration.', modelResult.message);
391
+ // Normalize input and append user messages on first invocation only
392
+ if (currentArgs !== undefined) {
393
+ const messagesToAppend = this._normalizeInput(currentArgs);
394
+ for (const message of messagesToAppend) {
395
+ yield this._appendMessage(message);
359
396
  }
360
- // Check if we need to force structured output tool
361
- if (!context.hasResult()) {
362
- if (wasForced) {
363
- // Already tried forcing - LLM refused to use the tool
364
- throw new StructuredOutputException('The model failed to invoke the structured output tool even after it was forced.');
397
+ currentArgs = undefined;
398
+ }
399
+ const modelResult = yield* this._invokeModel(structuredOutputChoice);
400
+ if (modelResult.stopReason !== 'toolUse') {
401
+ // If structured output is required, force it
402
+ if (structuredOutputTool) {
403
+ if (structuredOutputChoice) {
404
+ throw new StructuredOutputError('The model failed to invoke the structured output tool even after it was forced.');
365
405
  }
366
- // Force the model to use the structured output tool
367
- const toolName = context.getToolName();
368
- forcedToolChoice = { tool: { name: toolName } };
369
- this._meter.endCycle(cycleStartTime);
370
- this._tracer.endAgentLoopSpan(cycleSpan);
371
- continue;
406
+ structuredOutputChoice = { tool: { name: STRUCTURED_OUTPUT_TOOL_NAME } };
372
407
  }
373
- // Loop terminates - no tool use requested (and structured output satisfied if needed)
374
- yield this._appendMessage(modelResult.message);
375
- // End cycle tracking
376
408
  this._meter.endCycle(cycleStartTime);
377
- // End cycle span
378
409
  this._tracer.endAgentLoopSpan(cycleSpan);
379
- const structuredOutput = context.getResult();
410
+ yield this._appendMessage(modelResult.message);
411
+ if (structuredOutputChoice) {
412
+ continue;
413
+ }
380
414
  result = new AgentResult({
381
415
  stopReason: modelResult.stopReason,
382
416
  lastMessage: modelResult.message,
383
- structuredOutput,
417
+ traces: this._tracer.localTraces,
384
418
  metrics: this._meter.metrics,
385
419
  });
386
420
  return result;
387
421
  }
388
- // Execute tools sequentially
422
+ // Execute tools
389
423
  const toolResultMessage = yield* this.executeTools(modelResult.message, this._toolRegistry);
390
424
  /**
391
425
  * Deferred append: both messages are added AFTER tool execution completes.
392
- * This keeps agent.messages in a valid, reinvokable state at all times:
393
- *
394
- * - If interrupted during tool execution, messages has no dangling toolUse
395
- * without a matching toolResult, so the agent can be reinvoked cleanly.
396
- * - The Python SDK appends the assistant message BEFORE tool execution,
397
- * requiring recovery logic (generate_missing_tool_result_content) on
398
- * interrupts. We avoid that by deferring.
399
- * - Trade-off: MessageAddedEvent for the assistant message fires after tools
400
- * complete (not before as in Python), and agent.messages is incomplete
401
- * during tool execution. Events like BeforeToolsEvent.message and
402
- * BeforeToolCallEvent.toolUse provide the data directly.
426
+ * This keeps agent.messages in a valid, reinvokable state at all times.
427
+ * If interrupted during tool execution, messages has no dangling toolUse
428
+ * without a matching toolResult, so the agent can be reinvoked cleanly.
403
429
  */
404
430
  yield this._appendMessage(modelResult.message);
405
431
  yield this._appendMessage(toolResultMessage);
406
- // End cycle tracking
407
432
  this._meter.endCycle(cycleStartTime);
408
- // End cycle span
409
433
  this._tracer.endAgentLoopSpan(cycleSpan);
410
- // Continue loop
434
+ // Structured output captured: exit
435
+ const structuredOutput = structuredOutputTool
436
+ ? this._extractStructuredOutput(modelResult.message, toolResultMessage)
437
+ : undefined;
438
+ if (structuredOutput !== undefined) {
439
+ result = new AgentResult({
440
+ stopReason: modelResult.stopReason,
441
+ lastMessage: modelResult.message,
442
+ traces: this._tracer.localTraces,
443
+ structuredOutput,
444
+ metrics: this._meter.metrics,
445
+ });
446
+ return result;
447
+ }
411
448
  }
412
449
  catch (error) {
413
- // End cycle tracking and span with error
414
450
  this._meter.endCycle(cycleStartTime);
415
451
  this._tracer.endAgentLoopSpan(cycleSpan, { error: error });
416
452
  throw error;
@@ -428,12 +464,31 @@ export class Agent {
428
464
  accumulatedUsage: this._meter.metrics.accumulatedUsage,
429
465
  ...(result?.stopReason && { stopReason: result.stopReason }),
430
466
  });
431
- // Cleanup structured output context
432
- context.cleanup(this._toolRegistry);
467
+ // Cleanup structured output tool
468
+ if (structuredOutputTool) {
469
+ this._toolRegistry.remove(STRUCTURED_OUTPUT_TOOL_NAME);
470
+ }
433
471
  // Always emit final event
434
472
  yield new AfterInvocationEvent({ agent: this });
435
473
  }
436
474
  }
475
+ /**
476
+ * Extracts the validated structured output result from tool execution.
477
+ *
478
+ * @param toolUseMessage - The assistant message containing tool use blocks
479
+ * @param toolResultMessage - The message containing tool results
480
+ * @returns The parsed structured output, or undefined if not found
481
+ */
482
+ _extractStructuredOutput(toolUseMessage, toolResultMessage) {
483
+ const toolUse = toolUseMessage.content.find((block) => block.type === 'toolUseBlock' && block.name === STRUCTURED_OUTPUT_TOOL_NAME);
484
+ if (!toolUse)
485
+ return undefined;
486
+ const toolResult = toolResultMessage.content.find((block) => block.type === 'toolResultBlock' && block.toolUseId === toolUse.toolUseId && block.status === 'success');
487
+ if (!toolResult)
488
+ return undefined;
489
+ const firstContent = toolResult.content[0];
490
+ return firstContent?.type === 'jsonBlock' ? firstContent.json : undefined;
491
+ }
437
492
  /**
438
493
  * Normalizes agent invocation input into an array of messages to append.
439
494
  *
@@ -496,20 +551,15 @@ export class Agent {
496
551
  * @param toolChoice - Optional tool choice to force specific tool usage
497
552
  * @returns Object containing the assistant message, stop reason, and optional redaction message
498
553
  */
499
- async *invokeModel(args, forcedToolChoice) {
500
- // Normalize input and append messages to conversation
501
- const messagesToAppend = this._normalizeInput(args);
502
- for (const message of messagesToAppend) {
503
- yield this._appendMessage(message);
504
- }
554
+ async *_invokeModel(toolChoice) {
505
555
  const toolSpecs = this._toolRegistry.list().map((tool) => tool.toolSpec);
506
556
  const streamOptions = { toolSpecs };
507
557
  if (this.systemPrompt !== undefined) {
508
558
  streamOptions.systemPrompt = this.systemPrompt;
509
559
  }
510
- // Add tool choice if provided (for structured output forcing)
511
- if (forcedToolChoice) {
512
- streamOptions.toolChoice = forcedToolChoice;
560
+ // Add tool choice if provided
561
+ if (toolChoice) {
562
+ streamOptions.toolChoice = toolChoice;
513
563
  }
514
564
  yield new BeforeModelCallEvent({ agent: this });
515
565
  // Start model span within loop span context
@@ -517,6 +567,7 @@ export class Agent {
517
567
  const modelSpan = this._tracer.startModelInvokeSpan({
518
568
  messages: this.messages,
519
569
  ...(modelId && { modelId }),
570
+ ...(this.systemPrompt !== undefined && { systemPrompt: this.systemPrompt }),
520
571
  });
521
572
  try {
522
573
  const result = yield* this._streamFromModel(this.messages, streamOptions);
@@ -524,10 +575,12 @@ export class Agent {
524
575
  this._meter.updateCycle(result.metadata);
525
576
  // End model span with usage
526
577
  const usage = result.metadata?.usage;
578
+ const metrics = result.metadata?.metrics;
527
579
  this._tracer.endModelInvokeSpan(modelSpan, {
528
580
  output: result.message,
529
581
  stopReason: result.stopReason,
530
582
  ...(usage && { usage }),
583
+ ...(metrics && { metrics }),
531
584
  });
532
585
  yield new ModelMessageEvent({ agent: this, message: result.message, stopReason: result.stopReason });
533
586
  // Handle user content redaction if guardrails blocked input
@@ -542,7 +595,7 @@ export class Agent {
542
595
  const afterModelCallEvent = new AfterModelCallEvent({ agent: this, stopData });
543
596
  yield afterModelCallEvent;
544
597
  if (afterModelCallEvent.retry) {
545
- return yield* this.invokeModel(args);
598
+ return yield* this._invokeModel(toolChoice);
546
599
  }
547
600
  return result;
548
601
  }
@@ -556,7 +609,7 @@ export class Agent {
556
609
  yield errorEvent;
557
610
  // After yielding, hooks have been invoked and may have set retry
558
611
  if (errorEvent.retry) {
559
- return yield* this.invokeModel(args);
612
+ return yield* this._invokeModel(toolChoice);
560
613
  }
561
614
  // Re-throw error
562
615
  throw error;
@@ -604,26 +657,46 @@ export class Agent {
604
657
  * @returns User message containing tool results
605
658
  */
606
659
  async *executeTools(assistantMessage, toolRegistry) {
607
- yield new BeforeToolsEvent({ agent: this, message: assistantMessage });
608
- // Extract tool use blocks from assistant message
609
- const toolUseBlocks = assistantMessage.content.filter((block) => block.type === 'toolUseBlock');
610
- if (toolUseBlocks.length === 0) {
611
- // No tool use blocks found even though stopReason is toolUse
612
- throw new Error('Model indicated toolUse but no tool use blocks found in message');
613
- }
660
+ const beforeToolsEvent = new BeforeToolsEvent({ agent: this, message: assistantMessage });
661
+ yield beforeToolsEvent;
614
662
  const toolResultBlocks = [];
615
- for (const toolUseBlock of toolUseBlocks) {
616
- const toolResultBlock = yield* this.executeTool(toolUseBlock, toolRegistry);
617
- toolResultBlocks.push(toolResultBlock);
618
- // Yield the tool result event as it's created
619
- yield new ToolResultEvent({ agent: this, result: toolResultBlock });
663
+ let toolResultMessage;
664
+ try {
665
+ // Extract tool use blocks from assistant message
666
+ const toolUseBlocks = assistantMessage.content.filter((block) => block.type === 'toolUseBlock');
667
+ if (toolUseBlocks.length === 0) {
668
+ // No tool use blocks found even though stopReason is toolUse
669
+ throw new Error('Model indicated toolUse but no tool use blocks found in message');
670
+ }
671
+ // Cancel all tools if hook requested it
672
+ if (beforeToolsEvent.cancel) {
673
+ const cancelMessage = cancelToolMessage(beforeToolsEvent.cancel);
674
+ const cancelBlocks = toolUseBlocks.map((block) => new ToolResultBlock({
675
+ toolUseId: block.toolUseId,
676
+ status: 'error',
677
+ content: [new TextBlock(cancelMessage)],
678
+ }));
679
+ for (const result of cancelBlocks) {
680
+ yield new ToolResultEvent({ agent: this, result });
681
+ }
682
+ toolResultBlocks.push(...cancelBlocks);
683
+ }
684
+ else {
685
+ for (const toolUseBlock of toolUseBlocks) {
686
+ const toolResultBlock = yield* this.executeTool(toolUseBlock, toolRegistry);
687
+ toolResultBlocks.push(toolResultBlock);
688
+ // Yield the tool result event as it's created
689
+ yield new ToolResultEvent({ agent: this, result: toolResultBlock });
690
+ }
691
+ }
692
+ }
693
+ finally {
694
+ toolResultMessage = new Message({
695
+ role: 'user',
696
+ content: toolResultBlocks,
697
+ });
698
+ yield new AfterToolsEvent({ agent: this, message: toolResultMessage });
620
699
  }
621
- // Create user message with tool results
622
- const toolResultMessage = new Message({
623
- role: 'user',
624
- content: toolResultBlocks,
625
- });
626
- yield new AfterToolsEvent({ agent: this, message: toolResultMessage });
627
700
  return toolResultMessage;
628
701
  }
629
702
  /**
@@ -646,7 +719,28 @@ export class Agent {
646
719
  };
647
720
  // Retry loop for tool execution
648
721
  while (true) {
649
- yield new BeforeToolCallEvent({ agent: this, toolUse, tool });
722
+ const beforeToolCallEvent = new BeforeToolCallEvent({ agent: this, toolUse, tool });
723
+ yield beforeToolCallEvent;
724
+ // Cancel individual tool if hook requested it
725
+ if (beforeToolCallEvent.cancel) {
726
+ const cancelMessage = cancelToolMessage(beforeToolCallEvent.cancel);
727
+ const toolResult = new ToolResultBlock({
728
+ toolUseId: toolUseBlock.toolUseId,
729
+ status: 'error',
730
+ content: [new TextBlock(cancelMessage)],
731
+ });
732
+ const afterToolCallEvent = new AfterToolCallEvent({
733
+ agent: this,
734
+ toolUse,
735
+ tool,
736
+ result: toolResult,
737
+ });
738
+ yield afterToolCallEvent;
739
+ if (afterToolCallEvent.retry) {
740
+ continue;
741
+ }
742
+ return toolResult;
743
+ }
650
744
  // Start tool span within loop span context
651
745
  const toolSpan = this._tracer.startToolCallSpan({
652
746
  tool: toolUse,
@@ -774,7 +868,7 @@ export class Agent {
774
868
  }
775
869
  else if (lastMessage) {
776
870
  // Unexpected state: redaction requested but last message is not from user
777
- logger.warn(`role=<${lastMessage.role}> | received input redaction but last message is not from user | redaction skipped.`);
871
+ logger.warn(`role=<${lastMessage.role}> | received input redaction but last message is not from user | redaction skipped`);
778
872
  }
779
873
  }
780
874
  }
@@ -789,6 +883,14 @@ export class Agent {
789
883
  return new MessageAddedEvent({ agent: this, message });
790
884
  }
791
885
  }
886
+ /**
887
+ * Returns the cancel message for a cancelled tool.
888
+ * @param cancelTool - The cancel value (true or custom message)
889
+ * @returns The cancel message string
890
+ */
891
+ function cancelToolMessage(cancelTool) {
892
+ return typeof cancelTool === 'string' ? cancelTool : 'tool cancelled by hook';
893
+ }
792
894
  /**
793
895
  * Recursively flattens nested arrays of tools into a single flat array.
794
896
  * @param tools - Tools or nested arrays of tools