@langchain/langgraph 1.3.0 → 1.3.1
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/README.md +7 -3
- package/dist/prebuilt/react_agent_executor.cjs +3 -1
- package/dist/prebuilt/react_agent_executor.cjs.map +1 -1
- package/dist/prebuilt/react_agent_executor.js +3 -1
- package/dist/prebuilt/react_agent_executor.js.map +1 -1
- package/dist/pregel/index.cjs +2 -2
- package/dist/pregel/index.cjs.map +1 -1
- package/dist/pregel/index.js +2 -2
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/messages-v2.cjs +7 -7
- package/dist/pregel/messages-v2.cjs.map +1 -1
- package/dist/pregel/messages-v2.js +8 -8
- package/dist/pregel/messages-v2.js.map +1 -1
- package/dist/stream/transformers/messages.cjs +10 -0
- package/dist/stream/transformers/messages.cjs.map +1 -1
- package/dist/stream/transformers/messages.js +10 -0
- package/dist/stream/transformers/messages.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-v2.cjs","names":["BaseCallbackHandler"],"sources":["../../src/pregel/messages-v2.ts"],"sourcesContent":["import { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport {\n BaseMessage,\n isBaseMessage,\n isBaseMessageChunk,\n isToolMessage,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\ntype Meta = [string[], Record<string, unknown>];\ntype CompatibleContentBlock = { type: string; [key: string]: unknown };\n\nfunction getResponseMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"response_metadata\" in message &&\n typeof message.response_metadata === \"object\" &&\n message.response_metadata != null\n ) {\n return message.response_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction getUsageMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"usage_metadata\" in message &&\n typeof message.usage_metadata === \"object\" &&\n message.usage_metadata != null\n ) {\n return message.usage_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction startBlockFor(block: CompatibleContentBlock): CompatibleContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: \"\" };\n case \"reasoning\":\n return { type: \"reasoning\", reasoning: \"\" };\n case \"tool_call\":\n case \"tool_call_chunk\":\n return {\n type: \"tool_call_chunk\",\n ...(block.id != null ? { id: block.id } : {}),\n ...(block.name != null ? { name: block.name } : {}),\n args: \"\",\n };\n default:\n return block;\n }\n}\n\nfunction deltaFor(\n block: CompatibleContentBlock\n): ChatModelStreamEvent | undefined {\n switch (block.type) {\n case \"text\": {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n return text.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"text-delta\", text },\n }\n : undefined;\n }\n case \"reasoning\": {\n const reasoning =\n typeof block.reasoning === \"string\" ? block.reasoning : \"\";\n return reasoning.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"reasoning-delta\", reasoning },\n }\n : undefined;\n }\n case \"tool_call_chunk\":\n return {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: {\n type: \"block-delta\",\n fields: { ...block, type: \"tool_call_chunk\" },\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * A callback handler that implements protocol-native stream_mode=messages.\n *\n * LangChain Core owns chat model content-block event construction. This handler\n * only captures LangGraph metadata, forwards Core events to the Pregel messages\n * channel, and emits a small non-streaming fallback for models that cannot\n * produce stream events.\n */\nexport class StreamProtocolMessagesHandler extends BaseCallbackHandler {\n name = \"StreamProtocolMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage | true> = {};\n\n streamedRunIds = new Set<string>();\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_chat_model_stream_events = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n private normalizeMessageId(message: BaseMessage, runId: string | undefined) {\n let messageId = message.id;\n\n if (runId != null) {\n if (isToolMessage(message)) {\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\n this.stableMessageIdMap[runId] ??= messageId;\n }\n }\n\n if (messageId !== message.id) {\n // eslint-disable-next-line no-param-reassign\n message.id = messageId;\n // eslint-disable-next-line no-param-reassign\n message.lc_kwargs.id = messageId;\n }\n\n if (message.id != null) this.seen[message.id] = message;\n return message.id;\n }\n\n private emit(meta: Meta, data: ChatModelStreamEvent, runId?: string) {\n const metadata = runId != null ? { ...meta[1], run_id: runId } : meta[1];\n this.streamFn([meta[0], \"messages\", [data, metadata]]);\n }\n\n private emitFinalMessage(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n const existingId =\n message.id ??\n (runId != null ? this.stableMessageIdMap[runId] : undefined);\n if (dedupe && existingId != null && this.seen[existingId] !== undefined) {\n return;\n }\n\n const messageId = this.normalizeMessageId(message, runId);\n const role =\n message.type === \"human\"\n ? \"human\"\n : message.type === \"system\"\n ? \"system\"\n : message.type === \"tool\"\n ? \"tool\"\n : \"ai\";\n const toolCallId =\n role === \"tool\" && isToolMessage(message)\n ? message.tool_call_id\n : undefined;\n\n this.emit(\n meta,\n {\n event: \"message-start\",\n ...(messageId != null ? { id: messageId } : {}),\n ...(role !== \"ai\" ? ({ role } as Record<string, unknown>) : {}),\n ...(typeof toolCallId === \"string\"\n ? ({ tool_call_id: toolCallId } as Record<string, unknown>)\n : {}),\n } as ChatModelStreamEvent,\n runId\n );\n\n const contentBlocks: CompatibleContentBlock[] = Array.isArray(\n message.content\n )\n ? (message.content as CompatibleContentBlock[])\n : typeof message.content === \"string\" && message.content.length > 0\n ? [{ type: \"text\", text: message.content }]\n : [];\n\n contentBlocks.forEach((block, offset) => {\n const index = typeof block.index === \"number\" ? block.index : offset;\n this.emit(\n meta,\n {\n event: \"content-block-start\",\n index,\n content: startBlockFor(block),\n },\n runId\n );\n const delta = deltaFor({ ...block, index });\n if (delta != null) {\n this.emit(meta, delta, runId);\n }\n this.emit(\n meta,\n {\n event: \"content-block-finish\",\n index,\n content: block,\n },\n runId\n );\n });\n\n this.emit(\n meta,\n {\n event: \"message-finish\",\n ...(getUsageMetadata(message) != null\n ? { usage: getUsageMetadata(message) }\n : {}),\n ...(getResponseMetadata(message) != null\n ? { responseMetadata: getResponseMetadata(message) }\n : {}),\n },\n runId\n );\n }\n\n handleChatModelStart(\n _llm: Serialized,\n _messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n if (\n metadata &&\n (!tags || (!tags.includes(TAG_NOSTREAM) && !tags.includes(\"nostream\")))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n }\n }\n\n handleLLMNewToken() {\n // Core v2 stream events are forwarded via handleChatModelStreamEvent.\n }\n\n handleChatModelStreamEvent(event: ChatModelStreamEvent, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n let forwarded = event;\n if (event.event === \"message-start\") {\n this.streamedRunIds.add(runId);\n const id = event.id ?? `run-${runId}`;\n this.seen[id] = true;\n this.stableMessageIdMap[runId] ??= id;\n if (event.id == null) {\n forwarded = { ...event, id };\n }\n }\n\n this.emit(meta, forwarded, runId);\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n const message = isBaseMessage(chatGeneration?.message)\n ? chatGeneration.message\n : undefined;\n\n if (message != null) {\n if (this.streamedRunIds.has(runId)) {\n const messageId = this.normalizeMessageId(message, runId);\n if (messageId != null) this.seen[messageId] = message;\n } else {\n this.emitFinalMessage(meta, message, runId, true);\n }\n }\n\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleLLMError(_err: any, runId: string) {\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n handleChainStart(\n _chain: Serialized,\n inputs: ChainValues,\n runId: string,\n _parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ) {\n if (\n metadata !== undefined &&\n name === metadata.langgraph_node &&\n (tags === undefined || !tags.includes(TAG_HIDDEN))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n\n if (typeof inputs === \"object\") {\n for (const value of Object.values(inputs)) {\n if (\n (isBaseMessage(value) || isBaseMessageChunk(value)) &&\n value.id !== undefined\n ) {\n this.seen[value.id] = value;\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (\n (isBaseMessage(item) || isBaseMessageChunk(item)) &&\n item.id !== undefined\n ) {\n this.seen[item.id] = item;\n }\n }\n }\n }\n }\n }\n }\n\n handleChainEnd(outputs: ChainValues, runId: string) {\n const meta = this.metadatas[runId];\n delete this.metadatas[runId];\n if (meta === undefined) return;\n\n const emitMessage = (value: unknown) => {\n if (isBaseMessage(value)) {\n this.emitFinalMessage(meta, value, runId, true);\n }\n };\n\n if (isBaseMessage(outputs)) {\n emitMessage(outputs);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) emitMessage(value);\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (Array.isArray(value)) {\n for (const item of value) emitMessage(item);\n } else {\n emitMessage(value);\n }\n }\n }\n\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"messages-v2.cjs","names":["BaseCallbackHandler","ToolMessage","BaseMessage","BaseMessageChunk"],"sources":["../../src/pregel/messages-v2.ts"],"sourcesContent":["import { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport {\n BaseMessage,\n ToolMessage,\n BaseMessageChunk,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\ntype Meta = [string[], Record<string, unknown>];\ntype CompatibleContentBlock = { type: string; [key: string]: unknown };\n\nfunction getResponseMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"response_metadata\" in message &&\n typeof message.response_metadata === \"object\" &&\n message.response_metadata != null\n ) {\n return message.response_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction getUsageMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"usage_metadata\" in message &&\n typeof message.usage_metadata === \"object\" &&\n message.usage_metadata != null\n ) {\n return message.usage_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction startBlockFor(block: CompatibleContentBlock): CompatibleContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: \"\" };\n case \"reasoning\":\n return { type: \"reasoning\", reasoning: \"\" };\n case \"tool_call\":\n case \"tool_call_chunk\":\n return {\n type: \"tool_call_chunk\",\n ...(block.id != null ? { id: block.id } : {}),\n ...(block.name != null ? { name: block.name } : {}),\n args: \"\",\n };\n default:\n return block;\n }\n}\n\nfunction deltaFor(\n block: CompatibleContentBlock\n): ChatModelStreamEvent | undefined {\n switch (block.type) {\n case \"text\": {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n return text.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"text-delta\", text },\n }\n : undefined;\n }\n case \"reasoning\": {\n const reasoning =\n typeof block.reasoning === \"string\" ? block.reasoning : \"\";\n return reasoning.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"reasoning-delta\", reasoning },\n }\n : undefined;\n }\n case \"tool_call_chunk\":\n return {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: {\n type: \"block-delta\",\n fields: { ...block, type: \"tool_call_chunk\" },\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * A callback handler that implements protocol-native stream_mode=messages.\n *\n * LangChain Core owns chat model content-block event construction. This handler\n * only captures LangGraph metadata, forwards Core events to the Pregel messages\n * channel, and emits a small non-streaming fallback for models that cannot\n * produce stream events.\n */\nexport class StreamProtocolMessagesHandler extends BaseCallbackHandler {\n name = \"StreamProtocolMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage | true> = {};\n\n streamedRunIds = new Set<string>();\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_chat_model_stream_events = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n private normalizeMessageId(message: BaseMessage, runId: string | undefined) {\n let messageId = message.id;\n\n if (runId != null) {\n if (ToolMessage.isInstance(message)) {\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\n this.stableMessageIdMap[runId] ??= messageId;\n }\n }\n\n if (messageId !== message.id) {\n // eslint-disable-next-line no-param-reassign\n message.id = messageId;\n // eslint-disable-next-line no-param-reassign\n message.lc_kwargs.id = messageId;\n }\n\n if (message.id != null) this.seen[message.id] = message;\n return message.id;\n }\n\n private emit(meta: Meta, data: ChatModelStreamEvent, runId?: string) {\n const metadata = runId != null ? { ...meta[1], run_id: runId } : meta[1];\n this.streamFn([meta[0], \"messages\", [data, metadata]]);\n }\n\n private emitFinalMessage(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n const existingId =\n message.id ??\n (runId != null ? this.stableMessageIdMap[runId] : undefined);\n if (dedupe && existingId != null && this.seen[existingId] !== undefined) {\n return;\n }\n\n const messageId = this.normalizeMessageId(message, runId);\n const role =\n message.type === \"human\"\n ? \"human\"\n : message.type === \"system\"\n ? \"system\"\n : message.type === \"tool\"\n ? \"tool\"\n : \"ai\";\n const toolCallId =\n role === \"tool\" && ToolMessage.isInstance(message)\n ? message.tool_call_id\n : undefined;\n\n this.emit(\n meta,\n {\n event: \"message-start\",\n ...(messageId != null ? { id: messageId } : {}),\n ...(role !== \"ai\" ? ({ role } as Record<string, unknown>) : {}),\n ...(typeof toolCallId === \"string\"\n ? ({ tool_call_id: toolCallId } as Record<string, unknown>)\n : {}),\n } as ChatModelStreamEvent,\n runId\n );\n\n const contentBlocks: CompatibleContentBlock[] = Array.isArray(\n message.content\n )\n ? (message.content as CompatibleContentBlock[])\n : typeof message.content === \"string\" && message.content.length > 0\n ? [{ type: \"text\", text: message.content }]\n : [];\n\n contentBlocks.forEach((block, offset) => {\n const index = typeof block.index === \"number\" ? block.index : offset;\n this.emit(\n meta,\n {\n event: \"content-block-start\",\n index,\n content: startBlockFor(block),\n },\n runId\n );\n const delta = deltaFor({ ...block, index });\n if (delta != null) {\n this.emit(meta, delta, runId);\n }\n this.emit(\n meta,\n {\n event: \"content-block-finish\",\n index,\n content: block,\n },\n runId\n );\n });\n\n this.emit(\n meta,\n {\n event: \"message-finish\",\n ...(getUsageMetadata(message) != null\n ? { usage: getUsageMetadata(message) }\n : {}),\n ...(getResponseMetadata(message) != null\n ? { responseMetadata: getResponseMetadata(message) }\n : {}),\n },\n runId\n );\n }\n\n handleChatModelStart(\n _llm: Serialized,\n _messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n if (\n metadata &&\n (!tags || (!tags.includes(TAG_NOSTREAM) && !tags.includes(\"nostream\")))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n }\n }\n\n handleLLMNewToken() {\n // Core v2 stream events are forwarded via handleChatModelStreamEvent.\n }\n\n handleChatModelStreamEvent(event: ChatModelStreamEvent, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n let forwarded = event;\n if (event.event === \"message-start\") {\n this.streamedRunIds.add(runId);\n const id = event.id ?? `run-${runId}`;\n this.seen[id] = true;\n this.stableMessageIdMap[runId] ??= id;\n if (event.id == null) {\n forwarded = { ...event, id };\n }\n }\n\n this.emit(meta, forwarded, runId);\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n const message = BaseMessage.isInstance(chatGeneration?.message)\n ? chatGeneration.message\n : undefined;\n\n if (message != null) {\n if (this.streamedRunIds.has(runId)) {\n const messageId = this.normalizeMessageId(message, runId);\n if (messageId != null) this.seen[messageId] = message;\n } else {\n this.emitFinalMessage(meta, message, runId, true);\n }\n }\n\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleLLMError(_err: any, runId: string) {\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n handleChainStart(\n _chain: Serialized,\n inputs: ChainValues,\n runId: string,\n _parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ) {\n if (\n metadata !== undefined &&\n name === metadata.langgraph_node &&\n (tags === undefined || !tags.includes(TAG_HIDDEN))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n\n if (typeof inputs === \"object\") {\n for (const value of Object.values(inputs)) {\n if (\n (BaseMessage.isInstance(value) ||\n BaseMessageChunk.isInstance(value)) &&\n value.id !== undefined\n ) {\n this.seen[value.id] = value;\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (\n (BaseMessage.isInstance(item) ||\n BaseMessageChunk.isInstance(item)) &&\n item.id !== undefined\n ) {\n this.seen[item.id] = item;\n }\n }\n }\n }\n }\n }\n }\n\n handleChainEnd(outputs: ChainValues, runId: string) {\n const meta = this.metadatas[runId];\n delete this.metadatas[runId];\n if (meta === undefined) return;\n\n const emitMessage = (value: unknown) => {\n if (BaseMessage.isInstance(value) && !ToolMessage.isInstance(value)) {\n this.emitFinalMessage(meta, value, runId, true);\n }\n };\n\n if (BaseMessage.isInstance(outputs)) {\n emitMessage(outputs);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) emitMessage(value);\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (Array.isArray(value)) {\n for (const item of value) emitMessage(item);\n } else {\n emitMessage(value);\n }\n }\n }\n\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../constants.js";
|
|
2
2
|
import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
3
|
-
import {
|
|
3
|
+
import { BaseMessage, BaseMessageChunk, ToolMessage } from "@langchain/core/messages";
|
|
4
4
|
//#region src/pregel/messages-v2.ts
|
|
5
5
|
function getResponseMetadata(message) {
|
|
6
6
|
if ("response_metadata" in message && typeof message.response_metadata === "object" && message.response_metadata != null) return message.response_metadata;
|
|
@@ -88,7 +88,7 @@ var StreamProtocolMessagesHandler = class extends BaseCallbackHandler {
|
|
|
88
88
|
}
|
|
89
89
|
normalizeMessageId(message, runId) {
|
|
90
90
|
let messageId = message.id;
|
|
91
|
-
if (runId != null) if (
|
|
91
|
+
if (runId != null) if (ToolMessage.isInstance(message)) messageId ??= `run-${runId}-tool-${message.tool_call_id}`;
|
|
92
92
|
else {
|
|
93
93
|
if (messageId == null || messageId === `run-${runId}`) messageId = this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;
|
|
94
94
|
this.stableMessageIdMap[runId] ??= messageId;
|
|
@@ -116,7 +116,7 @@ var StreamProtocolMessagesHandler = class extends BaseCallbackHandler {
|
|
|
116
116
|
if (dedupe && existingId != null && this.seen[existingId] !== void 0) return;
|
|
117
117
|
const messageId = this.normalizeMessageId(message, runId);
|
|
118
118
|
const role = message.type === "human" ? "human" : message.type === "system" ? "system" : message.type === "tool" ? "tool" : "ai";
|
|
119
|
-
const toolCallId = role === "tool" &&
|
|
119
|
+
const toolCallId = role === "tool" && ToolMessage.isInstance(message) ? message.tool_call_id : void 0;
|
|
120
120
|
this.emit(meta, {
|
|
121
121
|
event: "message-start",
|
|
122
122
|
...messageId != null ? { id: messageId } : {},
|
|
@@ -178,7 +178,7 @@ var StreamProtocolMessagesHandler = class extends BaseCallbackHandler {
|
|
|
178
178
|
const meta = this.metadatas[runId];
|
|
179
179
|
if (meta === void 0) return;
|
|
180
180
|
const chatGeneration = output.generations?.[0]?.[0];
|
|
181
|
-
const message =
|
|
181
|
+
const message = BaseMessage.isInstance(chatGeneration?.message) ? chatGeneration.message : void 0;
|
|
182
182
|
if (message != null) if (this.streamedRunIds.has(runId)) {
|
|
183
183
|
const messageId = this.normalizeMessageId(message, runId);
|
|
184
184
|
if (messageId != null) this.seen[messageId] = message;
|
|
@@ -200,9 +200,9 @@ var StreamProtocolMessagesHandler = class extends BaseCallbackHandler {
|
|
|
200
200
|
...metadata
|
|
201
201
|
}];
|
|
202
202
|
if (typeof inputs === "object") {
|
|
203
|
-
for (const value of Object.values(inputs)) if ((
|
|
203
|
+
for (const value of Object.values(inputs)) if ((BaseMessage.isInstance(value) || BaseMessageChunk.isInstance(value)) && value.id !== void 0) this.seen[value.id] = value;
|
|
204
204
|
else if (Array.isArray(value)) {
|
|
205
|
-
for (const item of value) if ((
|
|
205
|
+
for (const item of value) if ((BaseMessage.isInstance(item) || BaseMessageChunk.isInstance(item)) && item.id !== void 0) this.seen[item.id] = item;
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
}
|
|
@@ -212,9 +212,9 @@ var StreamProtocolMessagesHandler = class extends BaseCallbackHandler {
|
|
|
212
212
|
delete this.metadatas[runId];
|
|
213
213
|
if (meta === void 0) return;
|
|
214
214
|
const emitMessage = (value) => {
|
|
215
|
-
if (
|
|
215
|
+
if (BaseMessage.isInstance(value) && !ToolMessage.isInstance(value)) this.emitFinalMessage(meta, value, runId, true);
|
|
216
216
|
};
|
|
217
|
-
if (
|
|
217
|
+
if (BaseMessage.isInstance(outputs)) emitMessage(outputs);
|
|
218
218
|
else if (Array.isArray(outputs)) for (const value of outputs) emitMessage(value);
|
|
219
219
|
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);
|
|
220
220
|
else emitMessage(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-v2.js","names":[],"sources":["../../src/pregel/messages-v2.ts"],"sourcesContent":["import { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport {\n BaseMessage,\n isBaseMessage,\n isBaseMessageChunk,\n isToolMessage,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\ntype Meta = [string[], Record<string, unknown>];\ntype CompatibleContentBlock = { type: string; [key: string]: unknown };\n\nfunction getResponseMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"response_metadata\" in message &&\n typeof message.response_metadata === \"object\" &&\n message.response_metadata != null\n ) {\n return message.response_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction getUsageMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"usage_metadata\" in message &&\n typeof message.usage_metadata === \"object\" &&\n message.usage_metadata != null\n ) {\n return message.usage_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction startBlockFor(block: CompatibleContentBlock): CompatibleContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: \"\" };\n case \"reasoning\":\n return { type: \"reasoning\", reasoning: \"\" };\n case \"tool_call\":\n case \"tool_call_chunk\":\n return {\n type: \"tool_call_chunk\",\n ...(block.id != null ? { id: block.id } : {}),\n ...(block.name != null ? { name: block.name } : {}),\n args: \"\",\n };\n default:\n return block;\n }\n}\n\nfunction deltaFor(\n block: CompatibleContentBlock\n): ChatModelStreamEvent | undefined {\n switch (block.type) {\n case \"text\": {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n return text.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"text-delta\", text },\n }\n : undefined;\n }\n case \"reasoning\": {\n const reasoning =\n typeof block.reasoning === \"string\" ? block.reasoning : \"\";\n return reasoning.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"reasoning-delta\", reasoning },\n }\n : undefined;\n }\n case \"tool_call_chunk\":\n return {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: {\n type: \"block-delta\",\n fields: { ...block, type: \"tool_call_chunk\" },\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * A callback handler that implements protocol-native stream_mode=messages.\n *\n * LangChain Core owns chat model content-block event construction. This handler\n * only captures LangGraph metadata, forwards Core events to the Pregel messages\n * channel, and emits a small non-streaming fallback for models that cannot\n * produce stream events.\n */\nexport class StreamProtocolMessagesHandler extends BaseCallbackHandler {\n name = \"StreamProtocolMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage | true> = {};\n\n streamedRunIds = new Set<string>();\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_chat_model_stream_events = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n private normalizeMessageId(message: BaseMessage, runId: string | undefined) {\n let messageId = message.id;\n\n if (runId != null) {\n if (isToolMessage(message)) {\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\n this.stableMessageIdMap[runId] ??= messageId;\n }\n }\n\n if (messageId !== message.id) {\n // eslint-disable-next-line no-param-reassign\n message.id = messageId;\n // eslint-disable-next-line no-param-reassign\n message.lc_kwargs.id = messageId;\n }\n\n if (message.id != null) this.seen[message.id] = message;\n return message.id;\n }\n\n private emit(meta: Meta, data: ChatModelStreamEvent, runId?: string) {\n const metadata = runId != null ? { ...meta[1], run_id: runId } : meta[1];\n this.streamFn([meta[0], \"messages\", [data, metadata]]);\n }\n\n private emitFinalMessage(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n const existingId =\n message.id ??\n (runId != null ? this.stableMessageIdMap[runId] : undefined);\n if (dedupe && existingId != null && this.seen[existingId] !== undefined) {\n return;\n }\n\n const messageId = this.normalizeMessageId(message, runId);\n const role =\n message.type === \"human\"\n ? \"human\"\n : message.type === \"system\"\n ? \"system\"\n : message.type === \"tool\"\n ? \"tool\"\n : \"ai\";\n const toolCallId =\n role === \"tool\" && isToolMessage(message)\n ? message.tool_call_id\n : undefined;\n\n this.emit(\n meta,\n {\n event: \"message-start\",\n ...(messageId != null ? { id: messageId } : {}),\n ...(role !== \"ai\" ? ({ role } as Record<string, unknown>) : {}),\n ...(typeof toolCallId === \"string\"\n ? ({ tool_call_id: toolCallId } as Record<string, unknown>)\n : {}),\n } as ChatModelStreamEvent,\n runId\n );\n\n const contentBlocks: CompatibleContentBlock[] = Array.isArray(\n message.content\n )\n ? (message.content as CompatibleContentBlock[])\n : typeof message.content === \"string\" && message.content.length > 0\n ? [{ type: \"text\", text: message.content }]\n : [];\n\n contentBlocks.forEach((block, offset) => {\n const index = typeof block.index === \"number\" ? block.index : offset;\n this.emit(\n meta,\n {\n event: \"content-block-start\",\n index,\n content: startBlockFor(block),\n },\n runId\n );\n const delta = deltaFor({ ...block, index });\n if (delta != null) {\n this.emit(meta, delta, runId);\n }\n this.emit(\n meta,\n {\n event: \"content-block-finish\",\n index,\n content: block,\n },\n runId\n );\n });\n\n this.emit(\n meta,\n {\n event: \"message-finish\",\n ...(getUsageMetadata(message) != null\n ? { usage: getUsageMetadata(message) }\n : {}),\n ...(getResponseMetadata(message) != null\n ? { responseMetadata: getResponseMetadata(message) }\n : {}),\n },\n runId\n );\n }\n\n handleChatModelStart(\n _llm: Serialized,\n _messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n if (\n metadata &&\n (!tags || (!tags.includes(TAG_NOSTREAM) && !tags.includes(\"nostream\")))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n }\n }\n\n handleLLMNewToken() {\n // Core v2 stream events are forwarded via handleChatModelStreamEvent.\n }\n\n handleChatModelStreamEvent(event: ChatModelStreamEvent, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n let forwarded = event;\n if (event.event === \"message-start\") {\n this.streamedRunIds.add(runId);\n const id = event.id ?? `run-${runId}`;\n this.seen[id] = true;\n this.stableMessageIdMap[runId] ??= id;\n if (event.id == null) {\n forwarded = { ...event, id };\n }\n }\n\n this.emit(meta, forwarded, runId);\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n const message = isBaseMessage(chatGeneration?.message)\n ? chatGeneration.message\n : undefined;\n\n if (message != null) {\n if (this.streamedRunIds.has(runId)) {\n const messageId = this.normalizeMessageId(message, runId);\n if (messageId != null) this.seen[messageId] = message;\n } else {\n this.emitFinalMessage(meta, message, runId, true);\n }\n }\n\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleLLMError(_err: any, runId: string) {\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n handleChainStart(\n _chain: Serialized,\n inputs: ChainValues,\n runId: string,\n _parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ) {\n if (\n metadata !== undefined &&\n name === metadata.langgraph_node &&\n (tags === undefined || !tags.includes(TAG_HIDDEN))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n\n if (typeof inputs === \"object\") {\n for (const value of Object.values(inputs)) {\n if (\n (isBaseMessage(value) || isBaseMessageChunk(value)) &&\n value.id !== undefined\n ) {\n this.seen[value.id] = value;\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (\n (isBaseMessage(item) || isBaseMessageChunk(item)) &&\n item.id !== undefined\n ) {\n this.seen[item.id] = item;\n }\n }\n }\n }\n }\n }\n }\n\n handleChainEnd(outputs: ChainValues, runId: string) {\n const meta = this.metadatas[runId];\n delete this.metadatas[runId];\n if (meta === undefined) return;\n\n const emitMessage = (value: unknown) => {\n if (isBaseMessage(value)) {\n this.emitFinalMessage(meta, value, runId, true);\n }\n };\n\n if (isBaseMessage(outputs)) {\n emitMessage(outputs);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) emitMessage(value);\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (Array.isArray(value)) {\n for (const item of value) emitMessage(item);\n } else {\n emitMessage(value);\n }\n }\n }\n\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"messages-v2.js","names":[],"sources":["../../src/pregel/messages-v2.ts"],"sourcesContent":["import { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport {\n BaseMessage,\n ToolMessage,\n BaseMessageChunk,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\ntype Meta = [string[], Record<string, unknown>];\ntype CompatibleContentBlock = { type: string; [key: string]: unknown };\n\nfunction getResponseMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"response_metadata\" in message &&\n typeof message.response_metadata === \"object\" &&\n message.response_metadata != null\n ) {\n return message.response_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction getUsageMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"usage_metadata\" in message &&\n typeof message.usage_metadata === \"object\" &&\n message.usage_metadata != null\n ) {\n return message.usage_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction startBlockFor(block: CompatibleContentBlock): CompatibleContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: \"\" };\n case \"reasoning\":\n return { type: \"reasoning\", reasoning: \"\" };\n case \"tool_call\":\n case \"tool_call_chunk\":\n return {\n type: \"tool_call_chunk\",\n ...(block.id != null ? { id: block.id } : {}),\n ...(block.name != null ? { name: block.name } : {}),\n args: \"\",\n };\n default:\n return block;\n }\n}\n\nfunction deltaFor(\n block: CompatibleContentBlock\n): ChatModelStreamEvent | undefined {\n switch (block.type) {\n case \"text\": {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n return text.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"text-delta\", text },\n }\n : undefined;\n }\n case \"reasoning\": {\n const reasoning =\n typeof block.reasoning === \"string\" ? block.reasoning : \"\";\n return reasoning.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"reasoning-delta\", reasoning },\n }\n : undefined;\n }\n case \"tool_call_chunk\":\n return {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: {\n type: \"block-delta\",\n fields: { ...block, type: \"tool_call_chunk\" },\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * A callback handler that implements protocol-native stream_mode=messages.\n *\n * LangChain Core owns chat model content-block event construction. This handler\n * only captures LangGraph metadata, forwards Core events to the Pregel messages\n * channel, and emits a small non-streaming fallback for models that cannot\n * produce stream events.\n */\nexport class StreamProtocolMessagesHandler extends BaseCallbackHandler {\n name = \"StreamProtocolMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage | true> = {};\n\n streamedRunIds = new Set<string>();\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_chat_model_stream_events = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n private normalizeMessageId(message: BaseMessage, runId: string | undefined) {\n let messageId = message.id;\n\n if (runId != null) {\n if (ToolMessage.isInstance(message)) {\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\n this.stableMessageIdMap[runId] ??= messageId;\n }\n }\n\n if (messageId !== message.id) {\n // eslint-disable-next-line no-param-reassign\n message.id = messageId;\n // eslint-disable-next-line no-param-reassign\n message.lc_kwargs.id = messageId;\n }\n\n if (message.id != null) this.seen[message.id] = message;\n return message.id;\n }\n\n private emit(meta: Meta, data: ChatModelStreamEvent, runId?: string) {\n const metadata = runId != null ? { ...meta[1], run_id: runId } : meta[1];\n this.streamFn([meta[0], \"messages\", [data, metadata]]);\n }\n\n private emitFinalMessage(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n const existingId =\n message.id ??\n (runId != null ? this.stableMessageIdMap[runId] : undefined);\n if (dedupe && existingId != null && this.seen[existingId] !== undefined) {\n return;\n }\n\n const messageId = this.normalizeMessageId(message, runId);\n const role =\n message.type === \"human\"\n ? \"human\"\n : message.type === \"system\"\n ? \"system\"\n : message.type === \"tool\"\n ? \"tool\"\n : \"ai\";\n const toolCallId =\n role === \"tool\" && ToolMessage.isInstance(message)\n ? message.tool_call_id\n : undefined;\n\n this.emit(\n meta,\n {\n event: \"message-start\",\n ...(messageId != null ? { id: messageId } : {}),\n ...(role !== \"ai\" ? ({ role } as Record<string, unknown>) : {}),\n ...(typeof toolCallId === \"string\"\n ? ({ tool_call_id: toolCallId } as Record<string, unknown>)\n : {}),\n } as ChatModelStreamEvent,\n runId\n );\n\n const contentBlocks: CompatibleContentBlock[] = Array.isArray(\n message.content\n )\n ? (message.content as CompatibleContentBlock[])\n : typeof message.content === \"string\" && message.content.length > 0\n ? [{ type: \"text\", text: message.content }]\n : [];\n\n contentBlocks.forEach((block, offset) => {\n const index = typeof block.index === \"number\" ? block.index : offset;\n this.emit(\n meta,\n {\n event: \"content-block-start\",\n index,\n content: startBlockFor(block),\n },\n runId\n );\n const delta = deltaFor({ ...block, index });\n if (delta != null) {\n this.emit(meta, delta, runId);\n }\n this.emit(\n meta,\n {\n event: \"content-block-finish\",\n index,\n content: block,\n },\n runId\n );\n });\n\n this.emit(\n meta,\n {\n event: \"message-finish\",\n ...(getUsageMetadata(message) != null\n ? { usage: getUsageMetadata(message) }\n : {}),\n ...(getResponseMetadata(message) != null\n ? { responseMetadata: getResponseMetadata(message) }\n : {}),\n },\n runId\n );\n }\n\n handleChatModelStart(\n _llm: Serialized,\n _messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n if (\n metadata &&\n (!tags || (!tags.includes(TAG_NOSTREAM) && !tags.includes(\"nostream\")))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n }\n }\n\n handleLLMNewToken() {\n // Core v2 stream events are forwarded via handleChatModelStreamEvent.\n }\n\n handleChatModelStreamEvent(event: ChatModelStreamEvent, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n let forwarded = event;\n if (event.event === \"message-start\") {\n this.streamedRunIds.add(runId);\n const id = event.id ?? `run-${runId}`;\n this.seen[id] = true;\n this.stableMessageIdMap[runId] ??= id;\n if (event.id == null) {\n forwarded = { ...event, id };\n }\n }\n\n this.emit(meta, forwarded, runId);\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n const message = BaseMessage.isInstance(chatGeneration?.message)\n ? chatGeneration.message\n : undefined;\n\n if (message != null) {\n if (this.streamedRunIds.has(runId)) {\n const messageId = this.normalizeMessageId(message, runId);\n if (messageId != null) this.seen[messageId] = message;\n } else {\n this.emitFinalMessage(meta, message, runId, true);\n }\n }\n\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleLLMError(_err: any, runId: string) {\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n handleChainStart(\n _chain: Serialized,\n inputs: ChainValues,\n runId: string,\n _parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ) {\n if (\n metadata !== undefined &&\n name === metadata.langgraph_node &&\n (tags === undefined || !tags.includes(TAG_HIDDEN))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n\n if (typeof inputs === \"object\") {\n for (const value of Object.values(inputs)) {\n if (\n (BaseMessage.isInstance(value) ||\n BaseMessageChunk.isInstance(value)) &&\n value.id !== undefined\n ) {\n this.seen[value.id] = value;\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (\n (BaseMessage.isInstance(item) ||\n BaseMessageChunk.isInstance(item)) &&\n item.id !== undefined\n ) {\n this.seen[item.id] = item;\n }\n }\n }\n }\n }\n }\n }\n\n handleChainEnd(outputs: ChainValues, runId: string) {\n const meta = this.metadatas[runId];\n delete this.metadatas[runId];\n if (meta === undefined) return;\n\n const emitMessage = (value: unknown) => {\n if (BaseMessage.isInstance(value) && !ToolMessage.isInstance(value)) {\n this.emitFinalMessage(meta, value, runId, true);\n }\n };\n\n if (BaseMessage.isInstance(outputs)) {\n emitMessage(outputs);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) emitMessage(value);\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (Array.isArray(value)) {\n for (const item of value) emitMessage(item);\n } else {\n emitMessage(value);\n }\n }\n }\n\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n}\n"],"mappings":"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"}
|
|
@@ -26,6 +26,7 @@ function getMessageStreamKey(data) {
|
|
|
26
26
|
function createMessagesTransformer(path, nodeFilter) {
|
|
27
27
|
const log = require_stream_channel.StreamChannel.local();
|
|
28
28
|
const active = /* @__PURE__ */ new Map();
|
|
29
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
29
30
|
return {
|
|
30
31
|
init: () => ({ messages: log.toAsyncIterable() }),
|
|
31
32
|
process(event) {
|
|
@@ -37,6 +38,10 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
37
38
|
switch (data.event) {
|
|
38
39
|
case "message-start": {
|
|
39
40
|
const key = getMessageStreamKey(data);
|
|
41
|
+
if (data.role === "tool") {
|
|
42
|
+
ignored.add(key);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
40
45
|
const source = require_stream_channel.StreamChannel.local();
|
|
41
46
|
const stream = Object.assign(new _langchain_core_language_models_stream.ChatModelStream(source.toAsyncIterable()), {
|
|
42
47
|
namespace: event.params.namespace,
|
|
@@ -53,10 +58,12 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
53
58
|
case "content-block-start":
|
|
54
59
|
case "content-block-delta":
|
|
55
60
|
case "content-block-finish":
|
|
61
|
+
if (ignored.has(getMessageStreamKey(data))) break;
|
|
56
62
|
active.get(getMessageStreamKey(data))?.source.push(data);
|
|
57
63
|
break;
|
|
58
64
|
case "message-finish": {
|
|
59
65
|
const key = getMessageStreamKey(data);
|
|
66
|
+
if (ignored.delete(key)) break;
|
|
60
67
|
const stream = active.get(key);
|
|
61
68
|
if (stream) {
|
|
62
69
|
stream.source.push(data);
|
|
@@ -66,6 +73,7 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
66
73
|
break;
|
|
67
74
|
}
|
|
68
75
|
case "error":
|
|
76
|
+
if (ignored.has(getMessageStreamKey(data))) break;
|
|
69
77
|
active.get(getMessageStreamKey(data))?.source.push(data);
|
|
70
78
|
break;
|
|
71
79
|
}
|
|
@@ -77,6 +85,7 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
77
85
|
stream.source.close();
|
|
78
86
|
active.delete(key);
|
|
79
87
|
}
|
|
88
|
+
ignored.clear();
|
|
80
89
|
log.close();
|
|
81
90
|
},
|
|
82
91
|
fail(err) {
|
|
@@ -84,6 +93,7 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
84
93
|
stream.source.fail(err);
|
|
85
94
|
active.delete(key);
|
|
86
95
|
}
|
|
96
|
+
ignored.clear();
|
|
87
97
|
log.fail(err);
|
|
88
98
|
}
|
|
89
99
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.cjs","names":["StreamChannel","hasPrefix","CoreChatModelStream"],"sources":["../../../src/stream/transformers/messages.ts"],"sourcesContent":["import type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChatModelStream as CoreChatModelStream } from \"@langchain/core/language_models/stream\";\nimport { hasPrefix } from \"../mux.js\";\nimport { StreamChannel } from \"../stream-channel.js\";\nimport type {\n ChatModelStream,\n MessagesEventData,\n Namespace,\n ProtocolEvent,\n StreamTransformer,\n} from \"../types.js\";\nimport type { MessagesTransformerProjection } from \"./types.js\";\n\ntype ActiveMessageStream = {\n source: StreamChannel<ChatModelStreamEvent>;\n stream: ChatModelStream;\n};\n\nfunction getMessageStreamKey(data: MessagesEventData): string {\n const record = data as unknown as Record<string, unknown>;\n if (typeof record.run_id === \"string\") return `run:${record.run_id}`;\n if (data.event === \"message-start\" && typeof record.id === \"string\") {\n return `message:${record.id}`;\n }\n return \"__default__\";\n}\n\n/**\n * Creates a {@link StreamTransformer} that groups `messages` channel events into\n * per-message {@link ChatModelStream} instances.\n *\n * A new `ChatModelStream` is created on `message-start` and closed on\n * `message-finish`. Content-block events in between are forwarded to the\n * active stream. Only events whose namespace exactly matches {@link path}\n * are processed; child namespaces are ignored.\n *\n * @param path - Namespace prefix to match against incoming events.\n * @param nodeFilter - If provided, only events emitted by this graph node\n * are processed; all others are skipped.\n * @returns A `StreamTransformer` whose projection contains the `messages`\n * async iterable.\n */\nexport function createMessagesTransformer(\n path: Namespace,\n nodeFilter?: string\n): StreamTransformer<MessagesTransformerProjection> {\n const log = StreamChannel.local<ChatModelStream>();\n const active = new Map<string, ActiveMessageStream>();\n\n return {\n init: () => ({\n messages: log.toAsyncIterable(),\n }),\n\n process(event: ProtocolEvent): boolean {\n if (event.method !== \"messages\") return true;\n if (!hasPrefix(event.params.namespace, path)) return true;\n\n // Only capture messages from this graph's own node executions,\n // which sit exactly one namespace level deeper than `path`.\n // Events at `path` itself are chain-level replays from the\n // callback system (handleChainEnd re-emits finalized messages)\n // and would duplicate the streamed content already captured\n // at depth+1.\n const depth = event.params.namespace.length;\n if (depth !== path.length + 1) return true;\n\n if (nodeFilter !== undefined && event.params.node !== nodeFilter) {\n return true;\n }\n\n const data = event.params.data as MessagesEventData;\n\n switch (data.event) {\n case \"message-start\": {\n const key = getMessageStreamKey(data);\n const source = StreamChannel.local<ChatModelStreamEvent>();\n const stream = Object.assign(\n new CoreChatModelStream(source.toAsyncIterable()),\n {\n namespace: event.params.namespace,\n node: event.params.node,\n }\n ) as ChatModelStream;\n active.set(key, { source, stream });\n source.push(data as unknown as ChatModelStreamEvent);\n log.push(stream);\n break;\n }\n\n case \"content-block-start\":\n case \"content-block-delta\":\n case \"content-block-finish\":\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n\n case \"message-finish\": {\n const key = getMessageStreamKey(data);\n const stream = active.get(key);\n if (stream) {\n stream.source.push(data as unknown as ChatModelStreamEvent);\n stream.source.close();\n active.delete(key);\n }\n break;\n }\n\n case \"error\":\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n }\n\n return true;\n },\n\n finalize(): void {\n for (const [key, stream] of active) {\n stream.source.push({ event: \"message-finish\" });\n stream.source.close();\n active.delete(key);\n }\n log.close();\n },\n\n fail(err: unknown): void {\n for (const [key, stream] of active) {\n stream.source.fail(err);\n active.delete(key);\n }\n log.fail(err);\n },\n };\n}\n"],"mappings":";;;;AAkBA,SAAS,oBAAoB,MAAiC;CAC5D,MAAM,SAAS;AACf,KAAI,OAAO,OAAO,WAAW,SAAU,QAAO,OAAO,OAAO;AAC5D,KAAI,KAAK,UAAU,mBAAmB,OAAO,OAAO,OAAO,SACzD,QAAO,WAAW,OAAO;AAE3B,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,0BACd,MACA,YACkD;CAClD,MAAM,MAAMA,uBAAAA,cAAc,OAAwB;CAClD,MAAM,yBAAS,IAAI,KAAkC;
|
|
1
|
+
{"version":3,"file":"messages.cjs","names":["StreamChannel","hasPrefix","CoreChatModelStream"],"sources":["../../../src/stream/transformers/messages.ts"],"sourcesContent":["import type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChatModelStream as CoreChatModelStream } from \"@langchain/core/language_models/stream\";\nimport { hasPrefix } from \"../mux.js\";\nimport { StreamChannel } from \"../stream-channel.js\";\nimport type {\n ChatModelStream,\n MessagesEventData,\n Namespace,\n ProtocolEvent,\n StreamTransformer,\n} from \"../types.js\";\nimport type { MessagesTransformerProjection } from \"./types.js\";\n\ntype ActiveMessageStream = {\n source: StreamChannel<ChatModelStreamEvent>;\n stream: ChatModelStream;\n};\n\nfunction getMessageStreamKey(data: MessagesEventData): string {\n const record = data as unknown as Record<string, unknown>;\n if (typeof record.run_id === \"string\") return `run:${record.run_id}`;\n if (data.event === \"message-start\" && typeof record.id === \"string\") {\n return `message:${record.id}`;\n }\n return \"__default__\";\n}\n\n/**\n * Creates a {@link StreamTransformer} that groups `messages` channel events into\n * per-message {@link ChatModelStream} instances.\n *\n * A new `ChatModelStream` is created on `message-start` and closed on\n * `message-finish`. Content-block events in between are forwarded to the\n * active stream. Only events whose namespace exactly matches {@link path}\n * are processed; child namespaces are ignored.\n *\n * @param path - Namespace prefix to match against incoming events.\n * @param nodeFilter - If provided, only events emitted by this graph node\n * are processed; all others are skipped.\n * @returns A `StreamTransformer` whose projection contains the `messages`\n * async iterable.\n */\nexport function createMessagesTransformer(\n path: Namespace,\n nodeFilter?: string\n): StreamTransformer<MessagesTransformerProjection> {\n const log = StreamChannel.local<ChatModelStream>();\n const active = new Map<string, ActiveMessageStream>();\n const ignored = new Set<string>();\n\n return {\n init: () => ({\n messages: log.toAsyncIterable(),\n }),\n\n process(event: ProtocolEvent): boolean {\n if (event.method !== \"messages\") return true;\n if (!hasPrefix(event.params.namespace, path)) return true;\n\n // Only capture messages from this graph's own node executions,\n // which sit exactly one namespace level deeper than `path`.\n // Events at `path` itself are chain-level replays from the\n // callback system (handleChainEnd re-emits finalized messages)\n // and would duplicate the streamed content already captured\n // at depth+1.\n const depth = event.params.namespace.length;\n if (depth !== path.length + 1) return true;\n\n if (nodeFilter !== undefined && event.params.node !== nodeFilter) {\n return true;\n }\n\n const data = event.params.data as MessagesEventData;\n\n switch (data.event) {\n case \"message-start\": {\n const key = getMessageStreamKey(data);\n const role = (data as unknown as Record<string, unknown>).role;\n // Tool results belong on the tools stream and state snapshots, not\n // the chat-token projection exposed as `run.messages`.\n if (role === \"tool\") {\n ignored.add(key);\n break;\n }\n const source = StreamChannel.local<ChatModelStreamEvent>();\n const stream = Object.assign(\n new CoreChatModelStream(source.toAsyncIterable()),\n {\n namespace: event.params.namespace,\n node: event.params.node,\n }\n ) as ChatModelStream;\n active.set(key, { source, stream });\n source.push(data as unknown as ChatModelStreamEvent);\n log.push(stream);\n break;\n }\n\n case \"content-block-start\":\n case \"content-block-delta\":\n case \"content-block-finish\":\n if (ignored.has(getMessageStreamKey(data))) break;\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n\n case \"message-finish\": {\n const key = getMessageStreamKey(data);\n if (ignored.delete(key)) break;\n const stream = active.get(key);\n if (stream) {\n stream.source.push(data as unknown as ChatModelStreamEvent);\n stream.source.close();\n active.delete(key);\n }\n break;\n }\n\n case \"error\":\n if (ignored.has(getMessageStreamKey(data))) break;\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n }\n\n return true;\n },\n\n finalize(): void {\n for (const [key, stream] of active) {\n stream.source.push({ event: \"message-finish\" });\n stream.source.close();\n active.delete(key);\n }\n ignored.clear();\n log.close();\n },\n\n fail(err: unknown): void {\n for (const [key, stream] of active) {\n stream.source.fail(err);\n active.delete(key);\n }\n ignored.clear();\n log.fail(err);\n },\n };\n}\n"],"mappings":";;;;AAkBA,SAAS,oBAAoB,MAAiC;CAC5D,MAAM,SAAS;AACf,KAAI,OAAO,OAAO,WAAW,SAAU,QAAO,OAAO,OAAO;AAC5D,KAAI,KAAK,UAAU,mBAAmB,OAAO,OAAO,OAAO,SACzD,QAAO,WAAW,OAAO;AAE3B,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,0BACd,MACA,YACkD;CAClD,MAAM,MAAMA,uBAAAA,cAAc,OAAwB;CAClD,MAAM,yBAAS,IAAI,KAAkC;CACrD,MAAM,0BAAU,IAAI,KAAa;AAEjC,QAAO;EACL,aAAa,EACX,UAAU,IAAI,iBAAiB,EAChC;EAED,QAAQ,OAA+B;AACrC,OAAI,MAAM,WAAW,WAAY,QAAO;AACxC,OAAI,CAACC,YAAAA,UAAU,MAAM,OAAO,WAAW,KAAK,CAAE,QAAO;AASrD,OADc,MAAM,OAAO,UAAU,WACvB,KAAK,SAAS,EAAG,QAAO;AAEtC,OAAI,eAAe,KAAA,KAAa,MAAM,OAAO,SAAS,WACpD,QAAO;GAGT,MAAM,OAAO,MAAM,OAAO;AAE1B,WAAQ,KAAK,OAAb;IACE,KAAK,iBAAiB;KACpB,MAAM,MAAM,oBAAoB,KAAK;AAIrC,SAHc,KAA4C,SAG7C,QAAQ;AACnB,cAAQ,IAAI,IAAI;AAChB;;KAEF,MAAM,SAASD,uBAAAA,cAAc,OAA6B;KAC1D,MAAM,SAAS,OAAO,OACpB,IAAIE,uCAAAA,gBAAoB,OAAO,iBAAiB,CAAC,EACjD;MACE,WAAW,MAAM,OAAO;MACxB,MAAM,MAAM,OAAO;MACpB,CACF;AACD,YAAO,IAAI,KAAK;MAAE;MAAQ;MAAQ,CAAC;AACnC,YAAO,KAAK,KAAwC;AACpD,SAAI,KAAK,OAAO;AAChB;;IAGF,KAAK;IACL,KAAK;IACL,KAAK;AACH,SAAI,QAAQ,IAAI,oBAAoB,KAAK,CAAC,CAAE;AAC5C,YACG,IAAI,oBAAoB,KAAK,CAAC,EAC7B,OAAO,KAAK,KAAwC;AACxD;IAEF,KAAK,kBAAkB;KACrB,MAAM,MAAM,oBAAoB,KAAK;AACrC,SAAI,QAAQ,OAAO,IAAI,CAAE;KACzB,MAAM,SAAS,OAAO,IAAI,IAAI;AAC9B,SAAI,QAAQ;AACV,aAAO,OAAO,KAAK,KAAwC;AAC3D,aAAO,OAAO,OAAO;AACrB,aAAO,OAAO,IAAI;;AAEpB;;IAGF,KAAK;AACH,SAAI,QAAQ,IAAI,oBAAoB,KAAK,CAAC,CAAE;AAC5C,YACG,IAAI,oBAAoB,KAAK,CAAC,EAC7B,OAAO,KAAK,KAAwC;AACxD;;AAGJ,UAAO;;EAGT,WAAiB;AACf,QAAK,MAAM,CAAC,KAAK,WAAW,QAAQ;AAClC,WAAO,OAAO,KAAK,EAAE,OAAO,kBAAkB,CAAC;AAC/C,WAAO,OAAO,OAAO;AACrB,WAAO,OAAO,IAAI;;AAEpB,WAAQ,OAAO;AACf,OAAI,OAAO;;EAGb,KAAK,KAAoB;AACvB,QAAK,MAAM,CAAC,KAAK,WAAW,QAAQ;AAClC,WAAO,OAAO,KAAK,IAAI;AACvB,WAAO,OAAO,IAAI;;AAEpB,WAAQ,OAAO;AACf,OAAI,KAAK,IAAI;;EAEhB"}
|
|
@@ -26,6 +26,7 @@ function getMessageStreamKey(data) {
|
|
|
26
26
|
function createMessagesTransformer(path, nodeFilter) {
|
|
27
27
|
const log = StreamChannel.local();
|
|
28
28
|
const active = /* @__PURE__ */ new Map();
|
|
29
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
29
30
|
return {
|
|
30
31
|
init: () => ({ messages: log.toAsyncIterable() }),
|
|
31
32
|
process(event) {
|
|
@@ -37,6 +38,10 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
37
38
|
switch (data.event) {
|
|
38
39
|
case "message-start": {
|
|
39
40
|
const key = getMessageStreamKey(data);
|
|
41
|
+
if (data.role === "tool") {
|
|
42
|
+
ignored.add(key);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
40
45
|
const source = StreamChannel.local();
|
|
41
46
|
const stream = Object.assign(new ChatModelStream(source.toAsyncIterable()), {
|
|
42
47
|
namespace: event.params.namespace,
|
|
@@ -53,10 +58,12 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
53
58
|
case "content-block-start":
|
|
54
59
|
case "content-block-delta":
|
|
55
60
|
case "content-block-finish":
|
|
61
|
+
if (ignored.has(getMessageStreamKey(data))) break;
|
|
56
62
|
active.get(getMessageStreamKey(data))?.source.push(data);
|
|
57
63
|
break;
|
|
58
64
|
case "message-finish": {
|
|
59
65
|
const key = getMessageStreamKey(data);
|
|
66
|
+
if (ignored.delete(key)) break;
|
|
60
67
|
const stream = active.get(key);
|
|
61
68
|
if (stream) {
|
|
62
69
|
stream.source.push(data);
|
|
@@ -66,6 +73,7 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
66
73
|
break;
|
|
67
74
|
}
|
|
68
75
|
case "error":
|
|
76
|
+
if (ignored.has(getMessageStreamKey(data))) break;
|
|
69
77
|
active.get(getMessageStreamKey(data))?.source.push(data);
|
|
70
78
|
break;
|
|
71
79
|
}
|
|
@@ -77,6 +85,7 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
77
85
|
stream.source.close();
|
|
78
86
|
active.delete(key);
|
|
79
87
|
}
|
|
88
|
+
ignored.clear();
|
|
80
89
|
log.close();
|
|
81
90
|
},
|
|
82
91
|
fail(err) {
|
|
@@ -84,6 +93,7 @@ function createMessagesTransformer(path, nodeFilter) {
|
|
|
84
93
|
stream.source.fail(err);
|
|
85
94
|
active.delete(key);
|
|
86
95
|
}
|
|
96
|
+
ignored.clear();
|
|
87
97
|
log.fail(err);
|
|
88
98
|
}
|
|
89
99
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","names":["CoreChatModelStream"],"sources":["../../../src/stream/transformers/messages.ts"],"sourcesContent":["import type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChatModelStream as CoreChatModelStream } from \"@langchain/core/language_models/stream\";\nimport { hasPrefix } from \"../mux.js\";\nimport { StreamChannel } from \"../stream-channel.js\";\nimport type {\n ChatModelStream,\n MessagesEventData,\n Namespace,\n ProtocolEvent,\n StreamTransformer,\n} from \"../types.js\";\nimport type { MessagesTransformerProjection } from \"./types.js\";\n\ntype ActiveMessageStream = {\n source: StreamChannel<ChatModelStreamEvent>;\n stream: ChatModelStream;\n};\n\nfunction getMessageStreamKey(data: MessagesEventData): string {\n const record = data as unknown as Record<string, unknown>;\n if (typeof record.run_id === \"string\") return `run:${record.run_id}`;\n if (data.event === \"message-start\" && typeof record.id === \"string\") {\n return `message:${record.id}`;\n }\n return \"__default__\";\n}\n\n/**\n * Creates a {@link StreamTransformer} that groups `messages` channel events into\n * per-message {@link ChatModelStream} instances.\n *\n * A new `ChatModelStream` is created on `message-start` and closed on\n * `message-finish`. Content-block events in between are forwarded to the\n * active stream. Only events whose namespace exactly matches {@link path}\n * are processed; child namespaces are ignored.\n *\n * @param path - Namespace prefix to match against incoming events.\n * @param nodeFilter - If provided, only events emitted by this graph node\n * are processed; all others are skipped.\n * @returns A `StreamTransformer` whose projection contains the `messages`\n * async iterable.\n */\nexport function createMessagesTransformer(\n path: Namespace,\n nodeFilter?: string\n): StreamTransformer<MessagesTransformerProjection> {\n const log = StreamChannel.local<ChatModelStream>();\n const active = new Map<string, ActiveMessageStream>();\n\n return {\n init: () => ({\n messages: log.toAsyncIterable(),\n }),\n\n process(event: ProtocolEvent): boolean {\n if (event.method !== \"messages\") return true;\n if (!hasPrefix(event.params.namespace, path)) return true;\n\n // Only capture messages from this graph's own node executions,\n // which sit exactly one namespace level deeper than `path`.\n // Events at `path` itself are chain-level replays from the\n // callback system (handleChainEnd re-emits finalized messages)\n // and would duplicate the streamed content already captured\n // at depth+1.\n const depth = event.params.namespace.length;\n if (depth !== path.length + 1) return true;\n\n if (nodeFilter !== undefined && event.params.node !== nodeFilter) {\n return true;\n }\n\n const data = event.params.data as MessagesEventData;\n\n switch (data.event) {\n case \"message-start\": {\n const key = getMessageStreamKey(data);\n const source = StreamChannel.local<ChatModelStreamEvent>();\n const stream = Object.assign(\n new CoreChatModelStream(source.toAsyncIterable()),\n {\n namespace: event.params.namespace,\n node: event.params.node,\n }\n ) as ChatModelStream;\n active.set(key, { source, stream });\n source.push(data as unknown as ChatModelStreamEvent);\n log.push(stream);\n break;\n }\n\n case \"content-block-start\":\n case \"content-block-delta\":\n case \"content-block-finish\":\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n\n case \"message-finish\": {\n const key = getMessageStreamKey(data);\n const stream = active.get(key);\n if (stream) {\n stream.source.push(data as unknown as ChatModelStreamEvent);\n stream.source.close();\n active.delete(key);\n }\n break;\n }\n\n case \"error\":\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n }\n\n return true;\n },\n\n finalize(): void {\n for (const [key, stream] of active) {\n stream.source.push({ event: \"message-finish\" });\n stream.source.close();\n active.delete(key);\n }\n log.close();\n },\n\n fail(err: unknown): void {\n for (const [key, stream] of active) {\n stream.source.fail(err);\n active.delete(key);\n }\n log.fail(err);\n },\n };\n}\n"],"mappings":";;;;AAkBA,SAAS,oBAAoB,MAAiC;CAC5D,MAAM,SAAS;AACf,KAAI,OAAO,OAAO,WAAW,SAAU,QAAO,OAAO,OAAO;AAC5D,KAAI,KAAK,UAAU,mBAAmB,OAAO,OAAO,OAAO,SACzD,QAAO,WAAW,OAAO;AAE3B,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,0BACd,MACA,YACkD;CAClD,MAAM,MAAM,cAAc,OAAwB;CAClD,MAAM,yBAAS,IAAI,KAAkC;
|
|
1
|
+
{"version":3,"file":"messages.js","names":["CoreChatModelStream"],"sources":["../../../src/stream/transformers/messages.ts"],"sourcesContent":["import type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChatModelStream as CoreChatModelStream } from \"@langchain/core/language_models/stream\";\nimport { hasPrefix } from \"../mux.js\";\nimport { StreamChannel } from \"../stream-channel.js\";\nimport type {\n ChatModelStream,\n MessagesEventData,\n Namespace,\n ProtocolEvent,\n StreamTransformer,\n} from \"../types.js\";\nimport type { MessagesTransformerProjection } from \"./types.js\";\n\ntype ActiveMessageStream = {\n source: StreamChannel<ChatModelStreamEvent>;\n stream: ChatModelStream;\n};\n\nfunction getMessageStreamKey(data: MessagesEventData): string {\n const record = data as unknown as Record<string, unknown>;\n if (typeof record.run_id === \"string\") return `run:${record.run_id}`;\n if (data.event === \"message-start\" && typeof record.id === \"string\") {\n return `message:${record.id}`;\n }\n return \"__default__\";\n}\n\n/**\n * Creates a {@link StreamTransformer} that groups `messages` channel events into\n * per-message {@link ChatModelStream} instances.\n *\n * A new `ChatModelStream` is created on `message-start` and closed on\n * `message-finish`. Content-block events in between are forwarded to the\n * active stream. Only events whose namespace exactly matches {@link path}\n * are processed; child namespaces are ignored.\n *\n * @param path - Namespace prefix to match against incoming events.\n * @param nodeFilter - If provided, only events emitted by this graph node\n * are processed; all others are skipped.\n * @returns A `StreamTransformer` whose projection contains the `messages`\n * async iterable.\n */\nexport function createMessagesTransformer(\n path: Namespace,\n nodeFilter?: string\n): StreamTransformer<MessagesTransformerProjection> {\n const log = StreamChannel.local<ChatModelStream>();\n const active = new Map<string, ActiveMessageStream>();\n const ignored = new Set<string>();\n\n return {\n init: () => ({\n messages: log.toAsyncIterable(),\n }),\n\n process(event: ProtocolEvent): boolean {\n if (event.method !== \"messages\") return true;\n if (!hasPrefix(event.params.namespace, path)) return true;\n\n // Only capture messages from this graph's own node executions,\n // which sit exactly one namespace level deeper than `path`.\n // Events at `path` itself are chain-level replays from the\n // callback system (handleChainEnd re-emits finalized messages)\n // and would duplicate the streamed content already captured\n // at depth+1.\n const depth = event.params.namespace.length;\n if (depth !== path.length + 1) return true;\n\n if (nodeFilter !== undefined && event.params.node !== nodeFilter) {\n return true;\n }\n\n const data = event.params.data as MessagesEventData;\n\n switch (data.event) {\n case \"message-start\": {\n const key = getMessageStreamKey(data);\n const role = (data as unknown as Record<string, unknown>).role;\n // Tool results belong on the tools stream and state snapshots, not\n // the chat-token projection exposed as `run.messages`.\n if (role === \"tool\") {\n ignored.add(key);\n break;\n }\n const source = StreamChannel.local<ChatModelStreamEvent>();\n const stream = Object.assign(\n new CoreChatModelStream(source.toAsyncIterable()),\n {\n namespace: event.params.namespace,\n node: event.params.node,\n }\n ) as ChatModelStream;\n active.set(key, { source, stream });\n source.push(data as unknown as ChatModelStreamEvent);\n log.push(stream);\n break;\n }\n\n case \"content-block-start\":\n case \"content-block-delta\":\n case \"content-block-finish\":\n if (ignored.has(getMessageStreamKey(data))) break;\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n\n case \"message-finish\": {\n const key = getMessageStreamKey(data);\n if (ignored.delete(key)) break;\n const stream = active.get(key);\n if (stream) {\n stream.source.push(data as unknown as ChatModelStreamEvent);\n stream.source.close();\n active.delete(key);\n }\n break;\n }\n\n case \"error\":\n if (ignored.has(getMessageStreamKey(data))) break;\n active\n .get(getMessageStreamKey(data))\n ?.source.push(data as unknown as ChatModelStreamEvent);\n break;\n }\n\n return true;\n },\n\n finalize(): void {\n for (const [key, stream] of active) {\n stream.source.push({ event: \"message-finish\" });\n stream.source.close();\n active.delete(key);\n }\n ignored.clear();\n log.close();\n },\n\n fail(err: unknown): void {\n for (const [key, stream] of active) {\n stream.source.fail(err);\n active.delete(key);\n }\n ignored.clear();\n log.fail(err);\n },\n };\n}\n"],"mappings":";;;;AAkBA,SAAS,oBAAoB,MAAiC;CAC5D,MAAM,SAAS;AACf,KAAI,OAAO,OAAO,WAAW,SAAU,QAAO,OAAO,OAAO;AAC5D,KAAI,KAAK,UAAU,mBAAmB,OAAO,OAAO,OAAO,SACzD,QAAO,WAAW,OAAO;AAE3B,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAgB,0BACd,MACA,YACkD;CAClD,MAAM,MAAM,cAAc,OAAwB;CAClD,MAAM,yBAAS,IAAI,KAAkC;CACrD,MAAM,0BAAU,IAAI,KAAa;AAEjC,QAAO;EACL,aAAa,EACX,UAAU,IAAI,iBAAiB,EAChC;EAED,QAAQ,OAA+B;AACrC,OAAI,MAAM,WAAW,WAAY,QAAO;AACxC,OAAI,CAAC,UAAU,MAAM,OAAO,WAAW,KAAK,CAAE,QAAO;AASrD,OADc,MAAM,OAAO,UAAU,WACvB,KAAK,SAAS,EAAG,QAAO;AAEtC,OAAI,eAAe,KAAA,KAAa,MAAM,OAAO,SAAS,WACpD,QAAO;GAGT,MAAM,OAAO,MAAM,OAAO;AAE1B,WAAQ,KAAK,OAAb;IACE,KAAK,iBAAiB;KACpB,MAAM,MAAM,oBAAoB,KAAK;AAIrC,SAHc,KAA4C,SAG7C,QAAQ;AACnB,cAAQ,IAAI,IAAI;AAChB;;KAEF,MAAM,SAAS,cAAc,OAA6B;KAC1D,MAAM,SAAS,OAAO,OACpB,IAAIA,gBAAoB,OAAO,iBAAiB,CAAC,EACjD;MACE,WAAW,MAAM,OAAO;MACxB,MAAM,MAAM,OAAO;MACpB,CACF;AACD,YAAO,IAAI,KAAK;MAAE;MAAQ;MAAQ,CAAC;AACnC,YAAO,KAAK,KAAwC;AACpD,SAAI,KAAK,OAAO;AAChB;;IAGF,KAAK;IACL,KAAK;IACL,KAAK;AACH,SAAI,QAAQ,IAAI,oBAAoB,KAAK,CAAC,CAAE;AAC5C,YACG,IAAI,oBAAoB,KAAK,CAAC,EAC7B,OAAO,KAAK,KAAwC;AACxD;IAEF,KAAK,kBAAkB;KACrB,MAAM,MAAM,oBAAoB,KAAK;AACrC,SAAI,QAAQ,OAAO,IAAI,CAAE;KACzB,MAAM,SAAS,OAAO,IAAI,IAAI;AAC9B,SAAI,QAAQ;AACV,aAAO,OAAO,KAAK,KAAwC;AAC3D,aAAO,OAAO,OAAO;AACrB,aAAO,OAAO,IAAI;;AAEpB;;IAGF,KAAK;AACH,SAAI,QAAQ,IAAI,oBAAoB,KAAK,CAAC,CAAE;AAC5C,YACG,IAAI,oBAAoB,KAAK,CAAC,EAC7B,OAAO,KAAK,KAAwC;AACxD;;AAGJ,UAAO;;EAGT,WAAiB;AACf,QAAK,MAAM,CAAC,KAAK,WAAW,QAAQ;AAClC,WAAO,OAAO,KAAK,EAAE,OAAO,kBAAkB,CAAC;AAC/C,WAAO,OAAO,OAAO;AACrB,WAAO,OAAO,IAAI;;AAEpB,WAAQ,OAAO;AACf,OAAI,OAAO;;EAGb,KAAK,KAAoB;AACvB,QAAK,MAAM,CAAC,KAAK,WAAW,QAAQ;AAClC,WAAO,OAAO,KAAK,IAAI;AACvB,WAAO,OAAO,IAAI;;AAEpB,WAAQ,OAAO;AACf,OAAI,KAAK,IAAI;;EAEhB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/langgraph",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "LangGraph",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@standard-schema/spec": "1.1.0",
|
|
21
21
|
"uuid": "^10.0.0",
|
|
22
22
|
"@langchain/langgraph-checkpoint": "^1.0.2",
|
|
23
|
-
"@langchain/langgraph-sdk": "~1.9.
|
|
23
|
+
"@langchain/langgraph-sdk": "~1.9.3"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@langchain/core": "^1.1.44",
|