@strands-agents/sdk 0.0.1

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 (423) hide show
  1. package/LICENSE +175 -0
  2. package/README.md +185 -0
  3. package/dist/__fixtures__/model-test-helpers.d.ts +56 -0
  4. package/dist/__fixtures__/model-test-helpers.d.ts.map +1 -0
  5. package/dist/__fixtures__/model-test-helpers.js +85 -0
  6. package/dist/__fixtures__/model-test-helpers.js.map +1 -0
  7. package/dist/__fixtures__/tool-helpers.d.ts +15 -0
  8. package/dist/__fixtures__/tool-helpers.d.ts.map +1 -0
  9. package/dist/__fixtures__/tool-helpers.js +22 -0
  10. package/dist/__fixtures__/tool-helpers.js.map +1 -0
  11. package/dist/__tests__/errors.test.d.ts +2 -0
  12. package/dist/__tests__/errors.test.d.ts.map +1 -0
  13. package/dist/__tests__/errors.test.js +20 -0
  14. package/dist/__tests__/errors.test.js.map +1 -0
  15. package/dist/__tests__/index.test.d.ts +2 -0
  16. package/dist/__tests__/index.test.d.ts.map +1 -0
  17. package/dist/__tests__/index.test.js +27 -0
  18. package/dist/__tests__/index.test.js.map +1 -0
  19. package/dist/errors.d.ts +22 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +25 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +19 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +17 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/models/__tests__/bedrock.test.d.ts +2 -0
  28. package/dist/models/__tests__/bedrock.test.d.ts.map +1 -0
  29. package/dist/models/__tests__/bedrock.test.js +1161 -0
  30. package/dist/models/__tests__/bedrock.test.js.map +1 -0
  31. package/dist/models/__tests__/model.test.d.ts +2 -0
  32. package/dist/models/__tests__/model.test.d.ts.map +1 -0
  33. package/dist/models/__tests__/model.test.js +297 -0
  34. package/dist/models/__tests__/model.test.js.map +1 -0
  35. package/dist/models/__tests__/openai.test.d.ts +2 -0
  36. package/dist/models/__tests__/openai.test.d.ts.map +1 -0
  37. package/dist/models/__tests__/openai.test.js +1016 -0
  38. package/dist/models/__tests__/openai.test.js.map +1 -0
  39. package/dist/models/__tests__/test-utils.d.ts +10 -0
  40. package/dist/models/__tests__/test-utils.d.ts.map +1 -0
  41. package/dist/models/__tests__/test-utils.js +17 -0
  42. package/dist/models/__tests__/test-utils.js.map +1 -0
  43. package/dist/models/bedrock.d.ts +272 -0
  44. package/dist/models/bedrock.d.ts.map +1 -0
  45. package/dist/models/bedrock.js +679 -0
  46. package/dist/models/bedrock.js.map +1 -0
  47. package/dist/models/model.d.ts +89 -0
  48. package/dist/models/model.d.ts.map +1 -0
  49. package/dist/models/model.js +122 -0
  50. package/dist/models/model.js.map +1 -0
  51. package/dist/models/openai.d.ts +262 -0
  52. package/dist/models/openai.d.ts.map +1 -0
  53. package/dist/models/openai.js +625 -0
  54. package/dist/models/openai.js.map +1 -0
  55. package/dist/models/streaming.d.ts +226 -0
  56. package/dist/models/streaming.d.ts.map +1 -0
  57. package/dist/models/streaming.js +2 -0
  58. package/dist/models/streaming.js.map +1 -0
  59. package/dist/src/__fixtures__/agent-helpers.d.ts +29 -0
  60. package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -0
  61. package/dist/src/__fixtures__/agent-helpers.js +19 -0
  62. package/dist/src/__fixtures__/agent-helpers.js.map +1 -0
  63. package/dist/src/__fixtures__/environment.d.ts +12 -0
  64. package/dist/src/__fixtures__/environment.d.ts.map +1 -0
  65. package/dist/src/__fixtures__/environment.js +12 -0
  66. package/dist/src/__fixtures__/environment.js.map +1 -0
  67. package/dist/src/__fixtures__/mock-hook-provider.d.ts +14 -0
  68. package/dist/src/__fixtures__/mock-hook-provider.d.ts.map +1 -0
  69. package/dist/src/__fixtures__/mock-hook-provider.js +33 -0
  70. package/dist/src/__fixtures__/mock-hook-provider.js.map +1 -0
  71. package/dist/src/__fixtures__/mock-message-model.d.ts +93 -0
  72. package/dist/src/__fixtures__/mock-message-model.d.ts.map +1 -0
  73. package/dist/src/__fixtures__/mock-message-model.js +226 -0
  74. package/dist/src/__fixtures__/mock-message-model.js.map +1 -0
  75. package/dist/src/__fixtures__/model-test-helpers.d.ts +56 -0
  76. package/dist/src/__fixtures__/model-test-helpers.d.ts.map +1 -0
  77. package/dist/src/__fixtures__/model-test-helpers.js +85 -0
  78. package/dist/src/__fixtures__/model-test-helpers.js.map +1 -0
  79. package/dist/src/__fixtures__/tool-helpers.d.ts +37 -0
  80. package/dist/src/__fixtures__/tool-helpers.d.ts.map +1 -0
  81. package/dist/src/__fixtures__/tool-helpers.js +78 -0
  82. package/dist/src/__fixtures__/tool-helpers.js.map +1 -0
  83. package/dist/src/__tests__/errors.test.d.ts +2 -0
  84. package/dist/src/__tests__/errors.test.d.ts.map +1 -0
  85. package/dist/src/__tests__/errors.test.js +64 -0
  86. package/dist/src/__tests__/errors.test.js.map +1 -0
  87. package/dist/src/__tests__/index.test.d.ts +2 -0
  88. package/dist/src/__tests__/index.test.d.ts.map +1 -0
  89. package/dist/src/__tests__/index.test.js +27 -0
  90. package/dist/src/__tests__/index.test.js.map +1 -0
  91. package/dist/src/__tests__/mcp.test.d.ts +2 -0
  92. package/dist/src/__tests__/mcp.test.d.ts.map +1 -0
  93. package/dist/src/__tests__/mcp.test.js +166 -0
  94. package/dist/src/__tests__/mcp.test.js.map +1 -0
  95. package/dist/src/agent/__tests__/agent.hook.test.d.ts +2 -0
  96. package/dist/src/agent/__tests__/agent.hook.test.d.ts.map +1 -0
  97. package/dist/src/agent/__tests__/agent.hook.test.js +250 -0
  98. package/dist/src/agent/__tests__/agent.hook.test.js.map +1 -0
  99. package/dist/src/agent/__tests__/agent.test.d.ts +2 -0
  100. package/dist/src/agent/__tests__/agent.test.d.ts.map +1 -0
  101. package/dist/src/agent/__tests__/agent.test.js +414 -0
  102. package/dist/src/agent/__tests__/agent.test.js.map +1 -0
  103. package/dist/src/agent/__tests__/printer.test.d.ts +2 -0
  104. package/dist/src/agent/__tests__/printer.test.d.ts.map +1 -0
  105. package/dist/src/agent/__tests__/printer.test.js +152 -0
  106. package/dist/src/agent/__tests__/printer.test.js.map +1 -0
  107. package/dist/src/agent/__tests__/state.test.d.ts +2 -0
  108. package/dist/src/agent/__tests__/state.test.d.ts.map +1 -0
  109. package/dist/src/agent/__tests__/state.test.js +231 -0
  110. package/dist/src/agent/__tests__/state.test.js.map +1 -0
  111. package/dist/src/agent/agent.d.ts +207 -0
  112. package/dist/src/agent/agent.d.ts.map +1 -0
  113. package/dist/src/agent/agent.js +481 -0
  114. package/dist/src/agent/agent.js.map +1 -0
  115. package/dist/src/agent/printer.d.ts +73 -0
  116. package/dist/src/agent/printer.d.ts.map +1 -0
  117. package/dist/src/agent/printer.js +145 -0
  118. package/dist/src/agent/printer.js.map +1 -0
  119. package/dist/src/agent/state.d.ts +102 -0
  120. package/dist/src/agent/state.d.ts.map +1 -0
  121. package/dist/src/agent/state.js +73 -0
  122. package/dist/src/agent/state.js.map +1 -0
  123. package/dist/src/agent/streaming.d.ts +91 -0
  124. package/dist/src/agent/streaming.d.ts.map +1 -0
  125. package/dist/src/agent/streaming.js +2 -0
  126. package/dist/src/agent/streaming.js.map +1 -0
  127. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts +2 -0
  128. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts.map +1 -0
  129. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +10 -0
  130. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +1 -0
  131. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts +2 -0
  132. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts.map +1 -0
  133. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +35 -0
  134. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +1 -0
  135. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts +2 -0
  136. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts.map +1 -0
  137. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +553 -0
  138. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +1 -0
  139. package/dist/src/conversation-manager/conversation-manager.d.ts +73 -0
  140. package/dist/src/conversation-manager/conversation-manager.d.ts.map +1 -0
  141. package/dist/src/conversation-manager/conversation-manager.js +24 -0
  142. package/dist/src/conversation-manager/conversation-manager.js.map +1 -0
  143. package/dist/src/conversation-manager/index.d.ts +8 -0
  144. package/dist/src/conversation-manager/index.d.ts.map +1 -0
  145. package/dist/src/conversation-manager/index.js +8 -0
  146. package/dist/src/conversation-manager/index.js.map +1 -0
  147. package/dist/src/conversation-manager/null-conversation-manager.d.ts +23 -0
  148. package/dist/src/conversation-manager/null-conversation-manager.d.ts.map +1 -0
  149. package/dist/src/conversation-manager/null-conversation-manager.js +23 -0
  150. package/dist/src/conversation-manager/null-conversation-manager.js.map +1 -0
  151. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts +105 -0
  152. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -0
  153. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +212 -0
  154. package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -0
  155. package/dist/src/errors.d.ts +83 -0
  156. package/dist/src/errors.d.ts.map +1 -0
  157. package/dist/src/errors.js +97 -0
  158. package/dist/src/errors.js.map +1 -0
  159. package/dist/src/hooks/__tests__/events.test.d.ts +2 -0
  160. package/dist/src/hooks/__tests__/events.test.d.ts.map +1 -0
  161. package/dist/src/hooks/__tests__/events.test.js +347 -0
  162. package/dist/src/hooks/__tests__/events.test.js.map +1 -0
  163. package/dist/src/hooks/__tests__/registry.test.d.ts +2 -0
  164. package/dist/src/hooks/__tests__/registry.test.d.ts.map +1 -0
  165. package/dist/src/hooks/__tests__/registry.test.js +154 -0
  166. package/dist/src/hooks/__tests__/registry.test.js.map +1 -0
  167. package/dist/src/hooks/events.d.ts +199 -0
  168. package/dist/src/hooks/events.d.ts.map +1 -0
  169. package/dist/src/hooks/events.js +191 -0
  170. package/dist/src/hooks/events.js.map +1 -0
  171. package/dist/src/hooks/index.d.ts +11 -0
  172. package/dist/src/hooks/index.d.ts.map +1 -0
  173. package/dist/src/hooks/index.js +11 -0
  174. package/dist/src/hooks/index.js.map +1 -0
  175. package/dist/src/hooks/registry.d.ts +65 -0
  176. package/dist/src/hooks/registry.d.ts.map +1 -0
  177. package/dist/src/hooks/registry.js +65 -0
  178. package/dist/src/hooks/registry.js.map +1 -0
  179. package/dist/src/hooks/types.d.ts +49 -0
  180. package/dist/src/hooks/types.d.ts.map +1 -0
  181. package/dist/src/hooks/types.js +2 -0
  182. package/dist/src/hooks/types.js.map +1 -0
  183. package/dist/src/index.d.ts +32 -0
  184. package/dist/src/index.d.ts.map +1 -0
  185. package/dist/src/index.js +29 -0
  186. package/dist/src/index.js.map +1 -0
  187. package/dist/src/mcp.d.ts +51 -0
  188. package/dist/src/mcp.d.ts.map +1 -0
  189. package/dist/src/mcp.js +91 -0
  190. package/dist/src/mcp.js.map +1 -0
  191. package/dist/src/models/__tests__/bedrock.test.d.ts +2 -0
  192. package/dist/src/models/__tests__/bedrock.test.d.ts.map +1 -0
  193. package/dist/src/models/__tests__/bedrock.test.js +1388 -0
  194. package/dist/src/models/__tests__/bedrock.test.js.map +1 -0
  195. package/dist/src/models/__tests__/model.test.d.ts +2 -0
  196. package/dist/src/models/__tests__/model.test.d.ts.map +1 -0
  197. package/dist/src/models/__tests__/model.test.js +342 -0
  198. package/dist/src/models/__tests__/model.test.js.map +1 -0
  199. package/dist/src/models/__tests__/openai.test.d.ts +2 -0
  200. package/dist/src/models/__tests__/openai.test.d.ts.map +1 -0
  201. package/dist/src/models/__tests__/openai.test.js +1189 -0
  202. package/dist/src/models/__tests__/openai.test.js.map +1 -0
  203. package/dist/src/models/__tests__/test-utils.d.ts +10 -0
  204. package/dist/src/models/__tests__/test-utils.d.ts.map +1 -0
  205. package/dist/src/models/__tests__/test-utils.js +17 -0
  206. package/dist/src/models/__tests__/test-utils.js.map +1 -0
  207. package/dist/src/models/bedrock.d.ts +289 -0
  208. package/dist/src/models/bedrock.d.ts.map +1 -0
  209. package/dist/src/models/bedrock.js +804 -0
  210. package/dist/src/models/bedrock.js.map +1 -0
  211. package/dist/src/models/model.d.ts +99 -0
  212. package/dist/src/models/model.d.ts.map +1 -0
  213. package/dist/src/models/model.js +169 -0
  214. package/dist/src/models/model.js.map +1 -0
  215. package/dist/src/models/openai.d.ts +262 -0
  216. package/dist/src/models/openai.d.ts.map +1 -0
  217. package/dist/src/models/openai.js +752 -0
  218. package/dist/src/models/openai.js.map +1 -0
  219. package/dist/src/models/streaming.d.ts +318 -0
  220. package/dist/src/models/streaming.d.ts.map +1 -0
  221. package/dist/src/models/streaming.js +122 -0
  222. package/dist/src/models/streaming.js.map +1 -0
  223. package/dist/src/registry/registry.d.ts +117 -0
  224. package/dist/src/registry/registry.d.ts.map +1 -0
  225. package/dist/src/registry/registry.js +298 -0
  226. package/dist/src/registry/registry.js.map +1 -0
  227. package/dist/src/registry/tool-registry.d.ts +34 -0
  228. package/dist/src/registry/tool-registry.d.ts.map +1 -0
  229. package/dist/src/registry/tool-registry.js +178 -0
  230. package/dist/src/registry/tool-registry.js.map +1 -0
  231. package/dist/src/tools/__tests__/tool.test.d.ts +2 -0
  232. package/dist/src/tools/__tests__/tool.test.d.ts.map +1 -0
  233. package/dist/src/tools/__tests__/tool.test.js +877 -0
  234. package/dist/src/tools/__tests__/tool.test.js.map +1 -0
  235. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts +2 -0
  236. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts.map +1 -0
  237. package/dist/src/tools/__tests__/zod-tool.test-d.js +227 -0
  238. package/dist/src/tools/__tests__/zod-tool.test-d.js.map +1 -0
  239. package/dist/src/tools/__tests__/zod-tool.test.d.ts +2 -0
  240. package/dist/src/tools/__tests__/zod-tool.test.d.ts.map +1 -0
  241. package/dist/src/tools/__tests__/zod-tool.test.js +372 -0
  242. package/dist/src/tools/__tests__/zod-tool.test.js.map +1 -0
  243. package/dist/src/tools/function-tool.d.ts +146 -0
  244. package/dist/src/tools/function-tool.d.ts.map +1 -0
  245. package/dist/src/tools/function-tool.js +188 -0
  246. package/dist/src/tools/function-tool.js.map +1 -0
  247. package/dist/src/tools/mcp-tool.d.ts +36 -0
  248. package/dist/src/tools/mcp-tool.d.ts.map +1 -0
  249. package/dist/src/tools/mcp-tool.js +78 -0
  250. package/dist/src/tools/mcp-tool.js.map +1 -0
  251. package/dist/src/tools/tool.d.ts +167 -0
  252. package/dist/src/tools/tool.d.ts.map +1 -0
  253. package/dist/src/tools/tool.js +68 -0
  254. package/dist/src/tools/tool.js.map +1 -0
  255. package/dist/src/tools/types.d.ts +62 -0
  256. package/dist/src/tools/types.d.ts.map +1 -0
  257. package/dist/src/tools/types.js +2 -0
  258. package/dist/src/tools/types.js.map +1 -0
  259. package/dist/src/tools/zod-tool.d.ts +70 -0
  260. package/dist/src/tools/zod-tool.d.ts.map +1 -0
  261. package/dist/src/tools/zod-tool.js +149 -0
  262. package/dist/src/tools/zod-tool.js.map +1 -0
  263. package/dist/src/types/__tests__/agent.test.d.ts +2 -0
  264. package/dist/src/types/__tests__/agent.test.d.ts.map +1 -0
  265. package/dist/src/types/__tests__/agent.test.js +155 -0
  266. package/dist/src/types/__tests__/agent.test.js.map +1 -0
  267. package/dist/src/types/__tests__/json.test.d.ts +2 -0
  268. package/dist/src/types/__tests__/json.test.d.ts.map +1 -0
  269. package/dist/src/types/__tests__/json.test.js +298 -0
  270. package/dist/src/types/__tests__/json.test.js.map +1 -0
  271. package/dist/src/types/__tests__/media.test.d.ts +2 -0
  272. package/dist/src/types/__tests__/media.test.d.ts.map +1 -0
  273. package/dist/src/types/__tests__/media.test.js +257 -0
  274. package/dist/src/types/__tests__/media.test.js.map +1 -0
  275. package/dist/src/types/__tests__/messages.test.d.ts +2 -0
  276. package/dist/src/types/__tests__/messages.test.d.ts.map +1 -0
  277. package/dist/src/types/__tests__/messages.test.js +364 -0
  278. package/dist/src/types/__tests__/messages.test.js.map +1 -0
  279. package/dist/src/types/__tests__/validation.test.d.ts +2 -0
  280. package/dist/src/types/__tests__/validation.test.d.ts.map +1 -0
  281. package/dist/src/types/__tests__/validation.test.js +30 -0
  282. package/dist/src/types/__tests__/validation.test.js.map +1 -0
  283. package/dist/src/types/agent.d.ts +57 -0
  284. package/dist/src/types/agent.d.ts.map +1 -0
  285. package/dist/src/types/agent.js +47 -0
  286. package/dist/src/types/agent.js.map +1 -0
  287. package/dist/src/types/json.d.ts +55 -0
  288. package/dist/src/types/json.d.ts.map +1 -0
  289. package/dist/src/types/json.js +72 -0
  290. package/dist/src/types/json.js.map +1 -0
  291. package/dist/src/types/media.d.ts +249 -0
  292. package/dist/src/types/media.d.ts.map +1 -0
  293. package/dist/src/types/media.js +173 -0
  294. package/dist/src/types/media.js.map +1 -0
  295. package/dist/src/types/messages.d.ts +438 -0
  296. package/dist/src/types/messages.d.ts.map +1 -0
  297. package/dist/src/types/messages.js +286 -0
  298. package/dist/src/types/messages.js.map +1 -0
  299. package/dist/src/types/validation.d.ts +10 -0
  300. package/dist/src/types/validation.d.ts.map +1 -0
  301. package/dist/src/types/validation.js +15 -0
  302. package/dist/src/types/validation.js.map +1 -0
  303. package/dist/tools/__tests__/registry.test.d.ts +2 -0
  304. package/dist/tools/__tests__/registry.test.d.ts.map +1 -0
  305. package/dist/tools/__tests__/registry.test.js +253 -0
  306. package/dist/tools/__tests__/registry.test.js.map +1 -0
  307. package/dist/tools/__tests__/tool.test.d.ts +2 -0
  308. package/dist/tools/__tests__/tool.test.d.ts.map +1 -0
  309. package/dist/tools/__tests__/tool.test.js +761 -0
  310. package/dist/tools/__tests__/tool.test.js.map +1 -0
  311. package/dist/tools/__tests__/zod-tool.test-d.d.ts +2 -0
  312. package/dist/tools/__tests__/zod-tool.test-d.d.ts.map +1 -0
  313. package/dist/tools/__tests__/zod-tool.test-d.js +227 -0
  314. package/dist/tools/__tests__/zod-tool.test-d.js.map +1 -0
  315. package/dist/tools/__tests__/zod-tool.test.d.ts +2 -0
  316. package/dist/tools/__tests__/zod-tool.test.d.ts.map +1 -0
  317. package/dist/tools/__tests__/zod-tool.test.js +342 -0
  318. package/dist/tools/__tests__/zod-tool.test.js.map +1 -0
  319. package/dist/tools/function-tool.d.ts +156 -0
  320. package/dist/tools/function-tool.d.ts.map +1 -0
  321. package/dist/tools/function-tool.js +237 -0
  322. package/dist/tools/function-tool.js.map +1 -0
  323. package/dist/tools/registry.d.ts +43 -0
  324. package/dist/tools/registry.d.ts.map +1 -0
  325. package/dist/tools/registry.js +82 -0
  326. package/dist/tools/registry.js.map +1 -0
  327. package/dist/tools/tool.d.ts +157 -0
  328. package/dist/tools/tool.d.ts.map +1 -0
  329. package/dist/tools/tool.js +2 -0
  330. package/dist/tools/tool.js.map +1 -0
  331. package/dist/tools/types.d.ts +119 -0
  332. package/dist/tools/types.d.ts.map +1 -0
  333. package/dist/tools/types.js +2 -0
  334. package/dist/tools/types.js.map +1 -0
  335. package/dist/tools/zod-tool.d.ts +70 -0
  336. package/dist/tools/zod-tool.d.ts.map +1 -0
  337. package/dist/tools/zod-tool.js +96 -0
  338. package/dist/tools/zod-tool.js.map +1 -0
  339. package/dist/types/__tests__/json.test.d.ts +2 -0
  340. package/dist/types/__tests__/json.test.d.ts.map +1 -0
  341. package/dist/types/__tests__/json.test.js +129 -0
  342. package/dist/types/__tests__/json.test.js.map +1 -0
  343. package/dist/types/__tests__/validation.test.d.ts +2 -0
  344. package/dist/types/__tests__/validation.test.d.ts.map +1 -0
  345. package/dist/types/__tests__/validation.test.js +30 -0
  346. package/dist/types/__tests__/validation.test.js.map +1 -0
  347. package/dist/types/json.d.ts +45 -0
  348. package/dist/types/json.d.ts.map +1 -0
  349. package/dist/types/json.js +17 -0
  350. package/dist/types/json.js.map +1 -0
  351. package/dist/types/messages.d.ts +160 -0
  352. package/dist/types/messages.d.ts.map +1 -0
  353. package/dist/types/messages.js +2 -0
  354. package/dist/types/messages.js.map +1 -0
  355. package/dist/types/validation.d.ts +10 -0
  356. package/dist/types/validation.d.ts.map +1 -0
  357. package/dist/types/validation.js +15 -0
  358. package/dist/types/validation.js.map +1 -0
  359. package/dist/vended_tools/bash/__tests__/bash.test.d.ts +2 -0
  360. package/dist/vended_tools/bash/__tests__/bash.test.d.ts.map +1 -0
  361. package/dist/vended_tools/bash/__tests__/bash.test.js +333 -0
  362. package/dist/vended_tools/bash/__tests__/bash.test.js.map +1 -0
  363. package/dist/vended_tools/bash/bash.d.ts +33 -0
  364. package/dist/vended_tools/bash/bash.d.ts.map +1 -0
  365. package/dist/vended_tools/bash/bash.js +264 -0
  366. package/dist/vended_tools/bash/bash.js.map +1 -0
  367. package/dist/vended_tools/bash/index.d.ts +7 -0
  368. package/dist/vended_tools/bash/index.d.ts.map +1 -0
  369. package/dist/vended_tools/bash/index.js +6 -0
  370. package/dist/vended_tools/bash/index.js.map +1 -0
  371. package/dist/vended_tools/bash/types.d.ts +65 -0
  372. package/dist/vended_tools/bash/types.d.ts.map +1 -0
  373. package/dist/vended_tools/bash/types.js +22 -0
  374. package/dist/vended_tools/bash/types.js.map +1 -0
  375. package/dist/vended_tools/file_editor/__tests__/file-editor.test.d.ts +2 -0
  376. package/dist/vended_tools/file_editor/__tests__/file-editor.test.d.ts.map +1 -0
  377. package/dist/vended_tools/file_editor/__tests__/file-editor.test.js +359 -0
  378. package/dist/vended_tools/file_editor/__tests__/file-editor.test.js.map +1 -0
  379. package/dist/vended_tools/file_editor/file-editor.d.ts +31 -0
  380. package/dist/vended_tools/file_editor/file-editor.d.ts.map +1 -0
  381. package/dist/vended_tools/file_editor/file-editor.js +353 -0
  382. package/dist/vended_tools/file_editor/file-editor.js.map +1 -0
  383. package/dist/vended_tools/file_editor/index.d.ts +6 -0
  384. package/dist/vended_tools/file_editor/index.d.ts.map +1 -0
  385. package/dist/vended_tools/file_editor/index.js +5 -0
  386. package/dist/vended_tools/file_editor/index.js.map +1 -0
  387. package/dist/vended_tools/file_editor/types.d.ts +61 -0
  388. package/dist/vended_tools/file_editor/types.d.ts.map +1 -0
  389. package/dist/vended_tools/file_editor/types.js +2 -0
  390. package/dist/vended_tools/file_editor/types.js.map +1 -0
  391. package/dist/vended_tools/http_request/__tests__/http-request.test.d.ts +2 -0
  392. package/dist/vended_tools/http_request/__tests__/http-request.test.d.ts.map +1 -0
  393. package/dist/vended_tools/http_request/__tests__/http-request.test.js +189 -0
  394. package/dist/vended_tools/http_request/__tests__/http-request.test.js.map +1 -0
  395. package/dist/vended_tools/http_request/http-request.d.ts +35 -0
  396. package/dist/vended_tools/http_request/http-request.d.ts.map +1 -0
  397. package/dist/vended_tools/http_request/http-request.js +95 -0
  398. package/dist/vended_tools/http_request/http-request.js.map +1 -0
  399. package/dist/vended_tools/http_request/index.d.ts +6 -0
  400. package/dist/vended_tools/http_request/index.d.ts.map +1 -0
  401. package/dist/vended_tools/http_request/index.js +5 -0
  402. package/dist/vended_tools/http_request/index.js.map +1 -0
  403. package/dist/vended_tools/http_request/types.d.ts +47 -0
  404. package/dist/vended_tools/http_request/types.d.ts.map +1 -0
  405. package/dist/vended_tools/http_request/types.js +2 -0
  406. package/dist/vended_tools/http_request/types.js.map +1 -0
  407. package/dist/vended_tools/notebook/__tests__/notebook.test.d.ts +2 -0
  408. package/dist/vended_tools/notebook/__tests__/notebook.test.d.ts.map +1 -0
  409. package/dist/vended_tools/notebook/__tests__/notebook.test.js +371 -0
  410. package/dist/vended_tools/notebook/__tests__/notebook.test.js.map +1 -0
  411. package/dist/vended_tools/notebook/index.d.ts +6 -0
  412. package/dist/vended_tools/notebook/index.d.ts.map +1 -0
  413. package/dist/vended_tools/notebook/index.js +5 -0
  414. package/dist/vended_tools/notebook/index.js.map +1 -0
  415. package/dist/vended_tools/notebook/notebook.d.ts +29 -0
  416. package/dist/vended_tools/notebook/notebook.d.ts.map +1 -0
  417. package/dist/vended_tools/notebook/notebook.js +215 -0
  418. package/dist/vended_tools/notebook/notebook.js.map +1 -0
  419. package/dist/vended_tools/notebook/types.d.ts +79 -0
  420. package/dist/vended_tools/notebook/types.d.ts.map +1 -0
  421. package/dist/vended_tools/notebook/types.js +2 -0
  422. package/dist/vended_tools/notebook/types.js.map +1 -0
  423. package/package.json +112 -0
