@strands-agents/sdk 1.0.0-rc.5 → 1.1.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 (380) hide show
  1. package/LICENSE +175 -0
  2. package/README.md +340 -0
  3. package/dist/src/__fixtures__/agent-helpers.d.ts +22 -1
  4. package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -1
  5. package/dist/src/__fixtures__/agent-helpers.js +45 -1
  6. package/dist/src/__fixtures__/agent-helpers.js.map +1 -1
  7. package/dist/src/__fixtures__/mock-plugin.d.ts.map +1 -1
  8. package/dist/src/__fixtures__/mock-plugin.js +3 -1
  9. package/dist/src/__fixtures__/mock-plugin.js.map +1 -1
  10. package/dist/src/__fixtures__/tool-helpers.d.ts +5 -2
  11. package/dist/src/__fixtures__/tool-helpers.d.ts.map +1 -1
  12. package/dist/src/__fixtures__/tool-helpers.js +23 -4
  13. package/dist/src/__fixtures__/tool-helpers.js.map +1 -1
  14. package/dist/src/__tests__/interrupt.test.d.ts +2 -0
  15. package/dist/src/__tests__/interrupt.test.d.ts.map +1 -0
  16. package/dist/src/__tests__/interrupt.test.js +259 -0
  17. package/dist/src/__tests__/interrupt.test.js.map +1 -0
  18. package/dist/src/__tests__/mcp.test.js +448 -2
  19. package/dist/src/__tests__/mcp.test.js.map +1 -1
  20. package/dist/src/a2a/__tests__/events.test.js +2 -0
  21. package/dist/src/a2a/__tests__/events.test.js.map +1 -1
  22. package/dist/src/a2a/__tests__/executor.test.js +16 -5
  23. package/dist/src/a2a/__tests__/executor.test.js.map +1 -1
  24. package/dist/src/a2a/a2a-agent.d.ts +8 -3
  25. package/dist/src/a2a/a2a-agent.d.ts.map +1 -1
  26. package/dist/src/a2a/a2a-agent.js +12 -6
  27. package/dist/src/a2a/a2a-agent.js.map +1 -1
  28. package/dist/src/a2a/executor.d.ts +13 -0
  29. package/dist/src/a2a/executor.d.ts.map +1 -1
  30. package/dist/src/a2a/executor.js +19 -1
  31. package/dist/src/a2a/executor.js.map +1 -1
  32. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts +2 -0
  33. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts.map +1 -0
  34. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js +23 -0
  35. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js.map +1 -0
  36. package/dist/src/agent/__tests__/agent.cancel.test.js +1 -1
  37. package/dist/src/agent/__tests__/agent.cancel.test.js.map +1 -1
  38. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts +2 -0
  39. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts.map +1 -0
  40. package/dist/src/agent/__tests__/agent.concurrent.test.js +488 -0
  41. package/dist/src/agent/__tests__/agent.concurrent.test.js.map +1 -0
  42. package/dist/src/agent/__tests__/agent.hook.test.js +724 -12
  43. package/dist/src/agent/__tests__/agent.hook.test.js.map +1 -1
  44. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts +2 -0
  45. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts.map +1 -0
  46. package/dist/src/agent/__tests__/agent.interrupt.test.js +730 -0
  47. package/dist/src/agent/__tests__/agent.interrupt.test.js.map +1 -0
  48. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts +2 -0
  49. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts.map +1 -0
  50. package/dist/src/agent/__tests__/agent.invocation-state.test.js +219 -0
  51. package/dist/src/agent/__tests__/agent.invocation-state.test.js.map +1 -0
  52. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts +2 -0
  53. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts.map +1 -0
  54. package/dist/src/agent/__tests__/agent.model-retry.test.js +161 -0
  55. package/dist/src/agent/__tests__/agent.model-retry.test.js.map +1 -0
  56. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts +2 -0
  57. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts.map +1 -0
  58. package/dist/src/agent/__tests__/agent.stateful-model.test.js +169 -0
  59. package/dist/src/agent/__tests__/agent.stateful-model.test.js.map +1 -0
  60. package/dist/src/agent/__tests__/agent.test.js +217 -2
  61. package/dist/src/agent/__tests__/agent.test.js.map +1 -1
  62. package/dist/src/agent/__tests__/agent.tracer.test.node.js +39 -0
  63. package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +1 -1
  64. package/dist/src/agent/__tests__/snapshot.test.js +51 -4
  65. package/dist/src/agent/__tests__/snapshot.test.js.map +1 -1
  66. package/dist/src/agent/agent-as-tool.d.ts.map +1 -1
  67. package/dist/src/agent/agent-as-tool.js +4 -2
  68. package/dist/src/agent/agent-as-tool.js.map +1 -1
  69. package/dist/src/agent/agent.d.ts +109 -4
  70. package/dist/src/agent/agent.d.ts.map +1 -1
  71. package/dist/src/agent/agent.js +790 -224
  72. package/dist/src/agent/agent.js.map +1 -1
  73. package/dist/src/agent/snapshot.d.ts +2 -2
  74. package/dist/src/agent/snapshot.d.ts.map +1 -1
  75. package/dist/src/agent/snapshot.js +20 -2
  76. package/dist/src/agent/snapshot.js.map +1 -1
  77. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +230 -9
  78. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +1 -1
  79. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +19 -6
  80. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +1 -1
  81. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +58 -4
  82. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +1 -1
  83. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js +76 -1
  84. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js.map +1 -1
  85. package/dist/src/conversation-manager/conversation-manager.d.ts +67 -22
  86. package/dist/src/conversation-manager/conversation-manager.d.ts.map +1 -1
  87. package/dist/src/conversation-manager/conversation-manager.js +65 -13
  88. package/dist/src/conversation-manager/conversation-manager.js.map +1 -1
  89. package/dist/src/conversation-manager/index.d.ts +1 -1
  90. package/dist/src/conversation-manager/index.d.ts.map +1 -1
  91. package/dist/src/conversation-manager/index.js +1 -1
  92. package/dist/src/conversation-manager/index.js.map +1 -1
  93. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts +17 -3
  94. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
  95. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +10 -4
  96. package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
  97. package/dist/src/conversation-manager/summarizing-conversation-manager.d.ts +23 -1
  98. package/dist/src/conversation-manager/summarizing-conversation-manager.d.ts.map +1 -1
  99. package/dist/src/conversation-manager/summarizing-conversation-manager.js +39 -17
  100. package/dist/src/conversation-manager/summarizing-conversation-manager.js.map +1 -1
  101. package/dist/src/errors.d.ts +11 -0
  102. package/dist/src/errors.d.ts.map +1 -1
  103. package/dist/src/errors.js +12 -0
  104. package/dist/src/errors.js.map +1 -1
  105. package/dist/src/hooks/__tests__/events.test.js +267 -73
  106. package/dist/src/hooks/__tests__/events.test.js.map +1 -1
  107. package/dist/src/hooks/__tests__/registry.test.js +182 -18
  108. package/dist/src/hooks/__tests__/registry.test.js.map +1 -1
  109. package/dist/src/hooks/events.d.ts +193 -51
  110. package/dist/src/hooks/events.d.ts.map +1 -1
  111. package/dist/src/hooks/events.js +182 -26
  112. package/dist/src/hooks/events.js.map +1 -1
  113. package/dist/src/hooks/index.d.ts +3 -2
  114. package/dist/src/hooks/index.d.ts.map +1 -1
  115. package/dist/src/hooks/index.js +1 -0
  116. package/dist/src/hooks/index.js.map +1 -1
  117. package/dist/src/hooks/registry.d.ts +12 -12
  118. package/dist/src/hooks/registry.d.ts.map +1 -1
  119. package/dist/src/hooks/registry.js +55 -15
  120. package/dist/src/hooks/registry.js.map +1 -1
  121. package/dist/src/hooks/types.d.ts +23 -0
  122. package/dist/src/hooks/types.d.ts.map +1 -1
  123. package/dist/src/hooks/types.js +17 -1
  124. package/dist/src/hooks/types.js.map +1 -1
  125. package/dist/src/index.d.ts +12 -7
  126. package/dist/src/index.d.ts.map +1 -1
  127. package/dist/src/index.js +4 -1
  128. package/dist/src/index.js.map +1 -1
  129. package/dist/src/interrupt.d.ts +220 -0
  130. package/dist/src/interrupt.d.ts.map +1 -0
  131. package/dist/src/interrupt.js +274 -0
  132. package/dist/src/interrupt.js.map +1 -0
  133. package/dist/src/logging/__tests__/warn-once.test.d.ts +2 -0
  134. package/dist/src/logging/__tests__/warn-once.test.d.ts.map +1 -0
  135. package/dist/src/logging/__tests__/warn-once.test.js +30 -0
  136. package/dist/src/logging/__tests__/warn-once.test.js.map +1 -0
  137. package/dist/src/logging/warn-once.d.ts +13 -0
  138. package/dist/src/logging/warn-once.d.ts.map +1 -0
  139. package/dist/src/logging/warn-once.js +18 -0
  140. package/dist/src/logging/warn-once.js.map +1 -0
  141. package/dist/src/mcp.d.ts +43 -3
  142. package/dist/src/mcp.d.ts.map +1 -1
  143. package/dist/src/mcp.js +85 -17
  144. package/dist/src/mcp.js.map +1 -1
  145. package/dist/src/mime.d.ts +2 -1
  146. package/dist/src/mime.d.ts.map +1 -1
  147. package/dist/src/mime.js +1 -0
  148. package/dist/src/mime.js.map +1 -1
  149. package/dist/src/models/__tests__/anthropic.test.js +147 -3
  150. package/dist/src/models/__tests__/anthropic.test.js.map +1 -1
  151. package/dist/src/models/__tests__/bedrock.test.js +228 -2
  152. package/dist/src/models/__tests__/bedrock.test.js.map +1 -1
  153. package/dist/src/models/__tests__/defaults.test.d.ts +2 -0
  154. package/dist/src/models/__tests__/defaults.test.d.ts.map +1 -0
  155. package/dist/src/models/__tests__/defaults.test.js +36 -0
  156. package/dist/src/models/__tests__/defaults.test.js.map +1 -0
  157. package/dist/src/models/__tests__/google.test.js +135 -0
  158. package/dist/src/models/__tests__/google.test.js.map +1 -1
  159. package/dist/src/models/__tests__/model.test.js +149 -1
  160. package/dist/src/models/__tests__/model.test.js.map +1 -1
  161. package/dist/src/models/anthropic.d.ts +20 -1
  162. package/dist/src/models/anthropic.d.ts.map +1 -1
  163. package/dist/src/models/anthropic.js +42 -8
  164. package/dist/src/models/anthropic.js.map +1 -1
  165. package/dist/src/models/bedrock.d.ts +27 -1
  166. package/dist/src/models/bedrock.d.ts.map +1 -1
  167. package/dist/src/models/bedrock.js +100 -12
  168. package/dist/src/models/bedrock.js.map +1 -1
  169. package/dist/src/models/defaults.d.ts +47 -0
  170. package/dist/src/models/defaults.d.ts.map +1 -0
  171. package/dist/src/models/defaults.js +170 -0
  172. package/dist/src/models/defaults.js.map +1 -0
  173. package/dist/src/models/google/model.d.ts +14 -1
  174. package/dist/src/models/google/model.d.ts.map +1 -1
  175. package/dist/src/models/google/model.js +54 -8
  176. package/dist/src/models/google/model.js.map +1 -1
  177. package/dist/src/models/google/types.d.ts +8 -0
  178. package/dist/src/models/google/types.d.ts.map +1 -1
  179. package/dist/src/models/model.d.ts +65 -0
  180. package/dist/src/models/model.d.ts.map +1 -1
  181. package/dist/src/models/model.js +138 -0
  182. package/dist/src/models/model.js.map +1 -1
  183. package/dist/src/models/openai/__tests__/chat.test.d.ts +2 -0
  184. package/dist/src/models/openai/__tests__/chat.test.d.ts.map +1 -0
  185. package/dist/src/models/{__tests__/openai.test.js → openai/__tests__/chat.test.js} +117 -7
  186. package/dist/src/models/openai/__tests__/chat.test.js.map +1 -0
  187. package/dist/src/models/openai/__tests__/responses.test.d.ts +2 -0
  188. package/dist/src/models/openai/__tests__/responses.test.d.ts.map +1 -0
  189. package/dist/src/models/openai/__tests__/responses.test.js +668 -0
  190. package/dist/src/models/openai/__tests__/responses.test.js.map +1 -0
  191. package/dist/src/models/openai/chat-adapter.d.ts +33 -0
  192. package/dist/src/models/openai/chat-adapter.d.ts.map +1 -0
  193. package/dist/src/models/openai/chat-adapter.js +383 -0
  194. package/dist/src/models/openai/chat-adapter.js.map +1 -0
  195. package/dist/src/models/openai/errors.d.ts +16 -0
  196. package/dist/src/models/openai/errors.d.ts.map +1 -0
  197. package/dist/src/models/openai/errors.js +40 -0
  198. package/dist/src/models/openai/errors.js.map +1 -0
  199. package/dist/src/models/openai/formatting.d.ts +18 -0
  200. package/dist/src/models/openai/formatting.d.ts.map +1 -0
  201. package/dist/src/models/openai/formatting.js +38 -0
  202. package/dist/src/models/openai/formatting.js.map +1 -0
  203. package/dist/src/models/openai/index.d.ts +19 -0
  204. package/dist/src/models/openai/index.d.ts.map +1 -0
  205. package/dist/src/models/openai/index.js +18 -0
  206. package/dist/src/models/openai/index.js.map +1 -0
  207. package/dist/src/models/openai/model.d.ts +77 -0
  208. package/dist/src/models/openai/model.d.ts.map +1 -0
  209. package/dist/src/models/openai/model.js +211 -0
  210. package/dist/src/models/openai/model.js.map +1 -0
  211. package/dist/src/models/openai/responses-adapter.d.ts +78 -0
  212. package/dist/src/models/openai/responses-adapter.d.ts.map +1 -0
  213. package/dist/src/models/openai/responses-adapter.js +467 -0
  214. package/dist/src/models/openai/responses-adapter.js.map +1 -0
  215. package/dist/src/models/openai/types.d.ts +131 -0
  216. package/dist/src/models/openai/types.d.ts.map +1 -0
  217. package/dist/src/models/openai/types.js +5 -0
  218. package/dist/src/models/openai/types.js.map +1 -0
  219. package/dist/src/multiagent/__tests__/events.test.js +122 -28
  220. package/dist/src/multiagent/__tests__/events.test.js.map +1 -1
  221. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts +2 -0
  222. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts.map +1 -0
  223. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js +95 -0
  224. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js.map +1 -0
  225. package/dist/src/multiagent/__tests__/graph.test.js +69 -0
  226. package/dist/src/multiagent/__tests__/graph.test.js.map +1 -1
  227. package/dist/src/multiagent/__tests__/nodes.test.js +18 -2
  228. package/dist/src/multiagent/__tests__/nodes.test.js.map +1 -1
  229. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts +2 -0
  230. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts.map +1 -0
  231. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js +56 -0
  232. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js.map +1 -0
  233. package/dist/src/multiagent/__tests__/swarm.test.js +77 -0
  234. package/dist/src/multiagent/__tests__/swarm.test.js.map +1 -1
  235. package/dist/src/multiagent/events.d.ts +19 -1
  236. package/dist/src/multiagent/events.d.ts.map +1 -1
  237. package/dist/src/multiagent/events.js +18 -0
  238. package/dist/src/multiagent/events.js.map +1 -1
  239. package/dist/src/multiagent/graph.d.ts +27 -5
  240. package/dist/src/multiagent/graph.d.ts.map +1 -1
  241. package/dist/src/multiagent/graph.js +61 -15
  242. package/dist/src/multiagent/graph.js.map +1 -1
  243. package/dist/src/multiagent/index.d.ts +1 -1
  244. package/dist/src/multiagent/index.d.ts.map +1 -1
  245. package/dist/src/multiagent/multiagent.d.ts +21 -6
  246. package/dist/src/multiagent/multiagent.d.ts.map +1 -1
  247. package/dist/src/multiagent/nodes.d.ts +28 -3
  248. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  249. package/dist/src/multiagent/nodes.js +42 -7
  250. package/dist/src/multiagent/nodes.js.map +1 -1
  251. package/dist/src/multiagent/swarm.d.ts +20 -4
  252. package/dist/src/multiagent/swarm.d.ts.map +1 -1
  253. package/dist/src/multiagent/swarm.js +65 -16
  254. package/dist/src/multiagent/swarm.js.map +1 -1
  255. package/dist/src/plugins/__tests__/registry.test.js +1 -1
  256. package/dist/src/plugins/__tests__/registry.test.js.map +1 -1
  257. package/dist/src/plugins/model-plugin.d.ts +20 -0
  258. package/dist/src/plugins/model-plugin.d.ts.map +1 -0
  259. package/dist/src/plugins/model-plugin.js +29 -0
  260. package/dist/src/plugins/model-plugin.js.map +1 -0
  261. package/dist/src/registry/__tests__/tool-registry.test.js +11 -0
  262. package/dist/src/registry/__tests__/tool-registry.test.js.map +1 -1
  263. package/dist/src/registry/tool-registry.d.ts +4 -0
  264. package/dist/src/registry/tool-registry.d.ts.map +1 -1
  265. package/dist/src/registry/tool-registry.js +6 -0
  266. package/dist/src/registry/tool-registry.js.map +1 -1
  267. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts +2 -0
  268. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts.map +1 -0
  269. package/dist/src/retry/__tests__/backoff-strategy.test.js +116 -0
  270. package/dist/src/retry/__tests__/backoff-strategy.test.js.map +1 -0
  271. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts +2 -0
  272. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts.map +1 -0
  273. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js +225 -0
  274. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js.map +1 -0
  275. package/dist/src/retry/backoff-strategy.d.ts +108 -0
  276. package/dist/src/retry/backoff-strategy.d.ts.map +1 -0
  277. package/dist/src/retry/backoff-strategy.js +86 -0
  278. package/dist/src/retry/backoff-strategy.js.map +1 -0
  279. package/dist/src/retry/default-model-retry-strategy.d.ts +76 -0
  280. package/dist/src/retry/default-model-retry-strategy.d.ts.map +1 -0
  281. package/dist/src/retry/default-model-retry-strategy.js +104 -0
  282. package/dist/src/retry/default-model-retry-strategy.js.map +1 -0
  283. package/dist/src/retry/index.d.ts +8 -0
  284. package/dist/src/retry/index.d.ts.map +1 -0
  285. package/dist/src/retry/index.js +7 -0
  286. package/dist/src/retry/index.js.map +1 -0
  287. package/dist/src/retry/model-retry-strategy.d.ts +80 -0
  288. package/dist/src/retry/model-retry-strategy.d.ts.map +1 -0
  289. package/dist/src/retry/model-retry-strategy.js +85 -0
  290. package/dist/src/retry/model-retry-strategy.js.map +1 -0
  291. package/dist/src/retry/retry-strategy.d.ts +34 -0
  292. package/dist/src/retry/retry-strategy.d.ts.map +1 -0
  293. package/dist/src/retry/retry-strategy.js +25 -0
  294. package/dist/src/retry/retry-strategy.js.map +1 -0
  295. package/dist/src/session/__tests__/session-manager.test.js +52 -11
  296. package/dist/src/session/__tests__/session-manager.test.js.map +1 -1
  297. package/dist/src/session/session-manager.d.ts +6 -0
  298. package/dist/src/session/session-manager.d.ts.map +1 -1
  299. package/dist/src/session/session-manager.js +17 -0
  300. package/dist/src/session/session-manager.js.map +1 -1
  301. package/dist/src/telemetry/__tests__/meter.test.js +23 -0
  302. package/dist/src/telemetry/__tests__/meter.test.js.map +1 -1
  303. package/dist/src/telemetry/meter.d.ts +15 -0
  304. package/dist/src/telemetry/meter.d.ts.map +1 -1
  305. package/dist/src/telemetry/meter.js +14 -0
  306. package/dist/src/telemetry/meter.js.map +1 -1
  307. package/dist/src/tools/__tests__/tool.test.js +24 -1
  308. package/dist/src/tools/__tests__/tool.test.js.map +1 -1
  309. package/dist/src/tools/function-tool.d.ts.map +1 -1
  310. package/dist/src/tools/function-tool.js +6 -1
  311. package/dist/src/tools/function-tool.js.map +1 -1
  312. package/dist/src/tools/mcp-tool.d.ts +24 -3
  313. package/dist/src/tools/mcp-tool.d.ts.map +1 -1
  314. package/dist/src/tools/mcp-tool.js +103 -31
  315. package/dist/src/tools/mcp-tool.js.map +1 -1
  316. package/dist/src/tools/tool.d.ts +21 -2
  317. package/dist/src/tools/tool.d.ts.map +1 -1
  318. package/dist/src/tools/tool.js +12 -0
  319. package/dist/src/tools/tool.js.map +1 -1
  320. package/dist/src/tsconfig.tsbuildinfo +1 -1
  321. package/dist/src/types/__tests__/agent.test.js +48 -0
  322. package/dist/src/types/__tests__/agent.test.js.map +1 -1
  323. package/dist/src/types/agent.d.ts +77 -9
  324. package/dist/src/types/agent.d.ts.map +1 -1
  325. package/dist/src/types/agent.js +30 -6
  326. package/dist/src/types/agent.js.map +1 -1
  327. package/dist/src/types/elicitation.d.ts +15 -0
  328. package/dist/src/types/elicitation.d.ts.map +1 -0
  329. package/dist/src/types/elicitation.js +2 -0
  330. package/dist/src/types/elicitation.js.map +1 -0
  331. package/dist/src/types/interrupt.d.ts +103 -0
  332. package/dist/src/types/interrupt.d.ts.map +1 -0
  333. package/dist/src/types/interrupt.js +63 -0
  334. package/dist/src/types/interrupt.js.map +1 -0
  335. package/dist/src/types/messages.d.ts +2 -1
  336. package/dist/src/types/messages.d.ts.map +1 -1
  337. package/dist/src/types/messages.js.map +1 -1
  338. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts +2 -0
  339. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts.map +1 -0
  340. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js +292 -0
  341. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js.map +1 -0
  342. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts +2 -0
  343. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts.map +1 -0
  344. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js +148 -0
  345. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js.map +1 -0
  346. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts +2 -0
  347. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts.map +1 -0
  348. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js +78 -0
  349. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js.map +1 -0
  350. package/dist/src/vended-plugins/context-offloader/index.d.ts +23 -0
  351. package/dist/src/vended-plugins/context-offloader/index.d.ts.map +1 -0
  352. package/dist/src/vended-plugins/context-offloader/index.js +21 -0
  353. package/dist/src/vended-plugins/context-offloader/index.js.map +1 -0
  354. package/dist/src/vended-plugins/context-offloader/plugin.d.ts +48 -0
  355. package/dist/src/vended-plugins/context-offloader/plugin.d.ts.map +1 -0
  356. package/dist/src/vended-plugins/context-offloader/plugin.js +244 -0
  357. package/dist/src/vended-plugins/context-offloader/plugin.js.map +1 -0
  358. package/dist/src/vended-plugins/context-offloader/storage.d.ts +114 -0
  359. package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -0
  360. package/dist/src/vended-plugins/context-offloader/storage.js +204 -0
  361. package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -0
  362. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js +21 -5
  363. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js.map +1 -1
  364. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +4 -0
  365. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +1 -1
  366. package/dist/src/vended-tools/bash/bash.d.ts.map +1 -1
  367. package/dist/src/vended-tools/bash/bash.js +0 -3
  368. package/dist/src/vended-tools/bash/bash.js.map +1 -1
  369. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js +4 -0
  370. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +1 -1
  371. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +4 -0
  372. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js.map +1 -1
  373. package/package.json +17 -9
  374. package/dist/src/models/__tests__/openai.test.d.ts +0 -2
  375. package/dist/src/models/__tests__/openai.test.d.ts.map +0 -1
  376. package/dist/src/models/__tests__/openai.test.js.map +0 -1
  377. package/dist/src/models/openai.d.ts +0 -312
  378. package/dist/src/models/openai.d.ts.map +0 -1
  379. package/dist/src/models/openai.js +0 -789
  380. package/dist/src/models/openai.js.map +0 -1
@@ -0,0 +1,169 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { Agent } from '../agent.js';
3
+ import { MockMessageModel } from '../../__fixtures__/mock-message-model.js';
4
+ import { MockSnapshotStorage } from '../../__fixtures__/mock-storage-provider.js';
5
+ import { SlidingWindowConversationManager } from '../../conversation-manager/sliding-window-conversation-manager.js';
6
+ import { NullConversationManager } from '../../conversation-manager/null-conversation-manager.js';
7
+ import { SessionManager } from '../../session/session-manager.js';
8
+ import { SNAPSHOT_SCHEMA_VERSION } from '../../types/snapshot.js';
9
+ import { Message } from '../../types/messages.js';
10
+ /**
11
+ * Mock model that advertises itself as stateful and records the modelState
12
+ * object it receives, so tests can verify the agent's modelState flows through.
13
+ */
14
+ class StatefulMockModel extends MockMessageModel {
15
+ receivedOptions = [];
16
+ _responseIds;
17
+ constructor(responseIds = ['resp_1', 'resp_2', 'resp_3']) {
18
+ super();
19
+ this._responseIds = responseIds;
20
+ }
21
+ get stateful() {
22
+ return true;
23
+ }
24
+ async *stream(messages, options) {
25
+ this.receivedOptions.push(options ?? {});
26
+ // Simulate that the provider captured a fresh response id on the wire.
27
+ if (options?.modelState) {
28
+ const next = this._responseIds[this.receivedOptions.length - 1];
29
+ if (next !== undefined) {
30
+ options.modelState.set('responseId', next);
31
+ }
32
+ }
33
+ yield* super.stream(messages, options);
34
+ }
35
+ }
36
+ describe('Agent with stateful model', () => {
37
+ describe('constructor', () => {
38
+ it('throws when a conversationManager is supplied alongside a stateful model', () => {
39
+ const model = new StatefulMockModel();
40
+ expect(() => new Agent({ model, conversationManager: new SlidingWindowConversationManager({ windowSize: 5 }) })).toThrow(/stateful model/);
41
+ });
42
+ it('assigns NullConversationManager when the model is stateful', () => {
43
+ const model = new StatefulMockModel();
44
+ const agent = new Agent({ model, printer: false });
45
+ // Private field; access through bracket notation to avoid making it public.
46
+ expect(agent._conversationManager).toBeInstanceOf(NullConversationManager);
47
+ });
48
+ it('initializes modelState as an empty store', () => {
49
+ const model = new StatefulMockModel();
50
+ const agent = new Agent({ model, printer: false });
51
+ expect(agent.modelState.getAll()).toEqual({});
52
+ });
53
+ it('hydrates modelState from AgentConfig.modelState', () => {
54
+ const model = new StatefulMockModel();
55
+ const agent = new Agent({ model, printer: false, modelState: { responseId: 'resp_restored' } });
56
+ expect(agent.modelState.getAll()).toEqual({ responseId: 'resp_restored' });
57
+ });
58
+ });
59
+ describe('invocation', () => {
60
+ it('passes agent.modelState to the model via streamOptions.modelState', async () => {
61
+ const model = new StatefulMockModel(['resp_first']).addTurn({ type: 'textBlock', text: 'Hi' });
62
+ const agent = new Agent({ model, printer: false });
63
+ await agent.invoke('Hello');
64
+ expect(model.receivedOptions[0]?.modelState).toBe(agent.modelState);
65
+ expect(agent.modelState.getAll()).toEqual({ responseId: 'resp_first' });
66
+ });
67
+ it('clears messages after invocation since the server holds history', async () => {
68
+ const model = new StatefulMockModel().addTurn({ type: 'textBlock', text: 'Hi there' });
69
+ const agent = new Agent({ model, printer: false });
70
+ await agent.invoke('First turn');
71
+ expect(agent.messages).toEqual([]);
72
+ });
73
+ it('clears messages before SessionManager snapshots on AfterInvocationEvent', async () => {
74
+ // Guards the ordering of ModelPlugin vs SessionManager hooks on
75
+ // AfterInvocationEvent: ModelPlugin must clear messages *before*
76
+ // SessionManager persists the snapshot, otherwise the stored snapshot
77
+ // would duplicate history that the server already owns.
78
+ const storage = new MockSnapshotStorage();
79
+ const sessionManager = new SessionManager({
80
+ sessionId: 'test-session',
81
+ storage: { snapshot: storage },
82
+ });
83
+ const model = new StatefulMockModel().addTurn({ type: 'textBlock', text: 'reply' });
84
+ const agent = new Agent({ id: 'agent-1', model, sessionManager, printer: false });
85
+ await agent.invoke('hi');
86
+ const snapshot = await storage.loadSnapshot({
87
+ location: { sessionId: 'test-session', scope: 'agent', scopeId: 'agent-1' },
88
+ });
89
+ expect(snapshot).not.toBeNull();
90
+ expect(snapshot.data.messages).toEqual([]);
91
+ });
92
+ it('preserves modelState across invocations so previous_response_id chains', async () => {
93
+ const model = new StatefulMockModel(['resp_1', 'resp_2'])
94
+ .addTurn({ type: 'textBlock', text: 'one' })
95
+ .addTurn({ type: 'textBlock', text: 'two' });
96
+ const agent = new Agent({ model, printer: false });
97
+ await agent.invoke('turn 1');
98
+ expect(agent.modelState.getAll()).toEqual({ responseId: 'resp_1' });
99
+ await agent.invoke('turn 2');
100
+ expect(agent.modelState.getAll()).toEqual({ responseId: 'resp_2' });
101
+ // Both turns should have seen the state at invocation time.
102
+ expect(model.receivedOptions).toHaveLength(2);
103
+ });
104
+ });
105
+ describe('stateless model (default)', () => {
106
+ it('does not clear messages after invocation', async () => {
107
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
108
+ const agent = new Agent({ model, printer: false });
109
+ await agent.invoke('Hi');
110
+ // user message + assistant reply
111
+ expect(agent.messages.length).toBe(2);
112
+ });
113
+ it('uses the caller-provided conversationManager', () => {
114
+ const model = new MockMessageModel();
115
+ const convo = new SlidingWindowConversationManager({ windowSize: 7 });
116
+ const agent = new Agent({ model, conversationManager: convo });
117
+ expect(agent._conversationManager).toBe(convo);
118
+ });
119
+ });
120
+ describe('SessionManager restore guard', () => {
121
+ // Pre-seeds a session snapshot with messages, then verifies that SessionManager
122
+ // discards those messages on restore when the model is stateful.
123
+ async function setupStorageWithMessages(agentId, sessionId) {
124
+ const storage = new MockSnapshotStorage();
125
+ await storage.saveSnapshot({
126
+ location: { sessionId, scope: 'agent', scopeId: agentId },
127
+ snapshotId: 'latest',
128
+ isLatest: true,
129
+ snapshot: {
130
+ scope: 'agent',
131
+ schemaVersion: SNAPSHOT_SCHEMA_VERSION,
132
+ createdAt: new Date().toISOString(),
133
+ data: {
134
+ messages: [{ role: 'user', content: [{ text: 'old turn' }] }],
135
+ state: {},
136
+ systemPrompt: null,
137
+ modelState: {},
138
+ },
139
+ appData: {},
140
+ },
141
+ });
142
+ return storage;
143
+ }
144
+ it('discards restored messages when the model is stateful', async () => {
145
+ const storage = await setupStorageWithMessages('agent-1', 'session-stateful');
146
+ const sessionManager = new SessionManager({
147
+ sessionId: 'session-stateful',
148
+ storage: { snapshot: storage },
149
+ });
150
+ const model = new StatefulMockModel();
151
+ const agent = new Agent({ id: 'agent-1', model, sessionManager, printer: false });
152
+ await agent.initialize();
153
+ expect(agent.messages).toEqual([]);
154
+ });
155
+ it('restores messages when the model is stateless', async () => {
156
+ const storage = await setupStorageWithMessages('agent-2', 'session-stateless');
157
+ const sessionManager = new SessionManager({
158
+ sessionId: 'session-stateless',
159
+ storage: { snapshot: storage },
160
+ });
161
+ const model = new MockMessageModel();
162
+ const agent = new Agent({ id: 'agent-2', model, sessionManager, printer: false });
163
+ await agent.initialize();
164
+ expect(agent.messages).toHaveLength(1);
165
+ expect(agent.messages[0].role).toBe('user');
166
+ });
167
+ });
168
+ });
169
+ //# sourceMappingURL=agent.stateful-model.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.stateful-model.test.js","sourceRoot":"","sources":["../../../../src/agent/__tests__/agent.stateful-model.test.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { createMockTool, createRandomTool } from '../../__fixtures__/tool-helper
7
7
  import { ConcurrentInvocationError } from '../../errors.js';
