clear session memory
This commit is contained in:
parent
16440aec37
commit
6827a13e37
|
|
@ -65,7 +65,18 @@ class DynamoDb_Memory implements INode {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
return initalizeDynamoDB(nodeData, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const dynamodbMemory = initalizeDynamoDB(nodeData, options)
|
||||||
|
dynamodbMemory.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initalizeDynamoDB = (nodeData: INodeData, options: ICommonObject): BufferMemory => {
|
||||||
const tableName = nodeData.inputs?.tableName as string
|
const tableName = nodeData.inputs?.tableName as string
|
||||||
const partitionKey = nodeData.inputs?.partitionKey as string
|
const partitionKey = nodeData.inputs?.partitionKey as string
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
|
@ -96,6 +107,5 @@ class DynamoDb_Memory implements INode {
|
||||||
})
|
})
|
||||||
return memory
|
return memory
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { nodeClass: DynamoDb_Memory }
|
module.exports = { nodeClass: DynamoDb_Memory }
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,16 @@ class MotorMemory_Memory implements INode {
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
return initalizeMotorhead(nodeData, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const motorhead = initalizeMotorhead(nodeData, options)
|
||||||
|
motorhead.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initalizeMotorhead = (nodeData: INodeData, options: ICommonObject): MotorheadMemory => {
|
||||||
const memoryKey = nodeData.inputs?.memoryKey as string
|
const memoryKey = nodeData.inputs?.memoryKey as string
|
||||||
const baseURL = nodeData.inputs?.baseURL as string
|
const baseURL = nodeData.inputs?.baseURL as string
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
|
@ -93,6 +103,5 @@ class MotorMemory_Memory implements INode {
|
||||||
|
|
||||||
return new MotorheadMemory(obj)
|
return new MotorheadMemory(obj)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { nodeClass: MotorMemory_Memory }
|
module.exports = { nodeClass: MotorMemory_Memory }
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,16 @@ class RedisBackedChatMemory_Memory implements INode {
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
|
return initalizeRedis(nodeData, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const redis = initalizeRedis(nodeData, options)
|
||||||
|
redis.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initalizeRedis = (nodeData: INodeData, options: ICommonObject): BufferMemory => {
|
||||||
const baseURL = nodeData.inputs?.baseURL as string
|
const baseURL = nodeData.inputs?.baseURL as string
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
const sessionTTL = nodeData.inputs?.sessionTTL as number
|
const sessionTTL = nodeData.inputs?.sessionTTL as number
|
||||||
|
|
@ -81,6 +91,5 @@ class RedisBackedChatMemory_Memory implements INode {
|
||||||
|
|
||||||
return redis
|
return redis
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { nodeClass: RedisBackedChatMemory_Memory }
|
module.exports = { nodeClass: RedisBackedChatMemory_Memory }
|
||||||
|
|
|
||||||
|
|
@ -104,31 +104,11 @@ class ZepMemory_Memory implements INode {
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||||
const baseURL = nodeData.inputs?.baseURL as string
|
|
||||||
const aiPrefix = nodeData.inputs?.aiPrefix as string
|
|
||||||
const humanPrefix = nodeData.inputs?.humanPrefix as string
|
|
||||||
const memoryKey = nodeData.inputs?.memoryKey as string
|
|
||||||
const inputKey = nodeData.inputs?.inputKey as string
|
|
||||||
const autoSummaryTemplate = nodeData.inputs?.autoSummaryTemplate as string
|
const autoSummaryTemplate = nodeData.inputs?.autoSummaryTemplate as string
|
||||||
const autoSummary = nodeData.inputs?.autoSummary as boolean
|
const autoSummary = nodeData.inputs?.autoSummary as boolean
|
||||||
const sessionId = nodeData.inputs?.sessionId as string
|
|
||||||
const apiKey = nodeData.inputs?.apiKey as string
|
|
||||||
const k = nodeData.inputs?.k as string
|
const k = nodeData.inputs?.k as string
|
||||||
|
|
||||||
const chatId = options?.chatId as string
|
let zep = initalizeZep(nodeData, options)
|
||||||
|
|
||||||
const obj: ZepMemoryInput = {
|
|
||||||
baseURL,
|
|
||||||
sessionId: sessionId ? sessionId : chatId,
|
|
||||||
aiPrefix,
|
|
||||||
humanPrefix,
|
|
||||||
returnMessages: true,
|
|
||||||
memoryKey,
|
|
||||||
inputKey
|
|
||||||
}
|
|
||||||
if (apiKey) obj.apiKey = apiKey
|
|
||||||
|
|
||||||
let zep = new ZepMemory(obj)
|
|
||||||
|
|
||||||
// hack to support summary
|
// hack to support summary
|
||||||
let tmpFunc = zep.loadMemoryVariables
|
let tmpFunc = zep.loadMemoryVariables
|
||||||
|
|
@ -153,6 +133,37 @@ class ZepMemory_Memory implements INode {
|
||||||
}
|
}
|
||||||
return zep
|
return zep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async clearSessionMemory(nodeData: INodeData, options: ICommonObject): Promise<void> {
|
||||||
|
const zep = initalizeZep(nodeData, options)
|
||||||
|
zep.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initalizeZep = (nodeData: INodeData, options: ICommonObject) => {
|
||||||
|
const baseURL = nodeData.inputs?.baseURL as string
|
||||||
|
const aiPrefix = nodeData.inputs?.aiPrefix as string
|
||||||
|
const humanPrefix = nodeData.inputs?.humanPrefix as string
|
||||||
|
const memoryKey = nodeData.inputs?.memoryKey as string
|
||||||
|
const inputKey = nodeData.inputs?.inputKey as string
|
||||||
|
|
||||||
|
const sessionId = nodeData.inputs?.sessionId as string
|
||||||
|
const apiKey = nodeData.inputs?.apiKey as string
|
||||||
|
|
||||||
|
const chatId = options?.chatId as string
|
||||||
|
|
||||||
|
const obj: ZepMemoryInput = {
|
||||||
|
baseURL,
|
||||||
|
sessionId: sessionId ? sessionId : chatId,
|
||||||
|
aiPrefix,
|
||||||
|
humanPrefix,
|
||||||
|
returnMessages: true,
|
||||||
|
memoryKey,
|
||||||
|
inputKey
|
||||||
|
}
|
||||||
|
if (apiKey) obj.apiKey = apiKey
|
||||||
|
|
||||||
|
return new ZepMemory(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { nodeClass: ZepMemory_Memory }
|
module.exports = { nodeClass: ZepMemory_Memory }
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ export interface INode extends INodeProperties {
|
||||||
}
|
}
|
||||||
init?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<any>
|
init?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<any>
|
||||||
run?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<string | ICommonObject>
|
run?(nodeData: INodeData, input: string, options?: ICommonObject): Promise<string | ICommonObject>
|
||||||
|
clearSessionMemory?(nodeData: INodeData, options?: ICommonObject): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INodeData extends INodeProperties {
|
export interface INodeData extends INodeProperties {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ import {
|
||||||
isFlowValidForStream,
|
isFlowValidForStream,
|
||||||
isVectorStoreFaiss,
|
isVectorStoreFaiss,
|
||||||
databaseEntities,
|
databaseEntities,
|
||||||
getApiKey
|
getApiKey,
|
||||||
|
clearSessionMemory
|
||||||
} from './utils'
|
} from './utils'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { getDataSource } from './DataSource'
|
import { getDataSource } from './DataSource'
|
||||||
|
|
@ -320,6 +321,19 @@ export class App {
|
||||||
|
|
||||||
// Delete all chatmessages from chatflowid
|
// Delete all chatmessages from chatflowid
|
||||||
this.app.delete('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
|
this.app.delete('/api/v1/chatmessage/:id', async (req: Request, res: Response) => {
|
||||||
|
const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({
|
||||||
|
id: req.params.id
|
||||||
|
})
|
||||||
|
if (!chatflow) {
|
||||||
|
res.status(404).send(`Chatflow ${req.params.id} not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const flowData = chatflow.flowData
|
||||||
|
const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
|
||||||
|
const nodes = parsedFlowData.nodes
|
||||||
|
let chatId = await getChatId(chatflow.id)
|
||||||
|
if (!chatId) chatId = chatflow.id
|
||||||
|
clearSessionMemory(nodes, this.nodesPool.componentNodes, chatId, req.query.sessionId as string)
|
||||||
const results = await this.AppDataSource.getRepository(ChatMessage).delete({ chatflowid: req.params.id })
|
const results = await this.AppDataSource.getRepository(ChatMessage).delete({ chatflowid: req.params.id })
|
||||||
return res.json(results)
|
return res.json(results)
|
||||||
})
|
})
|
||||||
|
|
@ -662,7 +676,7 @@ export class App {
|
||||||
if (!chatflow) return res.status(404).send(`Chatflow ${chatflowid} not found`)
|
if (!chatflow) return res.status(404).send(`Chatflow ${chatflowid} not found`)
|
||||||
|
|
||||||
let chatId = await getChatId(chatflow.id)
|
let chatId = await getChatId(chatflow.id)
|
||||||
if (!chatId) chatId = Date.now().toString()
|
if (!chatId) chatId = chatflowid
|
||||||
|
|
||||||
if (!isInternal) {
|
if (!isInternal) {
|
||||||
await this.validateKey(req, res, chatflow)
|
await this.validateKey(req, res, chatflow)
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,29 @@ export const buildLangchain = async (
|
||||||
return flowNodes
|
return flowNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear memory
|
||||||
|
* @param {IReactFlowNode[]} reactFlowNodes
|
||||||
|
* @param {IComponentNodes} componentNodes
|
||||||
|
* @param {string} chatId
|
||||||
|
* @param {string} sessionId
|
||||||
|
*/
|
||||||
|
export const clearSessionMemory = async (
|
||||||
|
reactFlowNodes: IReactFlowNode[],
|
||||||
|
componentNodes: IComponentNodes,
|
||||||
|
chatId: string,
|
||||||
|
sessionId?: string
|
||||||
|
) => {
|
||||||
|
for (const node of reactFlowNodes) {
|
||||||
|
if (node.data.category !== 'Memory') continue
|
||||||
|
const nodeInstanceFilePath = componentNodes[node.data.name].filePath as string
|
||||||
|
const nodeModule = await import(nodeInstanceFilePath)
|
||||||
|
const newNodeInstance = new nodeModule.nodeClass()
|
||||||
|
if (sessionId && node.data.inputs) node.data.inputs.sessionId = sessionId
|
||||||
|
if (newNodeInstance.clearSessionMemory) await newNodeInstance?.clearSessionMemory(node.data, { chatId })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get variable value from outputResponses.output
|
* Get variable value from outputResponses.output
|
||||||
* @param {string} paramValue
|
* @param {string} paramValue
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue