From cadc3b8fb341982e568555becdfc7e40c772bb10 Mon Sep 17 00:00:00 2001 From: Henry Heng Date: Fri, 6 Dec 2024 22:16:01 +0000 Subject: [PATCH] Feature/Add dedicated agent memory nodes (#3649) add dedicated agent memory nodes --- .../nodes/memory/AgentMemory/AgentMemory.ts | 7 +- .../MySQLAgentMemory/MySQLAgentMemory.ts | 112 ++++++++++++++++++ .../AgentMemory/MySQLAgentMemory/mysql.png | Bin 0 -> 3750 bytes .../{ => MySQLAgentMemory}/mysqlSaver.ts | 6 +- .../PostgresAgentMemory.ts | 111 +++++++++++++++++ .../{ => PostgresAgentMemory}/pgSaver.ts | 6 +- .../PostgresAgentMemory/postgres.svg | 1 + .../SQLiteAgentMemory/SQLiteAgentMemory.ts | 87 ++++++++++++++ .../AgentMemory/SQLiteAgentMemory/sqlite.png | Bin 0 -> 50383 bytes .../{ => SQLiteAgentMemory}/sqliteSaver.ts | 6 +- packages/server/src/utils/buildAgentGraph.ts | 3 +- packages/ui/src/views/canvas/AddNodes.jsx | 6 +- 12 files changed, 330 insertions(+), 15 deletions(-) create mode 100644 packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/MySQLAgentMemory.ts create mode 100644 packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/mysql.png rename packages/components/nodes/memory/AgentMemory/{ => MySQLAgentMemory}/mysqlSaver.ts (98%) create mode 100644 packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/PostgresAgentMemory.ts rename packages/components/nodes/memory/AgentMemory/{ => PostgresAgentMemory}/pgSaver.ts (98%) create mode 100644 packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/postgres.svg create mode 100644 packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/SQLiteAgentMemory.ts create mode 100644 packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqlite.png rename packages/components/nodes/memory/AgentMemory/{ => SQLiteAgentMemory}/sqliteSaver.ts (98%) diff --git a/packages/components/nodes/memory/AgentMemory/AgentMemory.ts b/packages/components/nodes/memory/AgentMemory/AgentMemory.ts index 33ef61cb..d317e138 100644 --- a/packages/components/nodes/memory/AgentMemory/AgentMemory.ts +++ b/packages/components/nodes/memory/AgentMemory/AgentMemory.ts @@ -2,10 +2,10 @@ import path from 'path' import { getBaseClasses, getCredentialData, getCredentialParam, getUserHome } from '../../../src/utils' import { SaverOptions } from './interface' import { ICommonObject, IDatabaseEntity, INode, INodeData, INodeParams } from '../../../src/Interface' -import { SqliteSaver } from './sqliteSaver' +import { SqliteSaver } from './SQLiteAgentMemory/sqliteSaver' import { DataSource } from 'typeorm' -import { PostgresSaver } from './pgSaver' -import { MySQLSaver } from './mysqlSaver' +import { PostgresSaver } from './PostgresAgentMemory/pgSaver' +import { MySQLSaver } from './MySQLAgentMemory/mysqlSaver' class AgentMemory_Memory implements INode { label: string @@ -29,6 +29,7 @@ class AgentMemory_Memory implements INode { this.category = 'Memory' this.description = 'Memory for agentflow to remember the state of the conversation' this.baseClasses = [this.type, ...getBaseClasses(SqliteSaver)] + this.badge = 'DEPRECATING' this.credential = { label: 'Connect Credential', name: 'credential', diff --git a/packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/MySQLAgentMemory.ts b/packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/MySQLAgentMemory.ts new file mode 100644 index 00000000..af3ebe61 --- /dev/null +++ b/packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/MySQLAgentMemory.ts @@ -0,0 +1,112 @@ +import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../../src/utils' +import { SaverOptions } from '../interface' +import { ICommonObject, IDatabaseEntity, INode, INodeData, INodeParams } from '../../../../src/Interface' +import { DataSource } from 'typeorm' +import { MySQLSaver } from './mysqlSaver' + +class MySQLAgentMemory_Memory implements INode { + label: string + name: string + version: number + description: string + type: string + icon: string + category: string + badge: string + baseClasses: string[] + inputs: INodeParams[] + credential: INodeParams + + constructor() { + this.label = 'MySQL Agent Memory' + this.name = 'mySQLAgentMemory' + this.version = 1.0 + this.type = 'AgentMemory' + this.icon = 'mysql.png' + this.category = 'Memory' + this.description = 'Memory for agentflow to remember the state of the conversation using MySQL database' + this.baseClasses = [this.type, ...getBaseClasses(MySQLSaver)] + this.credential = { + label: 'Connect Credential', + name: 'credential', + type: 'credential', + credentialNames: ['MySQLApi'], + optional: true + } + this.inputs = [ + { + label: 'Host', + name: 'host', + type: 'string' + }, + { + label: 'Database', + name: 'database', + type: 'string' + }, + { + label: 'Port', + name: 'port', + type: 'number', + default: '3306' + }, + { + label: 'Additional Connection Configuration', + name: 'additionalConfig', + type: 'json', + additionalParams: true, + optional: true + } + ] + } + + async init(nodeData: INodeData, _: string, options: ICommonObject): Promise { + const additionalConfig = nodeData.inputs?.additionalConfig as string + const databaseEntities = options.databaseEntities as IDatabaseEntity + const chatflowid = options.chatflowid as string + const appDataSource = options.appDataSource as DataSource + + let additionalConfiguration = {} + if (additionalConfig) { + try { + additionalConfiguration = typeof additionalConfig === 'object' ? additionalConfig : JSON.parse(additionalConfig) + } catch (exception) { + throw new Error('Invalid JSON in the Additional Configuration: ' + exception) + } + } + + const threadId = options.sessionId || options.chatId + + let datasourceOptions: ICommonObject = { + ...additionalConfiguration, + type: 'mysql' + } + + const credentialData = await getCredentialData(nodeData.credential ?? '', options) + const user = getCredentialParam('user', credentialData, nodeData) + const password = getCredentialParam('password', credentialData, nodeData) + const _port = (nodeData.inputs?.port as string) || '3306' + const port = parseInt(_port) + datasourceOptions = { + ...datasourceOptions, + host: nodeData.inputs?.host as string, + port, + database: nodeData.inputs?.database as string, + username: user, + user: user, + password: password, + charset: 'utf8mb4' + } + const args: SaverOptions = { + datasourceOptions, + threadId, + appDataSource, + databaseEntities, + chatflowid + } + const recordManager = new MySQLSaver(args) + return recordManager + } +} + +module.exports = { nodeClass: MySQLAgentMemory_Memory } diff --git a/packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/mysql.png b/packages/components/nodes/memory/AgentMemory/MySQLAgentMemory/mysql.png new file mode 100644 index 0000000000000000000000000000000000000000..11c2d8b2e83666b481dbd596a2f1f4109054aeca GIT binary patch literal 3750 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 { + const additionalConfig = nodeData.inputs?.additionalConfig as string + const databaseEntities = options.databaseEntities as IDatabaseEntity + const chatflowid = options.chatflowid as string + const appDataSource = options.appDataSource as DataSource + + let additionalConfiguration = {} + if (additionalConfig) { + try { + additionalConfiguration = typeof additionalConfig === 'object' ? additionalConfig : JSON.parse(additionalConfig) + } catch (exception) { + throw new Error('Invalid JSON in the Additional Configuration: ' + exception) + } + } + + const threadId = options.sessionId || options.chatId + + let datasourceOptions: ICommonObject = { + ...additionalConfiguration, + type: 'postgres' + } + + const credentialData = await getCredentialData(nodeData.credential ?? '', options) + const user = getCredentialParam('user', credentialData, nodeData) + const password = getCredentialParam('password', credentialData, nodeData) + const _port = (nodeData.inputs?.port as string) || '5432' + const port = parseInt(_port) + datasourceOptions = { + ...datasourceOptions, + host: nodeData.inputs?.host as string, + port, + database: nodeData.inputs?.database as string, + username: user, + user: user, + password: password + } + const args: SaverOptions = { + datasourceOptions, + threadId, + appDataSource, + databaseEntities, + chatflowid + } + const recordManager = new PostgresSaver(args) + return recordManager + } +} + +module.exports = { nodeClass: PostgresAgentMemory_Memory } diff --git a/packages/components/nodes/memory/AgentMemory/pgSaver.ts b/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts similarity index 98% rename from packages/components/nodes/memory/AgentMemory/pgSaver.ts rename to packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts index 7913825a..11f261a4 100644 --- a/packages/components/nodes/memory/AgentMemory/pgSaver.ts +++ b/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/pgSaver.ts @@ -2,9 +2,9 @@ import { BaseCheckpointSaver, Checkpoint, CheckpointMetadata } from '@langchain/ import { RunnableConfig } from '@langchain/core/runnables' import { BaseMessage } from '@langchain/core/messages' import { DataSource } from 'typeorm' -import { CheckpointTuple, SaverOptions, SerializerProtocol } from './interface' -import { IMessage, MemoryMethods } from '../../../src/Interface' -import { mapChatMessageToBaseMessage } from '../../../src/utils' +import { CheckpointTuple, SaverOptions, SerializerProtocol } from '../interface' +import { IMessage, MemoryMethods } from '../../../../src/Interface' +import { mapChatMessageToBaseMessage } from '../../../../src/utils' export class PostgresSaver extends BaseCheckpointSaver implements MemoryMethods { protected isSetup: boolean diff --git a/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/postgres.svg b/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/postgres.svg new file mode 100644 index 00000000..f631e7a8 --- /dev/null +++ b/packages/components/nodes/memory/AgentMemory/PostgresAgentMemory/postgres.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/SQLiteAgentMemory.ts b/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/SQLiteAgentMemory.ts new file mode 100644 index 00000000..b301e3a8 --- /dev/null +++ b/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/SQLiteAgentMemory.ts @@ -0,0 +1,87 @@ +import path from 'path' +import { getBaseClasses, getUserHome } from '../../../../src/utils' +import { SaverOptions } from '../interface' +import { ICommonObject, IDatabaseEntity, INode, INodeData, INodeParams } from '../../../../src/Interface' +import { SqliteSaver } from './sqliteSaver' +import { DataSource } from 'typeorm' + +class SQLiteAgentMemory_Memory implements INode { + label: string + name: string + version: number + description: string + type: string + icon: string + category: string + badge: string + baseClasses: string[] + inputs: INodeParams[] + credential: INodeParams + + constructor() { + this.label = 'SQLite Agent Memory' + this.name = 'sqliteAgentMemory' + this.version = 1.0 + this.type = 'SQLiteAgentMemory' + this.icon = 'sqlite.png' + this.category = 'Memory' + this.description = 'Memory for agentflow to remember the state of the conversation using SQLite database' + this.baseClasses = [this.type, ...getBaseClasses(SqliteSaver)] + this.inputs = [ + /*{ + label: 'Database File Path', + name: 'databaseFilePath', + type: 'string', + placeholder: 'C:\\Users\\User\\.flowise\\database.sqlite', + description: 'Path to the SQLite database file. Leave empty to use default application database', + optional: true + },*/ + { + label: 'Additional Connection Configuration', + name: 'additionalConfig', + type: 'json', + additionalParams: true, + optional: true + } + ] + } + + async init(nodeData: INodeData, _: string, options: ICommonObject): Promise { + const additionalConfig = nodeData.inputs?.additionalConfig as string + const databaseEntities = options.databaseEntities as IDatabaseEntity + const chatflowid = options.chatflowid as string + const appDataSource = options.appDataSource as DataSource + + let additionalConfiguration = {} + if (additionalConfig) { + try { + additionalConfiguration = typeof additionalConfig === 'object' ? additionalConfig : JSON.parse(additionalConfig) + } catch (exception) { + throw new Error('Invalid JSON in the Additional Configuration: ' + exception) + } + } + + const threadId = options.sessionId || options.chatId + + const database = path.join(process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise'), 'database.sqlite') + + let datasourceOptions: ICommonObject = { + database, + ...additionalConfiguration, + type: 'sqlite' + } + + const args: SaverOptions = { + datasourceOptions, + threadId, + appDataSource, + databaseEntities, + chatflowid + } + + const recordManager = new SqliteSaver(args) + return recordManager + } +} + +module.exports = { nodeClass: SQLiteAgentMemory_Memory } diff --git a/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqlite.png b/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqlite.png new file mode 100644 index 0000000000000000000000000000000000000000..9f35f2bdf3c9eb5d8a8fd48dc81627082a1d03fa GIT binary patch literal 50383 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

4hyefmb` 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 Nx{5j`_lnu`{|}An@!kLc literal 0 HcmV?d00001 diff --git a/packages/components/nodes/memory/AgentMemory/sqliteSaver.ts b/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqliteSaver.ts similarity index 98% rename from packages/components/nodes/memory/AgentMemory/sqliteSaver.ts rename to packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqliteSaver.ts index 4e5c5b80..dc746936 100644 --- a/packages/components/nodes/memory/AgentMemory/sqliteSaver.ts +++ b/packages/components/nodes/memory/AgentMemory/SQLiteAgentMemory/sqliteSaver.ts @@ -2,9 +2,9 @@ import { BaseCheckpointSaver, Checkpoint, CheckpointMetadata } from '@langchain/ import { RunnableConfig } from '@langchain/core/runnables' import { BaseMessage } from '@langchain/core/messages' import { DataSource, QueryRunner } from 'typeorm' -import { CheckpointTuple, SaverOptions, SerializerProtocol } from './interface' -import { IMessage, MemoryMethods } from '../../../src/Interface' -import { mapChatMessageToBaseMessage } from '../../../src/utils' +import { CheckpointTuple, SaverOptions, SerializerProtocol } from '../interface' +import { IMessage, MemoryMethods } from '../../../../src/Interface' +import { mapChatMessageToBaseMessage } from '../../../../src/utils' export class SqliteSaver extends BaseCheckpointSaver implements MemoryMethods { protected isSetup: boolean diff --git a/packages/server/src/utils/buildAgentGraph.ts b/packages/server/src/utils/buildAgentGraph.ts index c0e8d7a6..011cbcab 100644 --- a/packages/server/src/utils/buildAgentGraph.ts +++ b/packages/server/src/utils/buildAgentGraph.ts @@ -98,7 +98,8 @@ export const buildAgentGraph = async ( /*** Get Memory Node for Chat History ***/ let chatHistory: IMessage[] = [] - const memoryNode = nodes.find((node) => node.data.name === 'agentMemory') + const agentMemoryList = ['agentMemory', 'sqliteAgentMemory', 'postgresAgentMemory', 'mySQLAgentMemory'] + const memoryNode = nodes.find((node) => agentMemoryList.includes(node.data.name)) if (memoryNode) { chatHistory = await getSessionChatHistory( chatflowid, diff --git a/packages/ui/src/views/canvas/AddNodes.jsx b/packages/ui/src/views/canvas/AddNodes.jsx index e3e54383..93079a30 100644 --- a/packages/ui/src/views/canvas/AddNodes.jsx +++ b/packages/ui/src/views/canvas/AddNodes.jsx @@ -56,15 +56,17 @@ function a11yProps(index) { const blacklistCategoriesForAgentCanvas = ['Agents', 'Memory', 'Record Manager', 'Utilities'] +const agentMemoryNodes = ['agentMemory', 'sqliteAgentMemory', 'postgresAgentMemory', 'mySQLAgentMemory'] + // Show blacklisted nodes (exceptions) for agent canvas const exceptionsForAgentCanvas = { - Memory: ['agentMemory'], + Memory: agentMemoryNodes, Utilities: ['getVariable', 'setVariable', 'stickyNote'] } // Hide some nodes from the chatflow canvas const blacklistForChatflowCanvas = { - Memory: ['agentMemory'] + Memory: agentMemoryNodes } const AddNodes = ({ nodesData, node, isAgentCanvas }) => {