require("../constants.cjs");
let _langchain_core_messages = require("@langchain/core/messages");
let _langchain_core_callbacks_base = require("@langchain/core/callbacks/base");
//#region src/pregel/messages-v2.ts
function getResponseMetadata(message) {
	if ("response_metadata" in message && typeof message.response_metadata === "object" && message.response_metadata != null) return message.response_metadata;
}
function getUsageMetadata(message) {
	if ("usage_metadata" in message && typeof message.usage_metadata === "object" && message.usage_metadata != null) return message.usage_metadata;
}
function startBlockFor(block) {
	switch (block.type) {
		case "text": return {
			type: "text",
			text: ""
		};
		case "reasoning": return {
			type: "reasoning",
			reasoning: ""
		};
		case "tool_call":
		case "tool_call_chunk": return {
			type: "tool_call_chunk",
			...block.id != null ? { id: block.id } : {},
			...block.name != null ? { name: block.name } : {},
			args: ""
		};
		default: return block;
	}
}
function deltaFor(block) {
	switch (block.type) {
		case "text": {
			const text = typeof block.text === "string" ? block.text : "";
			return text.length > 0 ? {
				event: "content-block-delta",
				index: typeof block.index === "number" ? block.index : 0,
				delta: {
					type: "text-delta",
					text
				}
			} : void 0;
		}
		case "reasoning": {
			const reasoning = typeof block.reasoning === "string" ? block.reasoning : "";
			return reasoning.length > 0 ? {
				event: "content-block-delta",
				index: typeof block.index === "number" ? block.index : 0,
				delta: {
					type: "reasoning-delta",
					reasoning
				}
			} : void 0;
		}
		case "tool_call_chunk": return {
			event: "content-block-delta",
			index: typeof block.index === "number" ? block.index : 0,
			delta: {
				type: "block-delta",
				fields: {
					...block,
					type: "tool_call_chunk"
				}
			}
		};
		default: return;
	}
}
/**
* A callback handler that implements protocol-native stream_mode=messages.
*
* LangChain Core owns chat model content-block event construction. This handler
* only captures LangGraph metadata, forwards Core events to the Pregel messages
* channel, and emits a small non-streaming fallback for models that cannot
* produce stream events.
*/
var StreamProtocolMessagesHandler = class extends _langchain_core_callbacks_base.BaseCallbackHandler {
	name = "StreamProtocolMessagesHandler";
	streamFn;
	metadatas = {};
	seen = {};
	streamedRunIds = /* @__PURE__ */ new Set();
	stableMessageIdMap = {};
	lc_prefer_chat_model_stream_events = true;
	awaitHandlers = true;
	constructor(streamFn) {
		super();
		this.streamFn = streamFn;
	}
	normalizeMessageId(message, runId) {
		let messageId = message.id;
		if (runId != null) if (_langchain_core_messages.ToolMessage.isInstance(message)) messageId ??= `run-${runId}-tool-${message.tool_call_id}`;
		else {
			if (messageId == null || messageId === `run-${runId}`) messageId = this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;
			this.stableMessageIdMap[runId] ??= messageId;
		}
		if (messageId !== message.id) {
			message.id = messageId;
			message.lc_kwargs.id = messageId;
		}
		if (message.id != null) this.seen[message.id] = message;
		return message.id;
	}
	emit(meta, data, runId) {
		const metadata = runId != null ? {
			...meta[1],
			run_id: runId
		} : meta[1];
		this.streamFn([
			meta[0],
			"messages",
			[data, metadata]
		]);
	}
	emitFinalMessage(meta, message, runId, dedupe = false) {
		const existingId = message.id ?? (runId != null ? this.stableMessageIdMap[runId] : void 0);
		if (dedupe && existingId != null && this.seen[existingId] !== void 0) return;
		const messageId = this.normalizeMessageId(message, runId);
		const role = message.type === "human" ? "human" : message.type === "system" ? "system" : message.type === "tool" ? "tool" : "ai";
		const toolCallId = role === "tool" && _langchain_core_messages.ToolMessage.isInstance(message) ? message.tool_call_id : void 0;
		this.emit(meta, {
			event: "message-start",
			...messageId != null ? { id: messageId } : {},
			...role !== "ai" ? { role } : {},
			...typeof toolCallId === "string" ? { tool_call_id: toolCallId } : {}
		}, runId);
		(Array.isArray(message.content) ? message.content : typeof message.content === "string" && message.content.length > 0 ? [{
			type: "text",
			text: message.content
		}] : []).forEach((block, offset) => {
			const index = typeof block.index === "number" ? block.index : offset;
			this.emit(meta, {
				event: "content-block-start",
				index,
				content: startBlockFor(block)
			}, runId);
			const delta = deltaFor({
				...block,
				index
			});
			if (delta != null) this.emit(meta, delta, runId);
			this.emit(meta, {
				event: "content-block-finish",
				index,
				content: block
			}, runId);
		});
		this.emit(meta, {
			event: "message-finish",
			...getUsageMetadata(message) != null ? { usage: getUsageMetadata(message) } : {},
			...getResponseMetadata(message) != null ? { responseMetadata: getResponseMetadata(message) } : {}
		}, runId);
	}
	handleChatModelStart(_llm, _messages, runId, _parentRunId, _extraParams, tags, metadata, name) {
		if (metadata && (!tags || !tags.includes("langsmith:nostream") && !tags.includes("nostream"))) this.metadatas[runId] = [metadata.langgraph_checkpoint_ns.split("|"), {
			tags,
			name,
			...metadata
		}];
	}
	handleLLMNewToken() {}
	handleChatModelStreamEvent(event, runId) {
		const meta = this.metadatas[runId];
		if (meta === void 0) return;
		let forwarded = event;
		if (event.event === "message-start") {
			this.streamedRunIds.add(runId);
			const id = event.id ?? `run-${runId}`;
			this.seen[id] = true;
			this.stableMessageIdMap[runId] ??= id;
			if (event.id == null) forwarded = {
				...event,
				id
			};
		}
		this.emit(meta, forwarded, runId);
	}
	handleLLMEnd(output, runId) {
		const meta = this.metadatas[runId];
		if (meta === void 0) return;
		const chatGeneration = output.generations?.[0]?.[0];
		const message = _langchain_core_messages.BaseMessage.isInstance(chatGeneration?.message) ? chatGeneration.message : void 0;
		if (message != null) if (this.streamedRunIds.has(runId)) {
			const messageId = this.normalizeMessageId(message, runId);
			if (messageId != null) this.seen[messageId] = message;
		} else this.emitFinalMessage(meta, message, runId, true);
		this.streamedRunIds.delete(runId);
		delete this.metadatas[runId];
		delete this.stableMessageIdMap[runId];
	}
	handleLLMError(_err, runId) {
		this.streamedRunIds.delete(runId);
		delete this.metadatas[runId];
		delete this.stableMessageIdMap[runId];
	}
	handleChainStart(_chain, inputs, runId, _parentRunId, tags, metadata, _runType, name) {
		if (metadata !== void 0 && name === metadata.langgraph_node && (tags === void 0 || !tags.includes("langsmith:hidden"))) {
			this.metadatas[runId] = [metadata.langgraph_checkpoint_ns.split("|"), {
				tags,
				name,
				...metadata
			}];
			if (typeof inputs === "object") {
				for (const value of Object.values(inputs)) if ((_langchain_core_messages.BaseMessage.isInstance(value) || _langchain_core_messages.BaseMessageChunk.isInstance(value)) && value.id !== void 0) this.seen[value.id] = value;
				else if (Array.isArray(value)) {
					for (const item of value) if ((_langchain_core_messages.BaseMessage.isInstance(item) || _langchain_core_messages.BaseMessageChunk.isInstance(item)) && item.id !== void 0) this.seen[item.id] = item;
				}
			}
		}
	}
	handleChainEnd(outputs, runId) {
		const meta = this.metadatas[runId];
		delete this.metadatas[runId];
		if (meta === void 0) return;
		const emitMessage = (value) => {
			if (_langchain_core_messages.BaseMessage.isInstance(value) && !_langchain_core_messages.ToolMessage.isInstance(value)) this.emitFinalMessage(meta, value, runId, true);
		};
		if (_langchain_core_messages.BaseMessage.isInstance(outputs)) emitMessage(outputs);
		else if (Array.isArray(outputs)) for (const value of outputs) emitMessage(value);
		else if (outputs != null && typeof outputs === "object") for (const value of Object.values(outputs)) if (Array.isArray(value)) for (const item of value) emitMessage(item);
		else emitMessage(value);
		delete this.stableMessageIdMap[runId];
	}
	handleChainError(_err, runId) {
		delete this.metadatas[runId];
		delete this.stableMessageIdMap[runId];
	}
};
//#endregion
exports.StreamProtocolMessagesHandler = StreamProtocolMessagesHandler;

//# sourceMappingURL=messages-v2.cjs.map