8
8
  import { MaxTokensError, TextBlock, CachePointBlock, Message, ToolUseBlock, ToolResultBlock, ReasoningBlock, GuardContentBlock, ImageBlock, VideoBlock, DocumentBlock, } from '../../index.js';
9
9
  import { AgentPrinter } from '../printer.js';
10
- import { AfterInvocationEvent, AfterToolCallEvent, AfterToolsEvent, BeforeInvocationEvent, BeforeToolsEvent, } from '../../hooks/events.js';
10
+ import { AfterInvocationEvent, AfterToolCallEvent, AfterToolsEvent, BeforeInvocationEvent, BeforeModelCallEvent, BeforeToolsEvent, } from '../../hooks/events.js';
11
11
  import { BedrockModel } from '../../models/bedrock.js';
12
12
  import { StructuredOutputError } from '../../errors.js';
13
13
  import { expectLoopMetrics } from '../../__fixtures__/metrics-helpers.js';
@@ -36,7 +36,7 @@ describe('Agent', () => {
36
36
  const { items } = await collectGenerator(agent.stream('Test prompt'));
37
37
  expect(items.length).toBeGreaterThan(0);
38
38
  const firstItem = items[0];
39
- expect(firstItem).toEqual(new BeforeInvocationEvent({ agent: agent }));
39
+ expect(firstItem).toEqual(new BeforeInvocationEvent({ agent: agent, invocationState: {} }));
40
40
  });
