-
-
Notifications
You must be signed in to change notification settings - Fork 23.2k
feature/SupportZepMemoryAndAutoSummary #284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature/SupportZepMemoryAndAutoSummary #284
Conversation
|
zep-test Chatflow.zip |
|
thanks @wangerzi for the Zep addition! |
@HenryHengZJ Flowise is an interesting project, I'm very happy to make some contributions.😀 The session id in zep just like a required unique identifier of a conversion, zep server use session id to find memory, make summary, etc... But when we want to create a new conversion in flowise, we must change the session id (or automatic generate a uuid for new conversion), because we can't clear zep chat history in this session by api. Talk is cheap, I'm already prepared a demo to explain it: Execution Prepare:
// import { ZepMemory } from 'langchain/memory/zep'
// import { Memory, Message } from '@getzep/zep-js'
const { ZepMemory } = require('langchain/memory/zep')
const { Memory, Message } = require('@getzep/zep-js')
const sessionId = 'test-3'
const zepURL = 'http://localhost:8000'
const memory = new ZepMemory({
sessionId,
memoryKey: 'chat_history',
returnMessages: true,
baseURL: zepURL
})
async function init() {
const history = [
{
role: 'human',
content: 'Who was Octavia Butler?'
},
{
role: 'ai',
content: 'Octavia Estelle Butler (June 22, 1947 – February 24, 2006) was an American' + ' science fiction author.'
}
]
const messages = history.map(({ role, content }) => new Message({ role, content }))
const zepMemory = new Memory({ messages })
await memory.zepClient.addMemory(sessionId, zepMemory)
}
async function testSearch() {
await init()
const data = await memory.loadMemoryVariables({
lastN: 10
})
console.log('search data:', data)
}
async function testClear() {
await memory.clear()
}
async function testCase1() {
console.log('first search')
await testSearch()
await testClear()
console.log('already cleared')
await testSearch()
}
testCase1()Execution Result told us if we can't use official api $ node test-zep.js
first search
search data: {
chat_history: [
ChatMessage {
text: 'Who was Octavia Butler?',
name: undefined,
role: 'human'
},
ChatMessage {
text: 'Octavia Estelle Butler (June 22, 1947 – February 24, 2006) was an American science fiction author.',
name: undefined,
role: 'ai'
}
]
}
already cleared
D:\phpStudy\WWW\github\Flowise\node_modules\@getzep\zep-js\dist\zep-client.js:143
throw new exceptions_1.UnexpectedResponseError(`addMemoryAsync got an Unexpected status code: ${error.response.status}`);
^
UnexpectedResponseError: addMemoryAsync got an Unexpected status code: 400
at ZepClient.<anonymous> (D:\phpStudy\WWW\github\Flowise\node_modules\@getzep\zep-js\dist\zep-client.js:143:27)
at Generator.throw (<anonymous>)
at rejected (D:\phpStudy\WWW\github\Flowise\node_modules\@getzep\zep-js\dist\zep-client.js:29:65)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
responseData: undefined
}
Node.js v18.16.0References:
|
|
@wangerzi oh okay in that case, can we just use timestamp string as session id? that way we can save user from inputting/changing session id everytime |
|
@HenryHengZJ Sounds like a great idea to solve this problem👏, I'll try to use the conversion start time as zep session after 8 hours (after wake up🌞) |
|
@HenryHengZJ According to the current data structure, I think the first chat message id is a better choice for For generality, I found the first chat message in backend, and pass it by This is the minimum modification in my mind, but I'm not sure if you have better solution for this. Key Code: |
packages/server/src/ChildProcess.ts
Outdated
| depthQueue, | ||
| componentNodes, | ||
| incomingInput.question, | ||
| '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we also pass in the chatid from here - https://github.com/FlowiseAI/Flowise/blob/main/packages/server/src/index.ts#L445 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's missing, I have forgot the chatflow variable contains a correct chatflow.id we can use, I'll fix it later!👀
| setLoading(true) | ||
| setMessages((prevMessages) => [...prevMessages, { message: userInput, type: 'userMessage' }]) | ||
| addChatMessage(userInput, 'userMessage') | ||
| // waiting for first chatmessage uploaded, the first chatmessage id will be chatId for every components |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code await addChatMessage(userInput, 'userMessage') looks the same before and after changes, is the comment redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, maybe I should say goodmorning to you! Considering that when the chat message is sent for the first time, if the POST /chatmessage/{id} request and the POST /internal-prediction/${id} request are executed concurrently, the first message id ORM query will fail in the prediction request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i love the idea of using first chat id, that way when user clear the conversation, the session id will also be refreshed |
|
@HenryHengZJ I'm already update the code based on our conversation, and I create a new function |
| label: 'Session Id', | ||
| name: 'sessionId', | ||
| type: 'string', | ||
| placeholder: 'if empty, chatId will be used automatically', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can use description for the message
packages/server/src/ChildProcess.ts
Outdated
| const { startingNodeIds, depthQueue } = getStartingNodes(nonDirectedGraph, endingNodeId) | ||
|
|
||
| /*** BFS to traverse from Starting Nodes to Ending Node ***/ | ||
| const chatId = await getChatId(chatflow.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will not work because child processes dont have access to DataSource. You'll have to get the chatid in startChildProcess() and pass it in the IRunChatflowMessageValue - https://github.com/FlowiseAI/Flowise/blob/main/packages/server/src/index.ts#L449. Then retrieve it here - https://github.com/FlowiseAI/Flowise/blob/main/packages/server/src/ChildProcess.ts#L26
|
@HenryHengZJ Thank you very much for your patience and guidance, I have changed my code by your comment.😀 em, but I just have a little confusion, I don't known how to test |
In the |
Thanks for answering, I've updated some code to remove a useless ORM query and tested the |
|
thanks @wangerzi !! tested and it works like a charm! really appreciate the ground work of session id using chat id, it makes it easy for other memory implementation thats using session id as well |




Support https://docs.getzep.com/sdk/langchain/ in Flowise.
Some limits: