@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 8.27 kB
Source Map (JSON)
{"version":3,"file":"aurora_dsql.cjs","names":["BaseListChatMessageHistory","fields: AuroraDsqlChatMessageHistoryInput","e: any","message: BaseMessage","storedMessages: StoredMessage[]","row: { message: string }"],"sources":["../../../src/stores/message/aurora_dsql.ts"],"sourcesContent":["import { BaseListChatMessageHistory } from \"@langchain/core/chat_history\";\nimport {\n BaseMessage,\n StoredMessage,\n mapChatMessagesToStoredMessages,\n mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\nimport pg from \"pg\";\n\n/**\n * Type definition for the input parameters required when instantiating a\n * AuroraDsqlChatMessageHistory object.\n */\nexport type AuroraDsqlChatMessageHistoryInput = {\n /**\n * Name of the table to use when storing and retrieving chat message\n */\n tableName?: string;\n /**\n * Session ID to use when storing and retrieving chat message history.\n */\n sessionId: string;\n /**\n * Configuration object for the Postgres pool. If provided the\n * AuroraDsqlChatMessageHistory object will create a new pool using\n * the provided configuration. Otherwise it will use the provided\n * pool.\n */\n poolConfig?: pg.PoolConfig;\n /**\n * Postgres pool to use. If provided the PostgresChatMessageHistory\n * object will use the provided pool. Otherwise it will create a\n * new pool using the provided configuration.\n */\n pool?: pg.Pool;\n /**\n * If true, the table name will be escaped. ('lAnGcHaIn' will be escaped to '\"lAnGcHaIn\"')\n */\n escapeTableName?: boolean;\n};\n\nexport interface StoredAuroraDsqlMessageData {\n name: string | undefined;\n role: string | undefined;\n content: string;\n additional_kwargs?: Record<string, unknown>;\n type: string;\n tool_call_id: string | undefined;\n}\n\n/**\n * Class for managing chat message history using a Amazon Aurora DSQL Database as a\n * storage backend. Extends the BaseListChatMessageHistory class.\n * @example\n * ```typescript\n * const chatHistory = new AuroraDsqlChatMessageHistory({\n * tableName: \"langchain_chat_histories\",\n * sessionId: \"lc-example\",\n * pool: new pg.Pool({\n * host: \"your_dsql_endpoint\",\n * port: 5432,\n * user: \"admin\",\n * password: \"your_token\",\n * database: \"postgres\",\n * ssl: true\n * }),\n * });\n * ```\n */\nexport class AuroraDsqlChatMessageHistory extends BaseListChatMessageHistory {\n lc_namespace = [\"langchain\", \"stores\", \"message\", \"aurora_dsql\"];\n\n pool: pg.Pool;\n\n tableName = \"langchain_chat_histories\";\n\n sessionId: string;\n\n private initialized = false;\n\n /**\n * Creates a new AuroraDsqlChatMessageHistory.\n * @param {AuroraDsqlChatMessageHistoryInput} fields The input fields for the AuroraDsqlChatMessageHistory.\n * @param {string} fields.tableName The name of the table name to use. Defaults to `langchain_chat_histories`.\n * @param {string} fields.sessionId The session ID to use when storing and retrieving chat message history.\n * @param {pg.Pool} fields.pool The Postgres pool to use. If provided, the AuroraDsqlChatMessageHistory will use the provided pool.\n * @param {pg.PoolConfig} fields.poolConfig The configuration object for the Postgres pool. If no pool is provided, the config will be used to create a new pool.\n * If `pool` is provided, it will be used as the Postgres pool even if `poolConfig` is also provided.\n * @throws If neither `pool` nor `poolConfig` is provided.\n */\n constructor(fields: AuroraDsqlChatMessageHistoryInput) {\n super(fields);\n const { tableName, sessionId, pool, poolConfig, escapeTableName } = fields;\n // Ensure that either a client or config is provided\n if (!pool && !poolConfig) {\n throw new Error(\n \"AuroraDsqlChatMessageHistory requires either a pool instance or pool config\"\n );\n }\n this.pool = pool ?? new pg.Pool(poolConfig);\n const _tableName = tableName || this.tableName;\n this.tableName = escapeTableName\n ? pg.escapeIdentifier(_tableName)\n : _tableName;\n this.sessionId = sessionId;\n }\n\n /**\n * Checks if the table has been created and creates it if it hasn't.\n * @returns Promise that resolves when the table's existence is ensured.\n */\n private async ensureTable(): Promise<void> {\n if (this.initialized) return;\n\n const query = `\n CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n created_at timestamp default current_timestamp,\n session_id VARCHAR(255) NOT NULL,\n message TEXT NOT NULL\n );`;\n\n try {\n await this.pool.query(query);\n await this.createIndex();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n // This error indicates that the table already exists\n // Due to asynchronous nature of the code, it is possible that\n // the table is created between the time we check if it exists\n // and the time we try to create it. It can be safely ignored.\n // If it's not this error, rethrow it.\n if (!(\"code\" in e) || e.code !== \"23505\") {\n throw e;\n }\n }\n this.initialized = true;\n }\n\n private async createIndex() {\n const query = `CREATE INDEX ASYNC IF NOT EXISTS idx_on_session_id on ${this.tableName} (session_id);`;\n await this.pool.query(query);\n }\n\n async addMessage(message: BaseMessage): Promise<void> {\n await this.ensureTable();\n\n const map = mapChatMessagesToStoredMessages([message])[0];\n\n const query = `INSERT INTO ${this.tableName} (session_id, message) VALUES ($1, $2)`;\n\n await this.pool.query(query, [\n this.sessionId,\n JSON.stringify({ ...map?.data, type: map?.type }),\n ]);\n }\n\n async getMessages(): Promise<BaseMessage[]> {\n await this.ensureTable();\n\n const query = `SELECT message FROM ${this.tableName} WHERE session_id = $1 ORDER BY created_at asc`;\n\n const res = await this.pool.query(query, [this.sessionId]);\n\n const storedMessages: StoredMessage[] = res.rows.map(\n (row: { message: string }) => {\n const { type, ...data } = JSON.parse(\n row.message\n ) as StoredAuroraDsqlMessageData;\n return { type, data };\n }\n );\n return mapStoredMessagesToChatMessages(storedMessages);\n }\n\n async clear(): Promise<void> {\n await this.ensureTable();\n\n const query = `DELETE FROM ${this.tableName} WHERE session_id = $1`;\n await this.pool.query(query, [this.sessionId]);\n }\n\n /**\n * End the Postgres pool.\n */\n async end(): Promise<void> {\n await this.pool.end();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAqEA,IAAa,+BAAb,cAAkDA,yDAA2B;CAC3E,eAAe;EAAC;EAAa;EAAU;EAAW;CAAc;CAEhE;CAEA,YAAY;CAEZ;CAEA,AAAQ,cAAc;;;;;;;;;;;CAYtB,YAAYC,QAA2C;EACrD,MAAM,OAAO;EACb,MAAM,EAAE,WAAW,WAAW,MAAM,YAAY,iBAAiB,GAAG;AAEpE,MAAI,CAAC,QAAQ,CAAC,WACZ,OAAM,IAAI,MACR;EAGJ,KAAK,OAAO,QAAQ,IAAI,WAAG,KAAK;EAChC,MAAM,aAAa,aAAa,KAAK;EACrC,KAAK,YAAY,kBACb,WAAG,iBAAiB,WAAW,GAC/B;EACJ,KAAK,YAAY;CAClB;;;;;CAMD,MAAc,cAA6B;AACzC,MAAI,KAAK,YAAa;EAEtB,MAAM,QAAQ,CAAC;+BACY,EAAE,KAAK,UAAU;;;;;MAK1C,CAAC;AAEH,MAAI;GACF,MAAM,KAAK,KAAK,MAAM,MAAM;GAC5B,MAAM,KAAK,aAAa;EAEzB,SAAQC,GAAQ;AAMf,OAAI,EAAE,UAAU,MAAM,EAAE,SAAS,QAC/B,OAAM;EAET;EACD,KAAK,cAAc;CACpB;CAED,MAAc,cAAc;EAC1B,MAAM,QAAQ,CAAC,sDAAsD,EAAE,KAAK,UAAU,cAAc,CAAC;EACrG,MAAM,KAAK,KAAK,MAAM,MAAM;CAC7B;CAED,MAAM,WAAWC,SAAqC;EACpD,MAAM,KAAK,aAAa;EAExB,MAAM,qEAAsC,CAAC,OAAQ,EAAC,CAAC;EAEvD,MAAM,QAAQ,CAAC,YAAY,EAAE,KAAK,UAAU,sCAAsC,CAAC;EAEnF,MAAM,KAAK,KAAK,MAAM,OAAO,CAC3B,KAAK,WACL,KAAK,UAAU;GAAE,GAAG,KAAK;GAAM,MAAM,KAAK;EAAM,EAAC,AAClD,EAAC;CACH;CAED,MAAM,cAAsC;EAC1C,MAAM,KAAK,aAAa;EAExB,MAAM,QAAQ,CAAC,oBAAoB,EAAE,KAAK,UAAU,8CAA8C,CAAC;EAEnG,MAAM,MAAM,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,KAAK,SAAU,EAAC;EAE1D,MAAMC,iBAAkC,IAAI,KAAK,IAC/C,CAACC,QAA6B;GAC5B,MAAM,EAAE,KAAM,GAAG,MAAM,GAAG,KAAK,MAC7B,IAAI,QACL;AACD,UAAO;IAAE;IAAM;GAAM;EACtB,EACF;AACD,wEAAuC,eAAe;CACvD;CAED,MAAM,QAAuB;EAC3B,MAAM,KAAK,aAAa;EAExB,MAAM,QAAQ,CAAC,YAAY,EAAE,KAAK,UAAU,sBAAsB,CAAC;EACnE,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,KAAK,SAAU,EAAC;CAC/C;;;;CAKD,MAAM,MAAqB;EACzB,MAAM,KAAK,KAAK,KAAK;CACtB;AACF"}