{"version":3,"file":"messages.cjs","names":["generateToolUseId","generateMessageId","calculateDelay","delay","flattenHeaders","resolveStrictMode","strictOverrideField","getContext","getTestId","matchFixtureDiagnostic","recordMatchOptions","applyChaos","strictNoMatchMessage","strictNoMatchLogLine","proxyAndRecord","resolveResponse","isErrorResponse","isContentWithToolCallsResponse","extractOverrides","resolveReasoningForModel","resolveReasoningArtifactsForModel","createInterruptionSignal","isTextResponse","isToolCallResponse"],"sources":["../src/messages.ts"],"sourcesContent":["/**\n * Anthropic Claude Messages API support.\n *\n * Translates incoming /v1/messages requests into the ChatCompletionRequest\n * format used by the fixture router, and converts fixture responses back into\n * the Claude Messages API streaming (or non-streaming) format.\n */\n\nimport type * as http from \"node:http\";\nimport type {\n  ChatCompletionRequest,\n  ChatMessage,\n  Fixture,\n  HandlerDefaults,\n  RecordedTimings,\n  ResponseOverrides,\n  StreamingProfile,\n  ToolCall,\n  ToolDefinition,\n} from \"./types.js\";\nimport {\n  generateMessageId,\n  generateToolUseId,\n  extractOverrides,\n  isTextResponse,\n  isToolCallResponse,\n  isContentWithToolCallsResponse,\n  isErrorResponse,\n  flattenHeaders,\n  getTestId,\n  resolveResponse,\n  resolveStrictMode,\n  resolveReasoningForModel,\n  resolveReasoningArtifactsForModel,\n  strictOverrideField,\n  getContext,\n  strictNoMatchMessage,\n  strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic, recordMatchOptions } from \"./router.js\";\nimport { writeErrorResponse, delay, calculateDelay } from \"./sse-writer.js\";\nimport { createInterruptionSignal } from \"./interruption.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { Logger } from \"./logger.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\n/**\n * Non-empty placeholder signature written into emitted `thinking` blocks.\n *\n * The real Anthropic signature is a cryptographic value aimock cannot\n * reproduce, but extended-thinking invariant (b) requires a non-empty\n * `signature` on the leading thinking block of a tool-loop continuation turn.\n * Emitting \"\" would make a record→replay round-trip of an aimock thinking turn\n * self-trip that invariant under strict mode. A non-empty placeholder keeps\n * round-trips green; the invariant only checks for non-emptiness, not value.\n */\nconst PLACEHOLDER_SIGNATURE = \"aimock-placeholder-signature\";\n\n// ─── Claude Messages API request types ──────────────────────────────────────\n\ninterface ClaudeContentBlock {\n  type:\n    | \"text\"\n    | \"tool_use\"\n    | \"tool_result\"\n    | \"image\"\n    | \"document\"\n    | \"thinking\"\n    | \"redacted_thinking\";\n  text?: string;\n  id?: string;\n  name?: string;\n  input?: unknown;\n  tool_use_id?: string;\n  content?: string | ClaudeContentBlock[];\n  is_error?: boolean;\n  // Extended-thinking fields (Anthropic): `thinking` blocks carry the reasoning\n  // text plus a cryptographic `signature`; `redacted_thinking` blocks carry an\n  // opaque `data` payload instead.\n  thinking?: string;\n  signature?: string;\n  data?: string;\n}\n\ninterface ClaudeMessage {\n  role: \"user\" | \"assistant\";\n  content: string | ClaudeContentBlock[];\n}\n\ninterface ClaudeToolDef {\n  name: string;\n  description?: string;\n  input_schema?: object;\n}\n\ninterface ClaudeRequest {\n  model: string;\n  messages: ClaudeMessage[];\n  system?: string | ClaudeContentBlock[];\n  tools?: ClaudeToolDef[];\n  tool_choice?: unknown;\n  stream?: boolean;\n  max_tokens: number;\n  temperature?: number;\n  // Extended-thinking config. Explicitly modeled so it is no longer swallowed\n  // by the index signature below; read defensively (may be a non-object).\n  thinking?: { type?: \"enabled\" | \"disabled\"; budget_tokens?: number };\n  [key: string]: unknown;\n}\n\n// ─── Extended-thinking request invariants (Anthropic) ───────────────────────\n\n/**\n * A detected violation of the Anthropic extended-thinking request invariants on\n * a tool-loop continuation turn. `kind` distinguishes the three failure modes\n * so callers can template a per-kind error message and tests can assert without\n * string matching.\n */\ninterface ThinkingViolation {\n  kind: \"missing_thinking_first\" | \"missing_signature\" | \"dropped_redacted_thinking\";\n  messageIndex: number;\n  observedFirstBlockType?: string;\n}\n\n// ─── Input conversion: Claude → ChatCompletions messages ────────────────────\n\nfunction extractClaudeTextContent(content: string | ClaudeContentBlock[]): string {\n  if (typeof content === \"string\") return content;\n  if (!Array.isArray(content)) return \"\";\n  return content\n    .filter((b) => b != null && typeof b === \"object\" && b.type === \"text\")\n    .map((b) => b.text ?? \"\")\n    .join(\"\");\n}\n\nexport function claudeToCompletionRequest(req: ClaudeRequest): ChatCompletionRequest {\n  const messages: ChatMessage[] = [];\n\n  // system field → system message\n  if (req.system) {\n    const systemText =\n      typeof req.system === \"string\"\n        ? req.system\n        : Array.isArray(req.system)\n          ? req.system\n              .filter((b) => b != null && typeof b === \"object\" && b.type === \"text\")\n              .map((b) => b.text ?? \"\")\n              .join(\"\")\n          : \"\";\n    if (systemText) {\n      messages.push({ role: \"system\", content: systemText });\n    }\n  }\n\n  const reqMessages = Array.isArray(req.messages) ? req.messages : [];\n  for (const msg of reqMessages) {\n    // `req.messages` is untrusted JSON; entries may be null / non-object.\n    if (!msg || typeof msg !== \"object\") continue;\n    if (msg.role === \"user\") {\n      // Check for tool_result blocks\n      if (typeof msg.content !== \"string\" && Array.isArray(msg.content)) {\n        // Content blocks are equally untrusted; skip null / non-object entries.\n        const blocks = msg.content.filter((b) => b != null && typeof b === \"object\");\n        const toolResults = blocks.filter((b) => b.type === \"tool_result\");\n        const textBlocks = blocks.filter((b) => b.type === \"text\");\n\n        if (toolResults.length > 0) {\n          // Each tool_result → tool message\n          for (const tr of toolResults) {\n            const resultContent =\n              typeof tr.content === \"string\"\n                ? tr.content\n                : Array.isArray(tr.content)\n                  ? tr.content\n                      .filter((b) => b != null && typeof b === \"object\" && b.type === \"text\")\n                      .map((b) => b.text ?? \"\")\n                      .join(\"\")\n                  : \"\";\n            messages.push({\n              role: \"tool\",\n              content: resultContent,\n              tool_call_id: tr.tool_use_id,\n            });\n          }\n          // Any accompanying text blocks → user message\n          if (textBlocks.length > 0) {\n            messages.push({\n              role: \"user\",\n              content: textBlocks.map((b) => b.text ?? \"\").join(\"\"),\n            });\n          }\n          continue;\n        }\n      }\n      // Regular user message\n      messages.push({\n        role: \"user\",\n        content: extractClaudeTextContent(msg.content),\n      });\n    } else if (msg.role === \"assistant\") {\n      if (typeof msg.content === \"string\") {\n        messages.push({ role: \"assistant\", content: msg.content });\n      } else if (Array.isArray(msg.content)) {\n        const toolUseBlocks = msg.content.filter(\n          (b) => b != null && typeof b === \"object\" && b.type === \"tool_use\",\n        );\n        // Only `text` blocks feed fixture matching; `thinking` /\n        // `redacted_thinking` blocks are intentionally excluded from the\n        // matchable content.\n        const textContent = extractClaudeTextContent(msg.content);\n\n        if (toolUseBlocks.length > 0) {\n          messages.push({\n            role: \"assistant\",\n            content: textContent || null,\n            tool_calls: toolUseBlocks.map((b) => ({\n              id: b.id ?? generateToolUseId(),\n              type: \"function\" as const,\n              function: {\n                name: b.name ?? \"\",\n                arguments: typeof b.input === \"string\" ? b.input : JSON.stringify(b.input ?? {}),\n              },\n            })),\n          });\n        } else {\n          messages.push({ role: \"assistant\", content: textContent || null });\n        }\n      } else {\n        // null/undefined content — tool-only assistant turn\n        messages.push({ role: \"assistant\", content: null });\n      }\n    }\n  }\n\n  // Convert tools\n  let tools: ToolDefinition[] | undefined;\n  if (req.tools && req.tools.length > 0) {\n    tools = req.tools.map((t) => ({\n      type: \"function\" as const,\n      function: {\n        name: t.name,\n        description: t.description,\n        parameters: t.input_schema,\n      },\n    }));\n  }\n\n  return {\n    model: req.model,\n    messages,\n    stream: req.stream,\n    temperature: req.temperature,\n    max_tokens: req.max_tokens,\n    tools,\n    _endpointType: \"chat\",\n  };\n}\n\n// ─── Extended-thinking invariant validation ─────────────────────────────────\n\n/** True iff `req.thinking` is an object with `type === \"enabled\"`. */\nfunction isThinkingEnabled(req: ClaudeRequest): boolean {\n  const t = req.thinking;\n  return typeof t === \"object\" && t !== null && (t as { type?: unknown }).type === \"enabled\";\n}\n\n/**\n * True iff the user turn at `req.messages[userIndex]` carries a `tool_result`\n * referencing one of `toolUseIds` — i.e. it answers the preceding assistant\n * turn's `tool_use` block(s), making that assistant turn a tool-loop\n * continuation point.\n */\nfunction userTurnAnswersToolUse(msg: ClaudeMessage | undefined, toolUseIds: Set<string>): boolean {\n  if (!msg || msg.role !== \"user\" || !Array.isArray(msg.content)) return false;\n  return msg.content.some(\n    (b) =>\n      b != null &&\n      typeof b === \"object\" &&\n      b.type === \"tool_result\" &&\n      typeof b.tool_use_id === \"string\" &&\n      toolUseIds.has(b.tool_use_id),\n  );\n}\n\n/**\n * Validate the Anthropic extended-thinking request invariants on tool-loop\n * continuation turns. Pure: returns the first detected `ThinkingViolation` or\n * `null` when thinking is disabled or every in-scope turn is well-formed.\n *\n * Scope: an assistant turn is in-scope only when it (a) is array content\n * carrying at least one `tool_use` block and (b) is followed by a matching\n * `tool_result` on the next user turn. Text-only / `end_turn` turns, string or\n * empty turns, and trailing unanswered `tool_use` turns are all exempt.\n *\n * Scope detection assumes well-formed Anthropic transcripts: `tool_use` ids are\n * unique, and a tool_use turn is answered by the immediately-following user\n * turn's `tool_result` (adjacency). Malformed shapes — non-adjacent answers,\n * idless `tool_use` blocks, or a `tool_result` separated from its `tool_use` by\n * intervening turns — are intentionally treated as out-of-scope (and therefore\n * not 400'd) rather than validated, since the real Anthropic API would never\n * have produced them.\n */\nexport function validateThinkingInvariants(req: ClaudeRequest): ThinkingViolation | null {\n  if (!isThinkingEnabled(req)) return null;\n\n  const messages = Array.isArray(req.messages) ? req.messages : [];\n  for (let i = 0; i < messages.length; i++) {\n    const msg = messages[i];\n    // `req.messages` is untrusted JSON; entries may be null / non-object.\n    if (!msg || typeof msg !== \"object\") continue;\n    if (msg.role !== \"assistant\" || !Array.isArray(msg.content) || msg.content.length === 0) {\n      continue;\n    }\n\n    const toolUseIds = new Set<string>();\n    for (const b of msg.content) {\n      // Content blocks are equally untrusted; skip null / non-object entries.\n      if (!b || typeof b !== \"object\") continue;\n      if (b.type === \"tool_use\" && typeof b.id === \"string\") toolUseIds.add(b.id);\n    }\n    // Not a tool_use-bearing turn → not a reasoning-bearing continuation turn.\n    if (toolUseIds.size === 0) continue;\n    // Trailing/unanswered tool_use (no matching tool_result follows) → out of scope.\n    if (!userTurnAnswersToolUse(messages[i + 1], toolUseIds)) continue;\n\n    const first = msg.content[0];\n\n    // A null / non-object leading block cannot be a thinking block → it\n    // violates invariant (a) just as a wrong-typed block would.\n    if (!first || typeof first !== \"object\") {\n      return {\n        kind: \"missing_thinking_first\",\n        messageIndex: i,\n        observedFirstBlockType: undefined,\n      };\n    }\n\n    // (a) The in-scope turn must lead with a thinking / redacted_thinking block.\n    if (first.type !== \"thinking\" && first.type !== \"redacted_thinking\") {\n      return {\n        kind: \"missing_thinking_first\",\n        messageIndex: i,\n        observedFirstBlockType: first.type,\n      };\n    }\n\n    // (b) A leading `thinking` block must carry a non-empty string `signature`.\n    if (first.type === \"thinking\") {\n      if (typeof first.signature !== \"string\" || first.signature.length === 0) {\n        return { kind: \"missing_signature\", messageIndex: i };\n      }\n    }\n\n    // (c) A leading `redacted_thinking` block must preserve a non-empty `data`.\n    if (first.type === \"redacted_thinking\") {\n      if (typeof first.data !== \"string\" || first.data.length === 0) {\n        return { kind: \"dropped_redacted_thinking\", messageIndex: i };\n      }\n    }\n  }\n\n  return null;\n}\n\n/** Render the Anthropic-shaped 400 error message for a thinking violation. */\nfunction thinkingViolationMessage(v: ThinkingViolation): string {\n  const prefix = `messages.${v.messageIndex}.content.0`;\n  switch (v.kind) {\n    case \"missing_thinking_first\":\n      return `${prefix}: when \\`thinking\\` is enabled, a tool-loop continuation assistant turn must begin with a \\`thinking\\` block; got \\`${v.observedFirstBlockType ?? \"unknown\"}\\`.`;\n    case \"missing_signature\":\n      return `${prefix}: the leading \\`thinking\\` block is missing a non-empty \\`signature\\`.`;\n    case \"dropped_redacted_thinking\":\n      return `${prefix}: the leading \\`redacted_thinking\\` block must preserve its \\`data\\`.`;\n  }\n}\n\n// ─── Response building: fixture → Claude Messages API format ────────────────\n\nfunction claudeStopReason(finishReason: string | undefined, defaultReason: string): string {\n  if (!finishReason) return defaultReason;\n  if (finishReason === \"stop\") return \"end_turn\";\n  if (finishReason === \"tool_calls\") return \"tool_use\";\n  if (finishReason === \"length\") return \"max_tokens\";\n  return finishReason;\n}\n\nfunction claudeUsage(overrides?: ResponseOverrides): {\n  input_tokens: number;\n  output_tokens: number;\n} {\n  if (!overrides?.usage) return { input_tokens: 0, output_tokens: 0 };\n  return {\n    input_tokens: overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0,\n    output_tokens: overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0,\n  };\n}\n\ninterface ClaudeSSEEvent {\n  type: string;\n  [key: string]: unknown;\n}\n\n/**\n * Emit faithful Anthropic `redacted_thinking` content-block events at the head\n * of a streamed turn — one `content_block_start` (carrying the opaque `data`)\n * and `content_block_stop` per recorded block, with NO deltas (real Anthropic\n * delivers the encrypted reasoning entirely on the start event). Returns the\n * next free block index. When `redactedThinking` is empty/absent this is a\n * no-op, so no events are added.\n *\n * Leading placement keeps the turn round-trip-safe for the extended-thinking\n * leading-block invariant (a thinking / redacted_thinking block must come\n * first). It does NOT reproduce real Anthropic's stream order: aimock joins all\n * plaintext reasoning into one block and emits all redacted blocks ahead of it,\n * whereas real Anthropic interleaves `thinking` and `redacted_thinking` in the\n * order they occurred. The interleaving between the two is not preserved.\n */\nfunction pushRedactedThinkingStreamEvents(\n  events: ClaudeSSEEvent[],\n  startIndex: number,\n  redactedThinking: string[] | undefined,\n): number {\n  let blockIndex = startIndex;\n  for (const data of redactedThinking ?? []) {\n    events.push({\n      type: \"content_block_start\",\n      index: blockIndex,\n      content_block: { type: \"redacted_thinking\", data },\n    });\n    events.push({\n      type: \"content_block_stop\",\n      index: blockIndex,\n    });\n    blockIndex++;\n  }\n  return blockIndex;\n}\n\nfunction buildClaudeTextStreamEvents(\n  content: string,\n  model: string,\n  chunkSize: number,\n  reasoning?: string,\n  overrides?: ResponseOverrides,\n  reasoningSignature?: string,\n  redactedThinking?: string[],\n): ClaudeSSEEvent[] {\n  const msgId = overrides?.id ?? generateMessageId();\n  const effectiveModel = overrides?.model ?? model;\n  // Prefer a recorded real signature when one was captured; otherwise fall back\n  // to the round-trip-safe placeholder.\n  const signature = reasoningSignature ?? PLACEHOLDER_SIGNATURE;\n  const events: ClaudeSSEEvent[] = [];\n\n  // message_start\n  events.push({\n    type: \"message_start\",\n    message: {\n      id: msgId,\n      type: \"message\",\n      role: overrides?.role ?? \"assistant\",\n      content: [],\n      model: effectiveModel,\n      stop_reason: null,\n      stop_sequence: null,\n      usage: claudeUsage(overrides),\n    },\n  });\n\n  let blockIndex = 0;\n\n  // Redacted-thinking blocks lead the turn (before any thinking / text) to\n  // satisfy the leading-block invariant on replay; see the helper for the\n  // ordering caveat.\n  blockIndex = pushRedactedThinkingStreamEvents(events, blockIndex, redactedThinking);\n\n  // Thinking block (emitted before text when reasoning is present)\n  if (reasoning) {\n    // Real Anthropic emits an empty `signature` on the thinking\n    // `content_block_start`; the cryptographic signature arrives only via the\n    // trailing `signature_delta`. Mirror that wire shape here.\n    events.push({\n      type: \"content_block_start\",\n      index: blockIndex,\n      content_block: { type: \"thinking\", thinking: \"\", signature: \"\" },\n    });\n\n    for (let i = 0; i < reasoning.length; i += chunkSize) {\n      const slice = reasoning.slice(i, i + chunkSize);\n      events.push({\n        type: \"content_block_delta\",\n        index: blockIndex,\n        delta: { type: \"thinking_delta\", thinking: slice },\n      });\n    }\n\n    events.push({\n      type: \"content_block_delta\",\n      index: blockIndex,\n      delta: { type: \"signature_delta\", signature },\n    });\n\n    events.push({\n      type: \"content_block_stop\",\n      index: blockIndex,\n    });\n\n    blockIndex++;\n  }\n\n  // content_block_start (text)\n  events.push({\n    type: \"content_block_start\",\n    index: blockIndex,\n    content_block: { type: \"text\", text: \"\" },\n  });\n\n  // content_block_delta — text chunks\n  for (let i = 0; i < content.length; i += chunkSize) {\n    const slice = content.slice(i, i + chunkSize);\n    events.push({\n      type: \"content_block_delta\",\n      index: blockIndex,\n      delta: { type: \"text_delta\", text: slice },\n    });\n  }\n\n  // content_block_stop\n  events.push({\n    type: \"content_block_stop\",\n    index: blockIndex,\n  });\n\n  // message_delta\n  events.push({\n    type: \"message_delta\",\n    delta: {\n      stop_reason: claudeStopReason(overrides?.finishReason, \"end_turn\"),\n      stop_sequence: null,\n    },\n    usage: { output_tokens: claudeUsage(overrides).output_tokens },\n  });\n\n  // message_stop\n  events.push({ type: \"message_stop\" });\n\n  return events;\n}\n\nfunction buildClaudeToolCallStreamEvents(\n  toolCalls: ToolCall[],\n  model: string,\n  chunkSize: number,\n  logger: Logger,\n  reasoning?: string,\n  overrides?: ResponseOverrides,\n  reasoningSignature?: string,\n  redactedThinking?: string[],\n): ClaudeSSEEvent[] {\n  const msgId = overrides?.id ?? generateMessageId();\n  const effectiveModel = overrides?.model ?? model;\n  // Prefer a recorded real signature when one was captured; otherwise fall back\n  // to the round-trip-safe placeholder.\n  const signature = reasoningSignature ?? PLACEHOLDER_SIGNATURE;\n  const events: ClaudeSSEEvent[] = [];\n\n  // message_start\n  events.push({\n    type: \"message_start\",\n    message: {\n      id: msgId,\n      type: \"message\",\n      role: overrides?.role ?? \"assistant\",\n      content: [],\n      model: effectiveModel,\n      stop_reason: null,\n      stop_sequence: null,\n      usage: claudeUsage(overrides),\n    },\n  });\n\n  let blockIndex = 0;\n\n  // Redacted-thinking blocks lead the turn (before thinking / tool_use blocks)\n  // to satisfy the extended-thinking leading-block invariant on replay; see the\n  // helper for the ordering caveat.\n  blockIndex = pushRedactedThinkingStreamEvents(events, blockIndex, redactedThinking);\n\n  // Optional thinking block (emitted before the tool_use blocks when reasoning\n  // is present). Mirrors buildClaudeContentWithToolCallsStreamEvents exactly so\n  // a pure-tool-call turn under extended thinking emits a leading thinking\n  // block — without it, replaying the emitted turn under strict self-trips\n  // `missing_thinking_first`.\n  if (reasoning) {\n    // Real Anthropic emits an empty `signature` on the thinking\n    // `content_block_start`; the cryptographic signature arrives only via the\n    // trailing `signature_delta`. Mirror that wire shape here.\n    events.push({\n      type: \"content_block_start\",\n      index: blockIndex,\n      content_block: { type: \"thinking\", thinking: \"\", signature: \"\" },\n    });\n\n    for (let i = 0; i < reasoning.length; i += chunkSize) {\n      const slice = reasoning.slice(i, i + chunkSize);\n      events.push({\n        type: \"content_block_delta\",\n        index: blockIndex,\n        delta: { type: \"thinking_delta\", thinking: slice },\n      });\n    }\n\n    events.push({\n      type: \"content_block_delta\",\n      index: blockIndex,\n      delta: { type: \"signature_delta\", signature },\n    });\n\n    events.push({\n      type: \"content_block_stop\",\n      index: blockIndex,\n    });\n\n    blockIndex++;\n  }\n\n  for (const tc of toolCalls) {\n    const toolUseId = tc.id || generateToolUseId();\n\n    // Parse arguments to JSON object (Claude uses objects, not strings)\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    const argsJson = JSON.stringify(argsObj);\n\n    // content_block_start\n    events.push({\n      type: \"content_block_start\",\n      index: blockIndex,\n      content_block: {\n        type: \"tool_use\",\n        id: toolUseId,\n        name: tc.name,\n        input: {},\n      },\n    });\n\n    // content_block_delta — input_json_delta chunks\n    for (let i = 0; i < argsJson.length; i += chunkSize) {\n      const slice = argsJson.slice(i, i + chunkSize);\n      events.push({\n        type: \"content_block_delta\",\n        index: blockIndex,\n        delta: { type: \"input_json_delta\", partial_json: slice },\n      });\n    }\n\n    // content_block_stop\n    events.push({\n      type: \"content_block_stop\",\n      index: blockIndex,\n    });\n\n    blockIndex++;\n  }\n\n  // message_delta\n  events.push({\n    type: \"message_delta\",\n    delta: {\n      stop_reason: claudeStopReason(overrides?.finishReason, \"tool_use\"),\n      stop_sequence: null,\n    },\n    usage: { output_tokens: claudeUsage(overrides).output_tokens },\n  });\n\n  // message_stop\n  events.push({ type: \"message_stop\" });\n\n  return events;\n}\n\n// Non-streaming response builders\n\n/**\n * Push faithful Anthropic `redacted_thinking` content blocks (each a\n * `{ type: \"redacted_thinking\", data }`) onto a non-streaming content array, in\n * recorded order. No-op when `redactedThinking` is empty/absent, so no blocks\n * are added.\n *\n * Leading placement keeps the turn round-trip-safe for the extended-thinking\n * leading-block invariant. It does NOT reproduce real Anthropic's block order:\n * aimock joins all plaintext reasoning into one block and emits all redacted\n * blocks ahead of it, whereas real Anthropic interleaves `thinking` and\n * `redacted_thinking` in occurrence order. The interleaving is not preserved.\n */\nfunction pushRedactedThinkingBlocks(\n  contentBlocks: object[],\n  redactedThinking: string[] | undefined,\n): void {\n  for (const data of redactedThinking ?? []) {\n    contentBlocks.push({ type: \"redacted_thinking\", data });\n  }\n}\n\nfunction buildClaudeTextResponse(\n  content: string,\n  model: string,\n  reasoning?: string,\n  overrides?: ResponseOverrides,\n  reasoningSignature?: string,\n  redactedThinking?: string[],\n): object {\n  const contentBlocks: object[] = [];\n\n  // Redacted-thinking blocks lead the content array (before thinking / text);\n  // see the helper for the ordering caveat.\n  pushRedactedThinkingBlocks(contentBlocks, redactedThinking);\n\n  if (reasoning) {\n    contentBlocks.push({\n      type: \"thinking\",\n      thinking: reasoning,\n      // Prefer a recorded real signature; otherwise the round-trip-safe placeholder.\n      signature: reasoningSignature ?? PLACEHOLDER_SIGNATURE,\n    });\n  }\n\n  contentBlocks.push({ type: \"text\", text: content });\n\n  return {\n    id: overrides?.id ?? generateMessageId(),\n    type: \"message\",\n    role: overrides?.role ?? \"assistant\",\n    content: contentBlocks,\n    model: overrides?.model ?? model,\n    stop_reason: claudeStopReason(overrides?.finishReason, \"end_turn\"),\n    stop_sequence: null,\n    usage: claudeUsage(overrides),\n  };\n}\n\nfunction buildClaudeToolCallResponse(\n  toolCalls: ToolCall[],\n  model: string,\n  logger: Logger,\n  reasoning?: string,\n  overrides?: ResponseOverrides,\n  reasoningSignature?: string,\n  redactedThinking?: string[],\n): object {\n  const contentBlocks: object[] = [];\n\n  // Redacted-thinking blocks lead the content array (before thinking / tool_use)\n  // to satisfy the leading-block invariant on replay; see the helper for the\n  // ordering caveat.\n  pushRedactedThinkingBlocks(contentBlocks, redactedThinking);\n\n  // Leading thinking block when reasoning is present — mirrors\n  // buildClaudeContentWithToolCallsResponse so a pure-tool-call turn under\n  // extended thinking carries the same leading thinking block.\n  if (reasoning) {\n    contentBlocks.push({\n      type: \"thinking\",\n      thinking: reasoning,\n      // Prefer a recorded real signature; otherwise the round-trip-safe placeholder.\n      signature: reasoningSignature ?? PLACEHOLDER_SIGNATURE,\n    });\n  }\n\n  for (const tc of toolCalls) {\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    contentBlocks.push({\n      type: \"tool_use\",\n      id: tc.id || generateToolUseId(),\n      name: tc.name,\n      input: argsObj,\n    });\n  }\n\n  return {\n    id: overrides?.id ?? generateMessageId(),\n    type: \"message\",\n    role: overrides?.role ?? \"assistant\",\n    content: contentBlocks,\n    model: overrides?.model ?? model,\n    stop_reason: claudeStopReason(overrides?.finishReason, \"tool_use\"),\n    stop_sequence: null,\n    usage: claudeUsage(overrides),\n  };\n}\n\nfunction buildClaudeContentWithToolCallsStreamEvents(\n  content: string,\n  toolCalls: ToolCall[],\n  model: string,\n  chunkSize: number,\n  logger: Logger,\n  reasoning?: string,\n  overrides?: ResponseOverrides,\n  reasoningSignature?: string,\n  redactedThinking?: string[],\n): ClaudeSSEEvent[] {\n  const msgId = overrides?.id ?? generateMessageId();\n  const effectiveModel = overrides?.model ?? model;\n  // Prefer a recorded real signature when one was captured; otherwise fall back\n  // to the round-trip-safe placeholder.\n  const signature = reasoningSignature ?? PLACEHOLDER_SIGNATURE;\n  const events: ClaudeSSEEvent[] = [];\n\n  // message_start\n  events.push({\n    type: \"message_start\",\n    message: {\n      id: msgId,\n      type: \"message\",\n      role: overrides?.role ?? \"assistant\",\n      content: [],\n      model: effectiveModel,\n      stop_reason: null,\n      stop_sequence: null,\n      usage: claudeUsage(overrides),\n    },\n  });\n\n  let blockIndex = 0;\n\n  // Redacted-thinking blocks lead the turn (before thinking / text / tool_use);\n  // see the helper for the ordering caveat.\n  blockIndex = pushRedactedThinkingStreamEvents(events, blockIndex, redactedThinking);\n\n  // Optional thinking block\n  if (reasoning) {\n    // Real Anthropic emits an empty `signature` on the thinking\n    // `content_block_start`; the cryptographic signature arrives only via the\n    // trailing `signature_delta`. Mirror that wire shape here.\n    events.push({\n      type: \"content_block_start\",\n      index: blockIndex,\n      content_block: { type: \"thinking\", thinking: \"\", signature: \"\" },\n    });\n\n    for (let i = 0; i < reasoning.length; i += chunkSize) {\n      const slice = reasoning.slice(i, i + chunkSize);\n      events.push({\n        type: \"content_block_delta\",\n        index: blockIndex,\n        delta: { type: \"thinking_delta\", thinking: slice },\n      });\n    }\n\n    events.push({\n      type: \"content_block_delta\",\n      index: blockIndex,\n      delta: { type: \"signature_delta\", signature },\n    });\n\n    events.push({\n      type: \"content_block_stop\",\n      index: blockIndex,\n    });\n\n    blockIndex++;\n  }\n\n  // Text content block\n  events.push({\n    type: \"content_block_start\",\n    index: blockIndex,\n    content_block: { type: \"text\", text: \"\" },\n  });\n\n  for (let i = 0; i < content.length; i += chunkSize) {\n    const slice = content.slice(i, i + chunkSize);\n    events.push({\n      type: \"content_block_delta\",\n      index: blockIndex,\n      delta: { type: \"text_delta\", text: slice },\n    });\n  }\n\n  events.push({\n    type: \"content_block_stop\",\n    index: blockIndex,\n  });\n\n  blockIndex++;\n\n  // Tool use blocks\n  for (const tc of toolCalls) {\n    const toolUseId = tc.id || generateToolUseId();\n\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    const argsJson = JSON.stringify(argsObj);\n\n    events.push({\n      type: \"content_block_start\",\n      index: blockIndex,\n      content_block: {\n        type: \"tool_use\",\n        id: toolUseId,\n        name: tc.name,\n        input: {},\n      },\n    });\n\n    for (let i = 0; i < argsJson.length; i += chunkSize) {\n      const slice = argsJson.slice(i, i + chunkSize);\n      events.push({\n        type: \"content_block_delta\",\n        index: blockIndex,\n        delta: { type: \"input_json_delta\", partial_json: slice },\n      });\n    }\n\n    events.push({\n      type: \"content_block_stop\",\n      index: blockIndex,\n    });\n\n    blockIndex++;\n  }\n\n  // message_delta\n  events.push({\n    type: \"message_delta\",\n    delta: {\n      stop_reason: claudeStopReason(overrides?.finishReason, \"tool_use\"),\n      stop_sequence: null,\n    },\n    usage: { output_tokens: claudeUsage(overrides).output_tokens },\n  });\n\n  // message_stop\n  events.push({ type: \"message_stop\" });\n\n  return events;\n}\n\nfunction buildClaudeContentWithToolCallsResponse(\n  content: string,\n  toolCalls: ToolCall[],\n  model: string,\n  logger: Logger,\n  reasoning?: string,\n  overrides?: ResponseOverrides,\n  reasoningSignature?: string,\n  redactedThinking?: string[],\n): object {\n  const contentBlocks: object[] = [];\n\n  // Redacted-thinking blocks lead the content array (before thinking / text /\n  // tool_use); see the helper for the ordering caveat.\n  pushRedactedThinkingBlocks(contentBlocks, redactedThinking);\n\n  if (reasoning) {\n    contentBlocks.push({\n      type: \"thinking\",\n      thinking: reasoning,\n      // Prefer a recorded real signature; otherwise the round-trip-safe placeholder.\n      signature: reasoningSignature ?? PLACEHOLDER_SIGNATURE,\n    });\n  }\n\n  contentBlocks.push({ type: \"text\", text: content });\n\n  for (const tc of toolCalls) {\n    let argsObj: unknown;\n    try {\n      argsObj = JSON.parse(tc.arguments || \"{}\");\n    } catch {\n      logger.warn(\n        `Malformed JSON in fixture tool call arguments for \"${tc.name}\": ${tc.arguments}`,\n      );\n      argsObj = {};\n    }\n    contentBlocks.push({\n      type: \"tool_use\",\n      id: tc.id || generateToolUseId(),\n      name: tc.name,\n      input: argsObj,\n    });\n  }\n\n  return {\n    id: overrides?.id ?? generateMessageId(),\n    type: \"message\",\n    role: overrides?.role ?? \"assistant\",\n    content: contentBlocks,\n    model: overrides?.model ?? model,\n    stop_reason: claudeStopReason(overrides?.finishReason, \"tool_use\"),\n    stop_sequence: null,\n    usage: claudeUsage(overrides),\n  };\n}\n\n// ─── SSE writer for Claude Messages API ─────────────────────────────────────\n\ninterface ClaudeStreamOptions {\n  latency?: number;\n  streamingProfile?: StreamingProfile;\n  recordedTimings?: RecordedTimings;\n  replaySpeed?: number;\n  signal?: AbortSignal;\n  onChunkSent?: () => void;\n}\n\nasync function writeClaudeSSEStream(\n  res: http.ServerResponse,\n  events: ClaudeSSEEvent[],\n  optionsOrLatency?: number | ClaudeStreamOptions,\n): Promise<boolean> {\n  const opts: ClaudeStreamOptions =\n    typeof optionsOrLatency === \"number\" ? { latency: optionsOrLatency } : (optionsOrLatency ?? {});\n  const latency = opts.latency ?? 0;\n  const profile = opts.streamingProfile;\n  const { recordedTimings, replaySpeed } = opts;\n  const signal = opts.signal;\n  const onChunkSent = opts.onChunkSent;\n\n  if (res.writableEnded) return true;\n  res.setHeader(\"Content-Type\", \"text/event-stream\");\n  res.setHeader(\"Cache-Control\", \"no-cache\");\n  res.setHeader(\"Connection\", \"keep-alive\");\n\n  let chunkIndex = 0;\n  for (const event of events) {\n    const chunkDelay = calculateDelay(chunkIndex, profile, latency, recordedTimings, replaySpeed);\n    if (chunkDelay > 0) await delay(chunkDelay, signal);\n    if (signal?.aborted) return false;\n    if (res.writableEnded) return true;\n    res.write(`event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`);\n    onChunkSent?.();\n    if (signal?.aborted) return false;\n    chunkIndex++;\n  }\n\n  if (!res.writableEnded) {\n    res.end();\n  }\n  return true;\n}\n\n// ─── Request handler ────────────────────────────────────────────────────────\n\nexport async function handleMessages(\n  req: http.IncomingMessage,\n  res: http.ServerResponse,\n  raw: string,\n  fixtures: Fixture[],\n  journal: Journal,\n  defaults: HandlerDefaults,\n  setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n  const { logger } = defaults;\n  setCorsHeaders(res);\n\n  let claudeReq: ClaudeRequest;\n  try {\n    claudeReq = JSON.parse(raw) as ClaudeRequest;\n  } catch (parseErr) {\n    const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: req.url ?? \"/v1/messages\",\n      headers: flattenHeaders(req.headers),\n      body: null,\n      response: { status: 400, fixture: null },\n    });\n    writeErrorResponse(\n      res,\n      400,\n      JSON.stringify({\n        error: {\n          message: `Malformed JSON: ${detail}`,\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  // Extended-thinking invariant validation. The validator runs whenever\n  // thinking is enabled (it self-short-circuits to null otherwise). On a\n  // detected violation: strict ON → 400, strict OFF → warn + replay. Mirrors\n  // the real Anthropic API, which 400s on these.\n  const thinkingViolation = validateThinkingInvariants(claudeReq);\n  if (thinkingViolation) {\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const violationMessage = thinkingViolationMessage(thinkingViolation);\n    if (effectiveStrict) {\n      logger.error(`THINKING: ${violationMessage}`);\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: req.url ?? \"/v1/messages\",\n        headers: flattenHeaders(req.headers),\n        body: null,\n        response: {\n          status: 400,\n          fixture: null,\n          ...strictOverrideField(defaults.strict, req.headers),\n        },\n      });\n      writeErrorResponse(\n        res,\n        400,\n        JSON.stringify({\n          type: \"error\",\n          error: {\n            type: \"invalid_request_error\",\n            message: violationMessage,\n          },\n        }),\n      );\n      return;\n    }\n    logger.warn(`THINKING: ${violationMessage} (strict off — replaying anyway)`);\n    // Fall through to existing match/replay behavior.\n  }\n\n  // Convert to ChatCompletionRequest for fixture matching\n  const completionReq = claudeToCompletionRequest(claudeReq);\n  completionReq._context = getContext(req);\n\n  const testId = getTestId(req);\n  const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n    fixtures,\n    completionReq,\n    journal.getFixtureMatchCountsForTest(testId),\n    defaults.requestTransform,\n    // Record mode proxies on a miss to capture a fresh turn (see record gate\n    // below), so keep turnIndex strict to prevent an earlier-turn fixture from\n    // shadowing a longer request and skipping the new turn's recording.\n    recordMatchOptions(!!defaults.record, defaults.logger),\n  );\n\n  if (fixture) {\n    journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n    logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n  } else {\n    const lastUserMsg = completionReq.messages.filter((m) => m.role === \"user\").pop();\n    const snippet =\n      typeof lastUserMsg?.content === \"string\" ? lastUserMsg.content.slice(0, 80) : \"\";\n    logger.debug(\n      `No fixture matched for request (model=${completionReq.model ?? \"?\"}, msg=\"${snippet}\")`,\n    );\n  }\n\n  if (\n    applyChaos(\n      res,\n      fixture,\n      defaults.chaos,\n      req.headers,\n      journal,\n      {\n        method: req.method ?? \"POST\",\n        path: req.url ?? \"/v1/messages\",\n        headers: flattenHeaders(req.headers),\n        body: completionReq,\n      },\n      fixture ? \"fixture\" : \"proxy\",\n      defaults.registry,\n      defaults.logger,\n    )\n  )\n    return;\n\n  if (!fixture) {\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    if (effectiveStrict) {\n      const strictStatus = 503;\n      const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n      logger.error(\n        strictNoMatchLogLine(\n          req.method ?? \"POST\",\n          req.url ?? \"/v1/messages\",\n          skippedBySequenceOrTurn,\n        ),\n      );\n      journal.add({\n        method: req.method ?? \"POST\",\n        path: req.url ?? \"/v1/messages\",\n        headers: flattenHeaders(req.headers),\n        body: completionReq,\n        response: {\n          status: strictStatus,\n          fixture: null,\n          ...strictOverrideField(defaults.strict, req.headers),\n        },\n      });\n      writeErrorResponse(\n        res,\n        strictStatus,\n        JSON.stringify({\n          error: {\n            message: strictMessage,\n            type: \"invalid_request_error\",\n          },\n        }),\n      );\n      return;\n    }\n    if (defaults.record) {\n      const outcome = await proxyAndRecord(\n        req,\n        res,\n        completionReq,\n        \"anthropic\",\n        req.url ?? \"/v1/messages\",\n        fixtures,\n        defaults,\n        raw,\n      );\n      if (outcome === \"handled_by_hook\") return;\n      if (outcome !== \"not_configured\") {\n        journal.add({\n          method: req.method ?? \"POST\",\n          path: req.url ?? \"/v1/messages\",\n          headers: flattenHeaders(req.headers),\n          body: completionReq,\n          response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n        });\n        return;\n      }\n    }\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: req.url ?? \"/v1/messages\",\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: {\n        status: 404,\n        fixture: null,\n        ...strictOverrideField(defaults.strict, req.headers),\n      },\n    });\n    writeErrorResponse(\n      res,\n      404,\n      JSON.stringify({\n        error: {\n          message: \"No fixture matched\",\n          type: \"invalid_request_error\",\n        },\n      }),\n    );\n    return;\n  }\n\n  const response = await resolveResponse(fixture, completionReq);\n  const latency = fixture.latency ?? defaults.latency;\n  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);\n\n  // Error response\n  if (isErrorResponse(response)) {\n    const status = response.status ?? 500;\n    journal.add({\n      method: req.method ?? \"POST\",\n      path: req.url ?? \"/v1/messages\",\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status, fixture },\n    });\n    // Anthropic-style error format: { type: \"error\", error: { type, message } }\n    const anthropicError = {\n      type: \"error\",\n      error: {\n        type: response.error.type ?? \"api_error\",\n        message: response.error.message,\n      },\n    };\n    writeErrorResponse(res, status, JSON.stringify(anthropicError), {\n      retryAfter: response.retryAfter,\n    });\n    return;\n  }\n\n  // Content + tool calls response (must be checked before text/tool-only branches)\n  if (isContentWithToolCallsResponse(response)) {\n    if (response.webSearches?.length) {\n      logger.warn(\n        \"webSearches in fixture response are not supported for Claude Messages API — ignoring\",\n      );\n    }\n    const overrides = extractOverrides(response);\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      defaults.logger,\n    );\n    const { reasoningSignature: effReasoningSignature, redactedThinking: effRedactedThinking } =\n      resolveReasoningArtifactsForModel(\n        response.reasoningSignature,\n        response.redactedThinking,\n        completionReq.model,\n        effectiveStrict,\n        defaults.logger,\n      );\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: req.url ?? \"/v1/messages\",\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    if (claudeReq.stream !== true) {\n      const body = buildClaudeContentWithToolCallsResponse(\n        response.content,\n        response.toolCalls,\n        completionReq.model,\n        logger,\n        effReasoning,\n        overrides,\n        effReasoningSignature,\n        effRedactedThinking,\n      );\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const events = buildClaudeContentWithToolCallsStreamEvents(\n        response.content,\n        response.toolCalls,\n        completionReq.model,\n        chunkSize,\n        logger,\n        effReasoning,\n        overrides,\n        effReasoningSignature,\n        effRedactedThinking,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeClaudeSSEStream(res, events, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Text response\n  if (isTextResponse(response)) {\n    if (response.webSearches?.length) {\n      logger.warn(\n        \"webSearches in fixture response are not supported for Claude Messages API — ignoring\",\n      );\n    }\n    const overrides = extractOverrides(response);\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      defaults.logger,\n    );\n    const { reasoningSignature: effReasoningSignature, redactedThinking: effRedactedThinking } =\n      resolveReasoningArtifactsForModel(\n        response.reasoningSignature,\n        response.redactedThinking,\n        completionReq.model,\n        effectiveStrict,\n        defaults.logger,\n      );\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: req.url ?? \"/v1/messages\",\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    if (claudeReq.stream !== true) {\n      const body = buildClaudeTextResponse(\n        response.content,\n        completionReq.model,\n        effReasoning,\n        overrides,\n        effReasoningSignature,\n        effRedactedThinking,\n      );\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const events = buildClaudeTextStreamEvents(\n        response.content,\n        completionReq.model,\n        chunkSize,\n        effReasoning,\n        overrides,\n        effReasoningSignature,\n        effRedactedThinking,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeClaudeSSEStream(res, events, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Tool call response\n  if (isToolCallResponse(response)) {\n    if (response.webSearches?.length) {\n      logger.warn(\n        \"webSearches in fixture response are not supported for Claude Messages API — ignoring\",\n      );\n    }\n    const overrides = extractOverrides(response);\n    const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n    const effReasoning = resolveReasoningForModel(\n      response.reasoning,\n      completionReq.model,\n      effectiveStrict,\n      defaults.logger,\n    );\n    const { reasoningSignature: effReasoningSignature, redactedThinking: effRedactedThinking } =\n      resolveReasoningArtifactsForModel(\n        response.reasoningSignature,\n        response.redactedThinking,\n        completionReq.model,\n        effectiveStrict,\n        defaults.logger,\n      );\n    const journalEntry = journal.add({\n      method: req.method ?? \"POST\",\n      path: req.url ?? \"/v1/messages\",\n      headers: flattenHeaders(req.headers),\n      body: completionReq,\n      response: { status: 200, fixture },\n    });\n    if (claudeReq.stream !== true) {\n      const body = buildClaudeToolCallResponse(\n        response.toolCalls,\n        completionReq.model,\n        logger,\n        effReasoning,\n        overrides,\n        effReasoningSignature,\n        effRedactedThinking,\n      );\n      res.writeHead(200, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify(body));\n    } else {\n      const events = buildClaudeToolCallStreamEvents(\n        response.toolCalls,\n        completionReq.model,\n        chunkSize,\n        logger,\n        effReasoning,\n        overrides,\n        effReasoningSignature,\n        effRedactedThinking,\n      );\n      const interruption = createInterruptionSignal(fixture);\n      const completed = await writeClaudeSSEStream(res, events, {\n        latency,\n        streamingProfile: fixture.streamingProfile,\n        recordedTimings: fixture.recordedTimings,\n        replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n        signal: interruption?.signal,\n        onChunkSent: interruption?.tick,\n      });\n      if (!completed) {\n        if (!res.writableEnded) res.destroy();\n        journalEntry.response.interrupted = true;\n        journalEntry.response.interruptReason = interruption?.reason();\n      }\n      interruption?.cleanup();\n    }\n    return;\n  }\n\n  // Unknown response type\n  journal.add({\n    method: req.method ?? \"POST\",\n    path: req.url ?? \"/v1/messages\",\n    headers: flattenHeaders(req.headers),\n    body: completionReq,\n    response: { status: 500, fixture },\n  });\n  writeErrorResponse(\n    res,\n    500,\n    JSON.stringify({\n      error: {\n        message: \"Fixture response did not match any known type\",\n        type: \"server_error\",\n      },\n    }),\n  );\n}\n"],"mappings":"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"}