{"version":3,"file":"messages.cjs","names":["HumanMessageChunk","AIMessageChunk","SystemMessageChunk","ToolMessageChunk","RemoveMessage"],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n  type BaseMessage,\n  BaseMessageChunk,\n  RemoveMessage,\n  convertToChunk,\n  coerceMessageLikeToMessage,\n  isBaseMessageChunk,\n  HumanMessageChunk,\n  SystemMessageChunk,\n  AIMessageChunk,\n  ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n  ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n  : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n  ? ThreadState<StateWithBaseMessages<S>>[]\n  : T;\n\nexport function tryConvertToChunk(\n  message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n  try {\n    if (isBaseMessageChunk(message)) return message;\n    return convertToChunk(message);\n  } catch {\n    return null;\n  }\n}\n\nexport function tryCoerceMessageLikeToMessage(\n  message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n  if (message.type === \"human\" || message.type === \"user\") {\n    return new HumanMessageChunk(message);\n  }\n\n  if (message.type === \"ai\" || message.type === \"assistant\") {\n    return new AIMessageChunk(message);\n  }\n\n  if (message.type === \"system\") {\n    return new SystemMessageChunk(message);\n  }\n\n  if (message.type === \"tool\" && \"tool_call_id\" in message) {\n    return new ToolMessageChunk({\n      ...message,\n      tool_call_id: message.tool_call_id as string,\n    });\n  }\n\n  if (message.type === \"remove\" && message.id != null) {\n    return new RemoveMessage({ ...message, id: message.id });\n  }\n\n  return coerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n  chunks: Record<\n    string,\n    {\n      chunk?: BaseMessageChunk | BaseMessage;\n      metadata?: Record<string, unknown>;\n      index?: number;\n    }\n  > = {};\n\n  constructor() {\n    this.chunks = {};\n  }\n\n  add(\n    serialized: Message,\n    metadata: Record<string, unknown> | undefined\n  ): string | null {\n    // TODO: this is sometimes sent from the API\n    // figure out how to prevent this or move this to LC.js\n    if (serialized.type.endsWith(\"MessageChunk\")) {\n      // eslint-disable-next-line no-param-reassign\n      serialized.type = serialized.type\n        .slice(0, -\"MessageChunk\".length)\n        .toLowerCase() as Message[\"type\"];\n    }\n\n    const message = tryCoerceMessageLikeToMessage(serialized);\n    const chunk = tryConvertToChunk(message);\n\n    const { id } = chunk ?? message;\n    if (!id) {\n      console.warn(\n        \"No message ID found for chunk, ignoring in state\",\n        serialized\n      );\n      return null;\n    }\n\n    this.chunks[id] ??= {};\n    this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n    if (chunk) {\n      const prev = this.chunks[id].chunk;\n      this.chunks[id].chunk =\n        (isBaseMessageChunk(prev) ? prev : null)?.concat(chunk) ?? chunk;\n    } else {\n      this.chunks[id].chunk = message;\n    }\n\n    return id;\n  }\n\n  clear() {\n    this.chunks = {};\n  }\n\n  get(id: string | null | undefined, defaultIndex?: number) {\n    if (id == null) return null;\n    if (this.chunks[id] == null) return null;\n    if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n    return this.chunks[id];\n  }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n  const { type, data } = chunk.toDict();\n  return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n  messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n  return messages.map((msg) => {\n    if (typeof (msg as BaseMessage).getType === \"function\") {\n      return msg as BaseMessage;\n    }\n    return tryCoerceMessageLikeToMessage(\n      msg as Omit<Message, \"type\"> & { type: string }\n    );\n  });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n  StateType extends Record<string, unknown>,\n>(\n  history: ThreadState<StateType>[],\n  messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n  return history.map((state) => {\n    if (state.values == null) return state;\n    const messages = state.values[messagesKey];\n    if (!Array.isArray(messages)) return state;\n    return {\n      ...state,\n      values: {\n        ...state.values,\n        [messagesKey]: ensureMessageInstances(messages),\n      },\n    };\n  });\n}\n"],"mappings":";;;AAiCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,OAAA,GAAA,yBAAA,oBAAuB,QAAQ,CAAE,QAAO;AACxC,UAAA,GAAA,yBAAA,gBAAsB,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAgB,8BACd,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAIA,yBAAAA,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAIC,yBAAAA,eAAe,QAAQ;AAGpC,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAIC,yBAAAA,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAIC,yBAAAA,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,KAAI,QAAQ,SAAS,YAAY,QAAQ,MAAM,KAC7C,QAAO,IAAIC,yBAAAA,cAAc;EAAE,GAAG;EAAS,IAAI,QAAQ;EAAI,CAAC;AAG1D,SAAA,GAAA,yBAAA,4BAAkC,QAAQ;;AAG5C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,8BAA8B,WAAW;EACzD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,UAAA,GAAA,yBAAA,oBACM,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAAI;QAE7D,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAO,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsB,YACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}