UNPKG

@langchain/langgraph

Version:

LangGraph

1 lines 9.75 kB
{"version":3,"file":"messages.cjs","names":["BaseCallbackHandler","TAG_NOSTREAM","AIMessageChunk","TAG_HIDDEN"],"sources":["../../src/pregel/messages.ts"],"sourcesContent":["import {\n BaseCallbackHandler,\n HandleLLMNewTokenCallbackFields,\n NewTokenIndices,\n} from \"@langchain/core/callbacks/base\";\nimport {\n AIMessageChunk,\n BaseMessage,\n isBaseMessage,\n isBaseMessageChunk,\n isToolMessage,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport {\n ChatGeneration,\n ChatGenerationChunk,\n LLMResult,\n} from \"@langchain/core/outputs\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Meta = [string[], Record<string, any>];\n\nfunction isChatGenerationChunk(x: unknown): x is ChatGenerationChunk {\n return isBaseMessage((x as ChatGenerationChunk)?.message);\n}\n\n/**\n * A callback handler that implements stream_mode=messages.\n * Collects messages from (1) chat model stream events and (2) node outputs.\n */\n// TODO: Make this import and explicitly implement the\n// CallbackHandlerPrefersStreaming interface once we drop support for core 0.2\nexport class StreamMessagesHandler extends BaseCallbackHandler {\n name = \"StreamMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage> = {};\n\n emittedChatModelRunIds: Record<string, boolean> = {};\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_streaming = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n _emit(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n if (\n dedupe &&\n message.id !== undefined &&\n this.seen[message.id] !== undefined\n ) {\n return;\n }\n\n let messageId = message.id;\n\n if (runId != null) {\n if (isToolMessage(message)) {\n // Distinguish tool messages by tool call ID.\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n // For instance in ChatAnthropic, the first chunk has an message ID\n // but the subsequent chunks do not. To avoid clients seeing two messages\n // we rename the message ID if it's being auto-set to `run-${runId}`\n // (see https://github.com/langchain-ai/langchainjs/pull/6646).\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\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\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 this.streamFn([meta[0], \"messages\", [message, meta[1]]]);\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 // Include legacy LangGraph SDK tag\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 token: string,\n _idx: NewTokenIndices,\n runId: string,\n _parentRunId?: string,\n _tags?: string[],\n fields?: HandleLLMNewTokenCallbackFields\n ) {\n const chunk = fields?.chunk;\n this.emittedChatModelRunIds[runId] = true;\n if (this.metadatas[runId] !== undefined) {\n if (isChatGenerationChunk(chunk)) {\n this._emit(this.metadatas[runId], chunk.message, runId);\n } else {\n this._emit(\n this.metadatas[runId],\n new AIMessageChunk({ content: token }),\n runId\n );\n }\n }\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n // Filter out runs that we do not have metadata for\n if (this.metadatas[runId] === undefined) return;\n\n // In JS, non-streaming runs do not call handleLLMNewToken at the model level\n if (!this.emittedChatModelRunIds[runId]) {\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n if (isBaseMessage(chatGeneration?.message)) {\n this._emit(this.metadatas[runId], chatGeneration?.message, runId, true);\n }\n delete this.emittedChatModelRunIds[runId];\n }\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 delete this.metadatas[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 metadata = this.metadatas[runId];\n delete this.metadatas[runId];\n if (metadata !== undefined) {\n if (isBaseMessage(outputs)) {\n this._emit(metadata, outputs, runId, true);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) {\n if (isBaseMessage(value)) {\n this._emit(metadata, value, runId, true);\n }\n }\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (isBaseMessage(value)) {\n this._emit(metadata, value, runId, true);\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (isBaseMessage(item)) {\n this._emit(metadata, item, runId, true);\n }\n }\n }\n }\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n }\n}\n"],"mappings":";;;;;;AA0BA,SAAS,sBAAsB,GAAsC;AACnE,qDAAsB,GAA2B;;;;;;AASnD,IAAa,wBAAb,cAA2CA,oDAAoB;CAC7D,OAAO;CAEP;CAEA,YAA8C;CAE9C,OAAoC;CAEpC,yBAAkD;CAElD,qBAA6C;CAE7C,sBAAsB;CAEtB,YAAY,UAA8C;AACxD;AACA,OAAK,WAAW;;CAGlB,MACE,MACA,SACA,OACA,SAAS,OACT;AACA,MACE,UACA,QAAQ,OAAO,UACf,KAAK,KAAK,QAAQ,QAAQ,OAE1B;EAGF,IAAI,YAAY,QAAQ;AAExB,MAAI,SAAS,KACX,kDAAkB,SAEhB,eAAc,OAAO,MAAM,QAAQ,QAAQ;OACtC;AAKL,OAAI,aAAa,QAAQ,cAAc,OAAO,QAC5C,aACE,KAAK,mBAAmB,UAAU,aAAa,OAAO;AAG1D,QAAK,mBAAmB,WAAW;;AAIvC,MAAI,cAAc,QAAQ,IAAI;AAE5B,WAAQ,KAAK;AAGb,WAAQ,UAAU,KAAK;;AAGzB,MAAI,QAAQ,MAAM,KAAM,MAAK,KAAK,QAAQ,MAAM;AAChD,OAAK,SAAS;GAAC,KAAK;GAAI;GAAY,CAAC,SAAS,KAAK;;;CAGrD,qBACE,MACA,WACA,OACA,cACA,cACA,MACA,UACA,MACA;AACA,MACE,aAEC,CAAC,QAAS,CAAC,KAAK,SAASC,mCAAiB,CAAC,KAAK,SAAS,aAE1D,MAAK,UAAU,SAAS,CACrB,SAAS,wBAAmC,MAAM,MACnD;GAAE;GAAM;GAAM,GAAG;;;CAKvB,kBACE,OACA,MACA,OACA,cACA,OACA,QACA;EACA,MAAM,QAAQ,QAAQ;AACtB,OAAK,uBAAuB,SAAS;AACrC,MAAI,KAAK,UAAU,WAAW,OAC5B,KAAI,sBAAsB,OACxB,MAAK,MAAM,KAAK,UAAU,QAAQ,MAAM,SAAS;MAEjD,MAAK,MACH,KAAK,UAAU,QACf,IAAIC,yCAAe,EAAE,SAAS,UAC9B;;CAMR,aAAa,QAAmB,OAAe;AAE7C,MAAI,KAAK,UAAU,WAAW,OAAW;AAGzC,MAAI,CAAC,KAAK,uBAAuB,QAAQ;GACvC,MAAM,iBAAiB,OAAO,cAAc,KAAK;AACjD,oDAAkB,gBAAgB,SAChC,MAAK,MAAM,KAAK,UAAU,QAAQ,gBAAgB,SAAS,OAAO;AAEpE,UAAO,KAAK,uBAAuB;;AAErC,SAAO,KAAK,UAAU;AACtB,SAAO,KAAK,mBAAmB;;CAIjC,eAAe,MAAW,OAAe;AACvC,SAAO,KAAK,UAAU;;CAGxB,iBACE,QACA,QACA,OACA,cACA,MACA,UACA,UACA,MACA;AACA,MACE,aAAa,UACb,SAAS,SAAS,mBACjB,SAAS,UAAa,CAAC,KAAK,SAASC,gCACtC;AACA,QAAK,UAAU,SAAS,CACrB,SAAS,wBAAmC,MAAM,MACnD;IAAE;IAAM;IAAM,GAAG;;AAGnB,OAAI,OAAO,WAAW,UACpB;SAAK,MAAM,SAAS,OAAO,OAAO,QAChC,mDACiB,4DAA6B,WAC5C,MAAM,OAAO,OAEb,MAAK,KAAK,MAAM,MAAM;aACb,MAAM,QAAQ,QACvB;UAAK,MAAM,QAAQ,MACjB,mDACiB,2DAA4B,UAC3C,KAAK,OAAO,OAEZ,MAAK,KAAK,KAAK,MAAM;;;;;CASnC,eAAe,SAAsB,OAAe;EAClD,MAAM,WAAW,KAAK,UAAU;AAChC,SAAO,KAAK,UAAU;AACtB,MAAI,aAAa,QACf;oDAAkB,SAChB,MAAK,MAAM,UAAU,SAAS,OAAO;YAC5B,MAAM,QAAQ,UACvB;SAAK,MAAM,SAAS,QAClB,kDAAkB,OAChB,MAAK,MAAM,UAAU,OAAO,OAAO;cAG9B,WAAW,QAAQ,OAAO,YAAY,UAC/C;SAAK,MAAM,SAAS,OAAO,OAAO,SAChC,kDAAkB,OAChB,MAAK,MAAM,UAAU,OAAO,OAAO;aAC1B,MAAM,QAAQ,QACvB;UAAK,MAAM,QAAQ,MACjB,kDAAkB,MAChB,MAAK,MAAM,UAAU,MAAM,OAAO;;;;;CAUhD,iBAAiB,MAAW,OAAe;AACzC,SAAO,KAAK,UAAU"}