@copilotkit/aimock 1.29.0 → 1.31.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 (207) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +34 -0
  4. package/README.md +1 -1
  5. package/dist/agui-types.d.ts.map +1 -1
  6. package/dist/bedrock-converse.cjs +63 -31
  7. package/dist/bedrock-converse.cjs.map +1 -1
  8. package/dist/bedrock-converse.d.cts.map +1 -1
  9. package/dist/bedrock-converse.d.ts.map +1 -1
  10. package/dist/bedrock-converse.js +65 -33
  11. package/dist/bedrock-converse.js.map +1 -1
  12. package/dist/bedrock.cjs +95 -33
  13. package/dist/bedrock.cjs.map +1 -1
  14. package/dist/bedrock.d.cts.map +1 -1
  15. package/dist/bedrock.d.ts.map +1 -1
  16. package/dist/bedrock.js +97 -35
  17. package/dist/bedrock.js.map +1 -1
  18. package/dist/cli.cjs +18 -1
  19. package/dist/cli.cjs.map +1 -1
  20. package/dist/cli.js +18 -1
  21. package/dist/cli.js.map +1 -1
  22. package/dist/cohere.cjs +49 -15
  23. package/dist/cohere.cjs.map +1 -1
  24. package/dist/cohere.d.cts.map +1 -1
  25. package/dist/cohere.d.ts.map +1 -1
  26. package/dist/cohere.js +51 -17
  27. package/dist/cohere.js.map +1 -1
  28. package/dist/config-loader.d.ts.map +1 -1
  29. package/dist/elevenlabs-audio.cjs +8 -4
  30. package/dist/elevenlabs-audio.cjs.map +1 -1
  31. package/dist/elevenlabs-audio.d.cts.map +1 -1
  32. package/dist/elevenlabs-audio.d.ts.map +1 -1
  33. package/dist/elevenlabs-audio.js +10 -6
  34. package/dist/elevenlabs-audio.js.map +1 -1
  35. package/dist/embeddings.cjs +4 -3
  36. package/dist/embeddings.cjs.map +1 -1
  37. package/dist/embeddings.d.cts.map +1 -1
  38. package/dist/embeddings.d.ts.map +1 -1
  39. package/dist/embeddings.js +6 -5
  40. package/dist/embeddings.js.map +1 -1
  41. package/dist/fal-audio.cjs +18 -8
  42. package/dist/fal-audio.cjs.map +1 -1
  43. package/dist/fal-audio.d.cts.map +1 -1
  44. package/dist/fal-audio.d.ts.map +1 -1
  45. package/dist/fal-audio.js +22 -12
  46. package/dist/fal-audio.js.map +1 -1
  47. package/dist/fal.cjs +55 -46
  48. package/dist/fal.cjs.map +1 -1
  49. package/dist/fal.d.cts +8 -0
  50. package/dist/fal.d.cts.map +1 -1
  51. package/dist/fal.d.ts +8 -0
  52. package/dist/fal.d.ts.map +1 -1
  53. package/dist/fal.js +58 -49
  54. package/dist/fal.js.map +1 -1
  55. package/dist/gemini-embeddings.cjs +4 -3
  56. package/dist/gemini-embeddings.cjs.map +1 -1
  57. package/dist/gemini-embeddings.js +6 -5
  58. package/dist/gemini-embeddings.js.map +1 -1
  59. package/dist/gemini-interactions.cjs +3 -3
  60. package/dist/gemini-interactions.cjs.map +1 -1
  61. package/dist/gemini-interactions.d.cts.map +1 -1
  62. package/dist/gemini-interactions.d.ts.map +1 -1
  63. package/dist/gemini-interactions.js +5 -5
  64. package/dist/gemini-interactions.js.map +1 -1
  65. package/dist/gemini.cjs +55 -24
  66. package/dist/gemini.cjs.map +1 -1
  67. package/dist/gemini.d.cts.map +1 -1
  68. package/dist/gemini.d.ts.map +1 -1
  69. package/dist/gemini.js +57 -26
  70. package/dist/gemini.js.map +1 -1
  71. package/dist/helpers.cjs +120 -2
  72. package/dist/helpers.cjs.map +1 -1
  73. package/dist/helpers.d.cts +43 -3
  74. package/dist/helpers.d.cts.map +1 -1
  75. package/dist/helpers.d.ts +43 -3
  76. package/dist/helpers.d.ts.map +1 -1
  77. package/dist/helpers.js +117 -3
  78. package/dist/helpers.js.map +1 -1
  79. package/dist/images.cjs +12 -6
  80. package/dist/images.cjs.map +1 -1
  81. package/dist/images.d.cts.map +1 -1
  82. package/dist/images.d.ts.map +1 -1
  83. package/dist/images.js +14 -8
  84. package/dist/images.js.map +1 -1
  85. package/dist/index.cjs +13 -2
  86. package/dist/index.d.cts +4 -3
  87. package/dist/index.d.ts +4 -3
  88. package/dist/index.js +6 -5
  89. package/dist/llmock.cjs +2 -1
  90. package/dist/llmock.cjs.map +1 -1
  91. package/dist/llmock.d.cts.map +1 -1
  92. package/dist/llmock.d.ts.map +1 -1
  93. package/dist/llmock.js +2 -1
  94. package/dist/llmock.js.map +1 -1
  95. package/dist/messages.cjs +325 -85
  96. package/dist/messages.cjs.map +1 -1
  97. package/dist/messages.d.cts.map +1 -1
  98. package/dist/messages.d.ts.map +1 -1
  99. package/dist/messages.js +327 -87
  100. package/dist/messages.js.map +1 -1
  101. package/dist/metrics.cjs +9 -0
  102. package/dist/metrics.cjs.map +1 -1
  103. package/dist/metrics.d.cts.map +1 -1
  104. package/dist/metrics.d.ts.map +1 -1
  105. package/dist/metrics.js +7 -1
  106. package/dist/metrics.js.map +1 -1
  107. package/dist/model-utils.cjs +68 -0
  108. package/dist/model-utils.cjs.map +1 -1
  109. package/dist/model-utils.js +68 -1
  110. package/dist/model-utils.js.map +1 -1
  111. package/dist/ollama.cjs +58 -21
  112. package/dist/ollama.cjs.map +1 -1
  113. package/dist/ollama.d.cts.map +1 -1
  114. package/dist/ollama.d.ts.map +1 -1
  115. package/dist/ollama.js +60 -23
  116. package/dist/ollama.js.map +1 -1
  117. package/dist/openrouter-video.cjs +1609 -0
  118. package/dist/openrouter-video.cjs.map +1 -0
  119. package/dist/openrouter-video.d.cts +154 -0
  120. package/dist/openrouter-video.d.cts.map +1 -0
  121. package/dist/openrouter-video.d.ts +154 -0
  122. package/dist/openrouter-video.d.ts.map +1 -0
  123. package/dist/openrouter-video.js +1601 -0
  124. package/dist/openrouter-video.js.map +1 -0
  125. package/dist/recorder.cjs +97 -15
  126. package/dist/recorder.cjs.map +1 -1
  127. package/dist/recorder.d.cts.map +1 -1
  128. package/dist/recorder.d.ts.map +1 -1
  129. package/dist/recorder.js +96 -17
  130. package/dist/recorder.js.map +1 -1
  131. package/dist/responses.cjs +26 -12
  132. package/dist/responses.cjs.map +1 -1
  133. package/dist/responses.d.cts +1 -1
  134. package/dist/responses.d.cts.map +1 -1
  135. package/dist/responses.d.ts +1 -1
  136. package/dist/responses.d.ts.map +1 -1
  137. package/dist/responses.js +28 -14
  138. package/dist/responses.js.map +1 -1
  139. package/dist/router.cjs +37 -8
  140. package/dist/router.cjs.map +1 -1
  141. package/dist/router.d.cts +30 -1
  142. package/dist/router.d.cts.map +1 -1
  143. package/dist/router.d.ts +30 -1
  144. package/dist/router.d.ts.map +1 -1
  145. package/dist/router.js +37 -9
  146. package/dist/router.js.map +1 -1
  147. package/dist/server.cjs +173 -19
  148. package/dist/server.cjs.map +1 -1
  149. package/dist/server.d.cts +2 -0
  150. package/dist/server.d.cts.map +1 -1
  151. package/dist/server.d.ts +2 -0
  152. package/dist/server.d.ts.map +1 -1
  153. package/dist/server.js +176 -22
  154. package/dist/server.js.map +1 -1
  155. package/dist/speech.cjs +4 -2
  156. package/dist/speech.cjs.map +1 -1
  157. package/dist/speech.d.cts.map +1 -1
  158. package/dist/speech.d.ts.map +1 -1
  159. package/dist/speech.js +6 -4
  160. package/dist/speech.js.map +1 -1
  161. package/dist/stream-collapse.cjs +44 -1
  162. package/dist/stream-collapse.cjs.map +1 -1
  163. package/dist/stream-collapse.d.cts +28 -0
  164. package/dist/stream-collapse.d.cts.map +1 -1
  165. package/dist/stream-collapse.d.ts +28 -0
  166. package/dist/stream-collapse.d.ts.map +1 -1
  167. package/dist/stream-collapse.js +44 -2
  168. package/dist/stream-collapse.js.map +1 -1
  169. package/dist/transcription.cjs +4 -2
  170. package/dist/transcription.cjs.map +1 -1
  171. package/dist/transcription.d.cts.map +1 -1
  172. package/dist/transcription.d.ts.map +1 -1
  173. package/dist/transcription.js +6 -4
  174. package/dist/transcription.js.map +1 -1
  175. package/dist/types.d.cts +123 -8
  176. package/dist/types.d.cts.map +1 -1
  177. package/dist/types.d.ts +123 -8
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/vector-types.d.cts.map +1 -1
  180. package/dist/vector-types.d.ts.map +1 -1
  181. package/dist/video.cjs +4 -2
  182. package/dist/video.cjs.map +1 -1
  183. package/dist/video.d.cts.map +1 -1
  184. package/dist/video.d.ts.map +1 -1
  185. package/dist/video.js +6 -4
  186. package/dist/video.js.map +1 -1
  187. package/dist/ws-gemini-live.cjs +4 -3
  188. package/dist/ws-gemini-live.cjs.map +1 -1
  189. package/dist/ws-gemini-live.d.cts +2 -2
  190. package/dist/ws-gemini-live.d.cts.map +1 -1
  191. package/dist/ws-gemini-live.d.ts.map +1 -1
  192. package/dist/ws-gemini-live.js +6 -5
  193. package/dist/ws-gemini-live.js.map +1 -1
  194. package/dist/ws-realtime.cjs +4 -3
  195. package/dist/ws-realtime.cjs.map +1 -1
  196. package/dist/ws-realtime.d.cts +2 -2
  197. package/dist/ws-realtime.d.cts.map +1 -1
  198. package/dist/ws-realtime.d.ts.map +1 -1
  199. package/dist/ws-realtime.js +6 -5
  200. package/dist/ws-realtime.js.map +1 -1
  201. package/dist/ws-responses.cjs +8 -6
  202. package/dist/ws-responses.cjs.map +1 -1
  203. package/dist/ws-responses.d.cts.map +1 -1
  204. package/dist/ws-responses.d.ts.map +1 -1
  205. package/dist/ws-responses.js +10 -8
  206. package/dist/ws-responses.js.map +1 -1
  207. package/package.json +2 -2
