import { AIMessage, AIMessageChunk, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
//#region src/stream/assembled-to-message.ts
/**
* Convert the protocol-native {@link AssembledMessage} (a namespace +
* content-block bag) into a class instance from
* `@langchain/core/messages`.
*
* The v2 messages channel carries `role` on the `message-start`
* event, but `MessageAssembler` drops it by the time it produces an
* `AssembledMessage`. The selector-side caller therefore captures the
* role separately (via the assembler's per-update hook, see
* `projections/messages.ts`) and passes it in.
*
* The conversion is intentionally lossless in the limit: when the
* message finishes we emit the same BaseMessage shape that a
* `values.messages` entry would round-trip to via
* {@link tryCoerceMessageLikeToMessage}. Mid-stream, partial blocks
* (e.g. tool_call_chunk) are folded into the same shape so the UI
* can render an incrementally-completing message.
*/
/**
* Produce a `BaseMessage` class instance from an in-progress or
* finished assembled message. Safe to call repeatedly across deltas —
* each call returns a new instance whose content reflects the
* currently-observed blocks.
*/
function assembledToBaseMessage(input) {
	const { id, role, blocks, toolCallId, usage } = input;
	const textContent = extractContentString(blocks);
	const toolCalls = extractToolCalls(blocks);
	const toolCallChunks = extractToolCallChunks(blocks);
	const additionalKwargs = usage != null ? { usage } : void 0;
	switch (role) {
		case "human": return new HumanMessage({
			...id != null ? { id } : {},
			content: textContent,
			...additionalKwargs != null ? { additional_kwargs: additionalKwargs } : {}
		});
		case "system": return new SystemMessage({
			...id != null ? { id } : {},
			content: textContent,
			...additionalKwargs != null ? { additional_kwargs: additionalKwargs } : {}
		});
		case "tool": return new ToolMessage({
			...id != null ? { id } : {},
			content: textContent,
			tool_call_id: toolCallId ?? ""
		});
		default: {
			const payload = {
				...id != null ? { id } : {},
				content: cloneContentBlocks(blocks),
				...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
				...toolCallChunks.length > 0 ? { tool_call_chunks: toolCallChunks } : {},
				...additionalKwargs != null ? { additional_kwargs: additionalKwargs } : {},
				response_metadata: { output_version: "v1" }
			};
			return toolCallChunks.length > 0 ? new AIMessageChunk(payload) : new AIMessage(payload);
		}
	}
}
/**
* Convenience: given the raw assembled message + the role captured
* from `message-start`, produce a `BaseMessage` with the same id.
*/
function assembledMessageToBaseMessage(assembled, role, extras = {}) {
	return assembledToBaseMessage({
		id: assembled.id,
		role,
		blocks: assembled.blocks,
		toolCallId: extras.toolCallId,
		usage: assembled.usage
	});
}
function extractContentString(blocks) {
	let out = "";
	for (const block of blocks) if (block.type === "text" && typeof block.text === "string") out += block.text;
	return out;
}
function cloneContentBlocks(blocks) {
	return blocks.map((block) => structuredClone(block));
}
function extractToolCalls(blocks) {
	const out = [];
	for (const block of blocks) {
		if (block.type !== "tool_call" && block.type !== "tool_use") continue;
		const tc = block;
		out.push({
			id: tc.id ?? "",
			name: tc.name ?? "",
			args: normalizeToolCallArgs(tc.args ?? tc.input),
			type: "tool_call"
		});
	}
	return out;
}
function extractToolCallChunks(blocks) {
	const out = [];
	for (const block of blocks) {
		if (block.type !== "tool_call_chunk") continue;
		const tc = block;
		out.push({
			id: tc.id,
			name: tc.name,
			args: tc.args,
			index: tc.index,
			type: "tool_call_chunk"
		});
	}
	return out;
}
function normalizeToolCallArgs(value) {
	if (value != null && typeof value === "object" && !Array.isArray(value)) return value;
	if (typeof value === "string" && value.length > 0) try {
		const parsed = JSON.parse(value);
		if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
	} catch {}
	return {};
}
//#endregion
export { assembledMessageToBaseMessage, assembledToBaseMessage };

//# sourceMappingURL=assembled-to-message.js.map