From cf3bd72a982dea17b641f380c496d5ee563ed732 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 10 Jul 2023 16:51:36 +0100 Subject: [PATCH] update message schema --- .../ConversationalAgent/ConversationalAgent.ts | 6 +++--- .../OpenAIFunctionAgent/OpenAIFunctionAgent.ts | 6 +++--- .../ConversationChain/ConversationChain.ts | 6 +++--- .../ConversationalRetrievalQAChain.ts | 17 +++++------------ .../nodes/memory/ZepMemory/ZepMemory.ts | 4 ++-- packages/server/src/index.ts | 8 ++++---- 6 files changed, 20 insertions(+), 27 deletions(-) diff --git a/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts b/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts index 363b39076..568ced0b0 100644 --- a/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts +++ b/packages/components/nodes/agents/ConversationalAgent/ConversationalAgent.ts @@ -3,7 +3,7 @@ import { initializeAgentExecutorWithOptions, AgentExecutor, InitializeAgentExecu import { Tool } from 'langchain/tools' import { BaseChatMemory, ChatMessageHistory } from 'langchain/memory' import { getBaseClasses } from '../../../src/utils' -import { AIChatMessage, HumanChatMessage } from 'langchain/schema' +import { AIMessage, HumanMessage } from 'langchain/schema' import { BaseLanguageModel } from 'langchain/base_language' import { flatten } from 'lodash' @@ -99,9 +99,9 @@ class ConversationalAgent_Agents implements INode { for (const message of histories) { if (message.type === 'apiMessage') { - chatHistory.push(new AIChatMessage(message.message)) + chatHistory.push(new AIMessage(message.message)) } else if (message.type === 'userMessage') { - chatHistory.push(new HumanChatMessage(message.message)) + chatHistory.push(new HumanMessage(message.message)) } } memory.chatHistory = new ChatMessageHistory(chatHistory) diff --git a/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts b/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts index 1cbcb5473..43de74cb2 100644 --- a/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts +++ b/packages/components/nodes/agents/OpenAIFunctionAgent/OpenAIFunctionAgent.ts @@ -4,7 +4,7 @@ import { CustomChainHandler, getBaseClasses } from '../../../src/utils' import { BaseLanguageModel } from 'langchain/base_language' import { flatten } from 'lodash' import { BaseChatMemory, ChatMessageHistory } from 'langchain/memory' -import { AIChatMessage, HumanChatMessage } from 'langchain/schema' +import { AIMessage, HumanMessage } from 'langchain/schema' class OpenAIFunctionAgent_Agents implements INode { label: string @@ -84,9 +84,9 @@ class OpenAIFunctionAgent_Agents implements INode { for (const message of histories) { if (message.type === 'apiMessage') { - chatHistory.push(new AIChatMessage(message.message)) + chatHistory.push(new AIMessage(message.message)) } else if (message.type === 'userMessage') { - chatHistory.push(new HumanChatMessage(message.message)) + chatHistory.push(new HumanMessage(message.message)) } } memory.chatHistory = new ChatMessageHistory(chatHistory) diff --git a/packages/components/nodes/chains/ConversationChain/ConversationChain.ts b/packages/components/nodes/chains/ConversationChain/ConversationChain.ts index 843e05fc6..27af5b8ee 100644 --- a/packages/components/nodes/chains/ConversationChain/ConversationChain.ts +++ b/packages/components/nodes/chains/ConversationChain/ConversationChain.ts @@ -4,7 +4,7 @@ import { CustomChainHandler, getBaseClasses } from '../../../src/utils' import { ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate } from 'langchain/prompts' import { BufferMemory, ChatMessageHistory } from 'langchain/memory' import { BaseChatModel } from 'langchain/chat_models/base' -import { AIChatMessage, HumanChatMessage } from 'langchain/schema' +import { AIMessage, HumanMessage } from 'langchain/schema' const systemMessage = `The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.` @@ -81,9 +81,9 @@ class ConversationChain_Chains implements INode { for (const message of histories) { if (message.type === 'apiMessage') { - chatHistory.push(new AIChatMessage(message.message)) + chatHistory.push(new AIMessage(message.message)) } else if (message.type === 'userMessage') { - chatHistory.push(new HumanChatMessage(message.message)) + chatHistory.push(new HumanMessage(message.message)) } } memory.chatHistory = new ChatMessageHistory(chatHistory) diff --git a/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts b/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts index 4872717f9..2dccd0120 100644 --- a/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts +++ b/packages/components/nodes/chains/ConversationalRetrievalQAChain/ConversationalRetrievalQAChain.ts @@ -6,33 +6,26 @@ import { AIMessage, BaseRetriever, HumanMessage } from 'langchain/schema' import { BaseChatMemory, BufferMemory, ChatMessageHistory } from 'langchain/memory' import { PromptTemplate } from 'langchain/prompts' -const default_qa_template = `Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. +const default_qa_template = `Use the following pieces of context to answer the question at the end, in its original language. If you don't know the answer, just say that you don't know in its original language, don't try to make up an answer. {context} Question: {question} Helpful Answer:` -const qa_template = `Use the following pieces of context to answer the question at the end. +const qa_template = `Use the following pieces of context to answer the question at the end, in its original language. {context} Question: {question} Helpful Answer:` -const CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT = `Given the following conversation and a follow up question, return the conversation history excerpt that includes any relevant context to the question if it exists and rephrase the follow up question to be a standalone question. +const CUSTOM_QUESTION_GENERATOR_CHAIN_PROMPT = `Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language. include it in the standalone question. + Chat History: {chat_history} Follow Up Input: {question} -Your answer should follow the following format: -\`\`\` -Use the following pieces of context to answer the users question. -If you don't know the answer, just say that you don't know, don't try to make up an answer. ----------------- - -Standalone question: -\`\`\` -Your answer:` +Standalone question:` class ConversationalRetrievalQAChain_Chains implements INode { label: string diff --git a/packages/components/nodes/memory/ZepMemory/ZepMemory.ts b/packages/components/nodes/memory/ZepMemory/ZepMemory.ts index 23691e307..89d07b8fc 100644 --- a/packages/components/nodes/memory/ZepMemory/ZepMemory.ts +++ b/packages/components/nodes/memory/ZepMemory/ZepMemory.ts @@ -1,4 +1,4 @@ -import { SystemChatMessage } from 'langchain/schema' +import { SystemMessage } from 'langchain/schema' import { INode, INodeData, INodeParams } from '../../../src/Interface' import { getBaseClasses } from '../../../src/utils' import { ZepMemory, ZepMemoryInput } from 'langchain/memory/zep' @@ -123,7 +123,7 @@ class ZepMemory_Memory implements INode { let summary = autoSummaryTemplate.replace(/{summary}/g, memory.summary.content) // eslint-disable-next-line no-console console.log('[ZepMemory] auto summary:', summary) - data[zep.memoryKey].unshift(new SystemChatMessage(summary)) + data[zep.memoryKey].unshift(new SystemMessage(summary)) } } // for langchain zep memory compatibility, or we will get "Missing value for input variable chat_history" diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index cd4978a06..ef9bc42d6 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -687,13 +687,13 @@ export class App { } } - /* Don't rebuild the flow (to avoid duplicated upsert, recomputation) when all these conditions met: + /* Reuse the flow without having to rebuild (to avoid duplicated upsert, recomputation) when all these conditions met: * - Node Data already exists in pool * - Still in sync (i.e the flow has not been modified since) * - Existing overrideConfig and new overrideConfig are the same * - Flow doesn't start with nodes that depend on incomingInput.question ***/ - const isRebuildNeeded = () => { + const isFlowReusable = () => { return ( Object.prototype.hasOwnProperty.call(this.chatflowPool.activeChatflows, chatflowid) && this.chatflowPool.activeChatflows[chatflowid].inSync && @@ -707,7 +707,7 @@ export class App { } if (process.env.EXECUTION_MODE === 'child') { - if (isRebuildNeeded()) { + if (isFlowReusable()) { nodeToExecuteData = this.chatflowPool.activeChatflows[chatflowid].endingNodeData try { const result = await this.startChildProcess(chatflow, chatId, incomingInput, nodeToExecuteData) @@ -731,7 +731,7 @@ export class App { const nodes = parsedFlowData.nodes const edges = parsedFlowData.edges - if (isRebuildNeeded()) { + if (isFlowReusable()) { nodeToExecuteData = this.chatflowPool.activeChatflows[chatflowid].endingNodeData isStreamValid = isFlowValidForStream(nodes, nodeToExecuteData) } else {