mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 23:01:09 +03:00
Merge pull request #1591 from mokeyish/patch-2
Allows CustomFunction to be set as an Ending Node.
This commit is contained in:
@@ -52,11 +52,19 @@ class CustomFunction_Utilities implements INode {
|
|||||||
label: 'Output',
|
label: 'Output',
|
||||||
name: 'output',
|
name: 'output',
|
||||||
baseClasses: ['string', 'number', 'boolean', 'json', 'array']
|
baseClasses: ['string', 'number', 'boolean', 'json', 'array']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Ending Node',
|
||||||
|
name: 'EndingNode',
|
||||||
|
baseClasses: [this.type]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData, input: string, options: ICommonObject): Promise<any> {
|
async init(nodeData: INodeData, input: string, options: ICommonObject): Promise<any> {
|
||||||
|
const isEndingNode = nodeData?.outputs?.output === 'EndingNode'
|
||||||
|
if (isEndingNode && !options.isRun) return // prevent running both init and run twice
|
||||||
|
|
||||||
const javascriptFunction = nodeData.inputs?.javascriptFunction as string
|
const javascriptFunction = nodeData.inputs?.javascriptFunction as string
|
||||||
const functionInputVariablesRaw = nodeData.inputs?.functionInputVariables
|
const functionInputVariablesRaw = nodeData.inputs?.functionInputVariables
|
||||||
const appDataSource = options.appDataSource as DataSource
|
const appDataSource = options.appDataSource as DataSource
|
||||||
@@ -123,7 +131,8 @@ class CustomFunction_Utilities implements INode {
|
|||||||
const vm = new NodeVM(nodeVMOptions)
|
const vm = new NodeVM(nodeVMOptions)
|
||||||
try {
|
try {
|
||||||
const response = await vm.run(`module.exports = async function() {${javascriptFunction}}()`, __dirname)
|
const response = await vm.run(`module.exports = async function() {${javascriptFunction}}()`, __dirname)
|
||||||
if (typeof response === 'string') {
|
|
||||||
|
if (typeof response === 'string' && !isEndingNode) {
|
||||||
return handleEscapeCharacters(response, false)
|
return handleEscapeCharacters(response, false)
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
@@ -131,6 +140,10 @@ class CustomFunction_Utilities implements INode {
|
|||||||
throw new Error(e)
|
throw new Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
|
||||||
|
return await this.init(nodeData, input, { ...options, isRun: true })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { nodeClass: CustomFunction_Utilities }
|
module.exports = { nodeClass: CustomFunction_Utilities }
|
||||||
|
|||||||
@@ -465,8 +465,12 @@ export class App {
|
|||||||
const endingNodeData = endingNode.data
|
const endingNodeData = endingNode.data
|
||||||
if (!endingNodeData) return res.status(500).send(`Ending node ${endingNode.id} data not found`)
|
if (!endingNodeData) return res.status(500).send(`Ending node ${endingNode.id} data not found`)
|
||||||
|
|
||||||
if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
|
const isEndingNode = endingNodeData?.outputs?.output === 'EndingNode'
|
||||||
return res.status(500).send(`Ending node must be either a Chain or Agent`)
|
|
||||||
|
if (!isEndingNode) {
|
||||||
|
if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
|
||||||
|
return res.status(500).send(`Ending node must be either a Chain or Agent`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isStreaming = isFlowValidForStream(nodes, endingNodeData)
|
isStreaming = isFlowValidForStream(nodes, endingNodeData)
|
||||||
@@ -1665,20 +1669,20 @@ export class App {
|
|||||||
const endingNodeData = endingNode.data
|
const endingNodeData = endingNode.data
|
||||||
if (!endingNodeData) return res.status(500).send(`Ending node ${endingNode.id} data not found`)
|
if (!endingNodeData) return res.status(500).send(`Ending node ${endingNode.id} data not found`)
|
||||||
|
|
||||||
if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
|
const isEndingNode = endingNodeData?.outputs?.output === 'EndingNode'
|
||||||
return res.status(500).send(`Ending node must be either a Chain or Agent`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (!isEndingNode) {
|
||||||
endingNodeData.outputs &&
|
if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
|
||||||
Object.keys(endingNodeData.outputs).length &&
|
return res.status(500).send(`Ending node must be either a Chain or Agent`)
|
||||||
!Object.values(endingNodeData.outputs).includes(endingNodeData.name)
|
}
|
||||||
) {
|
|
||||||
return res
|
if (!Object.values(endingNodeData.outputs ?? {}).includes(endingNodeData.name)) {
|
||||||
.status(500)
|
return res
|
||||||
.send(
|
.status(500)
|
||||||
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
|
.send(
|
||||||
)
|
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isStreamValid = isFlowValidForStream(nodes, endingNodeData)
|
isStreamValid = isFlowValidForStream(nodes, endingNodeData)
|
||||||
|
|||||||
Reference in New Issue
Block a user