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:
Henry Heng
2024-07-22 17:46:14 +01:00
committed by GitHub
parent 34d0e4302c
commit bca4de0c63
152 changed files with 55307 additions and 35236 deletions
+56 -30
View File
@@ -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
}