package/dist/recorder.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { DEFAULT_TEST_ID } from "./constants.js";
2
+ import { normalizeModelName } from "./model-utils.js";
2
3
  import { getTestId, slugifyTestId } from "./helpers.js";
3
4
  import { getLastMessageByRole, getTextContent } from "./router.js";
4
5
  import { writeErrorResponse } from "./sse-writer.js";
5
- import { normalizeModelName } from "./model-utils.js";
6
- import { collapseStreamingResponse } from "./stream-collapse.js";
6
+ import { capturedRedactedData, collapseStreamingResponse } from "./stream-collapse.js";
7
7
  import { resolveUpstreamUrl } from "./url.js";
8
8
  import * as http$1 from "node:http";
9
9
  import * as crypto$1 from "node:crypto";
@@ -26,9 +26,39 @@ const STRIP_HEADERS = new Set([
26
26
  "host",
27
27
  "content-length",
28
28
  "cookie",
29
- "accept-encoding"
29
+ "accept-encoding",
30
+ "x-test-id",
31
+ "x-aimock-strict",
32
+ "x-aimock-context"
30
33
  ]);
31
34
  /**
35
+ * Build the header set forwarded to an upstream provider from an incoming
36
+ * request: everything except hop-by-hop, client-set, and mock-internal
37
+ * headers (STRIP_HEADERS, plus the x-aimock-chaos-* prefix family). Shared
38
+ * by the generic recorder proxy and the OpenRouter-video live lifecycle
39
+ * proxy.
40
+ */
41
+ function buildForwardHeaders(req) {
42
+ const out = {};
43
+ for (const [name, val] of Object.entries(req.headers)) {
44
+ const lower = name.toLowerCase();
45
+ if (val === void 0 || STRIP_HEADERS.has(lower) || lower.startsWith("x-aimock-chaos-")) continue;
46
+ out[name] = Array.isArray(val) ? val.join(", ") : val;
47
+ }
48
+ return out;
49
+ }
50
+ /**
51
+ * Make an arbitrary string safe to set as an HTTP header value. Node's
52
+ * `res.setHeader` throws ERR_INVALID_CHAR on anything outside Latin-1 (plus
53
+ * control characters) — and persist errors embed filesystem paths verbatim,
54
+ * so a Unicode fixture path would turn a recoverable record failure into a
55
+ * 500. Out-of-range characters are replaced with `?` rather than stripped so
56
+ * the value's shape stays legible.
57
+ */
58
+ function sanitizeHeaderValue(value) {
59
+ return value.replace(/[^\t\x20-\x7e\x80-\xff]/g, "?");
60
+ }
61
+ /**
32
62
  * Write a built fixture to disk (snapshot vs. timestamp file layout) and, when
33
63
  * the match is non-empty, register it in the in-memory cache so subsequent
34
64
  * identical requests match. Extracted from `proxyAndRecord` so the fal
@@ -40,11 +70,11 @@ function persistFixture(opts) {
40
70
  const { record, providerKey, testId, fixture, fixtures, warnings = [], logger } = opts;
41
71
  const m = fixture.match;
42
72
  const isEmptyMatch = m.userMessage === void 0 && m.inputText === void 0 && m.endpoint === void 0;
43
- if (isEmptyMatch) logger.warn("Recorded fixture has empty match criteria — skipping in-memory registration");
44
73
  if (record.proxyOnly) {
45
74
  logger.info(`Proxied ${providerKey} request (proxy-only mode)`);
46
75
  return { kind: "skipped" };
47
76
  }
77
+ if (isEmptyMatch) logger.warn("Recorded fixture has empty match criteria — skipping in-memory registration");
48
78
  const fixturePath = record.fixturePath ?? "./fixtures/recorded";
49
79
  let isSnapshotMode = testId !== DEFAULT_TEST_ID;
50
80
  let filepath;
@@ -68,14 +98,18 @@ function persistFixture(opts) {
68
98
  fs.mkdirSync(path.dirname(filepath), { recursive: true });
69
99
  let fileContent;
70
100
  if (mergeExisting && fs.existsSync(filepath)) try {
71
- fileContent = { fixtures: [...JSON.parse(fs.readFileSync(filepath, "utf-8")).fixtures ?? [], fixture] };
101
+ const existing = JSON.parse(fs.readFileSync(filepath, "utf-8"));
102
+ const existingFixtures = Array.isArray(existing.fixtures) ? existing.fixtures : void 0;
103
+ if (existingFixtures === void 0 && existing.fixtures !== void 0) logger.warn(`Existing fixture file ${filepath} has a non-array "fixtures" — discarding it and starting fresh`);
104
+ fileContent = { fixtures: [...existingFixtures ?? [], fixture] };
105
+ if (typeof existing._warning === "string" && existing._warning) fileWarnings.unshift(...existing._warning.split("; "));
72
106
  } catch (mergeErr) {
73
107
  const msg = mergeErr instanceof Error ? mergeErr.message : "unknown";
74
108
  logger.warn(`Could not read existing fixture file ${filepath} (${msg}) — overwriting`);
75
109
  fileContent = { fixtures: [fixture] };
76
110
  }
77
111
  else fileContent = { fixtures: [fixture] };
78
- if (fileWarnings.length > 0) fileContent._warning = fileWarnings.join("; ");
112
+ if (fileWarnings.length > 0) fileContent._warning = [...new Set(fileWarnings)].join("; ");
79
113
  const tmpPath = filepath + ".tmp." + process.pid;
80
114
  fs.writeFileSync(tmpPath, JSON.stringify(fileContent, null, 2), "utf-8");
81
115
  fs.renameSync(tmpPath, filepath);
@@ -120,8 +154,7 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
120
154
  return "relayed";
121
155
  }
122
156
  defaults.logger.warn(`NO FIXTURE MATCH — proxying to ${upstreamUrl}${pathname}`);
123
- const forwardHeaders = {};
124
- for (const [name, val] of Object.entries(req.headers)) if (val !== void 0 && !STRIP_HEADERS.has(name)) forwardHeaders[name] = Array.isArray(val) ? val.join(", ") : val;
157
+ const forwardHeaders = buildForwardHeaders(req);
125
158
  const requestBody = rawBody ?? JSON.stringify(request);
126
159
  let upstreamStatus;
127
160
  let upstreamHeaders;
@@ -192,14 +225,22 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
192
225
  } else if (collapsed.content === "" && (!collapsed.toolCalls || collapsed.toolCalls.length === 0)) {
193
226
  defaults.logger.warn("Stream collapse produced empty content — fixture may be incomplete");
194
227
  const reasoningSpread = collapsed.reasoning ? { reasoning: collapsed.reasoning } : {};
228
+ const reasoningSignatureSpread = collapsed.reasoning && collapsed.reasoningSignature ? { reasoningSignature: collapsed.reasoningSignature } : {};
229
+ logDroppedReasoningSignature(defaults.logger, collapsed.reasoning, collapsed.reasoningSignature);
230
+ const redactedThinkingSpread = collapsed.redactedThinking?.length ? { redactedThinking: collapsed.redactedThinking } : {};
195
231
  const webSearchesSpread = collapsed.webSearches?.length ? { webSearches: collapsed.webSearches } : {};
196
232
  fixtureResponse = {
197
233
  content: collapsed.content ?? "",
198
234
  ...reasoningSpread,
235
+ ...reasoningSignatureSpread,
236
+ ...redactedThinkingSpread,
199
237
  ...webSearchesSpread
200
238
  };
201
239
  } else {
202
240
  const reasoningSpread = collapsed.reasoning ? { reasoning: collapsed.reasoning } : {};
241
+ const reasoningSignatureSpread = collapsed.reasoning && collapsed.reasoningSignature ? { reasoningSignature: collapsed.reasoningSignature } : {};
242
+ logDroppedReasoningSignature(defaults.logger, collapsed.reasoning, collapsed.reasoningSignature);
243
+ const redactedThinkingSpread = collapsed.redactedThinking?.length ? { redactedThinking: collapsed.redactedThinking } : {};
203
244
  const webSearchesSpread = collapsed.webSearches?.length ? { webSearches: collapsed.webSearches } : {};
204
245
  if (collapsed.toolCalls && collapsed.toolCalls.length > 0) {
205
246
  const sanitizedToolCalls = collapsed.toolCalls.map((tc) => ({
@@ -211,16 +252,22 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
211
252
  content: collapsed.content,
212
253
  toolCalls: sanitizedToolCalls,
213
254
  ...reasoningSpread,
255
+ ...reasoningSignatureSpread,
256
+ ...redactedThinkingSpread,
214
257
  ...webSearchesSpread
215
258
  };
216
259
  else fixtureResponse = {
217
260
  toolCalls: sanitizedToolCalls,
218
261
  ...reasoningSpread,
262
+ ...reasoningSignatureSpread,
263
+ ...redactedThinkingSpread,
219
264
  ...webSearchesSpread
220
265
  };
221
266
  } else fixtureResponse = {
222
267
  content: collapsed.content ?? "",
223
268
  ...reasoningSpread,
269
+ ...reasoningSignatureSpread,
270
+ ...redactedThinkingSpread,
224
271
  ...webSearchesSpread
225
272
  };
226
273
  }
@@ -255,7 +302,7 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
255
302
  } catch (err) {
256
303
  defaults.logger.debug(`Could not parse encoding_format from raw body: ${err instanceof Error ? err.message : "unknown error"}`);
257
304
  }
258
- fixtureResponse = buildFixtureResponse(parsedResponse, upstreamStatus, encodingFormat);
305
+ fixtureResponse = buildFixtureResponse(parsedResponse, upstreamStatus, encodingFormat, defaults.logger);
259
306
  }
260
307
  }
261
308
  if (clientDisconnected) {
@@ -291,7 +338,7 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
291
338
  logger: defaults.logger
292
339
  });
293
340
  if (persistResult.kind === "failed") {
294
- if (!res.headersSent) res.setHeader("X-AIMock-Record-Error", persistResult.error);
341
+ if (!res.headersSent) res.setHeader("X-AIMock-Record-Error", sanitizeHeaderValue(persistResult.error));
295
342
  else defaults.logger.warn(`Cannot set X-AIMock-Record-Error header — headers already sent`);
296
343
  defaults.logger.warn(`Response relayed but NOT saved to disk — see error above`);
297
344
  }
@@ -348,6 +395,11 @@ var StreamingFrameDecoder = class {
348
395
  return this.decoder.end();
349
396
  }
350
397
  };
398
+ /**
399
+ * Sanitize a configured timeout: non-finite or non-positive values fall back
400
+ * to the default. Shared with the OpenRouter-video live lifecycle proxy so
401
+ * `record.upstreamTimeoutMs` is clamped identically on every proxy path.
402
+ */
351
403
  function clampTimeout(value, fallback) {
352
404
  if (value == null || !Number.isFinite(value) || value <= 0) return fallback;
353
405
  return value;
@@ -461,10 +513,19 @@ function makeUpstreamRequest(target, headers, body, clientRes, method = "POST",
461
513
  });
