ClouisleClouisle

Workflow Node Reference

Reference for all workflow node types, configuration fields, I/O specifications, SSRF protections, and validation rules

The Clouisle workflow engine supports native complex objects, streaming inference, conditional routing, and loop/iteration containers. Workflow definitions use schema_version: 2, where graph structures consist of nodes and edges (built on React Flow).

Node Categories & Catalog

The current canvas picker offers 19 addable node types (normalCategories: 2 model + 6 logic + 6 transform + 5 extension). Inside an iteration/loop container the picker switches to a container-only catalog (swapping iteration_exit/loop_exit in for iteration/loop/pause). The backend executor registry additionally holds 25 executable node types, including internal entry nodes such as user_input, trigger, iteration_start, and loop_start. The canvas also retains frontend aliases or visual markers such as start, iteration_exit, loop_exit, and comment; not all map to independent executors. The table lists regular nodes, runtime nodes, and visual helper markers together:

CategoryType Identifier (type)LabelPrimary Purpose
ModelllmLLMInvoke large language models for text generation and reasoning
media_generationMedia GenerationCall team-authorized image or video generation models
LogicconditionCondition BranchMulti-branch IF/ELSE routing logic
question_classifierQuestion ClassifierClassify user intent dynamically using LLMs
decisionDecisionAsk a decision model a typed question and branch on the answer
iterationIteration ContainerIterate over array variables sequentially
loopLoop ContainerExecute child nodes repeatedly until conditions are met or maximum count is reached
pausePauseSuspend workflow execution pending human approval or variable inputs
TransformcodeCode ExecutionExecute Python or JavaScript snippets in a secure sandbox
templateTemplate TransformFormat and assemble text using Jinja2 templates
file_to_urlFile to URLConvert temporary file/image variables to persistent access URLs
variable_aggregatorVariable AggregatorAggregate dispersed variables into an object, array, or concatenated text
variable_assignmentVariable AssignmentAssign or update conversation context variables
parameter_extractorParameter ExtractorExtract structured arguments via LLM, Regex, or JSON Path
Extensionsub_workflowSub-workflowInvoke other published workflows within the workspace
agentAgentCall a published Agent for autonomous goal execution
toolToolInvoke built-in tools, custom HTTP tools, or MCP services
knowledge_retrievalKnowledge RetrievalSearch a bound knowledge base and retrieve chunk contexts
answerOutputAssemble final results and support streaming output to clients
Executor-level (not in the canvas picker)http_requestHTTP RequestPerform external HTTP/HTTPS API calls (restricted by SSRF policies)
document_extractorDocument ExtractorExtract plain text or Markdown from uploaded PDF/DOCX files
Entry & Lifecycleuser_inputStartDefine human-initiated input parameters and system variables (frontend canvas alias start)
triggerTriggerWebhook, scheduled cron, or event-driven entry points
iteration_start / loop_startContainer StartInternal virtual entry executor node passing parent container context
iteration_exit / loop_exitContainer ExitInternal visual exit marker on the canvas (no backend executor; child nodes are orchestrated by parentId)
commentCommentStatic canvas sticker, ignored during runtime execution

Picker nodes vs executors

http_request and document_extractor have independent backend executors (callable by the API or by imported packages) but do not appear in the canvas picker, so they cannot be dragged in from the UI. Conversely, iteration_exit/loop_exit are only container exit markers on the canvas with no dedicated executor; the container schedules child nodes by parentId at runtime.


Detailed Node Configuration Reference

1. LLM Node (llm)

Configuration container: node.data.llmConfig or node.data.config.

FieldTypeDefaultDescription & Constraints
modelIdUUID stringRequiredTeam-authorized chat model ID (team_models.id)
systemPromptstring""System prompt supporting {{node.var}} template variables
userPromptstring""User prompt supporting template variable interpolation
temperaturefloat0.7Sampling temperature passed to the model
maxTokensint2048Maximum generated token count passed to the model
topPfloat1.0Nucleus sampling threshold passed to the model
streamingboolfalseEnable token streaming; downstream Output nodes can relay streams directly
responseFormatstring"text"Output format: "text", "json" (json_object), or "json_schema"
jsonSchemastring (JSON)nullStrict JSON schema definition required when format is json_schema
inputsarray[]Parameter mapping list bound to this node

