@copilotkit/aimock 1.7.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 (368) hide show
  1. package/.claude-plugin/marketplace.json +17 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/LICENSE +21 -0
  4. package/README.md +82 -0
  5. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  6. package/dist/a2a-handler.cjs +203 -0
  7. package/dist/a2a-handler.cjs.map +1 -0
  8. package/dist/a2a-handler.js +199 -0
  9. package/dist/a2a-handler.js.map +1 -0
  10. package/dist/a2a-mock.cjs +292 -0
  11. package/dist/a2a-mock.cjs.map +1 -0
  12. package/dist/a2a-mock.d.cts +41 -0
  13. package/dist/a2a-mock.d.cts.map +1 -0
  14. package/dist/a2a-mock.d.ts +41 -0
  15. package/dist/a2a-mock.d.ts.map +1 -0
  16. package/dist/a2a-mock.js +290 -0
  17. package/dist/a2a-mock.js.map +1 -0
  18. package/dist/a2a-stub.cjs +4 -0
  19. package/dist/a2a-stub.d.cts +3 -0
  20. package/dist/a2a-stub.d.ts +3 -0
  21. package/dist/a2a-stub.js +3 -0
  22. package/dist/a2a-types.d.cts +68 -0
  23. package/dist/a2a-types.d.cts.map +1 -0
  24. package/dist/a2a-types.d.ts +68 -0
  25. package/dist/a2a-types.d.ts.map +1 -0
  26. package/dist/aimock-cli.cjs +112 -0
  27. package/dist/aimock-cli.cjs.map +1 -0
  28. package/dist/aimock-cli.d.cts +19 -0
  29. package/dist/aimock-cli.d.cts.map +1 -0
  30. package/dist/aimock-cli.d.ts +19 -0
  31. package/dist/aimock-cli.d.ts.map +1 -0
  32. package/dist/aimock-cli.js +110 -0
  33. package/dist/aimock-cli.js.map +1 -0
  34. package/dist/aws-event-stream.cjs +117 -0
  35. package/dist/aws-event-stream.cjs.map +1 -0
  36. package/dist/aws-event-stream.d.cts +38 -0
  37. package/dist/aws-event-stream.d.cts.map +1 -0
  38. package/dist/aws-event-stream.d.ts +38 -0
  39. package/dist/aws-event-stream.d.ts.map +1 -0
  40. package/dist/aws-event-stream.js +114 -0
  41. package/dist/aws-event-stream.js.map +1 -0
  42. package/dist/bedrock-converse.cjs +445 -0
  43. package/dist/bedrock-converse.cjs.map +1 -0
  44. package/dist/bedrock-converse.d.cts +50 -0
  45. package/dist/bedrock-converse.d.cts.map +1 -0
  46. package/dist/bedrock-converse.d.ts +50 -0
  47. package/dist/bedrock-converse.d.ts.map +1 -0
  48. package/dist/bedrock-converse.js +443 -0
  49. package/dist/bedrock-converse.js.map +1 -0
  50. package/dist/bedrock.cjs +557 -0
  51. package/dist/bedrock.cjs.map +1 -0
  52. package/dist/bedrock.d.cts +41 -0
  53. package/dist/bedrock.d.cts.map +1 -0
  54. package/dist/bedrock.d.ts +41 -0
  55. package/dist/bedrock.d.ts.map +1 -0
  56. package/dist/bedrock.js +553 -0
  57. package/dist/bedrock.js.map +1 -0
  58. package/dist/chaos.cjs +114 -0
  59. package/dist/chaos.cjs.map +1 -0
  60. package/dist/chaos.d.cts +27 -0
  61. package/dist/chaos.d.cts.map +1 -0
  62. package/dist/chaos.d.ts +27 -0
  63. package/dist/chaos.d.ts.map +1 -0
  64. package/dist/chaos.js +113 -0
  65. package/dist/chaos.js.map +1 -0
  66. package/dist/cli.cjs +268 -0
  67. package/dist/cli.cjs.map +1 -0
  68. package/dist/cli.d.cts +1 -0
  69. package/dist/cli.d.ts +1 -0
  70. package/dist/cli.js +268 -0
  71. package/dist/cli.js.map +1 -0
  72. package/dist/cohere.cjs +434 -0
  73. package/dist/cohere.cjs.map +1 -0
  74. package/dist/cohere.d.cts +34 -0
  75. package/dist/cohere.d.cts.map +1 -0
  76. package/dist/cohere.d.ts +34 -0
  77. package/dist/cohere.d.ts.map +1 -0
  78. package/dist/cohere.js +433 -0
  79. package/dist/cohere.js.map +1 -0
  80. package/dist/config-loader.cjs +111 -0
  81. package/dist/config-loader.cjs.map +1 -0
  82. package/dist/config-loader.d.cts +100 -0
  83. package/dist/config-loader.d.cts.map +1 -0
  84. package/dist/config-loader.d.ts +100 -0
  85. package/dist/config-loader.d.ts.map +1 -0
  86. package/dist/config-loader.js +107 -0
  87. package/dist/config-loader.js.map +1 -0
  88. package/dist/embeddings.cjs +150 -0
  89. package/dist/embeddings.cjs.map +1 -0
  90. package/dist/embeddings.d.cts +12 -0
  91. package/dist/embeddings.d.cts.map +1 -0
  92. package/dist/embeddings.d.ts +12 -0
  93. package/dist/embeddings.d.ts.map +1 -0
  94. package/dist/embeddings.js +150 -0
  95. package/dist/embeddings.js.map +1 -0
  96. package/dist/fixture-loader.cjs +269 -0
  97. package/dist/fixture-loader.cjs.map +1 -0
  98. package/dist/fixture-loader.d.cts +17 -0
  99. package/dist/fixture-loader.d.cts.map +1 -0
  100. package/dist/fixture-loader.d.ts +17 -0
  101. package/dist/fixture-loader.d.ts.map +1 -0
  102. package/dist/fixture-loader.js +265 -0
  103. package/dist/fixture-loader.js.map +1 -0
  104. package/dist/gemini.cjs +403 -0
  105. package/dist/gemini.cjs.map +1 -0
  106. package/dist/gemini.d.cts +10 -0
  107. package/dist/gemini.d.cts.map +1 -0
  108. package/dist/gemini.d.ts +10 -0
  109. package/dist/gemini.d.ts.map +1 -0
  110. package/dist/gemini.js +403 -0
  111. package/dist/gemini.js.map +1 -0
  112. package/dist/helpers.cjs +276 -0
  113. package/dist/helpers.cjs.map +1 -0
  114. package/dist/helpers.d.cts +39 -0
  115. package/dist/helpers.d.cts.map +1 -0
  116. package/dist/helpers.d.ts +39 -0
  117. package/dist/helpers.d.ts.map +1 -0
  118. package/dist/helpers.js +259 -0
  119. package/dist/helpers.js.map +1 -0
  120. package/dist/index.cjs +113 -0
  121. package/dist/index.d.cts +42 -0
  122. package/dist/index.d.ts +42 -0
  123. package/dist/index.js +39 -0
  124. package/dist/interruption.cjs +40 -0
  125. package/dist/interruption.cjs.map +1 -0
  126. package/dist/interruption.d.cts +15 -0
  127. package/dist/interruption.d.cts.map +1 -0
  128. package/dist/interruption.d.ts +15 -0
  129. package/dist/interruption.d.ts.map +1 -0
  130. package/dist/interruption.js +39 -0
  131. package/dist/interruption.js.map +1 -0
  132. package/dist/journal.cjs +65 -0
  133. package/dist/journal.cjs.map +1 -0
  134. package/dist/journal.d.cts +23 -0
  135. package/dist/journal.d.cts.map +1 -0
  136. package/dist/journal.d.ts +23 -0
  137. package/dist/journal.d.ts.map +1 -0
  138. package/dist/journal.js +65 -0
  139. package/dist/journal.js.map +1 -0
  140. package/dist/jsonrpc.cjs +91 -0
  141. package/dist/jsonrpc.cjs.map +1 -0
  142. package/dist/jsonrpc.d.cts +24 -0
  143. package/dist/jsonrpc.d.cts.map +1 -0
  144. package/dist/jsonrpc.d.ts +24 -0
  145. package/dist/jsonrpc.d.ts.map +1 -0
  146. package/dist/jsonrpc.js +90 -0
  147. package/dist/jsonrpc.js.map +1 -0
  148. package/dist/llmock.cjs +223 -0
  149. package/dist/llmock.cjs.map +1 -0
  150. package/dist/llmock.d.cts +70 -0
  151. package/dist/llmock.d.cts.map +1 -0
  152. package/dist/llmock.d.ts +70 -0
  153. package/dist/llmock.d.ts.map +1 -0
  154. package/dist/llmock.js +223 -0
  155. package/dist/llmock.js.map +1 -0
  156. package/dist/logger.cjs +29 -0
  157. package/dist/logger.cjs.map +1 -0
  158. package/dist/logger.d.cts +14 -0
  159. package/dist/logger.d.cts.map +1 -0
  160. package/dist/logger.d.ts +14 -0
  161. package/dist/logger.d.ts.map +1 -0
  162. package/dist/logger.js +28 -0
  163. package/dist/logger.js.map +1 -0
  164. package/dist/mcp-handler.cjs +189 -0
  165. package/dist/mcp-handler.cjs.map +1 -0
  166. package/dist/mcp-handler.js +188 -0
  167. package/dist/mcp-handler.js.map +1 -0
  168. package/dist/mcp-mock.cjs +169 -0
  169. package/dist/mcp-mock.cjs.map +1 -0
  170. package/dist/mcp-mock.d.cts +40 -0
  171. package/dist/mcp-mock.d.cts.map +1 -0
  172. package/dist/mcp-mock.d.ts +40 -0
  173. package/dist/mcp-mock.d.ts.map +1 -0
  174. package/dist/mcp-mock.js +167 -0
  175. package/dist/mcp-mock.js.map +1 -0
  176. package/dist/mcp-stub.cjs +4 -0
  177. package/dist/mcp-stub.d.cts +3 -0
  178. package/dist/mcp-stub.d.ts +3 -0
  179. package/dist/mcp-stub.js +3 -0
  180. package/dist/mcp-types.d.cts +65 -0
  181. package/dist/mcp-types.d.cts.map +1 -0
  182. package/dist/mcp-types.d.ts +65 -0
  183. package/dist/mcp-types.d.ts.map +1 -0
  184. package/dist/messages.cjs +489 -0
  185. package/dist/messages.cjs.map +1 -0
  186. package/dist/messages.d.cts +10 -0
  187. package/dist/messages.d.cts.map +1 -0
  188. package/dist/messages.d.ts +10 -0
  189. package/dist/messages.d.ts.map +1 -0
  190. package/dist/messages.js +489 -0
  191. package/dist/messages.js.map +1 -0
  192. package/dist/metrics.cjs +160 -0
  193. package/dist/metrics.cjs.map +1 -0
  194. package/dist/metrics.d.cts +24 -0
  195. package/dist/metrics.d.cts.map +1 -0
  196. package/dist/metrics.d.ts +24 -0
  197. package/dist/metrics.d.ts.map +1 -0
  198. package/dist/metrics.js +158 -0
  199. package/dist/metrics.js.map +1 -0
  200. package/dist/moderation.cjs +91 -0
  201. package/dist/moderation.cjs.map +1 -0
  202. package/dist/moderation.d.cts +23 -0
  203. package/dist/moderation.d.cts.map +1 -0
  204. package/dist/moderation.d.ts +23 -0
  205. package/dist/moderation.d.ts.map +1 -0
  206. package/dist/moderation.js +91 -0
  207. package/dist/moderation.js.map +1 -0
  208. package/dist/ndjson-writer.cjs +31 -0
  209. package/dist/ndjson-writer.cjs.map +1 -0
  210. package/dist/ndjson-writer.d.cts +17 -0
  211. package/dist/ndjson-writer.d.cts.map +1 -0
  212. package/dist/ndjson-writer.d.ts +17 -0
  213. package/dist/ndjson-writer.d.ts.map +1 -0
  214. package/dist/ndjson-writer.js +31 -0
  215. package/dist/ndjson-writer.js.map +1 -0
  216. package/dist/ollama.cjs +519 -0
  217. package/dist/ollama.cjs.map +1 -0
  218. package/dist/ollama.d.cts +34 -0
  219. package/dist/ollama.d.cts.map +1 -0
  220. package/dist/ollama.d.ts +34 -0
  221. package/dist/ollama.d.ts.map +1 -0
  222. package/dist/ollama.js +517 -0
  223. package/dist/ollama.js.map +1 -0
  224. package/dist/recorder.cjs +311 -0
  225. package/dist/recorder.cjs.map +1 -0
  226. package/dist/recorder.d.cts +23 -0
  227. package/dist/recorder.d.cts.map +1 -0
  228. package/dist/recorder.d.ts +23 -0
  229. package/dist/recorder.d.ts.map +1 -0
  230. package/dist/recorder.js +305 -0
  231. package/dist/recorder.js.map +1 -0
  232. package/dist/rerank.cjs +71 -0
  233. package/dist/rerank.cjs.map +1 -0
  234. package/dist/rerank.d.cts +22 -0
  235. package/dist/rerank.d.cts.map +1 -0
  236. package/dist/rerank.d.ts +22 -0
  237. package/dist/rerank.d.ts.map +1 -0
  238. package/dist/rerank.js +71 -0
  239. package/dist/rerank.js.map +1 -0
  240. package/dist/responses.cjs +637 -0
  241. package/dist/responses.cjs.map +1 -0
  242. package/dist/responses.d.cts +16 -0
  243. package/dist/responses.d.cts.map +1 -0
  244. package/dist/responses.d.ts +16 -0
  245. package/dist/responses.d.ts.map +1 -0
  246. package/dist/responses.js +634 -0
  247. package/dist/responses.js.map +1 -0
  248. package/dist/router.cjs +68 -0
  249. package/dist/router.cjs.map +1 -0
  250. package/dist/router.d.cts +16 -0
  251. package/dist/router.d.cts.map +1 -0
  252. package/dist/router.d.ts +16 -0
  253. package/dist/router.d.ts.map +1 -0
  254. package/dist/router.js +65 -0
  255. package/dist/router.js.map +1 -0
  256. package/dist/search.cjs +59 -0
  257. package/dist/search.cjs.map +1 -0
  258. package/dist/search.d.cts +23 -0
  259. package/dist/search.d.cts.map +1 -0
  260. package/dist/search.d.ts +23 -0
  261. package/dist/search.d.ts.map +1 -0
  262. package/dist/search.js +59 -0
  263. package/dist/search.js.map +1 -0
  264. package/dist/server.cjs +935 -0
  265. package/dist/server.cjs.map +1 -0
  266. package/dist/server.d.cts +28 -0
  267. package/dist/server.d.cts.map +1 -0
  268. package/dist/server.d.ts +28 -0
  269. package/dist/server.d.ts.map +1 -0
  270. package/dist/server.js +933 -0
  271. package/dist/server.js.map +1 -0
  272. package/dist/sse-writer.cjs +59 -0
  273. package/dist/sse-writer.cjs.map +1 -0
  274. package/dist/sse-writer.d.cts +19 -0
  275. package/dist/sse-writer.d.cts.map +1 -0
  276. package/dist/sse-writer.d.ts +19 -0
  277. package/dist/sse-writer.d.ts.map +1 -0
  278. package/dist/sse-writer.js +55 -0
  279. package/dist/sse-writer.js.map +1 -0
  280. package/dist/stream-collapse.cjs +496 -0
  281. package/dist/stream-collapse.cjs.map +1 -0
  282. package/dist/stream-collapse.d.cts +70 -0
  283. package/dist/stream-collapse.d.cts.map +1 -0
  284. package/dist/stream-collapse.d.ts +70 -0
  285. package/dist/stream-collapse.d.ts.map +1 -0
  286. package/dist/stream-collapse.js +489 -0
  287. package/dist/stream-collapse.js.map +1 -0
  288. package/dist/suite.cjs +46 -0
  289. package/dist/suite.cjs.map +1 -0
  290. package/dist/suite.d.cts +31 -0
  291. package/dist/suite.d.cts.map +1 -0
  292. package/dist/suite.d.ts +31 -0
  293. package/dist/suite.d.ts.map +1 -0
  294. package/dist/suite.js +46 -0
  295. package/dist/suite.js.map +1 -0
  296. package/dist/types.d.cts +243 -0
  297. package/dist/types.d.cts.map +1 -0
  298. package/dist/types.d.ts +243 -0
  299. package/dist/types.d.ts.map +1 -0
  300. package/dist/url.cjs +21 -0
  301. package/dist/url.cjs.map +1 -0
  302. package/dist/url.d.cts +16 -0
  303. package/dist/url.d.cts.map +1 -0
  304. package/dist/url.d.ts +16 -0
  305. package/dist/url.d.ts.map +1 -0
  306. package/dist/url.js +20 -0
  307. package/dist/url.js.map +1 -0
  308. package/dist/vector-handler.cjs +239 -0
  309. package/dist/vector-handler.cjs.map +1 -0
  310. package/dist/vector-handler.js +238 -0
  311. package/dist/vector-handler.js.map +1 -0
  312. package/dist/vector-mock.cjs +229 -0
  313. package/dist/vector-mock.cjs.map +1 -0
  314. package/dist/vector-mock.d.cts +39 -0
  315. package/dist/vector-mock.d.cts.map +1 -0
  316. package/dist/vector-mock.d.ts +39 -0
  317. package/dist/vector-mock.d.ts.map +1 -0
  318. package/dist/vector-mock.js +227 -0
  319. package/dist/vector-mock.js.map +1 -0
  320. package/dist/vector-stub.cjs +4 -0
  321. package/dist/vector-stub.d.cts +3 -0
  322. package/dist/vector-stub.d.ts +3 -0
  323. package/dist/vector-stub.js +3 -0
  324. package/dist/vector-types.d.cts +32 -0
  325. package/dist/vector-types.d.cts.map +1 -0
  326. package/dist/vector-types.d.ts +32 -0
  327. package/dist/vector-types.d.ts.map +1 -0
  328. package/dist/watcher.cjs +59 -0
  329. package/dist/watcher.cjs.map +1 -0
  330. package/dist/watcher.js +58 -0
  331. package/dist/watcher.js.map +1 -0
  332. package/dist/ws-framing.cjs +187 -0
  333. package/dist/ws-framing.cjs.map +1 -0
  334. package/dist/ws-framing.d.cts +26 -0
  335. package/dist/ws-framing.d.cts.map +1 -0
  336. package/dist/ws-framing.d.ts +26 -0
  337. package/dist/ws-framing.d.ts.map +1 -0
  338. package/dist/ws-framing.js +184 -0
  339. package/dist/ws-framing.js.map +1 -0
  340. package/dist/ws-gemini-live.cjs +364 -0
  341. package/dist/ws-gemini-live.cjs.map +1 -0
  342. package/dist/ws-gemini-live.d.cts +18 -0
  343. package/dist/ws-gemini-live.d.cts.map +1 -0
  344. package/dist/ws-gemini-live.d.ts +18 -0
  345. package/dist/ws-gemini-live.d.ts.map +1 -0
  346. package/dist/ws-gemini-live.js +364 -0
  347. package/dist/ws-gemini-live.js.map +1 -0
  348. package/dist/ws-realtime.cjs +435 -0
  349. package/dist/ws-realtime.cjs.map +1 -0
  350. package/dist/ws-realtime.d.cts +17 -0
  351. package/dist/ws-realtime.d.cts.map +1 -0
  352. package/dist/ws-realtime.d.ts +17 -0
  353. package/dist/ws-realtime.d.ts.map +1 -0
  354. package/dist/ws-realtime.js +435 -0
  355. package/dist/ws-realtime.js.map +1 -0
  356. package/dist/ws-responses.cjs +164 -0
  357. package/dist/ws-responses.cjs.map +1 -0
  358. package/dist/ws-responses.d.cts +18 -0
  359. package/dist/ws-responses.d.cts.map +1 -0
  360. package/dist/ws-responses.d.ts +18 -0
  361. package/dist/ws-responses.d.ts.map +1 -0
  362. package/dist/ws-responses.js +164 -0
  363. package/dist/ws-responses.js.map +1 -0
  364. package/fixtures/example-greeting.json +12 -0
  365. package/fixtures/example-multi-turn.json +14 -0
  366. package/fixtures/example-tool-call.json +15 -0
  367. package/package.json +118 -0
  368. package/skills/write-fixtures/SKILL.md +625 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-mock.js","names":[],"sources":["../src/mcp-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n MCPMockOptions,\n MCPToolDefinition,\n MCPResourceDefinition,\n MCPResourceContent,\n MCPPromptDefinition,\n MCPPromptResult,\n MCPContent,\n MCPSession,\n} from \"./mcp-types.js\";\nimport { createMCPRequestHandler, type MCPState } from \"./mcp-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\n\nexport class MCPMock implements Mountable {\n private tools: Map<\n string,\n { def: MCPToolDefinition; handler?: (...args: unknown[]) => unknown }\n > = new Map();\n private resources: Map<string, { def: MCPResourceDefinition; content?: MCPResourceContent }> =\n new Map();\n private prompts: Map<\n string,\n {\n def: MCPPromptDefinition;\n handler?: (...args: unknown[]) => MCPPromptResult | Promise<MCPPromptResult>;\n }\n > = new Map();\n private sessions: Map<string, MCPSession> = new Map();\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: MCPMockOptions;\n private requestHandler: ReturnType<typeof createMCPRequestHandler>;\n\n constructor(options?: MCPMockOptions) {\n this.options = options ?? {};\n this.requestHandler = this.buildHandler();\n }\n\n // ---- Configuration: Tools ----\n\n addTool(def: MCPToolDefinition): this {\n this.tools.set(def.name, { def });\n return this;\n }\n\n onToolCall(\n name: string,\n handler: (args: unknown) => MCPContent[] | string | Promise<MCPContent[] | string>,\n ): this {\n const entry = this.tools.get(name);\n if (entry) {\n entry.handler = handler;\n } else {\n this.tools.set(name, { def: { name }, handler });\n }\n return this;\n }\n\n // ---- Configuration: Resources ----\n\n addResource(def: MCPResourceDefinition, content?: MCPResourceContent): this {\n this.resources.set(def.uri, { def, content });\n return this;\n }\n\n // ---- Configuration: Prompts ----\n\n addPrompt(\n def: MCPPromptDefinition,\n handler?: (args: unknown) => MCPPromptResult | Promise<MCPPromptResult>,\n ): this {\n this.prompts.set(def.name, { def, handler });\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n // Only handle POST and DELETE to the root of the mount\n if (pathname !== \"/\" && pathname !== \"\") {\n return false;\n }\n if (req.method !== \"POST\" && req.method !== \"DELETE\") {\n return false;\n }\n\n const body = await readBody(req);\n\n // Extract JSON-RPC method for metrics (skip for DELETE — no JSON-RPC body)\n if (this.registry) {\n if (req.method === \"DELETE\") {\n this.registry.incrementCounter(\"aimock_mcp_requests_total\", { method: \"session/delete\" });\n } else {\n try {\n const parsed = JSON.parse(body);\n const method =\n typeof parsed === \"object\" && parsed !== null && \"method\" in parsed\n ? String(parsed.method)\n : \"unknown\";\n this.registry.incrementCounter(\"aimock_mcp_requests_total\", { method });\n } catch {\n this.registry.incrementCounter(\"aimock_mcp_requests_total\", { method: \"unknown\" });\n }\n }\n }\n\n await this.requestHandler(req, res, body);\n\n // Journal the request after the handler completes\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"mcp\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n\n return true;\n }\n\n health(): { status: string; [key: string]: unknown } {\n return {\n status: \"ok\",\n tools: this.tools.size,\n resources: this.resources.size,\n prompts: this.prompts.size,\n sessions: this.sessions.size,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"Server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise((resolve, reject) => {\n const srv = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n req.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString();\n\n this.requestHandler(req, res, body)\n .then(() => {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/\",\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"mcp\",\n response: { status: res.statusCode, fixture: null },\n });\n }\n })\n .catch((err) => {\n console.error(\"MCPMock request error:\", err);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n }\n });\n });\n });\n\n srv.listen(port, host, () => {\n this.server = srv;\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n resolve(`http://${host}:${addr.port}`);\n } else {\n resolve(`http://${host}:${port}`);\n }\n });\n\n srv.on(\"error\", reject);\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"Server not started\");\n }\n const srv = this.server;\n this.server = null;\n await new Promise<void>((resolve, reject) => {\n srv.close((err) => (err ? reject(err) : resolve()));\n });\n }\n\n // ---- Inspection ----\n\n getRequests(): unknown[] {\n if (!this.journal) return [];\n return this.journal.getAll().filter((e) => e.service === \"mcp\");\n }\n\n getSessions(): Map<string, MCPSession> {\n return new Map(this.sessions);\n }\n\n reset(): this {\n this.tools.clear();\n this.resources.clear();\n this.prompts.clear();\n this.sessions.clear();\n this.requestHandler = this.buildHandler();\n return this;\n }\n\n // ---- Internal ----\n\n private buildHandler() {\n const state: MCPState = {\n serverInfo: this.options.serverInfo ?? { name: \"mcp-mock\", version: \"1.0.0\" },\n tools: this.tools,\n resources: this.resources,\n prompts: this.prompts,\n sessions: this.sessions,\n };\n return createMCPRequestHandler(state);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_mcp_mock = require('./mcp-mock.cjs');
3
+
4
+ exports.MCPMock = require_mcp_mock.MCPMock;
@@ -0,0 +1,3 @@
1
+ import { MCPContent, MCPMockOptions, MCPPromptDefinition, MCPPromptResult, MCPResourceContent, MCPResourceDefinition, MCPSession, MCPToolDefinition } from "./mcp-types.cjs";
2
+ import { MCPMock } from "./mcp-mock.cjs";
3
+ export { type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition };
@@ -0,0 +1,3 @@
1
+ import { MCPContent, MCPMockOptions, MCPPromptDefinition, MCPPromptResult, MCPResourceContent, MCPResourceDefinition, MCPSession, MCPToolDefinition } from "./mcp-types.js";
2
+ import { MCPMock } from "./mcp-mock.js";
3
+ export { type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition };
@@ -0,0 +1,3 @@
1
+ import { MCPMock } from "./mcp-mock.js";
2
+
3
+ export { MCPMock };
@@ -0,0 +1,65 @@
1
+ //#region src/mcp-types.d.ts
2
+ interface MCPMockOptions {
3
+ port?: number;
4
+ host?: string;
5
+ serverInfo?: {
6
+ name: string;
7
+ version: string;
8
+ };
9
+ }
10
+ interface MCPToolDefinition {
11
+ name: string;
12
+ description?: string;
13
+ inputSchema?: Record<string, unknown>;
14
+ }
15
+ interface MCPResourceDefinition {
16
+ uri: string;
17
+ name: string;
18
+ mimeType?: string;
19
+ description?: string;
20
+ }
21
+ interface MCPPromptDefinition {
22
+ name: string;
23
+ description?: string;
24
+ arguments?: Array<{
25
+ name: string;
26
+ description?: string;
27
+ required?: boolean;
28
+ }>;
29
+ }
30
+ type MCPContent = {
31
+ type: "text";
32
+ text: string;
33
+ } | {
34
+ type: "image";
35
+ data: string;
36
+ mimeType: string;
37
+ } | {
38
+ type: "resource";
39
+ resource: {
40
+ uri: string;
41
+ text?: string;
42
+ blob?: string;
43
+ mimeType?: string;
44
+ };
45
+ };
46
+ interface MCPResourceContent {
47
+ text?: string;
48
+ blob?: string;
49
+ mimeType?: string;
50
+ }
51
+ interface MCPPromptResult {
52
+ messages: Array<{
53
+ role: string;
54
+ content: MCPContent;
55
+ }>;
56
+ }
57
+ interface MCPSession {
58
+ id: string;
59
+ initialized: boolean;
60
+ createdAt: number;
61
+ }
62
+ //# sourceMappingURL=mcp-types.d.ts.map
63
+ //#endregion
64
+ export { MCPContent, MCPMockOptions, MCPPromptDefinition, MCPPromptResult, MCPResourceContent, MCPResourceDefinition, MCPSession, MCPToolDefinition };
65
+ //# sourceMappingURL=mcp-types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-types.d.cts","names":[],"sources":["../src/mcp-types.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAMA,IAAA,CAAA,EAAA,MAAA;EAMA,UAAA,CAAA,EAAA;IAOA,IAAA,EAAA,MAAA;IAML,OAAA,EAAU,MAAA;EAQL,CAAA;AAMjB;AAAgC,UAjCf,iBAAA,CAiCe;MACW,EAAA,MAAA;aAA/B,CAAA,EAAA,MAAA;EAAK,WAAA,CAAA,EA/BD,MA+BC,CAAA,MAAA,EAAA,OAAA,CAAA;AAGjB;UA/BiB,qBAAA;;;;;;UAOA,mBAAA;;;cAGH;;;;;;KAGF,UAAA;;;;;;;;;;;;;;;;UAQK,kBAAA;;;;;UAMA,eAAA;YACL;;aAA+B;;;UAG1B,UAAA"}
@@ -0,0 +1,65 @@
1
+ //#region src/mcp-types.d.ts
2
+ interface MCPMockOptions {
3
+ port?: number;
4
+ host?: string;
5
+ serverInfo?: {
6
+ name: string;
7
+ version: string;
8
+ };
9
+ }
10
+ interface MCPToolDefinition {
11
+ name: string;
12
+ description?: string;
13
+ inputSchema?: Record<string, unknown>;
14
+ }
15
+ interface MCPResourceDefinition {
16
+ uri: string;
17
+ name: string;
18
+ mimeType?: string;
19
+ description?: string;
20
+ }
21
+ interface MCPPromptDefinition {
22
+ name: string;
23
+ description?: string;
24
+ arguments?: Array<{
25
+ name: string;
26
+ description?: string;
27
+ required?: boolean;
28
+ }>;
29
+ }
30
+ type MCPContent = {
31
+ type: "text";
32
+ text: string;
33
+ } | {
34
+ type: "image";
35
+ data: string;
36
+ mimeType: string;
37
+ } | {
38
+ type: "resource";
39
+ resource: {
40
+ uri: string;
41
+ text?: string;
42
+ blob?: string;
43
+ mimeType?: string;
44
+ };
45
+ };
46
+ interface MCPResourceContent {
47
+ text?: string;
48
+ blob?: string;
49
+ mimeType?: string;
50
+ }
51
+ interface MCPPromptResult {
52
+ messages: Array<{
53
+ role: string;
54
+ content: MCPContent;
55
+ }>;
56
+ }
57
+ interface MCPSession {
58
+ id: string;
59
+ initialized: boolean;
60
+ createdAt: number;
61
+ }
62
+ //# sourceMappingURL=mcp-types.d.ts.map
63
+ //#endregion
64
+ export { MCPContent, MCPMockOptions, MCPPromptDefinition, MCPPromptResult, MCPResourceContent, MCPResourceDefinition, MCPSession, MCPToolDefinition };
65
+ //# sourceMappingURL=mcp-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-types.d.ts","names":[],"sources":["../src/mcp-types.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,IAAA,CAAA,EAAA,MAAA;EAMA,IAAA,CAAA,EAAA,MAAA;EAMA,UAAA,CAAA,EAAA;IAOA,IAAA,EAAA,MAAA;IAML,OAAA,EAAU,MAAA;EAQL,CAAA;AAMjB;AAAgC,UAjCf,iBAAA,CAiCe;MACW,EAAA,MAAA;aAA/B,CAAA,EAAA,MAAA;EAAK,WAAA,CAAA,EA/BD,MA+BC,CAAA,MAAA,EAAA,OAAA,CAAA;AAGjB;UA/BiB,qBAAA;;;;;;UAOA,mBAAA;;;cAGH;;;;;;KAGF,UAAA;;;;;;;;;;;;;;;;UAQK,kBAAA;;;;;UAMA,eAAA;YACL;;aAA+B;;;UAG1B,UAAA"}
@@ -0,0 +1,489 @@
1
+ const require_helpers = require('./helpers.cjs');
2
+ const require_router = require('./router.cjs');
3
+ const require_sse_writer = require('./sse-writer.cjs');
4
+ const require_interruption = require('./interruption.cjs');
5
+ const require_chaos = require('./chaos.cjs');
6
+ const require_recorder = require('./recorder.cjs');
7
+
8
+ //#region src/messages.ts
9
+ function extractClaudeTextContent(content) {
10
+ if (typeof content === "string") return content;
11
+ return content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
12
+ }
13
+ function claudeToCompletionRequest(req) {
14
+ const messages = [];
15
+ if (req.system) {
16
+ const systemText = typeof req.system === "string" ? req.system : req.system.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
17
+ if (systemText) messages.push({
18
+ role: "system",
19
+ content: systemText
20
+ });
21
+ }
22
+ for (const msg of req.messages) if (msg.role === "user") {
23
+ if (typeof msg.content !== "string" && Array.isArray(msg.content)) {
24
+ const toolResults = msg.content.filter((b) => b.type === "tool_result");
25
+ const textBlocks = msg.content.filter((b) => b.type === "text");
26
+ if (toolResults.length > 0) {
27
+ for (const tr of toolResults) {
28
+ const resultContent = typeof tr.content === "string" ? tr.content : Array.isArray(tr.content) ? tr.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("") : "";
29
+ messages.push({
30
+ role: "tool",
31
+ content: resultContent,
32
+ tool_call_id: tr.tool_use_id
33
+ });
34
+ }
35
+ if (textBlocks.length > 0) messages.push({
36
+ role: "user",
37
+ content: textBlocks.map((b) => b.text ?? "").join("")
38
+ });
39
+ continue;
40
+ }
41
+ }
42
+ messages.push({
43
+ role: "user",
44
+ content: extractClaudeTextContent(msg.content)
45
+ });
46
+ } else if (msg.role === "assistant") if (typeof msg.content === "string") messages.push({
47
+ role: "assistant",
48
+ content: msg.content
49
+ });
50
+ else if (Array.isArray(msg.content)) {
51
+ const toolUseBlocks = msg.content.filter((b) => b.type === "tool_use");
52
+ const textContent = extractClaudeTextContent(msg.content);
53
+ if (toolUseBlocks.length > 0) messages.push({
54
+ role: "assistant",
55
+ content: textContent || null,
56
+ tool_calls: toolUseBlocks.map((b) => ({
57
+ id: b.id ?? require_helpers.generateToolUseId(),
58
+ type: "function",
59
+ function: {
60
+ name: b.name ?? "",
61
+ arguments: typeof b.input === "string" ? b.input : JSON.stringify(b.input ?? {})
62
+ }
63
+ }))
64
+ });
65
+ else messages.push({
66
+ role: "assistant",
67
+ content: textContent || null
68
+ });
69
+ } else messages.push({
70
+ role: "assistant",
71
+ content: null
72
+ });
73
+ let tools;
74
+ if (req.tools && req.tools.length > 0) tools = req.tools.map((t) => ({
75
+ type: "function",
76
+ function: {
77
+ name: t.name,
78
+ description: t.description,
79
+ parameters: t.input_schema
80
+ }
81
+ }));
82
+ return {
83
+ model: req.model,
84
+ messages,
85
+ stream: req.stream,
86
+ temperature: req.temperature,
87
+ tools
88
+ };
89
+ }
90
+ function buildClaudeTextStreamEvents(content, model, chunkSize, reasoning) {
91
+ const msgId = require_helpers.generateMessageId();
92
+ const events = [];
93
+ events.push({
94
+ type: "message_start",
95
+ message: {
96
+ id: msgId,
97
+ type: "message",
98
+ role: "assistant",
99
+ content: [],
100
+ model,
101
+ stop_reason: null,
102
+ stop_sequence: null,
103
+ usage: {
104
+ input_tokens: 0,
105
+ output_tokens: 0
106
+ }
107
+ }
108
+ });
109
+ let blockIndex = 0;
110
+ if (reasoning) {
111
+ events.push({
112
+ type: "content_block_start",
113
+ index: blockIndex,
114
+ content_block: {
115
+ type: "thinking",
116
+ thinking: ""
117
+ }
118
+ });
119
+ for (let i = 0; i < reasoning.length; i += chunkSize) {
120
+ const slice = reasoning.slice(i, i + chunkSize);
121
+ events.push({
122
+ type: "content_block_delta",
123
+ index: blockIndex,
124
+ delta: {
125
+ type: "thinking_delta",
126
+ thinking: slice
127
+ }
128
+ });
129
+ }
130
+ events.push({
131
+ type: "content_block_stop",
132
+ index: blockIndex
133
+ });
134
+ blockIndex++;
135
+ }
136
+ events.push({
137
+ type: "content_block_start",
138
+ index: blockIndex,
139
+ content_block: {
140
+ type: "text",
141
+ text: ""
142
+ }
143
+ });
144
+ for (let i = 0; i < content.length; i += chunkSize) {
145
+ const slice = content.slice(i, i + chunkSize);
146
+ events.push({
147
+ type: "content_block_delta",
148
+ index: blockIndex,
149
+ delta: {
150
+ type: "text_delta",
151
+ text: slice
152
+ }
153
+ });
154
+ }
155
+ events.push({
156
+ type: "content_block_stop",
157
+ index: blockIndex
158
+ });
159
+ events.push({
160
+ type: "message_delta",
161
+ delta: {
162
+ stop_reason: "end_turn",
163
+ stop_sequence: null
164
+ },
165
+ usage: { output_tokens: 0 }
166
+ });
167
+ events.push({ type: "message_stop" });
168
+ return events;
169
+ }
170
+ function buildClaudeToolCallStreamEvents(toolCalls, model, chunkSize, logger) {
171
+ const msgId = require_helpers.generateMessageId();
172
+ const events = [];
173
+ events.push({
174
+ type: "message_start",
175
+ message: {
176
+ id: msgId,
177
+ type: "message",
178
+ role: "assistant",
179
+ content: [],
180
+ model,
181
+ stop_reason: null,
182
+ stop_sequence: null,
183
+ usage: {
184
+ input_tokens: 0,
185
+ output_tokens: 0
186
+ }
187
+ }
188
+ });
189
+ for (let idx = 0; idx < toolCalls.length; idx++) {
190
+ const tc = toolCalls[idx];
191
+ const toolUseId = tc.id || require_helpers.generateToolUseId();
192
+ let argsObj;
193
+ try {
194
+ argsObj = JSON.parse(tc.arguments || "{}");
195
+ } catch {
196
+ logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
197
+ argsObj = {};
198
+ }
199
+ const argsJson = JSON.stringify(argsObj);
200
+ events.push({
201
+ type: "content_block_start",
202
+ index: idx,
203
+ content_block: {
204
+ type: "tool_use",
205
+ id: toolUseId,
206
+ name: tc.name,
207
+ input: {}
208
+ }
209
+ });
210
+ for (let i = 0; i < argsJson.length; i += chunkSize) {
211
+ const slice = argsJson.slice(i, i + chunkSize);
212
+ events.push({
213
+ type: "content_block_delta",
214
+ index: idx,
215
+ delta: {
216
+ type: "input_json_delta",
217
+ partial_json: slice
218
+ }
219
+ });
220
+ }
221
+ events.push({
222
+ type: "content_block_stop",
223
+ index: idx
224
+ });
225
+ }
226
+ events.push({
227
+ type: "message_delta",
228
+ delta: {
229
+ stop_reason: "tool_use",
230
+ stop_sequence: null
231
+ },
232
+ usage: { output_tokens: 0 }
233
+ });
234
+ events.push({ type: "message_stop" });
235
+ return events;
236
+ }
237
+ function buildClaudeTextResponse(content, model, reasoning) {
238
+ const contentBlocks = [];
239
+ if (reasoning) contentBlocks.push({
240
+ type: "thinking",
241
+ thinking: reasoning
242
+ });
243
+ contentBlocks.push({
244
+ type: "text",
245
+ text: content
246
+ });
247
+ return {
248
+ id: require_helpers.generateMessageId(),
249
+ type: "message",
250
+ role: "assistant",
251
+ content: contentBlocks,
252
+ model,
253
+ stop_reason: "end_turn",
254
+ stop_sequence: null,
255
+ usage: {
256
+ input_tokens: 0,
257
+ output_tokens: 0
258
+ }
259
+ };
260
+ }
261
+ function buildClaudeToolCallResponse(toolCalls, model, logger) {
262
+ return {
263
+ id: require_helpers.generateMessageId(),
264
+ type: "message",
265
+ role: "assistant",
266
+ content: toolCalls.map((tc) => {
267
+ let argsObj;
268
+ try {
269
+ argsObj = JSON.parse(tc.arguments || "{}");
270
+ } catch {
271
+ logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
272
+ argsObj = {};
273
+ }
274
+ return {
275
+ type: "tool_use",
276
+ id: tc.id || require_helpers.generateToolUseId(),
277
+ name: tc.name,
278
+ input: argsObj
279
+ };
280
+ }),
281
+ model,
282
+ stop_reason: "tool_use",
283
+ stop_sequence: null,
284
+ usage: {
285
+ input_tokens: 0,
286
+ output_tokens: 0
287
+ }
288
+ };
289
+ }
290
+ async function writeClaudeSSEStream(res, events, optionsOrLatency) {
291
+ const opts = typeof optionsOrLatency === "number" ? { latency: optionsOrLatency } : optionsOrLatency ?? {};
292
+ const latency = opts.latency ?? 0;
293
+ const profile = opts.streamingProfile;
294
+ const signal = opts.signal;
295
+ const onChunkSent = opts.onChunkSent;
296
+ if (res.writableEnded) return true;
297
+ res.setHeader("Content-Type", "text/event-stream");
298
+ res.setHeader("Cache-Control", "no-cache");
299
+ res.setHeader("Connection", "keep-alive");
300
+ let chunkIndex = 0;
301
+ for (const event of events) {
302
+ const chunkDelay = require_sse_writer.calculateDelay(chunkIndex, profile, latency);
303
+ if (chunkDelay > 0) await require_sse_writer.delay(chunkDelay, signal);
304
+ if (signal?.aborted) return false;
305
+ if (res.writableEnded) return true;
306
+ res.write(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
307
+ onChunkSent?.();
308
+ if (signal?.aborted) return false;
309
+ chunkIndex++;
310
+ }
311
+ if (!res.writableEnded) res.end();
312
+ return true;
313
+ }
314
+ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
315
+ const { logger } = defaults;
316
+ setCorsHeaders(res);
317
+ let claudeReq;
318
+ try {
319
+ claudeReq = JSON.parse(raw);
320
+ } catch {
321
+ journal.add({
322
+ method: req.method ?? "POST",
323
+ path: req.url ?? "/v1/messages",
324
+ headers: require_helpers.flattenHeaders(req.headers),
325
+ body: null,
326
+ response: {
327
+ status: 400,
328
+ fixture: null
329
+ }
330
+ });
331
+ require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
332
+ message: "Malformed JSON",
333
+ type: "invalid_request_error"
334
+ } }));
335
+ return;
336
+ }
337
+ const completionReq = claudeToCompletionRequest(claudeReq);
338
+ const fixture = require_router.matchFixture(fixtures, completionReq, journal.fixtureMatchCounts);
339
+ if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures);
340
+ if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
341
+ method: req.method ?? "POST",
342
+ path: req.url ?? "/v1/messages",
343
+ headers: require_helpers.flattenHeaders(req.headers),
344
+ body: completionReq
345
+ }, defaults.registry, defaults.logger)) return;
346
+ if (!fixture) {
347
+ if (defaults.record) {
348
+ if (await require_recorder.proxyAndRecord(req, res, completionReq, "anthropic", req.url ?? "/v1/messages", fixtures, defaults, raw)) {
349
+ journal.add({
350
+ method: req.method ?? "POST",
351
+ path: req.url ?? "/v1/messages",
352
+ headers: require_helpers.flattenHeaders(req.headers),
353
+ body: completionReq,
354
+ response: {
355
+ status: res.statusCode ?? 200,
356
+ fixture: null
357
+ }
358
+ });
359
+ return;
360
+ }
361
+ }
362
+ const strictStatus = defaults.strict ? 503 : 404;
363
+ const strictMessage = defaults.strict ? "Strict mode: no fixture matched" : "No fixture matched";
364
+ if (defaults.strict) logger.error(`STRICT: No fixture matched for ${req.method ?? "POST"} ${req.url ?? "/v1/messages"}`);
365
+ journal.add({
366
+ method: req.method ?? "POST",
367
+ path: req.url ?? "/v1/messages",
368
+ headers: require_helpers.flattenHeaders(req.headers),
369
+ body: completionReq,
370
+ response: {
371
+ status: strictStatus,
372
+ fixture: null
373
+ }
374
+ });
375
+ require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
376
+ message: strictMessage,
377
+ type: "invalid_request_error"
378
+ } }));
379
+ return;
380
+ }
381
+ const response = fixture.response;
382
+ const latency = fixture.latency ?? defaults.latency;
383
+ const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
384
+ if (require_helpers.isErrorResponse(response)) {
385
+ const status = response.status ?? 500;
386
+ journal.add({
387
+ method: req.method ?? "POST",
388
+ path: req.url ?? "/v1/messages",
389
+ headers: require_helpers.flattenHeaders(req.headers),
390
+ body: completionReq,
391
+ response: {
392
+ status,
393
+ fixture
394
+ }
395
+ });
396
+ const anthropicError = {
397
+ type: "error",
398
+ error: {
399
+ type: response.error.type ?? "api_error",
400
+ message: response.error.message
401
+ }
402
+ };
403
+ require_sse_writer.writeErrorResponse(res, status, JSON.stringify(anthropicError));
404
+ return;
405
+ }
406
+ if (require_helpers.isTextResponse(response)) {
407
+ if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Claude Messages API — ignoring");
408
+ const journalEntry = journal.add({
409
+ method: req.method ?? "POST",
410
+ path: req.url ?? "/v1/messages",
411
+ headers: require_helpers.flattenHeaders(req.headers),
412
+ body: completionReq,
413
+ response: {
414
+ status: 200,
415
+ fixture
416
+ }
417
+ });
418
+ if (claudeReq.stream !== true) {
419
+ const body = buildClaudeTextResponse(response.content, completionReq.model, response.reasoning);
420
+ res.writeHead(200, { "Content-Type": "application/json" });
421
+ res.end(JSON.stringify(body));
422
+ } else {
423
+ const events = buildClaudeTextStreamEvents(response.content, completionReq.model, chunkSize, response.reasoning);
424
+ const interruption = require_interruption.createInterruptionSignal(fixture);
425
+ if (!await writeClaudeSSEStream(res, events, {
426
+ latency,
427
+ streamingProfile: fixture.streamingProfile,
428
+ signal: interruption?.signal,
429
+ onChunkSent: interruption?.tick
430
+ })) {
431
+ if (!res.writableEnded) res.destroy();
432
+ journalEntry.response.interrupted = true;
433
+ journalEntry.response.interruptReason = interruption?.reason();
434
+ }
435
+ interruption?.cleanup();
436
+ }
437
+ return;
438
+ }
439
+ if (require_helpers.isToolCallResponse(response)) {
440
+ const journalEntry = journal.add({
441
+ method: req.method ?? "POST",
442
+ path: req.url ?? "/v1/messages",
443
+ headers: require_helpers.flattenHeaders(req.headers),
444
+ body: completionReq,
445
+ response: {
446
+ status: 200,
447
+ fixture
448
+ }
449
+ });
450
+ if (claudeReq.stream !== true) {
451
+ const body = buildClaudeToolCallResponse(response.toolCalls, completionReq.model, logger);
452
+ res.writeHead(200, { "Content-Type": "application/json" });
453
+ res.end(JSON.stringify(body));
454
+ } else {
455
+ const events = buildClaudeToolCallStreamEvents(response.toolCalls, completionReq.model, chunkSize, logger);
456
+ const interruption = require_interruption.createInterruptionSignal(fixture);
457
+ if (!await writeClaudeSSEStream(res, events, {
458
+ latency,
459
+ streamingProfile: fixture.streamingProfile,
460
+ signal: interruption?.signal,
461
+ onChunkSent: interruption?.tick
462
+ })) {
463
+ if (!res.writableEnded) res.destroy();
464
+ journalEntry.response.interrupted = true;
465
+ journalEntry.response.interruptReason = interruption?.reason();
466
+ }
467
+ interruption?.cleanup();
468
+ }
469
+ return;
470
+ }
471
+ journal.add({
472
+ method: req.method ?? "POST",
473
+ path: req.url ?? "/v1/messages",
474
+ headers: require_helpers.flattenHeaders(req.headers),
475
+ body: completionReq,
476
+ response: {
477
+ status: 500,
478
+ fixture
479
+ }
480
+ });
481
+ require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
482
+ message: "Fixture response did not match any known type",
483
+ type: "server_error"
484
+ } }));
485
+ }
486
+
487
+ //#endregion
488
+ exports.handleMessages = handleMessages;
489
+ //# sourceMappingURL=messages.cjs.map