Spaces:
Configuration error
Configuration error
| import moment from 'moment' | |
| export const getUniqueNodeId = (nodeData, nodes) => { | |
| // Get amount of same nodes | |
| let totalSameNodes = 0 | |
| for (let i = 0; i < nodes.length; i += 1) { | |
| const node = nodes[i] | |
| if (node.data.name === nodeData.name) { | |
| totalSameNodes += 1 | |
| } | |
| } | |
| // Get unique id | |
| let nodeId = `${nodeData.name}_${totalSameNodes}` | |
| for (let i = 0; i < nodes.length; i += 1) { | |
| const node = nodes[i] | |
| if (node.id === nodeId) { | |
| totalSameNodes += 1 | |
| nodeId = `${nodeData.name}_${totalSameNodes}` | |
| } | |
| } | |
| return nodeId | |
| } | |
| export const initializeDefaultNodeData = (nodeParams) => { | |
| const initialValues = {} | |
| for (let i = 0; i < nodeParams.length; i += 1) { | |
| const input = nodeParams[i] | |
| initialValues[input.name] = input.default || '' | |
| } | |
| return initialValues | |
| } | |
| export const initNode = (nodeData, newNodeId) => { | |
| const inputAnchors = [] | |
| const inputParams = [] | |
| const incoming = nodeData.inputs ? nodeData.inputs.length : 0 | |
| const outgoing = 1 | |
| const whitelistTypes = ['options', 'string', 'number', 'boolean', 'password', 'json', 'code', 'date', 'file', 'folder'] | |
| for (let i = 0; i < incoming; i += 1) { | |
| const newInput = { | |
| ...nodeData.inputs[i], | |
| id: `${newNodeId}-input-${nodeData.inputs[i].name}-${nodeData.inputs[i].type}` | |
| } | |
| if (whitelistTypes.includes(nodeData.inputs[i].type)) { | |
| inputParams.push(newInput) | |
| } else { | |
| inputAnchors.push(newInput) | |
| } | |
| } | |
| const outputAnchors = [] | |
| for (let i = 0; i < outgoing; i += 1) { | |
| if (nodeData.outputs && nodeData.outputs.length) { | |
| const options = [] | |
| for (let j = 0; j < nodeData.outputs.length; j += 1) { | |
| let baseClasses = '' | |
| let type = '' | |
| const outputBaseClasses = nodeData.outputs[j].baseClasses ?? [] | |
| if (outputBaseClasses.length > 1) { | |
| baseClasses = outputBaseClasses.join('|') | |
| type = outputBaseClasses.join(' | ') | |
| } else if (outputBaseClasses.length === 1) { | |
| baseClasses = outputBaseClasses[0] | |
| type = outputBaseClasses[0] | |
| } | |
| const newOutputOption = { | |
| id: `${newNodeId}-output-${nodeData.outputs[j].name}-${baseClasses}`, | |
| name: nodeData.outputs[j].name, | |
| label: nodeData.outputs[j].label, | |
| type | |
| } | |
| options.push(newOutputOption) | |
| } | |
| const newOutput = { | |
| name: 'output', | |
| label: 'Output', | |
| type: 'options', | |
| options, | |
| default: nodeData.outputs[0].name | |
| } | |
| outputAnchors.push(newOutput) | |
| } else { | |
| const newOutput = { | |
| id: `${newNodeId}-output-${nodeData.name}-${nodeData.baseClasses.join('|')}`, | |
| name: nodeData.name, | |
| label: nodeData.type, | |
| type: nodeData.baseClasses.join(' | ') | |
| } | |
| outputAnchors.push(newOutput) | |
| } | |
| } | |
| /* Initial | |
| inputs = [ | |
| { | |
| label: 'field_label_1', | |
| name: 'string' | |
| }, | |
| { | |
| label: 'field_label_2', | |
| name: 'CustomType' | |
| } | |
| ] | |
| => Convert to inputs, inputParams, inputAnchors | |
| => inputs = { 'field': 'defaultvalue' } // Turn into inputs object with default values | |
| => // For inputs that are part of whitelistTypes | |
| inputParams = [ | |
| { | |
| label: 'field_label_1', | |
| name: 'string' | |
| } | |
| ] | |
| => // For inputs that are not part of whitelistTypes | |
| inputAnchors = [ | |
| { | |
| label: 'field_label_2', | |
| name: 'CustomType' | |
| } | |
| ] | |
| */ | |
| if (nodeData.inputs) { | |
| nodeData.inputAnchors = inputAnchors | |
| nodeData.inputParams = inputParams | |
| nodeData.inputs = initializeDefaultNodeData(nodeData.inputs) | |
| } else { | |
| nodeData.inputAnchors = [] | |
| nodeData.inputParams = [] | |
| nodeData.inputs = {} | |
| } | |
| if (nodeData.outputs) { | |
| nodeData.outputs = initializeDefaultNodeData(outputAnchors) | |
| } else { | |
| nodeData.outputs = {} | |
| } | |
| nodeData.outputAnchors = outputAnchors | |
| nodeData.id = newNodeId | |
| return nodeData | |
| } | |
| export const getEdgeLabelName = (source) => { | |
| const sourceSplit = source.split('-') | |
| if (sourceSplit.length && sourceSplit[0].includes('ifElse')) { | |
| const outputAnchorsIndex = sourceSplit[sourceSplit.length - 1] | |
| return outputAnchorsIndex === '0' ? 'true' : 'false' | |
| } | |
| return '' | |
| } | |
| export const isValidConnection = (connection, reactFlowInstance) => { | |
| const sourceHandle = connection.sourceHandle | |
| const targetHandle = connection.targetHandle | |
| const target = connection.target | |
| //sourceHandle: "llmChain_0-output-llmChain-BaseChain" | |
| //targetHandle: "mrlkAgentLLM_0-input-model-BaseLanguageModel" | |
| const sourceTypes = sourceHandle.split('-')[sourceHandle.split('-').length - 1].split('|') | |
| const targetTypes = targetHandle.split('-')[targetHandle.split('-').length - 1].split('|') | |
| if (targetTypes.some((t) => sourceTypes.includes(t))) { | |
| let targetNode = reactFlowInstance.getNode(target) | |
| if (!targetNode) { | |
| if (!reactFlowInstance.getEdges().find((e) => e.targetHandle === targetHandle)) { | |
| return true | |
| } | |
| } else { | |
| const targetNodeInputAnchor = | |
| targetNode.data.inputAnchors.find((ancr) => ancr.id === targetHandle) || | |
| targetNode.data.inputParams.find((ancr) => ancr.id === targetHandle) | |
| if ( | |
| (targetNodeInputAnchor && | |
| !targetNodeInputAnchor?.list && | |
| !reactFlowInstance.getEdges().find((e) => e.targetHandle === targetHandle)) || | |
| targetNodeInputAnchor?.list | |
| ) { | |
| return true | |
| } | |
| } | |
| } | |
| return false | |
| } | |
| export const convertDateStringToDateObject = (dateString) => { | |
| if (dateString === undefined || !dateString) return undefined | |
| const date = moment(dateString) | |
| if (!date.isValid) return undefined | |
| // Sat Sep 24 2022 07:30:14 | |
| return new Date(date.year(), date.month(), date.date(), date.hours(), date.minutes()) | |
| } | |
| export const getFileName = (fileBase64) => { | |
| let fileNames = [] | |
| if (fileBase64.startsWith('[') && fileBase64.endsWith(']')) { | |
| const files = JSON.parse(fileBase64) | |
| for (const file of files) { | |
| const splitDataURI = file.split(',') | |
| const filename = splitDataURI[splitDataURI.length - 1].split(':')[1] | |
| fileNames.push(filename) | |
| } | |
| return fileNames.join(', ') | |
| } else { | |
| const splitDataURI = fileBase64.split(',') | |
| const filename = splitDataURI[splitDataURI.length - 1].split(':')[1] | |
| return filename | |
| } | |
| } | |
| export const getFolderName = (base64ArrayStr) => { | |
| try { | |
| const base64Array = JSON.parse(base64ArrayStr) | |
| const filenames = [] | |
| for (let i = 0; i < base64Array.length; i += 1) { | |
| const fileBase64 = base64Array[i] | |
| const splitDataURI = fileBase64.split(',') | |
| const filename = splitDataURI[splitDataURI.length - 1].split(':')[1] | |
| filenames.push(filename) | |
| } | |
| return filenames.length ? filenames.join(',') : '' | |
| } catch (e) { | |
| return '' | |
| } | |
| } | |
| export const generateExportFlowData = (flowData) => { | |
| const nodes = flowData.nodes | |
| const edges = flowData.edges | |
| for (let i = 0; i < nodes.length; i += 1) { | |
| nodes[i].selected = false | |
| const node = nodes[i] | |
| const newNodeData = { | |
| id: node.data.id, | |
| label: node.data.label, | |
| name: node.data.name, | |
| type: node.data.type, | |
| baseClasses: node.data.baseClasses, | |
| category: node.data.category, | |
| description: node.data.description, | |
| inputParams: node.data.inputParams, | |
| inputAnchors: node.data.inputAnchors, | |
| inputs: {}, | |
| outputAnchors: node.data.outputAnchors, | |
| outputs: node.data.outputs, | |
| selected: false | |
| } | |
| // Remove password, file & folder | |
| if (node.data.inputs && Object.keys(node.data.inputs).length) { | |
| const nodeDataInputs = {} | |
| for (const input in node.data.inputs) { | |
| const inputParam = node.data.inputParams.find((inp) => inp.name === input) | |
| if (inputParam && inputParam.type === 'password') continue | |
| if (inputParam && inputParam.type === 'file') continue | |
| if (inputParam && inputParam.type === 'folder') continue | |
| nodeDataInputs[input] = node.data.inputs[input] | |
| } | |
| newNodeData.inputs = nodeDataInputs | |
| } | |
| nodes[i].data = newNodeData | |
| } | |
| const exportJson = { | |
| nodes, | |
| edges | |
| } | |
| return exportJson | |
| } | |
| export const getAvailableNodesForVariable = (nodes, edges, target, targetHandle) => { | |
| // example edge id = "llmChain_0-llmChain_0-output-outputPrediction-string-llmChain_1-llmChain_1-input-promptValues-string" | |
| // {source} -{sourceHandle} -{target} -{targetHandle} | |
| const parentNodes = [] | |
| const inputEdges = edges.filter((edg) => edg.target === target && edg.targetHandle === targetHandle) | |
| if (inputEdges && inputEdges.length) { | |
| for (let j = 0; j < inputEdges.length; j += 1) { | |
| const node = nodes.find((nd) => nd.id === inputEdges[j].source) | |
| parentNodes.push(node) | |
| } | |
| } | |
| return parentNodes | |
| } | |
| export const rearrangeToolsOrdering = (newValues, sourceNodeId) => { | |
| // RequestsGet and RequestsPost have to be in order before other tools | |
| newValues.push(`{{${sourceNodeId}.data.instance}}`) | |
| const sortKey = (item) => { | |
| if (item.includes('requestsGet') || item.includes('readFile')) { | |
| return 0 | |
| } else if (item.includes('requestsPost') || item.includes('writeFile')) { | |
| return 1 | |
| } else { | |
| return 2 | |
| } | |
| } | |
| newValues.sort((a, b) => sortKey(a) - sortKey(b)) | |
| } | |