Execution progress

Build custom timeline UIs with getProgress and SSE watchProgress.

Custom portals often show a timeline or status bar while a workflow or SDK action run is in flight. Prefer the business-readable executionPath (never raw nodes / edges), and use the SDK helpers below so you do not invent your own poll loop.

Snapshot: getProgress

Fetches status + executionPath, then enriches each step with catalogue logos/icons from workflowApps.list().

timeline.ts
const progress = await lunnoa.executions.getProgress(executionId);// progress.status, progress.activeStepIndexfor (const step of progress.steps) {  // step.label, step.status, step.iconUrl, step.appLogoUrl, step.durationMs}

Live updates: watchProgress

Subscribes to GET /api/executions/:id/stream (Public API SSE). The server pushes execution.progress snapshots as steps change, plus loop.progress for For Each / Repeat, and execution.finished on terminal status.

Use fetch with a Bearer token (the browser EventSource API cannot send Authorization headers).

live-timeline.ts
const controller = new AbortController();for await (const progress of lunnoa.executions.watchProgress(executionId, {  signal: controller.signal,})) {  renderTimeline(progress); // your UI  if (progress.status === 'NEEDS_INPUT') {    // show form from progress.pendingInput / submitInput  }}

Lower-level access to raw SSE frames: lunnoa.executions.stream(executionId).

Events on the wire

EventMeaning
connectedStream attached
execution.progressStatus + executionPath (+ pendingInput) snapshot
loop.progressFor Each / Repeat loop counters
execution.finishedTerminal status (SUCCESS / FAILED / CANCELLED)
heartbeatKeep-alive (~15s)

Related

  • Workflows: trigger runs and resume NEEDS_INPUT
  • Run actions: one-step SDK executions (source: SDK)
  • Errors: 401 / 403 / 429 handling