Workflow canvas

Building and checking agent workflows: a node canvas with a step library, a linear trigger-and-steps builder, and a run inspector showing what each step did.

Loading preview…

Install

  1. 1

    Run this command in your Tailwind CSS project. It adds components/ai/workflow-canvas-canvas.tsx and installs its dependencies.

    $ npx shadcn@latest add https://gradientdeck.com/ai-components/r/workflow-canvas-canvas.json

Usage & API

Example

workflow-canvas-canvas.tsx
import { WorkflowCanvas } from "@/components/ai/workflow-canvas-canvas"

<WorkflowCanvas
  nodes={[]}
  edges={[]}
  selectedId={null}
  onSelect={() => {}}
  onMoveNode={() => {}}
  onConnect={() => {}}
  onAddNode={() => {}}
  onUpdateNode={() => {}}
  onDeleteNode={() => {}}
/>

Props WorkflowCanvas

PropType & descriptionRequired
nodesFlowNode[]Required
edgesFlowEdge[]Required
selectedIdstring | nullRequired
onSelect(id: string | null) => voidRequired
onMoveNode(id: string, x: number, y: number) => voidRequired
onConnect(from: string, to: string, branch?: "yes" | "no") => voidRequired
onAddNode(kind: StepKind, at?: { x: number; y: number }) => void`at` is set when a step is dropped onto the canvas; otherwise place it yourself.Required
onUpdateNode(id: string, patch: { title?: string; field?: { key: string; value: string | boolean } }) => voidRequired
onDeleteNode(id: string) => voidRequired
runRecord<string, NodeRunState>Optional
runTimesRecord<string, string>Optional
activeEdgesstring[]Optional
overlayReactNodeSlot rendered over the bottom-left of the canvas (run results, undo).Optional

Dependencies

  • React
  • Tailwind CSS
  • motion
  • lucide-react
Implementation notes

Canvas fills the frame. On a wide screen the library is a left column: Search steps, then AI with Agent, Logic with Condition and Delay, and Apps with Linear issue, Slack message and HTTP request. A note at the bottom says to drag a step onto the canvas or click to add it below the selected one. Narrow screens replace that column with an Add step menu of the same items. Nodes are buttons labelled with the kind and title. An agent node also shows its model value and how many of its tool switches are on. The other kinds show a one-line summary from their fields. Dragging the background pans. Dragging a node calls onMoveNode. Fit runs until the person has panned or zoomed. Properties dock on the right from small breakpoints up, and as a bottom sheet on phones. Fields render as text, textarea, select or switch, and fields that share a group get a heading. An overlay slot sits at the lower left for a run result or an undo.

Choosing a layout

Use the canvas when the flow branches and crosses, and people need to see edges rather than a list. The library is the way to discover steps, grouped as AI, Logic and Apps, with search. Use the step list when the flow is mostly a sequence with one or two conditions. Inserting between cards, dragging to reorder, and turning a step off are clearer in a stack than on a board. A step that is off reads Off, skipped in runs, and fades. The condition's two columns are labelled with the value it tests and with Otherwise, and an empty path says nothing happens on it.

Use the run inspector after a workflow exists, on its runs page, not while someone is still wiring nodes. The list covers the last 24 hours and filters All or Failed. Open a run to see which steps ran, how long they took, and why one failed. Retry from this step is the action on a failed row. It calls onRetry with the run id and the step id. It does not rebuild the graph. For authoring, stay on the canvas or the step list. Model settings and the instructions editor still belong on the agent itself. A step card can show a model field because you put that field on the step. It is not a global model form.

Does the canvas run the workflow when a node is connected?

No. Connecting calls onConnect with the source id, the target id, and yes or no when the drag started on a condition port. Adding, moving, renaming, editing a field and deleting are separate callbacks. Pass run and runTimes if you want spinners and durations drawn on the nodes. The board does not schedule anything.

What does Retry from this step change?

It calls onRetry with the selected run's id and that step's id. The inspector does not replay steps locally. When you update the runs you pass in, the bars, the badge and the open error follow that data. Pending and skipped steps have no retry control because their rows do not expand.