@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 7.65 kB
Source Map (JSON)
{"version":3,"file":"file_system.cjs","names":["store: FileChatStore","BaseListChatMessageHistory","chatHistoryInput: FileSystemChatMessageHistoryInput","store","fs","message: BaseMessage","context: Record<string, unknown>"],"sources":["../../../src/stores/message/file_system.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nimport { BaseListChatMessageHistory } from \"@langchain/core/chat_history\";\nimport {\n BaseMessage,\n StoredMessage,\n mapChatMessagesToStoredMessages,\n mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\n\nexport const FILE_HISTORY_DEFAULT_FILE_PATH = \".history/history.json\";\n\n/**\n * Represents a lightweight file chat session.\n */\nexport type FileChatSession = {\n id: string;\n context: Record<string, unknown>;\n};\n\n/**\n * Represents a stored chat session.\n */\nexport type StoredFileChatSession = FileChatSession & {\n messages: StoredMessage[];\n};\n\n/**\n * Type for the store of chat sessions.\n */\nexport type FileChatStore = {\n [userId: string]: Record<string, StoredFileChatSession>;\n};\n\n/**\n * Type for the input to the `FileSystemChatMessageHistory` constructor.\n */\nexport interface FileSystemChatMessageHistoryInput {\n sessionId: string;\n userId?: string;\n filePath?: string;\n}\n\nlet store: FileChatStore;\n\n/**\n * Store chat message history using a local JSON file.\n * For demo and development purposes only.\n *\n * @example\n * ```typescript\n * const model = new ChatOpenAI({\n * model: \"gpt-3.5-turbo\",\n * temperature: 0,\n * });\n * const prompt = ChatPromptTemplate.fromMessages([\n * [\n * \"system\",\n * \"You are a helpful assistant. Answer all questions to the best of your ability.\",\n * ],\n * [\"placeholder\", \"chat_history\"],\n * [\"human\", \"{input}\"],\n * ]);\n *\n * const chain = prompt.pipe(model).pipe(new StringOutputParser());\n * const chainWithHistory = new RunnableWithMessageHistory({\n * runnable: chain,\n * inputMessagesKey: \"input\",\n * historyMessagesKey: \"chat_history\",\n * getMessageHistory: async (sessionId) => {\n * const chatHistory = new FileSystemChatMessageHistory({\n * sessionId: sessionId,\n * userId: \"userId\", // Optional\n * })\n * return chatHistory;\n * },\n * });\n * await chainWithHistory.invoke(\n * { input: \"What did I just say my name was?\" },\n * { configurable: { sessionId: \"session-id\" } }\n * );\n * ```\n */\nexport class FileSystemChatMessageHistory extends BaseListChatMessageHistory {\n lc_namespace = [\"langchain\", \"stores\", \"message\", \"file\"];\n\n private sessionId: string;\n\n private userId: string;\n\n private filePath: string;\n\n constructor(chatHistoryInput: FileSystemChatMessageHistoryInput) {\n super();\n\n this.sessionId = chatHistoryInput.sessionId;\n this.userId = chatHistoryInput.userId ?? \"\";\n this.filePath = chatHistoryInput.filePath ?? FILE_HISTORY_DEFAULT_FILE_PATH;\n }\n\n private async init(): Promise<void> {\n if (store) {\n return;\n }\n try {\n store = await this.loadStore();\n } catch (error) {\n console.error(\"Error initializing FileSystemChatMessageHistory:\", error);\n throw error;\n }\n }\n\n protected async loadStore(): Promise<FileChatStore> {\n try {\n const store = await fs.readFile(this.filePath, \"utf-8\");\n return JSON.parse(store) as FileChatStore;\n } catch (_error) {\n const error = _error as NodeJS.ErrnoException;\n if (error.code === \"ENOENT\") {\n return {};\n }\n throw new Error(\n `Error loading FileSystemChatMessageHistory store: ${error}`\n );\n }\n }\n\n protected async saveStore(): Promise<void> {\n try {\n await fs.mkdir(dirname(this.filePath), { recursive: true });\n await fs.writeFile(this.filePath, JSON.stringify(store));\n } catch (error) {\n throw new Error(\n `Error saving FileSystemChatMessageHistory store: ${error}`\n );\n }\n }\n\n async getMessages(): Promise<BaseMessage[]> {\n await this.init();\n const messages = store[this.userId]?.[this.sessionId]?.messages ?? [];\n return mapStoredMessagesToChatMessages(messages);\n }\n\n async addMessage(message: BaseMessage): Promise<void> {\n await this.init();\n const messages = await this.getMessages();\n messages.push(message);\n const storedMessages = mapChatMessagesToStoredMessages(messages);\n store[this.userId] ??= {};\n store[this.userId][this.sessionId] = {\n ...store[this.userId][this.sessionId],\n messages: storedMessages,\n };\n await this.saveStore();\n }\n\n async clear(): Promise<void> {\n await this.init();\n if (store[this.userId]) {\n delete store[this.userId][this.sessionId];\n }\n await this.saveStore();\n }\n\n async getContext(): Promise<Record<string, unknown>> {\n await this.init();\n return store[this.userId]?.[this.sessionId]?.context ?? {};\n }\n\n async setContext(context: Record<string, unknown>): Promise<void> {\n await this.init();\n store[this.userId] ??= {};\n store[this.userId][this.sessionId] = {\n ...store[this.userId][this.sessionId],\n context,\n };\n await this.saveStore();\n }\n\n async clearAllSessions() {\n await this.init();\n delete store[this.userId];\n await this.saveStore();\n }\n\n async getAllSessions(): Promise<FileChatSession[]> {\n await this.init();\n const userSessions = store[this.userId]\n ? Object.entries(store[this.userId]).map(([id, session]) => ({\n id,\n context: session.context,\n }))\n : [];\n return userSessions;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,iCAAiC;AAiC9C,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCJ,IAAa,+BAAb,cAAkDC,yDAA2B;CAC3E,eAAe;EAAC;EAAa;EAAU;EAAW;CAAO;CAEzD,AAAQ;CAER,AAAQ;CAER,AAAQ;CAER,YAAYC,kBAAqD;EAC/D,OAAO;EAEP,KAAK,YAAY,iBAAiB;EAClC,KAAK,SAAS,iBAAiB,UAAU;EACzC,KAAK,WAAW,iBAAiB,YAAY;CAC9C;CAED,MAAc,OAAsB;AAClC,MAAI,MACF;AAEF,MAAI;GACF,QAAQ,MAAM,KAAK,WAAW;EAC/B,SAAQ,OAAO;GACd,QAAQ,MAAM,oDAAoD,MAAM;AACxE,SAAM;EACP;CACF;CAED,MAAgB,YAAoC;AAClD,MAAI;GACF,MAAMC,UAAQ,MAAMC,iBAAG,SAAS,KAAK,UAAU,QAAQ;AACvD,UAAO,KAAK,MAAMD,QAAM;EACzB,SAAQ,QAAQ;GACf,MAAM,QAAQ;AACd,OAAI,MAAM,SAAS,SACjB,QAAO,CAAE;AAEX,SAAM,IAAI,MACR,CAAC,kDAAkD,EAAE,OAAO;EAE/D;CACF;CAED,MAAgB,YAA2B;AACzC,MAAI;GACF,MAAMC,iBAAG,6BAAc,KAAK,SAAS,EAAE,EAAE,WAAW,KAAM,EAAC;GAC3D,MAAMA,iBAAG,UAAU,KAAK,UAAU,KAAK,UAAU,MAAM,CAAC;EACzD,SAAQ,OAAO;AACd,SAAM,IAAI,MACR,CAAC,iDAAiD,EAAE,OAAO;EAE9D;CACF;CAED,MAAM,cAAsC;EAC1C,MAAM,KAAK,MAAM;EACjB,MAAM,WAAW,MAAM,KAAK,UAAU,KAAK,YAAY,YAAY,CAAE;AACrE,wEAAuC,SAAS;CACjD;CAED,MAAM,WAAWC,SAAqC;EACpD,MAAM,KAAK,MAAM;EACjB,MAAM,WAAW,MAAM,KAAK,aAAa;EACzC,SAAS,KAAK,QAAQ;EACtB,MAAM,gFAAiD,SAAS;EAChE,MAAM,KAAK,YAAY,CAAE;EACzB,MAAM,KAAK,QAAQ,KAAK,aAAa;GACnC,GAAG,MAAM,KAAK,QAAQ,KAAK;GAC3B,UAAU;EACX;EACD,MAAM,KAAK,WAAW;CACvB;CAED,MAAM,QAAuB;EAC3B,MAAM,KAAK,MAAM;AACjB,MAAI,MAAM,KAAK,SACb,OAAO,MAAM,KAAK,QAAQ,KAAK;EAEjC,MAAM,KAAK,WAAW;CACvB;CAED,MAAM,aAA+C;EACnD,MAAM,KAAK,MAAM;AACjB,SAAO,MAAM,KAAK,UAAU,KAAK,YAAY,WAAW,CAAE;CAC3D;CAED,MAAM,WAAWC,SAAiD;EAChE,MAAM,KAAK,MAAM;EACjB,MAAM,KAAK,YAAY,CAAE;EACzB,MAAM,KAAK,QAAQ,KAAK,aAAa;GACnC,GAAG,MAAM,KAAK,QAAQ,KAAK;GAC3B;EACD;EACD,MAAM,KAAK,WAAW;CACvB;CAED,MAAM,mBAAmB;EACvB,MAAM,KAAK,MAAM;EACjB,OAAO,MAAM,KAAK;EAClB,MAAM,KAAK,WAAW;CACvB;CAED,MAAM,iBAA6C;EACjD,MAAM,KAAK,MAAM;EACjB,MAAM,eAAe,MAAM,KAAK,UAC5B,OAAO,QAAQ,MAAM,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,MAAM;GACzD;GACA,SAAS,QAAQ;EAClB,GAAE,GACH,CAAE;AACN,SAAO;CACR;AACF"}