Feature/Full File Uploads & Message Delete API (#3314)

* add functionality for full file uploads, add remove messages from view dialog and API

* add attachments swagger

* update question to include uploadedFilesContent

* make config dialog modal lg size
This commit is contained in:
Henry Heng
2024-10-23 11:00:46 +01:00
committed by GitHub
parent 116d02d0bc
commit 53e504c32f
31 changed files with 1012 additions and 193 deletions
+28 -13
View File
@@ -19,7 +19,7 @@ import {
IReactFlowObject,
IReactFlowNode,
IDepthQueue,
chatType,
ChatType,
IChatMessage,
IChatFlow,
IReactFlowEdge
@@ -88,12 +88,14 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
}
let fileUploads: IFileUpload[] = []
let uploadedFilesContent = ''
if (incomingInput.uploads) {
fileUploads = incomingInput.uploads
for (let i = 0; i < fileUploads.length; i += 1) {
const upload = fileUploads[i]
if ((upload.type === 'file' || upload.type === 'audio') && upload.data) {
// if upload in an image, a rag file, or audio
if ((upload.type === 'file' || upload.type === 'file:rag' || upload.type === 'audio') && upload.data) {
const filename = upload.name
const splitDataURI = upload.data.split(',')
const bf = Buffer.from(splitDataURI.pop() || '', 'base64')
@@ -139,6 +141,13 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
}
}
}
if (upload.type === 'file:full' && upload.data) {
upload.type = 'stored-file:full'
// Omit upload.data since we don't store the content in database
uploadedFilesContent += `<doc name='${upload.name}'>${upload.data}</doc>\n\n`
fileUploads[i] = omit(upload, ['data'])
}
}
}
@@ -229,7 +238,8 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
edges,
baseURL,
appServer.sseStreamer,
true
true,
uploadedFilesContent
)
}
@@ -345,6 +355,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
apiMessageId,
componentNodes: appServer.nodesPool.componentNodes,
question: incomingInput.question,
uploadedFilesContent,
chatHistory,
chatId,
sessionId: sessionId ?? '',
@@ -384,7 +395,8 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
reactFlowNodes,
incomingInput.question,
chatHistory,
flowData
flowData,
uploadedFilesContent
)
nodeToExecuteData = reactFlowNodeData
@@ -398,6 +410,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
const nodeInstance = new nodeModule.nodeClass({ sessionId })
isStreamValid = (req.body.streaming === 'true' || req.body.streaming === true) && isStreamValid
const finalQuestion = uploadedFilesContent ? `${uploadedFilesContent}\n\n${incomingInput.question}` : incomingInput.question
const runParams = {
chatId,
@@ -411,7 +424,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
prependMessages
}
let result = await nodeInstance.run(nodeToExecuteData, incomingInput.question, {
let result = await nodeInstance.run(nodeToExecuteData, finalQuestion, {
...runParams,
...(isStreamValid && { sseStreamer: appServer.sseStreamer, shouldStreamResponse: true })
})
@@ -427,7 +440,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
role: 'userMessage',
content: incomingInput.question,
chatflowid,
chatType: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
chatType: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
chatId,
memoryType,
sessionId,
@@ -447,7 +460,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
role: 'apiMessage',
content: resultText,
chatflowid,
chatType: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
chatType: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
chatId,
memoryType,
sessionId
@@ -476,7 +489,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
version: await getAppVersion(),
chatflowId: chatflowid,
chatId,
type: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
type: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
flowGraph: getTelemetryFlowObj(nodes, edges)
})
@@ -517,7 +530,8 @@ const utilBuildAgentResponse = async (
edges: IReactFlowEdge[],
baseURL?: string,
sseStreamer?: IServerSideEventStreamer,
shouldStreamResponse?: boolean
shouldStreamResponse?: boolean,
uploadedFilesContent?: string
) => {
try {
const appServer = getRunningExpressApp()
@@ -530,7 +544,8 @@ const utilBuildAgentResponse = async (
isInternal,
baseURL,
sseStreamer,
shouldStreamResponse
shouldStreamResponse,
uploadedFilesContent
)
if (streamResults) {
const { finalResult, finalAction, sourceDocuments, artifacts, usedTools, agentReasoning } = streamResults
@@ -538,7 +553,7 @@ const utilBuildAgentResponse = async (
role: 'userMessage',
content: incomingInput.question,
chatflowid: agentflow.id,
chatType: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
chatType: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
chatId,
memoryType,
sessionId,
@@ -553,7 +568,7 @@ const utilBuildAgentResponse = async (
role: 'apiMessage',
content: finalResult,
chatflowid: agentflow.id,
chatType: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
chatType: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
chatId,
memoryType,
sessionId
@@ -581,7 +596,7 @@ const utilBuildAgentResponse = async (
version: await getAppVersion(),
agentflowId: agentflow.id,
chatId,
type: isInternal ? chatType.INTERNAL : chatType.EXTERNAL,
type: isInternal ? ChatType.INTERNAL : ChatType.EXTERNAL,
flowGraph: getTelemetryFlowObj(nodes, edges)
})