@copilotkit/aimock 1.41.0 → 1.42.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +12 -1
- package/README.md +2 -1
- package/dist/a2a-mock.cjs +18 -11
- package/dist/a2a-mock.cjs.map +1 -1
- package/dist/a2a-mock.d.cts +1 -0
- package/dist/a2a-mock.d.cts.map +1 -1
- package/dist/a2a-mock.d.ts +1 -0
- package/dist/a2a-mock.d.ts.map +1 -1
- package/dist/a2a-mock.js +18 -11
- package/dist/a2a-mock.js.map +1 -1
- package/dist/agui-handler.d.ts.map +1 -1
- package/dist/agui-mock.cjs +2 -0
- package/dist/agui-mock.cjs.map +1 -1
- package/dist/agui-mock.d.cts.map +1 -1
- package/dist/agui-mock.d.ts.map +1 -1
- package/dist/agui-mock.js +2 -0
- package/dist/agui-mock.js.map +1 -1
- package/dist/bedrock-converse.cjs +36 -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 +37 -3
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +50 -13
- 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 +51 -14
- package/dist/bedrock.js.map +1 -1
- package/dist/byteplus-video.cjs +2 -2
- package/dist/byteplus-video.cjs.map +1 -1
- package/dist/byteplus-video.d.cts.map +1 -1
- package/dist/byteplus-video.d.ts.map +1 -1
- package/dist/byteplus-video.js +2 -2
- package/dist/byteplus-video.js.map +1 -1
- package/dist/chaos.cjs +36 -7
- package/dist/chaos.cjs.map +1 -1
- package/dist/chaos.d.cts +8 -3
- package/dist/chaos.d.cts.map +1 -1
- package/dist/chaos.d.ts +8 -3
- package/dist/chaos.d.ts.map +1 -1
- package/dist/chaos.js +36 -8
- package/dist/chaos.js.map +1 -1
- package/dist/cohere.cjs +58 -5
- package/dist/cohere.cjs.map +1 -1
- package/dist/cohere.d.cts.map +1 -1
- package/dist/cohere.d.ts.map +1 -1
- package/dist/cohere.js +59 -6
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/elevenlabs-audio.cjs +36 -2
- package/dist/elevenlabs-audio.cjs.map +1 -1
- package/dist/elevenlabs-audio.d.cts.map +1 -1
- package/dist/elevenlabs-audio.d.ts.map +1 -1
- package/dist/elevenlabs-audio.js +37 -3
- package/dist/elevenlabs-audio.js.map +1 -1
- package/dist/embeddings.cjs +58 -3
- package/dist/embeddings.cjs.map +1 -1
- package/dist/embeddings.d.cts.map +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +59 -4
- package/dist/embeddings.js.map +1 -1
- package/dist/fal-audio.cjs +38 -2
- package/dist/fal-audio.cjs.map +1 -1
- package/dist/fal-audio.d.cts.map +1 -1
- package/dist/fal-audio.d.ts.map +1 -1
- package/dist/fal-audio.js +39 -3
- package/dist/fal-audio.js.map +1 -1
- package/dist/fixture-loader.cjs +0 -0
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.d.cts +9 -1
- package/dist/fixture-loader.d.cts.map +1 -1
- package/dist/fixture-loader.d.ts +9 -1
- package/dist/fixture-loader.d.ts.map +1 -1
- package/dist/fixture-loader.js +0 -0
- package/dist/fixture-loader.js.map +1 -1
- package/dist/gemini-embeddings.cjs +19 -1
- package/dist/gemini-embeddings.cjs.map +1 -1
- package/dist/gemini-embeddings.js +20 -2
- package/dist/gemini-embeddings.js.map +1 -1
- package/dist/gemini-interactions.cjs +15 -1
- 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 +16 -2
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +70 -6
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.d.cts.map +1 -1
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +71 -7
- package/dist/gemini.js.map +1 -1
- package/dist/grok-video.cjs +2 -2
- package/dist/grok-video.cjs.map +1 -1
- package/dist/grok-video.d.cts.map +1 -1
- package/dist/grok-video.d.ts.map +1 -1
- package/dist/grok-video.js +2 -2
- package/dist/grok-video.js.map +1 -1
- package/dist/helpers.cjs +160 -5
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +152 -6
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +22 -4
- package/dist/images.cjs.map +1 -1
- package/dist/images.d.cts.map +1 -1
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +23 -5
- package/dist/images.js.map +1 -1
- package/dist/llmock.cjs +15 -0
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +12 -0
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +12 -0
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +16 -1
- package/dist/llmock.js.map +1 -1
- package/dist/mcp-mock.cjs +11 -0
- package/dist/mcp-mock.cjs.map +1 -1
- package/dist/mcp-mock.d.cts.map +1 -1
- package/dist/mcp-mock.d.ts.map +1 -1
- package/dist/mcp-mock.js +11 -0
- package/dist/mcp-mock.js.map +1 -1
- package/dist/messages.cjs +18 -1
- package/dist/messages.cjs.map +1 -1
- package/dist/messages.d.cts.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +19 -2
- package/dist/messages.js.map +1 -1
- package/dist/moderation.cjs +67 -3
- package/dist/moderation.cjs.map +1 -1
- package/dist/moderation.d.cts +1 -0
- package/dist/moderation.d.cts.map +1 -1
- package/dist/moderation.d.ts +1 -0
- package/dist/moderation.d.ts.map +1 -1
- package/dist/moderation.js +68 -4
- package/dist/moderation.js.map +1 -1
- package/dist/ollama.cjs +75 -5
- 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 +76 -6
- package/dist/ollama.js.map +1 -1
- package/dist/openrouter-video.cjs +4 -4
- package/dist/openrouter-video.cjs.map +1 -1
- package/dist/openrouter-video.d.cts.map +1 -1
- package/dist/openrouter-video.d.ts.map +1 -1
- package/dist/openrouter-video.js +4 -4
- package/dist/openrouter-video.js.map +1 -1
- package/dist/rerank.cjs +65 -2
- package/dist/rerank.cjs.map +1 -1
- package/dist/rerank.d.cts +1 -1
- package/dist/rerank.d.cts.map +1 -1
- package/dist/rerank.d.ts +1 -1
- package/dist/rerank.d.ts.map +1 -1
- package/dist/rerank.js +66 -3
- package/dist/rerank.js.map +1 -1
- package/dist/responses.cjs +18 -1
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +19 -2
- package/dist/responses.js.map +1 -1
- package/dist/search.cjs +67 -3
- package/dist/search.cjs.map +1 -1
- package/dist/search.d.cts +1 -0
- package/dist/search.d.cts.map +1 -1
- package/dist/search.d.ts +1 -0
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +68 -4
- package/dist/search.js.map +1 -1
- package/dist/server.cjs +317 -13
- 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 +320 -16
- package/dist/server.js.map +1 -1
- package/dist/speech.cjs +18 -1
- package/dist/speech.cjs.map +1 -1
- package/dist/speech.d.cts.map +1 -1
- package/dist/speech.d.ts.map +1 -1
- package/dist/speech.js +19 -2
- package/dist/speech.js.map +1 -1
- package/dist/transcription.cjs +21 -2
- package/dist/transcription.cjs.map +1 -1
- package/dist/transcription.d.cts.map +1 -1
- package/dist/transcription.d.ts.map +1 -1
- package/dist/transcription.js +21 -2
- package/dist/transcription.js.map +1 -1
- package/dist/types.d.cts +39 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +39 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-mock.cjs +88 -0
- package/dist/vector-mock.cjs.map +1 -1
- package/dist/vector-mock.d.cts.map +1 -1
- package/dist/vector-mock.d.ts.map +1 -1
- package/dist/vector-mock.js +89 -1
- package/dist/vector-mock.js.map +1 -1
- package/dist/veo-video.cjs +2 -2
- package/dist/veo-video.cjs.map +1 -1
- package/dist/veo-video.d.cts.map +1 -1
- package/dist/veo-video.d.ts.map +1 -1
- package/dist/veo-video.js +2 -2
- package/dist/veo-video.js.map +1 -1
- package/dist/video.cjs +19 -2
- package/dist/video.cjs.map +1 -1
- package/dist/video.d.cts.map +1 -1
- package/dist/video.d.ts.map +1 -1
- package/dist/video.js +20 -3
- package/dist/video.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock-converse.js","names":[],"sources":["../src/bedrock-converse.ts"],"sourcesContent":["/**\n * AWS Bedrock Converse API support.\n *\n * Translates incoming Converse and Converse-stream requests (Bedrock Converse\n * format) into the ChatCompletionRequest format used by the fixture router,\n * and converts fixture responses back into Converse API format — either a\n * single JSON response or an Event Stream binary stream.\n */\n\nimport type * as http from \"node:http\";\nimport type {\n ChatCompletionRequest,\n ChatMessage,\n Fixture,\n FixtureBlock,\n HandlerDefaults,\n ResponseOverrides,\n ToolCall,\n ToolDefinition,\n} from \"./types.js\";\nimport {\n generateToolUseId,\n extractOverrides,\n isTextResponse,\n isToolCallResponse,\n isContentWithToolCallsResponse,\n resolveFixtureBlocks,\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// ─── Converse request types ─────────────────────────────────────────────────\n\ninterface ConverseContentBlock {\n text?: string;\n toolUse?: { toolUseId: string; name: string; input: object };\n toolResult?: { toolUseId: string; content: { text?: string }[] };\n}\n\ninterface ConverseMessage {\n role: \"user\" | \"assistant\";\n content: ConverseContentBlock[];\n}\n\ninterface ConverseToolSpec {\n name: string;\n description?: string;\n inputSchema?: object;\n}\n\ninterface ConverseRequest {\n messages: ConverseMessage[];\n system?: { text: string }[];\n inferenceConfig?: { maxTokens?: number; temperature?: number };\n toolConfig?: { tools: { toolSpec: ConverseToolSpec }[] };\n}\n\n// ─── Converse stop_reason mapping ──────────────────────────────────────────\n\nfunction converseStopReason(\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 Converse-format usage from fixture overrides.\n *\n * When no overrides are provided (the common case for mocks), all token\n * counts default to zero. This is intentional — aimock is a mock server\n * and does not perform real tokenisation. Callers that need non-zero\n * usage should supply explicit `usage` overrides in their fixture.\n */\nfunction converseUsage(overrides?: ResponseOverrides): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n} {\n if (!overrides?.usage) return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n const inputTokens = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;\n const outputTokens = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;\n return { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens };\n}\n\nfunction parseConverseToolArgumentsForStream(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\nfunction buildBedrockStreamTextEvents(\n content: 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 { eventType: \"messageStart\", payload: { role: \"assistant\" } },\n ];\n\n if (reasoning) {\n const blockIndex = 0;\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: blockIndex, start: { reasoningContent: {} } },\n });\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n }\n\n const textBlockIndex = reasoning ? 1 : 0;\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: textBlockIndex, start: {} },\n });\n for (let i = 0; i < content.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: textBlockIndex,\n delta: { text: content.slice(i, i + chunkSize) },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: textBlockIndex },\n });\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"end_turn\") },\n });\n const usage = converseUsage(overrides);\n events.push({\n eventType: \"metadata\",\n payload: { usage, metrics: { latencyMs: 0 } },\n });\n return events;\n}\n\nfunction buildBedrockStreamContentWithToolCallsEvents(\n content: string,\n toolCalls: ToolCall[],\n chunkSize: number,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n blocks?: FixtureBlock[],\n): Array<{ eventType: string; payload: object }> {\n if (blocks && blocks.length > 0) {\n // NEW PATH: stream `text`/`toolUse` content blocks in the fixture's array\n // order. Converse's indexed contentBlock events make ordering observable —\n // a `toolCall` block can take a lower `contentBlockIndex` than a `text`\n // block. Indices are assigned in encounter order, continuing from any\n // leading reasoning block (which occupies index 0).\n const events: Array<{ eventType: string; payload: object }> = [\n { eventType: \"messageStart\", payload: { role: \"assistant\" } },\n ];\n\n let blockIndex = 0;\n if (reasoning) {\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: blockIndex, start: { reasoningContent: {} } },\n });\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n blockIndex++;\n }\n\n const ordered = resolveFixtureBlocks(blocks);\n for (const block of ordered) {\n if (block.type === \"text\") {\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: blockIndex, start: {} },\n });\n for (let i = 0; i < block.text.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { text: block.text.slice(i, i + chunkSize) },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n } else {\n const toolUseId = block.id || generateToolUseId();\n events.push({\n eventType: \"contentBlockStart\",\n payload: {\n contentBlockIndex: blockIndex,\n start: { toolUse: { toolUseId, name: block.name } },\n },\n });\n const argsStr = parseConverseToolArgumentsForStream(\n { name: block.name, arguments: block.arguments } as ToolCall,\n logger,\n );\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n }\n blockIndex++;\n }\n\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"tool_use\") },\n });\n events.push({\n eventType: \"metadata\",\n payload: { usage: converseUsage(overrides), metrics: { latencyMs: 0 } },\n });\n return events;\n }\n\n const events = buildBedrockStreamTextEvents(content, chunkSize, reasoning, overrides);\n // Remove trailing metadata + messageStop events — we re-emit them after tool blocks\n for (let i = events.length - 1; i >= 0; i--) {\n const et = (events[i] as { eventType: string }).eventType;\n if (et === \"metadata\" || et === \"messageStop\") {\n events.splice(i, 1);\n }\n }\n let blockIndex = reasoning ? 2 : 1;\n\n for (const tc of toolCalls) {\n const toolUseId = tc.id || generateToolUseId();\n events.push({\n eventType: \"contentBlockStart\",\n payload: {\n contentBlockIndex: blockIndex,\n start: { toolUse: { toolUseId, name: tc.name } },\n },\n });\n const argsStr = parseConverseToolArgumentsForStream(tc, logger);\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n blockIndex++;\n }\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"tool_use\") },\n });\n const usage = converseUsage(overrides);\n events.push({\n eventType: \"metadata\",\n payload: { usage, metrics: { latencyMs: 0 } },\n });\n return events;\n}\n\nfunction buildBedrockStreamToolCallEvents(\n toolCalls: ToolCall[],\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 { eventType: \"messageStart\", payload: { role: \"assistant\" } },\n ];\n\n // A leading reasoning block occupies contentBlockIndex 0, shifting the\n // toolUse blocks by +1 (mirrors the content+tool builder's sequencing).\n if (reasoning) {\n const reasoningBlockIndex = 0;\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: reasoningBlockIndex, start: { reasoningContent: {} } },\n });\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: reasoningBlockIndex,\n delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: reasoningBlockIndex },\n });\n }\n\n const toolBlockOffset = reasoning ? 1 : 0;\n\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const blockIndex = tcIdx + toolBlockOffset;\n const tc = toolCalls[tcIdx];\n const toolUseId = tc.id || generateToolUseId();\n events.push({\n eventType: \"contentBlockStart\",\n payload: {\n contentBlockIndex: blockIndex,\n start: { toolUse: { toolUseId, name: tc.name } },\n },\n });\n const argsStr = parseConverseToolArgumentsForStream(tc, logger);\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n }\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"tool_use\") },\n });\n const usage = converseUsage(overrides);\n events.push({\n eventType: \"metadata\",\n payload: { usage, metrics: { latencyMs: 0 } },\n });\n return events;\n}\n\n// ─── Input conversion: Converse → ChatCompletionRequest ─────────────────────\n\nexport function converseToCompletionRequest(\n req: ConverseRequest,\n modelId: string,\n logger?: Logger,\n): ChatCompletionRequest {\n const messages: ChatMessage[] = [];\n\n // system field → system message\n if (req.system && req.system.length > 0) {\n const systemText = req.system.map((s) => s.text).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 toolResult blocks\n const toolResults = msg.content.filter((b) => b.toolResult);\n const textBlocks = msg.content.filter(\n (b) => b.text !== undefined && b.text !== \"\" && !b.toolResult,\n );\n const unsupportedBlocks = msg.content.filter(\n (b) => b.text === undefined && !b.toolResult && !b.toolUse,\n );\n if (unsupportedBlocks.length > 0 && logger) {\n logger.warn(\n `Converse user message contains unsupported content block types — these will be dropped during conversion`,\n );\n }\n\n if (toolResults.length > 0) {\n for (const block of toolResults) {\n const tr = block.toolResult!;\n const resultContent = tr.content.map((c) => c.text ?? \"\").join(\"\");\n messages.push({\n role: \"tool\",\n content: resultContent,\n tool_call_id: tr.toolUseId,\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 // Plain user message\n const text = msg.content\n .filter((b) => b.text !== undefined && b.text !== \"\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n messages.push({ role: \"user\", content: text });\n } else if (msg.role === \"assistant\") {\n const toolUseBlocks = msg.content.filter((b) => b.toolUse);\n const textContent = msg.content\n .filter((b) => b.text !== undefined && b.text !== \"\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\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.toolUse!.toolUseId,\n type: \"function\" as const,\n function: {\n name: b.toolUse!.name,\n arguments: JSON.stringify(b.toolUse!.input),\n },\n })),\n });\n } else {\n messages.push({ role: \"assistant\", content: textContent || null });\n }\n } else {\n const warnMsg = `Unexpected message role \"${msg.role}\" in Converse request — skipping`;\n if (logger) {\n logger.warn(warnMsg);\n }\n }\n }\n\n // Convert tools\n let tools: ToolDefinition[] | undefined;\n if (req.toolConfig?.tools && req.toolConfig.tools.length > 0) {\n tools = req.toolConfig.tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.toolSpec.name,\n description: t.toolSpec.description,\n parameters: (t.toolSpec.inputSchema && \"json\" in t.toolSpec.inputSchema\n ? (t.toolSpec.inputSchema as Record<string, unknown>).json\n : t.toolSpec.inputSchema) as object | undefined,\n },\n }));\n }\n\n return {\n model: modelId,\n messages,\n stream: false,\n temperature: req.inferenceConfig?.temperature,\n max_tokens: req.inferenceConfig?.maxTokens,\n tools,\n };\n}\n\n// ─── Response builders ──────────────────────────────────────────────────────\n\nfunction buildConverseTextResponse(\n content: string,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({\n reasoningContent: { reasoningText: { text: reasoning } },\n });\n }\n contentBlocks.push({ text: content });\n\n return {\n output: {\n message: {\n role: \"assistant\",\n content: contentBlocks,\n },\n },\n stopReason: converseStopReason(overrides?.finishReason, \"end_turn\"),\n usage: converseUsage(overrides),\n metrics: { latencyMs: 0 },\n };\n}\n\nfunction buildConverseToolCallResponse(\n toolCalls: ToolCall[],\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({\n reasoningContent: { reasoningText: { text: reasoning } },\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 toolUse: {\n toolUseId: tc.id || generateToolUseId(),\n name: tc.name,\n input: argsObj,\n },\n });\n }\n\n return {\n output: {\n message: {\n role: \"assistant\",\n content: contentBlocks,\n },\n },\n stopReason: converseStopReason(overrides?.finishReason, \"tool_use\"),\n usage: converseUsage(overrides),\n metrics: { latencyMs: 0 },\n };\n}\n\nfunction buildConverseContentWithToolCallsResponse(\n content: string,\n toolCalls: ToolCall[],\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n blocks?: FixtureBlock[],\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({\n reasoningContent: { reasoningText: { text: reasoning } },\n });\n }\n\n // Build a Converse `toolUse` content block from a fixture tool call, parsing\n // its string `arguments` into the object `input` Converse emits (warning on\n // malformed JSON — same idiom as the legacy/streaming paths).\n const toolUseBlock = (tc: { name: string; arguments: string; id?: string }): object => {\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 return {\n toolUse: {\n toolUseId: tc.id || generateToolUseId(),\n name: tc.name,\n input: argsObj,\n },\n };\n };\n\n if (blocks && blocks.length > 0) {\n // NEW PATH: the non-streaming `content[]` array is positionally observable,\n // so emit `text`/`toolUse` content blocks in the fixture's ARRAY ORDER\n // (after any leading reasoning block). A toolCall block before a text block\n // therefore yields a toolUse ahead of the text — matching the streaming\n // path for the same `blocks` fixture.\n const ordered = resolveFixtureBlocks(blocks);\n for (const block of ordered) {\n if (block.type === \"text\") {\n contentBlocks.push({ text: block.text });\n } else {\n contentBlocks.push(\n toolUseBlock({ name: block.name, arguments: block.arguments, id: block.id }),\n );\n }\n }\n } else {\n // LEGACY PATH (unchanged): text content block, then toolUse blocks in\n // `toolCalls` order.\n contentBlocks.push({ text: content });\n for (const tc of toolCalls) {\n contentBlocks.push(toolUseBlock(tc));\n }\n }\n\n return {\n output: {\n message: {\n role: \"assistant\",\n content: contentBlocks,\n },\n },\n stopReason: converseStopReason(overrides?.finishReason, \"tool_use\"),\n usage: converseUsage(overrides),\n metrics: { latencyMs: 0 },\n };\n}\n\n// ─── Request handlers ───────────────────────────────────────────────────────\n\nexport async function handleConverse(\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}/converse`;\n\n let converseReq: ConverseRequest;\n try {\n converseReq = JSON.parse(raw) as ConverseRequest;\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 (!converseReq.messages || !Array.isArray(converseReq.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 = converseToCompletionRequest(converseReq, 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 const errBody = {\n type: \"error\",\n error: {\n type: response.error.type ?? \"invalid_request_error\",\n message: response.error.message,\n },\n };\n writeErrorResponse(res, status, JSON.stringify(errBody), {\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 = buildConverseContentWithToolCallsResponse(\n response.content ?? \"\",\n response.toolCalls ?? [],\n logger,\n effReasoning,\n overrides,\n response.blocks,\n );\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\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 Bedrock Converse API — ignoring\",\n );\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 = buildConverseTextResponse(response.content, effReasoning, overrides);\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 = buildConverseToolCallResponse(response.toolCalls, logger, effReasoning, overrides);\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\nexport async function handleConverseStream(\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}/converse-stream`;\n\n let converseReq: ConverseRequest;\n try {\n converseReq = JSON.parse(raw) as ConverseRequest;\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 (!converseReq.messages || !Array.isArray(converseReq.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 = converseToCompletionRequest(converseReq, 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 const errBody = {\n type: \"error\",\n error: {\n type: response.error.type ?? \"invalid_request_error\",\n message: response.error.message,\n },\n };\n writeErrorResponse(res, status, JSON.stringify(errBody), {\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 chunkSize,\n logger,\n effReasoning,\n overrides,\n response.blocks,\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 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-converse.js","names":[],"sources":["../src/bedrock-converse.ts"],"sourcesContent":["/**\n * AWS Bedrock Converse API support.\n *\n * Translates incoming Converse and Converse-stream requests (Bedrock Converse\n * format) into the ChatCompletionRequest format used by the fixture router,\n * and converts fixture responses back into Converse API format — either a\n * single JSON response or an Event Stream binary stream.\n */\n\nimport type * as http from \"node:http\";\nimport type {\n ChatCompletionRequest,\n ChatMessage,\n Fixture,\n FixtureBlock,\n HandlerDefaults,\n ResponseOverrides,\n ToolCall,\n ToolDefinition,\n} from \"./types.js\";\nimport {\n generateToolUseId,\n extractOverrides,\n isTextResponse,\n isToolCallResponse,\n isContentWithToolCallsResponse,\n resolveFixtureBlocks,\n isErrorResponse,\n flattenHeaders,\n isJsonObject,\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// ─── Converse request types ─────────────────────────────────────────────────\n\ninterface ConverseContentBlock {\n text?: string;\n toolUse?: { toolUseId: string; name: string; input: object };\n toolResult?: { toolUseId: string; content: { text?: string }[] };\n}\n\ninterface ConverseMessage {\n role: \"user\" | \"assistant\";\n content: ConverseContentBlock[];\n}\n\ninterface ConverseToolSpec {\n name: string;\n description?: string;\n inputSchema?: object;\n}\n\ninterface ConverseRequest {\n messages: ConverseMessage[];\n system?: { text: string }[];\n inferenceConfig?: { maxTokens?: number; temperature?: number };\n toolConfig?: { tools: { toolSpec: ConverseToolSpec }[] };\n}\n\n// ─── Converse stop_reason mapping ──────────────────────────────────────────\n\nfunction converseStopReason(\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 Converse-format usage from fixture overrides.\n *\n * When no overrides are provided (the common case for mocks), all token\n * counts default to zero. This is intentional — aimock is a mock server\n * and does not perform real tokenisation. Callers that need non-zero\n * usage should supply explicit `usage` overrides in their fixture.\n */\nfunction converseUsage(overrides?: ResponseOverrides): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n} {\n if (!overrides?.usage) return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n const inputTokens = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;\n const outputTokens = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;\n return { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens };\n}\n\nfunction parseConverseToolArgumentsForStream(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\nfunction buildBedrockStreamTextEvents(\n content: 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 { eventType: \"messageStart\", payload: { role: \"assistant\" } },\n ];\n\n if (reasoning) {\n const blockIndex = 0;\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: blockIndex, start: { reasoningContent: {} } },\n });\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n }\n\n const textBlockIndex = reasoning ? 1 : 0;\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: textBlockIndex, start: {} },\n });\n for (let i = 0; i < content.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: textBlockIndex,\n delta: { text: content.slice(i, i + chunkSize) },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: textBlockIndex },\n });\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"end_turn\") },\n });\n const usage = converseUsage(overrides);\n events.push({\n eventType: \"metadata\",\n payload: { usage, metrics: { latencyMs: 0 } },\n });\n return events;\n}\n\nfunction buildBedrockStreamContentWithToolCallsEvents(\n content: string,\n toolCalls: ToolCall[],\n chunkSize: number,\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n blocks?: FixtureBlock[],\n): Array<{ eventType: string; payload: object }> {\n if (blocks && blocks.length > 0) {\n // NEW PATH: stream `text`/`toolUse` content blocks in the fixture's array\n // order. Converse's indexed contentBlock events make ordering observable —\n // a `toolCall` block can take a lower `contentBlockIndex` than a `text`\n // block. Indices are assigned in encounter order, continuing from any\n // leading reasoning block (which occupies index 0).\n const events: Array<{ eventType: string; payload: object }> = [\n { eventType: \"messageStart\", payload: { role: \"assistant\" } },\n ];\n\n let blockIndex = 0;\n if (reasoning) {\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: blockIndex, start: { reasoningContent: {} } },\n });\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n blockIndex++;\n }\n\n const ordered = resolveFixtureBlocks(blocks);\n for (const block of ordered) {\n if (block.type === \"text\") {\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: blockIndex, start: {} },\n });\n for (let i = 0; i < block.text.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { text: block.text.slice(i, i + chunkSize) },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n } else {\n const toolUseId = block.id || generateToolUseId();\n events.push({\n eventType: \"contentBlockStart\",\n payload: {\n contentBlockIndex: blockIndex,\n start: { toolUse: { toolUseId, name: block.name } },\n },\n });\n const argsStr = parseConverseToolArgumentsForStream(\n { name: block.name, arguments: block.arguments } as ToolCall,\n logger,\n );\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n }\n blockIndex++;\n }\n\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"tool_use\") },\n });\n events.push({\n eventType: \"metadata\",\n payload: { usage: converseUsage(overrides), metrics: { latencyMs: 0 } },\n });\n return events;\n }\n\n const events = buildBedrockStreamTextEvents(content, chunkSize, reasoning, overrides);\n // Remove trailing metadata + messageStop events — we re-emit them after tool blocks\n for (let i = events.length - 1; i >= 0; i--) {\n const et = (events[i] as { eventType: string }).eventType;\n if (et === \"metadata\" || et === \"messageStop\") {\n events.splice(i, 1);\n }\n }\n let blockIndex = reasoning ? 2 : 1;\n\n for (const tc of toolCalls) {\n const toolUseId = tc.id || generateToolUseId();\n events.push({\n eventType: \"contentBlockStart\",\n payload: {\n contentBlockIndex: blockIndex,\n start: { toolUse: { toolUseId, name: tc.name } },\n },\n });\n const argsStr = parseConverseToolArgumentsForStream(tc, logger);\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n blockIndex++;\n }\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"tool_use\") },\n });\n const usage = converseUsage(overrides);\n events.push({\n eventType: \"metadata\",\n payload: { usage, metrics: { latencyMs: 0 } },\n });\n return events;\n}\n\nfunction buildBedrockStreamToolCallEvents(\n toolCalls: ToolCall[],\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 { eventType: \"messageStart\", payload: { role: \"assistant\" } },\n ];\n\n // A leading reasoning block occupies contentBlockIndex 0, shifting the\n // toolUse blocks by +1 (mirrors the content+tool builder's sequencing).\n if (reasoning) {\n const reasoningBlockIndex = 0;\n events.push({\n eventType: \"contentBlockStart\",\n payload: { contentBlockIndex: reasoningBlockIndex, start: { reasoningContent: {} } },\n });\n for (let i = 0; i < reasoning.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: reasoningBlockIndex,\n delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: reasoningBlockIndex },\n });\n }\n\n const toolBlockOffset = reasoning ? 1 : 0;\n\n for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {\n const blockIndex = tcIdx + toolBlockOffset;\n const tc = toolCalls[tcIdx];\n const toolUseId = tc.id || generateToolUseId();\n events.push({\n eventType: \"contentBlockStart\",\n payload: {\n contentBlockIndex: blockIndex,\n start: { toolUse: { toolUseId, name: tc.name } },\n },\n });\n const argsStr = parseConverseToolArgumentsForStream(tc, logger);\n for (let i = 0; i < argsStr.length; i += chunkSize) {\n events.push({\n eventType: \"contentBlockDelta\",\n payload: {\n contentBlockIndex: blockIndex,\n delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } },\n },\n });\n }\n events.push({\n eventType: \"contentBlockStop\",\n payload: { contentBlockIndex: blockIndex },\n });\n }\n events.push({\n eventType: \"messageStop\",\n payload: { stopReason: converseStopReason(overrides?.finishReason, \"tool_use\") },\n });\n const usage = converseUsage(overrides);\n events.push({\n eventType: \"metadata\",\n payload: { usage, metrics: { latencyMs: 0 } },\n });\n return events;\n}\n\n// ─── Input conversion: Converse → ChatCompletionRequest ─────────────────────\n\nexport function converseToCompletionRequest(\n req: ConverseRequest,\n modelId: string,\n logger?: Logger,\n): ChatCompletionRequest {\n const messages: ChatMessage[] = [];\n\n // system field → system message\n if (req.system && req.system.length > 0) {\n const systemText = req.system.map((s) => s.text).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 toolResult blocks\n const toolResults = msg.content.filter((b) => b.toolResult);\n const textBlocks = msg.content.filter(\n (b) => b.text !== undefined && b.text !== \"\" && !b.toolResult,\n );\n const unsupportedBlocks = msg.content.filter(\n (b) => b.text === undefined && !b.toolResult && !b.toolUse,\n );\n if (unsupportedBlocks.length > 0 && logger) {\n logger.warn(\n `Converse user message contains unsupported content block types — these will be dropped during conversion`,\n );\n }\n\n if (toolResults.length > 0) {\n for (const block of toolResults) {\n const tr = block.toolResult!;\n const resultContent = tr.content.map((c) => c.text ?? \"\").join(\"\");\n messages.push({\n role: \"tool\",\n content: resultContent,\n tool_call_id: tr.toolUseId,\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 // Plain user message\n const text = msg.content\n .filter((b) => b.text !== undefined && b.text !== \"\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n messages.push({ role: \"user\", content: text });\n } else if (msg.role === \"assistant\") {\n const toolUseBlocks = msg.content.filter((b) => b.toolUse);\n const textContent = msg.content\n .filter((b) => b.text !== undefined && b.text !== \"\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\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.toolUse!.toolUseId,\n type: \"function\" as const,\n function: {\n name: b.toolUse!.name,\n arguments: JSON.stringify(b.toolUse!.input),\n },\n })),\n });\n } else {\n messages.push({ role: \"assistant\", content: textContent || null });\n }\n } else {\n const warnMsg = `Unexpected message role \"${msg.role}\" in Converse request — skipping`;\n if (logger) {\n logger.warn(warnMsg);\n }\n }\n }\n\n // Convert tools\n let tools: ToolDefinition[] | undefined;\n if (req.toolConfig?.tools && req.toolConfig.tools.length > 0) {\n tools = req.toolConfig.tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.toolSpec.name,\n description: t.toolSpec.description,\n parameters: (t.toolSpec.inputSchema && \"json\" in t.toolSpec.inputSchema\n ? (t.toolSpec.inputSchema as Record<string, unknown>).json\n : t.toolSpec.inputSchema) as object | undefined,\n },\n }));\n }\n\n return {\n model: modelId,\n messages,\n stream: false,\n temperature: req.inferenceConfig?.temperature,\n max_tokens: req.inferenceConfig?.maxTokens,\n tools,\n };\n}\n\n// ─── Response builders ──────────────────────────────────────────────────────\n\nfunction buildConverseTextResponse(\n content: string,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({\n reasoningContent: { reasoningText: { text: reasoning } },\n });\n }\n contentBlocks.push({ text: content });\n\n return {\n output: {\n message: {\n role: \"assistant\",\n content: contentBlocks,\n },\n },\n stopReason: converseStopReason(overrides?.finishReason, \"end_turn\"),\n usage: converseUsage(overrides),\n metrics: { latencyMs: 0 },\n };\n}\n\nfunction buildConverseToolCallResponse(\n toolCalls: ToolCall[],\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({\n reasoningContent: { reasoningText: { text: reasoning } },\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 toolUse: {\n toolUseId: tc.id || generateToolUseId(),\n name: tc.name,\n input: argsObj,\n },\n });\n }\n\n return {\n output: {\n message: {\n role: \"assistant\",\n content: contentBlocks,\n },\n },\n stopReason: converseStopReason(overrides?.finishReason, \"tool_use\"),\n usage: converseUsage(overrides),\n metrics: { latencyMs: 0 },\n };\n}\n\nfunction buildConverseContentWithToolCallsResponse(\n content: string,\n toolCalls: ToolCall[],\n logger: Logger,\n reasoning?: string,\n overrides?: ResponseOverrides,\n blocks?: FixtureBlock[],\n): object {\n const contentBlocks: object[] = [];\n if (reasoning) {\n contentBlocks.push({\n reasoningContent: { reasoningText: { text: reasoning } },\n });\n }\n\n // Build a Converse `toolUse` content block from a fixture tool call, parsing\n // its string `arguments` into the object `input` Converse emits (warning on\n // malformed JSON — same idiom as the legacy/streaming paths).\n const toolUseBlock = (tc: { name: string; arguments: string; id?: string }): object => {\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 return {\n toolUse: {\n toolUseId: tc.id || generateToolUseId(),\n name: tc.name,\n input: argsObj,\n },\n };\n };\n\n if (blocks && blocks.length > 0) {\n // NEW PATH: the non-streaming `content[]` array is positionally observable,\n // so emit `text`/`toolUse` content blocks in the fixture's ARRAY ORDER\n // (after any leading reasoning block). A toolCall block before a text block\n // therefore yields a toolUse ahead of the text — matching the streaming\n // path for the same `blocks` fixture.\n const ordered = resolveFixtureBlocks(blocks);\n for (const block of ordered) {\n if (block.type === \"text\") {\n contentBlocks.push({ text: block.text });\n } else {\n contentBlocks.push(\n toolUseBlock({ name: block.name, arguments: block.arguments, id: block.id }),\n );\n }\n }\n } else {\n // LEGACY PATH (unchanged): text content block, then toolUse blocks in\n // `toolCalls` order.\n contentBlocks.push({ text: content });\n for (const tc of toolCalls) {\n contentBlocks.push(toolUseBlock(tc));\n }\n }\n\n return {\n output: {\n message: {\n role: \"assistant\",\n content: contentBlocks,\n },\n },\n stopReason: converseStopReason(overrides?.finishReason, \"tool_use\"),\n usage: converseUsage(overrides),\n metrics: { latencyMs: 0 },\n };\n}\n\n// ─── Request handlers ───────────────────────────────────────────────────────\n\nexport async function handleConverse(\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}/converse`;\n\n let converseReq: ConverseRequest;\n try {\n converseReq = JSON.parse(raw) as ConverseRequest;\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 // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `converseReq.messages` throws a TypeError that\n // surfaces as a 500 instead of a 400.\n if (!isJsonObject(converseReq)) {\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: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n if (!converseReq.messages || !Array.isArray(converseReq.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 = converseToCompletionRequest(converseReq, 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 req.url,\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 const errBody = {\n type: \"error\",\n error: {\n type: response.error.type ?? \"invalid_request_error\",\n message: response.error.message,\n },\n };\n writeErrorResponse(res, status, JSON.stringify(errBody), {\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 = buildConverseContentWithToolCallsResponse(\n response.content ?? \"\",\n response.toolCalls ?? [],\n logger,\n effReasoning,\n overrides,\n response.blocks,\n );\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\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 Bedrock Converse API — ignoring\",\n );\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 = buildConverseTextResponse(response.content, effReasoning, overrides);\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 = buildConverseToolCallResponse(response.toolCalls, logger, effReasoning, overrides);\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\nexport async function handleConverseStream(\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}/converse-stream`;\n\n let converseReq: ConverseRequest;\n try {\n converseReq = JSON.parse(raw) as ConverseRequest;\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 // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `converseReq.messages` throws a TypeError that\n // surfaces as a 500 instead of a 400.\n if (!isJsonObject(converseReq)) {\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: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n if (!converseReq.messages || !Array.isArray(converseReq.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 = converseToCompletionRequest(converseReq, 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 req.url,\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 const errBody = {\n type: \"error\",\n error: {\n type: response.error.type ?? \"invalid_request_error\",\n message: response.error.message,\n },\n };\n writeErrorResponse(res, status, JSON.stringify(errBody), {\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 chunkSize,\n logger,\n effReasoning,\n overrides,\n response.blocks,\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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 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(\n \"webSearches in fixture response are not supported for Bedrock Converse API — ignoring\",\n );\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 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/bedrock.cjs
CHANGED
|
@@ -34,13 +34,14 @@ function bedrockUsage(overrides) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
function extractTextContent(content) {
|
|
37
|
+
if (content === null || content === void 0) return "";
|
|
37
38
|
if (typeof content === "string") return content;
|
|
38
|
-
return content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
|
|
39
|
+
return content.filter((b) => b !== null && b !== void 0 && b.type === "text").map((b) => b.text ?? "").join("");
|
|
39
40
|
}
|
|
40
41
|
function bedrockToCompletionRequest(req, modelId, logger) {
|
|
41
42
|
const messages = [];
|
|
42
43
|
if (req.system) {
|
|
43
|
-
const systemText = typeof req.system === "string" ? req.system : req.system.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
|
|
44
|
+
const systemText = typeof req.system === "string" ? req.system : Array.isArray(req.system) ? req.system.filter((b) => b !== null && b !== void 0 && b.type === "text").map((b) => b.text ?? "").join("") : "";
|
|
44
45
|
if (systemText) messages.push({
|
|
45
46
|
role: "system",
|
|
46
47
|
content: systemText
|
|
@@ -48,16 +49,16 @@ function bedrockToCompletionRequest(req, modelId, logger) {
|
|
|
48
49
|
}
|
|
49
50
|
for (const msg of req.messages) if (msg.role === "user") {
|
|
50
51
|
if (typeof msg.content !== "string" && Array.isArray(msg.content)) {
|
|
51
|
-
const unsupportedBlocks = msg.content.filter((b) => b.type !== "text" && b.type !== "tool_result");
|
|
52
|
+
const unsupportedBlocks = msg.content.filter((b) => b === null || b === void 0 || b.type !== "text" && b.type !== "tool_result");
|
|
52
53
|
if (unsupportedBlocks.length > 0 && logger) {
|
|
53
54
|
const types = [...new Set(unsupportedBlocks.map((b) => b.type))].join(", ");
|
|
54
55
|
logger.warn(`Bedrock user message contains unsupported content block types [${types}] — these will be dropped during conversion`);
|
|
55
56
|
}
|
|
56
|
-
const toolResults = msg.content.filter((b) => b.type === "tool_result");
|
|
57
|
-
const textBlocks = msg.content.filter((b) => b.type === "text");
|
|
57
|
+
const toolResults = msg.content.filter((b) => b !== null && b !== void 0 && b.type === "tool_result");
|
|
58
|
+
const textBlocks = msg.content.filter((b) => b !== null && b !== void 0 && b.type === "text");
|
|
58
59
|
if (toolResults.length > 0) {
|
|
59
60
|
for (const tr of toolResults) {
|
|
60
|
-
const resultContent = typeof tr.content === "string" ? tr.content : Array.isArray(tr.content) ? tr.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("") : "";
|
|
61
|
+
const resultContent = typeof tr.content === "string" ? tr.content : Array.isArray(tr.content) ? tr.content.filter((b) => b !== null && b !== void 0 && b.type === "text").map((b) => b.text ?? "").join("") : "";
|
|
61
62
|
messages.push({
|
|
62
63
|
role: "tool",
|
|
63
64
|
content: resultContent,
|
|
@@ -80,7 +81,7 @@ function bedrockToCompletionRequest(req, modelId, logger) {
|
|
|
80
81
|
content: msg.content
|
|
81
82
|
});
|
|
82
83
|
else if (Array.isArray(msg.content)) {
|
|
83
|
-
const toolUseBlocks = msg.content.filter((b) => b.type === "tool_use");
|
|
84
|
+
const toolUseBlocks = msg.content.filter((b) => b !== null && b !== void 0 && b.type === "tool_use");
|
|
84
85
|
const textContent = extractTextContent(msg.content);
|
|
85
86
|
if (toolUseBlocks.length > 0) messages.push({
|
|
86
87
|
role: "assistant",
|
|
@@ -253,7 +254,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
|
|
|
253
254
|
} }));
|
|
254
255
|
return;
|
|
255
256
|
}
|
|
256
|
-
if (!
|
|
257
|
+
if (!require_helpers.isJsonObject(bedrockReq)) {
|
|
257
258
|
journal.add({
|
|
258
259
|
method: req.method ?? "POST",
|
|
259
260
|
path: urlPath,
|
|
@@ -265,7 +266,25 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
|
|
|
265
266
|
}
|
|
266
267
|
});
|
|
267
268
|
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
268
|
-
message: "
|
|
269
|
+
message: "Request body must be a JSON object",
|
|
270
|
+
type: "invalid_request_error"
|
|
271
|
+
} }));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const bedrockShapeError = require_helpers.validateChatMessages(bedrockReq.messages, { checkToolCalls: false }) ?? require_helpers.validateToolsField(bedrockReq.tools) ?? (bedrockReq.system !== void 0 && bedrockReq.system !== null && typeof bedrockReq.system !== "string" && !Array.isArray(bedrockReq.system) ? "system must be a string or an array" : null);
|
|
275
|
+
if (bedrockShapeError) {
|
|
276
|
+
journal.add({
|
|
277
|
+
method: req.method ?? "POST",
|
|
278
|
+
path: urlPath,
|
|
279
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
280
|
+
body: null,
|
|
281
|
+
response: {
|
|
282
|
+
status: 400,
|
|
283
|
+
fixture: null
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
287
|
+
message: `Invalid request: ${bedrockShapeError}`,
|
|
269
288
|
type: "invalid_request_error"
|
|
270
289
|
} }));
|
|
271
290
|
return;
|
|
@@ -278,7 +297,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
|
|
|
278
297
|
if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
279
298
|
else logger.debug(`No fixture matched for request`);
|
|
280
299
|
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
281
|
-
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
|
|
300
|
+
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, req.url, journal, {
|
|
282
301
|
method: req.method ?? "POST",
|
|
283
302
|
path: urlPath,
|
|
284
303
|
headers: require_helpers.flattenHeaders(req.headers),
|
|
@@ -912,7 +931,25 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
|
|
|
912
931
|
} }));
|
|
913
932
|
return;
|
|
914
933
|
}
|
|
915
|
-
if (!
|
|
934
|
+
if (!require_helpers.isJsonObject(bedrockReq)) {
|
|
935
|
+
journal.add({
|
|
936
|
+
method: req.method ?? "POST",
|
|
937
|
+
path: urlPath,
|
|
938
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
939
|
+
body: null,
|
|
940
|
+
response: {
|
|
941
|
+
status: 400,
|
|
942
|
+
fixture: null
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
946
|
+
message: "Request body must be a JSON object",
|
|
947
|
+
type: "invalid_request_error"
|
|
948
|
+
} }));
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
const bedrockShapeError = require_helpers.validateChatMessages(bedrockReq.messages, { checkToolCalls: false }) ?? require_helpers.validateToolsField(bedrockReq.tools) ?? (bedrockReq.system !== void 0 && bedrockReq.system !== null && typeof bedrockReq.system !== "string" && !Array.isArray(bedrockReq.system) ? "system must be a string or an array" : null);
|
|
952
|
+
if (bedrockShapeError) {
|
|
916
953
|
journal.add({
|
|
917
954
|
method: req.method ?? "POST",
|
|
918
955
|
path: urlPath,
|
|
@@ -924,7 +961,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
|
|
|
924
961
|
}
|
|
925
962
|
});
|
|
926
963
|
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
927
|
-
message:
|
|
964
|
+
message: `Invalid request: ${bedrockShapeError}`,
|
|
928
965
|
type: "invalid_request_error"
|
|
929
966
|
} }));
|
|
930
967
|
return;
|
|
@@ -938,7 +975,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
|
|
|
938
975
|
if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
939
976
|
else logger.debug(`No fixture matched for request`);
|
|
940
977
|
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
941
|
-
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
|
|
978
|
+
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, req.url, journal, {
|
|
942
979
|
method: req.method ?? "POST",
|
|
943
980
|
path: urlPath,
|
|
944
981
|
headers: require_helpers.flattenHeaders(req.headers),
|