New Feature: Add post postprocessing of response from LLM using custom JS Function (#4079)

* New Feature: Add post postprocessing of response from LLM using custom Javascript functions

* Disable Save when there is no content

* add post processing ui changes, disable streaming

---------

Co-authored-by: Henry <hzj94@hotmail.com>
This commit is contained in:
Vinod Kiran
2025-02-26 23:10:03 +05:30
committed by GitHub
parent a8d74336dd
commit 9a92aa12f9
6 changed files with 297 additions and 7 deletions
@@ -1,4 +1,4 @@
import { removeFolderFromStorage } from 'flowise-components'
import { ICommonObject, removeFolderFromStorage } from 'flowise-components'
import { StatusCodes } from 'http-status-codes'
import { ChatflowType, IReactFlowObject } from '../../Interface'
import { ChatFlow } from '../../database/entities/ChatFlow'
@@ -28,6 +28,15 @@ const checkIfChatflowIsValidForStreaming = async (chatflowId: string): Promise<a
throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Chatflow ${chatflowId} not found`)
}
/* Check for post-processing settings, if available isStreamValid is always false */
let chatflowConfig: ICommonObject = {}
if (chatflow.chatbotConfig) {
chatflowConfig = JSON.parse(chatflow.chatbotConfig)
if (chatflowConfig?.postProcessing?.enabled === true) {
return { isStreaming: false }
}
}
/*** Get Ending Node with Directed Graph ***/
const flowData = chatflow.flowData
const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
+44 -3
View File
@@ -579,7 +579,19 @@ export const executeFlow = async ({
}
return undefined
} else {
const isStreamValid = await checkIfStreamValid(endingNodes, nodes, streaming)
let chatflowConfig: ICommonObject = {}
if (chatflow.chatbotConfig) {
chatflowConfig = JSON.parse(chatflow.chatbotConfig)
}
let isStreamValid = false
/* Check for post-processing settings, if available isStreamValid is always false */
if (chatflowConfig?.postProcessing?.enabled === true) {
isStreamValid = false
} else {
isStreamValid = await checkIfStreamValid(endingNodes, nodes, streaming)
}
/*** Find the last node to execute ***/
const { endingNodeData, endingNodeInstance } = await initEndingNode({
@@ -637,8 +649,37 @@ export const executeFlow = async ({
await utilAddChatMessage(userMessage, appDataSource)
let resultText = ''
if (result.text) resultText = result.text
else if (result.json) resultText = '```json\n' + JSON.stringify(result.json, null, 2)
if (result.text) {
resultText = result.text
/* Check for post-processing settings */
if (chatflowConfig?.postProcessing?.enabled === true) {
try {
const postProcessingFunction = JSON.parse(chatflowConfig?.postProcessing?.customFunction)
const nodeInstanceFilePath = componentNodes['customFunction'].filePath as string
const nodeModule = await import(nodeInstanceFilePath)
const nodeData = {
inputs: { javascriptFunction: postProcessingFunction },
outputs: { output: 'output' }
}
const options: ICommonObject = {
chatflowid: chatflow.id,
sessionId,
chatId,
input: question,
rawOutput: resultText,
appDataSource,
databaseEntities,
logger
}
const customFuncNodeInstance = new nodeModule.nodeClass()
let moderatedResponse = await customFuncNodeInstance.init(nodeData, question, options)
result.text = moderatedResponse
resultText = result.text
} catch (e) {
logger.log('[server]: Post Processing Error:', e)
}
}
} else if (result.json) resultText = '```json\n' + JSON.stringify(result.json, null, 2)
else resultText = JSON.stringify(result, null, 2)
const apiMessage: Omit<IChatMessage, 'createdDate'> = {