462
514
  }
463
515
  /**
516
+ * A captured Anthropic thinking-block signature is only persisted alongside
517
+ * non-empty plaintext `reasoning` (a bare signature has nothing to attach to on
518
+ * replay). When that gate drops a present signature, warn so the loss is
519
+ * observable (matching the recording-side anomaly convention in this file).
520
+ */
521
+ function logDroppedReasoningSignature(logger, reasoning, reasoningSignature) {
522
+ if (reasoningSignature && !reasoning) logger?.warn("Dropping captured reasoningSignature — no plaintext reasoning to attach it to");
523
+ }
524
+ /**
464
525
  * Detect the response format from the parsed upstream JSON and convert
465
526
  * it into an aimock FixtureResponse.
466
527
  */
467
- function buildFixtureResponse(parsed, status, encodingFormat) {
528
+ function buildFixtureResponse(parsed, status, encodingFormat, logger) {
468
529
  if (parsed === null || parsed === void 0) return {
469
530
  error: {
470
531
  message: "Upstream returned non-JSON response",
@@ -593,10 +654,20 @@ function buildFixtureResponse(parsed, status, encodingFormat) {
593
654
  const toolUseBlocks = blocks.filter((b) => b.type === "tool_use");
594
655
  const textBlocks = blocks.filter((b) => b.type === "text" && typeof b.text === "string");
595
656
  const thinkingBlocks = blocks.filter((b) => b.type === "thinking");
657
+ const redactedBlocks = blocks.filter((b) => b.type === "redacted_thinking");
658
+ const redactedThinking = blocks.map((b) => capturedRedactedData(b)).filter((data) => data !== void 0);
596
659
  const hasToolCalls = toolUseBlocks.length > 0;
597
660
  const joinedText = textBlocks.map((b) => String(b.text ?? "")).join("");
598
661
  const hasContent = joinedText.length > 0;
599
662
  const anthropicReasoning = thinkingBlocks.length > 0 ? thinkingBlocks.map((b) => String(b.thinking ?? "")).join("") : void 0;
663
+ const anthropicReasoningSignature = (() => {
664
+ let sig;
665
+ for (const b of thinkingBlocks) if (typeof b.signature === "string") sig = String(b.signature);
666
+ return sig;
667
+ })();
668
+ const reasoningSignatureSpread = anthropicReasoning && anthropicReasoningSignature ? { reasoningSignature: anthropicReasoningSignature } : {};
669
+ logDroppedReasoningSignature(logger, anthropicReasoning, anthropicReasoningSignature);
670
+ const redactedThinkingSpread = redactedThinking.length > 0 ? { redactedThinking } : {};
600
671
  if (hasToolCalls) {
601
672
  const toolCalls = toolUseBlocks.map((b) => ({
602
673
  name: String(b.name),
@@ -606,20 +677,28 @@ function buildFixtureResponse(parsed, status, encodingFormat) {
606
677
  if (hasContent) return {
607
678
  content: joinedText,
608
679
  toolCalls,
609
- ...anthropicReasoning ? { reasoning: anthropicReasoning } : {}
680
+ ...anthropicReasoning ? { reasoning: anthropicReasoning } : {},
681
+ ...reasoningSignatureSpread,
682
+ ...redactedThinkingSpread
610
683
  };
611
684
  return {
612
685
  toolCalls,
613
- ...anthropicReasoning ? { reasoning: anthropicReasoning } : {}
686
+ ...anthropicReasoning ? { reasoning: anthropicReasoning } : {},
687
+ ...reasoningSignatureSpread,
688
+ ...redactedThinkingSpread
614
689
  };
615
690
  }
616
691
  if (hasContent) return {
617
692
  content: joinedText,
618
- ...anthropicReasoning ? { reasoning: anthropicReasoning } : {}
693
+ ...anthropicReasoning ? { reasoning: anthropicReasoning } : {},
694
+ ...reasoningSignatureSpread,
695
+ ...redactedThinkingSpread
619
696
  };
620
- if (anthropicReasoning) return {
697
+ if (thinkingBlocks.length > 0 || redactedBlocks.length > 0) return {
621
698
  content: "",
622
- reasoning: anthropicReasoning
699
+ ...anthropicReasoning ? { reasoning: anthropicReasoning } : {},
700
+ ...reasoningSignatureSpread,
701
+ ...redactedThinkingSpread
623
702
  };
624
703
  }
625
704
  if (Array.isArray(obj.candidates) && obj.candidates.length > 0) {
@@ -816,5 +895,5 @@ function buildFixtureMetadata(request) {
816
895
  }
817
896
 
818
897
  //#endregion
819
- export { buildFixtureMatch, persistFixture, proxyAndRecord };
898
+ export { buildFixtureMatch, buildForwardHeaders, clampTimeout, persistFixture, proxyAndRecord, sanitizeHeaderValue };
820
899
  //# sourceMappingURL=recorder.js.map