@copilotkit/aimock 1.33.0 → 1.34.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.
- package/CHANGELOG.md +14 -0
- package/README.md +4 -0
- package/dist/agui-types.d.cts.map +1 -1
- package/dist/bedrock-converse.cjs +2 -2
- package/dist/bedrock-converse.cjs.map +1 -1
- package/dist/bedrock-converse.d.cts.map +1 -1
- package/dist/bedrock-converse.d.ts.map +1 -1
- package/dist/bedrock-converse.js +3 -3
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +2 -2
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.d.cts.map +1 -1
- package/dist/bedrock.d.ts.map +1 -1
- package/dist/bedrock.js +3 -3
- package/dist/bedrock.js.map +1 -1
- package/dist/cohere.cjs +2 -2
- package/dist/cohere.cjs.map +1 -1
- package/dist/cohere.js +3 -3
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/gemini-interactions.cjs +71 -70
- package/dist/gemini-interactions.cjs.map +1 -1
- package/dist/gemini-interactions.d.cts.map +1 -1
- package/dist/gemini-interactions.d.ts.map +1 -1
- package/dist/gemini-interactions.js +71 -70
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +1 -1
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.js +2 -2
- package/dist/gemini.js.map +1 -1
- package/dist/messages.cjs +1 -1
- package/dist/messages.cjs.map +1 -1
- package/dist/messages.js +2 -2
- package/dist/messages.js.map +1 -1
- package/dist/ollama.cjs +3 -3
- package/dist/ollama.cjs.map +1 -1
- package/dist/ollama.d.cts.map +1 -1
- package/dist/ollama.d.ts.map +1 -1
- package/dist/ollama.js +4 -4
- package/dist/ollama.js.map +1 -1
- package/dist/responses.cjs +1 -1
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.js +2 -2
- package/dist/responses.js.map +1 -1
- package/dist/router.cjs +236 -33
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.cts +54 -2
- package/dist/router.d.cts.map +1 -1
- package/dist/router.d.ts +54 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +236 -34
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/stream-collapse.cjs +56 -6
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +10 -3
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +10 -3
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +56 -6
- package/dist/stream-collapse.js.map +1 -1
- package/dist/vector-types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bedrock.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { extractOverrides, flattenHeaders, generateMessageId, generateToolUseId, getContext, getTestId, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, resolveReasoningForModel, resolveResponse, resolveStrictMode, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField } from "./helpers.js";
|
|
2
|
-
import { matchFixtureDiagnostic } from "./router.js";
|
|
2
|
+
import { matchFixtureDiagnostic, recordMatchOptions } from "./router.js";
|
|
3
3
|
import { writeErrorResponse } from "./sse-writer.js";
|
|
4
4
|
import { createInterruptionSignal } from "./interruption.js";
|
|
5
5
|
import { applyChaos } from "./chaos.js";
|
|
@@ -225,7 +225,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
|
|
|
225
225
|
completionReq._endpointType = "chat";
|
|
226
226
|
completionReq._context = getContext(req);
|
|
227
227
|
const testId = getTestId(req);
|
|
228
|
-
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
228
|
+
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, recordMatchOptions(!!defaults.record, defaults.logger));
|
|
229
229
|
if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
230
230
|
else logger.debug(`No fixture matched for request`);
|
|
231
231
|
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
@@ -797,7 +797,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
|
|
|
797
797
|
completionReq._endpointType = "chat";
|
|
798
798
|
completionReq._context = getContext(req);
|
|
799
799
|
const testId = getTestId(req);
|
|
800
|
-
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
800
|
+
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, recordMatchOptions(!!defaults.record, defaults.logger));
|
|
801
801
|
if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
802
802
|
else logger.debug(`No fixture matched for request`);
|
|
803
803
|
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
package/dist/bedrock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock.js","names":[],"sources":["../src/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock Claude endpoint support — invoke and invoke-with-response-stream.\n *\n * Handles four Bedrock endpoint families (split across two modules):\n *\n * This file (bedrock.ts):\n * - POST /model/{modelId}/invoke — non-streaming invoke\n * - POST /model/{modelId}/invoke-with-response-stream — binary EventStream streaming\n *\n * bedrock-converse.ts:\n * - POST /model/{modelId}/converse — Converse API (non-streaming)\n * - POST /model/{modelId}/converse-stream — Converse API (EventStream streaming)\n *\n * Translates incoming Bedrock Claude format into the ChatCompletionRequest\n * format used by the fixture router, and converts fixture responses back into\n * the appropriate Bedrock response format (JSON for invoke, AWS Event Stream\n * binary encoding for streaming).\n */\n\nimport type * as http from \"node:http\";\nimport type {\n ChatCompletionRequest,\n ChatMessage,\n Fixture,\n HandlerDefaults,\n ResponseOverrides,\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 getContext,\n getTestId,\n resolveResponse,\n resolveReasoningForModel,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { writeEventStream } from \"./aws-event-stream.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// ─── Bedrock Claude request types ────────────────────────────────────────────\n\ninterface BedrockContentBlock {\n type: \"text\" | \"tool_use\" | \"tool_result\" | \"image\" | \"document\";\n text?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: string | BedrockContentBlock[];\n is_error?: boolean;\n}\n\ninterface BedrockMessage {\n role: \"user\" | \"assistant\";\n content: string | BedrockContentBlock[];\n}\n\ninterface BedrockToolDef {\n name: string;\n description?: string;\n input_schema?: object;\n}\n\ninterface BedrockRequest {\n anthropic_version?: string;\n messages: BedrockMessage[];\n system?: string | BedrockContentBlock[];\n tools?: BedrockToolDef[];\n tool_choice?: unknown;\n max_tokens: number;\n temperature?: number;\n [key: string]: unknown;\n}\n\n// ─── Bedrock stop_reason mapping ───────────────────────────────────────────\n\nfunction bedrockStopReason(\n overrideFinishReason: string | undefined,\n defaultReason: string,\n): string {\n if (!overrideFinishReason) return defaultReason;\n if (overrideFinishReason === \"stop\") return \"end_turn\";\n if (overrideFinishReason === \"tool_calls\") return \"tool_use\";\n if (overrideFinishReason === \"length\") return \"max_tokens\";\n return overrideFinishReason;\n}\n\n/**\n * Build a Bedrock-style usage object from optional overrides.\n *\n * When no overrides are provided (the common case for mock fixtures),\n * returns all-zero token counts. This is intentional — aimock does not\n * attempt to estimate token usage from fixture content. Callers that\n * need realistic usage numbers should set `usage` in their fixture's\n * response overrides.\n */\nfunction bedrockUsage(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\n// ─── Input conversion: Bedrock → ChatCompletionRequest ──────────────────────\n\nfunction extractTextContent(content: string | BedrockContentBlock[]): string {\n if (typeof content === \"string\") return content;\n return content\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n}\n\nexport function bedrockToCompletionRequest(\n req: BedrockRequest,\n modelId: string,\n logger?: Logger,\n): 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 : req.system\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n if (systemText) {\n messages.push({ role: \"system\", content: systemText });\n }\n }\n\n for (const msg of req.messages) {\n if (msg.role === \"user\") {\n // Check for tool_result blocks\n if (typeof msg.content !== \"string\" && Array.isArray(msg.content)) {\n // Warn about non-text content blocks that will be dropped (image, document, etc.)\n const unsupportedBlocks = msg.content.filter(\n (b) => b.type !== \"text\" && b.type !== \"tool_result\",\n );\n if (unsupportedBlocks.length > 0 && logger) {\n const types = [...new Set(unsupportedBlocks.map((b) => b.type))].join(\", \");\n logger.warn(\n `Bedrock user message contains unsupported content block types [${types}] — these will be dropped during conversion`,\n );\n }\n\n const toolResults = msg.content.filter((b) => b.type === \"tool_result\");\n const textBlocks = msg.content.filter((b) => b.type === \"text\");\n\n if (toolResults.length > 0) {\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.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 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 messages.push({\n role: \"user\",\n content: extractTextContent(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((b) => b.type === \"tool_use\");\n const textContent = extractTextContent(msg.content);\n\n if (toolUseBlocks.length > 0) {\n messages.push({\n role: \"assistant\",\n content: textContent || null,\n tool_calls: toolUseBlocks.map((b, index) => {\n if (!b.id && logger) {\n logger.warn(\n `Bedrock assistant tool_use block at index ${index} is missing an id — using deterministic fallback \"tool_use_${index}\"`,\n );\n }\n return {\n id: b.id ?? `tool_use_${index}`,\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 });\n } else {\n messages.push({ role: \"assistant\", content: textContent || null });\n }\n } else {\n messages.push({ role: \"assistant\", content: null });\n }\n } else {\n if (logger) {\n logger.warn(\n `Bedrock message has unexpected role \"${(msg as { role: string }).role}\" — skipping`,\n );\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: modelId,\n messages,\n stream: false,\n temperature: req.temperature,\n max_tokens: req.max_tokens,\n tools,\n };\n}\n\n// ─── Response builders ──────────────────────────────────────────────────────\n\nfunction buildBedrockTextResponse(\n content: string,\n model: string,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({ type: \"thinking\", thinking: reasoning, signature: \"\" });\n }\n contentBlocks.push({ type: \"text\", text: content });\n\n return {\n id: overrides?.id ?? generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content: contentBlocks,\n model: overrides?.model ?? model,\n stop_reason: bedrockStopReason(overrides?.finishReason, \"end_turn\"),\n stop_sequence: null,\n usage: bedrockUsage(overrides),\n };\n}\n\nfunction buildBedrockToolCallResponse(\n toolCalls: ToolCall[],\n model: string,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n // Thinking block (emitted before tool_use blocks when reasoning is present)\n if (reasoning) {\n contentBlocks.push({ type: \"thinking\", thinking: reasoning, signature: \"\" });\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 return {\n id: overrides?.id ?? generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content: contentBlocks,\n model: overrides?.model ?? model,\n stop_reason: bedrockStopReason(overrides?.finishReason, \"tool_use\"),\n stop_sequence: null,\n usage: bedrockUsage(overrides),\n };\n}\n\n// ─── Request handler ────────────────────────────────────────────────────────\n\nexport async function handleBedrock(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n modelId: 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 const urlPath = req.url ?? `/model/${modelId}/invoke`;\n\n let bedrockReq: BedrockRequest;\n try {\n bedrockReq = JSON.parse(raw) as BedrockRequest;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 if (!bedrockReq.messages || !Array.isArray(bedrockReq.messages)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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: \"Invalid request: messages array is required\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Convert to ChatCompletionRequest for fixture matching\n const completionReq = bedrockToCompletionRequest(bedrockReq, modelId, logger);\n completionReq._endpointType = \"chat\";\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 );\n\n if (fixture) {\n logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n logger.debug(`No fixture matched for request`);\n }\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\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: urlPath,\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(strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn));\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 \"bedrock\",\n urlPath,\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: urlPath,\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: urlPath,\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\n // Error response\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status, fixture },\n });\n // Bedrock Claude error format: { type: \"error\", error: { type, message } }\n // Uses ?? (nullish coalescing) intentionally — preserves explicit empty-string types from fixtures.\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\n if (isContentWithToolCallsResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const textBody = buildBedrockTextResponse(\n response.content,\n completionReq.model,\n effReasoning,\n overrides,\n );\n const toolBody = buildBedrockToolCallResponse(\n response.toolCalls,\n completionReq.model,\n logger,\n // Reasoning is rendered by the text response in this merged path; pass\n // undefined here to avoid emitting a duplicate thinking block.\n undefined,\n overrides,\n );\n // Merge: take the text response as base, append tool_use blocks, set stop_reason to tool_use\n const merged = {\n ...(textBody as Record<string, unknown>),\n content: [\n ...((textBody as Record<string, unknown>).content as object[]),\n ...((toolBody as Record<string, unknown>).content as object[]),\n ],\n stop_reason: bedrockStopReason(overrides?.finishReason, \"tool_use\"),\n };\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(merged));\n return;\n }\n\n // Text response\n if (isTextResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const body = buildBedrockTextResponse(\n response.content,\n completionReq.model,\n effReasoning,\n overrides,\n );\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Tool call response\n if (isToolCallResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const body = buildBedrockToolCallResponse(\n response.toolCalls,\n completionReq.model,\n logger,\n effReasoning,\n overrides,\n );\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Unknown response type\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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\n// ─── Streaming event builders ───────────────────────────────────────────────\n\nconst BEDROCK_INVOKE_STREAM_EVENT_TYPE = \"chunk\";\n\nfunction buildBedrockInvokeMessageStart(\n model: string,\n overrides?: ResponseOverrides,\n): { eventType: string; payload: object } {\n return {\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"message_start\",\n message: {\n id: overrides?.id ?? generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: overrides?.model ?? model,\n stop_reason: null,\n stop_sequence: null,\n usage: bedrockUsage(overrides),\n },\n },\n };\n}\n\nfunction buildBedrockInvokeMessageDelta(stopReason: string): {\n eventType: string;\n payload: object;\n} {\n return {\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"message_delta\",\n delta: { stop_reason: stopReason, stop_sequence: null },\n usage: { output_tokens: 0 },\n },\n };\n}\n\nfunction buildBedrockInvokeMessageStop(): { eventType: string; payload: object } {\n return {\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"message_stop\" },\n };\n}\n\nfunction parseToolArgumentsForStream(toolCall: ToolCall, logger: Logger): string {\n try {\n const parsed = JSON.parse(toolCall.arguments || \"{}\");\n return JSON.stringify(parsed);\n } catch {\n logger.warn(\n `Malformed JSON in fixture tool call arguments for \"${toolCall.name}\": ${toolCall.arguments}`,\n );\n return \"{}\";\n }\n}\n\nexport function buildBedrockStreamTextEvents(\n content: string,\n model: string,\n chunkSize: number,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): Array<{ eventType: string; payload: object }> {\n const events: Array<{ eventType: string; payload: object }> = [];\n\n events.push(buildBedrockInvokeMessageStart(model, overrides));\n\n // Thinking block (emitted before text when reasoning is present)\n if (reasoning) {\n const blockIndex = 0;\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: blockIndex,\n content_block: { type: \"thinking\", thinking: \"\", signature: \"\" },\n },\n });\n\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n const slice = reasoning.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"thinking_delta\", thinking: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"signature_delta\", signature: \"\" },\n },\n });\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n }\n\n // Text block\n const textBlockIndex = reasoning ? 1 : 0;\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: textBlockIndex,\n content_block: { type: \"text\", text: \"\" },\n },\n });\n\n for (let i = 0; i < content.length; i += chunkSize) {\n const slice = content.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: textBlockIndex,\n delta: { type: \"text_delta\", text: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: textBlockIndex },\n });\n\n events.push(\n buildBedrockInvokeMessageDelta(bedrockStopReason(overrides?.finishReason, \"end_turn\")),\n );\n events.push(buildBedrockInvokeMessageStop());\n\n return events;\n}\n\nexport function buildBedrockStreamContentWithToolCallsEvents(\n content: string,\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): Array<{ eventType: string; payload: object }> {\n const events: Array<{ eventType: string; payload: object }> = [];\n\n events.push(buildBedrockInvokeMessageStart(model, overrides));\n\n let blockIndex = 0;\n\n // Thinking block (emitted before text when reasoning is present)\n if (reasoning) {\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\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 eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"thinking_delta\", thinking: slice },\n },\n });\n }\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"signature_delta\", signature: \"\" },\n },\n });\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n blockIndex++;\n }\n\n // Text block\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\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 eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"text_delta\", text: slice },\n },\n });\n }\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n blockIndex++;\n\n // Tool call blocks\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const toolUseId = tc.id || generateToolUseId();\n const currentBlock = blockIndex + tcIdx;\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: currentBlock,\n content_block: {\n type: \"tool_use\",\n id: toolUseId,\n name: tc.name,\n input: {},\n },\n },\n });\n\n const argsStr = parseToolArgumentsForStream(tc, logger);\n\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n const slice = argsStr.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: currentBlock,\n delta: { type: \"input_json_delta\", partial_json: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: currentBlock },\n });\n }\n\n events.push(\n buildBedrockInvokeMessageDelta(bedrockStopReason(overrides?.finishReason, \"tool_use\")),\n );\n events.push(buildBedrockInvokeMessageStop());\n\n return events;\n}\n\nexport function buildBedrockStreamToolCallEvents(\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): Array<{ eventType: string; payload: object }> {\n const events: Array<{ eventType: string; payload: object }> = [];\n\n events.push(buildBedrockInvokeMessageStart(model, overrides));\n\n // Leading reasoning block shifts every subsequent tool_use block index by 1.\n let blockIndex = 0;\n\n // Thinking block (emitted before tool_use blocks when reasoning is present)\n if (reasoning) {\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\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 eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"thinking_delta\", thinking: slice },\n },\n });\n }\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"signature_delta\", signature: \"\" },\n },\n });\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n blockIndex++;\n }\n\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const toolUseId = tc.id || generateToolUseId();\n const currentBlock = blockIndex + tcIdx;\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: currentBlock,\n content_block: {\n type: \"tool_use\",\n id: toolUseId,\n name: tc.name,\n input: {},\n },\n },\n });\n\n const argsStr = parseToolArgumentsForStream(tc, logger);\n\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n const slice = argsStr.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: currentBlock,\n delta: { type: \"input_json_delta\", partial_json: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: currentBlock },\n });\n }\n\n events.push(\n buildBedrockInvokeMessageDelta(bedrockStopReason(overrides?.finishReason, \"tool_use\")),\n );\n events.push(buildBedrockInvokeMessageStop());\n\n return events;\n}\n\n// ─── Streaming request handler ──────────────────────────────────────────────\n\nexport async function handleBedrockStream(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n modelId: 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 const urlPath = req.url ?? `/model/${modelId}/invoke-with-response-stream`;\n\n let bedrockReq: BedrockRequest;\n try {\n bedrockReq = JSON.parse(raw) as BedrockRequest;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 if (!bedrockReq.messages || !Array.isArray(bedrockReq.messages)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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: \"Invalid request: messages array is required\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n const completionReq = bedrockToCompletionRequest(bedrockReq, modelId, logger);\n completionReq.stream = true;\n completionReq._endpointType = \"chat\";\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 );\n\n if (fixture) {\n logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n logger.debug(`No fixture matched for request`);\n }\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\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: urlPath,\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(strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn));\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 \"bedrock\",\n urlPath,\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: urlPath,\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: urlPath,\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: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status, fixture },\n });\n // Bedrock Claude error format: { type: \"error\", error: { type, message } }\n // Uses ?? (nullish coalescing) intentionally — preserves explicit empty-string types from fixtures.\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 — stream as Event Stream\n if (isContentWithToolCallsResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n const journalEntry = journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const events = buildBedrockStreamContentWithToolCallsEvents(\n response.content,\n response.toolCalls,\n completionReq.model,\n chunkSize,\n logger,\n effReasoning,\n overrides,\n );\n const interruption = createInterruptionSignal(fixture);\n const completed = await writeEventStream(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 return;\n }\n\n // Text response — stream as Event Stream\n if (isTextResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n const journalEntry = journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const events = buildBedrockStreamTextEvents(\n response.content,\n completionReq.model,\n chunkSize,\n effReasoning,\n overrides,\n );\n const interruption = createInterruptionSignal(fixture);\n const completed = await writeEventStream(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 return;\n }\n\n // Tool call response — stream as Event Stream\n if (isToolCallResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n const journalEntry = journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const events = buildBedrockStreamToolCallEvents(\n response.toolCalls,\n completionReq.model,\n chunkSize,\n logger,\n effReasoning,\n overrides,\n );\n const interruption = createInterruptionSignal(fixture);\n const completed = await writeEventStream(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 return;\n }\n\n // Unknown response type\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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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"}
|
|
1
|
+
{"version":3,"file":"bedrock.js","names":[],"sources":["../src/bedrock.ts"],"sourcesContent":["/**\n * AWS Bedrock Claude endpoint support — invoke and invoke-with-response-stream.\n *\n * Handles four Bedrock endpoint families (split across two modules):\n *\n * This file (bedrock.ts):\n * - POST /model/{modelId}/invoke — non-streaming invoke\n * - POST /model/{modelId}/invoke-with-response-stream — binary EventStream streaming\n *\n * bedrock-converse.ts:\n * - POST /model/{modelId}/converse — Converse API (non-streaming)\n * - POST /model/{modelId}/converse-stream — Converse API (EventStream streaming)\n *\n * Translates incoming Bedrock Claude format into the ChatCompletionRequest\n * format used by the fixture router, and converts fixture responses back into\n * the appropriate Bedrock response format (JSON for invoke, AWS Event Stream\n * binary encoding for streaming).\n */\n\nimport type * as http from \"node:http\";\nimport type {\n ChatCompletionRequest,\n ChatMessage,\n Fixture,\n HandlerDefaults,\n ResponseOverrides,\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 getContext,\n getTestId,\n resolveResponse,\n resolveReasoningForModel,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic, recordMatchOptions } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { writeEventStream } from \"./aws-event-stream.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// ─── Bedrock Claude request types ────────────────────────────────────────────\n\ninterface BedrockContentBlock {\n type: \"text\" | \"tool_use\" | \"tool_result\" | \"image\" | \"document\";\n text?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: string | BedrockContentBlock[];\n is_error?: boolean;\n}\n\ninterface BedrockMessage {\n role: \"user\" | \"assistant\";\n content: string | BedrockContentBlock[];\n}\n\ninterface BedrockToolDef {\n name: string;\n description?: string;\n input_schema?: object;\n}\n\ninterface BedrockRequest {\n anthropic_version?: string;\n messages: BedrockMessage[];\n system?: string | BedrockContentBlock[];\n tools?: BedrockToolDef[];\n tool_choice?: unknown;\n max_tokens: number;\n temperature?: number;\n [key: string]: unknown;\n}\n\n// ─── Bedrock stop_reason mapping ───────────────────────────────────────────\n\nfunction bedrockStopReason(\n overrideFinishReason: string | undefined,\n defaultReason: string,\n): string {\n if (!overrideFinishReason) return defaultReason;\n if (overrideFinishReason === \"stop\") return \"end_turn\";\n if (overrideFinishReason === \"tool_calls\") return \"tool_use\";\n if (overrideFinishReason === \"length\") return \"max_tokens\";\n return overrideFinishReason;\n}\n\n/**\n * Build a Bedrock-style usage object from optional overrides.\n *\n * When no overrides are provided (the common case for mock fixtures),\n * returns all-zero token counts. This is intentional — aimock does not\n * attempt to estimate token usage from fixture content. Callers that\n * need realistic usage numbers should set `usage` in their fixture's\n * response overrides.\n */\nfunction bedrockUsage(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\n// ─── Input conversion: Bedrock → ChatCompletionRequest ──────────────────────\n\nfunction extractTextContent(content: string | BedrockContentBlock[]): string {\n if (typeof content === \"string\") return content;\n return content\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n}\n\nexport function bedrockToCompletionRequest(\n req: BedrockRequest,\n modelId: string,\n logger?: Logger,\n): 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 : req.system\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n if (systemText) {\n messages.push({ role: \"system\", content: systemText });\n }\n }\n\n for (const msg of req.messages) {\n if (msg.role === \"user\") {\n // Check for tool_result blocks\n if (typeof msg.content !== \"string\" && Array.isArray(msg.content)) {\n // Warn about non-text content blocks that will be dropped (image, document, etc.)\n const unsupportedBlocks = msg.content.filter(\n (b) => b.type !== \"text\" && b.type !== \"tool_result\",\n );\n if (unsupportedBlocks.length > 0 && logger) {\n const types = [...new Set(unsupportedBlocks.map((b) => b.type))].join(\", \");\n logger.warn(\n `Bedrock user message contains unsupported content block types [${types}] — these will be dropped during conversion`,\n );\n }\n\n const toolResults = msg.content.filter((b) => b.type === \"tool_result\");\n const textBlocks = msg.content.filter((b) => b.type === \"text\");\n\n if (toolResults.length > 0) {\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.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 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 messages.push({\n role: \"user\",\n content: extractTextContent(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((b) => b.type === \"tool_use\");\n const textContent = extractTextContent(msg.content);\n\n if (toolUseBlocks.length > 0) {\n messages.push({\n role: \"assistant\",\n content: textContent || null,\n tool_calls: toolUseBlocks.map((b, index) => {\n if (!b.id && logger) {\n logger.warn(\n `Bedrock assistant tool_use block at index ${index} is missing an id — using deterministic fallback \"tool_use_${index}\"`,\n );\n }\n return {\n id: b.id ?? `tool_use_${index}`,\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 });\n } else {\n messages.push({ role: \"assistant\", content: textContent || null });\n }\n } else {\n messages.push({ role: \"assistant\", content: null });\n }\n } else {\n if (logger) {\n logger.warn(\n `Bedrock message has unexpected role \"${(msg as { role: string }).role}\" — skipping`,\n );\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: modelId,\n messages,\n stream: false,\n temperature: req.temperature,\n max_tokens: req.max_tokens,\n tools,\n };\n}\n\n// ─── Response builders ──────────────────────────────────────────────────────\n\nfunction buildBedrockTextResponse(\n content: string,\n model: string,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({ type: \"thinking\", thinking: reasoning, signature: \"\" });\n }\n contentBlocks.push({ type: \"text\", text: content });\n\n return {\n id: overrides?.id ?? generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content: contentBlocks,\n model: overrides?.model ?? model,\n stop_reason: bedrockStopReason(overrides?.finishReason, \"end_turn\"),\n stop_sequence: null,\n usage: bedrockUsage(overrides),\n };\n}\n\nfunction buildBedrockToolCallResponse(\n toolCalls: ToolCall[],\n model: string,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n // Thinking block (emitted before tool_use blocks when reasoning is present)\n if (reasoning) {\n contentBlocks.push({ type: \"thinking\", thinking: reasoning, signature: \"\" });\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 return {\n id: overrides?.id ?? generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content: contentBlocks,\n model: overrides?.model ?? model,\n stop_reason: bedrockStopReason(overrides?.finishReason, \"tool_use\"),\n stop_sequence: null,\n usage: bedrockUsage(overrides),\n };\n}\n\n// ─── Request handler ────────────────────────────────────────────────────────\n\nexport async function handleBedrock(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n modelId: 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 const urlPath = req.url ?? `/model/${modelId}/invoke`;\n\n let bedrockReq: BedrockRequest;\n try {\n bedrockReq = JSON.parse(raw) as BedrockRequest;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 if (!bedrockReq.messages || !Array.isArray(bedrockReq.messages)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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: \"Invalid request: messages array is required\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Convert to ChatCompletionRequest for fixture matching\n const completionReq = bedrockToCompletionRequest(bedrockReq, modelId, logger);\n completionReq._endpointType = \"chat\";\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 logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n logger.debug(`No fixture matched for request`);\n }\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\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: urlPath,\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(strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn));\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 \"bedrock\",\n urlPath,\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: urlPath,\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: urlPath,\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\n // Error response\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status, fixture },\n });\n // Bedrock Claude error format: { type: \"error\", error: { type, message } }\n // Uses ?? (nullish coalescing) intentionally — preserves explicit empty-string types from fixtures.\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\n if (isContentWithToolCallsResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const textBody = buildBedrockTextResponse(\n response.content,\n completionReq.model,\n effReasoning,\n overrides,\n );\n const toolBody = buildBedrockToolCallResponse(\n response.toolCalls,\n completionReq.model,\n logger,\n // Reasoning is rendered by the text response in this merged path; pass\n // undefined here to avoid emitting a duplicate thinking block.\n undefined,\n overrides,\n );\n // Merge: take the text response as base, append tool_use blocks, set stop_reason to tool_use\n const merged = {\n ...(textBody as Record<string, unknown>),\n content: [\n ...((textBody as Record<string, unknown>).content as object[]),\n ...((toolBody as Record<string, unknown>).content as object[]),\n ],\n stop_reason: bedrockStopReason(overrides?.finishReason, \"tool_use\"),\n };\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(merged));\n return;\n }\n\n // Text response\n if (isTextResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const body = buildBedrockTextResponse(\n response.content,\n completionReq.model,\n effReasoning,\n overrides,\n );\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Tool call response\n if (isToolCallResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const body = buildBedrockToolCallResponse(\n response.toolCalls,\n completionReq.model,\n logger,\n effReasoning,\n overrides,\n );\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Unknown response type\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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\n// ─── Streaming event builders ───────────────────────────────────────────────\n\nconst BEDROCK_INVOKE_STREAM_EVENT_TYPE = \"chunk\";\n\nfunction buildBedrockInvokeMessageStart(\n model: string,\n overrides?: ResponseOverrides,\n): { eventType: string; payload: object } {\n return {\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"message_start\",\n message: {\n id: overrides?.id ?? generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: overrides?.model ?? model,\n stop_reason: null,\n stop_sequence: null,\n usage: bedrockUsage(overrides),\n },\n },\n };\n}\n\nfunction buildBedrockInvokeMessageDelta(stopReason: string): {\n eventType: string;\n payload: object;\n} {\n return {\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"message_delta\",\n delta: { stop_reason: stopReason, stop_sequence: null },\n usage: { output_tokens: 0 },\n },\n };\n}\n\nfunction buildBedrockInvokeMessageStop(): { eventType: string; payload: object } {\n return {\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"message_stop\" },\n };\n}\n\nfunction parseToolArgumentsForStream(toolCall: ToolCall, logger: Logger): string {\n try {\n const parsed = JSON.parse(toolCall.arguments || \"{}\");\n return JSON.stringify(parsed);\n } catch {\n logger.warn(\n `Malformed JSON in fixture tool call arguments for \"${toolCall.name}\": ${toolCall.arguments}`,\n );\n return \"{}\";\n }\n}\n\nexport function buildBedrockStreamTextEvents(\n content: string,\n model: string,\n chunkSize: number,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): Array<{ eventType: string; payload: object }> {\n const events: Array<{ eventType: string; payload: object }> = [];\n\n events.push(buildBedrockInvokeMessageStart(model, overrides));\n\n // Thinking block (emitted before text when reasoning is present)\n if (reasoning) {\n const blockIndex = 0;\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: blockIndex,\n content_block: { type: \"thinking\", thinking: \"\", signature: \"\" },\n },\n });\n\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n const slice = reasoning.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"thinking_delta\", thinking: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"signature_delta\", signature: \"\" },\n },\n });\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n }\n\n // Text block\n const textBlockIndex = reasoning ? 1 : 0;\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: textBlockIndex,\n content_block: { type: \"text\", text: \"\" },\n },\n });\n\n for (let i = 0; i < content.length; i += chunkSize) {\n const slice = content.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: textBlockIndex,\n delta: { type: \"text_delta\", text: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: textBlockIndex },\n });\n\n events.push(\n buildBedrockInvokeMessageDelta(bedrockStopReason(overrides?.finishReason, \"end_turn\")),\n );\n events.push(buildBedrockInvokeMessageStop());\n\n return events;\n}\n\nexport function buildBedrockStreamContentWithToolCallsEvents(\n content: string,\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): Array<{ eventType: string; payload: object }> {\n const events: Array<{ eventType: string; payload: object }> = [];\n\n events.push(buildBedrockInvokeMessageStart(model, overrides));\n\n let blockIndex = 0;\n\n // Thinking block (emitted before text when reasoning is present)\n if (reasoning) {\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\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 eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"thinking_delta\", thinking: slice },\n },\n });\n }\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"signature_delta\", signature: \"\" },\n },\n });\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n blockIndex++;\n }\n\n // Text block\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\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 eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"text_delta\", text: slice },\n },\n });\n }\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n blockIndex++;\n\n // Tool call blocks\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const toolUseId = tc.id || generateToolUseId();\n const currentBlock = blockIndex + tcIdx;\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: currentBlock,\n content_block: {\n type: \"tool_use\",\n id: toolUseId,\n name: tc.name,\n input: {},\n },\n },\n });\n\n const argsStr = parseToolArgumentsForStream(tc, logger);\n\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n const slice = argsStr.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: currentBlock,\n delta: { type: \"input_json_delta\", partial_json: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: currentBlock },\n });\n }\n\n events.push(\n buildBedrockInvokeMessageDelta(bedrockStopReason(overrides?.finishReason, \"tool_use\")),\n );\n events.push(buildBedrockInvokeMessageStop());\n\n return events;\n}\n\nexport function buildBedrockStreamToolCallEvents(\n toolCalls: ToolCall[],\n model: string,\n chunkSize: number,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): Array<{ eventType: string; payload: object }> {\n const events: Array<{ eventType: string; payload: object }> = [];\n\n events.push(buildBedrockInvokeMessageStart(model, overrides));\n\n // Leading reasoning block shifts every subsequent tool_use block index by 1.\n let blockIndex = 0;\n\n // Thinking block (emitted before tool_use blocks when reasoning is present)\n if (reasoning) {\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\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 eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"thinking_delta\", thinking: slice },\n },\n });\n }\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: blockIndex,\n delta: { type: \"signature_delta\", signature: \"\" },\n },\n });\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: blockIndex },\n });\n blockIndex++;\n }\n\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const tc = toolCalls[tcIdx];\n const toolUseId = tc.id || generateToolUseId();\n const currentBlock = blockIndex + tcIdx;\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_start\",\n index: currentBlock,\n content_block: {\n type: \"tool_use\",\n id: toolUseId,\n name: tc.name,\n input: {},\n },\n },\n });\n\n const argsStr = parseToolArgumentsForStream(tc, logger);\n\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n const slice = argsStr.slice(i, i + chunkSize);\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: {\n type: \"content_block_delta\",\n index: currentBlock,\n delta: { type: \"input_json_delta\", partial_json: slice },\n },\n });\n }\n\n events.push({\n eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,\n payload: { type: \"content_block_stop\", index: currentBlock },\n });\n }\n\n events.push(\n buildBedrockInvokeMessageDelta(bedrockStopReason(overrides?.finishReason, \"tool_use\")),\n );\n events.push(buildBedrockInvokeMessageStop());\n\n return events;\n}\n\n// ─── Streaming request handler ──────────────────────────────────────────────\n\nexport async function handleBedrockStream(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n modelId: 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 const urlPath = req.url ?? `/model/${modelId}/invoke-with-response-stream`;\n\n let bedrockReq: BedrockRequest;\n try {\n bedrockReq = JSON.parse(raw) as BedrockRequest;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 if (!bedrockReq.messages || !Array.isArray(bedrockReq.messages)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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: \"Invalid request: messages array is required\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n const completionReq = bedrockToCompletionRequest(bedrockReq, modelId, logger);\n completionReq.stream = true;\n completionReq._endpointType = \"chat\";\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 logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n logger.debug(`No fixture matched for request`);\n }\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\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: urlPath,\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(strictNoMatchLogLine(req.method ?? \"POST\", urlPath, skippedBySequenceOrTurn));\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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 \"bedrock\",\n urlPath,\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: urlPath,\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: urlPath,\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: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status, fixture },\n });\n // Bedrock Claude error format: { type: \"error\", error: { type, message } }\n // Uses ?? (nullish coalescing) intentionally — preserves explicit empty-string types from fixtures.\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 — stream as Event Stream\n if (isContentWithToolCallsResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n const journalEntry = journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const events = buildBedrockStreamContentWithToolCallsEvents(\n response.content,\n response.toolCalls,\n completionReq.model,\n chunkSize,\n logger,\n effReasoning,\n overrides,\n );\n const interruption = createInterruptionSignal(fixture);\n const completed = await writeEventStream(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 return;\n }\n\n // Text response — stream as Event Stream\n if (isTextResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n const journalEntry = journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const events = buildBedrockStreamTextEvents(\n response.content,\n completionReq.model,\n chunkSize,\n effReasoning,\n overrides,\n );\n const interruption = createInterruptionSignal(fixture);\n const completed = await writeEventStream(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 return;\n }\n\n // Tool call response — stream as Event Stream\n if (isToolCallResponse(response)) {\n if (response.webSearches?.length) {\n logger.warn(\"webSearches in fixture response are not supported for Bedrock API — ignoring\");\n }\n const overrides = extractOverrides(response);\n const effReasoning = resolveReasoningForModel(\n response.reasoning,\n completionReq.model,\n resolveStrictMode(defaults.strict, req.headers),\n logger,\n );\n const journalEntry = journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\n headers: flattenHeaders(req.headers),\n body: completionReq,\n response: { status: 200, fixture },\n });\n const events = buildBedrockStreamToolCallEvents(\n response.toolCalls,\n completionReq.model,\n chunkSize,\n logger,\n effReasoning,\n overrides,\n );\n const interruption = createInterruptionSignal(fixture);\n const completed = await writeEventStream(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 return;\n }\n\n // Unknown response type\n journal.add({\n method: req.method ?? \"POST\",\n path: urlPath,\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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"}
|
package/dist/cohere.cjs
CHANGED
|
@@ -561,7 +561,7 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
561
561
|
completionReq._endpointType = "chat";
|
|
562
562
|
completionReq._context = require_helpers.getContext(req);
|
|
563
563
|
const testId = require_helpers.getTestId(req);
|
|
564
|
-
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
564
|
+
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
|
|
565
565
|
if (fixture) {
|
|
566
566
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
567
567
|
logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
@@ -843,7 +843,7 @@ async function handleCohereEmbed(req, res, raw, fixtures, journal, defaults, set
|
|
|
843
843
|
_context: require_helpers.getContext(req)
|
|
844
844
|
};
|
|
845
845
|
const testId = require_helpers.getTestId(req);
|
|
846
|
-
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
846
|
+
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
|
|
847
847
|
if (fixture) {
|
|
848
848
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
849
849
|
logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|