@strands-agents/sdk 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (708) hide show
  1. package/dist/src/agent/agent.d.ts +1 -1
  2. package/dist/src/agent/agent.d.ts.map +1 -1
  3. package/dist/src/agent/agent.js +1 -1
  4. package/dist/src/agent/agent.js.map +1 -1
  5. package/dist/src/context-manager/modes/agentic/agentic-context.d.ts +3 -3
  6. package/dist/src/context-manager/modes/agentic/agentic-context.d.ts.map +1 -1
  7. package/dist/src/index.d.ts +1 -1
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +1 -1
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/index.node.d.ts.map +1 -1
  12. package/dist/src/index.node.js +3 -0
  13. package/dist/src/index.node.js.map +1 -1
  14. package/dist/src/interventions/actions.d.ts.map +1 -1
  15. package/dist/src/interventions/actions.js.map +1 -1
  16. package/dist/src/{mcp.d.ts → mcp/client.d.ts} +13 -4
  17. package/dist/src/mcp/client.d.ts.map +1 -0
  18. package/dist/src/{mcp.js → mcp/client.js} +15 -3
  19. package/dist/src/mcp/client.js.map +1 -0
  20. package/dist/src/mcp/config.d.ts +52 -0
  21. package/dist/src/mcp/config.d.ts.map +1 -0
  22. package/dist/src/mcp/config.js +12 -0
  23. package/dist/src/mcp/config.js.map +1 -0
  24. package/dist/src/mcp/config.node.d.ts +16 -0
  25. package/dist/src/mcp/config.node.d.ts.map +1 -0
  26. package/dist/src/mcp/config.node.js +145 -0
  27. package/dist/src/mcp/config.node.js.map +1 -0
  28. package/dist/src/mcp/index.d.ts +3 -0
  29. package/dist/src/mcp/index.d.ts.map +1 -0
  30. package/dist/src/mcp/index.js +2 -0
  31. package/dist/src/mcp/index.js.map +1 -0
  32. package/dist/src/memory/extraction/coordinator.d.ts +6 -1
  33. package/dist/src/memory/extraction/coordinator.d.ts.map +1 -1
  34. package/dist/src/memory/extraction/coordinator.js +48 -10
  35. package/dist/src/memory/extraction/coordinator.js.map +1 -1
  36. package/dist/src/memory/extraction/model-extractor.d.ts.map +1 -1
  37. package/dist/src/memory/extraction/model-extractor.js +30 -9
  38. package/dist/src/memory/extraction/model-extractor.js.map +1 -1
  39. package/dist/src/memory/extraction/types.d.ts +7 -0
  40. package/dist/src/memory/extraction/types.d.ts.map +1 -1
  41. package/dist/src/memory/extraction/types.js.map +1 -1
  42. package/dist/src/memory/memory-manager.d.ts +15 -2
  43. package/dist/src/memory/memory-manager.d.ts.map +1 -1
  44. package/dist/src/memory/memory-manager.js +123 -45
  45. package/dist/src/memory/memory-manager.js.map +1 -1
  46. package/dist/src/memory/types.d.ts +7 -0
  47. package/dist/src/memory/types.d.ts.map +1 -1
  48. package/dist/src/models/google/adapters.d.ts.map +1 -1
  49. package/dist/src/models/google/adapters.js +21 -3
  50. package/dist/src/models/google/adapters.js.map +1 -1
  51. package/dist/src/models/model.d.ts.map +1 -1
  52. package/dist/src/models/model.js +2 -1
  53. package/dist/src/models/model.js.map +1 -1
  54. package/dist/src/models/openai/errors.d.ts.map +1 -1
  55. package/dist/src/models/openai/errors.js +4 -1
  56. package/dist/src/models/openai/errors.js.map +1 -1
  57. package/dist/src/models/openai/responses-adapter.d.ts +1 -0
  58. package/dist/src/models/openai/responses-adapter.d.ts.map +1 -1
  59. package/dist/src/models/openai/responses-adapter.js +24 -10
  60. package/dist/src/models/openai/responses-adapter.js.map +1 -1
  61. package/dist/src/multiagent/graph.d.ts +7 -0
  62. package/dist/src/multiagent/graph.d.ts.map +1 -1
  63. package/dist/src/multiagent/graph.js +26 -2
  64. package/dist/src/multiagent/graph.js.map +1 -1
  65. package/dist/src/multiagent/nodes.d.ts +5 -0
  66. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  67. package/dist/src/multiagent/nodes.js +15 -0
  68. package/dist/src/multiagent/nodes.js.map +1 -1
  69. package/dist/src/multiagent/state.d.ts.map +1 -1
  70. package/dist/src/multiagent/state.js.map +1 -1
  71. package/dist/src/telemetry/tracer.d.ts +82 -2
  72. package/dist/src/telemetry/tracer.d.ts.map +1 -1
  73. package/dist/src/telemetry/tracer.js +242 -3
  74. package/dist/src/telemetry/tracer.js.map +1 -1
  75. package/dist/src/telemetry/types.d.ts +86 -1
  76. package/dist/src/telemetry/types.d.ts.map +1 -1
  77. package/dist/src/tools/function-tool.d.ts +1 -1
  78. package/dist/src/tools/function-tool.d.ts.map +1 -1
  79. package/dist/src/tools/function-tool.js +4 -12
  80. package/dist/src/tools/function-tool.js.map +1 -1
  81. package/dist/src/tools/mcp-tool.d.ts +2 -1
  82. package/dist/src/tools/mcp-tool.d.ts.map +1 -1
  83. package/dist/src/tools/mcp-tool.js +1 -0
  84. package/dist/src/tools/mcp-tool.js.map +1 -1
  85. package/dist/src/tools/tool-factory.d.ts +1 -1
  86. package/dist/src/tools/tool-factory.d.ts.map +1 -1
  87. package/dist/src/tools/types.d.ts +4 -0
  88. package/dist/src/tools/types.d.ts.map +1 -1
  89. package/dist/src/tools/zod-tool.d.ts +4 -2
  90. package/dist/src/tools/zod-tool.d.ts.map +1 -1
  91. package/dist/src/tools/zod-tool.js.map +1 -1
  92. package/dist/src/tsconfig.tsbuildinfo +1 -1
  93. package/dist/src/types/json.js +2 -2
  94. package/dist/src/types/json.js.map +1 -1
  95. package/dist/src/types/media.d.ts.map +1 -1
  96. package/dist/src/types/media.js.map +1 -1
  97. package/dist/src/types/messages.d.ts.map +1 -1
  98. package/dist/src/types/messages.js.map +1 -1
  99. package/dist/src/vended-interventions/cedar/cedar.d.ts +12 -0
  100. package/dist/src/vended-interventions/cedar/cedar.d.ts.map +1 -1
  101. package/dist/src/vended-interventions/cedar/cedar.js +15 -4
  102. package/dist/src/vended-interventions/cedar/cedar.js.map +1 -1
  103. package/dist/src/vended-interventions/cedar/schema-generator.d.ts +1 -1
  104. package/dist/src/vended-interventions/cedar/schema-generator.d.ts.map +1 -1
  105. package/dist/src/vended-interventions/cedar/schema-generator.js +8 -3
  106. package/dist/src/vended-interventions/cedar/schema-generator.js.map +1 -1
  107. package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.d.ts +1 -1
  108. package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.d.ts.map +1 -1
  109. package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.js.map +1 -1
  110. package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.d.ts +57 -0
  111. package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.d.ts.map +1 -1
  112. package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.js +86 -11
  113. package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.js.map +1 -1
  114. package/dist/src/vended-memory-stores/local/index.d.ts +2 -0
  115. package/dist/src/vended-memory-stores/local/index.d.ts.map +1 -0
  116. package/dist/src/vended-memory-stores/local/index.js +2 -0
  117. package/dist/src/vended-memory-stores/local/index.js.map +1 -0
  118. package/dist/src/vended-memory-stores/local/store.d.ts +122 -0
  119. package/dist/src/vended-memory-stores/local/store.d.ts.map +1 -0
  120. package/dist/src/vended-memory-stores/local/store.js +281 -0
  121. package/dist/src/vended-memory-stores/local/store.js.map +1 -0
  122. package/dist/src/vended-plugins/context-offloader/search.d.ts.map +1 -1
  123. package/dist/src/vended-plugins/context-offloader/search.js +4 -2
  124. package/dist/src/vended-plugins/context-offloader/search.js.map +1 -1
  125. package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -1
  126. package/dist/src/vended-plugins/context-offloader/storage.js +16 -3
  127. package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
  128. package/dist/src/vended-plugins/skills/skill.d.ts.map +1 -1
  129. package/dist/src/vended-plugins/skills/skill.js +4 -2
  130. package/dist/src/vended-plugins/skills/skill.js.map +1 -1
  131. package/dist/src/vended-tools/http-request/http-request.js +1 -1
  132. package/dist/src/vended-tools/http-request/http-request.js.map +1 -1
  133. package/dist/src/vended-tools/notebook/notebook.d.ts +1 -1
  134. package/package.json +46 -39
  135. package/dist/src/__fixtures__/agent-helpers.d.ts +0 -136
  136. package/dist/src/__fixtures__/agent-helpers.d.ts.map +0 -1
  137. package/dist/src/__fixtures__/agent-helpers.js +0 -156
  138. package/dist/src/__fixtures__/agent-helpers.js.map +0 -1
  139. package/dist/src/__fixtures__/environment.d.ts +0 -12
  140. package/dist/src/__fixtures__/environment.d.ts.map +0 -1
  141. package/dist/src/__fixtures__/environment.js +0 -12
  142. package/dist/src/__fixtures__/environment.js.map +0 -1
  143. package/dist/src/__fixtures__/metrics-helpers.d.ts +0 -55
  144. package/dist/src/__fixtures__/metrics-helpers.d.ts.map +0 -1
  145. package/dist/src/__fixtures__/metrics-helpers.js +0 -57
  146. package/dist/src/__fixtures__/metrics-helpers.js.map +0 -1
  147. package/dist/src/__fixtures__/mock-message-model.d.ts +0 -103
  148. package/dist/src/__fixtures__/mock-message-model.d.ts.map +0 -1
  149. package/dist/src/__fixtures__/mock-message-model.js +0 -245
  150. package/dist/src/__fixtures__/mock-message-model.js.map +0 -1
  151. package/dist/src/__fixtures__/mock-meter.d.ts +0 -32
  152. package/dist/src/__fixtures__/mock-meter.d.ts.map +0 -1
  153. package/dist/src/__fixtures__/mock-meter.js +0 -47
  154. package/dist/src/__fixtures__/mock-meter.js.map +0 -1
  155. package/dist/src/__fixtures__/mock-plugin.d.ts +0 -13
  156. package/dist/src/__fixtures__/mock-plugin.d.ts.map +0 -1
  157. package/dist/src/__fixtures__/mock-plugin.js +0 -35
  158. package/dist/src/__fixtures__/mock-plugin.js.map +0 -1
  159. package/dist/src/__fixtures__/mock-span.d.ts +0 -78
  160. package/dist/src/__fixtures__/mock-span.d.ts.map +0 -1
  161. package/dist/src/__fixtures__/mock-span.js +0 -93
  162. package/dist/src/__fixtures__/mock-span.js.map +0 -1
  163. package/dist/src/__fixtures__/mock-storage-provider.d.ts +0 -42
  164. package/dist/src/__fixtures__/mock-storage-provider.d.ts.map +0 -1
  165. package/dist/src/__fixtures__/mock-storage-provider.js +0 -122
  166. package/dist/src/__fixtures__/mock-storage-provider.js.map +0 -1
  167. package/dist/src/__fixtures__/model-test-helpers.d.ts +0 -56
  168. package/dist/src/__fixtures__/model-test-helpers.d.ts.map +0 -1
  169. package/dist/src/__fixtures__/model-test-helpers.js +0 -85
  170. package/dist/src/__fixtures__/model-test-helpers.js.map +0 -1
  171. package/dist/src/__fixtures__/register-node-defaults.d.ts +0 -2
  172. package/dist/src/__fixtures__/register-node-defaults.d.ts.map +0 -1
  173. package/dist/src/__fixtures__/register-node-defaults.js +0 -6
  174. package/dist/src/__fixtures__/register-node-defaults.js.map +0 -1
  175. package/dist/src/__fixtures__/slim-types.d.ts +0 -51
  176. package/dist/src/__fixtures__/slim-types.d.ts.map +0 -1
  177. package/dist/src/__fixtures__/slim-types.js +0 -6
  178. package/dist/src/__fixtures__/slim-types.js.map +0 -1
  179. package/dist/src/__fixtures__/test-sandbox.node.d.ts +0 -15
  180. package/dist/src/__fixtures__/test-sandbox.node.d.ts.map +0 -1
  181. package/dist/src/__fixtures__/test-sandbox.node.js +0 -23
  182. package/dist/src/__fixtures__/test-sandbox.node.js.map +0 -1
  183. package/dist/src/__fixtures__/tool-helpers.d.ts +0 -45
  184. package/dist/src/__fixtures__/tool-helpers.d.ts.map +0 -1
  185. package/dist/src/__fixtures__/tool-helpers.js +0 -101
  186. package/dist/src/__fixtures__/tool-helpers.js.map +0 -1
  187. package/dist/src/__tests__/default-slot.test.d.ts +0 -2
  188. package/dist/src/__tests__/default-slot.test.d.ts.map +0 -1
  189. package/dist/src/__tests__/default-slot.test.js +0 -33
  190. package/dist/src/__tests__/default-slot.test.js.map +0 -1
  191. package/dist/src/__tests__/errors.test.d.ts +0 -2
  192. package/dist/src/__tests__/errors.test.d.ts.map +0 -1
  193. package/dist/src/__tests__/errors.test.js +0 -170
  194. package/dist/src/__tests__/errors.test.js.map +0 -1
  195. package/dist/src/__tests__/index.test.d.ts +0 -2
  196. package/dist/src/__tests__/index.test.d.ts.map +0 -1
  197. package/dist/src/__tests__/index.test.js +0 -48
  198. package/dist/src/__tests__/index.test.js.map +0 -1
  199. package/dist/src/__tests__/interrupt.test.d.ts +0 -2
  200. package/dist/src/__tests__/interrupt.test.d.ts.map +0 -1
  201. package/dist/src/__tests__/interrupt.test.js +0 -264
  202. package/dist/src/__tests__/interrupt.test.js.map +0 -1
  203. package/dist/src/__tests__/mcp.test.d.ts +0 -2
  204. package/dist/src/__tests__/mcp.test.d.ts.map +0 -1
  205. package/dist/src/__tests__/mcp.test.js +0 -1003
  206. package/dist/src/__tests__/mcp.test.js.map +0 -1
  207. package/dist/src/__tests__/mime.test.d.ts +0 -2
  208. package/dist/src/__tests__/mime.test.d.ts.map +0 -1
  209. package/dist/src/__tests__/mime.test.js +0 -83
  210. package/dist/src/__tests__/mime.test.js.map +0 -1
  211. package/dist/src/__tests__/state-store.test.d.ts +0 -2
  212. package/dist/src/__tests__/state-store.test.d.ts.map +0 -1
  213. package/dist/src/__tests__/state-store.test.js +0 -285
  214. package/dist/src/__tests__/state-store.test.js.map +0 -1
  215. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts +0 -2
  216. package/dist/src/a2a/__tests__/a2a-agent.test.d.ts.map +0 -1
  217. package/dist/src/a2a/__tests__/a2a-agent.test.js +0 -383
  218. package/dist/src/a2a/__tests__/a2a-agent.test.js.map +0 -1
  219. package/dist/src/a2a/__tests__/adapters.test.d.ts +0 -2
  220. package/dist/src/a2a/__tests__/adapters.test.d.ts.map +0 -1
  221. package/dist/src/a2a/__tests__/adapters.test.js +0 -151
  222. package/dist/src/a2a/__tests__/adapters.test.js.map +0 -1
  223. package/dist/src/a2a/__tests__/async-lock.test.d.ts +0 -2
  224. package/dist/src/a2a/__tests__/async-lock.test.d.ts.map +0 -1
  225. package/dist/src/a2a/__tests__/async-lock.test.js +0 -137
  226. package/dist/src/a2a/__tests__/async-lock.test.js.map +0 -1
  227. package/dist/src/a2a/__tests__/events.test.d.ts +0 -2
  228. package/dist/src/a2a/__tests__/events.test.d.ts.map +0 -1
  229. package/dist/src/a2a/__tests__/events.test.js +0 -68
  230. package/dist/src/a2a/__tests__/events.test.js.map +0 -1
  231. package/dist/src/a2a/__tests__/executor.test.d.ts +0 -2
  232. package/dist/src/a2a/__tests__/executor.test.d.ts.map +0 -1
  233. package/dist/src/a2a/__tests__/executor.test.js +0 -345
  234. package/dist/src/a2a/__tests__/executor.test.js.map +0 -1
  235. package/dist/src/a2a/__tests__/server.test.d.ts +0 -2
  236. package/dist/src/a2a/__tests__/server.test.d.ts.map +0 -1
  237. package/dist/src/a2a/__tests__/server.test.js +0 -71
  238. package/dist/src/a2a/__tests__/server.test.js.map +0 -1
  239. package/dist/src/a2a/__tests__/server.test.node.d.ts +0 -2
  240. package/dist/src/a2a/__tests__/server.test.node.d.ts.map +0 -1
  241. package/dist/src/a2a/__tests__/server.test.node.js +0 -110
  242. package/dist/src/a2a/__tests__/server.test.node.js.map +0 -1
  243. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts +0 -2
  244. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.d.ts.map +0 -1
  245. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js +0 -23
  246. package/dist/src/agent/__tests__/agent-as-tool.invocation-state.test.js.map +0 -1
  247. package/dist/src/agent/__tests__/agent-as-tool.test.d.ts +0 -2
  248. package/dist/src/agent/__tests__/agent-as-tool.test.d.ts.map +0 -1
  249. package/dist/src/agent/__tests__/agent-as-tool.test.js +0 -347
  250. package/dist/src/agent/__tests__/agent-as-tool.test.js.map +0 -1
  251. package/dist/src/agent/__tests__/agent.cancel.test.d.ts +0 -2
  252. package/dist/src/agent/__tests__/agent.cancel.test.d.ts.map +0 -1
  253. package/dist/src/agent/__tests__/agent.cancel.test.js +0 -337
  254. package/dist/src/agent/__tests__/agent.cancel.test.js.map +0 -1
  255. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts +0 -2
  256. package/dist/src/agent/__tests__/agent.concurrent.test.d.ts.map +0 -1
  257. package/dist/src/agent/__tests__/agent.concurrent.test.js +0 -488
  258. package/dist/src/agent/__tests__/agent.concurrent.test.js.map +0 -1
  259. package/dist/src/agent/__tests__/agent.context-manager.test.d.ts +0 -2
  260. package/dist/src/agent/__tests__/agent.context-manager.test.d.ts.map +0 -1
  261. package/dist/src/agent/__tests__/agent.context-manager.test.js +0 -107
  262. package/dist/src/agent/__tests__/agent.context-manager.test.js.map +0 -1
  263. package/dist/src/agent/__tests__/agent.hook.test.d.ts +0 -2
  264. package/dist/src/agent/__tests__/agent.hook.test.d.ts.map +0 -1
  265. package/dist/src/agent/__tests__/agent.hook.test.js +0 -1332
  266. package/dist/src/agent/__tests__/agent.hook.test.js.map +0 -1
  267. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts +0 -2
  268. package/dist/src/agent/__tests__/agent.interrupt.test.d.ts.map +0 -1
  269. package/dist/src/agent/__tests__/agent.interrupt.test.js +0 -779
  270. package/dist/src/agent/__tests__/agent.interrupt.test.js.map +0 -1
  271. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts +0 -2
  272. package/dist/src/agent/__tests__/agent.invocation-state.test.d.ts.map +0 -1
  273. package/dist/src/agent/__tests__/agent.invocation-state.test.js +0 -219
  274. package/dist/src/agent/__tests__/agent.invocation-state.test.js.map +0 -1
  275. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts +0 -2
  276. package/dist/src/agent/__tests__/agent.model-retry.test.d.ts.map +0 -1
  277. package/dist/src/agent/__tests__/agent.model-retry.test.js +0 -161
  278. package/dist/src/agent/__tests__/agent.model-retry.test.js.map +0 -1
  279. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts +0 -2
  280. package/dist/src/agent/__tests__/agent.stateful-model.test.d.ts.map +0 -1
  281. package/dist/src/agent/__tests__/agent.stateful-model.test.js +0 -169
  282. package/dist/src/agent/__tests__/agent.stateful-model.test.js.map +0 -1
  283. package/dist/src/agent/__tests__/agent.test.d.ts +0 -2
  284. package/dist/src/agent/__tests__/agent.test.d.ts.map +0 -1
  285. package/dist/src/agent/__tests__/agent.test.js +0 -1624
  286. package/dist/src/agent/__tests__/agent.test.js.map +0 -1
  287. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts +0 -2
  288. package/dist/src/agent/__tests__/agent.tracer.test.node.d.ts.map +0 -1
  289. package/dist/src/agent/__tests__/agent.tracer.test.node.js +0 -535
  290. package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +0 -1
  291. package/dist/src/agent/__tests__/printer.test.d.ts +0 -2
  292. package/dist/src/agent/__tests__/printer.test.d.ts.map +0 -1
  293. package/dist/src/agent/__tests__/printer.test.js +0 -188
  294. package/dist/src/agent/__tests__/printer.test.js.map +0 -1
  295. package/dist/src/agent/__tests__/snapshot.test.d.ts +0 -2
  296. package/dist/src/agent/__tests__/snapshot.test.d.ts.map +0 -1
  297. package/dist/src/agent/__tests__/snapshot.test.js +0 -442
  298. package/dist/src/agent/__tests__/snapshot.test.js.map +0 -1
  299. package/dist/src/agent/__tests__/tool-caller.test.d.ts +0 -2
  300. package/dist/src/agent/__tests__/tool-caller.test.d.ts.map +0 -1
  301. package/dist/src/agent/__tests__/tool-caller.test.js +0 -459
  302. package/dist/src/agent/__tests__/tool-caller.test.js.map +0 -1
  303. package/dist/src/conversation-manager/__tests__/agentic-context.test.d.ts +0 -2
  304. package/dist/src/conversation-manager/__tests__/agentic-context.test.d.ts.map +0 -1
  305. package/dist/src/conversation-manager/__tests__/agentic-context.test.js +0 -332
  306. package/dist/src/conversation-manager/__tests__/agentic-context.test.js.map +0 -1
  307. package/dist/src/conversation-manager/__tests__/context-compression.test.d.ts +0 -2
  308. package/dist/src/conversation-manager/__tests__/context-compression.test.d.ts.map +0 -1
  309. package/dist/src/conversation-manager/__tests__/context-compression.test.js +0 -176
  310. package/dist/src/conversation-manager/__tests__/context-compression.test.js.map +0 -1
  311. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts +0 -2
  312. package/dist/src/conversation-manager/__tests__/conversation-manager.test.d.ts.map +0 -1
  313. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js +0 -321
  314. package/dist/src/conversation-manager/__tests__/conversation-manager.test.js.map +0 -1
  315. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts +0 -2
  316. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.d.ts.map +0 -1
  317. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js +0 -64
  318. package/dist/src/conversation-manager/__tests__/null-conversation-manager.test.js.map +0 -1
  319. package/dist/src/conversation-manager/__tests__/pin.test.d.ts +0 -2
  320. package/dist/src/conversation-manager/__tests__/pin.test.d.ts.map +0 -1
  321. package/dist/src/conversation-manager/__tests__/pin.test.js +0 -119
  322. package/dist/src/conversation-manager/__tests__/pin.test.js.map +0 -1
  323. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts +0 -2
  324. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.d.ts.map +0 -1
  325. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +0 -1080
  326. package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +0 -1
  327. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.d.ts +0 -2
  328. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.d.ts.map +0 -1
  329. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js +0 -400
  330. package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js.map +0 -1
  331. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.d.ts +0 -2
  332. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.d.ts.map +0 -1
  333. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.js +0 -138
  334. package/dist/src/conversation-manager/__tests__/token-usage-middleware.test.js.map +0 -1
  335. package/dist/src/hooks/__tests__/events.test.d.ts +0 -2
  336. package/dist/src/hooks/__tests__/events.test.d.ts.map +0 -1
  337. package/dist/src/hooks/__tests__/events.test.js +0 -1060
  338. package/dist/src/hooks/__tests__/events.test.js.map +0 -1
  339. package/dist/src/hooks/__tests__/registry.test.d.ts +0 -2
  340. package/dist/src/hooks/__tests__/registry.test.d.ts.map +0 -1
  341. package/dist/src/hooks/__tests__/registry.test.js +0 -325
  342. package/dist/src/hooks/__tests__/registry.test.js.map +0 -1
  343. package/dist/src/injection/__tests__/message-injection.test.d.ts +0 -2
  344. package/dist/src/injection/__tests__/message-injection.test.d.ts.map +0 -1
  345. package/dist/src/injection/__tests__/message-injection.test.js +0 -200
  346. package/dist/src/injection/__tests__/message-injection.test.js.map +0 -1
  347. package/dist/src/interventions/__tests__/handler.test.d.ts +0 -2
  348. package/dist/src/interventions/__tests__/handler.test.d.ts.map +0 -1
  349. package/dist/src/interventions/__tests__/handler.test.js +0 -35
  350. package/dist/src/interventions/__tests__/handler.test.js.map +0 -1
  351. package/dist/src/interventions/__tests__/registry.test.d.ts +0 -2
  352. package/dist/src/interventions/__tests__/registry.test.d.ts.map +0 -1
  353. package/dist/src/interventions/__tests__/registry.test.js +0 -692
  354. package/dist/src/interventions/__tests__/registry.test.js.map +0 -1
  355. package/dist/src/logging/__tests__/logger.test.d.ts +0 -2
  356. package/dist/src/logging/__tests__/logger.test.d.ts.map +0 -1
  357. package/dist/src/logging/__tests__/logger.test.js +0 -70
  358. package/dist/src/logging/__tests__/logger.test.js.map +0 -1
  359. package/dist/src/logging/__tests__/warn-once.test.d.ts +0 -2
  360. package/dist/src/logging/__tests__/warn-once.test.d.ts.map +0 -1
  361. package/dist/src/logging/__tests__/warn-once.test.js +0 -30
  362. package/dist/src/logging/__tests__/warn-once.test.js.map +0 -1
  363. package/dist/src/mcp.d.ts.map +0 -1
  364. package/dist/src/mcp.js.map +0 -1
  365. package/dist/src/memory/__tests__/memory-manager.test.d.ts +0 -2
  366. package/dist/src/memory/__tests__/memory-manager.test.d.ts.map +0 -1
  367. package/dist/src/memory/__tests__/memory-manager.test.js +0 -679
  368. package/dist/src/memory/__tests__/memory-manager.test.js.map +0 -1
  369. package/dist/src/memory/extraction/__tests__/extraction.test.d.ts +0 -2
  370. package/dist/src/memory/extraction/__tests__/extraction.test.d.ts.map +0 -1
  371. package/dist/src/memory/extraction/__tests__/extraction.test.js +0 -637
  372. package/dist/src/memory/extraction/__tests__/extraction.test.js.map +0 -1
  373. package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts +0 -2
  374. package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts.map +0 -1
  375. package/dist/src/memory/extraction/__tests__/model-extractor.test.js +0 -68
  376. package/dist/src/memory/extraction/__tests__/model-extractor.test.js.map +0 -1
  377. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts +0 -2
  378. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts.map +0 -1
  379. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js +0 -81
  380. package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js.map +0 -1
  381. package/dist/src/middleware/__tests__/agent-middleware.test.d.ts +0 -2
  382. package/dist/src/middleware/__tests__/agent-middleware.test.d.ts.map +0 -1
  383. package/dist/src/middleware/__tests__/agent-middleware.test.js +0 -1206
  384. package/dist/src/middleware/__tests__/agent-middleware.test.js.map +0 -1
  385. package/dist/src/middleware/__tests__/copy-on-input.test.d.ts +0 -2
  386. package/dist/src/middleware/__tests__/copy-on-input.test.d.ts.map +0 -1
  387. package/dist/src/middleware/__tests__/copy-on-input.test.js +0 -379
  388. package/dist/src/middleware/__tests__/copy-on-input.test.js.map +0 -1
  389. package/dist/src/middleware/__tests__/custom-stages.test.d.ts +0 -2
  390. package/dist/src/middleware/__tests__/custom-stages.test.d.ts.map +0 -1
  391. package/dist/src/middleware/__tests__/custom-stages.test.js +0 -97
  392. package/dist/src/middleware/__tests__/custom-stages.test.js.map +0 -1
  393. package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts +0 -2
  394. package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts.map +0 -1
  395. package/dist/src/middleware/__tests__/middleware-interrupts.test.js +0 -267
  396. package/dist/src/middleware/__tests__/middleware-interrupts.test.js.map +0 -1
  397. package/dist/src/middleware/__tests__/registry.test.d.ts +0 -2
  398. package/dist/src/middleware/__tests__/registry.test.d.ts.map +0 -1
  399. package/dist/src/middleware/__tests__/registry.test.js +0 -525
  400. package/dist/src/middleware/__tests__/registry.test.js.map +0 -1
  401. package/dist/src/models/__tests__/anthropic.test.d.ts +0 -2
  402. package/dist/src/models/__tests__/anthropic.test.d.ts.map +0 -1
  403. package/dist/src/models/__tests__/anthropic.test.js +0 -793
  404. package/dist/src/models/__tests__/anthropic.test.js.map +0 -1
  405. package/dist/src/models/__tests__/bedrock.test.d.ts +0 -2
  406. package/dist/src/models/__tests__/bedrock.test.d.ts.map +0 -1
  407. package/dist/src/models/__tests__/bedrock.test.js +0 -3964
  408. package/dist/src/models/__tests__/bedrock.test.js.map +0 -1
  409. package/dist/src/models/__tests__/defaults.test.d.ts +0 -2
  410. package/dist/src/models/__tests__/defaults.test.d.ts.map +0 -1
  411. package/dist/src/models/__tests__/defaults.test.js +0 -36
  412. package/dist/src/models/__tests__/defaults.test.js.map +0 -1
  413. package/dist/src/models/__tests__/google.test.d.ts +0 -2
  414. package/dist/src/models/__tests__/google.test.d.ts.map +0 -1
  415. package/dist/src/models/__tests__/google.test.js +0 -1104
  416. package/dist/src/models/__tests__/google.test.js.map +0 -1
  417. package/dist/src/models/__tests__/model.test.d.ts +0 -2
  418. package/dist/src/models/__tests__/model.test.d.ts.map +0 -1
  419. package/dist/src/models/__tests__/model.test.js +0 -921
  420. package/dist/src/models/__tests__/model.test.js.map +0 -1
  421. package/dist/src/models/__tests__/streaming.test.d.ts +0 -2
  422. package/dist/src/models/__tests__/streaming.test.d.ts.map +0 -1
  423. package/dist/src/models/__tests__/streaming.test.js +0 -50
  424. package/dist/src/models/__tests__/streaming.test.js.map +0 -1
  425. package/dist/src/models/__tests__/test-utils.d.ts +0 -10
  426. package/dist/src/models/__tests__/test-utils.d.ts.map +0 -1
  427. package/dist/src/models/__tests__/test-utils.js +0 -17
  428. package/dist/src/models/__tests__/test-utils.js.map +0 -1
  429. package/dist/src/models/__tests__/vercel.test.d.ts +0 -2
  430. package/dist/src/models/__tests__/vercel.test.d.ts.map +0 -1
  431. package/dist/src/models/__tests__/vercel.test.js +0 -740
  432. package/dist/src/models/__tests__/vercel.test.js.map +0 -1
  433. package/dist/src/models/openai/__tests__/chat.test.d.ts +0 -2
  434. package/dist/src/models/openai/__tests__/chat.test.d.ts.map +0 -1
  435. package/dist/src/models/openai/__tests__/chat.test.js +0 -1586
  436. package/dist/src/models/openai/__tests__/chat.test.js.map +0 -1
  437. package/dist/src/models/openai/__tests__/errors.test.d.ts +0 -2
  438. package/dist/src/models/openai/__tests__/errors.test.d.ts.map +0 -1
  439. package/dist/src/models/openai/__tests__/errors.test.js +0 -30
  440. package/dist/src/models/openai/__tests__/errors.test.js.map +0 -1
  441. package/dist/src/models/openai/__tests__/mantle.test.d.ts +0 -2
  442. package/dist/src/models/openai/__tests__/mantle.test.d.ts.map +0 -1
  443. package/dist/src/models/openai/__tests__/mantle.test.js +0 -189
  444. package/dist/src/models/openai/__tests__/mantle.test.js.map +0 -1
  445. package/dist/src/models/openai/__tests__/responses.test.d.ts +0 -2
  446. package/dist/src/models/openai/__tests__/responses.test.d.ts.map +0 -1
  447. package/dist/src/models/openai/__tests__/responses.test.js +0 -662
  448. package/dist/src/models/openai/__tests__/responses.test.js.map +0 -1
  449. package/dist/src/multiagent/__tests__/events.test.d.ts +0 -2
  450. package/dist/src/multiagent/__tests__/events.test.d.ts.map +0 -1
  451. package/dist/src/multiagent/__tests__/events.test.js +0 -493
  452. package/dist/src/multiagent/__tests__/events.test.js.map +0 -1
  453. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts +0 -2
  454. package/dist/src/multiagent/__tests__/graph.invocation-state.test.d.ts.map +0 -1
  455. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js +0 -95
  456. package/dist/src/multiagent/__tests__/graph.invocation-state.test.js.map +0 -1
  457. package/dist/src/multiagent/__tests__/graph.test.d.ts +0 -2
  458. package/dist/src/multiagent/__tests__/graph.test.d.ts.map +0 -1
  459. package/dist/src/multiagent/__tests__/graph.test.js +0 -677
  460. package/dist/src/multiagent/__tests__/graph.test.js.map +0 -1
  461. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts +0 -2
  462. package/dist/src/multiagent/__tests__/graph.tracer.test.d.ts.map +0 -1
  463. package/dist/src/multiagent/__tests__/graph.tracer.test.js +0 -218
  464. package/dist/src/multiagent/__tests__/graph.tracer.test.js.map +0 -1
  465. package/dist/src/multiagent/__tests__/interrupts.test.d.ts +0 -2
  466. package/dist/src/multiagent/__tests__/interrupts.test.d.ts.map +0 -1
  467. package/dist/src/multiagent/__tests__/interrupts.test.js +0 -390
  468. package/dist/src/multiagent/__tests__/interrupts.test.js.map +0 -1
  469. package/dist/src/multiagent/__tests__/nodes.test.d.ts +0 -2
  470. package/dist/src/multiagent/__tests__/nodes.test.d.ts.map +0 -1
  471. package/dist/src/multiagent/__tests__/nodes.test.js +0 -321
  472. package/dist/src/multiagent/__tests__/nodes.test.js.map +0 -1
  473. package/dist/src/multiagent/__tests__/queue.test.d.ts +0 -2
  474. package/dist/src/multiagent/__tests__/queue.test.d.ts.map +0 -1
  475. package/dist/src/multiagent/__tests__/queue.test.js +0 -118
  476. package/dist/src/multiagent/__tests__/queue.test.js.map +0 -1
  477. package/dist/src/multiagent/__tests__/snapshot.test.d.ts +0 -2
  478. package/dist/src/multiagent/__tests__/snapshot.test.d.ts.map +0 -1
  479. package/dist/src/multiagent/__tests__/snapshot.test.js +0 -161
  480. package/dist/src/multiagent/__tests__/snapshot.test.js.map +0 -1
  481. package/dist/src/multiagent/__tests__/state.test.d.ts +0 -2
  482. package/dist/src/multiagent/__tests__/state.test.d.ts.map +0 -1
  483. package/dist/src/multiagent/__tests__/state.test.js +0 -526
  484. package/dist/src/multiagent/__tests__/state.test.js.map +0 -1
  485. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts +0 -2
  486. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.d.ts.map +0 -1
  487. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js +0 -56
  488. package/dist/src/multiagent/__tests__/swarm.invocation-state.test.js.map +0 -1
  489. package/dist/src/multiagent/__tests__/swarm.test.d.ts +0 -2
  490. package/dist/src/multiagent/__tests__/swarm.test.d.ts.map +0 -1
  491. package/dist/src/multiagent/__tests__/swarm.test.js +0 -477
  492. package/dist/src/multiagent/__tests__/swarm.test.js.map +0 -1
  493. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts +0 -2
  494. package/dist/src/multiagent/__tests__/swarm.tracer.test.d.ts.map +0 -1
  495. package/dist/src/multiagent/__tests__/swarm.tracer.test.js +0 -235
  496. package/dist/src/multiagent/__tests__/swarm.tracer.test.js.map +0 -1
  497. package/dist/src/plugins/__tests__/plugin.test.d.ts +0 -2
  498. package/dist/src/plugins/__tests__/plugin.test.d.ts.map +0 -1
  499. package/dist/src/plugins/__tests__/plugin.test.js +0 -114
  500. package/dist/src/plugins/__tests__/plugin.test.js.map +0 -1
  501. package/dist/src/plugins/__tests__/registry.test.d.ts +0 -2
  502. package/dist/src/plugins/__tests__/registry.test.d.ts.map +0 -1
  503. package/dist/src/plugins/__tests__/registry.test.js +0 -147
  504. package/dist/src/plugins/__tests__/registry.test.js.map +0 -1
  505. package/dist/src/registry/__tests__/tool-registry.test.d.ts +0 -2
  506. package/dist/src/registry/__tests__/tool-registry.test.d.ts.map +0 -1
  507. package/dist/src/registry/__tests__/tool-registry.test.js +0 -210
  508. package/dist/src/registry/__tests__/tool-registry.test.js.map +0 -1
  509. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts +0 -2
  510. package/dist/src/retry/__tests__/backoff-strategy.test.d.ts.map +0 -1
  511. package/dist/src/retry/__tests__/backoff-strategy.test.js +0 -116
  512. package/dist/src/retry/__tests__/backoff-strategy.test.js.map +0 -1
  513. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts +0 -2
  514. package/dist/src/retry/__tests__/default-model-retry-strategy.test.d.ts.map +0 -1
  515. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js +0 -225
  516. package/dist/src/retry/__tests__/default-model-retry-strategy.test.js.map +0 -1
  517. package/dist/src/sandbox/__tests__/default.test.browser.d.ts +0 -2
  518. package/dist/src/sandbox/__tests__/default.test.browser.d.ts.map +0 -1
  519. package/dist/src/sandbox/__tests__/default.test.browser.js +0 -11
  520. package/dist/src/sandbox/__tests__/default.test.browser.js.map +0 -1
  521. package/dist/src/sandbox/__tests__/default.test.node.d.ts +0 -2
  522. package/dist/src/sandbox/__tests__/default.test.node.d.ts.map +0 -1
  523. package/dist/src/sandbox/__tests__/default.test.node.js +0 -23
  524. package/dist/src/sandbox/__tests__/default.test.node.js.map +0 -1
  525. package/dist/src/sandbox/__tests__/docker.test.node.d.ts +0 -2
  526. package/dist/src/sandbox/__tests__/docker.test.node.d.ts.map +0 -1
  527. package/dist/src/sandbox/__tests__/docker.test.node.js +0 -89
  528. package/dist/src/sandbox/__tests__/docker.test.node.js.map +0 -1
  529. package/dist/src/sandbox/__tests__/errors.test.node.d.ts +0 -2
  530. package/dist/src/sandbox/__tests__/errors.test.node.d.ts.map +0 -1
  531. package/dist/src/sandbox/__tests__/errors.test.node.js +0 -33
  532. package/dist/src/sandbox/__tests__/errors.test.node.js.map +0 -1
  533. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts +0 -2
  534. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts.map +0 -1
  535. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js +0 -124
  536. package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js.map +0 -1
  537. package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts +0 -2
  538. package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts.map +0 -1
  539. package/dist/src/sandbox/__tests__/posix-shell.test.node.js +0 -298
  540. package/dist/src/sandbox/__tests__/posix-shell.test.node.js.map +0 -1
  541. package/dist/src/sandbox/__tests__/ssh.test.node.d.ts +0 -2
  542. package/dist/src/sandbox/__tests__/ssh.test.node.d.ts.map +0 -1
  543. package/dist/src/sandbox/__tests__/ssh.test.node.js +0 -262
  544. package/dist/src/sandbox/__tests__/ssh.test.node.js.map +0 -1
  545. package/dist/src/session/__tests__/file-storage.test.node.d.ts +0 -2
  546. package/dist/src/session/__tests__/file-storage.test.node.d.ts.map +0 -1
  547. package/dist/src/session/__tests__/file-storage.test.node.js +0 -278
  548. package/dist/src/session/__tests__/file-storage.test.node.js.map +0 -1
  549. package/dist/src/session/__tests__/s3-storage.test.d.ts +0 -2
  550. package/dist/src/session/__tests__/s3-storage.test.d.ts.map +0 -1
  551. package/dist/src/session/__tests__/s3-storage.test.js +0 -461
  552. package/dist/src/session/__tests__/s3-storage.test.js.map +0 -1
  553. package/dist/src/session/__tests__/session-manager.test.d.ts +0 -2
  554. package/dist/src/session/__tests__/session-manager.test.d.ts.map +0 -1
  555. package/dist/src/session/__tests__/session-manager.test.js +0 -832
  556. package/dist/src/session/__tests__/session-manager.test.js.map +0 -1
  557. package/dist/src/session/__tests__/validation.test.d.ts +0 -2
  558. package/dist/src/session/__tests__/validation.test.d.ts.map +0 -1
  559. package/dist/src/session/__tests__/validation.test.js +0 -47
  560. package/dist/src/session/__tests__/validation.test.js.map +0 -1
  561. package/dist/src/telemetry/__tests__/config.test.d.ts +0 -2
  562. package/dist/src/telemetry/__tests__/config.test.d.ts.map +0 -1
  563. package/dist/src/telemetry/__tests__/config.test.js +0 -64
  564. package/dist/src/telemetry/__tests__/config.test.js.map +0 -1
  565. package/dist/src/telemetry/__tests__/config.test.node.d.ts +0 -2
  566. package/dist/src/telemetry/__tests__/config.test.node.d.ts.map +0 -1
  567. package/dist/src/telemetry/__tests__/config.test.node.js +0 -164
  568. package/dist/src/telemetry/__tests__/config.test.node.js.map +0 -1
  569. package/dist/src/telemetry/__tests__/json.test.d.ts +0 -2
  570. package/dist/src/telemetry/__tests__/json.test.d.ts.map +0 -1
  571. package/dist/src/telemetry/__tests__/json.test.js +0 -89
  572. package/dist/src/telemetry/__tests__/json.test.js.map +0 -1
  573. package/dist/src/telemetry/__tests__/local-trace.test.d.ts +0 -2
  574. package/dist/src/telemetry/__tests__/local-trace.test.d.ts.map +0 -1
  575. package/dist/src/telemetry/__tests__/local-trace.test.js +0 -158
  576. package/dist/src/telemetry/__tests__/local-trace.test.js.map +0 -1
  577. package/dist/src/telemetry/__tests__/meter.test.d.ts +0 -2
  578. package/dist/src/telemetry/__tests__/meter.test.d.ts.map +0 -1
  579. package/dist/src/telemetry/__tests__/meter.test.js +0 -695
  580. package/dist/src/telemetry/__tests__/meter.test.js.map +0 -1
  581. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts +0 -2
  582. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts.map +0 -1
  583. package/dist/src/telemetry/__tests__/tracer.test.node.js +0 -760
  584. package/dist/src/telemetry/__tests__/tracer.test.node.js.map +0 -1
  585. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts +0 -2
  586. package/dist/src/tools/__tests__/structured-output-tool.test.d.ts.map +0 -1
  587. package/dist/src/tools/__tests__/structured-output-tool.test.js +0 -84
  588. package/dist/src/tools/__tests__/structured-output-tool.test.js.map +0 -1
  589. package/dist/src/tools/__tests__/tool-factory.test.d.ts +0 -2
  590. package/dist/src/tools/__tests__/tool-factory.test.d.ts.map +0 -1
  591. package/dist/src/tools/__tests__/tool-factory.test.js +0 -98
  592. package/dist/src/tools/__tests__/tool-factory.test.js.map +0 -1
  593. package/dist/src/tools/__tests__/tool.test.d.ts +0 -2
  594. package/dist/src/tools/__tests__/tool.test.d.ts.map +0 -1
  595. package/dist/src/tools/__tests__/tool.test.js +0 -1043
  596. package/dist/src/tools/__tests__/tool.test.js.map +0 -1
  597. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts +0 -2
  598. package/dist/src/tools/__tests__/zod-tool.test-d.d.ts.map +0 -1
  599. package/dist/src/tools/__tests__/zod-tool.test-d.js +0 -227
  600. package/dist/src/tools/__tests__/zod-tool.test-d.js.map +0 -1
  601. package/dist/src/tools/__tests__/zod-tool.test.d.ts +0 -2
  602. package/dist/src/tools/__tests__/zod-tool.test.d.ts.map +0 -1
  603. package/dist/src/tools/__tests__/zod-tool.test.js +0 -563
  604. package/dist/src/tools/__tests__/zod-tool.test.js.map +0 -1
  605. package/dist/src/types/__tests__/agent.test.d.ts +0 -2
  606. package/dist/src/types/__tests__/agent.test.d.ts.map +0 -1
  607. package/dist/src/types/__tests__/agent.test.js +0 -476
  608. package/dist/src/types/__tests__/agent.test.js.map +0 -1
  609. package/dist/src/types/__tests__/citations.test.d.ts +0 -2
  610. package/dist/src/types/__tests__/citations.test.d.ts.map +0 -1
  611. package/dist/src/types/__tests__/citations.test.js +0 -104
  612. package/dist/src/types/__tests__/citations.test.js.map +0 -1
  613. package/dist/src/types/__tests__/json.test.d.ts +0 -2
  614. package/dist/src/types/__tests__/json.test.d.ts.map +0 -1
  615. package/dist/src/types/__tests__/json.test.js +0 -298
  616. package/dist/src/types/__tests__/json.test.js.map +0 -1
  617. package/dist/src/types/__tests__/media.test.d.ts +0 -2
  618. package/dist/src/types/__tests__/media.test.d.ts.map +0 -1
  619. package/dist/src/types/__tests__/media.test.js +0 -478
  620. package/dist/src/types/__tests__/media.test.js.map +0 -1
  621. package/dist/src/types/__tests__/messages.test.d.ts +0 -2
  622. package/dist/src/types/__tests__/messages.test.d.ts.map +0 -1
  623. package/dist/src/types/__tests__/messages.test.js +0 -681
  624. package/dist/src/types/__tests__/messages.test.js.map +0 -1
  625. package/dist/src/types/__tests__/validation.test.d.ts +0 -2
  626. package/dist/src/types/__tests__/validation.test.d.ts.map +0 -1
  627. package/dist/src/types/__tests__/validation.test.js +0 -30
  628. package/dist/src/types/__tests__/validation.test.js.map +0 -1
  629. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.d.ts +0 -2
  630. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.d.ts.map +0 -1
  631. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js +0 -675
  632. package/dist/src/vended-interventions/cedar/__tests__/cedar.test.node.js.map +0 -1
  633. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts +0 -2
  634. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts.map +0 -1
  635. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js +0 -358
  636. package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js.map +0 -1
  637. package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts +0 -2
  638. package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts.map +0 -1
  639. package/dist/src/vended-interventions/steering/__tests__/handler.test.js +0 -163
  640. package/dist/src/vended-interventions/steering/__tests__/handler.test.js.map +0 -1
  641. package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts +0 -2
  642. package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts.map +0 -1
  643. package/dist/src/vended-interventions/steering/__tests__/llm.test.js +0 -60
  644. package/dist/src/vended-interventions/steering/__tests__/llm.test.js.map +0 -1
  645. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts +0 -2
  646. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts.map +0 -1
  647. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js +0 -94
  648. package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js.map +0 -1
  649. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.d.ts +0 -2
  650. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.d.ts.map +0 -1
  651. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.js +0 -611
  652. package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.js.map +0 -1
  653. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.d.ts +0 -2
  654. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.d.ts.map +0 -1
  655. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.js +0 -96
  656. package/dist/src/vended-plugins/context-injector/__tests__/plugin.test.js.map +0 -1
  657. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts +0 -2
  658. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts.map +0 -1
  659. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js +0 -68
  660. package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js.map +0 -1
  661. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts +0 -2
  662. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.d.ts.map +0 -1
  663. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js +0 -539
  664. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.js.map +0 -1
  665. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts +0 -2
  666. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts.map +0 -1
  667. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js +0 -93
  668. package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js.map +0 -1
  669. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.d.ts +0 -2
  670. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.d.ts.map +0 -1
  671. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.js +0 -149
  672. package/dist/src/vended-plugins/context-offloader/__tests__/search.test.js.map +0 -1
  673. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts +0 -2
  674. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.d.ts.map +0 -1
  675. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js +0 -216
  676. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.js.map +0 -1
  677. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts +0 -2
  678. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.d.ts.map +0 -1
  679. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js +0 -78
  680. package/dist/src/vended-plugins/context-offloader/__tests__/storage.test.node.js.map +0 -1
  681. package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts +0 -2
  682. package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts.map +0 -1
  683. package/dist/src/vended-plugins/goal/__tests__/plugin.test.js +0 -736
  684. package/dist/src/vended-plugins/goal/__tests__/plugin.test.js.map +0 -1
  685. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.d.ts +0 -2
  686. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.d.ts.map +0 -1
  687. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js +0 -482
  688. package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js.map +0 -1
  689. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.d.ts +0 -2
  690. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.d.ts.map +0 -1
  691. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.js +0 -476
  692. package/dist/src/vended-plugins/skills/__tests__/skill.test.node.js.map +0 -1
  693. package/dist/src/vended-tools/bash/__tests__/bash.test.node.d.ts +0 -2
  694. package/dist/src/vended-tools/bash/__tests__/bash.test.node.d.ts.map +0 -1
  695. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +0 -390
  696. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +0 -1
  697. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts +0 -2
  698. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.d.ts.map +0 -1
  699. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js +0 -452
  700. package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +0 -1
  701. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts +0 -2
  702. package/dist/src/vended-tools/http-request/__tests__/http-request.test.d.ts.map +0 -1
  703. package/dist/src/vended-tools/http-request/__tests__/http-request.test.js +0 -189
  704. package/dist/src/vended-tools/http-request/__tests__/http-request.test.js.map +0 -1
  705. package/dist/src/vended-tools/notebook/__tests__/notebook.test.d.ts +0 -2
  706. package/dist/src/vended-tools/notebook/__tests__/notebook.test.d.ts.map +0 -1
  707. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +0 -388
  708. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js.map +0 -1
