@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 7.38 kB
Source Map (JSON)
{"version":3,"file":"postgres.cjs","names":["BaseListChatMessageHistory"],"sources":["../../../src/stores/message/postgres.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 * PostgresChatMessageHistory object.\n */\nexport type PostgresChatMessageHistoryInput = {\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 * PostgresChatMessageHistory 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 StoredPostgresMessageData {\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 Postgres Database as a\n * storage backend. Extends the BaseListChatMessageHistory class.\n * @example\n * ```typescript\n * const chatHistory = new PostgresChatMessageHistory({\n * tableName: \"langchain_chat_histories\",\n * sessionId: \"lc-example\",\n * pool: new pg.Pool({\n * host: \"127.0.0.1\",\n * port: 5432,\n * user: \"myuser\",\n * password: \"ChangeMe\",\n * database: \"api\",\n * }),\n * });\n * ```\n */\nexport class PostgresChatMessageHistory extends BaseListChatMessageHistory {\n lc_namespace = [\"langchain\", \"stores\", \"message\", \"postgres\"];\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 PostgresChatMessageHistory.\n * @param {PostgresChatMessageHistoryInput} fields The input fields for the PostgresChatMessageHistory.\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 PostgresChatMessageHistory will use the provided pool.\n * @param {pg.PoolConfig} fields.poolConfig The configuration object for the Postgres pool. If no pool is provided, the conig 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: PostgresChatMessageHistoryInput) {\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 \"PostgresChatMessageHistory 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 SERIAL PRIMARY KEY,\n session_id VARCHAR(255) NOT NULL,\n message JSONB NOT NULL\n );`;\n\n try {\n await this.pool.query(query);\n // oxlint-disable-next-line typescript/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 async addMessage(message: BaseMessage): Promise<void> {\n await this.ensureTable();\n const { data, type } = mapChatMessagesToStoredMessages([message])[0];\n\n const query = `INSERT INTO ${this.tableName} (session_id, message) VALUES ($1, $2)`;\n\n await this.pool.query(query, [this.sessionId, { ...data, type }]);\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 id`;\n\n const res = await this.pool.query(query, [this.sessionId]);\n\n const storedMessages: StoredMessage[] = res.rows.map(\n (row: { message: StoredPostgresMessageData }) => {\n const { type, ...data } = row.message;\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":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,IAAa,6BAAb,cAAgDA,6BAAAA,2BAA2B;CACzE,eAAe;EAAC;EAAa;EAAU;EAAW;EAAW;CAE7D;CAEA,YAAY;CAEZ;CAEA,cAAsB;;;;;;;;;;;CAYtB,YAAY,QAAyC;AACnD,QAAM,OAAO;EACb,MAAM,EAAE,WAAW,WAAW,MAAM,YAAY,oBAAoB;AAEpE,MAAI,CAAC,QAAQ,CAAC,WACZ,OAAM,IAAI,MACR,4EACD;AAEH,OAAK,OAAO,QAAQ,IAAI,GAAA,QAAG,KAAK,WAAW;EAC3C,MAAM,aAAa,aAAa,KAAK;AACrC,OAAK,YAAY,kBACb,GAAA,QAAG,iBAAiB,WAAW,GAC/B;AACJ,OAAK,YAAY;;;;;;CAOnB,MAAc,cAA6B;AACzC,MAAI,KAAK,YAAa;EAEtB,MAAM,QAAQ;qCACmB,KAAK,UAAU;;;;;AAMhD,MAAI;AACF,SAAM,KAAK,KAAK,MAAM,MAAM;WAErB,GAAQ;AAMf,OAAI,EAAE,UAAU,MAAM,EAAE,SAAS,QAC/B,OAAM;;AAGV,OAAK,cAAc;;CAGrB,MAAM,WAAW,SAAqC;AACpD,QAAM,KAAK,aAAa;EACxB,MAAM,EAAE,MAAM,UAAA,GAAA,yBAAA,iCAAyC,CAAC,QAAQ,CAAC,CAAC;EAElE,MAAM,QAAQ,eAAe,KAAK,UAAU;AAE5C,QAAM,KAAK,KAAK,MAAM,OAAO,CAAC,KAAK,WAAW;GAAE,GAAG;GAAM;GAAM,CAAC,CAAC;;CAGnE,MAAM,cAAsC;AAC1C,QAAM,KAAK,aAAa;EAExB,MAAM,QAAQ,uBAAuB,KAAK,UAAU;AAUpD,UAAA,GAAA,yBAAA,kCARY,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,KAAK,UAAU,CAAC,EAEd,KAAK,KAC9C,QAAgD;GAC/C,MAAM,EAAE,MAAM,GAAG,SAAS,IAAI;AAC9B,UAAO;IAAE;IAAM;IAAM;IAExB,CACqD;;CAGxD,MAAM,QAAuB;AAC3B,QAAM,KAAK,aAAa;EAExB,MAAM,QAAQ,eAAe,KAAK,UAAU;AAC5C,QAAM,KAAK,KAAK,MAAM,OAAO,CAAC,KAAK,UAAU,CAAC;;;;;CAMhD,MAAM,MAAqB;AACzB,QAAM,KAAK,KAAK,KAAK"}