41
41
  it('returns AgentResult as generator return value', async () => {
42
42
  const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'Hello' });
@@ -89,6 +89,7 @@ describe('Agent', () => {
89
89
  role: 'assistant',
90
90
  content: [new ToolUseBlock({ name: 'testTool', toolUseId: 'tool-1', input: {} })],
91
91
  }),
92
+ invocationState: {},
92
93
  }));
93
94
  expect(afterTools).toBeDefined();
94
95
  expect(afterTools?.type).toBe('afterToolsEvent');
@@ -1074,6 +1075,25 @@ describe('Agent', () => {
1074
1075
  const second = await agent.invoke('Second');
1075
1076
  expect(second.structuredOutput).toEqual({ name: 'Bob' });
1076
1077
  });
1078
+ it('skips structured output extraction when AfterToolsEvent.endTurn halts the loop', async () => {
1079
+ const schema = z.object({ name: z.string() });
1080
+ const model = new MockMessageModel()
1081
+ .addTurn({
1082
+ type: 'toolUseBlock',
1083
+ name: 'strands_structured_output',
1084
+ toolUseId: 'tool-1',
1085
+ input: { name: 'John' },
1086
+ })
1087
+ .addTurn({ type: 'textBlock', text: 'Done' });
1088
+ const agent = new Agent({ model, structuredOutputSchema: schema });
1089
+ agent.addHook(AfterToolsEvent, (event) => {
1090
+ event.endTurn = true;
1091
+ });
1092
+ const result = await agent.invoke('Test');
1093
+ expect(result.stopReason).toBe('endTurn');
1094
+ expect(result.structuredOutput).toBeUndefined();
1095
+ expect(model.callCount).toBe(1);
1096
+ });
1077
1097
  });
