Concepts

Flow Builder

Describe the flow you want in plain English and watch the nodes appear and wire themselves up — then keep chatting to refine it.

You need an AI provider first. Set Up AI walks you through it. The Flow Builder switch — and Home's Describe a watchflow to build… box — appear only once Settings ▸ AI Providers holds a provider Flow Builder can build with: a cloud API key, a local model such as Ollama or LM Studio, a Claude or ChatGPT subscription, or Watchflows AI Sparks. Remove the last one and both disappear.

Apple Intelligence alone is not enough. The on-device model is skipped when it is only your global default — its context window is too small to plan a flow. Pin it to the Flow Builder role in Settings ▸ AI Defaults if you want it anyway.

Two views of one flow

Every flow has a segmented switch in its toolbar — Canvas and Flow Builder (⇧⌘B). Canvas is the hands-on view: palette on the left, drag-and-drop wiring, inspector on the right. Flow Builder swaps that left sidebar for a conversation with the flow itself. The canvas stays live either way — nodes are still clickable and runs still animate — you are just steering with words.

Flow Builder: the conversation on the left, the flow it built still live on the canvas.
Flow Builder: the conversation on the left, the flow it built still live on the canvas.

On an empty canvas, a request like "OCR my screenshots and save the text next to them" produces a complete, connected flow. With nodes already there, a follow-up edits what exists — "now notify me when it finishes" adds and wires the new node without rebuilding the rest.

The conversation is persistent. Each flow keeps its own transcript — the newest 200 turns — across window closes and relaunches, and each request sends the model only the last 12 of them. Build turns also carry a snapshot of the graph as it stood afterwards; the newest 50 of those offer Restore here, recorded as its own turn and undoable like any other edit.

The model never touches your canvas

Every request runs through a pipeline that checks the plan against the real node system before anything is drawn.

  1. It reads the canvas. The nodes and connections are summarised as compact text. Any field the node marks secret — passwords, bearer tokens, API-key auth values, webhook secrets — is replaced with ••• before that summary goes anywhere.
  2. It sends a catalog of real nodes. Your request travels with the actual list of node types. Types that need an integration you have not connected are left out, so the builder never proposes a step that cannot work yet. A small local model — roughly 8B parameters or under — gets a trimmed catalog that still keeps every dropdown option.
  3. The plan is checked op by op. An unknown node type or an illegal connection fails the build outright. Bad config values, such as a dropdown option that does not exist or an unresolved {{variable}}, become checklist items instead. On a hard error the exact problem goes back to the model: one initial call plus at most two repair rounds.
  4. Only a valid plan is drawn. The whole attempt runs against a scratch copy of the flow, so a build that never validates leaves your canvas exactly as it was.

A freshly built flow arrives disabled, with a checklist of anything that needs you — a field the builder could not guess, a destructive node to confirm. Blank required fields block arming until you fill them in. The builder never quietly enables something that could delete files or run scripts.

It asks, and it reads your runs

When a request is missing a detail it genuinely needs, the builder asks rather than guessing — often with a control right in the conversation: a folder picker, a dropdown of the node's real options, an on/off switch. A database or table question is answered from this Mac, so no database or table name goes into a prompt at all. A secret is typed into a secure field, lands straight in the node's config, and is never sent to the model; the transcript records that you set the field, not what you set it to.

Once the open flow has run, the builder knows how its recent runs went. Ask a diagnostic question — or click Diagnose on a failed run, which opens Flow Builder with the question already asked — and it reads that run in full: the failing node, its error, what it emitted. An ordinary build request reads none of that, and the conversation says what it looked at either way.

Tell it the flow is wrong and it names the problem and offers Fix it and Leave it as chips, changing nothing until you pick. If a turn fails on the provider's side, the failure card has a Try again button that resends your message and clears the failed exchange.

Good to know

Your request goes to your provider. The canvas summary and your message are sent to whatever model you configured. Secret-marked fields are masked first — but a key typed into a non-secret field, such as a script body, a request header, or a JSON body, is not, and travels as-is. Pick a local provider such as Ollama or LM Studio to keep every request on this Mac.

A flow already in Flow Builder always keeps the switch. If the provider later goes away — key deleted, subscription lapsed, Sparks used up — the flow is not stranded: the switch stays so you can return to Canvas. Only entering Flow Builder is gated.

The model is the Flow Builder's own. Set it from the pill in the conversation header or in Settings ▸ AI Defaults. It is used for every build, whatever models the AI nodes inside the flow are set to. A more capable model plans noticeably better — if a build looks off, that is the biggest single upgrade.

It builds; it does not run. Flow Builder assembles flows for you to review and arm. AI Agents is the separate feature that lets an assistant run the flows you choose to expose.