mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 19:00:59 +03:00
Feature/seq agents (#2798)
* update build functions * sequential agents * update langchain to 0.2, added sequential agent nodes * add marketplace templates * update howto wordings * Merge branch 'main' into feature/Seq-Agents # Conflicts: # pnpm-lock.yaml * update deprecated functions and add new sequential nodes * add marketplace templates * update marketplace templates, add structured output to llm node * add multi agents template * update llm node with bindmodels * update cypress version * update templates sticky note wordings * update tool node to include human in loop action * update structured outputs error from models * update cohere package to resolve google genai pipeThrough bug * update mistral package version, added message reconstruction before invoke seq agent * add HITL to agent * update state messages restructuring * update load and split methods for s3 directory
This commit is contained in:
@@ -43,6 +43,8 @@ import logger from './logger'
|
||||
import { utilAddChatMessage } from './addChatMesage'
|
||||
import { buildAgentGraph } from './buildAgentGraph'
|
||||
import { getErrorMessage } from '../errors/utils'
|
||||
import { ChatMessage } from '../database/entities/ChatMessage'
|
||||
import { IAction } from 'flowise-components'
|
||||
|
||||
/**
|
||||
* Build Chatflow
|
||||
@@ -174,7 +176,7 @@ export const utilBuildChatflow = async (req: Request, socketIO?: Server, isInter
|
||||
const endingNodes = getEndingNodes(nodeDependencies, directedGraph, nodes)
|
||||
|
||||
/*** If the graph is an agent graph, build the agent response ***/
|
||||
if (endingNodes.filter((node) => node.data.category === 'Multi Agents').length) {
|
||||
if (endingNodes.filter((node) => node.data.category === 'Multi Agents' || node.data.category === 'Sequential Agents').length) {
|
||||
return await utilBuildAgentResponse(
|
||||
chatflow,
|
||||
isInternal,
|
||||
@@ -292,28 +294,27 @@ export const utilBuildChatflow = async (req: Request, socketIO?: Server, isInter
|
||||
|
||||
logger.debug(`[server]: Start building chatflow ${chatflowid}`)
|
||||
/*** BFS to traverse from Starting Nodes to Ending Node ***/
|
||||
const reactFlowNodes = await buildFlow(
|
||||
const reactFlowNodes = await buildFlow({
|
||||
startingNodeIds,
|
||||
nodes,
|
||||
edges,
|
||||
reactFlowNodes: nodes,
|
||||
reactFlowEdges: edges,
|
||||
graph,
|
||||
depthQueue,
|
||||
appServer.nodesPool.componentNodes,
|
||||
incomingInput.question,
|
||||
componentNodes: appServer.nodesPool.componentNodes,
|
||||
question: incomingInput.question,
|
||||
chatHistory,
|
||||
chatId,
|
||||
sessionId ?? '',
|
||||
sessionId: sessionId ?? '',
|
||||
chatflowid,
|
||||
appServer.AppDataSource,
|
||||
incomingInput?.overrideConfig,
|
||||
appServer.cachePool,
|
||||
false,
|
||||
undefined,
|
||||
incomingInput.uploads,
|
||||
appDataSource: appServer.AppDataSource,
|
||||
overrideConfig: incomingInput?.overrideConfig,
|
||||
cachePool: appServer.cachePool,
|
||||
isUpsert: false,
|
||||
uploads: incomingInput.uploads,
|
||||
baseURL,
|
||||
socketIO,
|
||||
incomingInput.socketIOClientId
|
||||
)
|
||||
socketIOClientId: incomingInput.socketIOClientId
|
||||
})
|
||||
|
||||
const nodeToExecute =
|
||||
endingNodeIds.length === 1
|
||||
@@ -432,14 +433,14 @@ export const utilBuildChatflow = async (req: Request, socketIO?: Server, isInter
|
||||
}
|
||||
|
||||
const utilBuildAgentResponse = async (
|
||||
chatflow: IChatFlow,
|
||||
agentflow: IChatFlow,
|
||||
isInternal: boolean,
|
||||
chatId: string,
|
||||
memoryType: string,
|
||||
sessionId: string,
|
||||
userMessageDateTime: Date,
|
||||
fileUploads: IFileUpload[],
|
||||
incomingInput: ICommonObject,
|
||||
incomingInput: IncomingInput,
|
||||
nodes: IReactFlowNode[],
|
||||
edges: IReactFlowEdge[],
|
||||
socketIO?: Server,
|
||||
@@ -447,13 +448,13 @@ const utilBuildAgentResponse = async (
|
||||
) => {
|
||||
try {
|
||||
const appServer = getRunningExpressApp()
|
||||
const streamResults = await buildAgentGraph(chatflow, chatId, sessionId, incomingInput, baseURL, socketIO)
|
||||
const streamResults = await buildAgentGraph(agentflow, chatId, sessionId, incomingInput, isInternal, baseURL, socketIO)
|
||||
if (streamResults) {
|
||||
const { finalResult, agentReasoning } = streamResults
|
||||
const { finalResult, finalAction, sourceDocuments, usedTools, agentReasoning } = streamResults
|
||||
const userMessage: Omit<IChatMessage, 'id'> = {
|
||||
role: 'userMessage',
|
||||
content: incomingInput.question,
|
||||
chatflowid: chatflow.id,
|
||||
chatflowid: agentflow.id,
|
||||
chatType: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
|
||||
chatId,
|
||||
memoryType,
|
||||
@@ -467,23 +468,54 @@ const utilBuildAgentResponse = async (
|
||||
const apiMessage: Omit<IChatMessage, 'id' | 'createdDate'> = {
|
||||
role: 'apiMessage',
|
||||
content: finalResult,
|
||||
chatflowid: chatflow.id,
|
||||
chatflowid: agentflow.id,
|
||||
chatType: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
|
||||
chatId,
|
||||
memoryType,
|
||||
sessionId
|
||||
}
|
||||
if (sourceDocuments.length) apiMessage.sourceDocuments = JSON.stringify(sourceDocuments)
|
||||
if (usedTools.length) apiMessage.usedTools = JSON.stringify(usedTools)
|
||||
if (agentReasoning.length) apiMessage.agentReasoning = JSON.stringify(agentReasoning)
|
||||
if (Object.keys(finalAction).length) apiMessage.action = JSON.stringify(finalAction)
|
||||
const chatMessage = await utilAddChatMessage(apiMessage)
|
||||
|
||||
await appServer.telemetry.sendTelemetry('prediction_sent', {
|
||||
await appServer.telemetry.sendTelemetry('agentflow_prediction_sent', {
|
||||
version: await getAppVersion(),
|
||||
chatlowId: chatflow.id,
|
||||
agentflowId: agentflow.id,
|
||||
chatId,
|
||||
type: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
|
||||
flowGraph: getTelemetryFlowObj(nodes, edges)
|
||||
})
|
||||
|
||||
// Find the previous chat message with the same action id and remove the action
|
||||
if (incomingInput.action && Object.keys(incomingInput.action).length) {
|
||||
let query = await appServer.AppDataSource.getRepository(ChatMessage)
|
||||
.createQueryBuilder('chat_message')
|
||||
.where('chat_message.chatId = :chatId', { chatId })
|
||||
.orWhere('chat_message.sessionId = :sessionId', { sessionId })
|
||||
.orderBy('chat_message.createdDate', 'DESC')
|
||||
.getMany()
|
||||
|
||||
for (const result of query) {
|
||||
if (result.action) {
|
||||
try {
|
||||
const action: IAction = JSON.parse(result.action)
|
||||
if (action.id === incomingInput.action.id) {
|
||||
const newChatMessage = new ChatMessage()
|
||||
Object.assign(newChatMessage, result)
|
||||
newChatMessage.action = null
|
||||
const cm = await appServer.AppDataSource.getRepository(ChatMessage).create(newChatMessage)
|
||||
await appServer.AppDataSource.getRepository(ChatMessage).save(cm)
|
||||
break
|
||||
}
|
||||
} catch (e) {
|
||||
// error converting action to JSON
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare response
|
||||
let result: ICommonObject = {}
|
||||
result.text = finalResult
|
||||
@@ -493,13 +525,7 @@ const utilBuildAgentResponse = async (
|
||||
if (sessionId) result.sessionId = sessionId
|
||||
if (memoryType) result.memoryType = memoryType
|
||||
if (agentReasoning.length) result.agentReasoning = agentReasoning
|
||||
|
||||
await appServer.telemetry.sendTelemetry('graph_compiled', {
|
||||
version: await getAppVersion(),
|
||||
graphId: chatflow.id,
|
||||
type: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
|
||||
flowGraph: getTelemetryFlowObj(nodes, edges)
|
||||
})
|
||||
if (Object.keys(finalAction).length) result.action = finalAction
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user