@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
@@ -5,12 +5,13 @@ import { MockMessageModel } from '../../__fixtures__/mock-message-model.js';
5
5
  import { collectGenerator } from '../../__fixtures__/model-test-helpers.js';
6
6
  import { createMockTool, createRandomTool } from '../../__fixtures__/tool-helpers.js';
7
7
  import { ConcurrentInvocationError } from '../../errors.js';
8
- import { MaxTokensError, TextBlock, CachePointBlock, AgentResult, Message, ToolUseBlock, ToolResultBlock, ReasoningBlock, GuardContentBlock, ImageBlock, VideoBlock, DocumentBlock, } from '../../index.js';
8
+ import { MaxTokensError, TextBlock, CachePointBlock, Message, ToolUseBlock, ToolResultBlock, ReasoningBlock, GuardContentBlock, ImageBlock, VideoBlock, DocumentBlock, } from '../../index.js';
9
9
  import { AgentPrinter } from '../printer.js';
10
- import { BeforeInvocationEvent, BeforeToolsEvent } from '../../hooks/events.js';
10
+ import { AfterInvocationEvent, AfterToolCallEvent, AfterToolsEvent, BeforeInvocationEvent, BeforeToolsEvent, } from '../../hooks/events.js';
11
11
  import { BedrockModel } from '../../models/bedrock.js';
12
- import { StructuredOutputException } from '../../structured-output/exceptions.js';
12
+ import { StructuredOutputError } from '../../errors.js';
13
13
  import { expectLoopMetrics } from '../../__fixtures__/metrics-helpers.js';
14
+ import { expectAgentResult } from '../../__fixtures__/agent-helpers.js';
14
15
  describe('Agent', () => {
15
16
  describe('stream', () => {
16
17
  describe('basic streaming', () => {
@@ -41,14 +42,14 @@ describe('Agent', () => {
41
42
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
42
43
  const agent = new Agent({ model });
43
44
  const { result } = await collectGenerator(agent.stream('Test prompt'));
44
- expect(result).toEqual(new AgentResult({
45
+ expect(result).toEqual(expectAgentResult({
45
46
  stopReason: 'endTurn',
46
- lastMessage: expect.objectContaining({
47
- role: 'assistant',
48
- content: expect.arrayContaining([expect.objectContaining({ type: 'textBlock', text: 'Hello' })]),
49
- }),
50
- metrics: expectLoopMetrics({ cycleCount: 1 }),
47
+ messageText: 'Hello',
48
+ cycleCount: 1,
49
+ traceCount: 1,
51
50
  }));
51
+ // Verify trace structure
52
+ expect(result.traces?.[0]?.children).toEqual(expect.arrayContaining([expect.objectContaining({ name: 'stream_messages' })]));
52
53
  });
53
54
  });
54
55
  describe('with tool use', () => {
@@ -108,13 +109,34 @@ describe('Agent', () => {
108
109
  });
109
110
  describe('error handling', () => {
110
111
  it('throws MaxTokensError when model hits token limit', async () => {
111
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial...' }, 'maxTokens');
112
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial...' }, { stopReason: 'maxTokens' });
112
113
  const agent = new Agent({ model });
113
114
  await expect(async () => {
114
115
  await collectGenerator(agent.stream('Test'));
115
116
  }).rejects.toThrow(MaxTokensError);
116
117
  });
117
118
  });
119
+ describe('hook error cleanup', () => {
120
+ it('fires AfterInvocationEvent when consumer breaks from stream', async () => {
121
+ const model = new MockMessageModel()
122
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} })
123
+ .addTurn({ type: 'textBlock', text: 'Done' });
124
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
125
+ toolUseId: 'tool-1',
126
+ status: 'success',
127
+ content: [new TextBlock('ok')],
128
+ }));
129
+ const agent = new Agent({ model, tools: [tool], printer: false });
130
+ const afterInvocationCallback = vi.fn();
131
+ agent.addHook(AfterInvocationEvent, afterInvocationCallback);
132
+ for await (const event of agent.stream('Test')) {
133
+ if (event.type === 'beforeToolsEvent') {
134
+ break;
135
+ }
136
+ }
137
+ expect(afterInvocationCallback).toHaveBeenCalledOnce();
138
+ });
139
+ });
118
140
  });
119
141
  describe('invoke', () => {
120
142
  describe('basic invocation', () => {
@@ -131,21 +153,18 @@ describe('Agent', () => {
131
153
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Response text' });
132
154
  const agent = new Agent({ model });
133
155
  const result = await agent.invoke('Test prompt');
134
- expect(result).toEqual(new AgentResult({
156
+ expect(result).toEqual(expectAgentResult({
135
157
  stopReason: 'endTurn',
136
- lastMessage: expect.objectContaining({
137
- type: 'message',
138
- role: 'assistant',
139
- content: expect.arrayContaining([expect.objectContaining({ type: 'textBlock', text: 'Response text' })]),
140
- }),
141
- metrics: expectLoopMetrics({ cycleCount: 1 }),
158
+ messageText: 'Response text',
159
+ cycleCount: 1,
160
+ traceCount: 1,
142
161
  }));
143
162
  });
144
163
  it('consumes stream events internally', async () => {
145
164
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
146
165
  const agent = new Agent({ model });
147
166
  const result = await agent.invoke('Test');
148
- expect(result).toEqual(new AgentResult({
167
+ expect(result).toEqual(expect.objectContaining({
149
168
  stopReason: 'endTurn',
150
169
  lastMessage: expect.objectContaining({
151
170
  type: 'message',
@@ -159,8 +178,12 @@ describe('Agent', () => {
159
178
  describe('with tool use', () => {
160
179
  it('executes tools and returns final result', async () => {
161
180
  const model = new MockMessageModel()
162
- .addTurn({ type: 'toolUseBlock', name: 'calc', toolUseId: 'tool-1', input: { a: 1, b: 2 } })
163
- .addTurn({ type: 'textBlock', text: 'The answer is 3' });
181
+ .addTurn({ type: 'toolUseBlock', name: 'calc', toolUseId: 'tool-1', input: { a: 1, b: 2 } }, {
182
+ usage: { inputTokens: 100, outputTokens: 50, totalTokens: 150 },
183
+ })
184
+ .addTurn({ type: 'textBlock', text: 'The answer is 3' }, {
185
+ usage: { inputTokens: 200, outputTokens: 30, totalTokens: 230 },
186
+ });
164
187
  const tool = createMockTool('calc', () => new ToolResultBlock({
165
188
  toolUseId: 'tool-1',
166
189
  status: 'success',
@@ -168,26 +191,245 @@ describe('Agent', () => {
168
191
  }));
169
192
  const agent = new Agent({ model, tools: [tool] });
170
193
  const result = await agent.invoke('What is 1 + 2?');
171
- expect(result).toEqual(new AgentResult({
194
+ expect(result).toEqual(expectAgentResult({
172
195
  stopReason: 'endTurn',
173
- lastMessage: expect.objectContaining({
174
- type: 'message',
175
- role: 'assistant',
176
- content: expect.arrayContaining([
177
- expect.objectContaining({ type: 'textBlock', text: 'The answer is 3' }),
178
- ]),
196
+ messageText: 'The answer is 3',
197
+ cycleCount: 2,
198
+ toolNames: ['calc'],
199
+ traceCount: 2,
200
+ usage: { inputTokens: 300, outputTokens: 80, totalTokens: 380 },
201
+ }));
202
+ // Verify detailed trace children structure
203
+ expect(result.traces?.[0]?.children).toEqual(expect.arrayContaining([
204
+ expect.objectContaining({ name: 'stream_messages' }),
205
+ expect.objectContaining({ name: 'Tool: calc' }),
206
+ ]));
207
+ expect(result.traces?.[1]?.children).toEqual(expect.arrayContaining([expect.objectContaining({ name: 'stream_messages' })]));
208
+ });
209
+ it('stores cycleId in trace metadata', async () => {
210
+ const model = new MockMessageModel()
211
+ .addTurn({ type: 'toolUseBlock', name: 'calc', toolUseId: 'tool-1', input: {} })
212
+ .addTurn({ type: 'textBlock', text: 'Done' });
213
+ const tool = createMockTool('calc', () => new ToolResultBlock({
214
+ toolUseId: 'tool-1',
215
+ status: 'success',
216
+ content: [new TextBlock('result')],
217
+ }));
218
+ const agent = new Agent({ model, tools: [tool] });
219
+ const result = await agent.invoke('Test');
220
+ expect(result.traces).toEqual([
221
+ expect.objectContaining({
222
+ name: 'Cycle 1',
223
+ metadata: expect.objectContaining({ cycleId: 'cycle-1' }),
224
+ }),
225
+ expect.objectContaining({
226
+ name: 'Cycle 2',
227
+ metadata: expect.objectContaining({ cycleId: 'cycle-2' }),
179
228
  }),
180
- metrics: expectLoopMetrics({ cycleCount: 2, toolNames: ['calc'] }),
229
+ ]);
230
+ });
231
+ it('stores tool metadata in trace children', async () => {
232
+ const model = new MockMessageModel()
233
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-abc123', input: {} })
234
+ .addTurn({ type: 'textBlock', text: 'Done' });
235
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
236
+ toolUseId: 'tool-abc123',
237
+ status: 'success',
238
+ content: [new TextBlock('result')],
181
239
  }));
240
+ const agent = new Agent({ model, tools: [tool] });
241
+ const result = await agent.invoke('Test');
242
+ expect(result.traces).toEqual(expect.arrayContaining([
243
+ expect.objectContaining({
244
+ name: 'Cycle 1',
245
+ children: expect.arrayContaining([
246
+ expect.objectContaining({
247
+ name: 'Tool: testTool',
248
+ metadata: expect.objectContaining({
249
+ toolUseId: 'tool-abc123',
250
+ toolName: 'testTool',
251
+ }),
252
+ }),
253
+ ]),
254
+ }),
255
+ ]));
182
256
  });
183
257
  });
184
258
  describe('error handling', () => {
185
259
  it('propagates maxTokens error', async () => {
186
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial' }, 'maxTokens');
260
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial' }, { stopReason: 'maxTokens' });
187
261
  const agent = new Agent({ model });
188
262
  await expect(agent.invoke('Test')).rejects.toThrow(MaxTokensError);
189
263
  });
190
264
  });
265
+ describe('metrics on errors', () => {
266
+ it('tracks cycle count when maxTokens error occurs', async () => {
267
+ const model = new MockMessageModel()
268
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} }, {
269
+ usage: { inputTokens: 100, outputTokens: 50, totalTokens: 150 },
270
+ })
271
+ .addTurn({ type: 'textBlock', text: 'Partial' }, {
272
+ stopReason: 'maxTokens',
273
+ usage: { inputTokens: 80, outputTokens: 20, totalTokens: 100 },
274
+ });
275
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
276
+ toolUseId: 'tool-1',
277
+ status: 'success',
278
+ content: [new TextBlock('Done')],
279
+ }));
280
+ const agent = new Agent({ model, tools: [tool] });
281
+ const meter = agent._meter;
282
+ await expect(agent.invoke('Test')).rejects.toThrow(MaxTokensError);
283
+ expect(meter.metrics.cycleCount).toBe(2);
284
+ // Only the first turn's usage is accumulated; the second turn throws
285
+ // MaxTokensError inside streamAggregated before metadata reaches updateCycle
286
+ expect(meter.metrics.accumulatedUsage).toStrictEqual({
287
+ inputTokens: 100,
288
+ outputTokens: 50,
289
+ totalTokens: 150,
290
+ });
291
+ expect(meter.metrics.accumulatedMetrics).toStrictEqual({
292
+ latencyMs: expect.any(Number),
293
+ });
294
+ expect(meter.metrics.toolMetrics).toStrictEqual({
295
+ testTool: {
296
+ callCount: 1,
297
+ successCount: 1,
298
+ errorCount: 0,
299
+ totalTime: expect.any(Number),
300
+ },
301
+ });
302
+ });
303
+ it('collects local traces for completed cycles when error occurs mid-run', async () => {
304
+ const model = new MockMessageModel()
305
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} }, {
306
+ usage: { inputTokens: 100, outputTokens: 50, totalTokens: 150 },
307
+ })
308
+ .addTurn({ type: 'textBlock', text: 'Partial' }, {
309
+ stopReason: 'maxTokens',
310
+ usage: { inputTokens: 80, outputTokens: 20, totalTokens: 100 },
311
+ });
312
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
313
+ toolUseId: 'tool-1',
314
+ status: 'success',
315
+ content: [new TextBlock('Done')],
316
+ }));
317
+ const agent = new Agent({ model, tools: [tool] });
318
+ const tracer = agent._tracer;
319
+ await expect(agent.invoke('Test')).rejects.toThrow(MaxTokensError);
320
+ // Cycle 1 completed (tool use), cycle 2 errored (maxTokens)
321
+ expect(tracer.localTraces).toEqual([
322
+ expect.objectContaining({
323
+ name: 'Cycle 1',
324
+ children: [
325
+ expect.objectContaining({ name: 'stream_messages' }),
326
+ expect.objectContaining({ name: 'Tool: testTool' }),
327
+ ],
328
+ }),
329
+ expect.objectContaining({
330
+ name: 'Cycle 2',
331
+ children: [expect.objectContaining({ name: 'stream_messages' })],
332
+ }),
333
+ ]);
334
+ });
335
+ it('tracks metrics when a hook throws an error', async () => {
336
+ const model = new MockMessageModel()
337
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} }, {
338
+ usage: { inputTokens: 60, outputTokens: 25, totalTokens: 85 },
339
+ })
340
+ .addTurn({ type: 'textBlock', text: 'Done' });
341
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
342
+ toolUseId: 'tool-1',
343
+ status: 'success',
344
+ content: [new TextBlock('Result')],
345
+ }));
346
+ const agent = new Agent({ model, tools: [tool] });
347
+ agent.addHook(BeforeToolsEvent, () => {
348
+ throw new Error('Hook failure');
349
+ });
350
+ const meter = agent._meter;
351
+ await expect(agent.invoke('Test')).rejects.toThrow('Hook failure');
352
+ // The hook throws after the model returns but before tools execute,
353
+ // so the first cycle's model usage is recorded but no tool metrics exist
354
+ expect(meter.metrics.cycleCount).toBe(1);
355
+ expect(meter.metrics.accumulatedUsage).toStrictEqual({
356
+ inputTokens: 60,
357
+ outputTokens: 25,
358
+ totalTokens: 85,
359
+ });
360
+ expect(meter.metrics.accumulatedMetrics).toStrictEqual({
361
+ latencyMs: expect.any(Number),
362
+ });
363
+ expect(meter.metrics.toolMetrics).toStrictEqual({});
364
+ });
365
+ });
366
+ describe('hook error cleanup', () => {
367
+ it('fires AfterInvocationEvent when a mid-stream hook throws', async () => {
368
+ const model = new MockMessageModel()
369
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} })
370
+ .addTurn({ type: 'textBlock', text: 'Done' });
371
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
372
+ toolUseId: 'tool-1',
373
+ status: 'success',
374
+ content: [new TextBlock('ok')],
375
+ }));
376
+ const agent = new Agent({ model, tools: [tool], printer: false });
377
+ agent.addHook(AfterToolCallEvent, () => {
378
+ throw new Error('hook error');
379
+ });
380
+ const afterInvocationCallback = vi.fn();
381
+ agent.addHook(AfterInvocationEvent, afterInvocationCallback);
382
+ await expect(agent.invoke('Test')).rejects.toThrow('hook error');
383
+ expect(afterInvocationCallback).toHaveBeenCalledOnce();
384
+ });
385
+ it('fires AfterToolsEvent when a mid-stream hook throws', async () => {
386
+ const model = new MockMessageModel()
387
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} })
388
+ .addTurn({ type: 'textBlock', text: 'Done' });
389
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
390
+ toolUseId: 'tool-1',
391
+ status: 'success',
392
+ content: [new TextBlock('ok')],
393
+ }));
394
+ const agent = new Agent({ model, tools: [tool], printer: false });
395
+ agent.addHook(AfterToolCallEvent, () => {
396
+ throw new Error('hook error');
397
+ });
398
+ const afterToolsCallback = vi.fn();
399
+ agent.addHook(AfterToolsEvent, afterToolsCallback);
400
+ await expect(agent.invoke('Test')).rejects.toThrow('hook error');
401
+ expect(afterToolsCallback).toHaveBeenCalledOnce();
402
+ });
403
+ it('does not fire AfterInvocationEvent when BeforeInvocationEvent hook throws', async () => {
404
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
405
+ const agent = new Agent({ model, printer: false });
406
+ agent.addHook(BeforeInvocationEvent, () => {
407
+ throw new Error('before hook error');
408
+ });
409
+ const afterInvocationCallback = vi.fn();
410
+ agent.addHook(AfterInvocationEvent, afterInvocationCallback);
411
+ await expect(agent.invoke('Test')).rejects.toThrow('before hook error');
412
+ expect(afterInvocationCallback).not.toHaveBeenCalled();
413
+ });
414
+ it('does not fire AfterToolsEvent when BeforeToolsEvent hook throws', async () => {
415
+ const model = new MockMessageModel()
416
+ .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} })
417
+ .addTurn({ type: 'textBlock', text: 'Done' });
418
+ const tool = createMockTool('testTool', () => new ToolResultBlock({
419
+ toolUseId: 'tool-1',
420
+ status: 'success',
421
+ content: [new TextBlock('ok')],
422
+ }));
423
+ const agent = new Agent({ model, tools: [tool], printer: false });
424
+ agent.addHook(BeforeToolsEvent, () => {
425
+ throw new Error('before tools hook error');
426
+ });
427
+ const afterToolsCallback = vi.fn();
428
+ agent.addHook(AfterToolsEvent, afterToolsCallback);
429
+ await expect(agent.invoke('Test')).rejects.toThrow('before tools hook error');
430
+ expect(afterToolsCallback).not.toHaveBeenCalled();
431
+ });
432
+ });
191
433
  });
192
434
  describe('API consistency', () => {
193
435
  it('invoke() and stream() produce same final result', async () => {
@@ -218,29 +460,36 @@ describe('Agent', () => {
218
460
  const agent2 = new Agent({ model: model2, tools: [tool2] });
219
461
  const invokeResult = await agent1.invoke('Use tool');
220
462
  const { result: streamResult } = await collectGenerator(agent2.stream('Use tool'));
221
- expect(invokeResult.stopReason).toBe(streamResult.stopReason);
222
- expect(invokeResult.lastMessage).toEqual(streamResult.lastMessage);
463
+ expect(invokeResult).toEqual(expect.objectContaining({
464
+ stopReason: streamResult.stopReason,
465
+ lastMessage: streamResult.lastMessage,
466
+ traces: streamResult.traces?.map((t) => expect.objectContaining({
467
+ name: t.name,
468
+ children: expect.arrayContaining(Array(t.children.length).fill(expect.objectContaining({ name: expect.any(String) }))),
469
+ })),
470
+ }));
223
471
  });
224
472
  });
225
473
  describe('messages', () => {
226
474
  it('returns array of messages', () => {
227
475
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
228
476
  const agent = new Agent({ model });
229
- const messages = agent.messages;
230
- expect(messages).toBeDefined();
231
- expect(Array.isArray(messages)).toBe(true);
477
+ expect(agent.messages).toEqual([]);
232
478
  });
233
479
  it('reflects conversation history after invoke', async () => {
234
480
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Response' });
235
481
  const agent = new Agent({ model });
236
482
  await agent.invoke('Hello');
237
- const messages = agent.messages;
238
- expect(messages.length).toBeGreaterThan(0);
239
- expect(messages.length).toBe(2);
240
- expect(messages[0]?.role).toBe('user');
241
- expect(messages[0]?.content).toEqual([{ type: 'textBlock', text: 'Hello' }]);
242
- expect(messages[1]?.role).toBe('assistant');
243
- expect(messages[1]?.content).toEqual([{ type: 'textBlock', text: 'Response' }]);
483
+ expect(agent.messages).toEqual([
484
+ expect.objectContaining({
485
+ role: 'user',
486
+ content: [{ type: 'textBlock', text: 'Hello' }],
487
+ }),
488
+ expect.objectContaining({
489
+ role: 'assistant',
490
+ content: [{ type: 'textBlock', text: 'Response' }],
491
+ }),
492
+ ]);
244
493
  });
245
494
  });
246
495
  describe('printer configuration', () => {
@@ -300,7 +549,7 @@ describe('Agent', () => {
300
549
  it('releases lock after errors and abandoned streams', async () => {
301
550
  // Test error case
302
551
  const model = new MockMessageModel()
303
- .addTurn({ type: 'textBlock', text: 'Partial' }, 'maxTokens')
552
+ .addTurn({ type: 'textBlock', text: 'Partial' }, { stopReason: 'maxTokens' })
304
553
  .addTurn({ type: 'textBlock', text: 'Success' });
305
554
  const agent = new Agent({ model });
306
555
  await expect(agent.invoke('First')).rejects.toThrow(MaxTokensError);
@@ -499,7 +748,7 @@ describe('Agent', () => {
499
748
  }),
500
749
  new VideoBlock({
501
750
  format: 'mp4',
502
- source: { s3Location: { uri: 's3://bucket/video.mp4' } },
751
+ source: { location: { type: 's3', uri: 's3://bucket/video.mp4' } },
503
752
  }),
504
753
  new DocumentBlock({
505
754
  format: 'pdf',
@@ -551,7 +800,7 @@ describe('Agent', () => {
551
800
  {
552
801
  video: {
553
802
  format: 'mp4',
554
- source: { s3Location: { uri: 's3://bucket/video.mp4' } },
803
+ source: { location: { type: 's3', uri: 's3://bucket/video.mp4' } },
555
804
  },
556
805
  },
557
806
  {
@@ -694,6 +943,7 @@ describe('Agent', () => {
694
943
  const agent = new Agent({ model, structuredOutputSchema: schema });
695
944
  const result = await agent.invoke('Test');
696
945
  expect(result.structuredOutput).toEqual({ name: 'John', age: 30 });
946
+ expect(model.callCount).toBe(1);
697
947
  });
698
948
  it('forces structured output tool when model does not use it', async () => {
699
949
  const schema = z.object({ value: z.number() });
@@ -705,16 +955,16 @@ describe('Agent', () => {
705
955
  const result = await agent.invoke('Test');
706
956
  expect(result.structuredOutput).toEqual({ value: 42 });
707
957
  });
708
- it('throws StructuredOutputException when model refuses to use tool after forcing', async () => {
958
+ it('throws StructuredOutputError when model refuses to use tool after forcing', async () => {
709
959
  const schema = z.object({ value: z.number() });
710
960
  // Model returns text twice - once normally, once when forced
711
961
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Response' });
712
962
  const agent = new Agent({ model, structuredOutputSchema: schema });
713
- await expect(agent.invoke('Test')).rejects.toThrow(StructuredOutputException);
963
+ await expect(agent.invoke('Test')).rejects.toThrow(StructuredOutputError);
714
964
  });
715
965
  it('throws MaxTokensError when maxTokens reached before structured output', async () => {
716
966
  const schema = z.object({ value: z.number() });
717
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial...' }, 'maxTokens');
967
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial...' }, { stopReason: 'maxTokens' });
718
968
  const agent = new Agent({ model, structuredOutputSchema: schema });
719
969
  await expect(agent.invoke('Test')).rejects.toThrow(MaxTokensError);
720
970
  });
@@ -756,7 +1006,7 @@ describe('Agent', () => {
756
1006
  });
757
1007
  it('cleans up structured output tool even when error occurs', async () => {
758
1008
  const schema = z.object({ value: z.number() });
759
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial...' }, 'maxTokens');
1009
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Partial...' }, { stopReason: 'maxTokens' });
760
1010
  const agent = new Agent({ model, structuredOutputSchema: schema });
761
1011
  await expect(agent.invoke('Test')).rejects.toThrow();
762
1012
  const toolNames = agent.tools.map((t) => t.name);