Node Config Panels
Generic SchemaForm, bespoke panels, and RawConfigSection.
When you click a node on the canvas, a config panel slides in from the right. The panel renders all configurable parameters for that node. Every field value is stored in the workflow AST and round-trips through the YAML pane.
How panels work
Rensei uses two kinds of config panel, automatically selected per node type:
| Kind | When used | Source |
|---|---|---|
| Generic SchemaForm | Any node without a bespoke panel | JSON Schema 7 declaration on the node definition |
| Bespoke panel | Nodes with a registered config-panel.tsx | Auto-discovered at build time via scripts/generate-node-manifest.ts |
Both kinds share the same outer chrome: the node's title, category badge, close button, and the Raw config section at the bottom.
Generic SchemaForm
For most nodes, the platform generates a form directly from the node's inputSchema (JSON Schema 7). Field types are inferred from the schema:
| Schema type | Rendered as |
|---|---|
string | Text input |
string with enum | Dropdown select |
boolean | Toggle |
number | Numeric input |
object | Collapsible sub-section |
array | Repeatable row list with add/remove |
Fields marked required in the schema show a red asterisk. Fields with description render a help tooltip on hover.
Expression fields and the SchemaPicker
Any string field that accepts template expressions shows a small {{ }} button next to the input. Clicking it opens the SchemaPicker - a variable tree of all values available from upstream nodes.
The SchemaPicker walks the graph backwards from the current node, collecting the outputSchema of each reachable upstream. Variables are grouped by node name and displayed in a collapsible tree. Clicking a variable inserts the canonical expression (e.g., {{ nodes.myNode.result }}).
Single-token expressions like {{ nodes.upstream.count }} preserve the original value type (number, boolean, object) at runtime. Multi-token interpolations always produce a string.
Inherited defaults
When a project has configured cascade defaults (via project environment settings), fields that inherit a default from the project or org level show a placeholder like Default: gpt-4o (from project) while the field is empty. Clearing a field restores the inherited value at runtime.
MokeData toggle
Every node in a workflow can be set to mock mode for test runs. The config panel exposes a Mock data toggle at the top. When enabled, you provide a static JSON payload that the executor returns instead of executing the real node. This is useful for fast iteration without triggering external API calls.
See Test-run mode for how mock coverage is measured across the full workflow.
Bespoke config panels
The following nodes have purpose-built config panels that replace or augment the generic form:
| Node | Key | What the panel provides |
|---|---|---|
agent.dispatch | donmai.agent.dispatch | Agent card picker + dispatch options |
agent.dispatch_stage | donmai.agent.dispatch_stage | Stage selector + inline override editor |
agent.invoke | donmai.agent.invoke | Agent card picker + invoke-mode settings |
linear.issue.predicate | linear.linear.issue.predicate | Structured predicate builder for Linear issue fields |
agent (foundational) | donmai.agent | Agent Composer - assembles an AgentDispatchRef from sub-refs |
agent-definition (foundational) | donmai.agent-definition | Points at an agent card row; inline override editor |
llm-model (foundational) | donmai.llm-model | LLM model profile ref with profile picker |
gate.human_query | rensei.gate.human_query | Approval gate - timeout, onTimeout policy, message template |
parallel.fanout | rensei.parallel.fanout | Branch definition editor |
parallel.fanin | rensei.parallel.fanin | Join strategy + branch selector |
Bespoke panels render their specialized UI first, then fall back to the generic SchemaForm for any fields they do not explicitly cover (unless the panel declares full coverage).
Adding a bespoke panel (DEV)
To add a bespoke panel for a new node type:
Create src/lib/nodes/<category>/<provider.id>/config-panel.tsx and export a named component whose name ends in ConfigPanel.
Implement the standard props contract:
export interface MyNodeConfigPanelProps {
value: MyNodeConfig
onChange: (next: MyNodeConfig) => void
workflowId?: string
nodeId?: string
workflowNodes?: WorkflowNode[]
workflowEdges?: WorkflowEdge[]
projectId?: string | null
}
export function MyNodeConfigPanel({ value, onChange, ... }: MyNodeConfigPanelProps) {
// ...
}Run pnpm generate:nodes (or start the dev server - predev runs it automatically). The generator detects the new file and emits an updated src/lib/nodes/config-panels.generated.ts. No changes to node-config-panel.tsx are needed.
Add RawConfigSection as the last element in your panel's JSX (required - see below).
Raw config section
Every panel - generic and bespoke alike - includes a collapsible Raw config (JSON) section at the bottom. It displays the full current config as pretty-printed JSON and accepts direct edits. Changes are validated and applied to the AST on blur.
This is a deliberate power-user escape hatch: if a bespoke panel does not expose a field you need to set, edit it directly in Raw config.
<RawConfigSection
value={value as Record<string, unknown>}
onChange={(next) => onChange(next as MyNodeConfig)}
/>The section is collapsed by default and does not distract normal workflows.
Port type editor
For group boundary ports, the config panel surfaces a Port type editor instead of a field form. This lets you declare the type of each input and output port on the group's interface:
- Kind -
any,string,number,boolean,object,array,union,struct - Required - whether a wired input is mandatory
- Label - display name shown on the canvas port
Struct-typed ports reference a workspace struct type. Ports with kind any accept any connection without type checking (backward-compatible default).
Upstream-aware panels
Bespoke panels that need to react to what is wired upstream (e.g., showing a model profile picker only when an llm-model foundational node is connected) can use the usePanelContext hook:
import { usePanelContext } from '@/components/workflow/use-panel-context'
const ctx = usePanelContext(nodeId ?? '', workflowNodes, workflowEdges)
const hasUpstreamModel = ctx.hasUpstream('llm-model')ctx.upstreamRefs lists all upstream node types connected to the current node. ctx.upstreamSchemas lists their output schemas for building variable-substitution previews.
Pickers
Several specialized pickers appear within config panels for resource-reference fields:
| Picker | Field purpose |
|---|---|
| Model profile picker | Select an LLM model profile configured for the org/project |
| Agent picker | Select an agent card reference |
| Integration credential picker | Select an integration credential for the target provider |
| Environment ref picker | Select a project environment reference |
| Resource ref picker | Select a workflow resource reference |
| Template ref picker | Select a workflow template reference |
| Partial picker | Select an agent skill or partial |
Each picker is scoped to the current project (or org, depending on the resource type) and is populated from the platform's registered catalog at the time the panel opens.
Related pages
- Canvas - canvas navigation and node placement
- Node Palette - finding and placing nodes
- Port Types - typed port declarations
- Expressions -
{{ }}template syntax and namespaces - Groups - group containers and boundary port authoring
- Struct Types - workspace-scoped named object shapes
- Test-run mode - mock data and coverage