Allows CustomFunction to be set as an Ending Node

This commit is contained in:
YISH
2024-01-25 14:14:30 +08:00
parent 09d2b96231
commit 50cef64193
2 changed files with 33 additions and 16 deletions
@@ -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 }
+9 -5
View File
@@ -465,9 +465,13 @@ 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`)
const isEndingNode = endingNodeData?.outputs?.output === 'EndingNode'
if (!isEndingNode) {
if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') { if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
return res.status(500).send(`Ending node must be either a Chain or Agent`) return res.status(500).send(`Ending node must be either a Chain or Agent`)
} }
}
isStreaming = isFlowValidForStream(nodes, endingNodeData) isStreaming = isFlowValidForStream(nodes, endingNodeData)
} }
@@ -1665,21 +1669,21 @@ 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`)
const isEndingNode = endingNodeData?.outputs?.output === 'EndingNode'
if (!isEndingNode) {
if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') { if (endingNodeData && endingNodeData.category !== 'Chains' && endingNodeData.category !== 'Agents') {
return res.status(500).send(`Ending node must be either a Chain or Agent`) return res.status(500).send(`Ending node must be either a Chain or Agent`)
} }
if ( if (!Object.values(endingNodeData.outputs ?? {}).includes(endingNodeData.name)) {
endingNodeData.outputs &&
Object.keys(endingNodeData.outputs).length &&
!Object.values(endingNodeData.outputs).includes(endingNodeData.name)
) {
return res return res
.status(500) .status(500)
.send( .send(
`Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction` `Output of ${endingNodeData.label} (${endingNodeData.id}) must be ${endingNodeData.label}, can't be an Output Prediction`
) )
} }
}
isStreamValid = isFlowValidForStream(nodes, endingNodeData) isStreamValid = isFlowValidForStream(nodes, endingNodeData)
} }