Node Types
Every step in a NORA workflow is a node. This guide covers all 10 node types: what each one does, how to configure it, and when to use it.
Overview
| Node Type | Purpose | Executes? |
|---|---|---|
| Command Node | Run shell commands and scripts | ✅ |
| Condition Node | Route workflow based on logic | ✅ (evaluates) |
| Wait Node | Pause execution for a duration | ✅ (timer) |
| Wait Until Time Node | Pause until a specific time | ✅ (timer) |
| AI Router Node | Classify text into categories using AI | ✅ |
| AI Agent Node | AI selects one tool per invocation | ✅ |
| AI Autonomous Agent Node | Multi-step AI executes tools iteratively | ✅ |
| Custom Script Agent Node | User-written script as a bidirectional agent | ✅ |
| Media Viewer Node | Display images, video, audio, PDFs inline | ❌ (display) |
| Notepad Node | Sticky-note annotations | ❌ (notes) |
Command Node
The Command Node is the most common node type. It runs a shell command or script and captures the output.
When to Use
- Running CLI tools, scripts, or system commands
- Executing Python, Node.js, PowerShell, or Bash scripts
- Any step that involves running something on the command line
Configuration
| Field | Description |
|---|---|
| Title | Display name shown on the canvas |
| Command | The shell command to execute (e.g., python process.py --input data/) |
| Working Directory | The directory the command runs in |
| Description | Optional description for documentation |
| Shell | Shell type: Auto-detect, CMD, PowerShell, pwsh, Bash, sh |
| Interactive | If enabled, opens in a separate terminal window instead of capturing inline |
| Timeout | Hard time limit for execution (in seconds). Node is killed if it exceeds this. |
| Links | Buttons displayed on the node — link to URLs, files, or directories |
Retry Configuration
Command Nodes support automatic retries on failure:
| Setting | Description |
|---|---|
| Enable Retry | Toggle retries on/off |
| Max Attempts | Number of tries before giving up (1–10) |
| Initial Delay | Wait time before the first retry (in seconds) |
| Backoff Strategy | How the delay changes between retries |
Backoff Strategies:
– Fixed — same delay every time (e.g., 1s → 1s → 1s)
– Linear — delay increases by the initial amount each time (e.g., 1s → 2s → 3s)
– Exponential — delay doubles each time (e.g., 1s → 2s → 4s)
Nodes with retry configured show a small badge (e.g., “🔄 ×3”) and timeout configured shows a clock badge (e.g., “⏱ 30s”).
Shell Auto-Detection
When set to Auto, NORA detects the right shell by analyzing your command:
– Commands with Get-, Set-, $env:, Where-Object, $_ → PowerShell
– Commands with grep, awk, sed, chmod → Bash
– Otherwise → CMD (Windows) or sh (Mac/Linux)
Important: Auto-detection only triggers on the patterns above. Commands that use
Invoke-RestMethod,ConvertTo-Json,$token, or other PowerShell syntax without those specific markers will be routed to CMD and fail. Always set Shell to PowerShell explicitly when writing PowerShell commands.
PowerShell Quoting Rules (Read This)
PowerShell commands in NORA pass through an intermediate cmd.exe layer before reaching powershell.exe. This means double-quoted strings inside your command can get mangled in transit.
Rule: use single quotes for static string values.
# ✅ Works — single quotes for token and URL
$token = 'ghp_abc123'; Invoke-RestMethod -Uri 'https://api.github.com/...' -Method GET -Headers @{ Authorization = "Bearer $token" }
# ❌ Fails — double quotes get stripped by cmd.exe
$token = "ghp_abc123"; Invoke-RestMethod -Uri "https://api.github.com/..." -Method GET
Single quotes are literal in PowerShell (no variable expansion). Use double quotes only when you need a variable to expand inside a string, such as "Bearer $token".
Multi-line commands must be collapsed to one line using semicolons — NORA sends a single command string:
$token = 'abc'; $body = @{ message = 'hello' } | ConvertTo-Json; Invoke-RestMethod -Uri 'https://...' -Method PUT -Body $body
See the PowerShell guide for full details, common errors, and real-world examples.
Tool Parameter Prompts
If a node has parameter definitions, running it opens a Parameter Prompt Modal that collects user inputs before execution. Parameters can be:
– Text — free-form text input
– Number — numeric input
– Enum — dropdown selection from predefined options
NORA caches your last-used values so you don’t have to re-enter them each time.
Inline Script Editing
If the command references a script file (e.g., python myscript.py), an ✎ Edit button appears. Clicking it opens the script in a full Monaco code editor (the same editor used in VS Code) with syntax highlighting for 18+ languages. You can edit, save, and optionally run the edited version immediately.
Run Buttons
| Button | Action |
|---|---|
| Run | Execute the command and show output inline on the node |
| Run in Terminal | Open a new terminal window for the command (useful for interactive programs) |
| Kill | Force-stop a running process (appears while running) |
Status Indicators
| Color | Meaning |
|---|---|
| Gray border | Idle — not yet run |
| Blue border (pulsing) | Currently executing |
| Green border | Completed successfully (exit code 0) |
| Red border | Failed (non-zero exit code) |
Output Panel
After execution, click the node to expand its output panel showing:
– Full command output (monospace, scrollable)
– Copy button to copy output to clipboard
– ✕ to close the panel
– Background color: green tint (success), red tint (error), yellow tint (running)
Link Buttons
Links appear as gray buttons on the node. NORA auto-detects the link type:
– URL (http/https) — opens in browser
– File (file:///) — opens in your configured default editor
– Directory (file:/// ending in folder path) — opens in file explorer with a 📁 icon
Condition Node
The Condition Node evaluates a condition and routes the workflow down one of two paths based on the result.
When to Use
- Route on success vs. failure of a previous step
- Run different branches during business hours vs. after hours
- Execute different paths on weekdays vs. weekends
Condition Types
NORA supports 10 condition types organized into categories. Each evaluates differently and uses specific edge labels.
Basic Logic
Status Check
Routes based on the exit code of the previous node.
| Field | Value |
|---|---|
| Logic Type | status |
| Edge labels | success and error |
The success edge is followed if the previous node exited with code 0. The error edge is followed otherwise.
Has Output? (Output Check)
Routes based on whether the previous node produced any stdout.
| Field | Value |
|---|---|
| Logic Type | output-check |
| Edge labels | has-output and no-output |
Useful for checking if a command returned results before processing.
Time & Date Conditions
Time Window
Routes based on the current time of day.
| Field | Value |
|---|---|
| Logic Type | time-window |
| Start Time | HH:MM (24-hour format, e.g., 09:00) |
| End Time | HH:MM (e.g., 17:00) |
| Edge labels | in-window and out-of-window |
If the current time is between Start and End, the in-window edge is followed. Otherwise, out-of-window.
Day Check
Routes based on the day of the week.
| Field | Value |
|---|---|
| Logic Type | day-check |
| Selected Days | Array of day numbers (0 = Sunday, 1 = Monday, …, 6 = Saturday) |
| Edge labels | match and no-match |
If today is one of the selected days, match is followed. Otherwise, no-match. Default: Monday–Friday.
Output Comparison Conditions
These conditions analyze the stdout from the previous node.
Output Contains
Routes based on whether stdout contains a specific substring.
| Field | Value |
|---|---|
| Logic Type | output-contains |
| Search String | Text to search for |
| Case Sensitive | true or false (default: false) |
| Edge labels | contains and not-contains |
Output Matches (Regex)
Routes based on whether stdout matches a regular expression pattern.
| Field | Value |
|---|---|
| Logic Type | output-matches |
| Regex Pattern | Regular expression to test |
| Regex Flags | Regex flags (default: i for case-insensitive) |
| Edge labels | matches and no-match |
Numeric Threshold
Extracts the first number from stdout and compares it against a threshold.
| Field | Value |
|---|---|
| Logic Type | numeric-threshold |
| Threshold | Number to compare against |
| Operator | >=, >, <=, <, or === |
| Edge labels | above and below |
Example: If stdout is "Score: 85 points", NORA extracts 85 for comparison.
Numeric Range
Checks if the first number in stdout falls within a min–max range.
| Field | Value |
|---|---|
| Logic Type | numeric-range |
| Range Min | Minimum value (inclusive) |
| Range Max | Maximum value (inclusive) |
| Edge labels | in-range and out-of-range |
Advanced Conditions
JSON Expression
Parses stdout as JSON and evaluates a custom expression using the expr-eval library.
| Field | Value |
|---|---|
| Logic Type | json-expression |
| Expression | JavaScript-like expression (e.g., data.count > 5 and status == "active") |
| Variables | Optional user-defined variables |
| Edge labels | true and false |
The expression has access to:
– All fields from the parsed JSON output
– output — the raw stdout string
– status — the parent node’s exit status
– Any user-defined variables
Example: If stdout is {"users": 42, "active": true}, the expression users > 10 and active evaluates to true.
Visual Indicators
Condition nodes display a badge showing their configuration:
– ✓✗ Status Check: “Success / Error”
– 📤 Output Check: “Has Output?”
– 🔍 Output Contains: “Contains: [text]”
– ⚙️ Output Matches: “Matches: /pattern/”
– 📊 Numeric Threshold: “>= 50”
– 📏 Numeric Range: “10 – 100”
– ⏰ Time Window: “09:00 – 17:00”
– 📅 Day Check: “Mon, Tue, Wed, Thu, Fri”
– 🧮 JSON Expression: “Expression”
Important: Edges leaving a Condition Node must have the correct labels, or the workflow won’t know which path to follow.
Condition Template Library
Access the condition template library via the Add Condition dropdown. Templates provide pre-configured conditions:
| Template | Logic Type | Edge Labels | Use Case |
|---|---|---|---|
| IF/Else (Status) | status |
success, error |
Branch on exit code |
| Has Output? | output-check |
has-output, no-output |
Check if command returned data |
| Output Contains | output-contains |
contains, not-contains |
Search for text in output |
| Output Matches | output-matches |
matches, no-match |
Regex matching |
| Numeric Threshold | numeric-threshold |
above, below |
Compare numbers |
| Numeric Range | numeric-range |
in-range, out-of-range |
Check number bounds |
| Time Window | time-window |
in-window, out-of-window |
Business hours routing |
| Day Check | day-check |
match, no-match |
Weekday/weekend routing |
| JSON Expression | json-expression |
true, false |
Complex JSON logic |
Wait Node
The Wait Node pauses workflow execution for a specified duration.
When to Use
- Add a delay between API calls to respect rate limits
- Wait for an external process to complete
- Space out steps that depend on timing
Configuration
| Field | Description |
|---|---|
| Duration | Number of time units to wait |
| Unit | seconds, minutes, or hours |
The node displays a badge: ⏳ Wait with the duration (e.g., “30 seconds”).
Wait Until Time Node
The Wait Until Time Node pauses workflow execution until a specific time of day.
When to Use
- Start a batch job at a specific time (e.g., 2:00 AM)
- Gate a workflow step until business hours begin
- Coordinate with time-dependent processes
Configuration
| Field | Description |
|---|---|
| Target Time | HH:MM in 24-hour format (e.g., 09:00) |
| Offset Days | Number of days to add (0 = today, 1 = tomorrow, etc.) |
The node displays a badge: ⏰ Wait Until with the target time.
Note: If the target time has already passed today and offset is 0, the node waits until that time tomorrow.
AI Router Node
The AI Router Node reads a file and uses AI to classify its content into one of several user-defined categories. Each category becomes a separate output path.
When to Use
- Sort incoming documents by type or topic
- Route customer messages by intent
- Classify data for different processing pipelines
Configuration
| Field | Description |
|---|---|
| AI Provider | Gemini, OpenAI, or Anthropic |
| Model | Model to use (dropdown with presets, or type a custom model name) |
| Input Folder Path | Directory containing files to classify |
| File Pattern | Filter pattern (e.g., *.json;*.txt) |
| Sort By | How to select which file to process (e.g., most recently modified) |
| Categories | List of classification categories (each becomes an output handle) |
| Custom Prompt | Optional instructions for the AI classifier |
| CSV Output | Optionally save classification results to a CSV file |
How It Works
- The node reads the latest file from the input folder matching the file pattern
- The file content is sent to the AI provider with the configured prompt
- The AI classifies the content into one of the defined categories
- The workflow follows the edge labeled with the matching category name
Output Handles
Each category you define creates a separate output handle on the right side of the node. Connect each handle to the node that should process that category.
Important: Edge labels on connections from an AI Router must match the category names (case-insensitive).
Cost Tracking
The node tracks and displays token usage and estimated cost after each classification.
Debug Mode (🐛)
Toggle the 🐛 button in the node header to enable Debug Mode. A scrollable 🐛 Raw Response panel appears after each run showing the complete JSON object returned by the AI API — useful for inspecting classification metadata, token counts, or unexpected routing.
AI Agent Node
The AI Agent Node uses AI to decide which tool to invoke from a predefined list. The AI makes a single decision per invocation, and the workflow routes to the matching tool’s downstream node.
When to Use
- Let AI decide which processing step to take next
- Dynamic routing based on content analysis
- Single-decision-point workflows where AI picks the best action
Configuration
| Field | Description |
|---|---|
| AI Provider | Gemini, OpenAI, or Anthropic |
| Model | Model to use (presets or custom) |
| Tools | Comma-separated list of tool names (e.g., search, summarize, archive) |
| Memory Folder Path | Directory of context files the AI can read |
| File Pattern | Filter for memory files |
| Sort By | How to order memory files |
| Max Memory Files | Limit on number of files loaded |
| Custom Prompt | System prompt defining the agent’s behavior |
| Conversation Mode | Single-turn or multi-turn (with configurable max turns) |
The memory folder path badge on the node shows Open and Copy buttons to quickly open the folder in your file explorer or copy the path to your clipboard.
How It Works
- The node loads context files from the memory folder
- The content is sent to the AI with the tool definitions and system prompt
- The AI decides which one tool to invoke
- The workflow follows the edge connected to that tool’s output handle
Output Handles
Each tool name creates an output handle: tool_<slug> (where the slug is the tool name lowercased with spaces replaced by hyphens). There are also always success and error handles.
Example: If tools are search, summarize, the output handles are:
– tool_search
– tool_summarize
– success
– error
Conversation Mode
In multi-turn mode, the AI agent can maintain context across multiple invocations. A turn counter tracks the conversation progress. This is useful when the AI’s decision depends on accumulated context from previous interactions.
Debug Mode (🐛)
Toggle the 🐛 button in the node header to enable Debug Mode. A scrollable 🐛 Raw Response panel appears after each run showing the complete JSON object returned by the AI API — useful for inspecting tool call arguments, raw model output, finish reason, or tracing unexpected routing decisions.
AI Autonomous Agent Node
The AI Autonomous Agent Node is a multi-step agent that iteratively executes tools to complete a complex task. Unlike the AI Agent (which makes one decision), the Autonomous Agent keeps working — calling tools, reading results, and deciding next steps — until the task is done.
When to Use
- Complex tasks requiring multiple tool calls (data analysis, report generation)
- Tasks where the sequence of steps isn’t known in advance
- Scenarios where the AI needs to make multiple decisions iteratively
Configuration
| Field | Description |
|---|---|
| AI Provider | Gemini, OpenAI, or Anthropic |
| Model | Model to use |
| Goal Prompt | System prompt defining the agent’s role and behavior |
| User Request | The task to accomplish (shown in the chat UI) |
| Memory Folder Path | Directory of context files |
| Default Working Directory | Where tool commands execute |
| Max Iterations | Maximum number of tool calls (default: 10) |
| Timeout | Time limit in minutes |
| Budget Limit | Maximum cost in USD (default: $10.00) |
| Tools | Tool definitions — add from Tool Library or define as JSON |
The memory folder path badge on the node shows Open and Copy buttons (same as AI Agent Node).
Built-In Tools
Every Autonomous Agent has these tools available automatically (no configuration needed):
| Tool | Description |
|---|---|
read_file |
Read the contents of any file (up to 50,000 characters) |
write_file |
Create or overwrite a file with specified content (auto-creates parent directories) |
list_directory |
List files and folders in a directory (recursive option) |
file_exists |
Check if a file or directory exists at the given path |
run_command |
Run shell commands and capture stdout/stderr (with timeout control) |
These are the same core tools available to Custom Script Agents, so the AA can read, write, and execute just like CSA.
You can add more tools from the Tool Library or define them inline. You can also drag script files directly from Windows File Explorer onto the agent node to add them as tools instantly.
Tool Discovery
Enable Tool Discovery to let the agent find and use tools from your Tool Library at runtime — without pre-configuring them on the node. When enabled:
- The agent receives a special
search_toolsbuilt-in that searches your Tool Library by keyword - If the agent calls an unknown tool, NORA attempts lazy resolution — searching the Tool Library for a matching tool
- Resolved tools are cached for the session
This is ideal for general-purpose agents that need flexibility. Instead of pre-defining 20 tools, enable Tool Discovery and let the agent find what it needs.
Session Persistence
Autonomous Agent sessions are persistent — if execution is interrupted, the agent can resume:
- Conversation history is preserved across restarts
- Shows Resume instead of Run when a prior session exists
- Click Clear Session to reset and start fresh
- Session state includes: iteration count, pending questions, partial results, cost tracking
Chat Interface
The Autonomous Agent has a chat UI directly on the node:
– Type your task in the input field
– Watch the execution log stream in real time
– The AI shows its thinking steps, tool calls, and results
– If the AI needs clarification, it enters the needs-input state and asks a question — type your answer to continue
Safety Guards
| Guard | Purpose |
|---|---|
| Max Iterations | Prevents runaway loops (stops after N tool calls) |
| Budget Limit | Stops execution if estimated cost exceeds the limit |
| Timeout | Hard time limit for the entire session |
⚠️ Cost tracking is approximate. See AI Cost Tracking for details.
Output Handles
| Handle | When Used |
|---|---|
complete |
Agent finished the task successfully |
partial |
Agent made progress but didn’t fully complete |
needs-input |
Agent is waiting for human input |
error |
Something went wrong |
Upstream Context
The Autonomous Agent automatically gathers output from all parent nodes (nodes connected upstream). This context is passed to the AI so it can build on previous workflow steps.
Adding Tools via Drag & Drop
You can drag script files (Python, Node.js, etc.) directly from Windows File Explorer onto an Autonomous Agent node to add them as tools. The script is immediately added to the agent’s tool list. This is a quick alternative to using the Tool Library drawer.
Debug Mode (🐛)
Toggle the 🐛 button in the node header to enable Debug Mode. When active:
– Full tool results — the 200-character truncation is removed from tool call results in the execution log
– debugInfo fields — rendered inline in log entries when present (JSON formatted)
Custom Script Agent Node
The Custom Script Agent Node lets you run your own Python or Node.js script as a bidirectional agent. Your script communicates with NORA via a JSON protocol over stdin/stdout. You bring your own LLM provider and API keys — NORA just handles orchestration.
Templates included. Copy a starter template from the
custom-script-templates/folder, replace the placeholder logic with your LLM calls, and configure the node to point to your script. See AI Features — Custom Script Agent for the full protocol reference, all templates, and LLM provider examples.
When to Use
- You need custom AI logic that doesn’t fit the built-in agent types
- You want to use any LLM provider (OpenAI, Anthropic, Gemini, Ollama, OpenRouter, LM Studio, Azure, or any OpenAI-compatible API)
- You need full control over the agent’s decision-making process
- You want to integrate with external APIs or services during agent execution
Configuration
| Field | Description | Default |
|---|---|---|
| Script Path | Absolute path to your .py or .js script file |
(required) |
| Script Type | Auto-detect (from extension), Python, or Node.js | Auto-detect |
| Working Directory | Where the script runs | Script’s folder |
| Route Labels | Comma-separated custom outcomes (e.g., approve, reject, review) |
(empty — just success/error) |
| User Request | Task/prompt passed to the script | (empty) |
| Memory / Input Folder Path | Folder of context files passed to the script automatically | (empty) |
| File Pattern | Glob patterns for memory files (e.g., *.txt;*.md;*.json;*.csv) |
*.txt;*.md;*.json;*.csv |
| Sort By | Last Modified or Created Time | Last Modified |
| Max Memory Files | Maximum context files to include | 5 |
| Max Runtime (minutes) | Script force-terminated after this duration (max 120) | 30 |
| Tools | Tool Library tools the script can invoke at runtime | (none) |
The memory folder path badge on the node shows Open and Copy buttons to quickly access or copy the path.
How It Works
- NORA spawns your script as a child process
- NORA sends a
startmessage via stdin with the full configuration (route labels, tools, memory file contents, conversation history, user request, working directory) - Your script reads JSON lines from stdin and writes JSON lines to stdout
- Your script can request tool execution, send chat messages, log progress, ask the user questions, and report AI cost
- When done, your script sends a
completeevent with a route label and output
Communication Protocol
Messages NORA sends to your script (via stdin):
| Message | When | Contains |
|---|---|---|
start |
Immediately after launch | config with route labels, tools, memory files, conversation history, user request, working directory |
tool_result |
After executing a requested tool | Tool ID, success status, output, duration |
user_message |
When the user responds to a question | User’s text response |
stop |
When the user clicks Cancel | — |
Messages your script sends back (via stdout, one JSON per line):
| Message | Purpose |
|---|---|
log |
Write to the execution log panel (level: info/warn/error/debug) |
thinking |
Show a progress step in the UI (iteration counter) |
message |
Display a chat message in the conversation area |
tool_request |
Ask NORA to execute a configured tool |
needs_input |
Pause and ask the user a question |
cost |
Report token usage and cost (accumulates across multiple events) |
complete |
Finish execution — route to a workflow edge |
error |
Signal a failure — routes to the error edge |
Non-JSON stdout is captured as debug logs. Stderr output appears as warn-level logs.
Built-in Tools
Every Custom Script Agent has these tools available automatically — no configuration needed:
| Tool | What It Does |
|---|---|
| read_file | Read the contents of a file |
| write_file | Write content to a file (creates directories as needed) |
| list_directory | List files and folders in a directory |
| file_exists | Check whether a file exists |
| search_tools | Search the Tool Library for available tools |
| run_command | Execute a shell command in the working directory (default 30s timeout, max 120s) |
You can add more tools from the Tool Library or define them via the node’s Tools configuration. Agents can also use the self-tooling pattern — writing a helper script via write_file and executing it via run_command — for capabilities like web scraping or data transformation. See AI Features — Self-Tooling Pattern for details.
Directory Safety
The working directory is validated at startup. If it resolves to a protected system location (Electron install directory, Windows system folders, Program Files), NORA falls back to Documents\NORA\csa-workdir. File operations via built-in tools also block path traversal (../) and writes to protected directories.
Process ID (PID) Badge
After the script launches, the node displays the OS process ID of the spawned subprocess below the description area. Click the badge to copy the PID to clipboard — useful for manual process inspection or attaching a debugger. The badge resets automatically when you click Run again.
API Key Management
Scripts manage their own API keys. Create a .env file in the same folder as your script:
ANTHROPIC_API_KEY=sk-ant-api03-your-key-here
OPENAI_API_KEY=sk-your-key-here
The included templates have a built-in .env parser — no external dependency needed.
Output Handles
Each route label becomes an output handle: route_<label>. Plus success and error handles.
Example: If route labels are approve, reject, escalate, the handles are:
– route_approve
– route_reject
– route_escalate
– success
– error
Included Templates
| File | Language | Description |
|---|---|---|
agent_template.py |
Python | Full template with helpers and commented OpenAI/Ollama/Anthropic examples |
agent_template.js |
Node.js | Same features, JavaScript with async/await and message queue |
agent_anthropic_claude.py |
Python | Ready-to-use Claude routing agent with built-in cost tracking |
Python Template (from agent_template.py)
#!/usr/bin/env python3
import json, sys, time
def emit(event_type, **data):
"""Send an event to the workflow UI."""
print(json.dumps({"event": event_type, **data}), flush=True)
def emit_log(message, level="info"):
emit("log", message=message, level=level)
def emit_thinking(iteration, message):
emit("thinking", iteration=iteration, message=message)
def emit_complete(route, output):
emit("complete", route=route, output=output)
def emit_error(message):
emit("error", message=message)
def read_message():
line = sys.stdin.readline()
if not line:
return None
return json.loads(line.strip())
def request_tool(tool_name, params):
"""Request tool execution and wait for result."""
req_id = f"req_{tool_name}_{int(time.time() * 1000)}"
emit("tool_request", id=req_id, tool=tool_name, params=params)
result = read_message()
if result and result.get("action") == "tool_result":
return {"success": result.get("success", False),
"output": result.get("output", ""),
"durationMs": result.get("durationMs", 0)}
return {"success": False, "output": "No response from tool", "durationMs": 0}
def main():
start_msg = read_message()
if not start_msg or start_msg.get("action") != "start":
emit_error("Expected start message")
return
config = start_msg.get("config", {})
route_labels = config.get("routeLabels", [])
tools = config.get("tools", [])
memory_files = config.get("memoryFiles", [])
user_request = config.get("userRequest", "")
emit_log(f"Received request: {user_request[:100]}...")
emit_thinking(iteration=1, message="Analyzing request...")
# YOUR AGENT LOGIC HERE — use any LLM provider
emit_complete(route="success", output="Analysis complete")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
emit_log("Agent interrupted", level="warn")
sys.exit(0)
except Exception as e:
emit_error(f"Agent crashed: {str(e)}")
sys.exit(1)
Node.js Template (from agent_template.js)
#!/usr/bin/env node
const readline = require('readline');
function emit(eventType, data = {}) {
console.log(JSON.stringify({ event: eventType, ...data }));
}
function emitLog(message, level = 'info') { emit('log', { message, level }); }
function emitThinking(iteration, message) { emit('thinking', { iteration, message }); }
function emitComplete(route, output) { emit('complete', { route, output }); }
function emitError(message) { emit('error', { message }); }
const rl = readline.createInterface({ input: process.stdin, terminal: false });
const messageQueue = [];
let messageResolver = null;
rl.on('line', (line) => {
try {
const msg = JSON.parse(line);
if (messageResolver) { const r = messageResolver; messageResolver = null; r(msg); }
else { messageQueue.push(msg); }
} catch (e) { emitLog(`Failed to parse: ${e.message}`, 'error'); }
});
function readMessage() {
return new Promise((resolve) => {
if (messageQueue.length > 0) resolve(messageQueue.shift());
else messageResolver = resolve;
});
}
async function main() {
const startMsg = await readMessage();
if (!startMsg || startMsg.action !== 'start') { emitError('Expected start message'); return; }
const config = startMsg.config || {};
const userRequest = config.userRequest || '';
emitLog(`Received request: ${userRequest.substring(0, 100)}...`);
emitThinking(1, 'Analyzing request...');
// YOUR AGENT LOGIC HERE — use any LLM provider
emitComplete('success', 'Analysis complete');
rl.close();
}
main().catch(err => { emitError(`Agent crashed: ${err.message}`); process.exit(1); });
Full details — API key setup, all LLM provider examples, multi-turn conversations, user input, tool requests, cost tracking, timeout/cancellation, and standalone testing are covered in the AI Features guide.
Media Viewer Node
The Media Viewer Node displays files inline on the canvas — images, video, audio, PDFs, and documents.
When to Use
- Preview output files generated by earlier workflow steps
- Monitor a folder for the latest output
- Display reference materials alongside your workflow
Configuration
| Field | Description |
|---|---|
| Media URL / Local Path | Path to the file or URL to display |
| Auto-Select Latest | Automatically pick the newest file in a folder |
| File Filter | Pattern to filter files (e.g., *.png;*.jpg) |
| Auto Refresh | Polling interval to check for new files (3s, 5s, 10s, or 30s) |
| Media Type | Auto-detect, Image, Video, Audio, PDF, or Document |
| Show Inline Preview | Display a preview directly on the node |
| Show Player Controls | Show play/pause/volume for audio/video |
| Autoplay | Auto-start playback for audio/video |
Supported Formats
| Type | Formats |
|---|---|
| Image | PNG, JPG, GIF, SVG, WebP, BMP |
| Video | MP4, WebM, OGG (with Range request support) |
| Audio | MP3, WAV, OGG, M4A |
| PDF documents | |
| Document | Office documents |
| Text | TXT, MD, CSV, JSON, and other text files |
Auto-Select Latest Mode
When enabled, the Media Viewer monitors a folder and automatically displays the most recently modified file matching the filter pattern. Combined with Auto Refresh, this creates a live preview that updates whenever new output is generated.
Expanding the View
Click the preview to open a fullscreen modal with the media at full resolution.
Path Buttons
The media path displayed on the node has two utility buttons:
– Open — opens the folder containing the media file in your system file explorer
– Copy — copies the full media file path to your clipboard
Notepad Node
The Notepad Node is a non-executing sticky note for adding annotations, documentation, and reminders to your canvas.
When to Use
- Document setup instructions for a workflow
- Add cost estimates and ROI calculations
- Leave notes for yourself or collaborators
- Organize the canvas with section labels
Configuration
| Field | Description |
|---|---|
| Title | Heading for the note |
| Notes | Text content (supports multi-line) |
| Color | Theme: Yellow, Blue, Green, Pink, Purple, or Gray |
| Layer | Background (behind other nodes) or Foreground (on top) |
Features
- Resizable — drag the edges to resize
- Editable — type directly into the note in Edit Mode (auto-saves with 400ms debounce)
- 6 color themes — use colors to categorize or highlight notes
- Layer control — place notes behind your workflow (background) or on top (foreground) for emphasis
Node Type Quick Reference
Adding Nodes in Edit Mode
| Button | Creates |
|---|---|
| Add Block | Command Node |
| Add Note | Notepad Node |
| Add Condition | Any type via the condition template library |
| 📁 Quick Add | Command Node (from a file/folder on disk) |
| Tool Library drag | Whatever the tool package defines |
The Add Condition button uses the condition template library, which includes templates for all node types — not just conditions. It’s the primary way to add AI nodes, wait nodes, and media viewer nodes.
Condition Template Categories
| Category | Templates |
|---|---|
| Basic Logic | IF/Else (Status), Has Result? |
| Comparisons | Compare Values, Threshold Check, Range Check |
| Time/Date | Time Window, Day Check, Wait/Delay, Wait Until Time |
| Data Quality | Validation Check |
| Display | Media Viewer |
| AI | AI Router, AI Agent, AI Autonomous Agent, Custom Script Agent |
Handles Reference
Handles are the connection points on nodes. The left handle is the input (target), and the right handle is the output (source). Some nodes have multiple named output handles.
| Node Type | Output Handles |
|---|---|
| Command Node | Single default output |
| Condition Node | Single output (routing via edge labels) |
| Wait / Wait Until | Single default output |
| AI Router | One per category (routing via edge labels) |
| AI Agent | tool_<name>, success, error |
| AI Autonomous Agent | complete, partial, needs-input, error |
| Custom Script Agent | route_<label>, success, error |
| Media Viewer | Single default output (pass-through) |
| Notepad | No handles |
What’s Next?
- Building Workflows — How to design, connect, save, and import workflows
- Running Workflows — All execution modes: foreground, background, scheduled
- AI Features — Deep dive into AI provider setup and AI node configuration
- Reference — Condition templates, keyboard shortcuts, and troubleshooting