Outputs:

  • response (string): Generated response text (a lazy streaming proxy when streaming is true)
  • reasoning (string): Chain-of-thought reasoning process (e.g., DeepSeek R1 reasoning trace)
  • usage (object): Token metrics including prompt_tokens, completion_tokens, and total_tokens

2. Decision Node (decision)

The Decision node hands one state to a decision model (model_type: decision, currently TypeSafe AI) and picks a branch from the returned typed answer. Unlike the LLM node, a decision model generates no prose — it returns only a typed answer plus a probability distribution, and the node maps that answer onto output handles.

Configuration container: node.data.decisionConfig (with node.data.config retained for legacy definitions).

FieldTypeDefaultDescription & Constraints
modelIdUUID stringRequiredTeam-authorized decision model ID; the picker lists only enabled models with model_type: decision
stateTemplatestringRequired (legacy alias inputVariable)State handed to the model; supports {{variables}} and must resolve to a string
questionIdstring"decision"Question key used to read the answer back from the response (answers[questionId])
questionTypestring"choice"Question type: choice, score, or noul (yes/no probability)
instructionsstringRequiredThe judgement you ask the model to make
optionsstring[]Frontend default ["yes","no"]choice: 1–255 unique non-empty options; score: 2–10 unique non-empty ordered levels
defaultHandlestring"default"Branch handle taken when confidence is below the threshold or the answer cannot be resolved
confidenceThresholdnumberUnsetOptional, 0–1 (frontend step 0.01); applies to choice/score only

Question-type behavior:

  • choice: the model picks one of options. Each option becomes an output handle.
  • score: the model rates the state against the ordered levels in options; the highest-probability level decides the branch, and the numeric score is exposed as an output too.
  • noul: returns a 0–1 yes/no probability; >= 0.5 routes to yes, otherwise no. noul does not return a confidence.

Branch handles:

  • choice/score: one handle per option/level, plus the fallback handle (default by default).
  • noul: fixed yes and no, plus the fallback handle.
  • Renaming options remaps existing connections onto the new handles where possible (remapDecisionBranchEdges); handles that cannot be mapped are flagged as errors by the validator (decisionBranchHandleInvalid) and must be reconnected.
  • Decision nodes that previously used yes/no as their options are auto-migrated on load (migrateLegacyDecisionBranchEdges).

Output variables:

  • answer (string): the selected option/level, or yes/no
  • selected_handle (string): the branch handle actually activated (may be the fallback handle)
  • usage (object): decision-model token usage
  • choice + confidence + probabilities (for choice)
  • score + confidence + probabilities (for score)
  • noul (number): yes/no probability (for noul)

Failure paths

Missing modelId, stateTemplate, or instructions, an invalid questionType, or an option count/uniqueness violation makes the node return validation_error directly; an answer type or probability key set that does not match the configuration returns decision_result_missing — it does not silently fall through to the default branch.

Retries (node-level)

As a workflow node, the Decision node is subject to the node-level retry policy (backend/app/services/workflow/retry.py): the default is RetryPolicy(max_retries=2, base_delay=1.0), i.e. up to 2 retries (3 attempts total), with exponential backoff (base 2.0) plus up to 25% jitter and a per-delay cap of 60 seconds. When enable_retry is true (the WorkflowOrchestrator default) the orchestrator wraps the executor in RetryableExecutor, so failed results such as validation_error and decision_result_missing are retried too. This retry comes from the node policy, not from the TypeSafe adapter (the decision adapter has no retry configuration of its own).


3. Media Generation Node (media_generation)

Configuration container: node.data.mediaGenerationConfig or node.data.config.

FieldTypeDefaultDescription
modestring"image"Media mode: "image" or "video"
modelIdUUID stringRequiredTeam-authorized image/video model ID
promptstringRequiredPositive prompt supporting variable interpolation
negativePromptstringnullNegative prompt (image generation only)
width / heightint/nullnullImage dimensions; when omitted, determined by upstream model or tool settings
numImagesint1Number of images; the model or tool configuration determines the upper bound
referenceImageVariablestringnullReference image variable for image-to-image workflows
durationfloat/nullnullVideo duration; when omitted, the tool configuration supplies its default
aspectRatiostring/nullnullVideo aspect ratio; when omitted, the tool configuration supplies its default
motionIntensityfloat/nullnullVideo motion intensity

Outputs:

  • result: Generated media URL. Returns an array of URL strings for images, or a single URL string for video.

4. Condition Branch Node (condition)

Configuration container: node.data.conditionConfig or node.data.config.

Evaluates tree-structured condition groups. Each condition consists of variable (variable reference), operator (comparison operator), and value (target value).

Supported Operators:

  • Equality: equals, not_equals
  • Text Patterns: contains, not_contains, starts_with, ends_with, regex_match
  • Numeric Comparison: greater_than (>), less_than (<), greater_or_equal (>=), less_or_equal (<=)
  • Null & Empty States: is_empty, is_not_empty, is_null, is_not_null

5. HTTP Request Node (http_request)

Configuration container: node.data.config.

FieldTypeDefaultDescription
methodstring"GET"HTTP method: GET, POST, PUT, DELETE, etc.
urlstringRequiredDestination URL supporting dynamic template variables
headersobject{}Key-value request headers supporting template variables
bodyanynullRequest payload (supports JSON objects or text interpolation)
timeoutint30Request timeout in seconds; the executor default is 30 and this node layer has no additional range validation

SSRF Protection Guardrails (YUN-150)

All outbound targets from HTTP Request nodes are strictly validated through validate_external_http_url after DNS resolution:

  • Private RFC 1918 subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), loopback (127.0.0.1, localhost), and cloud metadata (169.254.169.254) are blocked by default.
  • Internal requests are only permitted if the target IP/CIDR/domain is explicitly allowlisted in Site Settings > SSRF Outbound Targets (ssrf_allowed_targets) (e.g., allowlisting localhost/local or specific enterprise subnets).
  • Critical non-bypassable ranges (169.254.0.0/16, 224.0.0.0/4, 0.0.0.0/32) and Google Cloud metadata (metadata.google.internal) cannot be bypassed or accepted in allowlist configuration and remain permanently blocked.

Outputs:

  • statusCode (int): HTTP response status code (e.g., 200, 404)
  • body (any): Parsed JSON object, or raw string if response is not valid JSON
  • headers (object): Key-value response headers

6. Knowledge Retrieval Node (knowledge_retrieval)

Configuration container: node.data.knowledgeRetrievalConfig.

FieldTypeDefaultDescription
knowledgeBaseIdUUID stringRequiredTarget knowledge base identifier
querySourcestring"variable"Query source: "variable" or "constant"
queryVariableRefstring""Variable reference used when querySource is "variable"
queryConstantValuestring""Fixed query text used when querySource is "constant"
searchModestring"hybrid"Search mode: "hybrid", "vector", or "fulltext"
topKint5Maximum number of chunks to return
thresholdfloat0.0Similarity score cutoff threshold
outputVariablestring"results"Custom output variable name for retrieved chunks

Outputs:

  • results (array): Array of chunk objects containing content, score, metadata, documentId, and chunkId
  • context (string): Pre-concatenated text blocks separated by \n\n---\n\n for direct prompt injection
  • totalFound (int): Total count of matching chunks

7. Code Execution Node (code)

Configuration container: node.data.codeConfig or node.data.config.

Runs inside an isolated sandbox container with a default 30-second timeout (CODE_TIMEOUT = 30).

  • Python Entry: with language: "python", must define def main(inputs):, where inputs is a dictionary, returning a dict.
  • JavaScript Entry: with language: "javascript", must define function main(params) or const main = (params) =>, returning an object.
  • Any other language value is rejected (unsupported_code_execution_language).

Outputs: All top-level keys returned in the dictionary/object are mapped to individual downstream variables.


8. Data Transformation Nodes

Template Transform (template)

  • Container: node.data.templateConfig.
  • template: Jinja2 template string, e.g. Hello {{ user_name }}, ticket #{{ order_id }} is updated.
  • inputs: Variable mapping list binding upstream variables to template variables.
  • Outputs: output (string) or custom defined output variable name.

Variable Aggregator (variable_aggregator)

  • Container: node.data.variableAggregatorConfig.
  • mode: Aggregation strategy:
    • "object": Bundle variables into a JSON object key-value map
    • "array": Merge variables sequentially into an array list
    • "concat": Join string variables using separator
    • "merge": Deep or shallow merge multiple object variables
  • Outputs: result (default).

