Human decisions
Pause a workflow, review the context, then continue with a recorded answer.
A human decision belongs at a meaningful boundary: before returning a candidate, accepting a report or authorizing the next step. Give the reviewer the actual evidence.
A complete small example
Create laufwerk/workflows/decision/workflow.ts in your initialized project:
import { Workflow } from "@effect/workflow";
import { Human } from "@laufwerk/sdk";
import { Effect, Schema } from "effect";
export const workflow = Workflow.make({
name: "decision",
payload: { executionKey: Schema.String },
success: Schema.String,
error: Schema.String,
idempotencyKey: input => input.executionKey,
});
export const layer = workflow.toLayer(() => Effect.gen(function* () {
const accepted = yield* Human.confirm({
key: "accept",
title: "Accept this demonstration result?",
description: "This records a local decision. Nothing will be published.",
});
return accepted ? "accepted" : "declined";
}).pipe(Effect.mapError(String)));Run from the project root:
bun run --cwd laufwerk check
bunx laufwerk@0.0.1-alpha.6 run decision --input '{"executionKey":"decision-1"}'Expect waiting and one pending confirmation. This command can exit successfully while the workflow waits.
Run → waiting for your decision → accepted or declined → completedRespond in Studio
Run bunx laufwerk@0.0.1-alpha.6 studio, open the printed URL, and review the run's pending interaction. Answer it there. The workflow continues with the recorded answer.
Or use the CLI
The run output shows both IDs. Replace RUN_ID and INTERACTION_ID with those exact values:
bunx laufwerk@0.0.1-alpha.6 respond RUN_ID INTERACTION_ID --response '{"kind":"confirmation","value":true}'
bunx laufwerk@0.0.1-alpha.6 status RUN_IDUse false to decline. The response must be the typed object, not a bare Boolean. Text requests use {"kind":"text","value":"your answer"}; choices use {"kind":"single-choice","value":"AN_OFFERED_VALUE"}.
approve is the separate convenience command for an agent's tool approval. It is not a replacement for Human.confirm.
An answer of “declined” can correctly finish the workflow. Business acceptance and runtime completion are different things.