Feature/Add message history to agents (#3031)

add message history to agents
This commit is contained in:
Henry Heng
2024-08-17 19:28:01 +01:00
committed by GitHub
parent 36c6c6425c
commit 0a36aa7ef4
6 changed files with 256 additions and 16 deletions
@@ -1,6 +1,33 @@
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { ICommonObject, IDatabaseEntity, INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
import { ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate } from '@langchain/core/prompts'
import { getVM } from '../../sequentialagents/commonUtils'
import { DataSource } from 'typeorm'
const defaultFunc = `const { AIMessage, HumanMessage, ToolMessage } = require('@langchain/core/messages');
return [
new HumanMessage("What is 333382 🦜 1932?"),
new AIMessage({
content: "",
tool_calls: [
{
id: "12345",
name: "calulator",
args: {
number1: 333382,
number2: 1932,
operation: "divide",
},
},
],
}),
new ToolMessage({
tool_call_id: "12345",
content: "The answer is 172.558.",
}),
new AIMessage("The answer is 172.558."),
]`
const TAB_IDENTIFIER = 'selectedMessagesTab'
class ChatPromptTemplate_Prompts implements INode {
label: string
@@ -16,7 +43,7 @@ class ChatPromptTemplate_Prompts implements INode {
constructor() {
this.label = 'Chat Prompt Template'
this.name = 'chatPromptTemplate'
this.version = 1.0
this.version = 2.0
this.type = 'ChatPromptTemplate'
this.icon = 'prompt.svg'
this.category = 'Prompts'
@@ -33,6 +60,7 @@ class ChatPromptTemplate_Prompts implements INode {
{
label: 'Human Message',
name: 'humanMessagePrompt',
description: 'This prompt will be added at the end of the messages as human message',
type: 'string',
rows: 4,
placeholder: `{text}`
@@ -44,20 +72,62 @@ class ChatPromptTemplate_Prompts implements INode {
optional: true,
acceptVariable: true,
list: true
},
{
label: 'Messages History',
name: 'messageHistory',
description: 'Add messages after System Message. This is useful when you want to provide few shot examples',
type: 'tabs',
tabIdentifier: TAB_IDENTIFIER,
additionalParams: true,
default: 'messageHistoryCode',
tabs: [
//TODO: add UI for messageHistory
{
label: 'Add Messages (Code)',
name: 'messageHistoryCode',
type: 'code',
hideCodeExecute: true,
codeExample: defaultFunc,
optional: true,
additionalParams: true
}
]
}
]
}
async init(nodeData: INodeData): Promise<any> {
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
const systemMessagePrompt = nodeData.inputs?.systemMessagePrompt as string
const humanMessagePrompt = nodeData.inputs?.humanMessagePrompt as string
const promptValuesStr = nodeData.inputs?.promptValues
const tabIdentifier = nodeData.inputs?.[`${TAB_IDENTIFIER}_${nodeData.id}`] as string
const selectedTab = tabIdentifier ? tabIdentifier.split(`_${nodeData.id}`)[0] : 'messageHistoryCode'
const messageHistoryCode = nodeData.inputs?.messageHistoryCode
const messageHistory = nodeData.inputs?.messageHistory
const prompt = ChatPromptTemplate.fromMessages([
let prompt = ChatPromptTemplate.fromMessages([
SystemMessagePromptTemplate.fromTemplate(systemMessagePrompt),
HumanMessagePromptTemplate.fromTemplate(humanMessagePrompt)
])
if ((messageHistory && messageHistory === 'messageHistoryCode') || (selectedTab === 'messageHistoryCode' && messageHistoryCode)) {
const appDataSource = options.appDataSource as DataSource
const databaseEntities = options.databaseEntities as IDatabaseEntity
const vm = await getVM(appDataSource, databaseEntities, nodeData, {})
try {
const response = await vm.run(`module.exports = async function() {${messageHistoryCode}}()`, __dirname)
if (!Array.isArray(response)) throw new Error('Returned message history must be an array')
prompt = ChatPromptTemplate.fromMessages([
SystemMessagePromptTemplate.fromTemplate(systemMessagePrompt),
...response,
HumanMessagePromptTemplate.fromTemplate(humanMessagePrompt)
])
} catch (e) {
throw new Error(e)
}
}
let promptValues: ICommonObject = {}
if (promptValuesStr) {
try {