Variable Assignment (variable_assignment)

  • Container: node.data.variableAssignmentConfig.
  • assignments: List of assignments supporting three operations:
    • overwrite: Overwrite target context variable with variableRef
    • clear: Clear target variable
    • set: Assign fixed constantValue

Parameter Extractor (parameter_extractor)

  • Container: node.data.parameterExtractorConfig.
  • extractionMethod: Strategy: "llm" (model reasoning), "regex" (regular expressions), or "json_path" (JSON Path syntax).
  • Outputs: Each extracted parameter is exposed as an independent strongly typed output variable.

File to URL (file_to_url)

  • Container: node.data.fileToUrlConfig.
  • Converts incoming binary/temporary file or image variables into permanent or signed public URLs, avoiding large Base64 strings in LLM prompts.

9. Flow Control & Container Nodes

Question Classifier (question_classifier)

  • Container: node.data.questionClassifierConfig.
  • Configures a language model and multiple preset category branches (with id, name, description, and handle). At runtime, prompts the model to classify intent and route along the matching branch handle.

Iteration (iteration)

  • Container: node.data.iterationConfig (with node.data.config retained for legacy definitions).
  • iteratorVariable: Variable reference to traverse; legacy definitions may use inputVariable.
  • iteratorType: "array" (default) or "object". Array mode wraps scalar input in a one-element array; object mode does not iterate non-object input.
  • Array mode exposes itemVariable (default "item") and indexVariable (default "index"); object mode exposes keyVariable (default "key") and valueVariable (default "value").
  • maxIterations: Defaults to 100; a positive integer is capped at 1000 at runtime.

Loop (loop)

  • Container: node.data.loopConfig (with node.data.config retained for legacy definitions).
  • Prefer exitConditions (an array of conditions) together with exitLogicOperator ("and"; any other value is handled as "or") to define exit behavior. Each condition contains variable, operator, and value.
  • When exitConditions is absent, the legacy conditionVariable, conditionOperator, and conditionValue fields are used. With neither condition form configured, the loop continues until its iteration count limit.
  • counterVariable defaults to "loopCount" and falls back to legacy indexVariable; outputVariable defaults to "results".
  • maxIterations defaults to 100; the executor applies min(configured value, 1000). Supply a comparable integer value: unlike iteration, this path has no additional strict type validation.

Pause (pause)

  • Container: node.data.pauseConfig.
  • mode: "approval" (await human sign-off) or "variables" (await external form input).
  • Suspends workflow execution and fires an event notification, resuming when input or approval is received.

Output Node (answer)

  • Container: node.data.answerConfig.
  • outputs: Final key-value dictionary presented to the caller (string, number, boolean, array, object).
  • streaming: Can bind directly to an upstream streaming LLM node's response to stream text back to client applications.

Validation Checklist

The workflow editor uses its validation engine to report recognized errors and warnings in the checklist panel, helping authors correct definitions. The publish endpoint does not currently enforce this checklist; authors should address its findings before saving or publishing. Implemented checks include:

  1. Graph Checks:
    • Runtime plan validation requires exactly one user_input or trigger entry point and detects cycles in the workflow graph.
    • The validator flags nodes without an upstream edge, except user_input, trigger, iteration_start, loop_start, and comment.
  2. Node Configuration Checks:
    • Depending on node type, it reports missing models, tools, knowledge bases, extraction parameters, assignments, or processing children inside a container.
    • condition, question_classifier, decision, code, sub_workflow, agent, media_generation, pause, and variable-processing nodes each have corresponding configuration checks.
    • The decision node validates stateTemplate, instructions, option count and uniqueness, and whether any edge still references a stale branch handle (decisionBranchHandleInvalid).
  3. Variable & Container Checks:
    • The editor reports variable references unavailable from the visible upstream graph, invalid or duplicate parameter names, and container-structure issues.
    • It also reports placement of pause nodes inside iteration or loop containers.

Runtime execution still performs node configuration and authorization checks. Passing or ignoring checklist findings does not guarantee that external model, tool, or knowledge base calls will succeed.

How is this guide?

On this page