1078
1098
  });
1079
1099
  describe('Agent._redactLastMessage', () => {
@@ -1155,4 +1175,199 @@ describe('Agent._redactLastMessage', () => {
1155
1175
  expect(agent['messages']).toHaveLength(0);
1156
1176
  });
1157
1177
  });
1178
+ describe('_estimateInputTokens', () => {
1179
+ function captureProjectedTokens(agent) {
1180
+ return new Promise((resolve) => {
1181
+ agent.addHook(BeforeModelCallEvent, (event) => {
1182
+ resolve(event.projectedInputTokens);
1183
+ });
1184
+ });
1185
+ }
1186
+ it('uses full estimation on cold start (no prior usage metadata)', async () => {
1187
+ const model = new MockMessageModel();
1188
+ model.addTurn({ type: 'textBlock', text: 'Hello' });
1189
+ const countTokensSpy = vi.spyOn(model, 'countTokens');
1190
+ countTokensSpy.mockResolvedValue(42);
1191
+ const agent = new Agent({ model, printer: false });
1192
+ const tokenPromise = captureProjectedTokens(agent);
1193
+ await agent.invoke('Hi');
1194
+ expect(await tokenPromise).toBe(42);
1195
+ expect(countTokensSpy).toHaveBeenCalledWith(expect.any(Array), expect.any(Object));
1196
+ });
1197
+ it('uses known baseline when no new messages after last assistant', async () => {
1198
+ const model = new MockMessageModel();
1199
+ model.addTurn({ type: 'textBlock', text: 'Hello' });
1200
+ const agent = new Agent({
1201
+ model,
1202
+ printer: false,
1203
+ messages: [
1204
+ new Message({ role: 'user', content: [new TextBlock('Hi')] }),
1205
+ new Message({
1206
+ role: 'assistant',
1207
+ content: [new TextBlock('Hello')],
1208
+ metadata: { usage: { inputTokens: 100, outputTokens: 20, totalTokens: 120 } },
1209
+ }),
1210
+ ],
1211
+ });
1212
+ // Invoke with no args — no new user message appended, so the last assistant
1213
+ // message is still the final message and newMessages.length === 0
1214
+ const tokenPromise = captureProjectedTokens(agent);
1215
+ await agent.invoke([]);
1216
+ // baseline = inputTokens(100) + outputTokens(20) = 120
1217
+ expect(await tokenPromise).toBe(120);
1218
+ });
1219
+ it('returns undefined projectedInputTokens when estimation fails', async () => {
1220
+ const model = new MockMessageModel();
1221
+ model.addTurn({ type: 'textBlock', text: 'Hello' });
1222
+ vi.spyOn(model, 'countTokens').mockRejectedValue(new Error('API unavailable'));
1223
+ const agent = new Agent({ model, printer: false });
1224
+ const tokenPromise = captureProjectedTokens(agent);
1225
+ await agent.invoke('Hi');
1226
+ expect(await tokenPromise).toBeUndefined();
1227
+ });
1228
+ it('estimates delta for new messages after last assistant', async () => {
1229
+ const model = new MockMessageModel();
1230
+ model
1231
+ .addTurn([{ type: 'toolUseBlock', name: 'test', toolUseId: 'id-1', input: {} }], {
1232
+ usage: { inputTokens: 100, outputTokens: 30, totalTokens: 130 },
1233
+ })
1234
+ .addTurn({ type: 'textBlock', text: 'Done' });
1235
+ const countTokensSpy = vi.spyOn(model, 'countTokens');
1236
+ countTokensSpy.mockResolvedValue(50);
1237
+ const tool = createMockTool('test', () => new ToolResultBlock({
1238
+ toolUseId: 'id-1',
1239
+ status: 'success',
1240
+ content: [new TextBlock('result')],
1241
+ }));
1242
+ const agent = new Agent({ model, tools: [tool], printer: false });
1243
+ // Capture the second BeforeModelCallEvent (after tool execution)
1244
+ let callCount = 0;
1245
+ const tokenPromise = new Promise((resolve) => {
1246
+ agent.addHook(BeforeModelCallEvent, (event) => {
1247
+ callCount++;
1248
+ if (callCount === 2)
1249
+ resolve(event.projectedInputTokens);
1250
+ });
1251
+ });
1252
+ await agent.invoke('Use the tool');
1253
+ // baseline (100+30) + estimated delta (50) = 180
1254
+ expect(await tokenPromise).toBe(180);
1255
+ expect(countTokensSpy).toHaveBeenCalled();
1256
+ });
1257
+ it('uses baseline from prior invocation on second invoke', async () => {
1258
+ const model = new MockMessageModel();
1259
+ model
1260
+ .addTurn({ type: 'textBlock', text: 'First response' }, { usage: { inputTokens: 200, outputTokens: 50, totalTokens: 250 } })
1261
+ .addTurn({ type: 'textBlock', text: 'Second response' });
1262
+ const countTokensSpy = vi.spyOn(model, 'countTokens');
1263
+ countTokensSpy.mockResolvedValue(15);
1264
+ const agent = new Agent({ model, printer: false });
1265
+ await agent.invoke('First question');
1266
+ // Second invocation — the user message "Second question" is appended after
1267
+ // the assistant message with usage metadata, so it hits the baseline + delta path
1268
+ const tokenPromise = captureProjectedTokens(agent);
1269
+ await agent.invoke('Second question');
1270
+ // baseline (200+50) + estimated delta for new user message (15) = 265
1271
+ expect(await tokenPromise).toBe(265);
1272
+ });
1273
+ });
1274
+ describe('normalizeToolUseNames', () => {
1275
+ it('replaces invalid tool-use names with INVALID_TOOL_NAME before calling model', async () => {
1276
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'ok' });
1277
+ const streamSpy = vi.spyOn(model, 'stream');
1278
+ const agent = new Agent({
1279
+ model,
1280
+ printer: false,
1281
+ messages: [
1282
+ new Message({ role: 'user', content: [new TextBlock('do thing')] }),
1283
+ new Message({
1284
+ role: 'assistant',
1285
+ content: [new ToolUseBlock({ name: 'bad name!', toolUseId: 'tu-1', input: {} })],
1286
+ }),
1287
+ new Message({
1288
+ role: 'user',
1289
+ content: [
1290
+ new ToolResultBlock({
1291
+ toolUseId: 'tu-1',
1292
+ status: 'success',
1293
+ content: [new TextBlock('result')],
1294
+ }),
1295
+ ],
1296
+ }),
1297
+ ],
1298
+ });
1299
+ await agent.invoke('continue');
1300
+ const sentMessages = streamSpy.mock.calls[0]?.[0];
1301
+ const sentToolUse = sentMessages
1302
+ .find((m) => m.role === 'assistant')
1303
+ .content.find((b) => b.type === 'toolUseBlock');
1304
+ expect(sentToolUse).toStrictEqual(new ToolUseBlock({ name: 'INVALID_TOOL_NAME', toolUseId: 'tu-1', input: {} }));
1305
+ // Agent's stored history is not mutated.
1306
+ const storedToolUse = agent.messages
1307
+ .find((m) => m.role === 'assistant')
1308
+ .content.find((b) => b.type === 'toolUseBlock');
1309
+ expect(storedToolUse).toStrictEqual(new ToolUseBlock({ name: 'bad name!', toolUseId: 'tu-1', input: {} }));
1310
+ });
1311
+ it('preserves reasoningSignature on replaced tool-use blocks', async () => {
1312
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'ok' });
1313
+ const streamSpy = vi.spyOn(model, 'stream');
1314
+ const agent = new Agent({
1315
+ model,
1316
+ printer: false,
1317
+ messages: [
1318
+ new Message({ role: 'user', content: [new TextBlock('do thing')] }),
1319
+ new Message({
1320
+ role: 'assistant',
1321
+ content: [new ToolUseBlock({ name: 'bad!', toolUseId: 'tu-1', input: {}, reasoningSignature: 'sig-abc' })],
1322
+ }),
1323
+ new Message({
1324
+ role: 'user',
1325
+ content: [new ToolResultBlock({ toolUseId: 'tu-1', status: 'success', content: [new TextBlock('ok')] })],
1326
+ }),
1327
+ ],
1328
+ });
1329
+ await agent.invoke('continue');
1330
+ const sentMessages = streamSpy.mock.calls[0]?.[0];
1331
+ const sentToolUse = sentMessages
1332
+ .find((m) => m.role === 'assistant')
1333
+ .content.find((b) => b.type === 'toolUseBlock');
1334
+ expect(sentToolUse).toStrictEqual(new ToolUseBlock({
1335
+ name: 'INVALID_TOOL_NAME',
1336
+ toolUseId: 'tu-1',
1337
+ input: {},
1338
+ reasoningSignature: 'sig-abc',
1339
+ }));
1340
+ });
1341
+ it('leaves valid names untouched', async () => {
1342
+ const model = new MockMessageModel().addTurn({ type: 'textBlock', text: 'ok' });
1343
+ const streamSpy = vi.spyOn(model, 'stream');
1344
+ const agent = new Agent({
1345
+ model,
1346
+ printer: false,
1347
+ messages: [
1348
+ new Message({ role: 'user', content: [new TextBlock('do thing')] }),
1349
+ new Message({
1350
+ role: 'assistant',
1351
+ content: [new ToolUseBlock({ name: 'good_tool-1', toolUseId: 'tu-1', input: {} })],
1352
+ }),
1353
+ new Message({
1354
+ role: 'user',
1355
+ content: [
1356
+ new ToolResultBlock({
1357
+ toolUseId: 'tu-1',
1358
+ status: 'success',
1359
+ content: [new TextBlock('result')],
1360
+ }),
1361
+ ],
1362
+ }),
1363
+ ],
1364
+ });
1365
+ await agent.invoke('continue');
1366
+ const sentMessages = streamSpy.mock.calls[0]?.[0];
1367
+ const sentToolUse = sentMessages
1368
+ .find((m) => m.role === 'assistant')
1369
+ .content.find((b) => b.type === 'toolUseBlock');
1370
+ expect(sentToolUse).toStrictEqual(new ToolUseBlock({ name: 'good_tool-1', toolUseId: 'tu-1', input: {} }));
1371
+ });
1372
+ });
1158
1373
  //# sourceMappingURL=agent.test.js.map