import { extractOverrides, flattenHeaders, generateId, generateToolCallId, getContext, getTestId, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, resolveFixtureBlocks, resolveReasoningForModel, resolveResponse, resolveStrictMode, serializeErrorResponse, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField } from "./helpers.js";
import { matchFixtureDiagnostic, recordMatchOptions } from "./router.js";
import { calculateDelay, delay, writeErrorResponse } from "./sse-writer.js";
import { createInterruptionSignal } from "./interruption.js";
import { applyChaos } from "./chaos.js";
import { proxyAndRecord } from "./recorder.js";

//#region src/responses.ts
function extractTextContent(content) {
	if (!content) return "";
	if (typeof content === "string") return content;
	return content.filter((p) => p.type === "input_text" || p.type === "output_text").map((p) => p.text ?? "").join("");
}
function responsesInputToMessages(req) {
	const messages = [];
	const itemReferencePlaceholders = /* @__PURE__ */ new WeakSet();
	if (req.instructions) messages.push({
		role: "system",
		content: req.instructions
	});
	if (typeof req.input === "string") {
		messages.push({
			role: "user",
			content: req.input
		});
		return messages;
	}
	for (const item of req.input) if (item.role === "system" || item.role === "developer") messages.push({
		role: "system",
		content: extractTextContent(item.content)
	});
	else if (item.role === "user") messages.push({
		role: "user",
		content: extractTextContent(item.content)
	});
	else if (item.role === "assistant") messages.push({
		role: "assistant",
		content: extractTextContent(item.content)
	});
	else if (item.type === "function_call") messages.push({
		role: "assistant",
		content: null,
		tool_calls: [{
			id: item.call_id ?? generateToolCallId(),
			type: "function",
			function: {
				name: item.name ?? "",
				arguments: item.arguments ?? ""
			}
		}]
	});
	else if (item.type === "function_call_output") {
		if (!messages.some((m) => m.role === "assistant" && m.tool_calls?.some((tc) => tc.id === item.call_id))) {
			const lastMsg = messages[messages.length - 1];
			if (lastMsg && lastMsg.role === "assistant" && itemReferencePlaceholders.has(lastMsg) && !lastMsg.tool_calls) {
				lastMsg.content = null;
				lastMsg.tool_calls = [{
					id: item.call_id ?? generateToolCallId(),
					type: "function",
					function: {
						name: "",
						arguments: ""
					}
				}];
				itemReferencePlaceholders.delete(lastMsg);
			} else {
				let appended = false;
				for (let k = messages.length - 1; k >= 0; k--) {
					const m = messages[k];
					if (m.role === "assistant" && m.tool_calls) {
						m.tool_calls.push({
							id: item.call_id ?? generateToolCallId(),
							type: "function",
							function: {
								name: "",
								arguments: ""
							}
						});
						appended = true;
						break;
					}
					if (m.role === "user") break;
				}
				if (!appended) messages.push({
					role: "assistant",
					content: null,
					tool_calls: [{
						id: item.call_id ?? generateToolCallId(),
						type: "function",
						function: {
							name: "",
							arguments: ""
						}
					}]
				});
			}
		}
		messages.push({
			role: "tool",
			content: item.output ?? "",
			tool_call_id: item.call_id
		});
	} else if (item.type === "item_reference") {
		const placeholder = {
			role: "assistant",
			content: ""
		};
		itemReferencePlaceholders.add(placeholder);
		messages.push(placeholder);
	}
	return messages;
}
function responsesToolsToCompletionsTools(tools) {
	if (!tools || tools.length === 0) return void 0;
	return tools.filter((t) => t.type === "function").map((t) => ({
		type: "function",
		function: {
			name: t.name,
			description: t.description,
			parameters: t.parameters
		}
	}));
}
function responsesToCompletionRequest(req) {
	return {
		model: req.model,
		messages: responsesInputToMessages(req),
		stream: req.stream,
		temperature: req.temperature,
		max_tokens: req.max_output_tokens,
		tools: responsesToolsToCompletionsTools(req.tools),
		tool_choice: req.tool_choice,
		response_format: req.response_format
	};
}
function responsesStatus(finishReason, defaultStatus) {
	if (!finishReason) return defaultStatus;
	if (finishReason === "stop") return "completed";
	if (finishReason === "tool_calls") return "completed";
	if (finishReason === "length") return "incomplete";
	if (finishReason === "content_filter") return "failed";
	return finishReason;
}
function responsesUsage(overrides) {
	if (!overrides?.usage) return {
		input_tokens: 0,
		output_tokens: 0,
		total_tokens: 0
	};
	const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;
	const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;
	return {
		input_tokens: input,
		output_tokens: output,
		total_tokens: overrides.usage.total_tokens ?? input + output
	};
}
function responseId() {
	return generateId("resp");
}
function itemId() {
	return generateId("msg");
}
function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches, overrides) {
	const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides);
	const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
	events.push(...msgEvents);
	events.push({
		type: "response.completed",
		response: {
			id: respId,
			object: "response",
			created_at: created,
			model: overrides?.model ?? model,
			status: responsesStatus(overrides?.finishReason, "completed"),
			output: [...prefixOutputItems, msgItem],
			usage: responsesUsage(overrides)
		}
	});
	return events;
}
function buildToolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearches, overrides) {
	const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides);
	const fcOutputItems = [];
	for (let idx = 0; idx < toolCalls.length; idx++) {
		const tc = toolCalls[idx];
		const callId = tc.id || generateToolCallId();
		const fcId = generateId("fc");
		const outputIndex = nextOutputIndex + idx;
		events.push({
			type: "response.output_item.added",
			output_index: outputIndex,
			item: {
				type: "function_call",
				id: fcId,
				call_id: callId,
				name: tc.name,
				arguments: "",
				status: "in_progress"
			}
		});
		const args = tc.arguments;
		for (let i = 0; i < args.length; i += chunkSize) {
			const slice = args.slice(i, i + chunkSize);
			events.push({
				type: "response.function_call_arguments.delta",
				item_id: fcId,
				output_index: outputIndex,
				delta: slice
			});
		}
		events.push({
			type: "response.function_call_arguments.done",
			item_id: fcId,
			output_index: outputIndex,
			arguments: args
		});
		const doneItem = {
			type: "function_call",
			id: fcId,
			call_id: callId,
			name: tc.name,
			arguments: args,
			status: "completed"
		};
		events.push({
			type: "response.output_item.done",
			output_index: outputIndex,
			item: doneItem
		});
		fcOutputItems.push(doneItem);
	}
	events.push({
		type: "response.completed",
		response: {
			id: respId,
			object: "response",
			created_at: created,
			model: overrides?.model ?? model,
			status: responsesStatus(overrides?.finishReason, "completed"),
			output: [...prefixOutputItems, ...fcOutputItems],
			usage: responsesUsage(overrides)
		}
	});
	return events;
}
function buildReasoningStreamEvents(reasoning, model, chunkSize) {
	const reasoningId = generateId("rs");
	const events = [];
	events.push({
		type: "response.output_item.added",
		output_index: 0,
		item: {
			type: "reasoning",
			id: reasoningId,
			summary: []
		}
	});
	events.push({
		type: "response.reasoning_summary_part.added",
		item_id: reasoningId,
		output_index: 0,
		summary_index: 0,
		part: {
			type: "summary_text",
			text: ""
		}
	});
	for (let i = 0; i < reasoning.length; i += chunkSize) {
		const slice = reasoning.slice(i, i + chunkSize);
		events.push({
			type: "response.reasoning_summary_text.delta",
			item_id: reasoningId,
			output_index: 0,
			summary_index: 0,
			delta: slice
		});
	}
	events.push({
		type: "response.reasoning_summary_text.done",
		item_id: reasoningId,
		output_index: 0,
		summary_index: 0,
		text: reasoning
	});
	events.push({
		type: "response.reasoning_summary_part.done",
		item_id: reasoningId,
		output_index: 0,
		summary_index: 0,
		part: {
			type: "summary_text",
			text: reasoning
		}
	});
	events.push({
		type: "response.output_item.done",
		output_index: 0,
		item: {
			type: "reasoning",
			id: reasoningId,
			summary: [{
				type: "summary_text",
				text: reasoning
			}]
		}
	});
	return events;
}
function buildWebSearchStreamEvents(queries, startOutputIndex) {
	const events = [];
	for (let i = 0; i < queries.length; i++) {
		const searchId = generateId("ws");
		const outputIndex = startOutputIndex + i;
		events.push({
			type: "response.output_item.added",
			output_index: outputIndex,
			item: {
				type: "web_search_call",
				id: searchId,
				status: "in_progress",
				action: {
					type: "search",
					query: queries[i]
				}
			}
		});
		events.push({
			type: "response.output_item.done",
			output_index: outputIndex,
			item: {
				type: "web_search_call",
				id: searchId,
				status: "completed",
				action: {
					type: "search",
					query: queries[i]
				}
			}
		});
	}
	return events;
}
function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides) {
	const respId = overrides?.id ?? responseId();
	const created = overrides?.created ?? Math.floor(Date.now() / 1e3);
	const effectiveModel = overrides?.model ?? model;
	const events = [];
	const prefixOutputItems = [];
	let nextOutputIndex = 0;
	events.push({
		type: "response.created",
		response: {
			id: respId,
			object: "response",
			created_at: created,
			model: effectiveModel,
			status: "in_progress",
			output: []
		}
	});
	events.push({
		type: "response.in_progress",
		response: {
			id: respId,
			object: "response",
			created_at: created,
			model: effectiveModel,
			status: "in_progress",
			output: []
		}
	});
	if (reasoning) {
		const reasoningEvents = buildReasoningStreamEvents(reasoning, model, chunkSize);
		events.push(...reasoningEvents);
		const doneEvent = reasoningEvents.find((e) => e.type === "response.output_item.done" && e.item?.type === "reasoning");
		if (doneEvent) prefixOutputItems.push(doneEvent.item);
		nextOutputIndex++;
	}
	if (webSearches && webSearches.length > 0) {
		const searchEvents = buildWebSearchStreamEvents(webSearches, nextOutputIndex);
		events.push(...searchEvents);
		const doneEvents = searchEvents.filter((e) => e.type === "response.output_item.done" && e.item?.type === "web_search_call");
		for (const de of doneEvents) prefixOutputItems.push(de.item);
		nextOutputIndex += webSearches.length;
	}
	return {
		respId,
		created,
		events,
		prefixOutputItems,
		nextOutputIndex
	};
}
function buildMessageOutputEvents(content, chunkSize, outputIndex) {
	const msgId = itemId();
	const events = [];
	events.push({
		type: "response.output_item.added",
		output_index: outputIndex,
		item: {
			type: "message",
			id: msgId,
			status: "in_progress",
			role: "assistant",
			content: []
		}
	});
	events.push({
		type: "response.content_part.added",
		item_id: msgId,
		output_index: outputIndex,
		content_index: 0,
		part: {
			type: "output_text",
			text: "",
			annotations: []
		}
	});
	for (let i = 0; i < content.length; i += chunkSize) events.push({
		type: "response.output_text.delta",
		item_id: msgId,
		output_index: outputIndex,
		content_index: 0,
		delta: content.slice(i, i + chunkSize)
	});
	events.push({
		type: "response.output_text.done",
		item_id: msgId,
		output_index: outputIndex,
		content_index: 0,
		text: content
	});
	events.push({
		type: "response.content_part.done",
		item_id: msgId,
		output_index: outputIndex,
		content_index: 0,
		part: {
			type: "output_text",
			text: content,
			annotations: []
		}
	});
	const msgItem = {
		type: "message",
		id: msgId,
		status: "completed",
		role: "assistant",
		content: [{
			type: "output_text",
			text: content,
			annotations: []
		}]
	};
	events.push({
		type: "response.output_item.done",
		output_index: outputIndex,
		item: msgItem
	});
	return {
		events,
		msgItem
	};
}
/**
* Emit the output_item.added → arguments deltas → arguments.done →
* output_item.done events for a single function_call at `outputIndex`,
* returning the completed item for the final `output` array. Behavior is
* identical to the inline per-tool-call loop in the legacy path; both the
* legacy branch and the ordered-blocks branch share this so wire output stays
* byte-identical for a given (tool, outputIndex).
*/
function buildFunctionCallOutputEvents(toolCall, chunkSize, outputIndex) {
	const callId = toolCall.id || generateToolCallId();
	const fcId = generateId("fc");
	const args = toolCall.arguments;
	const events = [];
	events.push({
		type: "response.output_item.added",
		output_index: outputIndex,
		item: {
			type: "function_call",
			id: fcId,
			call_id: callId,
			name: toolCall.name,
			arguments: "",
			status: "in_progress"
		}
	});
	for (let i = 0; i < args.length; i += chunkSize) events.push({
		type: "response.function_call_arguments.delta",
		item_id: fcId,
		output_index: outputIndex,
		delta: args.slice(i, i + chunkSize)
	});
	events.push({
		type: "response.function_call_arguments.done",
		item_id: fcId,
		output_index: outputIndex,
		arguments: args
	});
	const fcItem = {
		type: "function_call",
		id: fcId,
		call_id: callId,
		name: toolCall.name,
		arguments: args,
		status: "completed"
	};
	events.push({
		type: "response.output_item.done",
		output_index: outputIndex,
		item: fcItem
	});
	return {
		events,
		fcItem
	};
}
function buildOutputPrefix(content, reasoning, webSearches) {
	const output = [];
	if (reasoning) output.push({
		type: "reasoning",
		id: generateId("rs"),
		summary: [{
			type: "summary_text",
			text: reasoning
		}]
	});
	if (webSearches && webSearches.length > 0) for (const query of webSearches) output.push({
		type: "web_search_call",
		id: generateId("ws"),
		status: "completed",
		action: {
			type: "search",
			query
		}
	});
	output.push({
		type: "message",
		id: itemId(),
		status: "completed",
		role: "assistant",
		content: [{
			type: "output_text",
			text: content,
			annotations: []
		}]
	});
	return output;
}
function buildResponseEnvelope(model, output, overrides) {
	return {
		id: overrides?.id ?? responseId(),
		object: "response",
		created_at: overrides?.created ?? Math.floor(Date.now() / 1e3),
		model: overrides?.model ?? model,
		status: responsesStatus(overrides?.finishReason, "completed"),
		output,
		usage: responsesUsage(overrides)
	};
}
function buildTextResponse(content, model, reasoning, webSearches, overrides) {
	return buildResponseEnvelope(model, buildOutputPrefix(content, reasoning, webSearches), overrides);
}
function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrides) {
	const output = [];
	if (reasoning) output.push({
		type: "reasoning",
		id: generateId("rs"),
		summary: [{
			type: "summary_text",
			text: reasoning
		}]
	});
	if (webSearches && webSearches.length > 0) for (const query of webSearches) output.push({
		type: "web_search_call",
		id: generateId("ws"),
		status: "completed",
		action: {
			type: "search",
			query
		}
	});
	for (const tc of toolCalls) output.push({
		type: "function_call",
		id: generateId("fc"),
		call_id: tc.id || generateToolCallId(),
		name: tc.name,
		arguments: tc.arguments,
		status: "completed"
	});
	return buildResponseEnvelope(model, output, overrides);
}
function buildContentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize, reasoning, webSearches, overrides, blocks) {
	const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides);
	const orderedOutputItems = [];
	if (blocks && blocks.length > 0) {
		const ordered = resolveFixtureBlocks(blocks);
		let outputIndex = nextOutputIndex;
		for (const block of ordered) {
			if (block.type === "text") {
				const { events: msgEvents, msgItem } = buildMessageOutputEvents(block.text, chunkSize, outputIndex);
				events.push(...msgEvents);
				orderedOutputItems.push(msgItem);
			} else {
				const { events: fcEvents, fcItem } = buildFunctionCallOutputEvents({
					name: block.name,
					arguments: block.arguments,
					id: block.id
				}, chunkSize, outputIndex);
				events.push(...fcEvents);
				orderedOutputItems.push(fcItem);
			}
			outputIndex += 1;
		}
	} else {
		const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
		events.push(...msgEvents);
		orderedOutputItems.push(msgItem);
		for (let idx = 0; idx < toolCalls.length; idx++) {
			const fcOutputIndex = nextOutputIndex + 1 + idx;
			const { events: fcEvents, fcItem } = buildFunctionCallOutputEvents(toolCalls[idx], chunkSize, fcOutputIndex);
			events.push(...fcEvents);
			orderedOutputItems.push(fcItem);
		}
	}
	events.push({
		type: "response.completed",
		response: {
			id: respId,
			object: "response",
			created_at: created,
			model: overrides?.model ?? model,
			status: responsesStatus(overrides?.finishReason, "completed"),
			output: [...prefixOutputItems, ...orderedOutputItems],
			usage: responsesUsage(overrides)
		}
	});
	return events;
}
function buildFunctionCallOutputItem(tc) {
	return {
		type: "function_call",
		id: generateId("fc"),
		call_id: tc.id || generateToolCallId(),
		name: tc.name,
		arguments: tc.arguments,
		status: "completed"
	};
}
function buildMessageOutputItem(content) {
	return {
		type: "message",
		id: itemId(),
		status: "completed",
		role: "assistant",
		content: [{
			type: "output_text",
			text: content,
			annotations: []
		}]
	};
}
function buildContentWithToolCallsResponse(content, toolCalls, model, reasoning, webSearches, overrides, blocks) {
	if (blocks && blocks.length > 0) {
		const ordered = resolveFixtureBlocks(blocks);
		const output = [];
		if (reasoning) output.push({
			type: "reasoning",
			id: generateId("rs"),
			summary: [{
				type: "summary_text",
				text: reasoning
			}]
		});
		if (webSearches && webSearches.length > 0) for (const query of webSearches) output.push({
			type: "web_search_call",
			id: generateId("ws"),
			status: "completed",
			action: {
				type: "search",
				query
			}
		});
		for (const block of ordered) if (block.type === "text") output.push(buildMessageOutputItem(block.text));
		else output.push(buildFunctionCallOutputItem({
			name: block.name,
			arguments: block.arguments,
			id: block.id
		}));
		return buildResponseEnvelope(model, output, overrides);
	}
	const output = buildOutputPrefix(content, reasoning, webSearches);
	for (const tc of toolCalls) output.push(buildFunctionCallOutputItem(tc));
	return buildResponseEnvelope(model, output, overrides);
}
async function writeResponsesSSEStream(res, events, optionsOrLatency) {
	const opts = typeof optionsOrLatency === "number" ? { latency: optionsOrLatency } : optionsOrLatency ?? {};
	const latency = opts.latency ?? 0;
	const profile = opts.streamingProfile;
	const { recordedTimings, replaySpeed } = opts;
	const signal = opts.signal;
	const onChunkSent = opts.onChunkSent;
	if (res.writableEnded) return true;
	res.setHeader("Content-Type", "text/event-stream");
	res.setHeader("Cache-Control", "no-cache");
	res.setHeader("Connection", "keep-alive");
	let chunkIndex = 0;
	for (const event of events) {
		const chunkDelay = calculateDelay(chunkIndex, profile, latency, recordedTimings, replaySpeed);
		if (chunkDelay > 0) await delay(chunkDelay, signal);
		if (signal?.aborted) return false;
		if (res.writableEnded) return true;
		res.write(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
		onChunkSent?.();
		if (signal?.aborted) return false;
		chunkIndex++;
	}
	if (!res.writableEnded) res.end();
	return true;
}
async function handleResponses(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
	setCorsHeaders(res);
	let responsesReq;
	try {
		responsesReq = JSON.parse(raw);
	} catch (parseErr) {
		const detail = parseErr instanceof Error ? parseErr.message : "unknown";
		journal.add({
			method: req.method ?? "POST",
			path: req.url ?? "/v1/responses",
			headers: flattenHeaders(req.headers),
			body: null,
			response: {
				status: 400,
				fixture: null
			}
		});
		writeErrorResponse(res, 400, JSON.stringify({ error: {
			message: `Malformed JSON: ${detail}`,
			type: "invalid_request_error",
			code: "invalid_json"
		} }));
		return;
	}
	const completionReq = responsesToCompletionRequest(responsesReq);
	completionReq._endpointType = "chat";
	completionReq._context = getContext(req);
	const testId = getTestId(req);
	const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, recordMatchOptions(!!defaults.record, defaults.logger));
	if (fixture) {
		defaults.logger.debug(`Responses fixture matched for ${req.method ?? "POST"} ${req.url ?? "/v1/responses"}`);
		journal.incrementFixtureMatchCount(fixture, fixtures, testId);
	} else defaults.logger.debug(`No responses fixture matched for ${req.method ?? "POST"} ${req.url ?? "/v1/responses"}`);
	if (applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
		method: req.method ?? "POST",
		path: req.url ?? "/v1/responses",
		headers: flattenHeaders(req.headers),
		body: completionReq
	}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
	if (!fixture) {
		if (resolveStrictMode(defaults.strict, req.headers)) {
			const strictStatus = 503;
			const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);
			defaults.logger.error(strictNoMatchLogLine(req.method ?? "POST", req.url ?? "/v1/responses", skippedBySequenceOrTurn));
			journal.add({
				method: req.method ?? "POST",
				path: req.url ?? "/v1/responses",
				headers: flattenHeaders(req.headers),
				body: completionReq,
				response: {
					status: strictStatus,
					fixture: null,
					...strictOverrideField(defaults.strict, req.headers)
				}
			});
			writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
				message: strictMessage,
				type: "invalid_request_error",
				code: "no_fixture_match"
			} }));
			return;
		}
		if (defaults.record) {
			const outcome = await proxyAndRecord(req, res, completionReq, "openai", req.url ?? "/v1/responses", fixtures, defaults, raw);
			if (outcome === "handled_by_hook") return;
			if (outcome !== "not_configured") {
				journal.add({
					method: req.method ?? "POST",
					path: req.url ?? "/v1/responses",
					headers: flattenHeaders(req.headers),
					body: completionReq,
					response: {
						status: res.statusCode ?? 200,
						fixture: null,
						source: "proxy"
					}
				});
				return;
			}
		}
		journal.add({
			method: req.method ?? "POST",
			path: req.url ?? "/v1/responses",
			headers: flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 404,
				fixture: null,
				...strictOverrideField(defaults.strict, req.headers)
			}
		});
		writeErrorResponse(res, 404, JSON.stringify({ error: {
			message: "No fixture matched",
			type: "invalid_request_error",
			code: "no_fixture_match"
		} }));
		return;
	}
	const response = await resolveResponse(fixture, completionReq);
	const latency = fixture.latency ?? defaults.latency;
	const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
	const fixtureTimings = fixture.recordedTimings;
	const effectiveReplaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
	if (isErrorResponse(response)) {
		const status = response.status ?? 500;
		journal.add({
			method: req.method ?? "POST",
			path: req.url ?? "/v1/responses",
			headers: flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status,
				fixture
			}
		});
		writeErrorResponse(res, status, serializeErrorResponse(response), { retryAfter: response.retryAfter });
		return;
	}
	if (isContentWithToolCallsResponse(response)) {
		const overrides = extractOverrides(response);
		const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
		const effReasoning = resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
		const journalEntry = journal.add({
			method: req.method ?? "POST",
			path: req.url ?? "/v1/responses",
			headers: flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		if (responsesReq.stream !== true) {
			const body = buildContentWithToolCallsResponse(response.content ?? "", response.toolCalls ?? [], completionReq.model, effReasoning, response.webSearches, overrides, response.blocks);
			res.writeHead(200, { "Content-Type": "application/json" });
			res.end(JSON.stringify(body));
		} else {
			const events = buildContentWithToolCallsStreamEvents(response.content ?? "", response.toolCalls ?? [], completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, response.blocks);
			const interruption = createInterruptionSignal(fixture);
			if (!await writeResponsesSSEStream(res, events, {
				latency,
				streamingProfile: fixture.streamingProfile,
				recordedTimings: fixtureTimings,
				replaySpeed: effectiveReplaySpeed,
				signal: interruption?.signal,
				onChunkSent: interruption?.tick
			})) {
				if (!res.writableEnded) res.destroy();
				journalEntry.response.interrupted = true;
				journalEntry.response.interruptReason = interruption?.reason();
			}
			interruption?.cleanup();
		}
		return;
	}
	if (isTextResponse(response)) {
		const overrides = extractOverrides(response);
		const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
		const effReasoning = resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
		const journalEntry = journal.add({
			method: req.method ?? "POST",
			path: req.url ?? "/v1/responses",
			headers: flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		if (responsesReq.stream !== true) {
			const body = buildTextResponse(response.content, completionReq.model, effReasoning, response.webSearches, overrides);
			res.writeHead(200, { "Content-Type": "application/json" });
			res.end(JSON.stringify(body));
		} else {
			const events = buildTextStreamEvents(response.content, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides);
			const interruption = createInterruptionSignal(fixture);
			if (!await writeResponsesSSEStream(res, events, {
				latency,
				streamingProfile: fixture.streamingProfile,
				recordedTimings: fixtureTimings,
				replaySpeed: effectiveReplaySpeed,
				signal: interruption?.signal,
				onChunkSent: interruption?.tick
			})) {
				if (!res.writableEnded) res.destroy();
				journalEntry.response.interrupted = true;
				journalEntry.response.interruptReason = interruption?.reason();
			}
			interruption?.cleanup();
		}
		return;
	}
	if (isToolCallResponse(response)) {
		const overrides = extractOverrides(response);
		const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
		const effReasoning = resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
		const journalEntry = journal.add({
			method: req.method ?? "POST",
			path: req.url ?? "/v1/responses",
			headers: flattenHeaders(req.headers),
			body: completionReq,
			response: {
				status: 200,
				fixture
			}
		});
		if (responsesReq.stream !== true) {
			const body = buildToolCallResponse(response.toolCalls, completionReq.model, effReasoning, response.webSearches, overrides);
			res.writeHead(200, { "Content-Type": "application/json" });
			res.end(JSON.stringify(body));
		} else {
			const events = buildToolCallStreamEvents(response.toolCalls, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides);
			const interruption = createInterruptionSignal(fixture);
			if (!await writeResponsesSSEStream(res, events, {
				latency,
				streamingProfile: fixture.streamingProfile,
				recordedTimings: fixtureTimings,
				replaySpeed: effectiveReplaySpeed,
				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: req.url ?? "/v1/responses",
		headers: flattenHeaders(req.headers),
		body: completionReq,
		response: {
			status: 500,
			fixture
		}
	});
	writeErrorResponse(res, 500, JSON.stringify({ error: {
		message: "Fixture response did not match any known type",
		type: "server_error"
	} }));
}

//#endregion
export { buildContentWithToolCallsStreamEvents, buildTextStreamEvents, buildToolCallStreamEvents, handleResponses, responsesToCompletionRequest };
//# sourceMappingURL=responses.js.map