Runs

How a Loop run progresses on the canvas, how nodes light up live, how to resume a checkpoint or retry a failure, and how to inspect past runs.

A run is one execution of a Loop. The orchestrator walks runnable nodes forward and pauses at human checkpoints. Watch each run unfold in place on the canvas · every node lights up as it runs.

Lifecycle

A run is one of:

  • queued · created, waiting for the first tick.
  • running · at least one node is actively executing.
  • awaiting_input · paused at a human.review or human.approve checkpoint. A user must resume.
  • completed · every reachable node reached complete or skipped.
  • failed · a node failed and no alternative path exists.
  • cancelled · a user clicked Cancel mid-run.

Each node carries its own status: pending, running, awaiting_input, complete, skipped, or failed. The medallion ring on every node tints to match: muted for pending, sky pulse for running, amber ping for awaiting, emerald for complete, rose for failed, plain muted for skipped.

Watching a run

Hit Run on the editor and the canvas takes over. Within a couple of seconds the trigger node lights emerald and the next downstream node shifts to a sky pulse. The orchestrator polls every two seconds while a run is live, so each node-state transition arrives in place. Edges along the active path animate so it is clear which branch is moving.

Running nodes shimmer their label text while they execute. Agent nodes also surface a live caption under the title: "Calling propose_email…" when the agent's last tool call lands, or "Thinking…" until the first tool fires. The caption clears the moment the node leaves the running state, so a stuck agent looks visibly stuck (the same shimmer keeps pulsing with no caption changes) rather than silently green.

The orchestrator also runs a tick heartbeat. Every state transition schedules an immediate re-tick plus a 5-second follow-up, so a node that stalls partway through a walk gets a second chance without you having to click anything. If a pod restart drops the in-memory schedule, the boot orchestrator re-seeds an immediate tick for every in-flight run, so a deploy mid-run does not leave you stranded.

Clicking a node swaps the inspector to a runtime panel:

  • Pending node · shows its config form, locked while the loop is in flight.
  • Running node · shows the start timestamp and a thin pulsing "Working" line.
  • Complete node · shows started and completed timestamps, plus collapsible Input and Output JSON blocks.
  • Failed node · shows the error message in a rose-tinted block, the input JSON disclosure, and a "Retry this node" CTA.
  • Skipped node · shows the upstream reason in a muted block.

When no node is selected, the inspector shows a run summary panel instead: trigger source, status, started and completed times, counts for awaiting and failed, a thin progress bar, and a Cancel button while the run is live.

Resuming a checkpoint

When a human.review or human.approve node returns awaiting_input, the run flips to awaiting_input and that node's ring pings amber. Click the awaiting node and the inspector swaps from the runtime panel to the matching resume panel:

  • review-list · a grid of tickable cards (property cards, lead cards, or a generic preview). Pick the subset to keep and click Continue. Skip resumes with an empty selection.
  • approve-queue · one row per agent proposal. Approve or Dismiss fires immediately on every click · no Submit step. Each row optimistically flips to "Sending" or "Dismissing", then locks to "Sent" or "Dismissed" the moment the server confirms. The bulk row at the bottom fires the same per-proposal path in a batch: "Send all N remaining" when the mix is email-only, "Approve all N remaining" otherwise, with "Dismiss all N remaining" as a sibling.

You can edit a proposal inline (subject, body, status, tags) before clicking Approve · the edits ride with the decision and the server runs them through the same validated CRM service path a manual user would use. Email sends, status changes, tag updates, notes, and tasks all execute one row at a time.

Dismissed rows fold into a View N dismissed collapsible at the bottom of the queue. Within the per-org undo window (default 30 seconds) sent or dismissed rows expose Undo · Restore links. Email sends are irreversible, so an emailed proposal cannot be Restored. The node flips to complete only after every proposal in the batch has a decision · the orchestrator then walks the next downstream node.

On resume, you stay on the canvas the whole time.

Tracing an AI step

Every node whose kind is agent.* spawns a managed Anthropic session when it runs. On the canvas, those nodes pick up a small AI glyph on the medallion ring once the session id lands. Click the node and the runtime inspector shows the session id as a violet chip in the header and an expandable "AI session" panel beneath the status block · open the panel to see every proposal the session emitted, one row per propose_* tool call, with the chosen status (pending · approved · dismissed). The row count matches what the downstream human.approve queue surfaces.

Retrying a failed node

When a node fails, its ring tints rose and the run stops walking that branch. Click the failed node, read the error message in the runtime panel, and hit Retry. The retry clears the node's failed state and re-ticks the run from that node only. Downstream descendants are not re-cleared automatically · if an old failure already cascaded through the run, click Retry on each failed node in order.

Viewing past runs

The bottom strip on the editor shows the last few runs with status pills. Click any pill to swap the canvas into "viewing run X" mode: every node ring reflects the chosen run's states, the inspector still works on click, and the run picker stays expanded for fast hopping between runs. A header pill returns to the live view.

The Run button hides while you are viewing a historical run, since you cannot fire a new run from inside an old one.

Cancelling

POST /loops/runs/<runId>/cancel marks the run cancelled. In-flight node work is best-effort interrupted; the run's terminal state is cancelled. The Cancel button lives in the run summary panel while the run is live.

Reading a refusal

Every agent node ends its turn one of three ways:

  • Proposals · one or more propose_* tool calls. The next human.approve node queues them as inbox rows for you to decide.
  • Structured refusal · a single propose_refusal({ reason }) call. The agent node tints amber on the canvas with a "Refused" pill in the inspector and the reason in plain text. The downstream human.approve short-circuits to complete with a passthrough refusal banner, so no empty inbox sits in your queue.
  • Silent stop · the agent ended without proposing anything AND without calling propose_refusal. This is treated as a runtime failure, not a success. The node tints rose with "Agent ran but produced nothing", the inspector surfaces the agent's last 500 characters of narration under "What the agent said before bailing", and the Retry button is available.

Common refusal reasons you will see in the wild:

  • "no email on file" · the lead has no email, so the personalised email or re-engagement drafter chose not to propose.
  • "no CRM data available" · the research agent's snapshot mount was empty.
  • "deal is already at a terminal stage" · a follow-up task would be redundant.

If you see a silent stop a few times in a row, the underlying cause is usually a missing CRM snapshot mount. The session create step fails fast for the loop-task agent when the mount cannot be built, so a silent stop after a clean session create means the agent itself produced nothing.

Past runs

A historical run still shows refusal reasons, narration, and the inspector variants exactly as the live run did. Past runs are read-only · Retry and Cancel hide while you are viewing one.

Fondaro Help

Docs & support

Hi there, how can we help?

Browse popular articles or ask a question below.

Popular articles

Or ask a question