@@ -0,0 +1,761 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { FunctionTool } from '../function-tool';
3
+ import { collectGenerator } from '../../__fixtures__/model-test-helpers';
4
+ describe('FunctionTool', () => {
5
+ describe('properties', () => {
6
+ it('has a non-empty toolName', () => {
7
+ const tool = new FunctionTool({
8
+ name: 'testTool',
9
+ description: 'Test description',
10
+ inputSchema: { type: 'object' },
11
+ callback: () => 'result',
12
+ });
13
+ expect(tool.toolName).toBeTruthy();
14
+ expect(typeof tool.toolName).toBe('string');
15
+ expect(tool.toolName.length).toBeGreaterThan(0);
16
+ expect(tool.toolName).toBe('testTool');
17
+ });
18
+ it('has a non-empty description', () => {
19
+ const tool = new FunctionTool({
20
+ name: 'testTool',
21
+ description: 'Test description',
22
+ inputSchema: { type: 'object' },
23
+ callback: () => 'result',
24
+ });
25
+ expect(tool.description).toBeTruthy();
26
+ expect(typeof tool.description).toBe('string');
27
+ expect(tool.description.length).toBeGreaterThan(0);
28
+ expect(tool.description).toBe('Test description');
29
+ });
30
+ it('has a valid toolSpec', () => {
31
+ const inputSchema = {
32
+ type: 'object',
33
+ properties: {
34
+ value: { type: 'string' },
35
+ },
36
+ };
37
+ const tool = new FunctionTool({
38
+ name: 'testTool',
39
+ description: 'Test description',
40
+ inputSchema,
41
+ callback: () => 'result',
42
+ });
43
+ // Verify entire toolSpec object at once
44
+ expect(tool.toolSpec).toEqual({
45
+ name: 'testTool',
46
+ description: 'Test description',
47
+ inputSchema,
48
+ });
49
+ });
50
+ it('has matching toolName and toolSpec.name', () => {
51
+ const tool = new FunctionTool({
52
+ name: 'testTool',
53
+ description: 'Test description',
54
+ inputSchema: { type: 'object' },
55
+ callback: () => 'result',
56
+ });
57
+ expect(tool.toolName).toBe(tool.toolSpec.name);
58
+ });
59
+ it('has matching description and toolSpec.description', () => {
60
+ const tool = new FunctionTool({
61
+ name: 'testTool',
62
+ description: 'Test description',
63
+ inputSchema: { type: 'object' },
64
+ callback: () => 'result',
65
+ });
66
+ expect(tool.description).toBe(tool.toolSpec.description);
67
+ });
68
+ });
69
+ describe('stream method', () => {
70
+ describe('with synchronous callback', () => {
71
+ it('wraps return value in ToolResult', async () => {
72
+ const tool = new FunctionTool({
73
+ name: 'syncTool',
74
+ description: 'Returns synchronous value',
75
+ inputSchema: { type: 'object', properties: { value: { type: 'number' } } },
76
+ callback: (input) => {
77
+ const { value } = input;
78
+ return value * 2;
79
+ },
80
+ });
81
+ const toolUse = {
82
+ name: 'syncTool',
83
+ toolUseId: 'test-sync-1',
84
+ input: { value: 5 },
85
+ };
86
+ const context = { toolUse, invocationState: {} };
87
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
88
+ // No stream events for sync callback
89
+ expect(streamEvents.length).toBe(0);
90
+ // Verify entire result with actual calculated value
91
+ expect(result).toEqual({
92
+ toolUseId: 'test-sync-1',
93
+ status: 'success',
94
+ content: [
95
+ {
96
+ type: 'toolResultTextContent',
97
+ text: '10', // 5 * 2 = 10 (converted to string)
98
+ },
99
+ ],
100
+ });
101
+ });
102
+ it('handles string return values', async () => {
103
+ const tool = new FunctionTool({
104
+ name: 'stringTool',
105
+ description: 'Returns string',
106
+ inputSchema: { type: 'object' },
107
+ callback: () => 'Hello, World!',
108
+ });
109
+ const toolUse = {
110
+ name: 'stringTool',
111
+ toolUseId: 'test-string',
112
+ input: {},
113
+ };
114
+ const context = { toolUse, invocationState: {} };
115
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
116
+ expect(streamEvents.length).toBe(0);
117
+ // Verify entire result object
118
+ expect(result).toEqual({
119
+ toolUseId: 'test-string',
120
+ status: 'success',
121
+ content: [
122
+ {
123
+ type: 'toolResultTextContent',
124
+ text: 'Hello, World!',
125
+ },
126
+ ],
127
+ });
128
+ });
129
+ it('handles object return values', async () => {
130
+ const tool = new FunctionTool({
131
+ name: 'objectTool',
132
+ description: 'Returns object',
133
+ inputSchema: { type: 'object' },
134
+ callback: () => ({ key: 'value', count: 42 }),
135
+ });
136
+ const toolUse = {
137
+ name: 'objectTool',
138
+ toolUseId: 'test-object',
139
+ input: {},
140
+ };
141
+ const context = { toolUse, invocationState: {} };
142
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
143
+ expect(streamEvents.length).toBe(0);
144
+ // Verify entire result object
145
+ expect(result).toEqual({
146
+ toolUseId: 'test-object',
147
+ status: 'success',
148
+ content: [
149
+ {
150
+ type: 'toolResultJsonContent',
151
+ json: { key: 'value', count: 42 },
152
+ },
153
+ ],
154
+ });
155
+ });
156
+ it('passes input to callback exactly as provided to stream', async () => {
157
+ const inputData = { name: 'test', value: 42, nested: { key: 'value' } };
158
+ let receivedInput;
159
+ const tool = new FunctionTool({
160
+ name: 'inputTool',
161
+ description: 'Captures input',
162
+ inputSchema: { type: 'object' },
163
+ callback: (input) => {
164
+ receivedInput = input;
165
+ return 'success';
166
+ },
167
+ });
168
+ const toolUse = {
169
+ name: 'inputTool',
170
+ toolUseId: 'test-input',
171
+ input: inputData,
172
+ };
173
+ await collectGenerator(tool.stream({ toolUse, invocationState: {} }));
174
+ expect(receivedInput).toEqual(inputData);
175
+ });
176
+ it('handles null return values correctly', async () => {
177
+ const tool = new FunctionTool({
178
+ name: 'nullTool',
179
+ description: 'Returns null',
180
+ inputSchema: { type: 'object' },
181
+ callback: () => null,
182
+ });
183
+ const { result } = await collectGenerator(tool.stream({ toolUse: { name: 'nullTool', toolUseId: 'test-null', input: {} }, invocationState: {} }));
184
+ expect(result).toEqual({
185
+ toolUseId: 'test-null',
186
+ status: 'success',
187
+ content: [{ type: 'toolResultTextContent', text: '<null>' }],
188
+ });
189
+ });
190
+ it('handles undefined return values correctly', async () => {
191
+ const tool = new FunctionTool({
192
+ name: 'undefinedTool',
193
+ description: 'Returns undefined',
194
+ inputSchema: { type: 'object' },
195
+ // @ts-expect-error we're intentionally testing a type violation
196
+ callback: () => undefined,
197
+ });
198
+ const { result } = await collectGenerator(tool.stream({
199
+ toolUse: { name: 'undefinedTool', toolUseId: 'test-undefined', input: {} },
200
+ invocationState: {},
201
+ }));
202
+ expect(result).toEqual({
203
+ toolUseId: 'test-undefined',
204
+ status: 'success',
205
+ content: [{ type: 'toolResultTextContent', text: '<undefined>' }],
206
+ });
207
+ });
208
+ it('handles boolean return values as text content', async () => {
209
+ const trueTool = new FunctionTool({
210
+ name: 'trueTool',
211
+ description: 'Returns true',
212
+ inputSchema: { type: 'object' },
213
+ callback: () => true,
214
+ });
215
+ const { result: trueResult } = await collectGenerator(trueTool.stream({ toolUse: { name: 'trueTool', toolUseId: 'test-true', input: {} }, invocationState: {} }));
216
+ expect(trueResult).toEqual({
217
+ toolUseId: 'test-true',
218
+ status: 'success',
219
+ content: [{ type: 'toolResultTextContent', text: 'true' }],
220
+ });
221
+ const falseTool = new FunctionTool({
222
+ name: 'falseTool',
223
+ description: 'Returns false',
224
+ inputSchema: { type: 'object' },
225
+ callback: () => false,
226
+ });
227
+ const { result: falseResult } = await collectGenerator(falseTool.stream({ toolUse: { name: 'falseTool', toolUseId: 'test-false', input: {} }, invocationState: {} }));
228
+ expect(falseResult).toEqual({
229
+ toolUseId: 'test-false',
230
+ status: 'success',
231
+ content: [{ type: 'toolResultTextContent', text: 'false' }],
232
+ });
233
+ });
234
+ it('handles number return values as text content', async () => {
235
+ const tool = new FunctionTool({
236
+ name: 'numberTool',
237
+ description: 'Returns number',
238
+ inputSchema: { type: 'object' },
239
+ callback: () => 42,
240
+ });
241
+ const { result } = await collectGenerator(tool.stream({ toolUse: { name: 'numberTool', toolUseId: 'test-number', input: {} }, invocationState: {} }));
242
+ expect(result).toEqual({
243
+ toolUseId: 'test-number',
244
+ status: 'success',
245
+ content: [{ type: 'toolResultTextContent', text: '42' }],
246
+ });
247
+ // Test negative number
248
+ const negativeTool = new FunctionTool({
249
+ name: 'negativeTool',
250
+ description: 'Returns negative number',
251
+ inputSchema: { type: 'object' },
252
+ callback: () => -3.14,
253
+ });
254
+ const { result: negativeResult } = await collectGenerator(negativeTool.stream({
255
+ toolUse: { name: 'negativeTool', toolUseId: 'test-negative', input: {} },
256
+ invocationState: {},
257
+ }));
258
+ expect(negativeResult).toEqual({
259
+ toolUseId: 'test-negative',
260
+ status: 'success',
261
+ content: [{ type: 'toolResultTextContent', text: '-3.14' }],
262
+ });
263
+ });
264
+ it('handles array return values as wrapped JSON content', async () => {
265
+ const tool = new FunctionTool({
266
+ name: 'arrayTool',
267
+ description: 'Returns array',
268
+ inputSchema: { type: 'object' },
269
+ callback: () => [1, 2, 3, { key: 'value' }],
270
+ });
271
+ const { result } = await collectGenerator(tool.stream({ toolUse: { name: 'arrayTool', toolUseId: 'test-array', input: {} }, invocationState: {} }));
272
+ expect(result).toEqual({
273
+ toolUseId: 'test-array',
274
+ status: 'success',
275
+ content: [{ type: 'toolResultJsonContent', json: { $value: [1, 2, 3, { key: 'value' }] } }],
276
+ });
277
+ });
278
+ it('deep copies objects to prevent mutation', async () => {
279
+ const original = { nested: { value: 'original' } };
280
+ const tool = new FunctionTool({
281
+ name: 'copyTool',
282
+ description: 'Returns object',
283
+ inputSchema: { type: 'object' },
284
+ callback: () => original,
285
+ });
286
+ const { result } = await collectGenerator(tool.stream({ toolUse: { name: 'copyTool', toolUseId: 'test-copy', input: {} }, invocationState: {} }));
287
+ // Mutate the original object
288
+ original.nested.value = 'mutated';
289
+ // Verify the result still has the original value
290
+ expect(result).toEqual({
291
+ toolUseId: 'test-copy',
292
+ status: 'success',
293
+ content: [{ type: 'toolResultJsonContent', json: { nested: { value: 'original' } } }],
294
+ });
295
+ });
296
+ it('deep copies arrays to prevent mutation', async () => {
297
+ const original = [{ value: 'original' }];
298
+ const tool = new FunctionTool({
299
+ name: 'arrayCopyTool',
300
+ description: 'Returns array',
301
+ inputSchema: { type: 'object' },
302
+ callback: () => original,
303
+ });
304
+ const { result } = await collectGenerator(tool.stream({
305
+ toolUse: { name: 'arrayCopyTool', toolUseId: 'test-array-copy', input: {} },
306
+ invocationState: {},
307
+ }));
308
+ // Mutate the original array
309
+ original[0].value = 'mutated';
310
+ // Verify the result still has the original value (wrapped in $value)
311
+ expect(result).toEqual({
312
+ toolUseId: 'test-array-copy',
313
+ status: 'success',
314
+ content: [{ type: 'toolResultJsonContent', json: { $value: [{ value: 'original' }] } }],
315
+ });
316
+ });
317
+ });
318
+ describe('with promise callback', () => {
319
+ it('wraps resolved value in ToolResult', async () => {
320
+ const tool = new FunctionTool({
321
+ name: 'promiseTool',
322
+ description: 'Returns promise',
323
+ inputSchema: { type: 'object', properties: { value: { type: 'number' } } },
324
+ callback: async (input) => {
325
+ const { value } = input;
326
+ return value + 10;
327
+ },
328
+ });
329
+ const toolUse = {
330
+ name: 'promiseTool',
331
+ toolUseId: 'test-promise-1',
332
+ input: { value: 5 },
333
+ };
334
+ const context = { toolUse, invocationState: {} };
335
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
336
+ expect(streamEvents.length).toBe(0);
337
+ expect(result.toolUseId).toBe('test-promise-1');
338
+ expect(result.status).toBe('success');
339
+ expect(result.status).toBe('success');
340
+ });
341
+ it('can access ToolContext in promise', async () => {
342
+ const tool = new FunctionTool({
343
+ name: 'contextTool',
344
+ description: 'Uses context',
345
+ inputSchema: { type: 'object' },
346
+ callback: async (_input, context) => {
347
+ return context.invocationState;
348
+ },
349
+ });
350
+ const toolUse = {
351
+ name: 'contextTool',
352
+ toolUseId: 'test-context',
353
+ input: {},
354
+ };
355
+ const context = { toolUse, invocationState: { userId: 'user-123' } };
356
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
357
+ expect(streamEvents.length).toBe(0);
358
+ expect(result.status).toBe('success');
359
+ });
360
+ });
361
+ describe('with async generator callback', () => {
362
+ it('yields ToolStreamEvents then final ToolResult', async () => {
363
+ const tool = new FunctionTool({
364
+ name: 'generatorTool',
365
+ description: 'Streams progress',
366
+ inputSchema: { type: 'object' },
367
+ callback: async function* () {
368
+ yield 'Starting...';
369
+ yield 'Processing...';
370
+ yield 'Complete!';
371
+ return 'Final result';
372
+ },
373
+ });
374
+ const toolUse = {
375
+ name: 'generatorTool',
376
+ toolUseId: 'test-gen-1',
377
+ input: {},
378
+ };
379
+ const context = { toolUse, invocationState: {} };
380
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
381
+ // Should have 3 stream events
382
+ expect(streamEvents.length).toBe(3);
383
+ // Verify all stream events are as expected
384
+ expect(streamEvents).toEqual([
385
+ { type: 'toolStreamEvent', data: 'Starting...' },
386
+ { type: 'toolStreamEvent', data: 'Processing...' },
387
+ { type: 'toolStreamEvent', data: 'Complete!' },
388
+ ]);
389
+ // Verify entire result object
390
+ expect(result).toEqual({
391
+ toolUseId: 'test-gen-1',
392
+ status: 'success',
393
+ content: [
394
+ {
395
+ type: 'toolResultTextContent',
396
+ text: 'Final result',
397
+ },
398
+ ],
399
+ });
400
+ });
401
+ it('can yield objects as ToolStreamEvents', async () => {
402
+ const tool = new FunctionTool({
403
+ name: 'objectGenTool',
404
+ description: 'Streams objects',
405
+ inputSchema: { type: 'object' },
406
+ callback: async function* () {
407
+ yield { progress: 0.25, message: 'Quarter done' };
408
+ yield { progress: 0.5, message: 'Halfway done' };
409
+ yield { progress: 1.0, message: 'Complete' };
410
+ return 'Done';
411
+ },
412
+ });
413
+ const toolUse = {
414
+ name: 'objectGenTool',
415
+ toolUseId: 'test-obj-gen',
416
+ input: {},
417
+ };
418
+ const context = { toolUse, invocationState: {} };
419
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
420
+ expect(streamEvents.length).toBe(3);
421
+ // Verify all stream events have data
422
+ for (const event of streamEvents) {
423
+ expect(event.type).toBe('toolStreamEvent');
424
+ expect(event.data).toBeDefined();
425
+ }
426
+ // Verify final result
427
+ expect(result.status).toBe('success');
428
+ });
429
+ });
430
+ describe('error handling', () => {
431
+ it('catches synchronous errors', async () => {
432
+ const tool = new FunctionTool({
433
+ name: 'errorTool',
434
+ description: 'Throws error',
435
+ inputSchema: { type: 'object' },
436
+ callback: () => {
437
+ throw new Error('Something went wrong');
438
+ },
439
+ });
440
+ const toolUse = {
441
+ name: 'errorTool',
442
+ toolUseId: 'test-error-1',
443
+ input: {},
444
+ };
445
+ const context = { toolUse, invocationState: {} };
446
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
447
+ expect(streamEvents.length).toBe(0);
448
+ expect(result.toolUseId).toBe('test-error-1');
449
+ expect(result.status).toBe('error');
450
+ expect(result.content.length).toBeGreaterThan(0);
451
+ expect(result.content[0]).toHaveProperty('type', 'toolResultTextContent');
452
+ });
453
+ it('catches promise rejections', async () => {
454
+ const tool = new FunctionTool({
455
+ name: 'rejectTool',
456
+ description: 'Rejects promise',
457
+ inputSchema: { type: 'object' },
458
+ callback: async () => {
459
+ throw new Error('Promise rejected');
460
+ },
461
+ });
462
+ const toolUse = {
463
+ name: 'rejectTool',
464
+ toolUseId: 'test-error-2',
465
+ input: {},
466
+ };
467
+ const context = { toolUse, invocationState: {} };
468
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
469
+ expect(streamEvents.length).toBe(0);
470
+ expect(result.status).toBe('error');
471
+ });
472
+ it('captures Error object in ToolResult when callback throws Error', async () => {
473
+ const testError = new Error('Test error message');
474
+ const tool = new FunctionTool({
475
+ name: 'errorObjectTool',
476
+ description: 'Throws Error object',
477
+ inputSchema: { type: 'object' },
478
+ callback: () => {
479
+ throw testError;
480
+ },
481
+ });
482
+ const toolUse = {
483
+ name: 'errorObjectTool',
484
+ toolUseId: 'test-error-capture',
485
+ input: {},
486
+ };
487
+ const { result } = await collectGenerator(tool.stream({ toolUse, invocationState: {} }));
488
+ expect(result).toEqual({
489
+ toolUseId: 'test-error-capture',
490
+ status: 'error',
491
+ content: [
492
+ {
493
+ type: 'toolResultTextContent',
494
+ text: 'Error: Test error message',
495
+ },
496
+ ],
497
+ error: testError,
498
+ });
499
+ });
500
+ it('wraps non-Error thrown values into Error object', async () => {
501
+ const tool = new FunctionTool({
502
+ name: 'stringThrowTool',
503
+ description: 'Throws string',
504
+ inputSchema: { type: 'object' },
505
+ callback: () => {
506
+ throw 'string error';
507
+ },
508
+ });
509
+ const toolUse = {
510
+ name: 'stringThrowTool',
511
+ toolUseId: 'test-string-wrap',
512
+ input: {},
513
+ };
514
+ const { result } = await collectGenerator(tool.stream({ toolUse, invocationState: {} }));
515
+ expect(result).toEqual({
516
+ toolUseId: 'test-string-wrap',
517
+ status: 'error',
518
+ content: [
519
+ {
520
+ type: 'toolResultTextContent',
521
+ text: 'Error: string error',
522
+ },
523
+ ],
524
+ error: expect.any(Error),
525
+ });
526
+ expect(result.error?.message).toBe('string error');
527
+ });
528
+ it('preserves custom Error subclass instances', async () => {
529
+ class CustomError extends Error {
530
+ code;
531
+ constructor(message, code) {
532
+ super(message);
533
+ this.code = code;
534
+ this.name = 'CustomError';
535
+ }
536
+ }
537
+ const customError = new CustomError('Custom error message', 'ERR_001');
538
+ const tool = new FunctionTool({
539
+ name: 'customErrorTool',
540
+ description: 'Throws custom error',
541
+ inputSchema: { type: 'object' },
542
+ callback: () => {
543
+ throw customError;
544
+ },
545
+ });
546
+ const toolUse = {
547
+ name: 'customErrorTool',
548
+ toolUseId: 'test-custom-error',
549
+ input: {},
550
+ };
551
+ const { result } = await collectGenerator(tool.stream({ toolUse, invocationState: {} }));
552
+ expect(result).toEqual({
553
+ toolUseId: 'test-custom-error',
554
+ status: 'error',
555
+ content: [
556
+ {
557
+ type: 'toolResultTextContent',
558
+ text: 'Error: Custom error message',
559
+ },
560
+ ],
561
+ error: customError,
562
+ });
563
+ expect(result.error.code).toBe('ERR_001');
564
+ });
565
+ it('preserves error stack traces', async () => {
566
+ const tool = new FunctionTool({
567
+ name: 'stackTraceTool',
568
+ description: 'Throws error with stack trace',
569
+ inputSchema: { type: 'object' },
570
+ callback: () => {
571
+ throw new Error('Error with stack');
572
+ },
573
+ });
574
+ const toolUse = {
575
+ name: 'stackTraceTool',
576
+ toolUseId: 'test-stack-trace',
577
+ input: {},
578
+ };
579
+ const { result } = await collectGenerator(tool.stream({ toolUse, invocationState: {} }));
580
+ expect(result).toEqual({
581
+ toolUseId: 'test-stack-trace',
582
+ status: 'error',
583
+ content: [
584
+ {
585
+ type: 'toolResultTextContent',
586
+ text: 'Error: Error with stack',
587
+ },
588
+ ],
589
+ error: expect.any(Error),
590
+ });
591
+ expect(result.error?.stack).toBeDefined();
592
+ expect(result.error?.stack).toContain('Error: Error with stack');
593
+ });
594
+ it('captures errors thrown in async generator callbacks', async () => {
595
+ const testError = new Error('Async generator error');
596
+ const tool = new FunctionTool({
597
+ name: 'asyncGenErrorTool',
598
+ description: 'Async generator that throws',
599
+ inputSchema: { type: 'object' },
600
+ callback: async function* () {
601
+ yield 'Starting...';
602
+ throw testError;
603
+ },
604
+ });
605
+ const toolUse = {
606
+ name: 'asyncGenErrorTool',
607
+ toolUseId: 'test-async-gen-error',
608
+ input: {},
609
+ };
610
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: {} }));
611
+ // Should have one stream event before the error
612
+ expect(streamEvents.length).toBe(1);
613
+ expect(streamEvents[0]).toEqual({ type: 'toolStreamEvent', data: 'Starting...' });
614
+ // Final result should have error object
615
+ expect(result).toEqual({
616
+ toolUseId: 'test-async-gen-error',
617
+ status: 'error',
618
+ content: [
619
+ {
620
+ type: 'toolResultTextContent',
621
+ text: 'Error: Async generator error',
622
+ },
623
+ ],
624
+ error: testError,
625
+ });
626
+ });
627
+ it('catches errors in async generators', async () => {
628
+ const tool = new FunctionTool({
629
+ name: 'genErrorTool',
630
+ description: 'Generator throws',
631
+ inputSchema: { type: 'object' },
632
+ callback: async function* () {
633
+ yield 'Starting...';
634
+ throw new Error('Generator error');
635
+ },
636
+ });
637
+ const toolUse = {
638
+ name: 'genErrorTool',
639
+ toolUseId: 'test-error-3',
640
+ input: {},
641
+ };
642
+ const context = { toolUse, invocationState: {} };
643
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
644
+ // Should have one stream event before the error
645
+ expect(streamEvents.length).toBe(1);
646
+ expect(streamEvents[0]?.type).toBe('toolStreamEvent');
647
+ // Final result should be error
648
+ expect(result.status).toBe('error');
649
+ });
650
+ it('handles non-Error thrown values', async () => {
651
+ const tool = new FunctionTool({
652
+ name: 'stringErrorTool',
653
+ description: 'Throws string',
654
+ inputSchema: { type: 'object' },
655
+ callback: () => {
656
+ throw 'String error';
657
+ },
658
+ });
659
+ const toolUse = {
660
+ name: 'stringErrorTool',
661
+ toolUseId: 'test-error-4',
662
+ input: {},
663
+ };
664
+ const context = { toolUse, invocationState: {} };
665
+ const { items: streamEvents, result } = await collectGenerator(tool.stream({ toolUse, invocationState: context.invocationState }));
666
+ expect(streamEvents.length).toBe(0);
667
+ expect(result.status).toBe('error');
668
+ });
669
+ it('returns error for circular references', async () => {
670
+ const tool = new FunctionTool({
671
+ name: 'circularTool',
672
+ description: 'Returns circular object',
673
+ inputSchema: { type: 'object' },
674
+ callback: () => {
675
+ // Create circular reference
676
+ const obj = { a: 1 };
677
+ obj.self = obj;
678
+ return obj;
679
+ },
680
+ });
681
+ const { result } = await collectGenerator(tool.stream({ toolUse: { name: 'circularTool', toolUseId: 'test-circular', input: {} }, invocationState: {} }));
682
+ expect(result).toEqual({
683
+ toolUseId: 'test-circular',
684
+ status: 'error',
685
+ error: expect.any(Error),
686
+ content: [
687
+ {
688
+ type: 'toolResultTextContent',
689
+ text: expect.stringContaining('Error:'),
690
+ },
691
+ ],
692
+ });
693
+ });
694
+ it('silently drops non-serializable values (functions)', async () => {
695
+ const tool = new FunctionTool({
696
+ name: 'functionTool',
697
+ description: 'Returns object with function',
698
+ inputSchema: { type: 'object' },
699
+ callback: () => {
700
+ return { fn: () => { } };
701
+ },
702
+ });
703
+ const { result } = await collectGenerator(tool.stream({
704
+ toolUse: { name: 'functionTool', toolUseId: 'test-function', input: {} },
705
+ invocationState: {},
706
+ }));
707
+ // Functions are silently dropped during JSON serialization
708
+ expect(result).toEqual({
709
+ toolUseId: 'test-function',
710
+ status: 'success',
711
+ content: [
712
+ {
713
+ type: 'toolResultJsonContent',
714
+ json: {},
715
+ },
716
+ ],
717
+ });
718
+ });
719
+ });
720
+ });
721
+ });
722
+ describe('Tool interface backwards compatibility', () => {
723
+ it('maintains stable interface signature', () => {
724
+ const tool = new FunctionTool({
725
+ name: 'testTool',
726
+ description: 'Test description',
727
+ inputSchema: { type: 'object' },
728
+ callback: () => 'result',
729
+ });
730
+ // Verify interface properties exist
731
+ expect(tool).toHaveProperty('toolName');
732
+ expect(tool).toHaveProperty('description');
733
+ expect(tool).toHaveProperty('toolSpec');
734
+ expect(tool).toHaveProperty('stream');
735
+ // Verify stream is a function
736
+ expect(typeof tool.stream).toBe('function');
737
+ });
738
+ it('stream method accepts correct parameter types', async () => {
739
+ const tool = new FunctionTool({
740
+ name: 'testTool',
741
+ description: 'Test description',
742
+ inputSchema: { type: 'object' },
743
+ callback: (input) => input,
744
+ });
745
+ const toolUse = {
746
+ name: 'testTool',
747
+ toolUseId: 'test-types',
748
+ input: { value: 123 },
749
+ };
750
+ const context = { toolUse, invocationState: {} };
751
+ // This should compile and execute without type errors
752
+ const stream = tool.stream({ ...context, toolUse });
753
+ expect(stream).toBeDefined();
754
+ expect(Symbol.asyncIterator in stream).toBe(true);
755
+ // Consume the stream with helper
756
+ const { result } = await collectGenerator(stream);
757
+ expect(result).toBeDefined();
758
+ expect(result.status).toBe('success');
759
+ });
760
+ });
761
+ //# sourceMappingURL=tool.test.js.map