{"version":3,"file":"messages.cjs","names":["BaseCallbackHandler","AIMessageChunk"],"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\nfunction normalizeStreamMetadata(\n  metadata?: Record<string, unknown>,\n  tags?: string[],\n  name?: string\n): Meta | undefined {\n  if (!metadata) {\n    return undefined;\n  }\n  const streamNamespace = metadata.langgraph_checkpoint_ns as\n    | string\n    | undefined;\n  const checkpointNs = metadata.checkpoint_ns as string | undefined;\n  const namespace = streamNamespace ?? checkpointNs;\n  if (!namespace) {\n    return undefined;\n  }\n  return [namespace.split(\"|\"), { tags, name, ...metadata }];\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] = normalizeStreamMetadata(metadata, tags, name);\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] = normalizeStreamMetadata(metadata, tags, name);\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,SAAA,GAAA,yBAAA,eAAsB,GAA2B,QAAQ;;AAG3D,SAAS,wBACP,UACA,MACA,MACkB;AAClB,KAAI,CAAC,SACH;CAEF,MAAM,kBAAkB,SAAS;CAGjC,MAAM,eAAe,SAAS;CAC9B,MAAM,YAAY,mBAAmB;AACrC,KAAI,CAAC,UACH;AAEF,QAAO,CAAC,UAAU,MAAM,IAAI,EAAE;EAAE;EAAM;EAAM,GAAG;EAAU,CAAC;;;;;;AAS5D,IAAa,wBAAb,cAA2CA,+BAAAA,oBAAoB;CAC7D,OAAO;CAEP;CAEA,YAA8C,EAAE;CAEhD,OAAoC,EAAE;CAEtC,yBAAkD,EAAE;CAEpD,qBAA6C,EAAE;CAE/C,sBAAsB;CAEtB,YAAY,UAA8C;AACxD,SAAO;AACP,OAAK,WAAW;;CAGlB,MACE,MACA,SACA,OACA,SAAS,OACT;AACA,MACE,UACA,QAAQ,OAAO,KAAA,KACf,KAAK,KAAK,QAAQ,QAAQ,KAAA,EAE1B;EAGF,IAAI,YAAY,QAAQ;AAExB,MAAI,SAAS,KACX,MAAA,GAAA,yBAAA,eAAkB,QAAQ,CAExB,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,GAAG;GAAC,CAAC;;CAG1D,qBACE,MACA,WACA,OACA,cACA,cACA,MACA,UACA,MACA;AACA,MACE,aAEC,CAAC,QAAS,CAAC,KAAK,SAAA,qBAAsB,IAAI,CAAC,KAAK,SAAS,WAAW,EAErE,MAAK,UAAU,SAAS,wBAAwB,UAAU,MAAM,KAAK;;CAIzE,kBACE,OACA,MACA,OACA,cACA,OACA,QACA;EACA,MAAM,QAAQ,QAAQ;AACtB,OAAK,uBAAuB,SAAS;AACrC,MAAI,KAAK,UAAU,WAAW,KAAA,EAC5B,KAAI,sBAAsB,MAAM,CAC9B,MAAK,MAAM,KAAK,UAAU,QAAQ,MAAM,SAAS,MAAM;MAEvD,MAAK,MACH,KAAK,UAAU,QACf,IAAIC,yBAAAA,eAAe,EAAE,SAAS,OAAO,CAAC,EACtC,MACD;;CAKP,aAAa,QAAmB,OAAe;AAE7C,MAAI,KAAK,UAAU,WAAW,KAAA,EAAW;AAGzC,MAAI,CAAC,KAAK,uBAAuB,QAAQ;GACvC,MAAM,iBAAiB,OAAO,cAAc,KAAK;AACjD,QAAA,GAAA,yBAAA,eAAkB,gBAAgB,QAAQ,CACxC,MAAK,MAAM,KAAK,UAAU,QAAQ,gBAAgB,SAAS,OAAO,KAAK;AAEzE,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,KAAA,KACb,SAAS,SAAS,mBACjB,SAAS,KAAA,KAAa,CAAC,KAAK,SAAA,mBAAoB,GACjD;AACA,QAAK,UAAU,SAAS,wBAAwB,UAAU,MAAM,KAAK;AAErE,OAAI,OAAO,WAAW;SACf,MAAM,SAAS,OAAO,OAAO,OAAO,CACvC,OAAA,GAAA,yBAAA,eACiB,MAAM,KAAA,GAAA,yBAAA,oBAAuB,MAAM,KAClD,MAAM,OAAO,KAAA,EAEb,MAAK,KAAK,MAAM,MAAM;aACb,MAAM,QAAQ,MAAM;UACxB,MAAM,QAAQ,MACjB,OAAA,GAAA,yBAAA,eACiB,KAAK,KAAA,GAAA,yBAAA,oBAAuB,KAAK,KAChD,KAAK,OAAO,KAAA,EAEZ,MAAK,KAAK,KAAK,MAAM;;;;;CASnC,eAAe,SAAsB,OAAe;EAClD,MAAM,WAAW,KAAK,UAAU;AAChC,SAAO,KAAK,UAAU;AACtB,MAAI,aAAa,KAAA;mDACG,QAAQ,CACxB,MAAK,MAAM,UAAU,SAAS,OAAO,KAAK;YACjC,MAAM,QAAQ,QAAQ;SAC1B,MAAM,SAAS,QAClB,MAAA,GAAA,yBAAA,eAAkB,MAAM,CACtB,MAAK,MAAM,UAAU,OAAO,OAAO,KAAK;cAGnC,WAAW,QAAQ,OAAO,YAAY;SAC1C,MAAM,SAAS,OAAO,OAAO,QAAQ,CACxC,MAAA,GAAA,yBAAA,eAAkB,MAAM,CACtB,MAAK,MAAM,UAAU,OAAO,OAAO,KAAK;aAC/B,MAAM,QAAQ,MAAM;UACxB,MAAM,QAAQ,MACjB,MAAA,GAAA,yBAAA,eAAkB,KAAK,CACrB,MAAK,MAAM,UAAU,MAAM,OAAO,KAAK;;;;;CAUrD,iBAAiB,MAAW,OAAe;AACzC,SAAO,KAAK,UAAU"}