Feature/agentflow v2 (#4298)

* agent flow v2

* chat message background

* conditon agent flow

* add sticky note

* update human input dynamic prompt

* add HTTP node

* add default tool icon

* fix export duplicate agentflow v2

* add agentflow v2 marketplaces

* refractor memoization, add iteration nodes

* add agentflow v2 templates

* add agentflow generator

* add migration scripts for mysql, mariadb, posrgres and fix date filters for executions

* update agentflow chat history config

* fix get all flows error after deletion and rename

* add previous nodes from parent node

* update generator prompt

* update run time state when using iteration nodes

* prevent looping connection, prevent duplication of start node, add executeflow node, add nodes agentflow, chat history variable

* update embed

* convert form input to string

* bump openai version

* add react rewards

* add prompt generator to prediction queue

* add array schema to overrideconfig

* UI touchup

* update embedded chat version

* fix node info dialog

* update start node and loop default iteration

* update UI fixes for agentflow v2

* fix async drop down

* add export import to agentflowsv2, executions, fix UI bugs

* add default empty object to flowlisttable

* add ability to share trace link publicly, allow MCP tool use for Agent and Assistant

* add runtime message length to variable, display conditions on UI

* fix array validation

* add ability to add knowledge from vector store and embeddings for agent

* add agent tool require human input

* add ephemeral memory to start node

* update agent flow node to show vs and embeddings icons

* feat: add import chat data functionality for AgentFlowV2

* feat: set chatMessage.executionId to null if not found in import JSON file or database

* fix: MariaDB execution migration script to utf8mb4_unicode_520_ci

---------

Co-authored-by: Ong Chung Yau <33013947+chungyau97@users.noreply.github.com>
Co-authored-by: chungyau97 <chungyau97@gmail.com>
This commit is contained in:
Henry Heng
2025-05-10 10:21:26 +08:00
committed by GitHub
parent 82e6f43b5c
commit 7924fbce0d
216 changed files with 33304 additions and 5269 deletions
+24 -1
View File
@@ -7,6 +7,9 @@ import { RedisEventPublisher } from './RedisEventPublisher'
import { AbortControllerPool } from '../AbortControllerPool'
import { BaseQueue } from './BaseQueue'
import { RedisOptions } from 'bullmq'
import logger from '../utils/logger'
import { generateAgentflowv2 as generateAgentflowv2_json } from 'flowise-components'
import { databaseEntities } from '../utils'
interface PredictionQueueOptions {
appDataSource: DataSource
@@ -16,6 +19,15 @@ interface PredictionQueueOptions {
abortControllerPool: AbortControllerPool
}
interface IGenerateAgentflowv2Params extends IExecuteFlowParams {
prompt: string
componentNodes: IComponentNodes
toolNodes: IComponentNodes
selectedChatModel: Record<string, any>
question: string
isAgentFlowGenerator: boolean
}
export class PredictionQueue extends BaseQueue {
private componentNodes: IComponentNodes
private telemetry: Telemetry
@@ -45,13 +57,24 @@ export class PredictionQueue extends BaseQueue {
return this.queue
}
async processJob(data: IExecuteFlowParams) {
async processJob(data: IExecuteFlowParams | IGenerateAgentflowv2Params) {
if (this.appDataSource) data.appDataSource = this.appDataSource
if (this.telemetry) data.telemetry = this.telemetry
if (this.cachePool) data.cachePool = this.cachePool
if (this.componentNodes) data.componentNodes = this.componentNodes
if (this.redisPublisher) data.sseStreamer = this.redisPublisher
if (Object.prototype.hasOwnProperty.call(data, 'isAgentFlowGenerator')) {
logger.info('Generating Agentflow...')
const { prompt, componentNodes, toolNodes, selectedChatModel, question } = data as IGenerateAgentflowv2Params
const options: Record<string, any> = {
appDataSource: this.appDataSource,
databaseEntities: databaseEntities,
logger: logger
}
return await generateAgentflowv2_json({ prompt, componentNodes, toolNodes, selectedChatModel }, question, options)
}
if (this.abortControllerPool) {
const abortControllerId = `${data.chatflow.id}_${data.chatId}`
const signal = new AbortController()
@@ -119,6 +119,21 @@ export class RedisEventPublisher implements IServerSideEventStreamer {
}
}
streamCalledToolsEvent(chatId: string, data: any) {
try {
this.redisPublisher.publish(
chatId,
JSON.stringify({
chatId,
eventType: 'calledTools',
data
})
)
} catch (error) {
console.error('Error streaming calledTools event:', error)
}
}
streamFileAnnotationsEvent(chatId: string, data: any) {
try {
this.redisPublisher.publish(
@@ -164,6 +179,36 @@ export class RedisEventPublisher implements IServerSideEventStreamer {
}
}
streamAgentFlowEvent(chatId: string, data: any): void {
try {
this.redisPublisher.publish(
chatId,
JSON.stringify({
chatId,
eventType: 'agentFlowEvent',
data
})
)
} catch (error) {
console.error('Error streaming agentFlow event:', error)
}
}
streamAgentFlowExecutedDataEvent(chatId: string, data: any): void {
try {
this.redisPublisher.publish(
chatId,
JSON.stringify({
chatId,
eventType: 'agentFlowExecutedData',
data
})
)
} catch (error) {
console.error('Error streaming agentFlowExecutedData event:', error)
}
}
streamNextAgentEvent(chatId: string, data: any): void {
try {
this.redisPublisher.publish(
@@ -179,6 +224,21 @@ export class RedisEventPublisher implements IServerSideEventStreamer {
}
}
streamNextAgentFlowEvent(chatId: string, data: any): void {
try {
this.redisPublisher.publish(
chatId,
JSON.stringify({
chatId,
eventType: 'nextAgentFlow',
data
})
)
} catch (error) {
console.error('Error streaming nextAgentFlow event:', error)
}
}
streamActionEvent(chatId: string, data: any): void {
try {
this.redisPublisher.publish(
@@ -254,6 +314,21 @@ export class RedisEventPublisher implements IServerSideEventStreamer {
}
}
streamUsageMetadataEvent(chatId: string, data: any): void {
try {
this.redisPublisher.publish(
chatId,
JSON.stringify({
chatId,
eventType: 'usageMetadata',
data
})
)
} catch (error) {
console.error('Error streaming usage metadata event:', error)
}
}
async disconnect() {
if (this.redisPublisher) {
await this.redisPublisher.quit()