UNPKG

dtamind-components

Version:

Apps integration for Dtamind. Contain Nodes and Credentials.

164 lines 7.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ioredis_1 = require("ioredis"); const memory_1 = require("langchain/memory"); const messages_1 = require("@langchain/core/messages"); const Interface_1 = require("../../../src/Interface"); const utils_1 = require("../../../src/utils"); class RedisBackedChatMemory_Memory { constructor() { this.label = 'Redis-Backed Chat Memory'; this.name = 'RedisBackedChatMemory'; this.version = 2.0; this.type = 'RedisBackedChatMemory'; this.icon = 'redis.svg'; this.category = 'Memory'; this.description = 'Summarizes the conversation and stores the memory in Redis server'; this.baseClasses = [this.type, ...(0, utils_1.getBaseClasses)(memory_1.BufferMemory)]; this.credential = { label: 'Connect Credential', name: 'credential', type: 'credential', optional: true, credentialNames: ['redisCacheApi', 'redisCacheUrlApi'] }; this.inputs = [ { label: 'Session Id', name: 'sessionId', type: 'string', description: 'If not specified, a random id will be used. Learn <a target="_blank" href="https://docs.dtamindai.com/memory/long-term-memory#ui-and-embedded-chat">more</a>', default: '', additionalParams: true, optional: true }, { label: 'Session Timeouts', name: 'sessionTTL', type: 'number', description: 'Seconds till a session expires. If not specified, the session will never expire.', additionalParams: true, optional: true }, { label: 'Memory Key', name: 'memoryKey', type: 'string', default: 'chat_history', additionalParams: true }, { label: 'Window Size', name: 'windowSize', type: 'number', description: 'Window of size k to surface the last k back-and-forth to use as memory.', additionalParams: true, optional: true } ]; } async init(nodeData, _, options) { return await initializeRedis(nodeData, options); } } const initializeRedis = async (nodeData, options) => { const sessionTTL = nodeData.inputs?.sessionTTL; const memoryKey = nodeData.inputs?.memoryKey; const sessionId = nodeData.inputs?.sessionId; const windowSize = nodeData.inputs?.windowSize; const credentialData = await (0, utils_1.getCredentialData)(nodeData.credential ?? '', options); const redisUrl = (0, utils_1.getCredentialParam)('redisUrl', credentialData, nodeData); const orgId = options.orgId; const redisOptions = redisUrl ? redisUrl : { port: parseInt((0, utils_1.getCredentialParam)('redisCachePort', credentialData, nodeData) || '6379'), host: (0, utils_1.getCredentialParam)('redisCacheHost', credentialData, nodeData), username: (0, utils_1.getCredentialParam)('redisCacheUser', credentialData, nodeData), password: (0, utils_1.getCredentialParam)('redisCachePwd', credentialData, nodeData), tls: (0, utils_1.getCredentialParam)('redisCacheSslEnabled', credentialData, nodeData) ? { rejectUnauthorized: false } : undefined }; const memory = new BufferMemoryExtended({ memoryKey: memoryKey ?? 'chat_history', sessionId, windowSize, sessionTTL, redisOptions, orgId }); return memory; }; class BufferMemoryExtended extends Interface_1.DtamindMemory { constructor(fields) { super(fields); this.sessionId = ''; this.orgId = ''; this.sessionId = fields.sessionId; this.windowSize = fields.windowSize; this.sessionTTL = fields.sessionTTL; this.orgId = fields.orgId; this.redisOptions = fields.redisOptions; } async withRedisClient(fn) { const client = typeof this.redisOptions === 'string' ? new ioredis_1.Redis(this.redisOptions, { keepAlive: process.env.REDIS_KEEP_ALIVE && !isNaN(parseInt(process.env.REDIS_KEEP_ALIVE, 10)) ? parseInt(process.env.REDIS_KEEP_ALIVE, 10) : undefined }) : new ioredis_1.Redis({ ...this.redisOptions, keepAlive: process.env.REDIS_KEEP_ALIVE && !isNaN(parseInt(process.env.REDIS_KEEP_ALIVE, 10)) ? parseInt(process.env.REDIS_KEEP_ALIVE, 10) : undefined }); try { return await fn(client); } finally { await client.quit(); } } async getChatMessages(overrideSessionId = '', returnBaseMessages = false, prependMessages) { return this.withRedisClient(async (client) => { const id = overrideSessionId ? overrideSessionId : this.sessionId; const rawStoredMessages = await client.lrange(id, this.windowSize ? this.windowSize * -1 : 0, -1); const orderedMessages = rawStoredMessages.reverse().map((message) => JSON.parse(message)); const baseMessages = orderedMessages.map(messages_1.mapStoredMessageToChatMessage); if (prependMessages?.length) { baseMessages.unshift(...(await (0, utils_1.mapChatMessageToBaseMessage)(prependMessages, this.orgId))); } return returnBaseMessages ? baseMessages : (0, utils_1.convertBaseMessagetoIMessage)(baseMessages); }); } async addChatMessages(msgArray, overrideSessionId = '') { await this.withRedisClient(async (client) => { const id = overrideSessionId ? overrideSessionId : this.sessionId; const input = msgArray.find((msg) => msg.type === 'userMessage'); const output = msgArray.find((msg) => msg.type === 'apiMessage'); if (input) { const newInputMessage = new messages_1.HumanMessage(input.text); const messageToAdd = [newInputMessage].map((msg) => msg.toDict()); await client.lpush(id, JSON.stringify(messageToAdd[0])); if (this.sessionTTL) await client.expire(id, this.sessionTTL); } if (output) { const newOutputMessage = new messages_1.AIMessage(output.text); const messageToAdd = [newOutputMessage].map((msg) => msg.toDict()); await client.lpush(id, JSON.stringify(messageToAdd[0])); if (this.sessionTTL) await client.expire(id, this.sessionTTL); } }); } async clearChatMessages(overrideSessionId = '') { await this.withRedisClient(async (client) => { const id = overrideSessionId ? overrideSessionId : this.sessionId; await client.del(id); await this.clear(); }); } } module.exports = { nodeClass: RedisBackedChatMemory_Memory }; //# sourceMappingURL=RedisBackedChatMemory.js.map