{"version":3,"file":"convex.cjs","names":["BaseListChatMessageHistory"],"sources":["../../../src/stores/message/convex.ts"],"sourcesContent":["/* oxlint-disable typescript/no-explicit-any */\n\nimport {\n  DocumentByInfo,\n  DocumentByName,\n  FieldPaths,\n  FunctionReference,\n  GenericActionCtx,\n  GenericDataModel,\n  NamedTableInfo,\n  TableNamesInDataModel,\n  IndexNames,\n  makeFunctionReference,\n} from \"convex/server\";\nimport { BaseListChatMessageHistory } from \"@langchain/core/chat_history\";\nimport {\n  BaseMessage,\n  mapChatMessagesToStoredMessages,\n  mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\n\n/**\n * Type that defines the config required to initialize the\n * ConvexChatMessageHistory class. At minimum it needs a sessionId\n * and an ActionCtx.\n */\nexport type ConvexChatMessageHistoryInput<\n  DataModel extends GenericDataModel,\n  TableName extends TableNamesInDataModel<DataModel> = \"messages\",\n  IndexName extends IndexNames<NamedTableInfo<DataModel, TableName>> =\n    \"bySessionId\",\n  SessionIdFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>> =\n    \"sessionId\",\n  MessageTextFieldName extends FieldPaths<\n    NamedTableInfo<DataModel, TableName>\n  > = \"message\",\n  InsertMutation extends FunctionReference<\n    \"mutation\",\n    \"internal\",\n    { table: string; document: object }\n  > = any,\n  LookupQuery extends FunctionReference<\n    \"query\",\n    \"internal\",\n    { table: string; index: string; keyField: string; key: string },\n    object[]\n  > = any,\n  DeleteManyMutation extends FunctionReference<\n    \"mutation\",\n    \"internal\",\n    { table: string; index: string; keyField: string; key: string }\n  > = any,\n> = {\n  readonly ctx: GenericActionCtx<DataModel>;\n  readonly sessionId: DocumentByName<DataModel, TableName>[SessionIdFieldName];\n  /**\n   * Defaults to \"messages\"\n   */\n  readonly table?: TableName;\n  /**\n   * Defaults to \"bySessionId\"\n   */\n  readonly index?: IndexName;\n  /**\n   * Defaults to \"sessionId\"\n   */\n  readonly sessionIdField?: SessionIdFieldName;\n  /**\n   * Defaults to \"message\"\n   */\n  readonly messageTextFieldName?: MessageTextFieldName;\n  /**\n   * Defaults to `internal.langchain.db.insert`\n   */\n  readonly insert?: InsertMutation;\n  /**\n   * Defaults to `internal.langchain.db.lookup`\n   */\n  readonly lookup?: LookupQuery;\n  /**\n   * Defaults to `internal.langchain.db.deleteMany`\n   */\n  readonly deleteMany?: DeleteManyMutation;\n};\n\nexport class ConvexChatMessageHistory<\n  DataModel extends GenericDataModel,\n  SessionIdFieldName extends FieldPaths<NamedTableInfo<DataModel, TableName>> =\n    \"sessionId\",\n  TableName extends TableNamesInDataModel<DataModel> = \"messages\",\n  IndexName extends IndexNames<NamedTableInfo<DataModel, TableName>> =\n    \"bySessionId\",\n  MessageTextFieldName extends FieldPaths<\n    NamedTableInfo<DataModel, TableName>\n  > = \"message\",\n  InsertMutation extends FunctionReference<\n    \"mutation\",\n    \"internal\",\n    { table: string; document: object }\n  > = any,\n  LookupQuery extends FunctionReference<\n    \"query\",\n    \"internal\",\n    { table: string; index: string; keyField: string; key: string },\n    object[]\n  > = any,\n  DeleteManyMutation extends FunctionReference<\n    \"mutation\",\n    \"internal\",\n    { table: string; index: string; keyField: string; key: string }\n  > = any,\n> extends BaseListChatMessageHistory {\n  lc_namespace = [\"langchain\", \"stores\", \"message\", \"convex\"];\n\n  private readonly ctx: GenericActionCtx<DataModel>;\n\n  private readonly sessionId: DocumentByInfo<\n    NamedTableInfo<DataModel, TableName>\n  >[SessionIdFieldName];\n\n  private readonly table: TableName;\n\n  private readonly index: IndexName;\n\n  private readonly sessionIdField: SessionIdFieldName;\n\n  private readonly messageTextFieldName: MessageTextFieldName;\n\n  private readonly insert: InsertMutation;\n\n  private readonly lookup: LookupQuery;\n\n  private readonly deleteMany: DeleteManyMutation;\n\n  constructor(\n    config: ConvexChatMessageHistoryInput<\n      DataModel,\n      TableName,\n      IndexName,\n      SessionIdFieldName,\n      MessageTextFieldName,\n      InsertMutation,\n      LookupQuery,\n      DeleteManyMutation\n    >\n  ) {\n    super();\n    this.ctx = config.ctx;\n    this.sessionId = config.sessionId;\n    this.table = config.table ?? (\"messages\" as TableName);\n    this.index = config.index ?? (\"bySessionId\" as IndexName);\n    this.sessionIdField =\n      config.sessionIdField ?? (\"sessionId\" as SessionIdFieldName);\n    this.messageTextFieldName =\n      config.messageTextFieldName ?? (\"message\" as MessageTextFieldName);\n    this.insert =\n      config.insert ?? (makeFunctionReference(\"langchain/db:insert\") as any);\n    this.lookup =\n      config.lookup ?? (makeFunctionReference(\"langchain/db:lookup\") as any);\n    this.deleteMany =\n      config.deleteMany ??\n      (makeFunctionReference(\"langchain/db:deleteMany\") as any);\n  }\n\n  async getMessages(): Promise<BaseMessage[]> {\n    const convexDocuments: any[] = await this.ctx.runQuery(this.lookup, {\n      table: this.table,\n      index: this.index,\n      keyField: this.sessionIdField,\n      key: this.sessionId,\n    } as any);\n\n    return mapStoredMessagesToChatMessages(\n      convexDocuments.map((doc) => doc[this.messageTextFieldName])\n    );\n  }\n\n  async addMessage(message: BaseMessage): Promise<void> {\n    const messages = mapChatMessagesToStoredMessages([message]);\n    // TODO: Remove chunking when Convex handles the concurrent requests correctly\n    const PAGE_SIZE = 16;\n    for (let i = 0; i < messages.length; i += PAGE_SIZE) {\n      await Promise.all(\n        messages.slice(i, i + PAGE_SIZE).map((message) =>\n          this.ctx.runMutation(this.insert, {\n            table: this.table,\n            document: {\n              [this.sessionIdField]: this.sessionId,\n              [this.messageTextFieldName]: message,\n            },\n          } as any)\n        )\n      );\n    }\n  }\n\n  async clear(): Promise<void> {\n    await this.ctx.runMutation(this.deleteMany, {\n      table: this.table,\n      index: this.index,\n      keyField: this.sessionIdField,\n      key: this.sessionId,\n    } as any);\n  }\n}\n"],"mappings":";;;;;;;AAqFA,IAAa,2BAAb,cA0BUA,6BAAAA,2BAA2B;CACnC,eAAe;EAAC;EAAa;EAAU;EAAW;EAAS;CAE3D;CAEA;CAIA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YACE,QAUA;AACA,SAAO;AACP,OAAK,MAAM,OAAO;AAClB,OAAK,YAAY,OAAO;AACxB,OAAK,QAAQ,OAAO,SAAU;AAC9B,OAAK,QAAQ,OAAO,SAAU;AAC9B,OAAK,iBACH,OAAO,kBAAmB;AAC5B,OAAK,uBACH,OAAO,wBAAyB;AAClC,OAAK,SACH,OAAO,WAAA,GAAA,cAAA,uBAAiC,sBAAsB;AAChE,OAAK,SACH,OAAO,WAAA,GAAA,cAAA,uBAAiC,sBAAsB;AAChE,OAAK,aACH,OAAO,eAAA,GAAA,cAAA,uBACgB,0BAA0B;;CAGrD,MAAM,cAAsC;AAQ1C,UAAA,GAAA,yBAAA,kCAP+B,MAAM,KAAK,IAAI,SAAS,KAAK,QAAQ;GAClE,OAAO,KAAK;GACZ,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,KAAK,KAAK;GACX,CAAQ,EAGS,KAAK,QAAQ,IAAI,KAAK,sBAAsB,CAC7D;;CAGH,MAAM,WAAW,SAAqC;EACpD,MAAM,YAAA,GAAA,yBAAA,iCAA2C,CAAC,QAAQ,CAAC;EAE3D,MAAM,YAAY;AAClB,OAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,UACxC,OAAM,QAAQ,IACZ,SAAS,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,YACpC,KAAK,IAAI,YAAY,KAAK,QAAQ;GAChC,OAAO,KAAK;GACZ,UAAU;KACP,KAAK,iBAAiB,KAAK;KAC3B,KAAK,uBAAuB;IAC9B;GACF,CAAQ,CACV,CACF;;CAIL,MAAM,QAAuB;AAC3B,QAAM,KAAK,IAAI,YAAY,KAAK,YAAY;GAC1C,OAAO,KAAK;GACZ,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,KAAK,KAAK;GACX,CAAQ"}