Implementation:FlowiseAI Flowise InitNode
| Attribute | Value |
|---|---|
| Source Repository | FlowiseAI/Flowise |
| Source File | packages/ui/src/utils/genericHelper.js
|
| Domain | Chatflow_Creation |
| Workflow | Chatflow_Creation |
| Last Updated | 2026-02-12 |
Overview
Concrete utility function for initializing a ReactFlow node from a server-provided component definition. The initNode function transforms a raw NodeDefinition into a fully configured node data object with classified inputs, initialized outputs, default values, and visibility states. A companion function getUniqueNodeId generates collision-free node identifiers.
Code Reference
Source Location
- File:
packages/ui/src/utils/genericHelper.js - Lines: L118-227 (
initNode), L4-17 (getUniqueNodeId)
Signature
export const initNode = (nodeData, newNodeId, isAgentflow) => { ... }
Where:
nodeData:NodeDefinitionfrom server (withinputs[],outputs[],credential?,baseClasses[])newNodeId:string-- unique ID generated bygetUniqueNodeId()isAgentflow:boolean-- toggles output anchor format (agentflow vs standard)
Returns: Modified nodeData with id, inputAnchors[], inputParams[], inputs (object with defaults), outputAnchors[]
The companion ID generator:
export const getUniqueNodeId = (nodeData, nodes) => {
let suffix = 0
let baseId = `${nodeData.name}_${suffix}`
while (nodes.some((node) => node.id === baseId)) {
suffix += 1
baseId = `${nodeData.name}_${suffix}`
}
return baseId
}
Import
import { initNode, getUniqueNodeId } from '@/utils/genericHelper'
I/O Contract
Inputs
| Parameter | Type | Required | Description |
|---|---|---|---|
| nodeData | NodeDefinition |
Yes | Raw component definition from the server registry, containing inputs[], outputs[], credential?, baseClasses[], name, label, type
|
| newNodeId | string |
Yes | Unique node identifier generated by getUniqueNodeId()
|
| isAgentflow | boolean |
No | When true, output anchors use agentflow format (simple indexed IDs); when false or omitted, standard format with base class encoding is used
|
Outputs
| Field | Type | Description |
|---|---|---|
| id | string |
The assigned unique node ID |
| inputAnchors | InputDef[] |
Inputs classified as connection handles (non-whitelist types), each with a generated id and display flag
|
| inputParams | InputDef[] |
Inputs classified as form fields (whitelist types), each with a generated id and display flag. Credential input is prepended if present.
|
| inputs | object |
Key-value map of input names to their default values (or empty string) |
| outputAnchors | OutputAnchor[] |
Output anchors with IDs encoding base classes |
| outputs | object |
Key-value map of output names to their default values |
| credential | string |
Reset to empty string (credential ID is stored in inputs at runtime)
|
Implementation Details
Whitelist Types
The following input types are classified as form-configurable parameters (inputParams):
const whitelistTypes = [
'asyncOptions',
'asyncMultiOptions',
'options',
'multiOptions',
'array',
'datagrid',
'string',
'number',
'boolean',
'password',
'json',
'code',
'date',
'file',
'folder',
'tabs',
'conditionFunction'
]
Any input with a type not in this list becomes an inputAnchor (connection handle).
Input ID Format
Each input is assigned an ID following the pattern:
{nodeId}-input-{inputName}-{inputType}
For example: chatOpenAI_0-input-model-asyncOptions
Output Anchor Formats
Standard chatflow format (when isAgentflow is false):
If the definition has explicit outputs, they are wrapped in an options structure:
{
name: 'output',
label: 'Output',
type: 'options',
options: [
{
id: `${newNodeId}-output-${output.name}-${baseClasses}`,
name: output.name,
label: output.label,
type: baseClasses.join(' | ')
}
],
default: outputs[0].name
}
Agentflow format (when isAgentflow is true):
{
id: `${newNodeId}-output-${index}`,
label: nodeData.label,
name: nodeData.name
}
Usage Examples
Drag-and-drop node creation (from Canvas component)
import { getUniqueNodeId, initNode } from '@/utils/genericHelper'
const onDrop = (event) => {
let nodeData = JSON.parse(event.dataTransfer.getData('application/reactflow'))
const position = reactFlowInstance.project({
x: event.clientX - reactFlowBounds.left - 100,
y: event.clientY - reactFlowBounds.top - 50
})
const newNodeId = getUniqueNodeId(nodeData, reactFlowInstance.getNodes())
const newNode = {
id: newNodeId,
position,
type: nodeData.type !== 'StickyNote' ? 'customNode' : 'stickyNote',
data: initNode(nodeData, newNodeId)
}
setNodes((nds) => nds.concat(newNode))
}
Programmatic node initialization
import { getUniqueNodeId, initNode } from '@/utils/genericHelper'
// Given a node definition from the registry
const nodeDef = {
name: 'chatOpenAI',
label: 'ChatOpenAI',
type: 'ChatOpenAI',
baseClasses: ['BaseChatModel', 'BaseLanguageModel'],
inputs: [
{ name: 'model', type: 'asyncOptions', label: 'Model Name' },
{ name: 'temperature', type: 'number', label: 'Temperature', default: 0.9 },
{ name: 'cache', type: 'BaseCache', label: 'Cache' }
],
outputs: [],
credential: { name: 'credential', type: 'credential', label: 'OpenAI API Key' }
}
const existingNodes = []
const newNodeId = getUniqueNodeId(nodeDef, existingNodes) // "chatOpenAI_0"
const initialized = initNode(nodeDef, newNodeId, false)
// initialized.inputParams includes: credential selector, model (asyncOptions), temperature (number)
// initialized.inputAnchors includes: cache (BaseCache)
// initialized.inputs = { model: '', temperature: 0.9, cache: '' }