Skip to content
Français

Compose typed workflows

Connect task results and choose the task type that fits each step.

defineTask() prepares the input, defineLoopTask() repeats an attempt until its check accepts, and defineWorkflow() runs them in order.

import { defineTask } from "@elie-laloum/outpost";

export const plan = defineTask({
  key: "plan",
  perform: () => ({ files: ["src/parser.ts"] }),
});
import { defineLoopTask } from "@elie-laloum/outpost";
import { plan } from "./plan.ts";

export const fix = defineLoopTask({
  key: "fix",
  after: [plan],
  maxRounds: 3,
  attempt: (context) => ({
    files: context.value(plan).files,
    round: context.round,
  }),
  check: (_, candidate) =>
    candidate.round === 2
      ? { done: true }
      : { done: false, feedback: "Cover the missing edge case." },
});
import { reportValue } from "./reporter.ts";
import { defineWorkflow } from "@elie-laloum/outpost";
import { plan } from "./plan.ts";
import { fix } from "./fix.ts";

export const result = await defineWorkflow("fix-parser", [plan, fix]).start();
result.unwrap();
reportValue(result.value(fix));
// Example output: { files: [ 'src/parser.ts' ], round: 2 }

Nothing runs until start(). The first round is rejected, the second receives the feedback and is accepted, and result.value(fix) keeps the type returned by attempt.

TaskRunsReturns
defineTask()Your own functionWhatever it returns
defineAgentTask()An agent on the shared workspaceIts text, commits and typed value
defineIsolatedTask()An agent in its own sandbox and worktreeThe same, per repository
defineLoopTask()Attempt and check, until acceptedThe accepted candidate
defineApprovalTask()A gate waiting on a personThe recorded decision

For a checkpointed workflow, return values that can be stored and restored as JSON without loss. A later process can then resume from the saved task results.

  • context.value() throws for a task that is missing from after, even when it already ran.
  • A task starts only once every task in its after list is done; defineWorkflow() rejects cycles and unknown dependencies before execution.
  • A rejection in the last round fails the loop task with LoopTaskExhausted.
  • To save task results in a checkpoint, use values that can be restored from JSON without loss. Class instances, streams and handles do not meet this requirement.
  • A workflow does not push, merge or deploy anything by itself. Those steps stay in your tasks.

API: defineTask · defineWorkflow · defineLoopTask · TaskContext · WorkflowResult · WorkflowFailure · defineJsonResponse.