Merge pull request #147 from FlowiseAI/feature/ConversationChain
Feature/Add conversation chain
This commit is contained in:
commit
0fb16c7849
|
|
@ -0,0 +1,97 @@
|
|||
import { ICommonObject, IMessage, INode, INodeData, INodeParams } from '../../../src/Interface'
|
||||
import { ConversationChain } from 'langchain/chains'
|
||||
import { 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'
|
||||
|
||||
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.`
|
||||
|
||||
class ConversationChain_Chains implements INode {
|
||||
label: string
|
||||
name: string
|
||||
type: string
|
||||
icon: string
|
||||
category: string
|
||||
baseClasses: string[]
|
||||
description: string
|
||||
inputs: INodeParams[]
|
||||
|
||||
constructor() {
|
||||
this.label = 'Conversation Chain'
|
||||
this.name = 'conversationChain'
|
||||
this.type = 'ConversationChain'
|
||||
this.icon = 'chain.svg'
|
||||
this.category = 'Chains'
|
||||
this.description = 'Chat models specific conversational chain with memory'
|
||||
this.baseClasses = [this.type, ...getBaseClasses(ConversationChain)]
|
||||
this.inputs = [
|
||||
{
|
||||
label: 'Language Model',
|
||||
name: 'model',
|
||||
type: 'BaseChatModel'
|
||||
},
|
||||
{
|
||||
label: 'Memory',
|
||||
name: 'memory',
|
||||
type: 'BaseMemory'
|
||||
},
|
||||
{
|
||||
label: 'System Message',
|
||||
name: 'systemMessagePrompt',
|
||||
type: 'string',
|
||||
rows: 4,
|
||||
additionalParams: true,
|
||||
optional: true,
|
||||
placeholder: 'You are a helpful assistant that write codes'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
async init(nodeData: INodeData): Promise<any> {
|
||||
const model = nodeData.inputs?.model as BaseChatModel
|
||||
const memory = nodeData.inputs?.memory as BufferMemory
|
||||
const prompt = nodeData.inputs?.systemMessagePrompt as string
|
||||
|
||||
const obj: any = {
|
||||
llm: model,
|
||||
memory
|
||||
}
|
||||
|
||||
const chatPrompt = ChatPromptTemplate.fromPromptMessages([
|
||||
SystemMessagePromptTemplate.fromTemplate(prompt ? `${prompt}\n${systemMessage}` : systemMessage),
|
||||
new MessagesPlaceholder(memory.memoryKey ?? 'chat_history'),
|
||||
HumanMessagePromptTemplate.fromTemplate('{input}')
|
||||
])
|
||||
obj.prompt = chatPrompt
|
||||
|
||||
const chain = new ConversationChain(obj)
|
||||
return chain
|
||||
}
|
||||
|
||||
async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
|
||||
const chain = nodeData.instance as ConversationChain
|
||||
const memory = nodeData.inputs?.memory as BufferMemory
|
||||
|
||||
if (options && options.chatHistory) {
|
||||
const chatHistory = []
|
||||
const histories: IMessage[] = options.chatHistory
|
||||
|
||||
for (const message of histories) {
|
||||
if (message.type === 'apiMessage') {
|
||||
chatHistory.push(new AIChatMessage(message.message))
|
||||
} else if (message.type === 'userMessage') {
|
||||
chatHistory.push(new HumanChatMessage(message.message))
|
||||
}
|
||||
}
|
||||
memory.chatHistory = new ChatMessageHistory(chatHistory)
|
||||
chain.memory = memory
|
||||
}
|
||||
|
||||
const res = await chain.call({ input })
|
||||
return res?.response
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { nodeClass: ConversationChain_Chains }
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-dna" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M14.828 14.828a4 4 0 1 0 -5.656 -5.656a4 4 0 0 0 5.656 5.656z"></path>
|
||||
<path d="M9.172 20.485a4 4 0 1 0 -5.657 -5.657"></path>
|
||||
<path d="M14.828 3.515a4 4 0 0 0 5.657 5.657"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 489 B |
|
|
@ -0,0 +1,282 @@
|
|||
{
|
||||
"description": "Basic example of Conversation Chain with built-in memory - works exactly like ChatGPT",
|
||||
"nodes": [
|
||||
{
|
||||
"width": 300,
|
||||
"height": 524,
|
||||
"id": "chatOpenAI_0",
|
||||
"position": {
|
||||
"x": 750.6529856117049,
|
||||
"y": -75.72544375812092
|
||||
},
|
||||
"type": "customNode",
|
||||
"data": {
|
||||
"id": "chatOpenAI_0",
|
||||
"label": "ChatOpenAI",
|
||||
"name": "chatOpenAI",
|
||||
"type": "ChatOpenAI",
|
||||
"baseClasses": ["ChatOpenAI", "BaseChatModel", "BaseLanguageModel", "BaseLangChain"],
|
||||
"category": "Chat Models",
|
||||
"description": "Wrapper around OpenAI large language models that use the Chat endpoint",
|
||||
"inputParams": [
|
||||
{
|
||||
"label": "OpenAI Api Key",
|
||||
"name": "openAIApiKey",
|
||||
"type": "password",
|
||||
"id": "chatOpenAI_0-input-openAIApiKey-password"
|
||||
},
|
||||
{
|
||||
"label": "Model Name",
|
||||
"name": "modelName",
|
||||
"type": "options",
|
||||
"options": [
|
||||
{
|
||||
"label": "gpt-4",
|
||||
"name": "gpt-4"
|
||||
},
|
||||
{
|
||||
"label": "gpt-4-0314",
|
||||
"name": "gpt-4-0314"
|
||||
},
|
||||
{
|
||||
"label": "gpt-4-32k-0314",
|
||||
"name": "gpt-4-32k-0314"
|
||||
},
|
||||
{
|
||||
"label": "gpt-3.5-turbo",
|
||||
"name": "gpt-3.5-turbo"
|
||||
},
|
||||
{
|
||||
"label": "gpt-3.5-turbo-0301",
|
||||
"name": "gpt-3.5-turbo-0301"
|
||||
}
|
||||
],
|
||||
"default": "gpt-3.5-turbo",
|
||||
"optional": true,
|
||||
"id": "chatOpenAI_0-input-modelName-options"
|
||||
},
|
||||
{
|
||||
"label": "Temperature",
|
||||
"name": "temperature",
|
||||
"type": "number",
|
||||
"default": 0.9,
|
||||
"optional": true,
|
||||
"id": "chatOpenAI_0-input-temperature-number"
|
||||
},
|
||||
{
|
||||
"label": "Max Tokens",
|
||||
"name": "maxTokens",
|
||||
"type": "number",
|
||||
"optional": true,
|
||||
"additionalParams": true,
|
||||
"id": "chatOpenAI_0-input-maxTokens-number"
|
||||
},
|
||||
{
|
||||
"label": "Top Probability",
|
||||
"name": "topP",
|
||||
"type": "number",
|
||||
"optional": true,
|
||||
"additionalParams": true,
|
||||
"id": "chatOpenAI_0-input-topP-number"
|
||||
},
|
||||
{
|
||||
"label": "Frequency Penalty",
|
||||
"name": "frequencyPenalty",
|
||||
"type": "number",
|
||||
"optional": true,
|
||||
"additionalParams": true,
|
||||
"id": "chatOpenAI_0-input-frequencyPenalty-number"
|
||||
},
|
||||
{
|
||||
"label": "Presence Penalty",
|
||||
"name": "presencePenalty",
|
||||
"type": "number",
|
||||
"optional": true,
|
||||
"additionalParams": true,
|
||||
"id": "chatOpenAI_0-input-presencePenalty-number"
|
||||
},
|
||||
{
|
||||
"label": "Timeout",
|
||||
"name": "timeout",
|
||||
"type": "number",
|
||||
"optional": true,
|
||||
"additionalParams": true,
|
||||
"id": "chatOpenAI_0-input-timeout-number"
|
||||
}
|
||||
],
|
||||
"inputAnchors": [],
|
||||
"inputs": {
|
||||
"modelName": "gpt-3.5-turbo",
|
||||
"temperature": 0.9,
|
||||
"maxTokens": "",
|
||||
"topP": "",
|
||||
"frequencyPenalty": "",
|
||||
"presencePenalty": "",
|
||||
"timeout": ""
|
||||
},
|
||||
"outputAnchors": [
|
||||
{
|
||||
"id": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
|
||||
"name": "chatOpenAI",
|
||||
"label": "ChatOpenAI",
|
||||
"type": "ChatOpenAI | BaseChatModel | BaseLanguageModel | BaseLangChain"
|
||||
}
|
||||
],
|
||||
"outputs": {},
|
||||
"selected": false
|
||||
},
|
||||
"positionAbsolute": {
|
||||
"x": 750.6529856117049,
|
||||
"y": -75.72544375812092
|
||||
},
|
||||
"selected": false,
|
||||
"dragging": false
|
||||
},
|
||||
{
|
||||
"width": 300,
|
||||
"height": 376,
|
||||
"id": "bufferMemory_0",
|
||||
"position": {
|
||||
"x": 753.4300788823234,
|
||||
"y": 479.5336426526603
|
||||
},
|
||||
"type": "customNode",
|
||||
"data": {
|
||||
"id": "bufferMemory_0",
|
||||
"label": "Buffer Memory",
|
||||
"name": "bufferMemory",
|
||||
"type": "BufferMemory",
|
||||
"baseClasses": ["BufferMemory", "BaseChatMemory", "BaseMemory"],
|
||||
"category": "Memory",
|
||||
"description": "Remembers previous conversational back and forths directly",
|
||||
"inputParams": [
|
||||
{
|
||||
"label": "Memory Key",
|
||||
"name": "memoryKey",
|
||||
"type": "string",
|
||||
"default": "chat_history",
|
||||
"id": "bufferMemory_0-input-memoryKey-string"
|
||||
},
|
||||
{
|
||||
"label": "Input Key",
|
||||
"name": "inputKey",
|
||||
"type": "string",
|
||||
"default": "input",
|
||||
"id": "bufferMemory_0-input-inputKey-string"
|
||||
}
|
||||
],
|
||||
"inputAnchors": [],
|
||||
"inputs": {
|
||||
"memoryKey": "chat_history",
|
||||
"inputKey": "input"
|
||||
},
|
||||
"outputAnchors": [
|
||||
{
|
||||
"id": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
|
||||
"name": "bufferMemory",
|
||||
"label": "BufferMemory",
|
||||
"type": "BufferMemory | BaseChatMemory | BaseMemory"
|
||||
}
|
||||
],
|
||||
"outputs": {},
|
||||
"selected": false
|
||||
},
|
||||
"selected": false,
|
||||
"positionAbsolute": {
|
||||
"x": 753.4300788823234,
|
||||
"y": 479.5336426526603
|
||||
},
|
||||
"dragging": false
|
||||
},
|
||||
{
|
||||
"width": 300,
|
||||
"height": 332,
|
||||
"id": "conversationChain_0",
|
||||
"position": {
|
||||
"x": 1201.6630991237407,
|
||||
"y": 291.86981791303066
|
||||
},
|
||||
"type": "customNode",
|
||||
"data": {
|
||||
"id": "conversationChain_0",
|
||||
"label": "Conversation Chain",
|
||||
"name": "conversationChain",
|
||||
"type": "ConversationChain",
|
||||
"baseClasses": ["ConversationChain", "LLMChain", "BaseChain", "BaseLangChain"],
|
||||
"category": "Chains",
|
||||
"description": "Chat models specific conversational chain with memory",
|
||||
"inputParams": [
|
||||
{
|
||||
"label": "System Message",
|
||||
"name": "systemMessagePrompt",
|
||||
"type": "string",
|
||||
"rows": 4,
|
||||
"additionalParams": true,
|
||||
"optional": true,
|
||||
"placeholder": "You are a helpful assistant that write codes",
|
||||
"id": "conversationChain_0-input-systemMessagePrompt-string"
|
||||
}
|
||||
],
|
||||
"inputAnchors": [
|
||||
{
|
||||
"label": "Language Model",
|
||||
"name": "model",
|
||||
"type": "BaseChatModel",
|
||||
"id": "conversationChain_0-input-model-BaseChatModel"
|
||||
},
|
||||
{
|
||||
"label": "Memory",
|
||||
"name": "memory",
|
||||
"type": "BaseMemory",
|
||||
"id": "conversationChain_0-input-memory-BaseMemory"
|
||||
}
|
||||
],
|
||||
"inputs": {
|
||||
"model": "{{chatOpenAI_0.data.instance}}",
|
||||
"memory": "{{bufferMemory_0.data.instance}}",
|
||||
"systemMessagePrompt": ""
|
||||
},
|
||||
"outputAnchors": [
|
||||
{
|
||||
"id": "conversationChain_0-output-conversationChain-ConversationChain|LLMChain|BaseChain|BaseLangChain",
|
||||
"name": "conversationChain",
|
||||
"label": "ConversationChain",
|
||||
"type": "ConversationChain | LLMChain | BaseChain | BaseLangChain"
|
||||
}
|
||||
],
|
||||
"outputs": {},
|
||||
"selected": false
|
||||
},
|
||||
"selected": false,
|
||||
"positionAbsolute": {
|
||||
"x": 1201.6630991237407,
|
||||
"y": 291.86981791303066
|
||||
},
|
||||
"dragging": false
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "chatOpenAI_0",
|
||||
"sourceHandle": "chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain",
|
||||
"target": "conversationChain_0",
|
||||
"targetHandle": "conversationChain_0-input-model-BaseChatModel",
|
||||
"type": "buttonedge",
|
||||
"id": "chatOpenAI_0-chatOpenAI_0-output-chatOpenAI-ChatOpenAI|BaseChatModel|BaseLanguageModel|BaseLangChain-conversationChain_0-conversationChain_0-input-model-BaseChatModel",
|
||||
"data": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": "bufferMemory_0",
|
||||
"sourceHandle": "bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory",
|
||||
"target": "conversationChain_0",
|
||||
"targetHandle": "conversationChain_0-input-memory-BaseMemory",
|
||||
"type": "buttonedge",
|
||||
"id": "bufferMemory_0-bufferMemory_0-output-bufferMemory-BufferMemory|BaseChatMemory|BaseMemory-conversationChain_0-conversationChain_0-input-memory-BaseMemory",
|
||||
"data": {
|
||||
"label": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"description": "Basic example of LLM Chain with a Prompt Template and LLM Model",
|
||||
"description": "Basic example of stateless (no memory) LLM Chain with a Prompt Template and LLM Model",
|
||||
"nodes": [
|
||||
{
|
||||
"width": 300,
|
||||
|
|
|
|||
Loading…
Reference in New Issue