@strands-agents/sdk 1.7.0 → 1.8.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 (659) hide show
  1. package/dist/src/agent/agent.d.ts +1 -1
  2. package/dist/src/agent/agent.d.ts.map +1 -1
  3. package/dist/src/agent/agent.js +1 -1
  4. package/dist/src/agent/agent.js.map +1 -1
  5. package/dist/src/context-manager/modes/agentic/agentic-context.d.ts +3 -3
  6. package/dist/src/context-manager/modes/agentic/agentic-context.d.ts.map +1 -1
  7. package/dist/src/index.d.ts +1 -1
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +1 -1
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/index.node.d.ts.map +1 -1
  12. package/dist/src/index.node.js +3 -0
  13. package/dist/src/index.node.js.map +1 -1
  14. package/dist/src/interventions/actions.d.ts.map +1 -1
  15. package/dist/src/interventions/actions.js.map +1 -1
  16. package/dist/src/{mcp.d.ts → mcp/client.d.ts} +13 -4
  17. package/dist/src/mcp/client.d.ts.map +1 -0
  18. package/dist/src/{mcp.js → mcp/client.js} +15 -3
  19. package/dist/src/mcp/client.js.map +1 -0
  20. package/dist/src/mcp/config.d.ts +52 -0
  21. package/dist/src/mcp/config.d.ts.map +1 -0
  22. package/dist/src/mcp/config.js +12 -0
  23. package/dist/src/mcp/config.js.map +1 -0
  24. package/dist/src/mcp/config.node.d.ts +16 -0
  25. package/dist/src/mcp/config.node.d.ts.map +1 -0
  26. package/dist/src/mcp/config.node.js +145 -0
  27. package/dist/src/mcp/config.node.js.map +1 -0
  28. package/dist/src/mcp/index.d.ts +3 -0
  29. package/dist/src/mcp/index.d.ts.map +1 -0
  30. package/dist/src/mcp/index.js +2 -0
  31. package/dist/src/mcp/index.js.map +1 -0
  32. package/dist/src/models/model.d.ts.map +1 -1
  33. package/dist/src/models/model.js +2 -1
  34. package/dist/src/models/model.js.map +1 -1
  35. package/dist/src/multiagent/graph.d.ts +7 -0
  36. package/dist/src/multiagent/graph.d.ts.map +1 -1
  37. package/dist/src/multiagent/graph.js +22 -1
  38. package/dist/src/multiagent/graph.js.map +1 -1
  39. package/dist/src/multiagent/nodes.d.ts +5 -0
  40. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  41. package/dist/src/multiagent/nodes.js +15 -0
  42. package/dist/src/multiagent/nodes.js.map +1 -1
  43. package/dist/src/multiagent/state.d.ts.map +1 -1
  44. package/dist/src/multiagent/state.js.map +1 -1
  45. package/dist/src/tools/function-tool.d.ts +1 -1
  46. package/dist/src/tools/function-tool.d.ts.map +1 -1
  47. package/dist/src/tools/function-tool.js +4 -12
  48. package/dist/src/tools/function-tool.js.map +1 -1
  49. package/dist/src/tools/mcp-tool.d.ts +2 -1
  50. package/dist/src/tools/mcp-tool.d.ts.map +1 -1
  51. package/dist/src/tools/mcp-tool.js +1 -0
  52. package/dist/src/tools/mcp-tool.js.map +1 -1
  53. package/dist/src/tools/tool-factory.d.ts +1 -1
  54. package/dist/src/tools/tool-factory.d.ts.map +1 -1
  55. package/dist/src/tools/types.d.ts +4 -0
  56. package/dist/src/tools/types.d.ts.map +1 -1
  57. package/dist/src/tools/zod-tool.d.ts +4 -2
  58. package/dist/src/tools/zod-tool.d.ts.map +1 -1
  59. package/dist/src/tools/zod-tool.js.map +1 -1
  60. package/dist/src/tsconfig.tsbuildinfo +1 -1
  61. package/dist/src/types/media.d.ts.map +1 -1
  62. package/dist/src/types/media.js.map +1 -1
  63. package/dist/src/types/messages.d.ts.map +1 -1
  64. package/dist/src/types/messages.js.map +1 -1
  65. package/dist/src/vended-memory-stores/local/index.d.ts +2 -0
  66. package/dist/src/vended-memory-stores/local/index.d.ts.map +1 -0
  67. package/dist/src/vended-memory-stores/local/index.js +2 -0
  68. package/dist/src/vended-memory-stores/local/index.js.map +1 -0
  69. package/dist/src/vended-memory-stores/local/store.d.ts +122 -0
  70. package/dist/src/vended-memory-stores/local/store.d.ts.map +1 -0
  71. package/dist/src/vended-memory-stores/local/store.js +281 -0
  72. package/dist/src/vended-memory-stores/local/store.js.map +1 -0
  73. package/dist/src/vended-plugins/context-offloader/search.d.ts.map +1 -1
  74. package/dist/src/vended-plugins/context-offloader/search.js +4 -2
  75. package/dist/src/vended-plugins/context-offloader/search.js.map +1 -1
  76. package/dist/src/vended-plugins/context-offloader/storage.js +1 -1
  77. package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
  78. package/dist/src/vended-plugins/skills/skill.d.ts.map +1 -1
  79. package/dist/src/vended-plugins/skills/skill.js.map +1 -1
  80. package/dist/src/vended-tools/notebook/notebook.d.ts +1 -1
  81. package/package.json +21 -14
  82. package/dist/src/__fixtures__/agent-helpers.d.ts +0 -136
  83. package/dist/src/__fixtures__/agent-helpers.d.ts.map +0 -1
  84. package/dist/src/__fixtures__/agent-helpers.js +0 -156
  85. package/dist/src/__fixtures__/agent-helpers.js.map +0 -1
  86. package/dist/src/__fixtures__/environment.d.ts +0 -12
  87. package/dist/src/__fixtures__/environment.d.ts.map +0 -1
  88. package/dist/src/__fixtures__/environment.js +0 -12
  89. package/dist/src/__fixtures__/environment.js.map +0 -1
  90. package/dist/src/__fixtures__/metrics-helpers.d.ts +0 -55
  91. package/dist/src/__fixtures__/metrics-helpers.d.ts.map +0 -1
  92. package/dist/src/__fixtures__/metrics-helpers.js +0 -57
  93. package/dist/src/__fixtures__/metrics-helpers.js.map +0 -1
  94. package/dist/src/__fixtures__/mock-message-model.d.ts +0 -103
  95. package/dist/src/__fixtures__/mock-message-model.d.ts.map +0 -1
  96. package/dist/src/__fixtures__/mock-message-model.js +0 -245
  97. package/dist/src/__fixtures__/mock-message-model.js.map +0 -1
  98. package/dist/src/__fixtures__/mock-meter.d.ts +0 -32
  99. package/dist/src/__fixtures__/mock-meter.d.ts.map +0 -1
  100. package/dist/src/__fixtures__/mock-meter.js +0 -47
  101. package/dist/src/__fixtures__/mock-meter.js.map +0 -1
  102. package/dist/src/__fixtures__/mock-plugin.d.ts +0 -13
  103. package/dist/src/__fixtures__/mock-plugin.d.ts.map +0 -1
  104. package/dist/src/__fixtures__/mock-plugin.js +0 -35
  105. package/dist/src/__fixtures__/mock-plugin.js.map +0 -1
  106. package/dist/src/__fixtures__/mock-span.d.ts +0 -78
  107. package/dist/src/__fixtures__/mock-span.d.ts.map +0 -1
  108. package/dist/src/__fixtures__/mock-span.js +0 -93
  109. package/dist/src/__fixtures__/mock-span.js.map +0 -1
  110. package/dist/src/__fixtures__/mock-storage-provider.d.ts +0 -42
  111. package/dist/src/__fixtures__/mock-storage-provider.d.ts.map +0 -1
  112. package/dist/src/__fixtures__/mock-storage-provider.js +0 -122
  113. package/dist/src/__fixtures__/mock-storage-provider.js.map +0 -1
  114. package/dist/src/__fixtures__/model-test-helpers.d.ts +0 -56
  115. package/dist/src/__fixtures__/model-test-helpers.d.ts.map +0 -1
  116. package/dist/src/__fixtures__/model-test-helpers.js +0 -85
  117. package/dist/src/__fixtures__/model-test-helpers.js.map +0 -1
  118. package/dist/src/__fixtures__/register-node-defaults.d.ts +0 -2
  119. package/dist/src/__fixtures__/register-node-defaults.d.ts.map +0 -1
  120. package/dist/src/__fixtures__/register-node-defaults.js +0 -6
  121. package/dist/src/__fixtures__/register-node-defaults.js.map +0 -1
  122. package/dist/src/__fixtures__/slim-types.d.ts +0 -51
  123. package/dist/src/__fixtures__/slim-types.d.ts.map +0 -1
  124. package/dist/src/__fixtures__/slim-types.js +0 -6
  125. package/dist/src/__fixtures__/slim-types.js.map +0 -1
  126. package/dist/src/__fixtures__/test-sandbox.node.d.ts +0 -15
  127. package/dist/src/__fixtures__/test-sandbox.node.d.ts.map +0 -1
  128. package/dist/src/__fixtures__/test-sandbox.node.js +0 -23
  129. package/dist/src/__fixtures__/test-sandbox.node.js.map +0 -1
  130. package/dist/src/__fixtures__/tool-helpers.d.ts +0 -45
  131. package/dist/src/__fixtures__/tool-helpers.d.ts.map +0 -1
  132. package/dist/src/__fixtures__/tool-helpers.js +0 -101
  133. package/dist/src/__fixtures__/tool-helpers.js.map +0 -1
  134. package/dist/src/__tests__/default-slot.test.d.ts +0 -2
  135. package/dist/src/__tests__/default-slot.test.d.ts.map +0 -1
  136. package/dist/src/__tests__/default-slot.test.js +0 -33
  137. package/dist/src/__tests__/default-slot.test.js.map +0 -1
  138. package/dist/src/__tests__/errors.test.d.ts +0 -2
  139. package/dist/src/__tests__/errors.test.d.ts.map +0 -1
  140. package/dist/src/__tests__/errors.test.js +0 -170
  141. package/dist/src/__tests__/errors.test.js.map +0 -1
  142. package/dist/src/__tests__/index.test.d.ts +0 -2
  143. package/dist/src/__tests__/index.test.d.ts.map +0 -1
  144. package/dist/src/__tests__/index.test.js +0 -48
  145. package/dist/src/__tests__/index.test.js.map +0 -1
  146. package/dist/src/__tests__/interrupt.test.d.ts +0 -2
  147. package/dist/src/__tests__/interrupt.test.d.ts.map +0 -1
  148. package/dist/src/__tests__/interrupt.test.js +0 -264
  149. package/dist/src/__tests__/interrupt.test.js.map +0 -1
  150. package/dist/src/__tests__/mcp.test.d.ts +0 -2
  151. package/dist/src/__tests__/mcp.test.d.ts.map +0 -1
  152. package/dist/src/__tests__/mcp.test.js +0 -1003
  153. package/dist/src/__tests__/mcp.test.js.map +0 -1
  154. package/dist/src/__tests__/mime.test.d.ts +0 -2
  155. package/dist/src/__tests__/mime.test.d.ts.map +0 -1
  156. package/dist/src/__tests__/mime.test.js +0 -83
  157. package/dist/src/__tests__/mime.test.js.map +0 -1
  158. package/dist/src/__tests__/state-store.test.d.ts +0 -2
  159. package/dist/src/__tests__/state-store.test.d.ts.map +0 -1
  160. package/dist/src/__tests__/state-store.test.js +0 -285
  161. package/dist/src/__tests__/state-store.test.js.map +0 -1
  162. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts +0 -2
  163. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts.map +0 -1
  164. package/dist/src/a2a/__tests__/a2a-agent.test.js +0 -383
  165. package/dist/src/a2a/__tests__/a2a-agent.test.js.map +0 -1
  166. package/dist/src/a2a/__tests__/adapters.test.d.ts +0 -2
  167. package/dist/src/a2a/__tests__/adapters.test.d.ts.map +0 -1
  168. package/dist/src/a2a/__tests__/adapters.test.js +0 -151
  169. package/dist/src/a2a/__tests__/adapters.test.js.map +0 -1
  170. package/dist/src/a2a/__tests__/async-lock.test.d.ts +0 -2
  171. package/dist/src/a2a/__tests__/async-lock.test.d.ts.map +0 -1
  172. package/dist/src/a2a/__tests__/async-lock.test.js +0 -137
  173. package/dist/src/a2a/__tests__/async-lock.test.js.map +0 -1
  174. package/dist/src/a2a/__tests__/events.test.d.ts +0 -2
  175. package/dist/src/a2a/__tests__/events.test.d.ts.map +0 -1
  176. package/dist/src/a2a/__tests__/events.test.js +0 -68
  177. package/dist/src/a2a/__tests__/events.test.js.map +0 -1
  178. package/dist/src/a2a/__tests__/executor.test.d.ts +0 -2
  179. package/dist/src/a2a/__tests__/executor.test.d.ts.map +0 -1
  180. package/dist/src/a2a/__tests__/executor.test.js +0 -345
  181. package/dist/src/a2a/__tests__/executor.test.js.map +0 -1
  182. package/dist/src/a2a/__tests__/server.test.d.ts +0 -2
  183. package/dist/src/a2a/__tests__/server.test.d.ts.map +0 -1
  184. package/dist/src/a2a/__tests__/server.test.js +0 -71
  185. package/dist/src/a2a/__tests__/server.test.js.map +0 -1
  186. package/dist/src/a2a/__tests__/server.test.node.d.ts +0 -2
  187. package/dist/src/a2a/__tests__/server.test.node.d.ts.map +0 -1
  188. package/dist/src/a2a/__tests__/server.test.node.js +0 -110
  189. package/dist/src/a2a/__tests__/server.test.node.js.map +0 -1
  190. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts +0 -2
  191. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts.map +0 -1
  192. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js +0 -23
  193. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js.map +0 -1
  194. package/dist/src/agent/__tests__/agent-as-tool.test.d.ts +0 -2
  195. package/dist/src/agent/__tests__/agent-as-tool.test.d.ts.map +0 -1
  196. package/dist/src/agent/__tests__/agent-as-tool.test.js +0 -347
  197. package/dist/src/agent/__tests__/agent-as-tool.test.js.map +0 -1
  198. package/dist/src/agent/__tests__/agent.cancel.test.d.ts +0 -2
  199. package/dist/src/agent/__tests__/agent.cancel.test.d.ts.map +0 -1
  200. package/dist/src/agent/__tests__/agent.cancel.test.js +0 -337
  201. package/dist/src/agent/__tests__/agent.cancel.test.js.map +0 -1
  202. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts +0 -2
  203. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts.map +0 -1
  204. package/dist/src/agent/__tests__/agent.concurrent.test.js +0 -488
  205. package/dist/src/agent/__tests__/agent.concurrent.test.js.map +0 -1
  206. package/dist/src/agent/__tests__/agent.context-manager.test.d.ts +0 -2
  207. package/dist/src/agent/__tests__/agent.context-manager.test.d.ts.map +0 -1
  208. package/dist/src/agent/__tests__/agent.context-manager.test.js +0 -106
  209. package/dist/src/agent/__tests__/agent.context-manager.test.js.map +0 -1
  210. package/dist/src/agent/__tests__/agent.hook.test.d.ts +0 -2
  211. package/dist/src/agent/__tests__/agent.hook.test.d.ts.map +0 -1
  212. package/dist/src/agent/__tests__/agent.hook.test.js +0 -1332
  213. package/dist/src/agent/__tests__/agent.hook.test.js.map +0 -1
  214. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts +0 -2
  215. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts.map +0 -1
  216. package/dist/src/agent/__tests__/agent.interrupt.test.js +0 -779
  217. package/dist/src/agent/__tests__/agent.interrupt.test.js.map +0 -1
  218. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts +0 -2
  219. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts.map +0 -1
  220. package/dist/src/agent/__tests__/agent.invocation-state.test.js +0 -219
  221. package/dist/src/agent/__tests__/agent.invocation-state.test.js.map +0 -1
  222. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts +0 -2
  223. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts.map +0 -1
  224. package/dist/src/agent/__tests__/agent.model-retry.test.js +0 -161
  225. package/dist/src/agent/__tests__/agent.model-retry.test.js.map +0 -1
  226. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts +0 -2
  227. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts.map +0 -1
  228. package/dist/src/agent/__tests__/agent.stateful-model.test.js +0 -169
  229. package/dist/src/agent/__tests__/agent.stateful-model.test.js.map +0 -1
  230. package/dist/src/agent/__tests__/agent.test.d.ts +0 -2
  231. package/dist/src/agent/__tests__/agent.test.d.ts.map +0 -1
  232. package/dist/src/agent/__tests__/agent.test.js +0 -1624
  233. package/dist/src/agent/__tests__/agent.test.js.map +0 -1
  234. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts +0 -2
  235. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts.map +0 -1
  236. package/dist/src/agent/__tests__/agent.tracer.test.node.js +0 -535
  237. package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +0 -1
  238. package/dist/src/agent/__tests__/printer.test.d.ts +0 -2
  239. package/dist/src/agent/__tests__/printer.test.d.ts.map +0 -1
  240. package/dist/src/agent/__tests__/printer.test.js +0 -188
  241. package/dist/src/agent/__tests__/printer.test.js.map +0 -1
  242. package/dist/src/agent/__tests__/snapshot.test.d.ts +0 -2
  243. package/dist/src/agent/__tests__/snapshot.test.d.ts.map +0 -1
  244. package/dist/src/agent/__tests__/snapshot.test.js +0 -442
  245. package/dist/src/agent/__tests__/snapshot.test.js.map +0 -1
  246. package/dist/src/agent/__tests__/tool-caller.test.d.ts +0 -2
  247. package/dist/src/agent/__tests__/tool-caller.test.d.ts.map +0 -1
  248. package/dist/src/agent/__tests__/tool-caller.test.js +0 -459
  249. package/dist/src/agent/__tests__/tool-caller.test.js.map +0 -1
  250. package/dist/src/conversation-manager/__tests__/agentic-context.test.d.ts +0 -2
  251. package/dist/src/conversation-manager/__tests__/agentic-context.test.d.ts.map +0 -1
  252. package/dist/src/conversation-manager/__tests__/agentic-context.test.js +0 -332
  253. package/dist/src/conversation-manager/__tests__/agentic-context.test.js.map +0 -1
  254. package/dist/src/conversation-manager/__tests__/context-compression.test.d.ts +0 -2
  255. package/dist/src/conversation-manager/__tests__/context-compression.test.d.ts.map +0 -1
  256. package/dist/src/conversation-manager/__tests__/context-compression.test.js +0 -176
  257. package/dist/src/conversation-manager/__tests__/context-compression.test.js.map +0 -1
  258. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts +0 -2
  259. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts.map +0 -1
  260. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +0 -321
  261. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +0 -1
  262. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts +0 -2
  263. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts.map +0 -1
  264. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +0 -64
  265. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +0 -1
  266. package/dist/src/conversation-manager/__tests__/pin.test.d.ts +0 -2
  267. package/dist/src/conversation-manager/__tests__/pin.test.d.ts.map +0 -1
  268. package/dist/src/conversation-manager/__tests__/pin.test.js +0 -119
  269. package/dist/src/conversation-manager/__tests__/pin.test.js.map +0 -1
  270. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts +0 -2
  271. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts.map +0 -1
  272. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +0 -1080
  273. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +0 -1
  274. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.d.ts +0 -2
  275. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.d.ts.map +0 -1
  276. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js +0 -400
  277. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js.map +0 -1
  278. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.d.ts +0 -2
  279. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.d.ts.map +0 -1
  280. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.js +0 -138
  281. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.js.map +0 -1
  282. package/dist/src/hooks/__tests__/events.test.d.ts +0 -2
  283. package/dist/src/hooks/__tests__/events.test.d.ts.map +0 -1
  284. package/dist/src/hooks/__tests__/events.test.js +0 -1060
  285. package/dist/src/hooks/__tests__/events.test.js.map +0 -1
  286. package/dist/src/hooks/__tests__/registry.test.d.ts +0 -2
  287. package/dist/src/hooks/__tests__/registry.test.d.ts.map +0 -1
  288. package/dist/src/hooks/__tests__/registry.test.js +0 -325
  289. package/dist/src/hooks/__tests__/registry.test.js.map +0 -1
  290. package/dist/src/injection/__tests__/message-injection.test.d.ts +0 -2
  291. package/dist/src/injection/__tests__/message-injection.test.d.ts.map +0 -1
  292. package/dist/src/injection/__tests__/message-injection.test.js +0 -200
  293. package/dist/src/injection/__tests__/message-injection.test.js.map +0 -1
  294. package/dist/src/interventions/__tests__/handler.test.d.ts +0 -2
  295. package/dist/src/interventions/__tests__/handler.test.d.ts.map +0 -1
  296. package/dist/src/interventions/__tests__/handler.test.js +0 -35
  297. package/dist/src/interventions/__tests__/handler.test.js.map +0 -1
  298. package/dist/src/interventions/__tests__/registry.test.d.ts +0 -2
  299. package/dist/src/interventions/__tests__/registry.test.d.ts.map +0 -1
  300. package/dist/src/interventions/__tests__/registry.test.js +0 -692
  301. package/dist/src/interventions/__tests__/registry.test.js.map +0 -1
  302. package/dist/src/logging/__tests__/logger.test.d.ts +0 -2
  303. package/dist/src/logging/__tests__/logger.test.d.ts.map +0 -1
  304. package/dist/src/logging/__tests__/logger.test.js +0 -70
  305. package/dist/src/logging/__tests__/logger.test.js.map +0 -1
  306. package/dist/src/logging/__tests__/warn-once.test.d.ts +0 -2
  307. package/dist/src/logging/__tests__/warn-once.test.d.ts.map +0 -1
  308. package/dist/src/logging/__tests__/warn-once.test.js +0 -30
  309. package/dist/src/logging/__tests__/warn-once.test.js.map +0 -1
  310. package/dist/src/mcp.d.ts.map +0 -1
  311. package/dist/src/mcp.js.map +0 -1
  312. package/dist/src/memory/__tests__/memory-manager.test.d.ts +0 -2
  313. package/dist/src/memory/__tests__/memory-manager.test.d.ts.map +0 -1
  314. package/dist/src/memory/__tests__/memory-manager.test.js +0 -679
  315. package/dist/src/memory/__tests__/memory-manager.test.js.map +0 -1
  316. package/dist/src/memory/__tests__/memory-tracing.test.d.ts +0 -2
  317. package/dist/src/memory/__tests__/memory-tracing.test.d.ts.map +0 -1
  318. package/dist/src/memory/__tests__/memory-tracing.test.js +0 -250
  319. package/dist/src/memory/__tests__/memory-tracing.test.js.map +0 -1
  320. package/dist/src/memory/extraction/__tests__/extraction.test.d.ts +0 -2
  321. package/dist/src/memory/extraction/__tests__/extraction.test.d.ts.map +0 -1
  322. package/dist/src/memory/extraction/__tests__/extraction.test.js +0 -639
  323. package/dist/src/memory/extraction/__tests__/extraction.test.js.map +0 -1
  324. package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts +0 -2
  325. package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts.map +0 -1
  326. package/dist/src/memory/extraction/__tests__/model-extractor.test.js +0 -104
  327. package/dist/src/memory/extraction/__tests__/model-extractor.test.js.map +0 -1
  328. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts +0 -2
  329. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts.map +0 -1
  330. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js +0 -81
  331. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js.map +0 -1
  332. package/dist/src/middleware/__tests__/agent-middleware.test.d.ts +0 -2
  333. package/dist/src/middleware/__tests__/agent-middleware.test.d.ts.map +0 -1
  334. package/dist/src/middleware/__tests__/agent-middleware.test.js +0 -1206
  335. package/dist/src/middleware/__tests__/agent-middleware.test.js.map +0 -1
  336. package/dist/src/middleware/__tests__/copy-on-input.test.d.ts +0 -2
  337. package/dist/src/middleware/__tests__/copy-on-input.test.d.ts.map +0 -1
  338. package/dist/src/middleware/__tests__/copy-on-input.test.js +0 -379
  339. package/dist/src/middleware/__tests__/copy-on-input.test.js.map +0 -1
  340. package/dist/src/middleware/__tests__/custom-stages.test.d.ts +0 -2
  341. package/dist/src/middleware/__tests__/custom-stages.test.d.ts.map +0 -1
  342. package/dist/src/middleware/__tests__/custom-stages.test.js +0 -97
  343. package/dist/src/middleware/__tests__/custom-stages.test.js.map +0 -1
  344. package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts +0 -2
  345. package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts.map +0 -1
  346. package/dist/src/middleware/__tests__/middleware-interrupts.test.js +0 -267
  347. package/dist/src/middleware/__tests__/middleware-interrupts.test.js.map +0 -1
  348. package/dist/src/middleware/__tests__/registry.test.d.ts +0 -2
  349. package/dist/src/middleware/__tests__/registry.test.d.ts.map +0 -1
  350. package/dist/src/middleware/__tests__/registry.test.js +0 -525
  351. package/dist/src/middleware/__tests__/registry.test.js.map +0 -1
  352. package/dist/src/models/__tests__/anthropic.test.d.ts +0 -2
  353. package/dist/src/models/__tests__/anthropic.test.d.ts.map +0 -1
  354. package/dist/src/models/__tests__/anthropic.test.js +0 -793
  355. package/dist/src/models/__tests__/anthropic.test.js.map +0 -1
  356. package/dist/src/models/__tests__/bedrock.test.d.ts +0 -2
  357. package/dist/src/models/__tests__/bedrock.test.d.ts.map +0 -1
  358. package/dist/src/models/__tests__/bedrock.test.js +0 -3964
  359. package/dist/src/models/__tests__/bedrock.test.js.map +0 -1
  360. package/dist/src/models/__tests__/defaults.test.d.ts +0 -2
  361. package/dist/src/models/__tests__/defaults.test.d.ts.map +0 -1
  362. package/dist/src/models/__tests__/defaults.test.js +0 -36
  363. package/dist/src/models/__tests__/defaults.test.js.map +0 -1
  364. package/dist/src/models/__tests__/google.test.d.ts +0 -2
  365. package/dist/src/models/__tests__/google.test.d.ts.map +0 -1
  366. package/dist/src/models/__tests__/google.test.js +0 -1145
  367. package/dist/src/models/__tests__/google.test.js.map +0 -1
  368. package/dist/src/models/__tests__/model.test.d.ts +0 -2
  369. package/dist/src/models/__tests__/model.test.d.ts.map +0 -1
  370. package/dist/src/models/__tests__/model.test.js +0 -921
  371. package/dist/src/models/__tests__/model.test.js.map +0 -1
  372. package/dist/src/models/__tests__/streaming.test.d.ts +0 -2
  373. package/dist/src/models/__tests__/streaming.test.d.ts.map +0 -1
  374. package/dist/src/models/__tests__/streaming.test.js +0 -50
  375. package/dist/src/models/__tests__/streaming.test.js.map +0 -1
  376. package/dist/src/models/__tests__/test-utils.d.ts +0 -10
  377. package/dist/src/models/__tests__/test-utils.d.ts.map +0 -1
  378. package/dist/src/models/__tests__/test-utils.js +0 -17
  379. package/dist/src/models/__tests__/test-utils.js.map +0 -1
  380. package/dist/src/models/__tests__/vercel.test.d.ts +0 -2
  381. package/dist/src/models/__tests__/vercel.test.d.ts.map +0 -1
  382. package/dist/src/models/__tests__/vercel.test.js +0 -740
  383. package/dist/src/models/__tests__/vercel.test.js.map +0 -1
  384. package/dist/src/models/openai/__tests__/chat.test.d.ts +0 -2
  385. package/dist/src/models/openai/__tests__/chat.test.d.ts.map +0 -1
  386. package/dist/src/models/openai/__tests__/chat.test.js +0 -1586
  387. package/dist/src/models/openai/__tests__/chat.test.js.map +0 -1
  388. package/dist/src/models/openai/__tests__/errors.test.d.ts +0 -2
  389. package/dist/src/models/openai/__tests__/errors.test.d.ts.map +0 -1
  390. package/dist/src/models/openai/__tests__/errors.test.js +0 -39
  391. package/dist/src/models/openai/__tests__/errors.test.js.map +0 -1
  392. package/dist/src/models/openai/__tests__/mantle.test.d.ts +0 -2
  393. package/dist/src/models/openai/__tests__/mantle.test.d.ts.map +0 -1
  394. package/dist/src/models/openai/__tests__/mantle.test.js +0 -189
  395. package/dist/src/models/openai/__tests__/mantle.test.js.map +0 -1
  396. package/dist/src/models/openai/__tests__/responses.test.d.ts +0 -2
  397. package/dist/src/models/openai/__tests__/responses.test.d.ts.map +0 -1
  398. package/dist/src/models/openai/__tests__/responses.test.js +0 -709
  399. package/dist/src/models/openai/__tests__/responses.test.js.map +0 -1
  400. package/dist/src/multiagent/__tests__/events.test.d.ts +0 -2
  401. package/dist/src/multiagent/__tests__/events.test.d.ts.map +0 -1
  402. package/dist/src/multiagent/__tests__/events.test.js +0 -493
  403. package/dist/src/multiagent/__tests__/events.test.js.map +0 -1
  404. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts +0 -2
  405. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts.map +0 -1
  406. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js +0 -95
  407. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js.map +0 -1
  408. package/dist/src/multiagent/__tests__/graph.test.d.ts +0 -2
  409. package/dist/src/multiagent/__tests__/graph.test.d.ts.map +0 -1
  410. package/dist/src/multiagent/__tests__/graph.test.js +0 -698
  411. package/dist/src/multiagent/__tests__/graph.test.js.map +0 -1
  412. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts +0 -2
  413. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts.map +0 -1
  414. package/dist/src/multiagent/__tests__/graph.tracer.test.js +0 -218
  415. package/dist/src/multiagent/__tests__/graph.tracer.test.js.map +0 -1
  416. package/dist/src/multiagent/__tests__/interrupts.test.d.ts +0 -2
  417. package/dist/src/multiagent/__tests__/interrupts.test.d.ts.map +0 -1
  418. package/dist/src/multiagent/__tests__/interrupts.test.js +0 -390
  419. package/dist/src/multiagent/__tests__/interrupts.test.js.map +0 -1
  420. package/dist/src/multiagent/__tests__/nodes.test.d.ts +0 -2
  421. package/dist/src/multiagent/__tests__/nodes.test.d.ts.map +0 -1
  422. package/dist/src/multiagent/__tests__/nodes.test.js +0 -321
  423. package/dist/src/multiagent/__tests__/nodes.test.js.map +0 -1
  424. package/dist/src/multiagent/__tests__/queue.test.d.ts +0 -2
  425. package/dist/src/multiagent/__tests__/queue.test.d.ts.map +0 -1
  426. package/dist/src/multiagent/__tests__/queue.test.js +0 -118
  427. package/dist/src/multiagent/__tests__/queue.test.js.map +0 -1
  428. package/dist/src/multiagent/__tests__/snapshot.test.d.ts +0 -2
  429. package/dist/src/multiagent/__tests__/snapshot.test.d.ts.map +0 -1
  430. package/dist/src/multiagent/__tests__/snapshot.test.js +0 -161
  431. package/dist/src/multiagent/__tests__/snapshot.test.js.map +0 -1
  432. package/dist/src/multiagent/__tests__/state.test.d.ts +0 -2
  433. package/dist/src/multiagent/__tests__/state.test.d.ts.map +0 -1
  434. package/dist/src/multiagent/__tests__/state.test.js +0 -526
  435. package/dist/src/multiagent/__tests__/state.test.js.map +0 -1
  436. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts +0 -2
  437. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts.map +0 -1
  438. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js +0 -56
  439. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js.map +0 -1
  440. package/dist/src/multiagent/__tests__/swarm.test.d.ts +0 -2
  441. package/dist/src/multiagent/__tests__/swarm.test.d.ts.map +0 -1
  442. package/dist/src/multiagent/__tests__/swarm.test.js +0 -477
  443. package/dist/src/multiagent/__tests__/swarm.test.js.map +0 -1
  444. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts +0 -2
  445. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts.map +0 -1
  446. package/dist/src/multiagent/__tests__/swarm.tracer.test.js +0 -235
  447. package/dist/src/multiagent/__tests__/swarm.tracer.test.js.map +0 -1
  448. package/dist/src/plugins/__tests__/plugin.test.d.ts +0 -2
  449. package/dist/src/plugins/__tests__/plugin.test.d.ts.map +0 -1
  450. package/dist/src/plugins/__tests__/plugin.test.js +0 -114
  451. package/dist/src/plugins/__tests__/plugin.test.js.map +0 -1
  452. package/dist/src/plugins/__tests__/registry.test.d.ts +0 -2
  453. package/dist/src/plugins/__tests__/registry.test.d.ts.map +0 -1
  454. package/dist/src/plugins/__tests__/registry.test.js +0 -147
  455. package/dist/src/plugins/__tests__/registry.test.js.map +0 -1
  456. package/dist/src/registry/__tests__/tool-registry.test.d.ts +0 -2
  457. package/dist/src/registry/__tests__/tool-registry.test.d.ts.map +0 -1
  458. package/dist/src/registry/__tests__/tool-registry.test.js +0 -210
  459. package/dist/src/registry/__tests__/tool-registry.test.js.map +0 -1
  460. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts +0 -2
  461. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts.map +0 -1
  462. package/dist/src/retry/__tests__/backoff-strategy.test.js +0 -116
  463. package/dist/src/retry/__tests__/backoff-strategy.test.js.map +0 -1
  464. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts +0 -2
  465. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts.map +0 -1
  466. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js +0 -225
  467. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js.map +0 -1
  468. package/dist/src/sandbox/__tests__/default.test.browser.d.ts +0 -2
  469. package/dist/src/sandbox/__tests__/default.test.browser.d.ts.map +0 -1
  470. package/dist/src/sandbox/__tests__/default.test.browser.js +0 -11
  471. package/dist/src/sandbox/__tests__/default.test.browser.js.map +0 -1
  472. package/dist/src/sandbox/__tests__/default.test.node.d.ts +0 -2
  473. package/dist/src/sandbox/__tests__/default.test.node.d.ts.map +0 -1
  474. package/dist/src/sandbox/__tests__/default.test.node.js +0 -23
  475. package/dist/src/sandbox/__tests__/default.test.node.js.map +0 -1
  476. package/dist/src/sandbox/__tests__/docker.test.node.d.ts +0 -2
  477. package/dist/src/sandbox/__tests__/docker.test.node.d.ts.map +0 -1
  478. package/dist/src/sandbox/__tests__/docker.test.node.js +0 -89
  479. package/dist/src/sandbox/__tests__/docker.test.node.js.map +0 -1
  480. package/dist/src/sandbox/__tests__/errors.test.node.d.ts +0 -2
  481. package/dist/src/sandbox/__tests__/errors.test.node.d.ts.map +0 -1
  482. package/dist/src/sandbox/__tests__/errors.test.node.js +0 -33
  483. package/dist/src/sandbox/__tests__/errors.test.node.js.map +0 -1
  484. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts +0 -2
  485. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts.map +0 -1
  486. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js +0 -124
  487. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js.map +0 -1
  488. package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts +0 -2
  489. package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts.map +0 -1
  490. package/dist/src/sandbox/__tests__/posix-shell.test.node.js +0 -298
  491. package/dist/src/sandbox/__tests__/posix-shell.test.node.js.map +0 -1
  492. package/dist/src/sandbox/__tests__/ssh.test.node.d.ts +0 -2
  493. package/dist/src/sandbox/__tests__/ssh.test.node.d.ts.map +0 -1
  494. package/dist/src/sandbox/__tests__/ssh.test.node.js +0 -262
  495. package/dist/src/sandbox/__tests__/ssh.test.node.js.map +0 -1
  496. package/dist/src/session/__tests__/file-storage.test.node.d.ts +0 -2
  497. package/dist/src/session/__tests__/file-storage.test.node.d.ts.map +0 -1
  498. package/dist/src/session/__tests__/file-storage.test.node.js +0 -278
  499. package/dist/src/session/__tests__/file-storage.test.node.js.map +0 -1
  500. package/dist/src/session/__tests__/s3-storage.test.d.ts +0 -2
  501. package/dist/src/session/__tests__/s3-storage.test.d.ts.map +0 -1
  502. package/dist/src/session/__tests__/s3-storage.test.js +0 -461
  503. package/dist/src/session/__tests__/s3-storage.test.js.map +0 -1
  504. package/dist/src/session/__tests__/session-manager.test.d.ts +0 -2
  505. package/dist/src/session/__tests__/session-manager.test.d.ts.map +0 -1
  506. package/dist/src/session/__tests__/session-manager.test.js +0 -832
  507. package/dist/src/session/__tests__/session-manager.test.js.map +0 -1
  508. package/dist/src/session/__tests__/validation.test.d.ts +0 -2
  509. package/dist/src/session/__tests__/validation.test.d.ts.map +0 -1
  510. package/dist/src/session/__tests__/validation.test.js +0 -47
  511. package/dist/src/session/__tests__/validation.test.js.map +0 -1
  512. package/dist/src/telemetry/__tests__/config.test.d.ts +0 -2
  513. package/dist/src/telemetry/__tests__/config.test.d.ts.map +0 -1
  514. package/dist/src/telemetry/__tests__/config.test.js +0 -64
  515. package/dist/src/telemetry/__tests__/config.test.js.map +0 -1
  516. package/dist/src/telemetry/__tests__/config.test.node.d.ts +0 -2
  517. package/dist/src/telemetry/__tests__/config.test.node.d.ts.map +0 -1
  518. package/dist/src/telemetry/__tests__/config.test.node.js +0 -164
  519. package/dist/src/telemetry/__tests__/config.test.node.js.map +0 -1
  520. package/dist/src/telemetry/__tests__/json.test.d.ts +0 -2
  521. package/dist/src/telemetry/__tests__/json.test.d.ts.map +0 -1
  522. package/dist/src/telemetry/__tests__/json.test.js +0 -89
  523. package/dist/src/telemetry/__tests__/json.test.js.map +0 -1
  524. package/dist/src/telemetry/__tests__/local-trace.test.d.ts +0 -2
  525. package/dist/src/telemetry/__tests__/local-trace.test.d.ts.map +0 -1
  526. package/dist/src/telemetry/__tests__/local-trace.test.js +0 -158
  527. package/dist/src/telemetry/__tests__/local-trace.test.js.map +0 -1
  528. package/dist/src/telemetry/__tests__/meter.test.d.ts +0 -2
  529. package/dist/src/telemetry/__tests__/meter.test.d.ts.map +0 -1
  530. package/dist/src/telemetry/__tests__/meter.test.js +0 -695
  531. package/dist/src/telemetry/__tests__/meter.test.js.map +0 -1
  532. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts +0 -2
  533. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts.map +0 -1
  534. package/dist/src/telemetry/__tests__/tracer.test.node.js +0 -958
  535. package/dist/src/telemetry/__tests__/tracer.test.node.js.map +0 -1
  536. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts +0 -2
  537. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts.map +0 -1
  538. package/dist/src/tools/__tests__/structured-output-tool.test.js +0 -84
  539. package/dist/src/tools/__tests__/structured-output-tool.test.js.map +0 -1
  540. package/dist/src/tools/__tests__/tool-factory.test.d.ts +0 -2
  541. package/dist/src/tools/__tests__/tool-factory.test.d.ts.map +0 -1
  542. package/dist/src/tools/__tests__/tool-factory.test.js +0 -98
  543. package/dist/src/tools/__tests__/tool-factory.test.js.map +0 -1
  544. package/dist/src/tools/__tests__/tool.test.d.ts +0 -2
  545. package/dist/src/tools/__tests__/tool.test.d.ts.map +0 -1
  546. package/dist/src/tools/__tests__/tool.test.js +0 -1043
  547. package/dist/src/tools/__tests__/tool.test.js.map +0 -1
  548. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts +0 -2
  549. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts.map +0 -1
  550. package/dist/src/tools/__tests__/zod-tool.test-d.js +0 -227
  551. package/dist/src/tools/__tests__/zod-tool.test-d.js.map +0 -1
  552. package/dist/src/tools/__tests__/zod-tool.test.d.ts +0 -2
  553. package/dist/src/tools/__tests__/zod-tool.test.d.ts.map +0 -1
  554. package/dist/src/tools/__tests__/zod-tool.test.js +0 -563
  555. package/dist/src/tools/__tests__/zod-tool.test.js.map +0 -1
  556. package/dist/src/types/__tests__/agent.test.d.ts +0 -2
  557. package/dist/src/types/__tests__/agent.test.d.ts.map +0 -1
  558. package/dist/src/types/__tests__/agent.test.js +0 -476
  559. package/dist/src/types/__tests__/agent.test.js.map +0 -1
  560. package/dist/src/types/__tests__/citations.test.d.ts +0 -2
  561. package/dist/src/types/__tests__/citations.test.d.ts.map +0 -1
  562. package/dist/src/types/__tests__/citations.test.js +0 -104
  563. package/dist/src/types/__tests__/citations.test.js.map +0 -1
  564. package/dist/src/types/__tests__/json.test.d.ts +0 -2
  565. package/dist/src/types/__tests__/json.test.d.ts.map +0 -1
  566. package/dist/src/types/__tests__/json.test.js +0 -298
  567. package/dist/src/types/__tests__/json.test.js.map +0 -1
  568. package/dist/src/types/__tests__/media.test.d.ts +0 -2
  569. package/dist/src/types/__tests__/media.test.d.ts.map +0 -1
  570. package/dist/src/types/__tests__/media.test.js +0 -478
  571. package/dist/src/types/__tests__/media.test.js.map +0 -1
  572. package/dist/src/types/__tests__/messages.test.d.ts +0 -2
  573. package/dist/src/types/__tests__/messages.test.d.ts.map +0 -1
  574. package/dist/src/types/__tests__/messages.test.js +0 -681
  575. package/dist/src/types/__tests__/messages.test.js.map +0 -1
  576. package/dist/src/types/__tests__/validation.test.d.ts +0 -2
  577. package/dist/src/types/__tests__/validation.test.d.ts.map +0 -1
  578. package/dist/src/types/__tests__/validation.test.js +0 -30
  579. package/dist/src/types/__tests__/validation.test.js.map +0 -1
  580. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.d.ts +0 -2
  581. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.d.ts.map +0 -1
  582. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js +0 -756
  583. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js.map +0 -1
  584. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts +0 -2
  585. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts.map +0 -1
  586. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js +0 -358
  587. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js.map +0 -1
  588. package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts +0 -2
  589. package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts.map +0 -1
  590. package/dist/src/vended-interventions/steering/__tests__/handler.test.js +0 -163
  591. package/dist/src/vended-interventions/steering/__tests__/handler.test.js.map +0 -1
  592. package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts +0 -2
  593. package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts.map +0 -1
  594. package/dist/src/vended-interventions/steering/__tests__/llm.test.js +0 -60
  595. package/dist/src/vended-interventions/steering/__tests__/llm.test.js.map +0 -1
  596. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts +0 -2
  597. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts.map +0 -1
  598. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js +0 -94
  599. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js.map +0 -1
  600. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.d.ts +0 -2
  601. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.d.ts.map +0 -1
  602. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.js +0 -758
  603. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.js.map +0 -1
  604. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.d.ts +0 -2
  605. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.d.ts.map +0 -1
  606. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.js +0 -96
  607. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.js.map +0 -1
  608. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts +0 -2
  609. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts.map +0 -1
  610. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js +0 -68
  611. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js.map +0 -1
  612. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts +0 -2
  613. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts.map +0 -1
  614. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js +0 -539
  615. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js.map +0 -1
  616. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts +0 -2
  617. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts.map +0 -1
  618. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js +0 -97
  619. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js.map +0 -1
  620. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.d.ts +0 -2
  621. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.d.ts.map +0 -1
  622. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.js +0 -149
  623. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.js.map +0 -1
  624. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts +0 -2
  625. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts.map +0 -1
  626. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js +0 -216
  627. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js.map +0 -1
  628. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts +0 -2
  629. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts.map +0 -1
  630. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js +0 -78
  631. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js.map +0 -1
  632. package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts +0 -2
  633. package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts.map +0 -1
  634. package/dist/src/vended-plugins/goal/__tests__/plugin.test.js +0 -736
  635. package/dist/src/vended-plugins/goal/__tests__/plugin.test.js.map +0 -1
  636. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.d.ts +0 -2
  637. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.d.ts.map +0 -1
  638. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js +0 -482
  639. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js.map +0 -1
  640. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.d.ts +0 -2
  641. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.d.ts.map +0 -1
  642. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.js +0 -476
  643. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.js.map +0 -1
  644. package/dist/src/vended-tools/bash/__tests__/bash.test.node.d.ts +0 -2
  645. package/dist/src/vended-tools/bash/__tests__/bash.test.node.d.ts.map +0 -1
  646. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +0 -390
  647. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +0 -1
  648. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts +0 -2
  649. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts.map +0 -1
  650. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js +0 -452
  651. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +0 -1
  652. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts +0 -2
  653. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts.map +0 -1
  654. package/dist/src/vended-tools/http-request/__tests__/http-request.test.js +0 -189
  655. package/dist/src/vended-tools/http-request/__tests__/http-request.test.js.map +0 -1
  656. package/dist/src/vended-tools/notebook/__tests__/notebook.test.d.ts +0 -2
  657. package/dist/src/vended-tools/notebook/__tests__/notebook.test.d.ts.map +0 -1
  658. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +0 -388
  659. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js.map +0 -1
