feat: Add options to filter conversation history messages used in sequential LLM and Agent nodes (#3653)

* feat: Add option to disable conversation history

- Add new `disableConversationHistory` boolean parameter in LLMNodes.ts and Agent.ts to optionally skip including conversation history in prompts
- Fix potential error in Agent.ts when messages array is empty by adding null safety checks
- Improve memory efficiency by allowing stateless interactions when history isn't needed

* feat: add conversation history filtering options

Replace the disable conversation history feature with a more flexible filtering system that allows selecting:
- User question only
- Last message only
- All messages (default)
- No messages

This provides more granular control over conversation context management.

* chore: break lines

* chore: removed ending semi columns

* chore: fix eslint errors

* fix(sequentialagents): improve conversation history filtering logic

- Remove unnecessary state.messages check for user_question case
- Add proper null handling for last_message and all_messages cases
- Remove @ts-ignore comments with proper typing

* Update LLMNode.ts

* Update Agent.ts

---------

Co-authored-by: Henry Heng <henryheng@flowiseai.com>
This commit is contained in:
Jean Ibarz
2024-12-12 14:29:28 +01:00
committed by GitHub
parent d974564ba5
commit 26b78ad55a
4 changed files with 147 additions and 29 deletions
@@ -14,7 +14,8 @@ import {
MessageContentImageUrl,
INodeOutputsValue,
ISeqAgentNode,
IDatabaseEntity
IDatabaseEntity,
ConversationHistorySelection
} from '../../../src/Interface'
import { AgentExecutor } from '../../../src/agents'
import { getInputVariables, getVars, handleEscapeCharacters, prepareSandboxVars } from '../../../src/utils'
@@ -25,6 +26,7 @@ import {
getVM,
processImageMessage,
transformObjectPropertyToFunction,
filterConversationHistory,
restructureMessages,
checkMessageHistory
} from '../commonUtils'
@@ -173,7 +175,7 @@ class LLMNode_SeqAgents implements INode {
constructor() {
this.label = 'LLM Node'
this.name = 'seqLLMNode'
this.version = 3.0
this.version = 4.0
this.type = 'LLMNode'
this.icon = 'llmNode.svg'
this.category = 'Sequential Agents'
@@ -195,6 +197,53 @@ class LLMNode_SeqAgents implements INode {
optional: true,
additionalParams: true
},
{
label: 'Prepend Messages History',
name: 'messageHistory',
description:
'Prepend a list of messages between System Prompt and Human Prompt. This is useful when you want to provide few shot examples',
type: 'code',
hideCodeExecute: true,
codeExample: messageHistoryExample,
optional: true,
additionalParams: true
},
{
label: 'Conversation History',
name: 'conversationHistorySelection',
type: 'options',
options: [
{
label: 'User Question',
name: 'user_question',
description: 'Use the user question from the historical conversation messages as input.'
},
{
label: 'Last Conversation Message',
name: 'last_message',
description: 'Use the last conversation message from the historical conversation messages as input.'
},
{
label: 'All Conversation Messages',
name: 'all_messages',
description: 'Use all conversation messages from the historical conversation messages as input.'
},
{
label: 'Empty',
name: 'empty',
description:
'Do not use any messages from the conversation history. ' +
'Ensure to use either System Prompt, Human Prompt, or Messages History.'
}
],
default: 'all_messages',
optional: true,
description:
'Select which messages from the conversation history to include in the prompt. ' +
'The selected messages will be inserted between the System Prompt (if defined) and ' +
'[Messages History, Human Prompt].',
additionalParams: true
},
{
label: 'Human Prompt',
name: 'humanMessagePrompt',
@@ -204,17 +253,6 @@ class LLMNode_SeqAgents implements INode {
optional: true,
additionalParams: true
},
{
label: 'Messages History',
name: 'messageHistory',
description:
'Return a list of messages between System Prompt and Human Prompt. This is useful when you want to provide few shot examples',
type: 'code',
hideCodeExecute: true,
codeExample: messageHistoryExample,
optional: true,
additionalParams: true
},
{
label: 'Start | Agent | Condition | LLM | Tool Node',
name: 'sequentialNode',
@@ -534,6 +572,9 @@ async function agentNode(
throw new Error('Aborted!')
}
const historySelection = (nodeData.inputs?.conversationHistorySelection || 'all_messages') as ConversationHistorySelection
// @ts-ignore
state.messages = filterConversationHistory(historySelection, input, state)
// @ts-ignore
state.messages = restructureMessages(llm, state)