AI Workflow Builder
Pro4 variants: canvas node graph, list step editor, template gallery and run history — with a column-layout DAG, enable/disable toggles, category filter and execution logs.
import { SvAiWorkflowBuilderComponent } from '@styloviz-pro/ai-workflow-builder';Demo & usage
Basic usage
ProUsage example — open the gallery for the full interactive demo.
An interactive demo for this component lives in the gallery.
Open live demoMore examples
List editor & run history
ProWhen to use
- Building and reviewing multi-step AI automations as a DAG or step list.
- Products that let users compose chains of LLM/tool steps.
- For visualizing a finished run rather than editing, use the AI Agent Activity Log.
Async states
- loading
- error
- retry
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| loading | boolean | false | True while the data is being fetched. |
| error | SvDataError | string | null | null | Load failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`. |
| variant | WorkflowBuilderVariant | 'canvas' | View: canvas DAG, list editor, template gallery or run history. |
| workflow | WorkflowDefinition | null | null | The workflow being edited, the templates on offer, and the run history. These were signals seeded from the bundled fixtures, so a host could not supply its own — the builder always drew the same three-node sample. They are inputs now; `DEMO_WORKFLOW*` stay exported for showcases. The `workflow` input is copied into a local signal because the canvas edits it: the host owns what arrives, the component owns what the user does to it next, and a fresh input replaces both. |
| templates | readonly WorkflowTemplate[] | [] | Starter templates for the template-gallery variant, filterable by category and search. |
| runs | readonly WorkflowRun[] | [] | Past executions for the run-history variant, listed with status, cost and duration and summarised in the stats header. |
| editable | boolean | false | Whether the canvas offers the editing controls at all. OFF BY DEFAULT, AND NOT BECAUSE EDITING IS DANGEROUS. This component shipped as a viewer: hosts put the canvas variant on dashboards to show a pipeline. Adding an Add-node control and a Delete button to every one of those on upgrade would be a change to a screen nobody asked to change, and the reader who finds a Delete button on a read-only dashboard has been told something false about what they are looking at. |
| nodeTypes | readonly NodeType[] | SV_NODE_TYPES | The node types the palette offers. A host running a workflow engine without human-review steps should not offer a node type its runtime will reject — the reader finds out when the run fails, which is the most expensive place to find out. |
| historyCeiling | number | SV_HISTORY_CEILING | How many edits `undo` can walk back. Fifty is past what anybody undoes in one sitting and nowhere near a memory problem, because a command is a node or an edge rather than a copy of the workflow. Undo and redo are a command stack, not a stack of snapshots: past the ceiling the oldest edit is dropped rather than the newest refused, and a new edit after an undo clears the redo branch. Undoing a delete puts the node, its edges and the list variant's matching step back at the indexes they were at — not appended, which would reshuffle the debug trace. A fresh `[workflow]` clears the history. Exported as `svRecord` / `svUndo` / `svRedo` / `svApply` / `svInvert` for a host that owns the workflow. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| retry | void | The host should re-run the failed load. |
| nodeCreate | WorkflowNode | A node was created. |
| nodeDelete | { nodeId: string; removedEdgeIds: readonly string[] } | A node was removed, with the edges that went with it. |
| edgeCreate | WorkflowEdge | Two nodes were connected. A connection is refused in four cases and only four: a node feeding itself, a duplicate of an existing edge, a source with no output port, and a target that accepts none (a trigger). A cycle is not one of them — a loop node is a cycle by design — but an edge that leaves no node without a predecessor is reported, because the debug trace measures depth from those. The same rules are exported as `svCheckConnect`. |
| edgeDelete | string | A connection was removed. |
| workflowEdit | WorkflowDefinition | The whole workflow after an edit. Named `workflowEdit`, not `workflowChange`: `[workflow]` is a plain input, and `(workflowChange)` beside it would read as a two-way binding that does not exist — a host would write `[(workflow)]` and Angular would silently not write back. Not offered, and deliberately not faked: collaborative editing and schema migration. There is no presence, no merge and no conflict resolution, so two editors on one workflow overwrite each other, and `WorkflowDefinition` is unversioned until This output is the hook for both. |
| nodeSelect | string | Emitted with the id of the workflow node the user selects. |
| runSelect | string | Emitted with the id of the run the user selects from history. |
| runStart | string | Emitted with the workflow id when `triggerRun()` starts executing. |
| runComplete | WorkflowRunResult | Emitted when the run finishes — every node has resolved to `success` or `skipped`. A host wiring this to a real backend swaps the simulation in `triggerRun()` for a `POST /runs` call and reports the same shape back. |
Wire it to your API
This component is headless about transport: it renders what you give it and reports what the user asks for. Nothing below requires @styloviz/data — drive it from whatever you already use.
Template
ProBound to the names this component actually exposes.
Host class
ProDrive the three async inputs from your own fetch.
- This component does not emit a query, so it renders what you give it. Fetch on your own trigger and bind `templates`, `loading` and `error`.
- Normalize failures with `toSvDataError()` from `@styloviz/core`. It derives `retryable` from the status, so a 404 does not get a "Try again" button that can only fail again.
Full walkthrough: Connecting to a backend.
Customization & theming
- Canvas DAG or list step editor.
- Template gallery and run history.
- Token/cost tracking per run.
- The Run Workflow / Run buttons execute the workflow as a live simulation — nodes and steps animate running → success in sequence, disabled steps are skipped, and re-running resets the state.
- Emits `nodeSelect` and `runSelect` with the chosen node/run id.
- `[editable]` (off) turns the canvas from a viewer into an editor: a node palette, a connections panel and the keyboard shortcuts. Off by default because hosts put the canvas variant on dashboards to show a pipeline, and a Delete button appearing on one of those tells the reader something false about what they are looking at.
- `[nodeTypes]` (all nine, from `SV_NODE_TYPES`) is the palette. Offer only what the runtime accepts: a node type the engine will reject is a failure the reader discovers at run time, which is the most expensive place to discover it.
- Edits are applied to the component's own copy and emitted: `(nodeCreate)`, `(edgeCreate)`, `(nodeDelete)` with the edge ids that went with the node, `(edgeDelete)`, and `(workflowEdit)` with the whole definition. Named `workflowEdit` rather than `workflowChange` because `[workflow]` is a plain input — `[(workflow)]` is not a binding this component offers, and a `Change` output beside an input would imply it is.
- The editing operations are exported as pure functions — `svCreateNode`, `svPlaceAfter`, `svCheckConnect`, `svConnect`, `svDeleteNode` — so a host that keeps the workflow in its own store can run the same rules against it.
- A connection is refused in four cases and only four: a node feeding itself, a duplicate of an existing edge, a source with no output port, and a target that accepts none (a trigger). A cycle is not one of them — a loop node is a cycle by design — but an edge that leaves no node without a predecessor is reported, because the debug trace measures depth from those and with none of them every node reads at the same level.
- Undo and redo are a command stack, not a stack of snapshots: `[historyCeiling]` (50, from `SV_HISTORY_CEILING`) edits are remembered, the oldest is dropped rather than the newest refused, and a new edit after an undo clears the redo branch — those commands describe a graph that no longer exists. Exported as `svRecord` / `svUndo` / `svRedo` / `svApply` / `svInvert` for a host that owns the workflow.
- Undoing a delete puts the node, its edges AND the list variant's matching step back at the indexes they were at. Membership alone is not enough: the debug trace maps nodes in array order, so an undo that appends reshuffles the whole trace for an edit that changed nothing.
- A fresh `[workflow]` clears the history. The stack belongs to the workflow it was recorded against, and a command naming a node from the previous graph is one `undo` that appears to do nothing.
- Not offered, and deliberately not faked: collaborative editing and schema migration. The command stack is the shape collaboration needs — a stack of snapshots can only say mine or theirs, where a stack of commands can say what each person did — but there is no presence, no merge and no conflict resolution here, so two editors on one workflow will overwrite each other. Version the `WorkflowDefinition` yourself until `AI-06-M6` lands; `(workflowEdit)` is the hook for both.
Best practices
- Do: Offer both canvas (visual) and list (precise) editing for different users.
- Do: Track token/cost per run so expensive workflows are visible before scaling.
- Tip: Let users enable/disable steps to test variations without deleting them.
Accessibility
- Nodes and steps are keyboard reachable; step enable toggles use role="switch".
- Category filter reports aria-pressed; log toggles expose aria-expanded.
- Run status surfaced as text; the Run button disables while executing.
- With `[editable]`, the canvas can be built without a pointer: on a node, `n` adds one after it, `c` starts a connection and `c` on a second node completes it, `Delete` removes it and `Escape` cancels a pending connection. The shortcuts are written on the canvas, because a single letter nobody can discover is not a feature.
- Connecting is two discrete steps rather than one continuous gesture, which is what makes it announceable at all: a drag has no moment to report.
- Every edit — and every refusal — goes into a `role="status"` live region. An edit a screen reader cannot hear did not happen, and a silently dropped connection is how a reader presses the same two keys four times believing it worked.
- The connection control offers only the nodes that can be connected and writes the reason beside the one on offer, rather than presenting a disabled button that tells the reader something is wrong with them.
- The Add control says where the node will go before it goes there — column and row — because the reader cannot watch it appear.
- Undo and redo take Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z on a node card, and their buttons are named after the edit they will reverse — `Undo deleting Classify and 3 connections`, not `Undo`. A reader who pressed the wrong key by accident is the least able to remember what it was.
- Undo and redo announcements name a connection by its nodes’ labels (“Undid connecting Classify to Route”), not their ids — pass the nodes to `svCommandLabel` / `svUndoLabel` / `svRedoLabel` to get the same sentence in a host-owned stack. Proven in a real browser by `e2e/ai-workflow-builder.at.spec.ts`: Tab order in and out of the canvas, refusals announced, and undo/redo on Ctrl+Z, Ctrl+Shift+Z and Ctrl+Y.
Feedback on AI Workflow Builder
Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.