@@ -1,1332 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest';
2
- import { Agent } from '../agent.js';
3
- import { AfterInvocationEvent, AfterModelCallEvent, AfterToolCallEvent, AfterToolsEvent, AgentResultEvent, BeforeInvocationEvent, BeforeModelCallEvent, BeforeToolCallEvent, BeforeToolsEvent, MessageAddedEvent, ModelStreamUpdateEvent, InitializedEvent, HookableEvent, ModelMessageEvent, } from '../../hooks/index.js';
4
- import { MockMessageModel } from '../../__fixtures__/mock-message-model.js';
5
- import { MockPlugin } from '../../__fixtures__/mock-plugin.js';
6
- import { collectIterator } from '../../__fixtures__/model-test-helpers.js';
7
- import { createMockTool } from '../../__fixtures__/tool-helpers.js';
8
- import { expectAgentResult } from '../../__fixtures__/agent-helpers.js';
9
- import { Message, TextBlock, ToolResultBlock } from '../../types/messages.js';
10
- describe('Agent Hooks Integration', () => {
11
- let mockPlugin;
12
- beforeEach(() => {
13
- mockPlugin = new MockPlugin();
14
- });
15
- describe('invocation lifecycle', () => {
16
- it('fires hooks during invoke', async () => {
17
- const lifecyclePlugin = new MockPlugin();
18
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
19
- const agent = new Agent({ model, plugins: [lifecyclePlugin] });
20
- await agent.invoke('Hi');
21
- expect(lifecyclePlugin.invocations).toHaveLength(7);
22
- expect(lifecyclePlugin.invocations[0]).toEqual(new InitializedEvent({ agent }));
23
- expect(lifecyclePlugin.invocations[1]).toEqual(new BeforeInvocationEvent({ agent, invocationState: {} }));
24
- expect(lifecyclePlugin.invocations[2]).toEqual(new MessageAddedEvent({
25
- agent,
26
- message: new Message({ role: 'user', content: [new TextBlock('Hi')] }),
27
- invocationState: {},
28
- }));
29
- expect(lifecyclePlugin.invocations[3]).toEqual(new BeforeModelCallEvent({
30
- agent,
31
- model: agent.model,
32
- invocationState: {},
33
- projectedInputTokens: expect.any(Number),
34
- }));
35
- expect(lifecyclePlugin.invocations[4]).toEqual(new AfterModelCallEvent({
36
- agent,
37
- model: agent.model,
38
- invocationState: {},
39
- attemptCount: 1,
40
- stopData: {
41
- stopReason: 'endTurn',
42
- message: new Message({ role: 'assistant', content: [new TextBlock('Hello')] }),
43
- },
44
- }));
45
- expect(lifecyclePlugin.invocations[5]).toEqual(new MessageAddedEvent({
46
- agent,
47
- message: new Message({ role: 'assistant', content: [new TextBlock('Hello')] }),
48
- invocationState: {},
49
- }));
50
- expect(lifecyclePlugin.invocations[6]).toEqual(new AfterInvocationEvent({ agent, invocationState: {} }));
51
- });
52
- it('fires hooks during stream', async () => {
53
- const lifecyclePlugin = new MockPlugin();
54
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
55
- const agent = new Agent({ model, plugins: [lifecyclePlugin] });
56
- await collectIterator(agent.stream('Hi'));
57
- expect(lifecyclePlugin.invocations).toHaveLength(7);
58
- expect(lifecyclePlugin.invocations[0]).toEqual(new InitializedEvent({ agent }));
59
- expect(lifecyclePlugin.invocations[1]).toEqual(new BeforeInvocationEvent({ agent, invocationState: {} }));
60
- expect(lifecyclePlugin.invocations[2]).toEqual(new MessageAddedEvent({
61
- agent,
62
- message: new Message({ role: 'user', content: [new TextBlock('Hi')] }),
63
- invocationState: {},
64
- }));
65
- expect(lifecyclePlugin.invocations[3]).toEqual(new BeforeModelCallEvent({
66
- agent,
67
- model: agent.model,
68
- invocationState: {},
69
- projectedInputTokens: expect.any(Number),
70
- }));
71
- expect(lifecyclePlugin.invocations[4]).toEqual(new AfterModelCallEvent({
72
- agent,
73
- model: agent.model,
74
- invocationState: {},
75
- attemptCount: 1,
76
- stopData: {
77
- stopReason: 'endTurn',
78
- message: new Message({ role: 'assistant', content: [new TextBlock('Hello')] }),
79
- },
80
- }));
81
- expect(lifecyclePlugin.invocations[5]).toEqual(new MessageAddedEvent({
82
- agent,
83
- message: new Message({ role: 'assistant', content: [new TextBlock('Hello')] }),
84
- invocationState: {},
85
- }));
86
- expect(lifecyclePlugin.invocations[6]).toEqual(new AfterInvocationEvent({ agent, invocationState: {} }));
87
- });
88
- });
89
- describe('runtime hook registration', () => {
90
- it('allows adding hooks after agent creation via addHook', async () => {
91
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
92
- const agent = new Agent({ model });
93
- // Track events via individual hook registrations
94
- const invocations = [];
95
- agent.addHook(BeforeInvocationEvent, (e) => {
96
- invocations.push(e);
97
- });
98
- agent.addHook(AfterInvocationEvent, (e) => {
99
- invocations.push(e);
100
- });
101
- await agent.invoke('Hi');
102
- expect(invocations).toHaveLength(2);
103
- expect(invocations[0]).toEqual(new BeforeInvocationEvent({ agent, invocationState: {} }));
104
- expect(invocations[1]).toEqual(new AfterInvocationEvent({ agent, invocationState: {} }));
105
- });
106
- });
107
- describe('multi-turn conversations', () => {
108
- it('fires hooks for each invoke call', async () => {
109
- const lifecyclePlugin = new MockPlugin();
110
- const model = new MockMessageModel()
111
- .addTurn({ type: 'textBlock', text: 'First response' })
112
- .addTurn({ type: 'textBlock', text: 'Second response' });
113
- const agent = new Agent({ model, plugins: [lifecyclePlugin] });
114
- await agent.invoke('First message');
115
- // First turn: InitializedEvent + BeforeInvocation, MessageAdded, BeforeModelCall, AfterModelCall, MessageAdded, AfterInvocation
116
- expect(lifecyclePlugin.invocations).toHaveLength(7);
117
- await agent.invoke('Second message');
118
- // Should have 13 events total (7 for first turn + 6 for second turn, no InitializedEvent on second)
119
- expect(lifecyclePlugin.invocations).toHaveLength(13);
120
- // Filter for just Invocation events to verify they fire for each turn
121
- const invocationEvents = lifecyclePlugin.invocations.filter((e) => e instanceof BeforeInvocationEvent || e instanceof AfterInvocationEvent);
122
- expect(invocationEvents).toHaveLength(4); // 2 for each turn
123
- });
124
- });
125
- describe('tool execution hooks', () => {
126
- it('fires tool hooks during tool execution', async () => {
127
- const tool = createMockTool('testTool', () => {
128
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Tool result')] });
129
- });
130
- const model = new MockMessageModel()
131
- .addTurn({ type: 'toolUseBlock', name: 'testTool', toolUseId: 'tool-1', input: {} })
132
- .addTurn({ type: 'textBlock', text: 'Final response' });
133
- const agent = new Agent({
134
- model,
135
- tools: [tool],
136
- plugins: [mockPlugin],
137
- });
138
- await agent.invoke('Test with tool');
139
- // Find key events
140
- const beforeToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof BeforeToolCallEvent);
141
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
142
- const messageAddedEvents = mockPlugin.invocations.filter((e) => e instanceof MessageAddedEvent);
143
- // Verify tool hooks fired
144
- expect(beforeToolCallEvents.length).toBe(1);
145
- expect(afterToolCallEvents.length).toBe(1);
146
- // Verify 3 MessageAdded events: input message, assistant with tool use, tool result, final assistant
147
- expect(messageAddedEvents.length).toBe(4);
148
- // Verify BeforeToolCallEvent
149
- const beforeToolCall = beforeToolCallEvents[0];
150
- expect(beforeToolCall).toEqual(new BeforeToolCallEvent({
151
- agent,
152
- toolUse: { name: 'testTool', toolUseId: 'tool-1', input: {} },
153
- tool,
154
- invocationState: {},
155
- }));
156
- // Verify AfterToolCallEvent
157
- const afterToolCall = afterToolCallEvents[0];
158
- expect(afterToolCall).toEqual(new AfterToolCallEvent({
159
- agent,
160
- toolUse: { name: 'testTool', toolUseId: 'tool-1', input: {} },
161
- tool,
162
- result: new ToolResultBlock({
163
- toolUseId: 'tool-1',
164
- status: 'success',
165
- content: [new TextBlock('Tool result')],
166
- }),
167
- invocationState: {},
168
- }));
169
- });
170
- it('fires AfterToolCallEvent with error when tool fails', async () => {
171
- const tool = createMockTool('failingTool', () => {
172
- throw new Error('Tool execution failed');
173
- });
174
- const model = new MockMessageModel()
175
- .addTurn({ type: 'toolUseBlock', name: 'failingTool', toolUseId: 'tool-1', input: {} })
176
- .addTurn({ type: 'textBlock', text: 'Handled error' });
177
- const agent = new Agent({
178
- model,
179
- tools: [tool],
180
- plugins: [mockPlugin],
181
- });
182
- // Agent should complete successfully (tool errors are handled gracefully)
183
- const result = await agent.invoke('Test with failing tool');
184
- expect(result.stopReason).toBe('endTurn');
185
- // Find AfterToolCallEvent
186
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
187
- expect(afterToolCallEvents.length).toBe(1);
188
- const afterToolCall = afterToolCallEvents[0];
189
- expect(afterToolCall).toEqual(new AfterToolCallEvent({
190
- agent,
191
- toolUse: { name: 'failingTool', toolUseId: 'tool-1', input: {} },
192
- tool,
193
- result: new ToolResultBlock({
194
- error: new Error('Tool execution failed'),
195
- toolUseId: 'tool-1',
196
- status: 'error',
197
- content: [new TextBlock('Tool execution failed')],
198
- }),
199
- error: new Error('Tool execution failed'),
200
- invocationState: {},
201
- }));
202
- });
203
- });
204
- describe('ModelStreamUpdateEvent', () => {
205
- it('is yielded in the stream and dispatched to hooks', async () => {
206
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
207
- const streamUpdateEvents = [];
208
- const agent = new Agent({ model });
209
- agent.addHook(ModelStreamUpdateEvent, (event) => {
210
- streamUpdateEvents.push(event);
211
- });
212
- // Collect all stream events
213
- const allStreamEvents = [];
214
- for await (const event of agent.stream('Test')) {
215
- allStreamEvents.push(event);
216
- }
217
- // Should be yielded in the stream
218
- const streamUpdates = allStreamEvents.filter((e) => e instanceof ModelStreamUpdateEvent);
219
- expect(streamUpdates.length).toBeGreaterThan(0);
220
- // Should also fire as hook
221
- expect(streamUpdateEvents.length).toBeGreaterThan(0);
222
- // Stream and hook should receive the same event instances
223
- expect(streamUpdates).toStrictEqual(streamUpdateEvents);
224
- });
225
- });
226
- describe('MessageAddedEvent', () => {
227
- it('fires for initial user input', async () => {
228
- const initialMessage = { role: 'user', content: [{ type: 'textBlock', text: 'Initial' }] };
229
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Response' });
230
- const agent = new Agent({
231
- model,
232
- messages: [initialMessage],
233
- plugins: [mockPlugin],
234
- });
235
- await agent.invoke('New message');
236
- const messageAddedEvents = mockPlugin.invocations.filter((e) => e instanceof MessageAddedEvent);
237
- // Should have 2 MessageAdded event
238
- expect(messageAddedEvents).toHaveLength(2);
239
- expect(messageAddedEvents[0]).toEqual(new MessageAddedEvent({
240
- agent,
241
- message: new Message({ role: 'user', content: [new TextBlock('New message')] }),
242
- invocationState: {},
243
- }));
244
- expect(messageAddedEvents[1]).toEqual(new MessageAddedEvent({
245
- agent,
246
- message: new Message({ role: 'assistant', content: [new TextBlock('Response')] }),
247
- invocationState: {},
248
- }));
249
- });
250
- });
251
- describe('AfterModelCallEvent retry', () => {
252
- it('does not duplicate user messages on error retry', async () => {
253
- const model = new MockMessageModel()
254
- .addTurn(new Error('context overflow'))
255
- .addTurn({ type: 'textBlock', text: 'Success' });
256
- const agent = new Agent({ model, printer: false });
257
- agent.addHook(AfterModelCallEvent, (event) => {
258
- if (event.error) {
259
- event.retry = true;
260
- }
261
- });
262
- await agent.invoke('Hello');
263
- // Count user messages with "Hello" — should be exactly 1
264
- const userMessages = agent.messages.filter((m) => m.role === 'user' && m.content.some((b) => b.type === 'textBlock' && b.text === 'Hello'));
265
- expect(userMessages).toHaveLength(1);
266
- });
267
- it('does not duplicate user messages on success retry', async () => {
268
- let callCount = 0;
269
- const model = new MockMessageModel()
270
- .addTurn({ type: 'textBlock', text: 'First' })
271
- .addTurn({ type: 'textBlock', text: 'Second' });
272
- const agent = new Agent({ model, printer: false });
273
- agent.addHook(AfterModelCallEvent, (event) => {
274
- callCount++;
275
- if (callCount === 1 && !event.error) {
276
- event.retry = true;
277
- }
278
- });
279
- await agent.invoke('Hello');
280
- const userMessages = agent.messages.filter((m) => m.role === 'user' && m.content.some((b) => b.type === 'textBlock' && b.text === 'Hello'));
281
- expect(userMessages).toHaveLength(1);
282
- });
283
- it('retries model call when hook sets retry', async () => {
284
- let callCount = 0;
285
- const model = new MockMessageModel()
286
- .addTurn(new Error('First attempt failed'))
287
- .addTurn({ type: 'textBlock', text: 'Success after retry' });
288
- const agent = new Agent({ model });
289
- agent.addHook(AfterModelCallEvent, (event) => {
290
- callCount++;
291
- if (callCount === 1 && event.error) {
292
- event.retry = true;
293
- }
294
- });
295
- const result = await agent.invoke('Test');
296
- expect(result.lastMessage.content[0]).toEqual({ type: 'textBlock', text: 'Success after retry' });
297
- expect(callCount).toBe(2);
298
- });
299
- it('does not retry when retry is not set', async () => {
300
- const model = new MockMessageModel().addTurn(new Error('Failure'));
301
- const agent = new Agent({ model });
302
- await expect(agent.invoke('Test')).rejects.toThrow('Failure');
303
- });
304
- it('retries model call on success when hook requests it', async () => {
305
- let callCount = 0;
306
- const model = new MockMessageModel()
307
- .addTurn({ type: 'textBlock', text: 'First response' })
308
- .addTurn({ type: 'textBlock', text: 'Second response after retry' });
309
- const agent = new Agent({ model });
310
- agent.addHook(AfterModelCallEvent, (event) => {
311
- callCount++;
312
- if (callCount === 1 && !event.error) {
313
- event.retry = true;
314
- }
315
- });
316
- const result = await agent.invoke('Test');
317
- expect(result.lastMessage.content[0]).toEqual({ type: 'textBlock', text: 'Second response after retry' });
318
- expect(callCount).toBe(2);
319
- });
320
- });
321
- describe('AfterToolCallEvent retry', () => {
322
- it('retries tool call when hook sets retry', async () => {
323
- let toolCallCount = 0;
324
- const tool = createMockTool('retryableTool', () => {
325
- toolCallCount++;
326
- if (toolCallCount === 1) {
327
- throw new Error('First attempt failed');
328
- }
329
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
330
- });
331
- let hookCallCount = 0;
332
- const model = new MockMessageModel()
333
- .addTurn({ type: 'toolUseBlock', name: 'retryableTool', toolUseId: 'tool-1', input: {} })
334
- .addTurn({ type: 'textBlock', text: 'Done' });
335
- const agent = new Agent({ model, tools: [tool] });
336
- agent.addHook(AfterToolCallEvent, (event) => {
337
- hookCallCount++;
338
- if (hookCallCount === 1 && event.error) {
339
- event.retry = true;
340
- }
341
- });
342
- const result = await agent.invoke('Test');
343
- expect(result.stopReason).toBe('endTurn');
344
- expect(toolCallCount).toBe(2);
345
- expect(hookCallCount).toBe(2);
346
- });
347
- it('does not retry tool call when retry is not set', async () => {
348
- let toolCallCount = 0;
349
- const tool = createMockTool('failingTool', () => {
350
- toolCallCount++;
351
- throw new Error('Tool failed');
352
- });
353
- const model = new MockMessageModel()
354
- .addTurn({ type: 'toolUseBlock', name: 'failingTool', toolUseId: 'tool-1', input: {} })
355
- .addTurn({ type: 'textBlock', text: 'Handled error' });
356
- const agent = new Agent({ model, tools: [tool] });
357
- const result = await agent.invoke('Test');
358
- expect(result.stopReason).toBe('endTurn');
359
- expect(toolCallCount).toBe(1);
360
- });
361
- it('fires BeforeToolCallEvent on each retry', async () => {
362
- let toolCallCount = 0;
363
- const tool = createMockTool('retryableTool', () => {
364
- toolCallCount++;
365
- return new ToolResultBlock({
366
- toolUseId: 'tool-1',
367
- status: 'success',
368
- content: [new TextBlock(`Result ${toolCallCount}`)],
369
- });
370
- });
371
- let beforeCount = 0;
372
- let afterCount = 0;
373
- const model = new MockMessageModel()
374
- .addTurn({ type: 'toolUseBlock', name: 'retryableTool', toolUseId: 'tool-1', input: {} })
375
- .addTurn({ type: 'textBlock', text: 'Done' });
376
- const agent = new Agent({ model, tools: [tool] });
377
- agent.addHook(BeforeToolCallEvent, () => {
378
- beforeCount++;
379
- });
380
- agent.addHook(AfterToolCallEvent, (event) => {
381
- afterCount++;
382
- if (afterCount === 1) {
383
- event.retry = true;
384
- }
385
- });
386
- await agent.invoke('Test');
387
- expect(beforeCount).toBe(2);
388
- expect(afterCount).toBe(2);
389
- expect(toolCallCount).toBe(2);
390
- });
391
- it('retries tool call on success when hook requests it', async () => {
392
- let toolCallCount = 0;
393
- const tool = createMockTool('successTool', () => {
394
- toolCallCount++;
395
- return new ToolResultBlock({
396
- toolUseId: 'tool-1',
397
- status: 'success',
398
- content: [new TextBlock(`Result ${toolCallCount}`)],
399
- });
400
- });
401
- let hookCallCount = 0;
402
- const model = new MockMessageModel()
403
- .addTurn({ type: 'toolUseBlock', name: 'successTool', toolUseId: 'tool-1', input: {} })
404
- .addTurn({ type: 'textBlock', text: 'Done' });
405
- const agent = new Agent({ model, tools: [tool] });
406
- agent.addHook(AfterToolCallEvent, (event) => {
407
- hookCallCount++;
408
- if (hookCallCount === 1) {
409
- event.retry = true;
410
- }
411
- });
412
- const result = await agent.invoke('Test');
413
- expect(result.stopReason).toBe('endTurn');
414
- expect(toolCallCount).toBe(2);
415
- expect(hookCallCount).toBe(2);
416
- });
417
- });
418
- describe('cancel tool via hooks', () => {
419
- it('cancels individual tool call with default message when cancel is true', async () => {
420
- let toolExecuted = false;
421
- const tool = createMockTool('blockedTool', () => {
422
- toolExecuted = true;
423
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
424
- });
425
- const model = new MockMessageModel()
426
- .addTurn({ type: 'toolUseBlock', name: 'blockedTool', toolUseId: 'tool-1', input: {} })
427
- .addTurn({ type: 'textBlock', text: 'Done' });
428
- const agent = new Agent({ model, tools: [tool], plugins: [mockPlugin] });
429
- agent.addHook(BeforeToolCallEvent, (event) => {
430
- event.cancel = true;
431
- });
432
- const result = await agent.invoke('Test');
433
- expect(result.stopReason).toBe('endTurn');
434
- expect(toolExecuted).toBe(false);
435
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
436
- expect(afterToolCallEvents).toHaveLength(1);
437
- const afterEvent = afterToolCallEvents[0];
438
- expect(afterEvent.result).toEqual(new ToolResultBlock({
439
- toolUseId: 'tool-1',
440
- status: 'error',
441
- content: [new TextBlock('Tool cancelled by hook')],
442
- }));
443
- });
444
- it('cancels individual tool call with custom message when cancel is a string', async () => {
445
- let toolExecuted = false;
446
- const tool = createMockTool('blockedTool', () => {
447
- toolExecuted = true;
448
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
449
- });
450
- const model = new MockMessageModel()
451
- .addTurn({ type: 'toolUseBlock', name: 'blockedTool', toolUseId: 'tool-1', input: {} })
452
- .addTurn({ type: 'textBlock', text: 'Done' });
453
- const agent = new Agent({ model, tools: [tool], plugins: [mockPlugin] });
454
- agent.addHook(BeforeToolCallEvent, (event) => {
455
- event.cancel = 'Tool call limit exceeded';
456
- });
457
- const result = await agent.invoke('Test');
458
- expect(result.stopReason).toBe('endTurn');
459
- expect(toolExecuted).toBe(false);
460
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
461
- expect(afterToolCallEvents).toHaveLength(1);
462
- const afterEvent = afterToolCallEvents[0];
463
- expect(afterEvent.result).toEqual(new ToolResultBlock({
464
- toolUseId: 'tool-1',
465
- status: 'error',
466
- content: [new TextBlock('Tool call limit exceeded')],
467
- }));
468
- });
469
- it('cancels only specific tools when BeforeToolCallEvent selectively cancels', async () => {
470
- const executedTools = [];
471
- const tool1 = createMockTool('allowedTool', () => {
472
- executedTools.push('allowedTool');
473
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Allowed')] });
474
- });
475
- const tool2 = createMockTool('blockedTool', () => {
476
- executedTools.push('blockedTool');
477
- return new ToolResultBlock({ toolUseId: 'tool-2', status: 'success', content: [new TextBlock('Blocked')] });
478
- });
479
- const model = new MockMessageModel()
480
- .addTurn([
481
- { type: 'toolUseBlock', name: 'allowedTool', toolUseId: 'tool-1', input: {} },
482
- { type: 'toolUseBlock', name: 'blockedTool', toolUseId: 'tool-2', input: {} },
483
- ])
484
- .addTurn({ type: 'textBlock', text: 'Done' });
485
- const agent = new Agent({ model, tools: [tool1, tool2], plugins: [mockPlugin] });
486
- agent.addHook(BeforeToolCallEvent, (event) => {
487
- if (event.toolUse.name === 'blockedTool') {
488
- event.cancel = 'This tool is blocked';
489
- }
490
- });
491
- const result = await agent.invoke('Test');
492
- expect(result.stopReason).toBe('endTurn');
493
- expect(executedTools).toEqual(['allowedTool']);
494
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
495
- expect(afterToolCallEvents).toHaveLength(2);
496
- expect(afterToolCallEvents[0].result).toEqual(new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Allowed')] }));
497
- expect(afterToolCallEvents[1].result).toEqual(new ToolResultBlock({
498
- toolUseId: 'tool-2',
499
- status: 'error',
500
- content: [new TextBlock('This tool is blocked')],
501
- }));
502
- });
503
- it('cancels all tools with default message when BeforeToolsEvent.cancel is true', async () => {
504
- let toolExecuted = false;
505
- const tool = createMockTool('blockedTool', () => {
506
- toolExecuted = true;
507
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
508
- });
509
- const model = new MockMessageModel()
510
- .addTurn({ type: 'toolUseBlock', name: 'blockedTool', toolUseId: 'tool-1', input: {} })
511
- .addTurn({ type: 'textBlock', text: 'Done' });
512
- const agent = new Agent({ model, tools: [tool], plugins: [mockPlugin] });
513
- agent.addHook(BeforeToolsEvent, (event) => {
514
- event.cancel = true;
515
- });
516
- const result = await agent.invoke('Test');
517
- expect(result.stopReason).toBe('endTurn');
518
- expect(toolExecuted).toBe(false);
519
- const afterToolsEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolsEvent);
520
- expect(afterToolsEvents).toHaveLength(1);
521
- const afterEvent = afterToolsEvents[0];
522
- expect(afterEvent.message.content[0]).toEqual(new ToolResultBlock({
523
- toolUseId: 'tool-1',
524
- status: 'error',
525
- content: [new TextBlock('Tool cancelled by hook')],
526
- }));
527
- });
528
- it('cancels all tools with custom message when BeforeToolsEvent.cancel is a string', async () => {
529
- let toolExecuted = false;
530
- const tool = createMockTool('blockedTool', () => {
531
- toolExecuted = true;
532
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
533
- });
534
- const model = new MockMessageModel()
535
- .addTurn({ type: 'toolUseBlock', name: 'blockedTool', toolUseId: 'tool-1', input: {} })
536
- .addTurn({ type: 'textBlock', text: 'Done' });
537
- const agent = new Agent({ model, tools: [tool], plugins: [mockPlugin] });
538
- agent.addHook(BeforeToolsEvent, (event) => {
539
- event.cancel = 'All tools blocked';
540
- });
541
- const result = await agent.invoke('Test');
542
- expect(result.stopReason).toBe('endTurn');
543
- expect(toolExecuted).toBe(false);
544
- const afterToolsEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolsEvent);
545
- expect(afterToolsEvents).toHaveLength(1);
546
- const afterEvent = afterToolsEvents[0];
547
- expect(afterEvent.message.content[0]).toEqual(new ToolResultBlock({
548
- toolUseId: 'tool-1',
549
- status: 'error',
550
- content: [new TextBlock('All tools blocked')],
551
- }));
552
- });
553
- it('cancels all tools in a batch via BeforeToolsEvent with correct toolUseIds', async () => {
554
- const executedTools = [];
555
- const tool1 = createMockTool('tool1', () => {
556
- executedTools.push('tool1');
557
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Result 1')] });
558
- });
559
- const tool2 = createMockTool('tool2', () => {
560
- executedTools.push('tool2');
561
- return new ToolResultBlock({ toolUseId: 'tool-2', status: 'success', content: [new TextBlock('Result 2')] });
562
- });
563
- const model = new MockMessageModel()
564
- .addTurn([
565
- { type: 'toolUseBlock', name: 'tool1', toolUseId: 'tool-1', input: {} },
566
- { type: 'toolUseBlock', name: 'tool2', toolUseId: 'tool-2', input: {} },
567
- ])
568
- .addTurn({ type: 'textBlock', text: 'Done' });
569
- const agent = new Agent({ model, tools: [tool1, tool2], plugins: [mockPlugin] });
570
- agent.addHook(BeforeToolsEvent, (event) => {
571
- event.cancel = 'Batch cancelled';
572
- });
573
- const result = await agent.invoke('Test');
574
- expect(result.stopReason).toBe('endTurn');
575
- expect(executedTools).toEqual([]);
576
- const afterToolsEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolsEvent);
577
- expect(afterToolsEvents).toHaveLength(1);
578
- const afterEvent = afterToolsEvents[0];
579
- expect(afterEvent.message.content).toEqual([
580
- new ToolResultBlock({
581
- toolUseId: 'tool-1',
582
- status: 'error',
583
- content: [new TextBlock('Batch cancelled')],
584
- }),
585
- new ToolResultBlock({
586
- toolUseId: 'tool-2',
587
- status: 'error',
588
- content: [new TextBlock('Batch cancelled')],
589
- }),
590
- ]);
591
- });
592
- it('emits cancel events correctly via stream()', async () => {
593
- let toolExecuted = false;
594
- const tool = createMockTool('blockedTool', () => {
595
- toolExecuted = true;
596
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
597
- });
598
- const model = new MockMessageModel()
599
- .addTurn({ type: 'toolUseBlock', name: 'blockedTool', toolUseId: 'tool-1', input: {} })
600
- .addTurn({ type: 'textBlock', text: 'Done' });
601
- const agent = new Agent({ model, tools: [tool] });
602
- agent.addHook(BeforeToolCallEvent, (event) => {
603
- event.cancel = 'Cancelled via stream';
604
- });
605
- const items = await collectIterator(agent.stream('Test'));
606
- expect(toolExecuted).toBe(false);
607
- const beforeToolCallEvents = items.filter((e) => e instanceof BeforeToolCallEvent);
608
- const afterToolCallEvents = items.filter((e) => e instanceof AfterToolCallEvent);
609
- expect(beforeToolCallEvents).toHaveLength(1);
610
- expect(afterToolCallEvents).toHaveLength(1);
611
- const afterEvent = afterToolCallEvents[0];
612
- expect(afterEvent.result).toEqual(new ToolResultBlock({
613
- toolUseId: 'tool-1',
614
- status: 'error',
615
- content: [new TextBlock('Cancelled via stream')],
616
- }));
617
- });
618
- it('allows retry after cancel on BeforeToolCallEvent', async () => {
619
- let toolCallCount = 0;
620
- const tool = createMockTool('retryTool', () => {
621
- toolCallCount++;
622
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Success')] });
623
- });
624
- let beforeCount = 0;
625
- const model = new MockMessageModel()
626
- .addTurn({ type: 'toolUseBlock', name: 'retryTool', toolUseId: 'tool-1', input: {} })
627
- .addTurn({ type: 'textBlock', text: 'Done' });
628
- const agent = new Agent({ model, tools: [tool] });
629
- agent.addHook(BeforeToolCallEvent, (event) => {
630
- beforeCount++;
631
- if (beforeCount === 1) {
632
- event.cancel = 'Not yet';
633
- }
634
- });
635
- agent.addHook(AfterToolCallEvent, (event) => {
636
- if (event.result.status === 'error' && beforeCount === 1) {
637
- event.retry = true;
638
- }
639
- });
640
- const result = await agent.invoke('Test');
641
- expect(result.stopReason).toBe('endTurn');
642
- expect(beforeCount).toBe(2);
643
- expect(toolCallCount).toBe(1); // Only executed on second attempt
644
- });
645
- it('allows hooks to replace result on AfterToolCallEvent', async () => {
646
- const tool = createMockTool('myTool', () => {
647
- return new ToolResultBlock({
648
- toolUseId: 'tool-1',
649
- status: 'success',
650
- content: [new TextBlock('original result')],
651
- });
652
- });
653
- const model = new MockMessageModel()
654
- .addTurn({ type: 'toolUseBlock', name: 'myTool', toolUseId: 'tool-1', input: {} })
655
- .addTurn({ type: 'textBlock', text: 'Done' });
656
- const agent = new Agent({ model, tools: [tool] });
657
- agent.addHook(AfterToolCallEvent, (event) => {
658
- event.result = new ToolResultBlock({
659
- toolUseId: event.result.toolUseId,
660
- status: 'success',
661
- content: [new TextBlock('replaced result')],
662
- });
663
- });
664
- await agent.invoke('Test');
665
- const toolResultMessage = agent.messages.find((m) => m.role === 'user' && m.content.some((b) => b.type === 'toolResultBlock'));
666
- const toolResultBlock = toolResultMessage.content.find((b) => b.type === 'toolResultBlock');
667
- expect(toolResultBlock).toStrictEqual(new ToolResultBlock({
668
- toolUseId: 'tool-1',
669
- status: 'success',
670
- content: [new TextBlock('replaced result')],
671
- }));
672
- });
673
- });
674
- describe('AfterToolsEvent.endTurn', () => {
675
- const makeSingleToolSetup = () => ({
676
- tool: createMockTool('myTool', () => {
677
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('result')] });
678
- }),
679
- model: new MockMessageModel()
680
- .addTurn({ type: 'toolUseBlock', name: 'myTool', toolUseId: 'tool-1', input: {} })
681
- .addTurn({ type: 'textBlock', text: 'Should not reach this' }),
682
- });
683
- it('halts the loop when endTurn is true with default message', async () => {
684
- const { tool, model } = makeSingleToolSetup();
685
- const agent = new Agent({ model, tools: [tool], plugins: [mockPlugin] });
686
- agent.addHook(AfterToolsEvent, (event) => {
687
- event.endTurn = true;
688
- });
689
- const result = await agent.invoke('Test');
690
- expect(result).toEqual(expect.objectContaining({
691
- type: 'agentResult',
692
- stopReason: 'endTurn',
693
- lastMessage: expect.objectContaining({
694
- role: 'assistant',
695
- content: expect.arrayContaining([
696
- expect.objectContaining({ type: 'textBlock', text: 'Turn ended early by hook after tool execution' }),
697
- ]),
698
- }),
699
- }));
700
- expect(model.callCount).toBe(1);
701
- });
702
- it('halts the loop with custom assistant message when endTurn is a string', async () => {
703
- const { tool, model } = makeSingleToolSetup();
704
- const agent = new Agent({ model, tools: [tool] });
705
- agent.addHook(AfterToolsEvent, (event) => {
706
- event.endTurn = 'enough information gathered';
707
- });
708
- const result = await agent.invoke('Test');
709
- expect(result).toEqual(expect.objectContaining({
710
- type: 'agentResult',
711
- stopReason: 'endTurn',
712
- lastMessage: expect.objectContaining({
713
- role: 'assistant',
714
- content: expect.arrayContaining([
715
- expect.objectContaining({ type: 'textBlock', text: 'enough information gathered' }),
716
- ]),
717
- }),
718
- }));
719
- expect(model.callCount).toBe(1);
720
- });
721
- it('does not halt when endTurn is false (default)', async () => {
722
- const { tool, model } = makeSingleToolSetup();
723
- const agent = new Agent({ model, tools: [tool] });
724
- const result = await agent.invoke('Test');
725
- expect(result).toEqual(expect.objectContaining({
726
- type: 'agentResult',
727
- stopReason: 'endTurn',
728
- lastMessage: expect.objectContaining({ role: 'assistant' }),
729
- }));
730
- expect(model.callCount).toBe(2);
731
- });
732
- it('treats empty string endTurn as falsy (does not halt)', async () => {
733
- const { tool, model } = makeSingleToolSetup();
734
- const agent = new Agent({ model, tools: [tool] });
735
- agent.addHook(AfterToolsEvent, (event) => {
736
- event.endTurn = '';
737
- });
738
- const result = await agent.invoke('Test');
739
- expect(result).toEqual(expect.objectContaining({
740
- type: 'agentResult',
741
- stopReason: 'endTurn',
742
- lastMessage: expect.objectContaining({ role: 'assistant' }),
743
- }));
744
- expect(model.callCount).toBe(2);
745
- });
746
- it('appends tool results and default endTurn message to conversation history', async () => {
747
- const { tool, model } = makeSingleToolSetup();
748
- const agent = new Agent({ model, tools: [tool] });
749
- agent.addHook(AfterToolsEvent, (event) => {
750
- event.endTurn = true;
751
- });
752
- await agent.invoke('Test');
753
- expect(agent.messages).toHaveLength(4);
754
- expect(agent.messages[0].role).toBe('user');
755
- expect(agent.messages[1].role).toBe('assistant');
756
- expect(agent.messages[1].content).toEqual(expect.arrayContaining([expect.objectContaining({ type: 'toolUseBlock' })]));
757
- expect(agent.messages[2].role).toBe('user');
758
- expect(agent.messages[2].content).toEqual(expect.arrayContaining([expect.objectContaining({ type: 'toolResultBlock' })]));
759
- expect(agent.messages[3].role).toBe('assistant');
760
- expect(agent.messages[3].content).toEqual(expect.arrayContaining([
761
- expect.objectContaining({ type: 'textBlock', text: 'Turn ended early by hook after tool execution' }),
762
- ]));
763
- });
764
- it('halts the loop with concurrent tool execution', async () => {
765
- const tool1 = createMockTool('tool1', () => {
766
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('Result 1')] });
767
- });
768
- const tool2 = createMockTool('tool2', () => {
769
- return new ToolResultBlock({ toolUseId: 'tool-2', status: 'success', content: [new TextBlock('Result 2')] });
770
- });
771
- const model = new MockMessageModel()
772
- .addTurn([
773
- { type: 'toolUseBlock', name: 'tool1', toolUseId: 'tool-1', input: {} },
774
- { type: 'toolUseBlock', name: 'tool2', toolUseId: 'tool-2', input: {} },
775
- ])
776
- .addTurn({ type: 'textBlock', text: 'Should not reach this' });
777
- const agent = new Agent({ model, tools: [tool1, tool2], toolExecutor: 'concurrent' });
778
- agent.addHook(AfterToolsEvent, (event) => {
779
- event.endTurn = true;
780
- });
781
- const result = await agent.invoke('Test');
782
- expect(result).toEqual(expect.objectContaining({
783
- type: 'agentResult',
784
- stopReason: 'endTurn',
785
- lastMessage: expect.objectContaining({ role: 'assistant' }),
786
- }));
787
- expect(model.callCount).toBe(1);
788
- });
789
- it('emits AfterToolsEvent with endTurn via stream()', async () => {
790
- const { tool, model } = makeSingleToolSetup();
791
- const agent = new Agent({ model, tools: [tool] });
792
- agent.addHook(AfterToolsEvent, (event) => {
793
- event.endTurn = true;
794
- });
795
- const items = await collectIterator(agent.stream('Test'));
796
- const afterToolsEvents = items.filter((e) => e instanceof AfterToolsEvent);
797
- expect(afterToolsEvents).toHaveLength(1);
798
- expect(afterToolsEvents[0].endTurn).toBe(true);
799
- const resultEvents = items.filter((e) => e instanceof AgentResultEvent);
800
- expect(resultEvents).toHaveLength(1);
801
- expect(resultEvents[0].result.stopReason).toBe('endTurn');
802
- });
803
- it('halts even when set on a cancelled-tools AfterToolsEvent', async () => {
804
- const { tool, model } = makeSingleToolSetup();
805
- const agent = new Agent({ model, tools: [tool] });
806
- agent.addHook(BeforeToolsEvent, (event) => {
807
- event.cancel = true;
808
- });
809
- agent.addHook(AfterToolsEvent, (event) => {
810
- event.endTurn = true;
811
- });
812
- const result = await agent.invoke('Test');
813
- expect(result).toEqual(expect.objectContaining({
814
- type: 'agentResult',
815
- stopReason: 'endTurn',
816
- lastMessage: expect.objectContaining({ role: 'assistant' }),
817
- }));
818
- expect(model.callCount).toBe(1);
819
- });
820
- });
821
- describe('cancel invocation via hooks', () => {
822
- it('cancels invocation with default message when cancel is true', async () => {
823
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
824
- const agent = new Agent({ model, plugins: [mockPlugin] });
825
- agent.addHook(BeforeInvocationEvent, (event) => {
826
- event.cancel = true;
827
- });
828
- const result = await agent.invoke('Test');
829
- expect(result.stopReason).toBe('endTurn');
830
- expect(result.lastMessage.content[0]).toEqual(new TextBlock('invocation denied by hook'));
831
- const beforeModelCallEvents = mockPlugin.invocations.filter((e) => e instanceof BeforeModelCallEvent);
832
- expect(beforeModelCallEvents).toHaveLength(0);
833
- });
834
- it('cancels invocation with custom message when cancel is a string', async () => {
835
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
836
- const agent = new Agent({ model, plugins: [mockPlugin] });
837
- agent.addHook(BeforeInvocationEvent, (event) => {
838
- event.cancel = 'Unauthorized user';
839
- });
840
- const result = await agent.invoke('Test');
841
- expect(result.stopReason).toBe('endTurn');
842
- expect(result.lastMessage.content[0]).toEqual(new TextBlock('Unauthorized user'));
843
- });
844
- it('does not append user message when invocation is cancelled', async () => {
845
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
846
- const agent = new Agent({ model });
847
- agent.addHook(BeforeInvocationEvent, (event) => {
848
- event.cancel = true;
849
- });
850
- await agent.invoke('Test');
851
- expect(agent.messages).toHaveLength(1);
852
- expect(agent.messages[0].role).toBe('assistant');
853
- });
854
- it('emits AfterInvocationEvent when invocation is cancelled', async () => {
855
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
856
- const agent = new Agent({ model, plugins: [mockPlugin] });
857
- agent.addHook(BeforeInvocationEvent, (event) => {
858
- event.cancel = true;
859
- });
860
- await agent.invoke('Test');
861
- const beforeInvocationEvents = mockPlugin.invocations.filter((e) => e instanceof BeforeInvocationEvent);
862
- const afterInvocationEvents = mockPlugin.invocations.filter((e) => e instanceof AfterInvocationEvent);
863
- expect(beforeInvocationEvents).toHaveLength(1);
864
- expect(afterInvocationEvents).toHaveLength(1);
865
- });
866
- });
867
- describe('cancel model call via hooks', () => {
868
- it('cancels model call with default message when cancel is true', async () => {
869
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
870
- const agent = new Agent({ model, plugins: [mockPlugin] });
871
- agent.addHook(BeforeModelCallEvent, (event) => {
872
- event.cancel = true;
873
- });
874
- const result = await agent.invoke('Test');
875
- expect(result.stopReason).toBe('endTurn');
876
- expect(result.lastMessage.content[0]).toEqual(new TextBlock('model call denied by hook'));
877
- });
878
- it('cancels model call with custom message when cancel is a string', async () => {
879
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
880
- const agent = new Agent({ model, plugins: [mockPlugin] });
881
- agent.addHook(BeforeModelCallEvent, (event) => {
882
- event.cancel = 'Rate limited';
883
- });
884
- const result = await agent.invoke('Test');
885
- expect(result.stopReason).toBe('endTurn');
886
- expect(result.lastMessage.content[0]).toEqual(new TextBlock('Rate limited'));
887
- });
888
- it('emits AfterModelCallEvent when model call is cancelled', async () => {
889
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
890
- const agent = new Agent({ model, plugins: [mockPlugin] });
891
- agent.addHook(BeforeModelCallEvent, (event) => {
892
- event.cancel = true;
893
- });
894
- await agent.invoke('Test');
895
- const beforeModelCallEvents = mockPlugin.invocations.filter((e) => e instanceof BeforeModelCallEvent);
896
- const afterModelCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterModelCallEvent);
897
- expect(beforeModelCallEvents).toHaveLength(1);
898
- expect(afterModelCallEvents).toHaveLength(1);
899
- });
900
- it('does not emit ModelMessageEvent when model call is cancelled', async () => {
901
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
902
- const agent = new Agent({ model, plugins: [mockPlugin] });
903
- agent.addHook(BeforeModelCallEvent, (event) => {
904
- event.cancel = true;
905
- });
906
- await agent.invoke('Test');
907
- const modelMessageEvents = mockPlugin.invocations.filter((e) => e instanceof ModelMessageEvent);
908
- expect(modelMessageEvents).toHaveLength(0);
909
- });
910
- it('allows retry after cancel on model call', async () => {
911
- let beforeCount = 0;
912
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
913
- const agent = new Agent({ model, plugins: [mockPlugin] });
914
- agent.addHook(BeforeModelCallEvent, (event) => {
915
- beforeCount++;
916
- if (beforeCount === 1) {
917
- event.cancel = 'Not yet';
918
- }
919
- });
920
- agent.addHook(AfterModelCallEvent, (event) => {
921
- if (beforeCount === 1) {
922
- event.retry = true;
923
- }
924
- });
925
- const result = await agent.invoke('Test');
926
- expect(result.stopReason).toBe('endTurn');
927
- expect(beforeCount).toBe(2);
928
- expect(result.lastMessage.content[0]).toEqual(new TextBlock('Hello'));
929
- });
930
- });
931
- describe('BeforeToolCallEvent selectedTool', () => {
932
- it('invokes the replacement tool instead of the registry tool', async () => {
933
- let originalExecuted = false;
934
- let replacementExecuted = false;
935
- const originalTool = createMockTool('originalTool', () => {
936
- originalExecuted = true;
937
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('original')] });
938
- });
939
- const replacementTool = createMockTool('replacementTool', () => {
940
- replacementExecuted = true;
941
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('replacement')] });
942
- });
943
- const model = new MockMessageModel()
944
- .addTurn({ type: 'toolUseBlock', name: 'originalTool', toolUseId: 'tool-1', input: {} })
945
- .addTurn({ type: 'textBlock', text: 'Done' });
946
- const agent = new Agent({ model, tools: [originalTool], plugins: [mockPlugin] });
947
- agent.addHook(BeforeToolCallEvent, (event) => {
948
- event.selectedTool = replacementTool;
949
- });
950
- await agent.invoke('Test');
951
- expect(originalExecuted).toBe(false);
952
- expect(replacementExecuted).toBe(true);
953
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
954
- expect(afterToolCallEvents).toHaveLength(1);
955
- expect(afterToolCallEvents[0].result.content).toEqual([new TextBlock('replacement')]);
956
- });
957
- it('cancel wins over selectedTool', async () => {
958
- let replacementExecuted = false;
959
- const replacementTool = createMockTool('replacementTool', () => {
960
- replacementExecuted = true;
961
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('replacement')] });
962
- });
963
- const registryTool = createMockTool('registryTool', () => {
964
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('registry')] });
965
- });
966
- const model = new MockMessageModel()
967
- .addTurn({ type: 'toolUseBlock', name: 'registryTool', toolUseId: 'tool-1', input: {} })
968
- .addTurn({ type: 'textBlock', text: 'Done' });
969
- const agent = new Agent({ model, tools: [registryTool], plugins: [mockPlugin] });
970
- agent.addHook(BeforeToolCallEvent, (event) => {
971
- event.selectedTool = replacementTool;
972
- event.cancel = 'blocked';
973
- });
974
- await agent.invoke('Test');
975
- expect(replacementExecuted).toBe(false);
976
- // AfterToolCallEvent.tool should report the selectedTool even on the cancel path,
977
- // so observability hooks see a consistent `tool` value regardless of branch.
978
- const afterToolCallEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolCallEvent);
979
- expect(afterToolCallEvents).toHaveLength(1);
980
- expect(afterToolCallEvents[0].tool).toBe(replacementTool);
981
- });
982
- it('works with concurrent tool executor', async () => {
983
- let originalExecuted = false;
984
- let replacementExecuted = false;
985
- const originalTool = createMockTool('originalTool', () => {
986
- originalExecuted = true;
987
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('original')] });
988
- });
989
- const replacementTool = createMockTool('replacementTool', () => {
990
- replacementExecuted = true;
991
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('replacement')] });
992
- });
993
- const otherTool = createMockTool('otherTool', () => {
994
- return new ToolResultBlock({ toolUseId: 'tool-2', status: 'success', content: [new TextBlock('other')] });
995
- });
996
- const model = new MockMessageModel()
997
- .addTurn([
998
- { type: 'toolUseBlock', name: 'originalTool', toolUseId: 'tool-1', input: {} },
999
- { type: 'toolUseBlock', name: 'otherTool', toolUseId: 'tool-2', input: {} },
1000
- ])
1001
- .addTurn({ type: 'textBlock', text: 'Done' });
1002
- const agent = new Agent({
1003
- model,
1004
- tools: [originalTool, otherTool],
1005
- toolExecutor: 'concurrent',
1006
- });
1007
- agent.addHook(BeforeToolCallEvent, (event) => {
1008
- if (event.toolUse.name === 'originalTool') {
1009
- event.selectedTool = replacementTool;
1010
- }
1011
- });
1012
- await agent.invoke('Test');
1013
- expect(originalExecuted).toBe(false);
1014
- expect(replacementExecuted).toBe(true);
1015
- });
1016
- });
1017
- describe('BeforeToolCallEvent toolUse mutation', () => {
1018
- it('passes mutated input to the tool', async () => {
1019
- const capturedInputs = [];
1020
- const tool = createMockTool('tool', () => {
1021
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('ok')] });
1022
- });
1023
- // Wrap to capture input via the context the tool receives.
1024
- const capturingTool = {
1025
- ...tool,
1026
- async *stream(context) {
1027
- capturedInputs.push(context.toolUse.input);
1028
- return yield* tool.stream(context);
1029
- },
1030
- };
1031
- const model = new MockMessageModel()
1032
- .addTurn({ type: 'toolUseBlock', name: 'tool', toolUseId: 'tool-1', input: { a: 1 } })
1033
- .addTurn({ type: 'textBlock', text: 'Done' });
1034
- const agent = new Agent({ model, tools: [capturingTool] });
1035
- agent.addHook(BeforeToolCallEvent, (event) => {
1036
- event.toolUse.input = { a: 2, injected: true };
1037
- });
1038
- await agent.invoke('Test');
1039
- expect(capturedInputs).toEqual([{ a: 2, injected: true }]);
1040
- });
1041
- it('re-resolves the tool when hook renames toolUse.name', async () => {
1042
- let origExecuted = false;
1043
- let renamedExecuted = false;
1044
- const origTool = createMockTool('orig', () => {
1045
- origExecuted = true;
1046
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('orig')] });
1047
- });
1048
- const renamedTool = createMockTool('renamed', () => {
1049
- renamedExecuted = true;
1050
- return new ToolResultBlock({ toolUseId: 'tool-1', status: 'success', content: [new TextBlock('renamed')] });
1051
- });
1052
- const model = new MockMessageModel()
1053
- .addTurn({ type: 'toolUseBlock', name: 'orig', toolUseId: 'tool-1', input: {} })
1054
- .addTurn({ type: 'textBlock', text: 'Done' });
1055
- const agent = new Agent({ model, tools: [origTool, renamedTool] });
1056
- agent.addHook(BeforeToolCallEvent, (event) => {
1057
- event.toolUse.name = 'renamed';
1058
- });
1059
- await agent.invoke('Test');
1060
- expect(origExecuted).toBe(false);
1061
- expect(renamedExecuted).toBe(true);
1062
- });
1063
- it('works with concurrent tool executor', async () => {
1064
- const capturedInputs = {};
1065
- const baseA = createMockTool('toolA', () => {
1066
- return new ToolResultBlock({ toolUseId: 'a', status: 'success', content: [new TextBlock('a done')] });
1067
- });
1068
- const baseB = createMockTool('toolB', () => {
1069
- return new ToolResultBlock({ toolUseId: 'b', status: 'success', content: [new TextBlock('b done')] });
1070
- });
1071
- const toolA = {
1072
- ...baseA,
1073
- async *stream(context) {
1074
- capturedInputs[context.toolUse.name] = context.toolUse.input;
1075
- return yield* baseA.stream(context);
1076
- },
1077
- };
1078
- const toolB = {
1079
- ...baseB,
1080
- async *stream(context) {
1081
- capturedInputs[context.toolUse.name] = context.toolUse.input;
1082
- return yield* baseB.stream(context);
1083
- },
1084
- };
1085
- const model = new MockMessageModel()
1086
- .addTurn([
1087
- { type: 'toolUseBlock', name: 'toolA', toolUseId: 'a', input: { original: 'a' } },
1088
- { type: 'toolUseBlock', name: 'toolB', toolUseId: 'b', input: { original: 'b' } },
1089
- ])
1090
- .addTurn({ type: 'textBlock', text: 'Done' });
1091
- const agent = new Agent({ model, tools: [toolA, toolB], toolExecutor: 'concurrent' });
1092
- agent.addHook(BeforeToolCallEvent, (event) => {
1093
- event.toolUse.input = { mutated: event.toolUse.name };
1094
- });
1095
- await agent.invoke('Test');
1096
- expect(capturedInputs).toEqual({
1097
- toolA: { mutated: 'toolA' },
1098
- toolB: { mutated: 'toolB' },
1099
- });
1100
- });
1101
- });
1102
- describe('AfterToolCallEvent result mutation', () => {
1103
- it('propagates mutated result into the conversation message', async () => {
1104
- const tool = createMockTool('tool', () => {
1105
- return new ToolResultBlock({
1106
- toolUseId: 'tool-1',
1107
- status: 'success',
1108
- content: [new TextBlock('SECRET_VALUE')],
1109
- });
1110
- });
1111
- const model = new MockMessageModel()
1112
- .addTurn({ type: 'toolUseBlock', name: 'tool', toolUseId: 'tool-1', input: {} })
1113
- .addTurn({ type: 'textBlock', text: 'Done' });
1114
- const agent = new Agent({ model, tools: [tool] });
1115
- agent.addHook(AfterToolCallEvent, (event) => {
1116
- event.result = new ToolResultBlock({
1117
- toolUseId: 'tool-1',
1118
- status: 'success',
1119
- content: [new TextBlock('[REDACTED]')],
1120
- });
1121
- });
1122
- await agent.invoke('Test');
1123
- const toolResultMessage = agent.messages.find((m) => m.content.some((b) => b.type === 'toolResultBlock' && b.toolUseId === 'tool-1'));
1124
- expect(toolResultMessage).toBeDefined();
1125
- const block = toolResultMessage.content.find((b) => b.type === 'toolResultBlock' && b.toolUseId === 'tool-1');
1126
- expect(block.content).toEqual([new TextBlock('[REDACTED]')]);
1127
- });
1128
- it('propagates mutated result into AfterToolsEvent', async () => {
1129
- const tool = createMockTool('tool', () => {
1130
- return new ToolResultBlock({
1131
- toolUseId: 'tool-1',
1132
- status: 'success',
1133
- content: [new TextBlock('SECRET_VALUE')],
1134
- });
1135
- });
1136
- const model = new MockMessageModel()
1137
- .addTurn({ type: 'toolUseBlock', name: 'tool', toolUseId: 'tool-1', input: {} })
1138
- .addTurn({ type: 'textBlock', text: 'Done' });
1139
- const agent = new Agent({ model, tools: [tool], plugins: [mockPlugin] });
1140
- agent.addHook(AfterToolCallEvent, (event) => {
1141
- event.result = new ToolResultBlock({
1142
- toolUseId: 'tool-1',
1143
- status: 'success',
1144
- content: [new TextBlock('[REDACTED]')],
1145
- });
1146
- });
1147
- await agent.invoke('Test');
1148
- const afterToolsEvents = mockPlugin.invocations.filter((e) => e instanceof AfterToolsEvent);
1149
- expect(afterToolsEvents).toHaveLength(1);
1150
- const block = afterToolsEvents[0].message.content.find((b) => b.type === 'toolResultBlock' && b.toolUseId === 'tool-1');
1151
- expect(block.content).toEqual([new TextBlock('[REDACTED]')]);
1152
- });
1153
- });
1154
- describe('AfterInvocationEvent resume', () => {
1155
- it('re-invokes the agent with the resume args', async () => {
1156
- const model = new MockMessageModel()
1157
- .addTurn({ type: 'textBlock', text: 'first' })
1158
- .addTurn({ type: 'textBlock', text: 'second' });
1159
- let invocationCount = 0;
1160
- const agent = new Agent({ model });
1161
- agent.addHook(AfterInvocationEvent, (event) => {
1162
- invocationCount++;
1163
- if (invocationCount === 1) {
1164
- event.resume = 'follow-up';
1165
- }
1166
- });
1167
- const result = await agent.invoke('initial');
1168
- expect(invocationCount).toBe(2);
1169
- expect(result).toEqual(expectAgentResult({
1170
- stopReason: 'endTurn',
1171
- messageText: 'second',
1172
- // Meter cycleCount is cumulative across the resume chain (1 cycle per invocation x 2).
1173
- cycleCount: 2,
1174
- }));
1175
- });
1176
- it('chains multiple resumes', async () => {
1177
- const model = new MockMessageModel()
1178
- .addTurn({ type: 'textBlock', text: 'a' })
1179
- .addTurn({ type: 'textBlock', text: 'b' })
1180
- .addTurn({ type: 'textBlock', text: 'c' });
1181
- let invocationCount = 0;
1182
- const agent = new Agent({ model });
1183
- agent.addHook(AfterInvocationEvent, (event) => {
1184
- invocationCount++;
1185
- if (invocationCount === 1)
1186
- event.resume = 'second';
1187
- else if (invocationCount === 2)
1188
- event.resume = 'third';
1189
- });
1190
- const result = await agent.invoke('first');
1191
- expect(invocationCount).toBe(3);
1192
- expect(result.lastMessage.content[0]).toEqual({ type: 'textBlock', text: 'c' });
1193
- });
1194
- it('does not resume when resume is left undefined', async () => {
1195
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'only' });
1196
- let invocationCount = 0;
1197
- const agent = new Agent({ model });
1198
- agent.addHook(AfterInvocationEvent, () => {
1199
- invocationCount++;
1200
- });
1201
- await agent.invoke('hi');
1202
- expect(invocationCount).toBe(1);
1203
- });
1204
- it('does not resume when the invocation errors', async () => {
1205
- const model = new MockMessageModel().addTurn(new Error('boom'));
1206
- let invocationCount = 0;
1207
- const agent = new Agent({ model });
1208
- agent.addHook(AfterInvocationEvent, (event) => {
1209
- invocationCount++;
1210
- event.resume = 'should-not-run';
1211
- });
1212
- await expect(agent.invoke('hi')).rejects.toThrow('boom');
1213
- expect(invocationCount).toBe(1);
1214
- });
1215
- it('first-registered hook wins when multiple hooks set resume', async () => {
1216
- // AfterInvocationEvent reverses callback order (_shouldReverseCallbacks=true),
1217
- // so the first-registered hook fires last and its resume value wins.
1218
- const model = new MockMessageModel()
1219
- .addTurn({ type: 'textBlock', text: 'first' })
1220
- .addTurn({ type: 'textBlock', text: 'second' });
1221
- let invocationCount = 0;
1222
- const agent = new Agent({ model });
1223
- agent.addHook(BeforeInvocationEvent, () => {
1224
- invocationCount++;
1225
- });
1226
- agent.addHook(AfterInvocationEvent, (event) => {
1227
- if (invocationCount === 1)
1228
- event.resume = 'first-registered wins';
1229
- });
1230
- agent.addHook(AfterInvocationEvent, (event) => {
1231
- if (invocationCount === 1)
1232
- event.resume = 'second-registered loses';
1233
- });
1234
- await agent.invoke('initial');
1235
- const userTexts = agent.messages
1236
- .filter((m) => m.role === 'user')
1237
- .flatMap((m) => m.content.filter((b) => b.type === 'textBlock').map((b) => b.text));
1238
- expect(userTexts).toEqual(['initial', 'first-registered wins']);
1239
- });
1240
- it('ignores resume set during an erroring invocation', async () => {
1241
- // Resume should not fire when the invocation ends with an error, even if
1242
- // AfterInvocationEvent (which fires in _stream's finally) still runs.
1243
- const model = new MockMessageModel().addTurn(new Error('boom'));
1244
- let resumeFired = false;
1245
- const agent = new Agent({ model });
1246
- agent.addHook(AfterInvocationEvent, (event) => {
1247
- event.resume = 'should not run';
1248
- });
1249
- agent.addHook(BeforeInvocationEvent, () => {
1250
- // Track whether BeforeInvocationEvent fires a second time (would indicate resume ran).
1251
- if (resumeFired)
1252
- throw new Error('unexpected second invocation');
1253
- resumeFired = true;
1254
- });
1255
- await expect(agent.invoke('hi')).rejects.toThrow('boom');
1256
- });
1257
- it('emits only one AgentResultEvent for a resumed chain', async () => {
1258
- const model = new MockMessageModel()
1259
- .addTurn({ type: 'textBlock', text: 'first' })
1260
- .addTurn({ type: 'textBlock', text: 'second' });
1261
- let invocationCount = 0;
1262
- const agent = new Agent({ model });
1263
- agent.addHook(AfterInvocationEvent, (event) => {
1264
- invocationCount++;
1265
- if (invocationCount === 1) {
1266
- event.resume = 'follow-up';
1267
- }
1268
- });
1269
- const items = await collectIterator(agent.stream('initial'));
1270
- const agentResults = items.filter((e) => e instanceof AgentResultEvent);
1271
- expect(agentResults).toHaveLength(1);
1272
- const afterInvocations = items.filter((e) => e instanceof AfterInvocationEvent);
1273
- expect(afterInvocations).toHaveLength(2);
1274
- });
1275
- });
1276
- describe('queue-based lifecycle plugin (WASM bridge pattern)', () => {
1277
- function createLifecycleBridgePlugin(queue) {
1278
- return {
1279
- name: 'strands:lifecycle-bridge',
1280
- initAgent(agent) {
1281
- agent.addHook(InitializedEvent, () => {
1282
- queue.push('initialized');
1283
- });
1284
- agent.addHook(BeforeInvocationEvent, () => {
1285
- queue.push('before-invocation');
1286
- });
1287
- agent.addHook(AfterInvocationEvent, () => {
1288
- queue.push('after-invocation');
1289
- });
1290
- agent.addHook(BeforeModelCallEvent, () => {
1291
- queue.push('before-model-call');
1292
- });
1293
- agent.addHook(AfterModelCallEvent, () => {
1294
- queue.push('after-model-call');
1295
- });
1296
- agent.addHook(MessageAddedEvent, () => {
1297
- queue.push('message-added');
1298
- });
1299
- agent.addHook(BeforeToolCallEvent, () => {
1300
- queue.push('before-tool-call');
1301
- });
1302
- agent.addHook(AfterToolCallEvent, () => {
1303
- queue.push('after-tool-call');
1304
- });
1305
- },
1306
- };
1307
- }
1308
- it('receives lifecycle events when registered via plugins config', async () => {
1309
- const queue = [];
1310
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
1311
- const agent = new Agent({ model, plugins: [createLifecycleBridgePlugin(queue)] });
1312
- await agent.invoke('Hi');
1313
- expect(queue).toStrictEqual([
1314
- 'initialized',
1315
- 'before-invocation',
1316
- 'message-added',
1317
- 'before-model-call',
1318
- 'after-model-call',
1319
- 'message-added',
1320
- 'after-invocation',
1321
- ]);
1322
- });
1323
- it('receives no events when passed via non-existent hooks config field', async () => {
1324
- const queue = [];
1325
- const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
1326
- const agent = new Agent({ model, hooks: [createLifecycleBridgePlugin(queue)] });
1327
- await agent.invoke('Hi');
1328
- expect(queue).toHaveLength(0);
1329
- });
1330
- });
1331
- });
1332
- //# sourceMappingURL=agent.hook.test.js.map