LaufwerkLaufwerk
Learn Laufwerk

Projects, workflows and runs

Define a runnable file, choose an execution identity, and run it through the CLI or Studio.

A workflow is a reusable definition. A run is the recorded work for one input identity. Start by making this distinction concrete without an agent.

Add a workflow

After initializing a project, save this file at laufwerk/workflows/estimate/workflow.ts.

workflow.ts
import { Workflow } from "@effect/workflow";
import { Effect, Schema } from "effect";

export const workflow = Workflow.make({
  name: "estimate",
  payload: {
    requestId: Schema.String,
    pages: Schema.Number.pipe(Schema.int(), Schema.between(1, 100)),
  },
  success: Schema.Struct({ minutes: Schema.Number }),
  error: Schema.String,
  idempotencyKey: input => input.requestId,
});
export const layer = workflow.toLayer(input =>
  Effect.succeed({ minutes: input.pages * 3 }),
);

payload validates input. success describes the result. toLayer registers the implementation. Constructing an Effect describes work; the runtime executes it. For multiple operations, Effect.gen and yield* let you use each successful value in the next operation.

Start and inspect it

From the project root:

bunx laufwerk@0.0.1-alpha.13 run estimate --input '{"requestId":"estimate-1","pages":4}' --json

The workflow result is {"minutes":12}, inside the CLI's run response. Repeat the command: the same request ID addresses the same run. Changing pages while keeping requestId is not a request to recalculate it. Use estimate-2 for genuinely new work. Existing runs also retain their original workflow bundle; editing the file changes future runs.

Studio's Start run uses the same definition and identity. Applications can start it through HTTP.

Organize only what you need

laufwerk/
  workflows/estimate/workflow.ts   # Discovered definition and registration
  agents/                         # Reusable model/tool configurations
  tools/                          # Your callable integration code
  components/                     # Reusable workflow logic
  project.json                    # Stable project identity
  laufwerk.config.ts              # Project configuration

Those helper folders do not execute themselves. Import their code from workflows. Keep project.json when updating so your project retains its connection to run history. Runtime state lives outside this source tree by default.

Reference: Workflow options and methods · Project configuration


← The system at a glance · Next: Agents, tools and skills →

On this page