@strands-agents/sdk 1.7.0 → 1.9.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 (686) hide show
  1. package/dist/src/agent/agent.d.ts +32 -2
  2. package/dist/src/agent/agent.d.ts.map +1 -1
  3. package/dist/src/agent/agent.js +92 -4
  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/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
  8. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +2 -0
  9. package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
  10. package/dist/src/errors.d.ts +7 -0
  11. package/dist/src/errors.d.ts.map +1 -1
  12. package/dist/src/errors.js +10 -0
  13. package/dist/src/errors.js.map +1 -1
  14. package/dist/src/experimental/checkpoint.d.ts +118 -0
  15. package/dist/src/experimental/checkpoint.d.ts.map +1 -0
  16. package/dist/src/experimental/checkpoint.js +108 -0
  17. package/dist/src/experimental/checkpoint.js.map +1 -0
  18. package/dist/src/experimental/index.d.ts +10 -0
  19. package/dist/src/experimental/index.d.ts.map +1 -0
  20. package/dist/src/experimental/index.js +9 -0
  21. package/dist/src/experimental/index.js.map +1 -0
  22. package/dist/src/index.d.ts +1 -1
  23. package/dist/src/index.d.ts.map +1 -1
  24. package/dist/src/index.js +1 -1
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/index.node.d.ts.map +1 -1
  27. package/dist/src/index.node.js +3 -0
  28. package/dist/src/index.node.js.map +1 -1
  29. package/dist/src/injection/message-injection.d.ts.map +1 -1
  30. package/dist/src/injection/message-injection.js +2 -0
  31. package/dist/src/injection/message-injection.js.map +1 -1
  32. package/dist/src/interventions/actions.d.ts.map +1 -1
  33. package/dist/src/interventions/actions.js.map +1 -1
  34. package/dist/src/{mcp.d.ts → mcp/client.d.ts} +13 -4
  35. package/dist/src/mcp/client.d.ts.map +1 -0
  36. package/dist/src/{mcp.js → mcp/client.js} +15 -3
  37. package/dist/src/mcp/client.js.map +1 -0
  38. package/dist/src/mcp/config.d.ts +52 -0
  39. package/dist/src/mcp/config.d.ts.map +1 -0
  40. package/dist/src/mcp/config.js +12 -0
  41. package/dist/src/mcp/config.js.map +1 -0
  42. package/dist/src/mcp/config.node.d.ts +16 -0
  43. package/dist/src/mcp/config.node.d.ts.map +1 -0
  44. package/dist/src/mcp/config.node.js +145 -0
  45. package/dist/src/mcp/config.node.js.map +1 -0
  46. package/dist/src/mcp/index.d.ts +3 -0
  47. package/dist/src/mcp/index.d.ts.map +1 -0
  48. package/dist/src/mcp/index.js +2 -0
  49. package/dist/src/mcp/index.js.map +1 -0
  50. package/dist/src/models/model.d.ts.map +1 -1
  51. package/dist/src/models/model.js +2 -1
  52. package/dist/src/models/model.js.map +1 -1
  53. package/dist/src/multiagent/graph.d.ts +7 -0
  54. package/dist/src/multiagent/graph.d.ts.map +1 -1
  55. package/dist/src/multiagent/graph.js +22 -1
  56. package/dist/src/multiagent/graph.js.map +1 -1
  57. package/dist/src/multiagent/multiagent.d.ts +2 -1
  58. package/dist/src/multiagent/multiagent.d.ts.map +1 -1
  59. package/dist/src/multiagent/multiagent.js.map +1 -1
  60. package/dist/src/multiagent/nodes.d.ts +5 -0
  61. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  62. package/dist/src/multiagent/nodes.js +15 -0
  63. package/dist/src/multiagent/nodes.js.map +1 -1
  64. package/dist/src/multiagent/state.d.ts.map +1 -1
  65. package/dist/src/multiagent/state.js.map +1 -1
  66. package/dist/src/tools/function-tool.d.ts +1 -1
  67. package/dist/src/tools/function-tool.d.ts.map +1 -1
  68. package/dist/src/tools/function-tool.js +4 -12
  69. package/dist/src/tools/function-tool.js.map +1 -1
  70. package/dist/src/tools/mcp-tool.d.ts +2 -1
  71. package/dist/src/tools/mcp-tool.d.ts.map +1 -1
  72. package/dist/src/tools/mcp-tool.js +1 -0
  73. package/dist/src/tools/mcp-tool.js.map +1 -1
  74. package/dist/src/tools/tool-factory.d.ts +1 -1
  75. package/dist/src/tools/tool-factory.d.ts.map +1 -1
  76. package/dist/src/tools/types.d.ts +4 -0
  77. package/dist/src/tools/types.d.ts.map +1 -1
  78. package/dist/src/tools/zod-tool.d.ts +4 -2
  79. package/dist/src/tools/zod-tool.d.ts.map +1 -1
  80. package/dist/src/tools/zod-tool.js.map +1 -1
  81. package/dist/src/tsconfig.tsbuildinfo +1 -1
  82. package/dist/src/types/agent.d.ts +18 -1
  83. package/dist/src/types/agent.d.ts.map +1 -1
  84. package/dist/src/types/agent.js +12 -0
  85. package/dist/src/types/agent.js.map +1 -1
  86. package/dist/src/types/media.d.ts.map +1 -1
  87. package/dist/src/types/media.js.map +1 -1
  88. package/dist/src/types/messages.d.ts +22 -1
  89. package/dist/src/types/messages.d.ts.map +1 -1
  90. package/dist/src/types/messages.js +22 -0
  91. package/dist/src/types/messages.js.map +1 -1
  92. package/dist/src/vended-memory-stores/test-memory-store/index.d.ts +2 -0
  93. package/dist/src/vended-memory-stores/test-memory-store/index.d.ts.map +1 -0
  94. package/dist/src/vended-memory-stores/test-memory-store/index.js +2 -0
  95. package/dist/src/vended-memory-stores/test-memory-store/index.js.map +1 -0
  96. package/dist/src/vended-memory-stores/test-memory-store/store.d.ts +122 -0
  97. package/dist/src/vended-memory-stores/test-memory-store/store.d.ts.map +1 -0
  98. package/dist/src/vended-memory-stores/test-memory-store/store.js +281 -0
  99. package/dist/src/vended-memory-stores/test-memory-store/store.js.map +1 -0
  100. package/dist/src/vended-plugins/context-offloader/search.d.ts.map +1 -1
  101. package/dist/src/vended-plugins/context-offloader/search.js +4 -2
  102. package/dist/src/vended-plugins/context-offloader/search.js.map +1 -1
  103. package/dist/src/vended-plugins/context-offloader/storage.js +1 -1
  104. package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
  105. package/dist/src/vended-plugins/skills/skill.d.ts.map +1 -1
  106. package/dist/src/vended-plugins/skills/skill.js.map +1 -1
  107. package/dist/src/vended-tools/notebook/notebook.d.ts +1 -1
  108. package/package.json +41 -30
  109. package/dist/src/__fixtures__/agent-helpers.d.ts +0 -136
  110. package/dist/src/__fixtures__/agent-helpers.d.ts.map +0 -1
  111. package/dist/src/__fixtures__/agent-helpers.js +0 -156
  112. package/dist/src/__fixtures__/agent-helpers.js.map +0 -1
  113. package/dist/src/__fixtures__/environment.d.ts +0 -12
  114. package/dist/src/__fixtures__/environment.d.ts.map +0 -1
  115. package/dist/src/__fixtures__/environment.js +0 -12
  116. package/dist/src/__fixtures__/environment.js.map +0 -1
  117. package/dist/src/__fixtures__/metrics-helpers.d.ts +0 -55
  118. package/dist/src/__fixtures__/metrics-helpers.d.ts.map +0 -1
  119. package/dist/src/__fixtures__/metrics-helpers.js +0 -57
  120. package/dist/src/__fixtures__/metrics-helpers.js.map +0 -1
  121. package/dist/src/__fixtures__/mock-message-model.d.ts +0 -103
  122. package/dist/src/__fixtures__/mock-message-model.d.ts.map +0 -1
  123. package/dist/src/__fixtures__/mock-message-model.js +0 -245
  124. package/dist/src/__fixtures__/mock-message-model.js.map +0 -1
  125. package/dist/src/__fixtures__/mock-meter.d.ts +0 -32
  126. package/dist/src/__fixtures__/mock-meter.d.ts.map +0 -1
  127. package/dist/src/__fixtures__/mock-meter.js +0 -47
  128. package/dist/src/__fixtures__/mock-meter.js.map +0 -1
  129. package/dist/src/__fixtures__/mock-plugin.d.ts +0 -13
  130. package/dist/src/__fixtures__/mock-plugin.d.ts.map +0 -1
  131. package/dist/src/__fixtures__/mock-plugin.js +0 -35
  132. package/dist/src/__fixtures__/mock-plugin.js.map +0 -1
  133. package/dist/src/__fixtures__/mock-span.d.ts +0 -78
  134. package/dist/src/__fixtures__/mock-span.d.ts.map +0 -1
  135. package/dist/src/__fixtures__/mock-span.js +0 -93
  136. package/dist/src/__fixtures__/mock-span.js.map +0 -1
  137. package/dist/src/__fixtures__/mock-storage-provider.d.ts +0 -42
  138. package/dist/src/__fixtures__/mock-storage-provider.d.ts.map +0 -1
  139. package/dist/src/__fixtures__/mock-storage-provider.js +0 -122
  140. package/dist/src/__fixtures__/mock-storage-provider.js.map +0 -1
  141. package/dist/src/__fixtures__/model-test-helpers.d.ts +0 -56
  142. package/dist/src/__fixtures__/model-test-helpers.d.ts.map +0 -1
  143. package/dist/src/__fixtures__/model-test-helpers.js +0 -85
  144. package/dist/src/__fixtures__/model-test-helpers.js.map +0 -1
  145. package/dist/src/__fixtures__/register-node-defaults.d.ts +0 -2
  146. package/dist/src/__fixtures__/register-node-defaults.d.ts.map +0 -1
  147. package/dist/src/__fixtures__/register-node-defaults.js +0 -6
  148. package/dist/src/__fixtures__/register-node-defaults.js.map +0 -1
  149. package/dist/src/__fixtures__/slim-types.d.ts +0 -51
  150. package/dist/src/__fixtures__/slim-types.d.ts.map +0 -1
  151. package/dist/src/__fixtures__/slim-types.js +0 -6
  152. package/dist/src/__fixtures__/slim-types.js.map +0 -1
  153. package/dist/src/__fixtures__/test-sandbox.node.d.ts +0 -15
  154. package/dist/src/__fixtures__/test-sandbox.node.d.ts.map +0 -1
  155. package/dist/src/__fixtures__/test-sandbox.node.js +0 -23
  156. package/dist/src/__fixtures__/test-sandbox.node.js.map +0 -1
  157. package/dist/src/__fixtures__/tool-helpers.d.ts +0 -45
  158. package/dist/src/__fixtures__/tool-helpers.d.ts.map +0 -1
  159. package/dist/src/__fixtures__/tool-helpers.js +0 -101
  160. package/dist/src/__fixtures__/tool-helpers.js.map +0 -1
  161. package/dist/src/__tests__/default-slot.test.d.ts +0 -2
  162. package/dist/src/__tests__/default-slot.test.d.ts.map +0 -1
  163. package/dist/src/__tests__/default-slot.test.js +0 -33
  164. package/dist/src/__tests__/default-slot.test.js.map +0 -1
  165. package/dist/src/__tests__/errors.test.d.ts +0 -2
  166. package/dist/src/__tests__/errors.test.d.ts.map +0 -1
  167. package/dist/src/__tests__/errors.test.js +0 -170
  168. package/dist/src/__tests__/errors.test.js.map +0 -1
  169. package/dist/src/__tests__/index.test.d.ts +0 -2
  170. package/dist/src/__tests__/index.test.d.ts.map +0 -1
  171. package/dist/src/__tests__/index.test.js +0 -48
  172. package/dist/src/__tests__/index.test.js.map +0 -1
  173. package/dist/src/__tests__/interrupt.test.d.ts +0 -2
  174. package/dist/src/__tests__/interrupt.test.d.ts.map +0 -1
  175. package/dist/src/__tests__/interrupt.test.js +0 -264
  176. package/dist/src/__tests__/interrupt.test.js.map +0 -1
  177. package/dist/src/__tests__/mcp.test.d.ts +0 -2
  178. package/dist/src/__tests__/mcp.test.d.ts.map +0 -1
  179. package/dist/src/__tests__/mcp.test.js +0 -1003
  180. package/dist/src/__tests__/mcp.test.js.map +0 -1
  181. package/dist/src/__tests__/mime.test.d.ts +0 -2
  182. package/dist/src/__tests__/mime.test.d.ts.map +0 -1
  183. package/dist/src/__tests__/mime.test.js +0 -83
  184. package/dist/src/__tests__/mime.test.js.map +0 -1
  185. package/dist/src/__tests__/state-store.test.d.ts +0 -2
  186. package/dist/src/__tests__/state-store.test.d.ts.map +0 -1
  187. package/dist/src/__tests__/state-store.test.js +0 -285
  188. package/dist/src/__tests__/state-store.test.js.map +0 -1
  189. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts +0 -2
  190. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts.map +0 -1
  191. package/dist/src/a2a/__tests__/a2a-agent.test.js +0 -383
  192. package/dist/src/a2a/__tests__/a2a-agent.test.js.map +0 -1
  193. package/dist/src/a2a/__tests__/adapters.test.d.ts +0 -2
  194. package/dist/src/a2a/__tests__/adapters.test.d.ts.map +0 -1
  195. package/dist/src/a2a/__tests__/adapters.test.js +0 -151
  196. package/dist/src/a2a/__tests__/adapters.test.js.map +0 -1
  197. package/dist/src/a2a/__tests__/async-lock.test.d.ts +0 -2
  198. package/dist/src/a2a/__tests__/async-lock.test.d.ts.map +0 -1
  199. package/dist/src/a2a/__tests__/async-lock.test.js +0 -137
  200. package/dist/src/a2a/__tests__/async-lock.test.js.map +0 -1
  201. package/dist/src/a2a/__tests__/events.test.d.ts +0 -2
  202. package/dist/src/a2a/__tests__/events.test.d.ts.map +0 -1
  203. package/dist/src/a2a/__tests__/events.test.js +0 -68
  204. package/dist/src/a2a/__tests__/events.test.js.map +0 -1
  205. package/dist/src/a2a/__tests__/executor.test.d.ts +0 -2
  206. package/dist/src/a2a/__tests__/executor.test.d.ts.map +0 -1
  207. package/dist/src/a2a/__tests__/executor.test.js +0 -345
  208. package/dist/src/a2a/__tests__/executor.test.js.map +0 -1
  209. package/dist/src/a2a/__tests__/server.test.d.ts +0 -2
  210. package/dist/src/a2a/__tests__/server.test.d.ts.map +0 -1
  211. package/dist/src/a2a/__tests__/server.test.js +0 -71
  212. package/dist/src/a2a/__tests__/server.test.js.map +0 -1
  213. package/dist/src/a2a/__tests__/server.test.node.d.ts +0 -2
  214. package/dist/src/a2a/__tests__/server.test.node.d.ts.map +0 -1
  215. package/dist/src/a2a/__tests__/server.test.node.js +0 -110
  216. package/dist/src/a2a/__tests__/server.test.node.js.map +0 -1
  217. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts +0 -2
  218. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts.map +0 -1
  219. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js +0 -23
  220. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js.map +0 -1
  221. package/dist/src/agent/__tests__/agent-as-tool.test.d.ts +0 -2
  222. package/dist/src/agent/__tests__/agent-as-tool.test.d.ts.map +0 -1
  223. package/dist/src/agent/__tests__/agent-as-tool.test.js +0 -347
  224. package/dist/src/agent/__tests__/agent-as-tool.test.js.map +0 -1
  225. package/dist/src/agent/__tests__/agent.cancel.test.d.ts +0 -2
  226. package/dist/src/agent/__tests__/agent.cancel.test.d.ts.map +0 -1
  227. package/dist/src/agent/__tests__/agent.cancel.test.js +0 -337
  228. package/dist/src/agent/__tests__/agent.cancel.test.js.map +0 -1
  229. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts +0 -2
  230. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts.map +0 -1
  231. package/dist/src/agent/__tests__/agent.concurrent.test.js +0 -488
  232. package/dist/src/agent/__tests__/agent.concurrent.test.js.map +0 -1
  233. package/dist/src/agent/__tests__/agent.context-manager.test.d.ts +0 -2
  234. package/dist/src/agent/__tests__/agent.context-manager.test.d.ts.map +0 -1
  235. package/dist/src/agent/__tests__/agent.context-manager.test.js +0 -106
  236. package/dist/src/agent/__tests__/agent.context-manager.test.js.map +0 -1
  237. package/dist/src/agent/__tests__/agent.hook.test.d.ts +0 -2
  238. package/dist/src/agent/__tests__/agent.hook.test.d.ts.map +0 -1
  239. package/dist/src/agent/__tests__/agent.hook.test.js +0 -1332
  240. package/dist/src/agent/__tests__/agent.hook.test.js.map +0 -1
  241. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts +0 -2
  242. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts.map +0 -1
  243. package/dist/src/agent/__tests__/agent.interrupt.test.js +0 -779
  244. package/dist/src/agent/__tests__/agent.interrupt.test.js.map +0 -1
  245. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts +0 -2
  246. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts.map +0 -1
  247. package/dist/src/agent/__tests__/agent.invocation-state.test.js +0 -219
  248. package/dist/src/agent/__tests__/agent.invocation-state.test.js.map +0 -1
  249. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts +0 -2
  250. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts.map +0 -1
  251. package/dist/src/agent/__tests__/agent.model-retry.test.js +0 -161
  252. package/dist/src/agent/__tests__/agent.model-retry.test.js.map +0 -1
  253. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts +0 -2
  254. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts.map +0 -1
  255. package/dist/src/agent/__tests__/agent.stateful-model.test.js +0 -169
  256. package/dist/src/agent/__tests__/agent.stateful-model.test.js.map +0 -1
  257. package/dist/src/agent/__tests__/agent.test.d.ts +0 -2
  258. package/dist/src/agent/__tests__/agent.test.d.ts.map +0 -1
  259. package/dist/src/agent/__tests__/agent.test.js +0 -1624
  260. package/dist/src/agent/__tests__/agent.test.js.map +0 -1
  261. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts +0 -2
  262. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts.map +0 -1
  263. package/dist/src/agent/__tests__/agent.tracer.test.node.js +0 -535
  264. package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +0 -1
  265. package/dist/src/agent/__tests__/printer.test.d.ts +0 -2
  266. package/dist/src/agent/__tests__/printer.test.d.ts.map +0 -1
  267. package/dist/src/agent/__tests__/printer.test.js +0 -188
  268. package/dist/src/agent/__tests__/printer.test.js.map +0 -1
  269. package/dist/src/agent/__tests__/snapshot.test.d.ts +0 -2
  270. package/dist/src/agent/__tests__/snapshot.test.d.ts.map +0 -1
  271. package/dist/src/agent/__tests__/snapshot.test.js +0 -442
  272. package/dist/src/agent/__tests__/snapshot.test.js.map +0 -1
  273. package/dist/src/agent/__tests__/tool-caller.test.d.ts +0 -2
  274. package/dist/src/agent/__tests__/tool-caller.test.d.ts.map +0 -1
  275. package/dist/src/agent/__tests__/tool-caller.test.js +0 -459
  276. package/dist/src/agent/__tests__/tool-caller.test.js.map +0 -1
  277. package/dist/src/conversation-manager/__tests__/agentic-context.test.d.ts +0 -2
  278. package/dist/src/conversation-manager/__tests__/agentic-context.test.d.ts.map +0 -1
  279. package/dist/src/conversation-manager/__tests__/agentic-context.test.js +0 -332
  280. package/dist/src/conversation-manager/__tests__/agentic-context.test.js.map +0 -1
  281. package/dist/src/conversation-manager/__tests__/context-compression.test.d.ts +0 -2
  282. package/dist/src/conversation-manager/__tests__/context-compression.test.d.ts.map +0 -1
  283. package/dist/src/conversation-manager/__tests__/context-compression.test.js +0 -176
  284. package/dist/src/conversation-manager/__tests__/context-compression.test.js.map +0 -1
  285. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts +0 -2
  286. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts.map +0 -1
  287. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +0 -321
  288. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +0 -1
  289. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts +0 -2
  290. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts.map +0 -1
  291. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +0 -64
  292. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +0 -1
  293. package/dist/src/conversation-manager/__tests__/pin.test.d.ts +0 -2
  294. package/dist/src/conversation-manager/__tests__/pin.test.d.ts.map +0 -1
  295. package/dist/src/conversation-manager/__tests__/pin.test.js +0 -119
  296. package/dist/src/conversation-manager/__tests__/pin.test.js.map +0 -1
  297. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts +0 -2
  298. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts.map +0 -1
  299. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +0 -1080
  300. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +0 -1
  301. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.d.ts +0 -2
  302. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.d.ts.map +0 -1
  303. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js +0 -400
  304. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js.map +0 -1
  305. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.d.ts +0 -2
  306. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.d.ts.map +0 -1
  307. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.js +0 -138
  308. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.js.map +0 -1
  309. package/dist/src/hooks/__tests__/events.test.d.ts +0 -2
  310. package/dist/src/hooks/__tests__/events.test.d.ts.map +0 -1
  311. package/dist/src/hooks/__tests__/events.test.js +0 -1060
  312. package/dist/src/hooks/__tests__/events.test.js.map +0 -1
  313. package/dist/src/hooks/__tests__/registry.test.d.ts +0 -2
  314. package/dist/src/hooks/__tests__/registry.test.d.ts.map +0 -1
  315. package/dist/src/hooks/__tests__/registry.test.js +0 -325
  316. package/dist/src/hooks/__tests__/registry.test.js.map +0 -1
  317. package/dist/src/injection/__tests__/message-injection.test.d.ts +0 -2
  318. package/dist/src/injection/__tests__/message-injection.test.d.ts.map +0 -1
  319. package/dist/src/injection/__tests__/message-injection.test.js +0 -200
  320. package/dist/src/injection/__tests__/message-injection.test.js.map +0 -1
  321. package/dist/src/interventions/__tests__/handler.test.d.ts +0 -2
  322. package/dist/src/interventions/__tests__/handler.test.d.ts.map +0 -1
  323. package/dist/src/interventions/__tests__/handler.test.js +0 -35
  324. package/dist/src/interventions/__tests__/handler.test.js.map +0 -1
  325. package/dist/src/interventions/__tests__/registry.test.d.ts +0 -2
  326. package/dist/src/interventions/__tests__/registry.test.d.ts.map +0 -1
  327. package/dist/src/interventions/__tests__/registry.test.js +0 -692
  328. package/dist/src/interventions/__tests__/registry.test.js.map +0 -1
  329. package/dist/src/logging/__tests__/logger.test.d.ts +0 -2
  330. package/dist/src/logging/__tests__/logger.test.d.ts.map +0 -1
  331. package/dist/src/logging/__tests__/logger.test.js +0 -70
  332. package/dist/src/logging/__tests__/logger.test.js.map +0 -1
  333. package/dist/src/logging/__tests__/warn-once.test.d.ts +0 -2
  334. package/dist/src/logging/__tests__/warn-once.test.d.ts.map +0 -1
  335. package/dist/src/logging/__tests__/warn-once.test.js +0 -30
  336. package/dist/src/logging/__tests__/warn-once.test.js.map +0 -1
  337. package/dist/src/mcp.d.ts.map +0 -1
  338. package/dist/src/mcp.js.map +0 -1
  339. package/dist/src/memory/__tests__/memory-manager.test.d.ts +0 -2
  340. package/dist/src/memory/__tests__/memory-manager.test.d.ts.map +0 -1
  341. package/dist/src/memory/__tests__/memory-manager.test.js +0 -679
  342. package/dist/src/memory/__tests__/memory-manager.test.js.map +0 -1
  343. package/dist/src/memory/__tests__/memory-tracing.test.d.ts +0 -2
  344. package/dist/src/memory/__tests__/memory-tracing.test.d.ts.map +0 -1
  345. package/dist/src/memory/__tests__/memory-tracing.test.js +0 -250
  346. package/dist/src/memory/__tests__/memory-tracing.test.js.map +0 -1
  347. package/dist/src/memory/extraction/__tests__/extraction.test.d.ts +0 -2
  348. package/dist/src/memory/extraction/__tests__/extraction.test.d.ts.map +0 -1
  349. package/dist/src/memory/extraction/__tests__/extraction.test.js +0 -639
  350. package/dist/src/memory/extraction/__tests__/extraction.test.js.map +0 -1
  351. package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts +0 -2
  352. package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts.map +0 -1
  353. package/dist/src/memory/extraction/__tests__/model-extractor.test.js +0 -104
  354. package/dist/src/memory/extraction/__tests__/model-extractor.test.js.map +0 -1
  355. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts +0 -2
  356. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts.map +0 -1
  357. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js +0 -81
  358. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js.map +0 -1
  359. package/dist/src/middleware/__tests__/agent-middleware.test.d.ts +0 -2
  360. package/dist/src/middleware/__tests__/agent-middleware.test.d.ts.map +0 -1
  361. package/dist/src/middleware/__tests__/agent-middleware.test.js +0 -1206
  362. package/dist/src/middleware/__tests__/agent-middleware.test.js.map +0 -1
  363. package/dist/src/middleware/__tests__/copy-on-input.test.d.ts +0 -2
  364. package/dist/src/middleware/__tests__/copy-on-input.test.d.ts.map +0 -1
  365. package/dist/src/middleware/__tests__/copy-on-input.test.js +0 -379
  366. package/dist/src/middleware/__tests__/copy-on-input.test.js.map +0 -1
  367. package/dist/src/middleware/__tests__/custom-stages.test.d.ts +0 -2
  368. package/dist/src/middleware/__tests__/custom-stages.test.d.ts.map +0 -1
  369. package/dist/src/middleware/__tests__/custom-stages.test.js +0 -97
  370. package/dist/src/middleware/__tests__/custom-stages.test.js.map +0 -1
  371. package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts +0 -2
  372. package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts.map +0 -1
  373. package/dist/src/middleware/__tests__/middleware-interrupts.test.js +0 -267
  374. package/dist/src/middleware/__tests__/middleware-interrupts.test.js.map +0 -1
  375. package/dist/src/middleware/__tests__/registry.test.d.ts +0 -2
  376. package/dist/src/middleware/__tests__/registry.test.d.ts.map +0 -1
  377. package/dist/src/middleware/__tests__/registry.test.js +0 -525
  378. package/dist/src/middleware/__tests__/registry.test.js.map +0 -1
  379. package/dist/src/models/__tests__/anthropic.test.d.ts +0 -2
  380. package/dist/src/models/__tests__/anthropic.test.d.ts.map +0 -1
  381. package/dist/src/models/__tests__/anthropic.test.js +0 -793
  382. package/dist/src/models/__tests__/anthropic.test.js.map +0 -1
  383. package/dist/src/models/__tests__/bedrock.test.d.ts +0 -2
  384. package/dist/src/models/__tests__/bedrock.test.d.ts.map +0 -1
  385. package/dist/src/models/__tests__/bedrock.test.js +0 -3964
  386. package/dist/src/models/__tests__/bedrock.test.js.map +0 -1
  387. package/dist/src/models/__tests__/defaults.test.d.ts +0 -2
  388. package/dist/src/models/__tests__/defaults.test.d.ts.map +0 -1
  389. package/dist/src/models/__tests__/defaults.test.js +0 -36
  390. package/dist/src/models/__tests__/defaults.test.js.map +0 -1
  391. package/dist/src/models/__tests__/google.test.d.ts +0 -2
  392. package/dist/src/models/__tests__/google.test.d.ts.map +0 -1
  393. package/dist/src/models/__tests__/google.test.js +0 -1145
  394. package/dist/src/models/__tests__/google.test.js.map +0 -1
  395. package/dist/src/models/__tests__/model.test.d.ts +0 -2
  396. package/dist/src/models/__tests__/model.test.d.ts.map +0 -1
  397. package/dist/src/models/__tests__/model.test.js +0 -921
  398. package/dist/src/models/__tests__/model.test.js.map +0 -1
  399. package/dist/src/models/__tests__/streaming.test.d.ts +0 -2
  400. package/dist/src/models/__tests__/streaming.test.d.ts.map +0 -1
  401. package/dist/src/models/__tests__/streaming.test.js +0 -50
  402. package/dist/src/models/__tests__/streaming.test.js.map +0 -1
  403. package/dist/src/models/__tests__/test-utils.d.ts +0 -10
  404. package/dist/src/models/__tests__/test-utils.d.ts.map +0 -1
  405. package/dist/src/models/__tests__/test-utils.js +0 -17
  406. package/dist/src/models/__tests__/test-utils.js.map +0 -1
  407. package/dist/src/models/__tests__/vercel.test.d.ts +0 -2
  408. package/dist/src/models/__tests__/vercel.test.d.ts.map +0 -1
  409. package/dist/src/models/__tests__/vercel.test.js +0 -740
  410. package/dist/src/models/__tests__/vercel.test.js.map +0 -1
  411. package/dist/src/models/openai/__tests__/chat.test.d.ts +0 -2
  412. package/dist/src/models/openai/__tests__/chat.test.d.ts.map +0 -1
  413. package/dist/src/models/openai/__tests__/chat.test.js +0 -1586
  414. package/dist/src/models/openai/__tests__/chat.test.js.map +0 -1
  415. package/dist/src/models/openai/__tests__/errors.test.d.ts +0 -2
  416. package/dist/src/models/openai/__tests__/errors.test.d.ts.map +0 -1
  417. package/dist/src/models/openai/__tests__/errors.test.js +0 -39
  418. package/dist/src/models/openai/__tests__/errors.test.js.map +0 -1
  419. package/dist/src/models/openai/__tests__/mantle.test.d.ts +0 -2
  420. package/dist/src/models/openai/__tests__/mantle.test.d.ts.map +0 -1
  421. package/dist/src/models/openai/__tests__/mantle.test.js +0 -189
  422. package/dist/src/models/openai/__tests__/mantle.test.js.map +0 -1
  423. package/dist/src/models/openai/__tests__/responses.test.d.ts +0 -2
  424. package/dist/src/models/openai/__tests__/responses.test.d.ts.map +0 -1
  425. package/dist/src/models/openai/__tests__/responses.test.js +0 -709
  426. package/dist/src/models/openai/__tests__/responses.test.js.map +0 -1
  427. package/dist/src/multiagent/__tests__/events.test.d.ts +0 -2
  428. package/dist/src/multiagent/__tests__/events.test.d.ts.map +0 -1
  429. package/dist/src/multiagent/__tests__/events.test.js +0 -493
  430. package/dist/src/multiagent/__tests__/events.test.js.map +0 -1
  431. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts +0 -2
  432. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts.map +0 -1
  433. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js +0 -95
  434. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js.map +0 -1
  435. package/dist/src/multiagent/__tests__/graph.test.d.ts +0 -2
  436. package/dist/src/multiagent/__tests__/graph.test.d.ts.map +0 -1
  437. package/dist/src/multiagent/__tests__/graph.test.js +0 -698
  438. package/dist/src/multiagent/__tests__/graph.test.js.map +0 -1
  439. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts +0 -2
  440. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts.map +0 -1
  441. package/dist/src/multiagent/__tests__/graph.tracer.test.js +0 -218
  442. package/dist/src/multiagent/__tests__/graph.tracer.test.js.map +0 -1
  443. package/dist/src/multiagent/__tests__/interrupts.test.d.ts +0 -2
  444. package/dist/src/multiagent/__tests__/interrupts.test.d.ts.map +0 -1
  445. package/dist/src/multiagent/__tests__/interrupts.test.js +0 -390
  446. package/dist/src/multiagent/__tests__/interrupts.test.js.map +0 -1
  447. package/dist/src/multiagent/__tests__/nodes.test.d.ts +0 -2
  448. package/dist/src/multiagent/__tests__/nodes.test.d.ts.map +0 -1
  449. package/dist/src/multiagent/__tests__/nodes.test.js +0 -321
  450. package/dist/src/multiagent/__tests__/nodes.test.js.map +0 -1
  451. package/dist/src/multiagent/__tests__/queue.test.d.ts +0 -2
  452. package/dist/src/multiagent/__tests__/queue.test.d.ts.map +0 -1
  453. package/dist/src/multiagent/__tests__/queue.test.js +0 -118
  454. package/dist/src/multiagent/__tests__/queue.test.js.map +0 -1
  455. package/dist/src/multiagent/__tests__/snapshot.test.d.ts +0 -2
  456. package/dist/src/multiagent/__tests__/snapshot.test.d.ts.map +0 -1
  457. package/dist/src/multiagent/__tests__/snapshot.test.js +0 -161
  458. package/dist/src/multiagent/__tests__/snapshot.test.js.map +0 -1
  459. package/dist/src/multiagent/__tests__/state.test.d.ts +0 -2
  460. package/dist/src/multiagent/__tests__/state.test.d.ts.map +0 -1
  461. package/dist/src/multiagent/__tests__/state.test.js +0 -526
  462. package/dist/src/multiagent/__tests__/state.test.js.map +0 -1
  463. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts +0 -2
  464. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts.map +0 -1
  465. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js +0 -56
  466. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js.map +0 -1
  467. package/dist/src/multiagent/__tests__/swarm.test.d.ts +0 -2
  468. package/dist/src/multiagent/__tests__/swarm.test.d.ts.map +0 -1
  469. package/dist/src/multiagent/__tests__/swarm.test.js +0 -477
  470. package/dist/src/multiagent/__tests__/swarm.test.js.map +0 -1
  471. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts +0 -2
  472. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts.map +0 -1
  473. package/dist/src/multiagent/__tests__/swarm.tracer.test.js +0 -235
  474. package/dist/src/multiagent/__tests__/swarm.tracer.test.js.map +0 -1
  475. package/dist/src/plugins/__tests__/plugin.test.d.ts +0 -2
  476. package/dist/src/plugins/__tests__/plugin.test.d.ts.map +0 -1
  477. package/dist/src/plugins/__tests__/plugin.test.js +0 -114
  478. package/dist/src/plugins/__tests__/plugin.test.js.map +0 -1
  479. package/dist/src/plugins/__tests__/registry.test.d.ts +0 -2
  480. package/dist/src/plugins/__tests__/registry.test.d.ts.map +0 -1
  481. package/dist/src/plugins/__tests__/registry.test.js +0 -147
  482. package/dist/src/plugins/__tests__/registry.test.js.map +0 -1
  483. package/dist/src/registry/__tests__/tool-registry.test.d.ts +0 -2
  484. package/dist/src/registry/__tests__/tool-registry.test.d.ts.map +0 -1
  485. package/dist/src/registry/__tests__/tool-registry.test.js +0 -210
  486. package/dist/src/registry/__tests__/tool-registry.test.js.map +0 -1
  487. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts +0 -2
  488. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts.map +0 -1
  489. package/dist/src/retry/__tests__/backoff-strategy.test.js +0 -116
  490. package/dist/src/retry/__tests__/backoff-strategy.test.js.map +0 -1
  491. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts +0 -2
  492. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts.map +0 -1
  493. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js +0 -225
  494. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js.map +0 -1
  495. package/dist/src/sandbox/__tests__/default.test.browser.d.ts +0 -2
  496. package/dist/src/sandbox/__tests__/default.test.browser.d.ts.map +0 -1
  497. package/dist/src/sandbox/__tests__/default.test.browser.js +0 -11
  498. package/dist/src/sandbox/__tests__/default.test.browser.js.map +0 -1
  499. package/dist/src/sandbox/__tests__/default.test.node.d.ts +0 -2
  500. package/dist/src/sandbox/__tests__/default.test.node.d.ts.map +0 -1
  501. package/dist/src/sandbox/__tests__/default.test.node.js +0 -23
  502. package/dist/src/sandbox/__tests__/default.test.node.js.map +0 -1
  503. package/dist/src/sandbox/__tests__/docker.test.node.d.ts +0 -2
  504. package/dist/src/sandbox/__tests__/docker.test.node.d.ts.map +0 -1
  505. package/dist/src/sandbox/__tests__/docker.test.node.js +0 -89
  506. package/dist/src/sandbox/__tests__/docker.test.node.js.map +0 -1
  507. package/dist/src/sandbox/__tests__/errors.test.node.d.ts +0 -2
  508. package/dist/src/sandbox/__tests__/errors.test.node.d.ts.map +0 -1
  509. package/dist/src/sandbox/__tests__/errors.test.node.js +0 -33
  510. package/dist/src/sandbox/__tests__/errors.test.node.js.map +0 -1
  511. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts +0 -2
  512. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts.map +0 -1
  513. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js +0 -124
  514. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js.map +0 -1
  515. package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts +0 -2
  516. package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts.map +0 -1
  517. package/dist/src/sandbox/__tests__/posix-shell.test.node.js +0 -298
  518. package/dist/src/sandbox/__tests__/posix-shell.test.node.js.map +0 -1
  519. package/dist/src/sandbox/__tests__/ssh.test.node.d.ts +0 -2
  520. package/dist/src/sandbox/__tests__/ssh.test.node.d.ts.map +0 -1
  521. package/dist/src/sandbox/__tests__/ssh.test.node.js +0 -262
  522. package/dist/src/sandbox/__tests__/ssh.test.node.js.map +0 -1
  523. package/dist/src/session/__tests__/file-storage.test.node.d.ts +0 -2
  524. package/dist/src/session/__tests__/file-storage.test.node.d.ts.map +0 -1
  525. package/dist/src/session/__tests__/file-storage.test.node.js +0 -278
  526. package/dist/src/session/__tests__/file-storage.test.node.js.map +0 -1
  527. package/dist/src/session/__tests__/s3-storage.test.d.ts +0 -2
  528. package/dist/src/session/__tests__/s3-storage.test.d.ts.map +0 -1
  529. package/dist/src/session/__tests__/s3-storage.test.js +0 -461
  530. package/dist/src/session/__tests__/s3-storage.test.js.map +0 -1
  531. package/dist/src/session/__tests__/session-manager.test.d.ts +0 -2
  532. package/dist/src/session/__tests__/session-manager.test.d.ts.map +0 -1
  533. package/dist/src/session/__tests__/session-manager.test.js +0 -832
  534. package/dist/src/session/__tests__/session-manager.test.js.map +0 -1
  535. package/dist/src/session/__tests__/validation.test.d.ts +0 -2
  536. package/dist/src/session/__tests__/validation.test.d.ts.map +0 -1
  537. package/dist/src/session/__tests__/validation.test.js +0 -47
  538. package/dist/src/session/__tests__/validation.test.js.map +0 -1
  539. package/dist/src/telemetry/__tests__/config.test.d.ts +0 -2
  540. package/dist/src/telemetry/__tests__/config.test.d.ts.map +0 -1
  541. package/dist/src/telemetry/__tests__/config.test.js +0 -64
  542. package/dist/src/telemetry/__tests__/config.test.js.map +0 -1
  543. package/dist/src/telemetry/__tests__/config.test.node.d.ts +0 -2
  544. package/dist/src/telemetry/__tests__/config.test.node.d.ts.map +0 -1
  545. package/dist/src/telemetry/__tests__/config.test.node.js +0 -164
  546. package/dist/src/telemetry/__tests__/config.test.node.js.map +0 -1
  547. package/dist/src/telemetry/__tests__/json.test.d.ts +0 -2
  548. package/dist/src/telemetry/__tests__/json.test.d.ts.map +0 -1
  549. package/dist/src/telemetry/__tests__/json.test.js +0 -89
  550. package/dist/src/telemetry/__tests__/json.test.js.map +0 -1
  551. package/dist/src/telemetry/__tests__/local-trace.test.d.ts +0 -2
  552. package/dist/src/telemetry/__tests__/local-trace.test.d.ts.map +0 -1
  553. package/dist/src/telemetry/__tests__/local-trace.test.js +0 -158
  554. package/dist/src/telemetry/__tests__/local-trace.test.js.map +0 -1
  555. package/dist/src/telemetry/__tests__/meter.test.d.ts +0 -2
  556. package/dist/src/telemetry/__tests__/meter.test.d.ts.map +0 -1
  557. package/dist/src/telemetry/__tests__/meter.test.js +0 -695
  558. package/dist/src/telemetry/__tests__/meter.test.js.map +0 -1
  559. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts +0 -2
  560. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts.map +0 -1
  561. package/dist/src/telemetry/__tests__/tracer.test.node.js +0 -958
  562. package/dist/src/telemetry/__tests__/tracer.test.node.js.map +0 -1
  563. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts +0 -2
  564. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts.map +0 -1
  565. package/dist/src/tools/__tests__/structured-output-tool.test.js +0 -84
  566. package/dist/src/tools/__tests__/structured-output-tool.test.js.map +0 -1
  567. package/dist/src/tools/__tests__/tool-factory.test.d.ts +0 -2
  568. package/dist/src/tools/__tests__/tool-factory.test.d.ts.map +0 -1
  569. package/dist/src/tools/__tests__/tool-factory.test.js +0 -98
  570. package/dist/src/tools/__tests__/tool-factory.test.js.map +0 -1
  571. package/dist/src/tools/__tests__/tool.test.d.ts +0 -2
  572. package/dist/src/tools/__tests__/tool.test.d.ts.map +0 -1
  573. package/dist/src/tools/__tests__/tool.test.js +0 -1043
  574. package/dist/src/tools/__tests__/tool.test.js.map +0 -1
  575. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts +0 -2
  576. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts.map +0 -1
  577. package/dist/src/tools/__tests__/zod-tool.test-d.js +0 -227
  578. package/dist/src/tools/__tests__/zod-tool.test-d.js.map +0 -1
  579. package/dist/src/tools/__tests__/zod-tool.test.d.ts +0 -2
  580. package/dist/src/tools/__tests__/zod-tool.test.d.ts.map +0 -1
  581. package/dist/src/tools/__tests__/zod-tool.test.js +0 -563
  582. package/dist/src/tools/__tests__/zod-tool.test.js.map +0 -1
  583. package/dist/src/types/__tests__/agent.test.d.ts +0 -2
  584. package/dist/src/types/__tests__/agent.test.d.ts.map +0 -1
  585. package/dist/src/types/__tests__/agent.test.js +0 -476
  586. package/dist/src/types/__tests__/agent.test.js.map +0 -1
  587. package/dist/src/types/__tests__/citations.test.d.ts +0 -2
  588. package/dist/src/types/__tests__/citations.test.d.ts.map +0 -1
  589. package/dist/src/types/__tests__/citations.test.js +0 -104
  590. package/dist/src/types/__tests__/citations.test.js.map +0 -1
  591. package/dist/src/types/__tests__/json.test.d.ts +0 -2
  592. package/dist/src/types/__tests__/json.test.d.ts.map +0 -1
  593. package/dist/src/types/__tests__/json.test.js +0 -298
  594. package/dist/src/types/__tests__/json.test.js.map +0 -1
  595. package/dist/src/types/__tests__/media.test.d.ts +0 -2
  596. package/dist/src/types/__tests__/media.test.d.ts.map +0 -1
  597. package/dist/src/types/__tests__/media.test.js +0 -478
  598. package/dist/src/types/__tests__/media.test.js.map +0 -1
  599. package/dist/src/types/__tests__/messages.test.d.ts +0 -2
  600. package/dist/src/types/__tests__/messages.test.d.ts.map +0 -1
  601. package/dist/src/types/__tests__/messages.test.js +0 -681
  602. package/dist/src/types/__tests__/messages.test.js.map +0 -1
  603. package/dist/src/types/__tests__/validation.test.d.ts +0 -2
  604. package/dist/src/types/__tests__/validation.test.d.ts.map +0 -1
  605. package/dist/src/types/__tests__/validation.test.js +0 -30
  606. package/dist/src/types/__tests__/validation.test.js.map +0 -1
  607. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.d.ts +0 -2
  608. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.d.ts.map +0 -1
  609. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js +0 -756
  610. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js.map +0 -1
  611. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts +0 -2
  612. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts.map +0 -1
  613. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js +0 -358
  614. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js.map +0 -1
  615. package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts +0 -2
  616. package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts.map +0 -1
  617. package/dist/src/vended-interventions/steering/__tests__/handler.test.js +0 -163
  618. package/dist/src/vended-interventions/steering/__tests__/handler.test.js.map +0 -1
  619. package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts +0 -2
  620. package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts.map +0 -1
  621. package/dist/src/vended-interventions/steering/__tests__/llm.test.js +0 -60
  622. package/dist/src/vended-interventions/steering/__tests__/llm.test.js.map +0 -1
  623. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts +0 -2
  624. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts.map +0 -1
  625. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js +0 -94
  626. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js.map +0 -1
  627. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.d.ts +0 -2
  628. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.d.ts.map +0 -1
  629. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.js +0 -758
  630. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.node.js.map +0 -1
  631. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.d.ts +0 -2
  632. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.d.ts.map +0 -1
  633. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.js +0 -96
  634. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.js.map +0 -1
  635. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts +0 -2
  636. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts.map +0 -1
  637. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js +0 -68
  638. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js.map +0 -1
  639. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts +0 -2
  640. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts.map +0 -1
  641. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js +0 -539
  642. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js.map +0 -1
  643. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts +0 -2
  644. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts.map +0 -1
  645. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js +0 -97
  646. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js.map +0 -1
  647. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.d.ts +0 -2
  648. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.d.ts.map +0 -1
  649. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.js +0 -149
  650. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.js.map +0 -1
  651. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts +0 -2
  652. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts.map +0 -1
  653. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js +0 -216
  654. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js.map +0 -1
  655. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts +0 -2
  656. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts.map +0 -1
  657. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js +0 -78
  658. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js.map +0 -1
  659. package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts +0 -2
  660. package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts.map +0 -1
  661. package/dist/src/vended-plugins/goal/__tests__/plugin.test.js +0 -736
  662. package/dist/src/vended-plugins/goal/__tests__/plugin.test.js.map +0 -1
  663. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.d.ts +0 -2
  664. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.d.ts.map +0 -1
  665. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js +0 -482
  666. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js.map +0 -1
  667. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.d.ts +0 -2
  668. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.d.ts.map +0 -1
  669. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.js +0 -476
  670. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.js.map +0 -1
  671. package/dist/src/vended-tools/bash/__tests__/bash.test.node.d.ts +0 -2
  672. package/dist/src/vended-tools/bash/__tests__/bash.test.node.d.ts.map +0 -1
  673. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +0 -390
  674. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +0 -1
  675. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts +0 -2
  676. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts.map +0 -1
  677. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js +0 -452
  678. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +0 -1
  679. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts +0 -2
  680. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts.map +0 -1
  681. package/dist/src/vended-tools/http-request/__tests__/http-request.test.js +0 -189
  682. package/dist/src/vended-tools/http-request/__tests__/http-request.test.js.map +0 -1
  683. package/dist/src/vended-tools/notebook/__tests__/notebook.test.d.ts +0 -2
  684. package/dist/src/vended-tools/notebook/__tests__/notebook.test.d.ts.map +0 -1
  685. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +0 -388
  686. 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