Skip to Content
WorkflowsWhat is a workflow

What is a workflow

A workflow is a file that calls workflow(). Each time it is triggered, the platform starts one run of its execute function.

import { workflow } from "@loops/sdk"; type ScanRequest = { patientId: string; phoneNumber: string }; export const healthScanWorkflow = workflow<ScanRequest>({ id: "health-scan", execute: async ({ step, event }) => { const { patientId, phoneNumber } = event.body; await step.do("Generate a health scan", async ({ ctx }) => { await ctx.FACIAL_SCAN.create({ metadata: { patientId, phoneNumber }, }); }); const scan = await step.waitForScan({ timeout: "30 minutes" }); return { patientId, scanId: scan.id }; }, });

The parts

  • id — the workflow’s name.
  • event.body — the JSON the run was started with. A POST body, a store event, or the input another file passed to trigger. Its type is the one you pass to workflow<T>.
  • step.do(name, fn) — a saved unit of work. Once it finishes, its return value is stored, and a replay uses that value instead of running it again.
  • ctx — the tools and bindings, such as FACIAL_SCAN. It only exists inside a step.do.
  • step.waitForScan — pauses the run until the patient finishes the scan, or the timeout fires. A paused run uses no compute.
  • env — the loop’s variables and secrets, next to step and event.

step.do and step.waitForScan are the only two step methods.

A run

One trigger is one run. The run gets a runId, and everything it does is recorded against it: the input, each step and its status, every console.*, and what execute returned. Read it under Runs.

A step that throws is tried once more after a second. If it throws again, the run fails. A finished step is replayed from its saved value. Code between steps runs again on replay, so anything that reaches the outside world belongs inside a step.do. Return JSON from a step, because the saved value is what later replays get.

A waitForScan that times out throws. Catch it to carry on without the scan:

const scan = await step.waitForScan({ timeout: "30 minutes" }).catch(() => null); if (!scan) return { patientId, status: "no scan" };

Starting a workflow

  • A POST to the workflow’s URL. The JSON body becomes event.body. See Triggering a run.
  • Another file, with healthScanWorkflow.trigger(body). An agent does this from a tool. See Calling a workflow.
  • A store event, when a Shopify store is connected. See Shopify.

The caller gets the runId back straight away. It does not wait for the run to finish.

Last updated on