const require_helpers = require('./helpers.cjs');
const require_router = require('./router.cjs');
const require_sse_writer = require('./sse-writer.cjs');
const require_interruption = require('./interruption.cjs');
const require_chaos = require('./chaos.cjs');
const require_recorder = require('./recorder.cjs');
const require_aws_event_stream = require('./aws-event-stream.cjs');

//#region src/bedrock-converse.ts
function converseStopReason(overrideFinishReason, defaultReason) {
	if (!overrideFinishReason) return defaultReason;
	if (overrideFinishReason === "stop") return "end_turn";
	if (overrideFinishReason === "tool_calls") return "tool_use";
	if (overrideFinishReason === "length") return "max_tokens";
	return overrideFinishReason;
}
/**
* Build Converse-format usage from fixture overrides.
*
* When no overrides are provided (the common case for mocks), all token
* counts default to zero.  This is intentional — aimock is a mock server
* and does not perform real tokenisation.  Callers that need non-zero
* usage should supply explicit `usage` overrides in their fixture.
*/
function converseUsage(overrides) {
	if (!overrides?.usage) return {
		inputTokens: 0,
		outputTokens: 0,
		totalTokens: 0
	};
	const inputTokens = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;
	const outputTokens = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;
	return {
		inputTokens,
		outputTokens,
		totalTokens: inputTokens + outputTokens
	};
}
function parseConverseToolArgumentsForStream(toolCall, logger) {
	try {
		const parsed = JSON.parse(toolCall.arguments || "{}");
		return JSON.stringify(parsed);
	} catch {
		logger.warn(`Malformed JSON in fixture tool call arguments for "${toolCall.name}": ${toolCall.arguments}`);
		return "{}";
	}
}
function buildBedrockStreamTextEvents(content, chunkSize, reasoning, overrides) {
	const events = [{
		eventType: "messageStart",
		payload: { role: "assistant" }
	}];
	if (reasoning) {
		const blockIndex = 0;
		events.push({
			eventType: "contentBlockStart",
			payload: {
				contentBlockIndex: blockIndex,
				start: { reasoningContent: {} }
			}
		});
		for (let i = 0; i < reasoning.length; i += chunkSize) events.push({
			eventType: "contentBlockDelta",
			payload: {
				contentBlockIndex: blockIndex,
				delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } }
			}
		});
		events.push({
			eventType: "contentBlockStop",
			payload: { contentBlockIndex: blockIndex }
		});
	}
	const textBlockIndex = reasoning ? 1 : 0;
	events.push({
		eventType: "contentBlockStart",
		payload: {
			contentBlockIndex: textBlockIndex,
			start: {}
		}
	});
	for (let i = 0; i < content.length; i += chunkSize) events.push({
		eventType: "contentBlockDelta",
		payload: {
			contentBlockIndex: textBlockIndex,
			delta: { text: content.slice(i, i + chunkSize) }
		}
	});
	events.push({
		eventType: "contentBlockStop",
		payload: { contentBlockIndex: textBlockIndex }
	});
	events.push({
		eventType: "messageStop",
		payload: { stopReason: converseStopReason(overrides?.finishReason, "end_turn") }
	});
	const usage = converseUsage(overrides);
	events.push({
		eventType: "metadata",
		payload: {
			usage,
			metrics: { latencyMs: 0 }
		}
	});
	return events;
}
function buildBedrockStreamContentWithToolCallsEvents(content, toolCalls, chunkSize, logger, reasoning, overrides, blocks) {
	if (blocks && blocks.length > 0) {
		const events = [{
			eventType: "messageStart",
			payload: { role: "assistant" }
		}];
		let blockIndex = 0;
		if (reasoning) {
			events.push({
				eventType: "contentBlockStart",
				payload: {
					contentBlockIndex: blockIndex,
					start: { reasoningContent: {} }
				}
			});
			for (let i = 0; i < reasoning.length; i += chunkSize) events.push({
				eventType: "contentBlockDelta",
				payload: {
					contentBlockIndex: blockIndex,
					delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } }
				}
			});
			events.push({
				eventType: "contentBlockStop",
				payload: { contentBlockIndex: blockIndex }
			});
			blockIndex++;
		}
		const ordered = require_helpers.resolveFixtureBlocks(blocks);
		for (const block of ordered) {
			if (block.type === "text") {
				events.push({
					eventType: "contentBlockStart",
					payload: {
						contentBlockIndex: blockIndex,
						start: {}
					}
				});
				for (let i = 0; i < block.text.length; i += chunkSize) events.push({
					eventType: "contentBlockDelta",
					payload: {
						contentBlockIndex: blockIndex,
						delta: { text: block.text.slice(i, i + chunkSize) }
					}
				});
				events.push({
					eventType: "contentBlockStop",
					payload: { contentBlockIndex: blockIndex }
				});
			} else {
				const toolUseId = block.id || require_helpers.generateToolUseId();
				events.push({
					eventType: "contentBlockStart",
					payload: {
						contentBlockIndex: blockIndex,
						start: { toolUse: {
							toolUseId,
							name: block.name
						} }
					}
				});
				const argsStr = parseConverseToolArgumentsForStream({
					name: block.name,
					arguments: block.arguments
				}, logger);
				for (let i = 0; i < argsStr.length; i += chunkSize) events.push({
					eventType: "contentBlockDelta",
					payload: {
						contentBlockIndex: blockIndex,
						delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } }
					}
				});
				events.push({
					eventType: "contentBlockStop",
					payload: { contentBlockIndex: blockIndex }
				});
			}
			blockIndex++;
		}
		events.push({
			eventType: "messageStop",
			payload: { stopReason: converseStopReason(overrides?.finishReason, "tool_use") }
		});
		events.push({
			eventType: "metadata",
			payload: {
				usage: converseUsage(overrides),
				metrics: { latencyMs: 0 }
			}
		});
		return events;
	}
	const events = buildBedrockStreamTextEvents(content, chunkSize, reasoning, overrides);
	for (let i = events.length - 1; i >= 0; i--) {
		const et = events[i].eventType;
		if (et === "metadata" || et === "messageStop") events.splice(i, 1);
	}
	let blockIndex = reasoning ? 2 : 1;
	for (const tc of toolCalls) {
		const toolUseId = tc.id || require_helpers.generateToolUseId();
		events.push({
			eventType: "contentBlockStart",
			payload: {
				contentBlockIndex: blockIndex,
				start: { toolUse: {
					toolUseId,
					name: tc.name
				} }
			}
		});
		const argsStr = parseConverseToolArgumentsForStream(tc, logger);
		for (let i = 0; i < argsStr.length; i += chunkSize) events.push({
			eventType: "contentBlockDelta",
			payload: {
				contentBlockIndex: blockIndex,
				delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } }
			}
		});
		events.push({
			eventType: "contentBlockStop",
			payload: { contentBlockIndex: blockIndex }
		});
		blockIndex++;
	}
	events.push({
		eventType: "messageStop",
		payload: { stopReason: converseStopReason(overrides?.finishReason, "tool_use") }
	});
	const usage = converseUsage(overrides);
	events.push({
		eventType: "metadata",
		payload: {
			usage,
			metrics: { latencyMs: 0 }
		}
	});
	return events;
}
function buildBedrockStreamToolCallEvents(toolCalls, chunkSize, logger, reasoning, overrides) {
	const events = [{
		eventType: "messageStart",
		payload: { role: "assistant" }
	}];
	if (reasoning) {
		const reasoningBlockIndex = 0;
		events.push({
			eventType: "contentBlockStart",
			payload: {
				contentBlockIndex: reasoningBlockIndex,
				start: { reasoningContent: {} }
			}
		});
		for (let i = 0; i < reasoning.length; i += chunkSize) events.push({
			eventType: "contentBlockDelta",
			payload: {
				contentBlockIndex: reasoningBlockIndex,
				delta: { reasoningContent: { text: reasoning.slice(i, i + chunkSize) } }
			}
		});
		events.push({
			eventType: "contentBlockStop",
			payload: { contentBlockIndex: reasoningBlockIndex }
		});
	}
	const toolBlockOffset = reasoning ? 1 : 0;
	for (let tcIdx = 0; tcIdx < toolCalls.length; tcIdx++) {
		const blockIndex = tcIdx + toolBlockOffset;
		const tc = toolCalls[tcIdx];
		const toolUseId = tc.id || require_helpers.generateToolUseId();
		events.push({
			eventType: "contentBlockStart",
			payload: {
				contentBlockIndex: blockIndex,
				start: { toolUse: {
					toolUseId,
					name: tc.name
				} }
			}
		});
		const argsStr = parseConverseToolArgumentsForStream(tc, logger);
		for (let i = 0; i < argsStr.length; i += chunkSize) events.push({
			eventType: "contentBlockDelta",
			payload: {
				contentBlockIndex: blockIndex,
				delta: { toolUse: { input: argsStr.slice(i, i + chunkSize) } }
			}
		});
		events.push({
			eventType: "contentBlockStop",
			payload: { contentBlockIndex: blockIndex }
		});
	}
	events.push({
		eventType: "messageStop",
		payload: { stopReason: converseStopReason(overrides?.finishReason, "tool_use") }
	});
	const usage = converseUsage(overrides);
	events.push({
		eventType: "metadata",
		payload: {
			usage,
			metrics: { latencyMs: 0 }
		}
	});
	return events;
}
function converseToCompletionRequest(req, modelId, logger) {
	const messages = [];
	if (req.system && req.system.length > 0) {
		const systemText = req.system.map((s) => s.text).join("");
		if (systemText) messages.push({
			role: "system",
			content: systemText
		});
	}
	for (const msg of req.messages) if (msg.role === "user") {
		const toolResults = msg.content.filter((b) => b.toolResult);
		const textBlocks = msg.content.filter((b) => b.text !== void 0 && b.text !== "" && !b.toolResult);
		if (msg.content.filter((b) => b.text === void 0 && !b.toolResult && !b.toolUse).length > 0 && logger) logger.warn(`Converse user message contains unsupported content block types — these will be dropped during conversion`);
		if (toolResults.length > 0) {
			for (const block of toolResults) {
				const tr = block.toolResult;
				const resultContent = tr.content.map((c) => c.text ?? "").join("");
				messages.push({
					role: "tool",
					content: resultContent,
					tool_call_id: tr.toolUseId
				});
			}
			if (textBlocks.length > 0) messages.push({
				role: "user",
				content: textBlocks.map((b) => b.text ?? "").join("")
			});
			continue;
		}
		const text = msg.content.filter((b) => b.text !== void 0 && b.text !== "").map((b) => b.text ?? "").join("");
		messages.push({
			role: "user",
			content: text
		});
	} else if (msg.role === "assistant") {
		const toolUseBlocks = msg.content.filter((b) => b.toolUse);
		const textContent = msg.content.filter((b) => b.text !== void 0 && b.text !== "").map((b) => b.text ?? "").join("");
		if (toolUseBlocks.length > 0) messages.push({
			role: "assistant",
			content: textContent || null,
			tool_calls: toolUseBlocks.map((b) => ({
				id: b.toolUse.toolUseId,
				type: "function",
				function: {
					name: b.toolUse.name,
					arguments: JSON.stringify(b.toolUse.input)
				}
			}))
		});
		else messages.push({
			role: "assistant",
			content: textContent || null
		});
	} else {
		const warnMsg = `Unexpected message role "${msg.role}" in Converse request — skipping`;
		if (logger) logger.warn(warnMsg);
	}
	let tools;
	if (req.toolConfig?.tools && req.toolConfig.tools.length > 0) tools = req.toolConfig.tools.map((t) => ({
		type: "function",
		function: {
			name: t.toolSpec.name,
			description: t.toolSpec.description,
			parameters: t.toolSpec.inputSchema && "json" in t.toolSpec.inputSchema ? t.toolSpec.inputSchema.json : t.toolSpec.inputSchema
		}
	}));
	return {
		model: modelId,
		messages,
		stream: false,
		temperature: req.inferenceConfig?.temperature,
		max_tokens: req.inferenceConfig?.maxTokens,
		tools
	};
}
function buildConverseTextResponse(content, reasoning, overrides) {
	const contentBlocks = [];
	if (reasoning) contentBlocks.push({ reasoningContent: { reasoningText: { text: reasoning } } });
	contentBlocks.push({ text: content });
	return {
		output: { message: {
			role: "assistant",
			content: contentBlocks
		} },
		stopReason: converseStopReason(overrides?.finishReason, "end_turn"),
		usage: converseUsage(overrides),
		metrics: { latencyMs: 0 }
	};
}
function buildConverseToolCallResponse(toolCalls, logger, reasoning, overrides) {
	const contentBlocks = [];
	if (reasoning) contentBlocks.push({ reasoningContent: { reasoningText: { text: reasoning } } });
	for (const tc of toolCalls) {
		let argsObj;
		try {
			argsObj = JSON.parse(tc.arguments || "{}");
		} catch {
			logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
			argsObj = {};
		}
		contentBlocks.push({ toolUse: {
			toolUseId: tc.id || require_helpers.generateToolUseId(),
			name: tc.name,
			input: argsObj
		} });
	}
	return {
		output: { message: {
			role: "assistant",
			content: contentBlocks
		} },
		stopReason: converseStopReason(overrides?.finishReason, "tool_use"),
		usage: converseUsage(overrides),
		metrics: { latencyMs: 0 }
	};
}
function buildConverseContentWithToolCallsResponse(content, toolCalls, logger, reasoning, overrides, blocks) {
	const contentBlocks = [];
	if (reasoning) contentBlocks.push({ reasoningContent: { reasoningText: { text: reasoning } } });
	const toolUseBlock = (tc) => {
		let argsObj;
		try {
			argsObj = JSON.parse(tc.arguments || "{}");
		} catch {
			logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
			argsObj = {};
		}
		return { toolUse: {
			toolUseId: tc.id || require_helpers.generateToolUseId(),
			name: tc.name,
			input: argsObj
		} };
	};
	if (blocks && blocks.length > 0) {
		const ordered = require_helpers.resolveFixtureBlocks(blocks);
		for (const block of ordered) if (block.type === "text") contentBlocks.push({ text: block.text });
		else contentBlocks.push(toolUseBlock({
			name: block.name,
			arguments: block.arguments,
			id: block.id
		}));
	} else {
		contentBlocks.push({ text: content });
		for (const tc of toolCalls) contentBlocks.push(toolUseBlock(tc));
	}
	return {
		output: { message: {
			role: "assistant",
			content: contentBlocks
		} },
		stopReason: converseStopReason(overrides?.finishReason, "tool_use"),
		usage: converseUsage(overrides),
		metrics: { latencyMs: 0 }
	};
}
async function handleConverse(req, res, raw, modelId, fixtures, journal, defaults, setCorsHeaders) {
	const { logger } = defaults;
	setCorsHeaders(res);
	const urlPath = req.url ?? `/model/${modelId}/converse`;
	let converseReq;
	try {
		converseReq = JSON.parse(raw);
	} catch (parseErr) {
		const detail = parseErr instanceof Error ? parseErr.message : "unknown";
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: null,
			response: {
				status: 400,
				fixture: null
			}
		});
		require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
			message: `Malformed JSON: ${detail}`,
			type: "invalid_request_error"
		} }));
		return;
	}
	if (!converseReq.messages || !Array.isArray(converseReq.messages)) {
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: null,
			response: {
				status: 400,
				fixture: null
			}
		});
		require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
			message: "Invalid request: messages array is required",
			type: "invalid_request_error"
		} }));
		return;
	}
	const completionReq = converseToCompletionRequest(converseReq, modelId, logger);
	completionReq._endpointType = "chat";
	completionReq._context = require_helpers.getContext(req);
	const testId = require_helpers.getTestId(req);
	const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
	if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
	else logger.debug(`No fixture matched for request`);
	if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
	if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
		method: req.method ?? "POST",
		path: urlPath,
		headers: require_helpers.flattenHeaders(req.headers),
		body: completionReq
	}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
	if (!fixture) {
		if (require_helpers.resolveStrictMode(defaults.strict, req.headers)) {
			const strictStatus = 503;
			const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
			logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", urlPath, skippedBySequenceOrTurn));
			journal.add({
				method: req.method ?? "POST",
				path: urlPath,
				headers: require_helpers.flattenHeaders(req.headers),
				body: completionReq,
				response: {
					status: strictStatus,
					fixture: null,
					...require_helpers.strictOverrideField(defaults.strict, req.headers)
				}
			});
			require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
				message: strictMessage,
				type: "invalid_request_error"
			} }));
			return;
		}
		if (defaults.record) {
			const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, "bedrock", urlPath, fixtures, defaults, raw);
			if (outcome === "handled_by_hook") return;
			if (outcome !== "not_configured") {
				journal.add({
					method: req.method ?? "POST",
					path: urlPath,
					headers: require_helpers.flattenHeaders(req.headers),
					body: completionReq,
					response: {
						status: res.statusCode ?? 200,
						fixture: null,
						source: "proxy"
					}
				});
				return;
			}
		}
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 404,
				fixture: null,
				...require_helpers.strictOverrideField(defaults.strict, req.headers)
			}
		});
		require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
			message: "No fixture matched",
			type: "invalid_request_error"
		} }));
		return;
	}
	const response = await require_helpers.resolveResponse(fixture, completionReq);
	if (require_helpers.isErrorResponse(response)) {
		const status = response.status ?? 500;
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status,
				fixture
			}
		});
		const errBody = {
			type: "error",
			error: {
				type: response.error.type ?? "invalid_request_error",
				message: response.error.message
			}
		};
		require_sse_writer.writeErrorResponse(res, status, JSON.stringify(errBody), { retryAfter: response.retryAfter });
		return;
	}
	if (require_helpers.isContentWithToolCallsResponse(response)) {
		if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock Converse API — ignoring");
		const overrides = require_helpers.extractOverrides(response);
		const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		const body = buildConverseContentWithToolCallsResponse(response.content ?? "", response.toolCalls ?? [], logger, effReasoning, overrides, response.blocks);
		res.writeHead(200, { "Content-Type": "application/json" });
		res.end(JSON.stringify(body));
		return;
	}
	if (require_helpers.isTextResponse(response)) {
		if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock Converse API — ignoring");
		const overrides = require_helpers.extractOverrides(response);
		const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		const body = buildConverseTextResponse(response.content, effReasoning, overrides);
		res.writeHead(200, { "Content-Type": "application/json" });
		res.end(JSON.stringify(body));
		return;
	}
	if (require_helpers.isToolCallResponse(response)) {
		if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock Converse API — ignoring");
		const overrides = require_helpers.extractOverrides(response);
		const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		const body = buildConverseToolCallResponse(response.toolCalls, logger, effReasoning, overrides);
		res.writeHead(200, { "Content-Type": "application/json" });
		res.end(JSON.stringify(body));
		return;
	}
	journal.add({
		method: req.method ?? "POST",
		path: urlPath,
		headers: require_helpers.flattenHeaders(req.headers),
		body: completionReq,
		response: {
			status: 500,
			fixture
		}
	});
	require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
		message: "Fixture response did not match any known type",
		type: "server_error"
	} }));
}
async function handleConverseStream(req, res, raw, modelId, fixtures, journal, defaults, setCorsHeaders) {
	const { logger } = defaults;
	setCorsHeaders(res);
	const urlPath = req.url ?? `/model/${modelId}/converse-stream`;
	let converseReq;
	try {
		converseReq = JSON.parse(raw);
	} catch (parseErr) {
		const detail = parseErr instanceof Error ? parseErr.message : "unknown";
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: null,
			response: {
				status: 400,
				fixture: null
			}
		});
		require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
			message: `Malformed JSON: ${detail}`,
			type: "invalid_request_error"
		} }));
		return;
	}
	if (!converseReq.messages || !Array.isArray(converseReq.messages)) {
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: null,
			response: {
				status: 400,
				fixture: null
			}
		});
		require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
			message: "Invalid request: messages array is required",
			type: "invalid_request_error"
		} }));
		return;
	}
	const completionReq = converseToCompletionRequest(converseReq, modelId, logger);
	completionReq.stream = true;
	completionReq._endpointType = "chat";
	completionReq._context = require_helpers.getContext(req);
	const testId = require_helpers.getTestId(req);
	const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
	if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
	else logger.debug(`No fixture matched for request`);
	if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
	if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
		method: req.method ?? "POST",
		path: urlPath,
		headers: require_helpers.flattenHeaders(req.headers),
		body: completionReq
	}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
	if (!fixture) {
		if (require_helpers.resolveStrictMode(defaults.strict, req.headers)) {
			const strictStatus = 503;
			const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
			logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", urlPath, skippedBySequenceOrTurn));
			journal.add({
				method: req.method ?? "POST",
				path: urlPath,
				headers: require_helpers.flattenHeaders(req.headers),
				body: completionReq,
				response: {
					status: strictStatus,
					fixture: null,
					...require_helpers.strictOverrideField(defaults.strict, req.headers)
				}
			});
			require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
				message: strictMessage,
				type: "invalid_request_error"
			} }));
			return;
		}
		if (defaults.record) {
			const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, "bedrock", urlPath, fixtures, defaults, raw);
			if (outcome === "handled_by_hook") return;
			if (outcome !== "not_configured") {
				journal.add({
					method: req.method ?? "POST",
					path: urlPath,
					headers: require_helpers.flattenHeaders(req.headers),
					body: completionReq,
					response: {
						status: res.statusCode ?? 200,
						fixture: null,
						source: "proxy"
					}
				});
				return;
			}
		}
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 404,
				fixture: null,
				...require_helpers.strictOverrideField(defaults.strict, req.headers)
			}
		});
		require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
			message: "No fixture matched",
			type: "invalid_request_error"
		} }));
		return;
	}
	const response = await require_helpers.resolveResponse(fixture, completionReq);
	const latency = fixture.latency ?? defaults.latency;
	const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
	if (require_helpers.isErrorResponse(response)) {
		const status = response.status ?? 500;
		journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status,
				fixture
			}
		});
		const errBody = {
			type: "error",
			error: {
				type: response.error.type ?? "invalid_request_error",
				message: response.error.message
			}
		};
		require_sse_writer.writeErrorResponse(res, status, JSON.stringify(errBody), { retryAfter: response.retryAfter });
		return;
	}
	if (require_helpers.isContentWithToolCallsResponse(response)) {
		if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock Converse API — ignoring");
		const overrides = require_helpers.extractOverrides(response);
		const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
		const journalEntry = journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		const events = buildBedrockStreamContentWithToolCallsEvents(response.content ?? "", response.toolCalls ?? [], chunkSize, logger, effReasoning, overrides, response.blocks);
		const interruption = require_interruption.createInterruptionSignal(fixture);
		if (!await require_aws_event_stream.writeEventStream(res, events, {
			latency,
			streamingProfile: fixture.streamingProfile,
			recordedTimings: fixture.recordedTimings,
			replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
			signal: interruption?.signal,
			onChunkSent: interruption?.tick
		})) {
			if (!res.writableEnded) res.destroy();
			journalEntry.response.interrupted = true;
			journalEntry.response.interruptReason = interruption?.reason();
		}
		interruption?.cleanup();
		return;
	}
	if (require_helpers.isTextResponse(response)) {
		if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock Converse API — ignoring");
		const overrides = require_helpers.extractOverrides(response);
		const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
		const journalEntry = journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		const events = buildBedrockStreamTextEvents(response.content, chunkSize, effReasoning, overrides);
		const interruption = require_interruption.createInterruptionSignal(fixture);
		if (!await require_aws_event_stream.writeEventStream(res, events, {
			latency,
			streamingProfile: fixture.streamingProfile,
			recordedTimings: fixture.recordedTimings,
			replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
			signal: interruption?.signal,
			onChunkSent: interruption?.tick
		})) {
			if (!res.writableEnded) res.destroy();
			journalEntry.response.interrupted = true;
			journalEntry.response.interruptReason = interruption?.reason();
		}
		interruption?.cleanup();
		return;
	}
	if (require_helpers.isToolCallResponse(response)) {
		if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock Converse API — ignoring");
		const overrides = require_helpers.extractOverrides(response);
		const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
		const journalEntry = journal.add({
			method: req.method ?? "POST",
			path: urlPath,
			headers: require_helpers.flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		const events = buildBedrockStreamToolCallEvents(response.toolCalls, chunkSize, logger, effReasoning, overrides);
		const interruption = require_interruption.createInterruptionSignal(fixture);
		if (!await require_aws_event_stream.writeEventStream(res, events, {
			latency,
			streamingProfile: fixture.streamingProfile,
			recordedTimings: fixture.recordedTimings,
			replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
			signal: interruption?.signal,
			onChunkSent: interruption?.tick
		})) {
			if (!res.writableEnded) res.destroy();
			journalEntry.response.interrupted = true;
			journalEntry.response.interruptReason = interruption?.reason();
		}
		interruption?.cleanup();
		return;
	}
	journal.add({
		method: req.method ?? "POST",
		path: urlPath,
		headers: require_helpers.flattenHeaders(req.headers),
		body: completionReq,
		response: {
			status: 500,
			fixture
		}
	});
	require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
		message: "Fixture response did not match any known type",
		type: "server_error"
	} }));
}

//#endregion
exports.converseToCompletionRequest = converseToCompletionRequest;
exports.handleConverse = handleConverse;
exports.handleConverseStream = handleConverseStream;
//# sourceMappingURL=bedrock-converse.cjs.map