@@ -1,1586 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import OpenAI from 'openai';
3
- import { isNode } from '../../../__fixtures__/environment.js';
4
- import { OpenAIModel } from '../index.js';
5
- import { ContextWindowOverflowError, ModelThrottledError } from '../../../errors.js';
6
- import { collectIterator } from '../../../__fixtures__/model-test-helpers.js';
7
- import { Message, TextBlock, ToolUseBlock, ToolResultBlock, GuardContentBlock } from '../../../types/messages.js';
8
- import { ImageBlock, DocumentBlock, VideoBlock } from '../../../types/media.js';
9
- import { warnOnce } from '../../../logging/warn-once.js';
10
- import { logger } from '../../../logging/logger.js';
11
- /**
12
- * Helper to create a mock OpenAI client with streaming support
13
- */
14
- function createMockClient(streamGenerator) {
15
- return {
16
- chat: {
17
- completions: {
18
- create: vi.fn(async () => streamGenerator()),
19
- },
20
- },
21
- };
22
- }
23
- // Mock the OpenAI SDK
24
- vi.mock('openai', () => {
25
- const mockConstructor = vi.fn(function () {
26
- return {};
27
- });
28
- return {
29
- default: mockConstructor,
30
- };
31
- });
32
- vi.mock('../../../logging/warn-once.js', () => ({
33
- warnOnce: vi.fn(),
34
- }));
35
- describe('OpenAIModel', () => {
36
- beforeEach(() => {
37
- vi.clearAllMocks();
38
- vi.restoreAllMocks();
39
- // Set default env var for most tests using Vitest's stubEnv (Node.js only)
40
- if (isNode) {
41
- vi.stubEnv('OPENAI_API_KEY', 'sk-test-env');
42
- }
43
- });
44
- afterEach(() => {
45
- vi.clearAllMocks();
46
- // Restore all environment variables to their original state (Node.js only)
47
- if (isNode) {
48
- vi.unstubAllEnvs();
49
- }
50
- });
51
- // Shared helper to create a mock OpenAI client that captures the request
52
- const createMockClientWithCapture = (captureContainer) => {
53
- return {
54
- chat: {
55
- completions: {
56
- create: vi.fn(async (request) => {
57
- captureContainer.request = request;
58
- return (async function* () {
59
- yield { choices: [{ delta: { role: 'assistant' }, index: 0 }] };
60
- yield { choices: [{ finish_reason: 'stop', delta: {}, index: 0 }] };
61
- })();
62
- }),
63
- },
64
- },
65
- };
66
- };
67
- describe('constructor', () => {
68
- it('creates an instance with required modelId', () => {
69
- const provider = new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test' });
70
- const config = provider.getConfig();
71
- expect(config.modelId).toBe('gpt-5.4');
72
- });
73
- it('uses custom model ID', () => {
74
- const customModelId = 'gpt-3.5-turbo';
75
- const provider = new OpenAIModel({ api: 'chat', modelId: customModelId, apiKey: 'sk-test' });
76
- expect(provider.getConfig()).toStrictEqual({
77
- modelId: customModelId,
78
- });
79
- });
80
- it('warns when modelId is not explicitly set', () => {
81
- new OpenAIModel({ api: 'chat', apiKey: 'sk-test' });
82
- expect(warnOnce).toHaveBeenCalledWith(expect.objectContaining({ warn: expect.any(Function) }), expect.stringContaining('using default modelId'));
83
- });
84
- it('does not warn when modelId is explicitly set', () => {
85
- new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test' });
86
- expect(warnOnce).not.toHaveBeenCalledWith(expect.objectContaining({ warn: expect.any(Function) }), expect.stringContaining('using default modelId'));
87
- });
88
- it('uses API key from constructor parameter', () => {
89
- const apiKey = 'sk-explicit';
90
- new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey });
91
- expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
92
- apiKey: apiKey,
93
- }));
94
- });
95
- // Node.js-specific test: environment variable usage
96
- if (isNode) {
97
- it('uses API key from environment variable', () => {
98
- vi.stubEnv('OPENAI_API_KEY', 'sk-from-env');
99
- new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4' });
100
- // OpenAI client should be called without explicit apiKey (uses env var internally)
101
- expect(OpenAI).toHaveBeenCalled();
102
- });
103
- }
104
- it('explicit API key takes precedence over environment variable', () => {
105
- if (isNode) {
106
- vi.stubEnv('OPENAI_API_KEY', 'sk-from-env');
107
- }
108
- const explicitKey = 'sk-explicit';
109
- new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: explicitKey });
110
- expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
111
- apiKey: explicitKey,
112
- }));
113
- });
114
- it('throws error when no API key is available', () => {
115
- if (isNode) {
116
- vi.stubEnv('OPENAI_API_KEY', '');
117
- }
118
- expect(() => new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4' })).toThrow("OpenAI API key is required. Provide it via the 'apiKey' option (string or function) or set the OPENAI_API_KEY environment variable.");
119
- });
120
- it('uses custom client configuration', () => {
121
- const timeout = 30000;
122
- new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test', clientConfig: { timeout } });
123
- expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
124
- timeout: timeout,
125
- }));
126
- });
127
- it('uses provided client instance', () => {
128
- vi.clearAllMocks();
129
- const mockClient = {};
130
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
131
- // Should not create a new OpenAI client
132
- expect(OpenAI).not.toHaveBeenCalled();
133
- expect(provider).toBeDefined();
134
- });
135
- it('provided client takes precedence over apiKey and clientConfig', () => {
136
- vi.clearAllMocks();
137
- const mockClient = {};
138
- new OpenAIModel({
139
- api: 'chat',
140
- modelId: 'gpt-5.4',
141
- apiKey: 'sk-test',
142
- client: mockClient,
143
- clientConfig: { timeout: 30000 },
144
- });
145
- // Should not create a new OpenAI client when client is provided
146
- expect(OpenAI).not.toHaveBeenCalled();
147
- });
148
- it('does not require API key when client is provided', () => {
149
- vi.clearAllMocks();
150
- if (isNode) {
151
- vi.stubEnv('OPENAI_API_KEY', '');
152
- }
153
- const mockClient = {};
154
- expect(() => new OpenAIModel({ api: 'chat', client: mockClient })).not.toThrow();
155
- });
156
- it('accepts function-based API key', () => {
157
- const apiKeyFn = vi.fn(async () => 'sk-dynamic');
158
- new OpenAIModel({
159
- api: 'chat',
160
- modelId: 'gpt-5.4',
161
- apiKey: apiKeyFn,
162
- });
163
- expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
164
- apiKey: apiKeyFn,
165
- }));
166
- });
167
- it('accepts async function-based API key', () => {
168
- const apiKeyFn = async () => {
169
- await new Promise((resolve) => globalThis.setTimeout(resolve, 10));
170
- return 'sk-async-key';
171
- };
172
- new OpenAIModel({
173
- api: 'chat',
174
- modelId: 'gpt-5.4',
175
- apiKey: apiKeyFn,
176
- });
177
- expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({
178
- apiKey: apiKeyFn,
179
- }));
180
- });
181
- });
182
- describe('updateConfig', () => {
183
- it('merges new config with existing config', () => {
184
- const provider = new OpenAIModel({ api: 'chat', modelId: 'gpt-5.4', apiKey: 'sk-test', temperature: 0.5 });
185
- provider.updateConfig({ modelId: 'gpt-5.4', temperature: 0.8, maxTokens: 2048 });
186
- expect(provider.getConfig()).toStrictEqual({
187
- modelId: 'gpt-5.4',
188
- temperature: 0.8,
189
- maxTokens: 2048,
190
- contextWindowLimit: 1_050_000,
191
- });
192
- });
193
- it('preserves fields not included in the update', () => {
194
- const provider = new OpenAIModel({
195
- api: 'chat',
196
- apiKey: 'sk-test',
197
- modelId: 'gpt-3.5-turbo',
198
- temperature: 0.5,
199
- maxTokens: 1024,
200
- });
201
- provider.updateConfig({ modelId: 'gpt-3.5-turbo', temperature: 0.8 });
202
- expect(provider.getConfig()).toStrictEqual({
203
- modelId: 'gpt-3.5-turbo',
204
- temperature: 0.8,
205
- maxTokens: 1024,
206
- });
207
- });
208
- it('re-resolves contextWindowLimit when modelId changes and it was auto-resolved', () => {
209
- const provider = new OpenAIModel({ api: 'chat', apiKey: 'sk-test' });
210
- expect(provider.getConfig().contextWindowLimit).toBe(1_050_000); // gpt-5.4 default
211
- provider.updateConfig({ modelId: 'gpt-4o' });
212
- expect(provider.getConfig().contextWindowLimit).toBe(128_000); // gpt-4o value
213
- });
214
- it('preserves explicit contextWindowLimit when modelId changes', () => {
215
- const provider = new OpenAIModel({ api: 'chat', apiKey: 'sk-test', contextWindowLimit: 50_000 });
216
- expect(provider.getConfig().contextWindowLimit).toBe(50_000);
217
- provider.updateConfig({ modelId: 'gpt-4o' });
218
- expect(provider.getConfig().contextWindowLimit).toBe(50_000); // preserved
219
- });
220
- });
221
- describe('getConfig', () => {
222
- it('returns the current configuration', () => {
223
- const provider = new OpenAIModel({
224
- api: 'chat',
225
- modelId: 'gpt-5.4',
226
- apiKey: 'sk-test',
227
- maxTokens: 1024,
228
- temperature: 0.7,
229
- });
230
- expect(provider.getConfig()).toStrictEqual({
231
- modelId: 'gpt-5.4',
232
- maxTokens: 1024,
233
- temperature: 0.7,
234
- contextWindowLimit: 1_050_000,
235
- });
236
- });
237
- it('includes contextWindowLimit in config when provided', () => {
238
- const provider = new OpenAIModel({
239
- api: 'chat',
240
- modelId: 'gpt-4o',
241
- apiKey: 'sk-test',
242
- contextWindowLimit: 128_000,
243
- });
244
- expect(provider.getConfig()).toStrictEqual({
245
- modelId: 'gpt-4o',
246
- contextWindowLimit: 128_000,
247
- });
248
- });
249
- it('auto-populates contextWindowLimit from model ID lookup', () => {
250
- const provider = new OpenAIModel({ api: 'chat', modelId: 'gpt-4o', apiKey: 'sk-test' });
251
- expect(provider.getConfig()).toStrictEqual({
252
- modelId: 'gpt-4o',
253
- contextWindowLimit: 128_000,
254
- });
255
- });
256
- it('auto-populates contextWindowLimit for default model ID', () => {
257
- const provider = new OpenAIModel({ api: 'chat', apiKey: 'sk-test' });
258
- expect(provider.getConfig()).toStrictEqual({
259
- contextWindowLimit: 1_050_000,
260
- });
261
- });
262
- it('does not override explicit contextWindowLimit', () => {
263
- const provider = new OpenAIModel({
264
- api: 'chat',
265
- modelId: 'gpt-4o',
266
- apiKey: 'sk-test',
267
- contextWindowLimit: 50_000,
268
- });
269
- expect(provider.getConfig()).toStrictEqual({
270
- modelId: 'gpt-4o',
271
- contextWindowLimit: 50_000,
272
- });
273
- });
274
- it('leaves contextWindowLimit undefined for unknown model IDs', () => {
275
- const provider = new OpenAIModel({ api: 'chat', modelId: 'unknown-model', apiKey: 'sk-test' });
276
- expect(provider.getConfig()).toStrictEqual({
277
- modelId: 'unknown-model',
278
- });
279
- });
280
- });
281
- describe('managed params warning', () => {
282
- it('warns on construction when params contains provider-managed keys', () => {
283
- const warnSpy = vi.spyOn(logger, 'warn');
284
- new OpenAIModel({
285
- api: 'chat',
286
- client: {},
287
- params: { model: 'bad', stream: false },
288
- });
289
- expect(warnSpy).toHaveBeenCalledTimes(2);
290
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("'model'"));
291
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("'stream'"));
292
- warnSpy.mockRestore();
293
- });
294
- it('warns on updateConfig when params contains provider-managed keys', () => {
295
- const model = new OpenAIModel({ api: 'chat', client: {} });
296
- const warnSpy = vi.spyOn(logger, 'warn');
297
- model.updateConfig({ params: { stream_options: { include_usage: false } } });
298
- expect(warnSpy).toHaveBeenCalledTimes(1);
299
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("'stream_options'"));
300
- warnSpy.mockRestore();
301
- });
302
- it('does not warn when params contains only non-managed keys', () => {
303
- const warnSpy = vi.spyOn(logger, 'warn');
304
- new OpenAIModel({ api: 'chat', client: {}, params: { seed: 42 } });
305
- expect(warnSpy).not.toHaveBeenCalled();
306
- warnSpy.mockRestore();
307
- });
308
- it('provider-managed fields in params are overridden and cannot take effect', async () => {
309
- const captured = { request: null };
310
- const mockClient = createMockClientWithCapture(captured);
311
- const warnSpy = vi.spyOn(logger, 'warn');
312
- const provider = new OpenAIModel({
313
- api: 'chat',
314
- modelId: 'gpt-5.4',
315
- client: mockClient,
316
- params: {
317
- model: 'attacker-model',
318
- messages: [{ role: 'user', content: 'hijacked' }],
319
- stream: false,
320
- stream_options: { include_usage: false },
321
- },
322
- });
323
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
324
- await collectIterator(provider.stream(messages));
325
- expect(captured.request.model).toBe('gpt-5.4');
326
- expect(captured.request.stream).toBe(true);
327
- expect(captured.request.stream_options).toEqual({ include_usage: true });
328
- expect(Array.isArray(captured.request.messages)).toBe(true);
329
- expect(captured.request.messages[0]).toEqual({ role: 'user', content: [{ type: 'text', text: 'Hi' }] });
330
- warnSpy.mockRestore();
331
- });
332
- });
333
- describe('stream', () => {
334
- describe('validation', () => {
335
- it('throws error when messages array is empty', async () => {
336
- const mockClient = createMockClient(async function* () { });
337
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
338
- await expect(async () => {
339
- await collectIterator(provider.stream([]));
340
- }).rejects.toThrow('At least one message is required');
341
- });
342
- it('validates system prompt is not empty', async () => {
343
- const mockClient = createMockClient(async function* () {
344
- yield {
345
- choices: [{ delta: { role: 'assistant', content: 'Hello' }, index: 0 }],
346
- };
347
- yield {
348
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
349
- };
350
- });
351
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
352
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
353
- // System prompt that's only whitespace should not be sent
354
- const events = await collectIterator(provider.stream(messages, { systemPrompt: ' ' }));
355
- // Should still get valid events
356
- expect(events.length).toBeGreaterThan(0);
357
- expect(events[0]?.type).toBe('modelMessageStartEvent');
358
- });
359
- it('throws error for streaming with n > 1', async () => {
360
- const mockClient = createMockClient(async function* () { });
361
- const provider = new OpenAIModel({
362
- api: 'chat',
363
- modelId: 'gpt-5.4',
364
- client: mockClient,
365
- params: { n: 2 },
366
- });
367
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
368
- await expect(async () => {
369
- for await (const _ of provider.stream(messages)) {
370
- // Should not reach here
371
- }
372
- }).rejects.toThrow('Streaming with n > 1 is not supported');
373
- });
374
- it('throws error for tool spec without name or description', async () => {
375
- const mockClient = createMockClient(async function* () { });
376
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
377
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
378
- await expect(async () => {
379
- for await (const _ of provider.stream(messages, {
380
- toolSpecs: [{ name: '', description: 'test', inputSchema: {} }],
381
- })) {
382
- // Should not reach here
383
- }
384
- }).rejects.toThrow('Tool specification must have both name and description');
385
- });
386
- it('throws error for empty tool result content', async () => {
387
- const mockClient = createMockClient(async function* () { });
388
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
389
- const messages = [
390
- new Message({
391
- role: 'user',
392
- content: [
393
- new ToolResultBlock({
394
- toolUseId: 'tool-123',
395
- status: 'success',
396
- content: [],
397
- }),
398
- ],
399
- }),
400
- ];
401
- await expect(async () => {
402
- for await (const _ of provider.stream(messages)) {
403
- // Should not reach here
404
- }
405
- }).rejects.toThrow('Tool result for toolUseId "tool-123" has empty content');
406
- });
407
- it('handles tool result with error status', async () => {
408
- const mockClient = createMockClient(async function* () {
409
- yield {
410
- choices: [{ delta: { role: 'assistant', content: 'Ok' }, index: 0 }],
411
- };
412
- yield {
413
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
414
- };
415
- });
416
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
417
- const messages = [
418
- new Message({ role: 'user', content: [new TextBlock('Run tool')] }),
419
- new Message({
420
- role: 'assistant',
421
- content: [
422
- new ToolUseBlock({
423
- name: 'calculator',
424
- toolUseId: 'tool-123',
425
- input: { expr: 'invalid' },
426
- }),
427
- ],
428
- }),
429
- new Message({
430
- role: 'user',
431
- content: [
432
- new ToolResultBlock({
433
- toolUseId: 'tool-123',
434
- status: 'error',
435
- content: [new TextBlock('Division by zero')],
436
- }),
437
- ],
438
- }),
439
- ];
440
- // Should not throw - error status is handled by prepending [ERROR]
441
- const events = await collectIterator(provider.stream(messages));
442
- // Verify we got a response
443
- expect(events.length).toBeGreaterThan(0);
444
- expect(events[0]?.type).toBe('modelMessageStartEvent');
445
- });
446
- it('throws error for circular reference in tool input', async () => {
447
- const mockClient = createMockClient(async function* () { });
448
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
449
- const circular = { a: 1 };
450
- circular.self = circular;
451
- const messages = [
452
- new Message({ role: 'user', content: [new TextBlock('Hi')] }),
453
- new Message({
454
- role: 'assistant',
455
- content: [
456
- new ToolUseBlock({
457
- name: 'test',
458
- toolUseId: 'tool-1',
459
- input: circular,
460
- }),
461
- ],
462
- }),
463
- ];
464
- await expect(async () => {
465
- for await (const _ of provider.stream(messages)) {
466
- // Should not reach here
467
- }
468
- }).rejects.toThrow('Failed to serialize tool input');
469
- });
470
- });
471
- describe('basic streaming', () => {
472
- it('yields correct event sequence for simple text response', async () => {
473
- const mockClient = createMockClient(async function* () {
474
- yield {
475
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
476
- };
477
- yield {
478
- choices: [{ delta: { content: 'Hello' }, index: 0 }],
479
- };
480
- yield {
481
- choices: [{ delta: { content: ' world' }, index: 0 }],
482
- };
483
- yield {
484
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
485
- };
486
- });
487
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
488
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
489
- const events = await collectIterator(provider.stream(messages));
490
- // Now includes complete content block lifecycle: start, deltas, stop
491
- expect(events).toHaveLength(6);
492
- expect(events[0]).toEqual({ type: 'modelMessageStartEvent', role: 'assistant' });
493
- expect(events[1]).toEqual({
494
- type: 'modelContentBlockStartEvent',
495
- });
496
- expect(events[2]).toEqual({
497
- type: 'modelContentBlockDeltaEvent',
498
- delta: { type: 'textDelta', text: 'Hello' },
499
- });
500
- expect(events[3]).toEqual({
501
- type: 'modelContentBlockDeltaEvent',
502
- delta: { type: 'textDelta', text: ' world' },
503
- });
504
- expect(events[4]).toEqual({
505
- type: 'modelContentBlockStopEvent',
506
- });
507
- expect(events[5]).toEqual({ type: 'modelMessageStopEvent', stopReason: 'endTurn' });
508
- });
509
- });
510
- it('emits modelMetadataEvent with usage information', async () => {
511
- const mockClient = createMockClient(async function* () {
512
- yield {
513
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
514
- };
515
- yield {
516
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
517
- };
518
- yield {
519
- choices: [],
520
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 },
521
- };
522
- });
523
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
524
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
525
- const events = await collectIterator(provider.stream(messages));
526
- const metadataEvent = events.find((e) => e.type === 'modelMetadataEvent');
527
- expect(metadataEvent).toBeDefined();
528
- expect(metadataEvent).toEqual({
529
- type: 'modelMetadataEvent',
530
- usage: {
531
- inputTokens: 10,
532
- outputTokens: 5,
533
- totalTokens: 15,
534
- },
535
- });
536
- });
537
- it('handles usage with undefined properties', async () => {
538
- const mockClient = createMockClient(async function* () {
539
- yield {
540
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
541
- };
542
- yield {
543
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
544
- };
545
- yield {
546
- choices: [],
547
- usage: {}, // Empty usage object
548
- };
549
- });
550
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
551
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
552
- const events = await collectIterator(provider.stream(messages));
553
- const metadataEvent = events.find((e) => e.type === 'modelMetadataEvent');
554
- expect(metadataEvent).toBeDefined();
555
- expect(metadataEvent).toEqual({
556
- type: 'modelMetadataEvent',
557
- usage: {
558
- inputTokens: 0,
559
- outputTokens: 0,
560
- totalTokens: 0,
561
- },
562
- });
563
- });
564
- it('filters out empty string content deltas', async () => {
565
- const mockClient = createMockClient(async function* () {
566
- yield {
567
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
568
- };
569
- yield {
570
- choices: [{ delta: { content: '' }, index: 0 }], // Empty content
571
- };
572
- yield {
573
- choices: [{ delta: { content: 'Hello' }, index: 0 }],
574
- };
575
- yield {
576
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
577
- };
578
- });
579
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
580
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
581
- const events = await collectIterator(provider.stream(messages));
582
- // Should not emit event for empty content
583
- const contentEvents = events.filter((e) => e.type === 'modelContentBlockDeltaEvent');
584
- expect(contentEvents).toHaveLength(1);
585
- expect(contentEvents[0].delta.text).toBe('Hello');
586
- });
587
- it('prevents duplicate message start events', async () => {
588
- const mockClient = createMockClient(async function* () {
589
- yield {
590
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
591
- };
592
- yield {
593
- choices: [{ delta: { role: 'assistant', content: 'Hello' }, index: 0 }], // Duplicate role
594
- };
595
- yield {
596
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
597
- };
598
- });
599
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
600
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
601
- // Suppress console.warn for this test
602
- vi.spyOn(console, 'warn').mockImplementation(() => { });
603
- const events = await collectIterator(provider.stream(messages));
604
- // Should only have one message start event
605
- const startEvents = events.filter((e) => e.type === 'modelMessageStartEvent');
606
- expect(startEvents).toHaveLength(1);
607
- });
608
- });
609
- describe('tool calling', () => {
610
- it('handles tool use request with contentBlockStart and contentBlockStop events', async () => {
611
- const mockClient = createMockClient(async function* () {
612
- yield {
613
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
614
- };
615
- yield {
616
- choices: [
617
- {
618
- delta: {
619
- tool_calls: [
620
- {
621
- index: 0,
622
- id: 'call_123',
623
- type: 'function',
624
- function: { name: 'calculator', arguments: '' },
625
- },
626
- ],
627
- },
628
- index: 0,
629
- },
630
- ],
631
- };
632
- yield {
633
- choices: [
634
- {
635
- delta: {
636
- tool_calls: [{ index: 0, function: { arguments: '{"expr' } }],
637
- },
638
- index: 0,
639
- },
640
- ],
641
- };
642
- yield {
643
- choices: [
644
- {
645
- delta: {
646
- tool_calls: [{ index: 0, function: { arguments: '":"2+2"}' } }],
647
- },
648
- index: 0,
649
- },
650
- ],
651
- };
652
- yield {
653
- choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }],
654
- };
655
- });
656
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
657
- const messages = [new Message({ role: 'user', content: [new TextBlock('Calculate 2+2')] })];
658
- const events = await collectIterator(provider.stream(messages));
659
- // Verify key events in sequence
660
- expect(events[0]).toEqual({ type: 'modelMessageStartEvent', role: 'assistant' });
661
- expect(events[1]).toEqual({
662
- type: 'modelContentBlockStartEvent',
663
- start: {
664
- type: 'toolUseStart',
665
- name: 'calculator',
666
- toolUseId: 'call_123',
667
- },
668
- });
669
- expect(events[2]).toEqual({
670
- type: 'modelContentBlockDeltaEvent',
671
- delta: {
672
- type: 'toolUseInputDelta',
673
- input: '{"expr',
674
- },
675
- });
676
- expect(events[3]).toEqual({
677
- type: 'modelContentBlockDeltaEvent',
678
- delta: {
679
- type: 'toolUseInputDelta',
680
- input: '":"2+2"}',
681
- },
682
- });
683
- expect(events[4]).toEqual({
684
- type: 'modelContentBlockStopEvent',
685
- });
686
- expect(events[5]).toEqual({ type: 'modelMessageStopEvent', stopReason: 'toolUse' });
687
- });
688
- it('handles multiple tool calls', async () => {
689
- const mockClient = createMockClient(async function* () {
690
- yield {
691
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
692
- };
693
- yield {
694
- choices: [
695
- {
696
- delta: {
697
- tool_calls: [
698
- {
699
- index: 0,
700
- id: 'call_1',
701
- type: 'function',
702
- function: { name: 'tool1', arguments: '{}' },
703
- },
704
- ],
705
- },
706
- index: 0,
707
- },
708
- ],
709
- };
710
- yield {
711
- choices: [
712
- {
713
- delta: {
714
- tool_calls: [
715
- {
716
- index: 1,
717
- id: 'call_2',
718
- type: 'function',
719
- function: { name: 'tool2', arguments: '{}' },
720
- },
721
- ],
722
- },
723
- index: 0,
724
- },
725
- ],
726
- };
727
- yield {
728
- choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }],
729
- };
730
- });
731
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
732
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
733
- const events = await collectIterator(provider.stream(messages));
734
- // Should emit stop events for both tool calls
735
- const stopEvents = events.filter((e) => e.type === 'modelContentBlockStopEvent');
736
- expect(stopEvents).toHaveLength(2);
737
- expect(stopEvents[0]).toEqual({ type: 'modelContentBlockStopEvent' });
738
- expect(stopEvents[1]).toEqual({ type: 'modelContentBlockStopEvent' });
739
- });
740
- it('skips tool calls with invalid index', async () => {
741
- const mockClient = createMockClient(async function* () {
742
- yield {
743
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
744
- };
745
- yield {
746
- choices: [
747
- {
748
- delta: {
749
- tool_calls: [
750
- {
751
- index: undefined, // Invalid index
752
- id: 'call_123',
753
- type: 'function',
754
- function: { name: 'tool', arguments: '{}' },
755
- },
756
- ],
757
- },
758
- index: 0,
759
- },
760
- ],
761
- };
762
- yield {
763
- choices: [{ finish_reason: 'stop', delta: {}, index: 0 }],
764
- };
765
- });
766
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
767
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
768
- // Suppress console.warn for this test
769
- vi.spyOn(console, 'warn').mockImplementation(() => { });
770
- const events = await collectIterator(provider.stream(messages));
771
- // Should not emit any tool-related events
772
- const toolEvents = events.filter((e) => e.type === 'modelContentBlockStartEvent' || e.type === 'modelContentBlockDeltaEvent');
773
- expect(toolEvents).toHaveLength(0);
774
- // The important thing is that invalid tool calls don't crash the stream
775
- // and are properly skipped
776
- expect(events.length).toBeGreaterThan(0); // Still got message events
777
- });
778
- it('tool argument deltas can be reassembled into valid JSON', async () => {
779
- const mockClient = createMockClient(async function* () {
780
- yield { choices: [{ delta: { role: 'assistant' }, index: 0 }] };
781
- yield {
782
- choices: [
783
- {
784
- delta: {
785
- tool_calls: [
786
- {
787
- index: 0,
788
- id: 'call_123',
789
- type: 'function',
790
- function: { name: 'calculator', arguments: '' },
791
- },
792
- ],
793
- },
794
- index: 0,
795
- },
796
- ],
797
- };
798
- // Split JSON across multiple chunks in realistic ways
799
- yield { choices: [{ delta: { tool_calls: [{ index: 0, function: { arguments: '{"' } }] }, index: 0 }] };
800
- yield { choices: [{ delta: { tool_calls: [{ index: 0, function: { arguments: 'x":' } }] }, index: 0 }] };
801
- yield { choices: [{ delta: { tool_calls: [{ index: 0, function: { arguments: '10,' } }] }, index: 0 }] };
802
- yield { choices: [{ delta: { tool_calls: [{ index: 0, function: { arguments: '"y":' } }] }, index: 0 }] };
803
- yield { choices: [{ delta: { tool_calls: [{ index: 0, function: { arguments: '20}' } }] }, index: 0 }] };
804
- yield { choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }] };
805
- });
806
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
807
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
808
- const events = await collectIterator(provider.stream(messages));
809
- // Extract and concatenate all tool input deltas
810
- const inputDeltas = events
811
- .filter((e) => e.type === 'modelContentBlockDeltaEvent' && e.delta.type === 'toolUseInputDelta')
812
- .map((e) => e.delta.input);
813
- const reassembled = inputDeltas.join('');
814
- // Should be valid JSON
815
- expect(() => JSON.parse(reassembled)).not.toThrow();
816
- expect(JSON.parse(reassembled)).toEqual({ x: 10, y: 20 });
817
- });
818
- it('handles messages with both text and tool calls', async () => {
819
- const mockClient = createMockClient(async function* () {
820
- yield { choices: [{ delta: { role: 'assistant' }, index: 0 }] };
821
- // Text content first
822
- yield { choices: [{ delta: { content: 'Let me calculate ' }, index: 0 }] };
823
- yield { choices: [{ delta: { content: 'that for you.' }, index: 0 }] };
824
- // Then tool call
825
- yield {
826
- choices: [
827
- {
828
- delta: {
829
- tool_calls: [
830
- {
831
- index: 0,
832
- id: 'call_123',
833
- type: 'function',
834
- function: { name: 'calculator', arguments: '{"expr":"2+2"}' },
835
- },
836
- ],
837
- },
838
- index: 0,
839
- },
840
- ],
841
- };
842
- yield { choices: [{ finish_reason: 'tool_calls', delta: {}, index: 0 }] };
843
- });
844
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
845
- const messages = [new Message({ role: 'user', content: [new TextBlock('Calculate 2+2')] })];
846
- const events = await collectIterator(provider.stream(messages));
847
- // Should have text deltas followed by tool events
848
- expect(events[0]?.type).toBe('modelMessageStartEvent');
849
- // Text content block start
850
- expect(events[1]?.type).toBe('modelContentBlockStartEvent');
851
- // Text deltas
852
- expect(events[2]?.type).toBe('modelContentBlockDeltaEvent');
853
- expect(events[2].delta.type).toBe('textDelta');
854
- expect(events[2].delta.text).toBe('Let me calculate ');
855
- // Tool events should follow
856
- const toolStartEvent = events.find((e) => e.type === 'modelContentBlockStartEvent' && e.start?.type === 'toolUseStart');
857
- expect(toolStartEvent).toBeDefined();
858
- // Both text and tool blocks should have stop events
859
- const stopEvents = events.filter((e) => e.type === 'modelContentBlockStopEvent');
860
- expect(stopEvents.length).toBeGreaterThan(0);
861
- });
862
- });
863
- describe('stop reasons', () => {
864
- it('maps OpenAI stop reasons to SDK stop reasons', async () => {
865
- const stopReasons = [
866
- { openai: 'stop', sdk: 'endTurn' },
867
- { openai: 'tool_calls', sdk: 'toolUse' },
868
- { openai: 'length', sdk: 'maxTokens' },
869
- { openai: 'content_filter', sdk: 'contentFiltered' },
870
- ];
871
- for (const { openai, sdk } of stopReasons) {
872
- const mockClient = createMockClient(async function* () {
873
- yield {
874
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
875
- };
876
- yield {
877
- choices: [{ finish_reason: openai, delta: {}, index: 0 }],
878
- };
879
- });
880
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
881
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
882
- const events = await collectIterator(provider.stream(messages));
883
- const stopEvent = events.find((e) => e.type === 'modelMessageStopEvent');
884
- expect(stopEvent).toBeDefined();
885
- expect(stopEvent.stopReason).toBe(sdk);
886
- }
887
- });
888
- it('handles unknown stop reasons with warning', async () => {
889
- const mockClient = createMockClient(async function* () {
890
- yield {
891
- choices: [{ delta: { role: 'assistant' }, index: 0 }],
892
- };
893
- yield {
894
- choices: [{ finish_reason: 'new_unknown_reason', delta: {}, index: 0 }],
895
- };
896
- });
897
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
898
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
899
- const events = await collectIterator(provider.stream(messages));
900
- // Should convert unknown stop reason to camelCase
901
- const stopEvent = events.find((e) => e.type === 'modelMessageStopEvent');
902
- expect(stopEvent).toBeDefined();
903
- expect(stopEvent.stopReason).toBe('newUnknownReason');
904
- // Note: Warning logging is verified manually/visually since console.warn spying
905
- // has test isolation issues when running the full test suite
906
- });
907
- });
908
- describe('API request formatting', () => {
909
- it('formats API request correctly with all options', async () => {
910
- let capturedRequest = null;
911
- let callCount = 0;
912
- const mockClient = {
913
- chat: {
914
- completions: {
915
- create: vi.fn(async (request) => {
916
- capturedRequest = request;
917
- callCount++;
918
- // Return an async generator
919
- return (async function* () {
920
- yield { choices: [{ delta: { role: 'assistant' }, index: 0 }] };
921
- yield { choices: [{ finish_reason: 'stop', delta: {}, index: 0 }] };
922
- })();
923
- }),
924
- },
925
- },
926
- };
927
- const provider = new OpenAIModel({
928
- api: 'chat',
929
- modelId: 'gpt-5.4',
930
- client: mockClient,
931
- temperature: 0.7,
932
- maxTokens: 1000,
933
- });
934
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
935
- const toolSpecs = [
936
- {
937
- name: 'calculator',
938
- description: 'Calculate expressions',
939
- inputSchema: { type: 'object', properties: { expr: { type: 'string' } } },
940
- },
941
- ];
942
- await collectIterator(provider.stream(messages, {
943
- systemPrompt: 'You are a helpful assistant',
944
- toolSpecs,
945
- toolChoice: { auto: {} },
946
- }));
947
- // Verify create was called with correct structure
948
- expect(callCount).toBe(1);
949
- expect(capturedRequest).toBeDefined();
950
- expect(capturedRequest).toEqual({
951
- model: 'gpt-5.4',
952
- stream: true,
953
- stream_options: { include_usage: true },
954
- temperature: 0.7,
955
- max_completion_tokens: 1000,
956
- messages: [
957
- { role: 'system', content: 'You are a helpful assistant' },
958
- { role: 'user', content: [{ type: 'text', text: 'Hi' }] },
959
- ],
960
- tools: [
961
- {
962
- type: 'function',
963
- function: {
964
- name: 'calculator',
965
- description: 'Calculate expressions',
966
- parameters: { type: 'object', properties: { expr: { type: 'string' } } },
967
- },
968
- },
969
- ],
970
- tool_choice: 'auto',
971
- });
972
- });
973
- });
974
- describe('systemPrompt handling', () => {
975
- it('formats array system prompt with text blocks only', async () => {
976
- const captured = { request: null };
977
- const mockClient = createMockClientWithCapture(captured);
978
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
979
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
980
- await collectIterator(provider.stream(messages, {
981
- systemPrompt: [
982
- { type: 'textBlock', text: 'You are a helpful assistant' },
983
- { type: 'textBlock', text: 'Additional context here' },
984
- ],
985
- }));
986
- expect(captured.request).toBeDefined();
987
- expect(captured.request.messages).toEqual([
988
- { role: 'system', content: 'You are a helpful assistantAdditional context here' },
989
- { role: 'user', content: [{ type: 'text', text: 'Hello' }] },
990
- ]);
991
- });
992
- it('formats array system prompt with cache points', async () => {
993
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
994
- const captured = { request: null };
995
- const mockClient = createMockClientWithCapture(captured);
996
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
997
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
998
- collectIterator(provider.stream(messages, {
999
- systemPrompt: [
1000
- { type: 'textBlock', text: 'You are a helpful assistant' },
1001
- { type: 'textBlock', text: 'Large context document' },
1002
- { type: 'cachePointBlock', cacheType: 'default' },
1003
- ],
1004
- }));
1005
- // Verify warning was logged
1006
- expect(warnSpy).toHaveBeenCalledWith('cache points are not supported in openai system prompts, ignoring cache points');
1007
- // Verify system message contains only text (cache points ignored)
1008
- expect(captured.request).toBeDefined();
1009
- expect(captured.request.messages).toEqual([
1010
- { role: 'system', content: 'You are a helpful assistantLarge context document' },
1011
- { role: 'user', content: [{ type: 'text', text: 'Hello' }] },
1012
- ]);
1013
- warnSpy.mockRestore();
1014
- });
1015
- it('handles empty array system prompt', async () => {
1016
- const captured = { request: null };
1017
- const mockClient = createMockClientWithCapture(captured);
1018
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1019
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
1020
- await collectIterator(provider.stream(messages, {
1021
- systemPrompt: [],
1022
- }));
1023
- // Empty array should not add system message
1024
- expect(captured.request).toBeDefined();
1025
- expect(captured.request.messages).toEqual([{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }]);
1026
- });
1027
- it('formats array system prompt with single text block', async () => {
1028
- const captured = { request: null };
1029
- const mockClient = createMockClientWithCapture(captured);
1030
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1031
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
1032
- await collectIterator(provider.stream(messages, {
1033
- systemPrompt: [{ type: 'textBlock', text: 'You are a helpful assistant' }],
1034
- }));
1035
- expect(captured.request).toBeDefined();
1036
- expect(captured.request.messages).toEqual([
1037
- { role: 'system', content: 'You are a helpful assistant' },
1038
- { role: 'user', content: [{ type: 'text', text: 'Hello' }] },
1039
- ]);
1040
- });
1041
- it('warns and filters guard content from system prompt', async () => {
1042
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1043
- const captured = { request: null };
1044
- const mockClient = createMockClientWithCapture(captured);
1045
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1046
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
1047
- await collectIterator(provider.stream(messages, {
1048
- systemPrompt: [
1049
- { type: 'textBlock', text: 'You are a helpful assistant' },
1050
- {
1051
- type: 'guardContentBlock',
1052
- text: {
1053
- qualifiers: ['grounding_source'],
1054
- text: 'Guard content',
1055
- },
1056
- },
1057
- ],
1058
- }));
1059
- // Verify warning was logged
1060
- expect(warnSpy).toHaveBeenCalledWith('guard content is not supported in openai system prompts, removing guard content block');
1061
- // Verify guard content is filtered out
1062
- expect(captured.request).toBeDefined();
1063
- expect(captured.request.messages).toEqual([
1064
- { role: 'system', content: 'You are a helpful assistant' },
1065
- { role: 'user', content: [{ type: 'text', text: 'Hello' }] },
1066
- ]);
1067
- warnSpy.mockRestore();
1068
- });
1069
- it('preserves text blocks when filtering guard content', async () => {
1070
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1071
- const captured = { request: null };
1072
- const mockClient = createMockClientWithCapture(captured);
1073
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1074
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
1075
- await collectIterator(provider.stream(messages, {
1076
- systemPrompt: [
1077
- { type: 'textBlock', text: 'First text' },
1078
- {
1079
- type: 'guardContentBlock',
1080
- text: {
1081
- qualifiers: ['query'],
1082
- text: 'Guard content',
1083
- },
1084
- },
1085
- { type: 'textBlock', text: 'Second text' },
1086
- ],
1087
- }));
1088
- // Verify warning was logged
1089
- expect(warnSpy).toHaveBeenCalledWith('guard content is not supported in openai system prompts, removing guard content block');
1090
- // Verify both text blocks preserved, guard content removed
1091
- expect(captured.request).toBeDefined();
1092
- expect(captured.request.messages).toEqual([
1093
- { role: 'system', content: 'First textSecond text' },
1094
- { role: 'user', content: [{ type: 'text', text: 'Hello' }] },
1095
- ]);
1096
- warnSpy.mockRestore();
1097
- });
1098
- it('handles system prompt with only guard content', async () => {
1099
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1100
- const captured = { request: null };
1101
- const mockClient = createMockClientWithCapture(captured);
1102
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1103
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hello')] })];
1104
- await collectIterator(provider.stream(messages, {
1105
- systemPrompt: [
1106
- {
1107
- type: 'guardContentBlock',
1108
- text: {
1109
- qualifiers: ['guard_content'],
1110
- text: 'Only guard content',
1111
- },
1112
- },
1113
- ],
1114
- }));
1115
- // Verify warning was logged
1116
- expect(warnSpy).toHaveBeenCalledWith('guard content is not supported in openai system prompts, removing guard content block');
1117
- // Verify no system message added (only guard content)
1118
- expect(captured.request).toBeDefined();
1119
- expect(captured.request.messages).toEqual([{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }]);
1120
- warnSpy.mockRestore();
1121
- });
1122
- });
1123
- describe('guard content in messages', () => {
1124
- it('warns and filters guard content from user messages', async () => {
1125
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1126
- const captured = { request: null };
1127
- const mockClient = createMockClientWithCapture(captured);
1128
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1129
- const messages = [
1130
- new Message({
1131
- role: 'user',
1132
- content: [
1133
- new TextBlock('Verify this:'),
1134
- new GuardContentBlock({
1135
- text: {
1136
- qualifiers: ['grounding_source'],
1137
- text: 'Guard content',
1138
- },
1139
- }),
1140
- new TextBlock('Is it correct?'),
1141
- ],
1142
- }),
1143
- ];
1144
- await collectIterator(provider.stream(messages));
1145
- // Verify warning was logged
1146
- expect(warnSpy).toHaveBeenCalledWith('block_type=<guardContentBlock> | unsupported content type in openai user message | skipping');
1147
- // Verify guard content filtered out
1148
- expect(captured.request).toBeDefined();
1149
- expect(captured.request.messages).toEqual([
1150
- {
1151
- role: 'user',
1152
- content: [
1153
- { type: 'text', text: 'Verify this:' },
1154
- { type: 'text', text: 'Is it correct?' },
1155
- ],
1156
- },
1157
- ]);
1158
- warnSpy.mockRestore();
1159
- });
1160
- it('warns and filters guard content with image from user messages', async () => {
1161
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1162
- const captured = { request: null };
1163
- const mockClient = createMockClientWithCapture(captured);
1164
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1165
- const imageBytes = new Uint8Array([1, 2, 3, 4]);
1166
- const messages = [
1167
- new Message({
1168
- role: 'user',
1169
- content: [
1170
- new TextBlock('Check this image:'),
1171
- new GuardContentBlock({
1172
- image: {
1173
- format: 'jpeg',
1174
- source: { bytes: imageBytes },
1175
- },
1176
- }),
1177
- ],
1178
- }),
1179
- ];
1180
- await collectIterator(provider.stream(messages));
1181
- // Verify warning was logged
1182
- expect(warnSpy).toHaveBeenCalledWith('block_type=<guardContentBlock> | unsupported content type in openai user message | skipping');
1183
- // Verify guard content filtered out
1184
- expect(captured.request).toBeDefined();
1185
- expect(captured.request.messages).toEqual([
1186
- { role: 'user', content: [{ type: 'text', text: 'Check this image:' }] },
1187
- ]);
1188
- warnSpy.mockRestore();
1189
- });
1190
- it('handles message with only guard content', async () => {
1191
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1192
- const captured = { request: null };
1193
- const mockClient = createMockClientWithCapture(captured);
1194
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1195
- const messages = [
1196
- new Message({
1197
- role: 'user',
1198
- content: [
1199
- new GuardContentBlock({
1200
- text: {
1201
- qualifiers: ['guard_content'],
1202
- text: 'Only guard content',
1203
- },
1204
- }),
1205
- ],
1206
- }),
1207
- ];
1208
- await collectIterator(provider.stream(messages));
1209
- // Verify warning was logged
1210
- expect(warnSpy).toHaveBeenCalledWith('block_type=<guardContentBlock> | unsupported content type in openai user message | skipping');
1211
- // Verify no user message added (only guard content)
1212
- expect(captured.request).toBeDefined();
1213
- expect(captured.request.messages).toEqual([]);
1214
- warnSpy.mockRestore();
1215
- });
1216
- });
1217
- describe('media blocks', () => {
1218
- it('formats image block in user message as image_url with base64', async () => {
1219
- const captured = { request: null };
1220
- const mockClient = createMockClientWithCapture(captured);
1221
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1222
- const imageBytes = new Uint8Array([72, 101, 108, 108, 111]);
1223
- const messages = [
1224
- new Message({
1225
- role: 'user',
1226
- content: [
1227
- new TextBlock('What is in this image?'),
1228
- new ImageBlock({ format: 'png', source: { bytes: imageBytes } }),
1229
- ],
1230
- }),
1231
- ];
1232
- await collectIterator(provider.stream(messages));
1233
- const userMsg = captured.request.messages[0];
1234
- expect(userMsg.role).toBe('user');
1235
- expect(userMsg.content).toHaveLength(2);
1236
- expect(userMsg.content[0]).toEqual({ type: 'text', text: 'What is in this image?' });
1237
- expect(userMsg.content[1]).toEqual({
1238
- type: 'image_url',
1239
- image_url: { url: 'data:image/png;base64,SGVsbG8=' },
1240
- });
1241
- });
1242
- it('formats image block in user message with URL source', async () => {
1243
- const captured = { request: null };
1244
- const mockClient = createMockClientWithCapture(captured);
1245
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1246
- const messages = [
1247
- new Message({
1248
- role: 'user',
1249
- content: [new ImageBlock({ format: 'jpeg', source: { url: 'https://example.com/img.jpg' } })],
1250
- }),
1251
- ];
1252
- await collectIterator(provider.stream(messages));
1253
- const userMsg = captured.request.messages[0];
1254
- expect(userMsg.content[0]).toEqual({
1255
- type: 'image_url',
1256
- image_url: { url: 'https://example.com/img.jpg' },
1257
- });
1258
- });
1259
- it('formats document block with bytes source as file in user message', async () => {
1260
- const captured = { request: null };
1261
- const mockClient = createMockClientWithCapture(captured);
1262
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1263
- const docBytes = new Uint8Array([1, 2, 3]);
1264
- const messages = [
1265
- new Message({
1266
- role: 'user',
1267
- content: [new DocumentBlock({ name: 'report.pdf', format: 'pdf', source: { bytes: docBytes } })],
1268
- }),
1269
- ];
1270
- await collectIterator(provider.stream(messages));
1271
- const userMsg = captured.request.messages[0];
1272
- expect(userMsg.content[0]).toEqual({
1273
- type: 'file',
1274
- file: { file_data: 'data:application/pdf;base64,AQID', filename: 'report.pdf' },
1275
- });
1276
- });
1277
- it('splits image from tool result into separate user message', async () => {
1278
- const captured = { request: null };
1279
- const mockClient = createMockClientWithCapture(captured);
1280
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1281
- const imageBytes = new Uint8Array([72, 101, 108, 108, 111]);
1282
- const messages = [
1283
- new Message({
1284
- role: 'user',
1285
- content: [
1286
- new ToolResultBlock({
1287
- toolUseId: 'tool-1',
1288
- status: 'success',
1289
- content: [
1290
- new TextBlock('Screenshot captured'),
1291
- new ImageBlock({ format: 'png', source: { bytes: imageBytes } }),
1292
- ],
1293
- }),
1294
- ],
1295
- }),
1296
- ];
1297
- await collectIterator(provider.stream(messages));
1298
- // Tool message with text only
1299
- const toolMsg = captured.request.messages[0];
1300
- expect(toolMsg.role).toBe('tool');
1301
- expect(toolMsg.tool_call_id).toBe('tool-1');
1302
- expect(toolMsg.content).toBe('Screenshot captured');
1303
- // Separate user message with image
1304
- const userMsg = captured.request.messages[1];
1305
- expect(userMsg.role).toBe('user');
1306
- expect(userMsg.content[0]).toEqual({
1307
- type: 'image_url',
1308
- image_url: { url: 'data:image/png;base64,SGVsbG8=' },
1309
- });
1310
- });
1311
- it('injects placeholder text when tool result contains only images', async () => {
1312
- const captured = { request: null };
1313
- const mockClient = createMockClientWithCapture(captured);
1314
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1315
- const messages = [
1316
- new Message({
1317
- role: 'user',
1318
- content: [
1319
- new ToolResultBlock({
1320
- toolUseId: 'tool-1',
1321
- status: 'success',
1322
- content: [new ImageBlock({ format: 'png', source: { bytes: new Uint8Array([1]) } })],
1323
- }),
1324
- ],
1325
- }),
1326
- ];
1327
- await collectIterator(provider.stream(messages));
1328
- const toolMsg = captured.request.messages[0];
1329
- expect(toolMsg.content).toContain('Tool successfully returned an image');
1330
- });
1331
- it('skips document block in tool result with warning', async () => {
1332
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1333
- const captured = { request: null };
1334
- const mockClient = createMockClientWithCapture(captured);
1335
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1336
- const messages = [
1337
- new Message({
1338
- role: 'user',
1339
- content: [
1340
- new ToolResultBlock({
1341
- toolUseId: 'tool-1',
1342
- status: 'success',
1343
- content: [
1344
- new TextBlock('result'),
1345
- new DocumentBlock({ name: 'doc.pdf', format: 'pdf', source: { bytes: new Uint8Array([1]) } }),
1346
- ],
1347
- }),
1348
- ],
1349
- }),
1350
- ];
1351
- await collectIterator(provider.stream(messages));
1352
- const toolMsg = captured.request.messages[0];
1353
- expect(toolMsg.content).toBe('result');
1354
- expect(warnSpy).toHaveBeenCalled();
1355
- warnSpy.mockRestore();
1356
- });
1357
- it('skips video block in tool result with warning', async () => {
1358
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
1359
- const captured = { request: null };
1360
- const mockClient = createMockClientWithCapture(captured);
1361
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1362
- const messages = [
1363
- new Message({
1364
- role: 'user',
1365
- content: [
1366
- new ToolResultBlock({
1367
- toolUseId: 'tool-1',
1368
- status: 'success',
1369
- content: [
1370
- new TextBlock('result'),
1371
- new VideoBlock({ format: 'mp4', source: { bytes: new Uint8Array([1]) } }),
1372
- ],
1373
- }),
1374
- ],
1375
- }),
1376
- ];
1377
- await collectIterator(provider.stream(messages));
1378
- const toolMsg = captured.request.messages[0];
1379
- expect(toolMsg.content).toBe('result');
1380
- expect(warnSpy).toHaveBeenCalled();
1381
- warnSpy.mockRestore();
1382
- });
1383
- });
1384
- describe('error handling', () => {
1385
- it('throws ContextWindowOverflowError for structured error with code', async () => {
1386
- const mockClient = {
1387
- chat: {
1388
- completions: {
1389
- create: vi.fn(async () => {
1390
- const error = new Error('Context length exceeded');
1391
- error.code = 'context_length_exceeded';
1392
- throw error;
1393
- }),
1394
- },
1395
- },
1396
- };
1397
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1398
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1399
- await expect(async () => {
1400
- for await (const _ of provider.stream(messages)) {
1401
- // Should not reach here
1402
- }
1403
- }).rejects.toThrow(ContextWindowOverflowError);
1404
- });
1405
- it('throws ContextWindowOverflowError for error with message pattern', async () => {
1406
- const mockClient = {
1407
- chat: {
1408
- completions: {
1409
- create: vi.fn(async () => {
1410
- throw new Error('maximum context length exceeded');
1411
- }),
1412
- },
1413
- },
1414
- };
1415
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1416
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1417
- await expect(async () => {
1418
- for await (const _ of provider.stream(messages)) {
1419
- // Should not reach here
1420
- }
1421
- }).rejects.toThrow(ContextWindowOverflowError);
1422
- });
1423
- it('throws ContextWindowOverflowError for APIError instance', async () => {
1424
- const mockClient = {
1425
- chat: {
1426
- completions: {
1427
- create: vi.fn(async () => {
1428
- // Simulate APIError from openai package
1429
- const error = new Error('Context length exceeded');
1430
- error.name = 'APIError';
1431
- error.status = 400;
1432
- error.code = 'context_length_exceeded';
1433
- // Make it behave like an APIError instance
1434
- Object.setPrototypeOf(error, Error.prototype);
1435
- throw error;
1436
- }),
1437
- },
1438
- },
1439
- };
1440
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1441
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1442
- await expect(async () => {
1443
- for await (const _ of provider.stream(messages)) {
1444
- // Should not reach here
1445
- }
1446
- }).rejects.toThrow(ContextWindowOverflowError);
1447
- });
1448
- it('passes through other errors unchanged', async () => {
1449
- const mockClient = {
1450
- chat: {
1451
- completions: {
1452
- create: vi.fn(async () => {
1453
- throw new Error('Invalid API key');
1454
- }),
1455
- },
1456
- },
1457
- };
1458
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1459
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1460
- await expect(async () => {
1461
- for await (const _ of provider.stream(messages)) {
1462
- // Should not reach here
1463
- }
1464
- }).rejects.toThrow('Invalid API key');
1465
- });
1466
- it('handles stream interruption errors', async () => {
1467
- const mockClient = createMockClient(async function* () {
1468
- yield { choices: [{ delta: { role: 'assistant' }, index: 0 }] };
1469
- yield { choices: [{ delta: { content: 'Hello' }, index: 0 }] };
1470
- // Stream interruption
1471
- throw new Error('Network connection lost');
1472
- });
1473
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1474
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1475
- await expect(async () => {
1476
- for await (const _ of provider.stream(messages)) {
1477
- // Stream will be interrupted
1478
- }
1479
- }).rejects.toThrow('Network connection lost');
1480
- });
1481
- it('throws ModelThrottledError for HTTP 429 status', async () => {
1482
- const originalError = new Error('Too many requests');
1483
- originalError.status = 429;
1484
- const mockClient = {
1485
- chat: {
1486
- completions: {
1487
- create: vi.fn(async () => {
1488
- throw originalError;
1489
- }),
1490
- },
1491
- },
1492
- };
1493
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1494
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1495
- await expect(async () => {
1496
- for await (const _ of provider.stream(messages)) {
1497
- // Should not reach here
1498
- }
1499
- }).rejects.toThrow(ModelThrottledError);
1500
- });
1501
- it('throws ModelThrottledError for rate_limit_exceeded error code', async () => {
1502
- const originalError = new Error('Rate limit reached');
1503
- originalError.code = 'rate_limit_exceeded';
1504
- const mockClient = {
1505
- chat: {
1506
- completions: {
1507
- create: vi.fn(async () => {
1508
- throw originalError;
1509
- }),
1510
- },
1511
- },
1512
- };
1513
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1514
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1515
- await expect(async () => {
1516
- for await (const _ of provider.stream(messages)) {
1517
- // Should not reach here
1518
- }
1519
- }).rejects.toThrow(ModelThrottledError);
1520
- });
1521
- it('throws ModelThrottledError for error message containing rate limit pattern', async () => {
1522
- const mockClient = {
1523
- chat: {
1524
- completions: {
1525
- create: vi.fn(async () => {
1526
- throw new Error('You have exceeded your rate limit');
1527
- }),
1528
- },
1529
- },
1530
- };
1531
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1532
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1533
- await expect(async () => {
1534
- for await (const _ of provider.stream(messages)) {
1535
- // Should not reach here
1536
- }
1537
- }).rejects.toThrow(ModelThrottledError);
1538
- });
1539
- it('throws ModelThrottledError for too many requests message', async () => {
1540
- const mockClient = {
1541
- chat: {
1542
- completions: {
1543
- create: vi.fn(async () => {
1544
- throw new Error('Too many requests, please slow down');
1545
- }),
1546
- },
1547
- },
1548
- };
1549
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1550
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1551
- await expect(async () => {
1552
- for await (const _ of provider.stream(messages)) {
1553
- // Should not reach here
1554
- }
1555
- }).rejects.toThrow(ModelThrottledError);
1556
- });
1557
- it('preserves original error as cause in ModelThrottledError', async () => {
1558
- const originalError = new Error('Request too large for gpt-5.4 on tokens per min');
1559
- originalError.status = 429;
1560
- const mockClient = {
1561
- chat: {
1562
- completions: {
1563
- create: vi.fn(async () => {
1564
- throw originalError;
1565
- }),
1566
- },
1567
- },
1568
- };
1569
- const provider = new OpenAIModel({ api: 'chat', client: mockClient });
1570
- const messages = [new Message({ role: 'user', content: [new TextBlock('Hi')] })];
1571
- try {
1572
- for await (const _ of provider.stream(messages)) {
1573
- // Should not reach here
1574
- }
1575
- expect.fail('Should have thrown');
1576
- }
1577
- catch (error) {
1578
- expect(error).toBeInstanceOf(ModelThrottledError);
1579
- const throttleError = error;
1580
- expect(throttleError.cause).toBe(originalError);
1581
- expect(throttleError.message).toBe('Request too large for gpt-5.4 on tokens per min');
1582
- }
1583
- });
1584
- });
1585
- });
1586
- //# sourceMappingURL=chat.test.js.map