Merge pull request #1591 from mokeyish/patch-2

Allows CustomFunction to be set as an Ending Node.
This commit is contained in:
Henry Heng
2024-01-26 12:15:40 +00:00
committed by GitHub
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 }
+19 -15
View File
@@ -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)