Skip to main content
import { runWorkflow } from "smithers-orchestrator";
import { Effect } from "effect";

const result = await Effect.runPromise(runWorkflow(workflow, {
  input: { task: "fix bug" },
}));

result.runId;     // string
result.status;    // "finished" | "failed" | "cancelled" | "continued" | "waiting-approval" | "waiting-event" | "waiting-timer"
result.output;    // populated only if your schema has a key literally named `output`
result.error;     // serialized SmithersError on failure
Signature:
function runWorkflow<Schema>(
  workflow: SmithersWorkflow<Schema>,
  opts: RunOptions,                 // see Types
): Effect.Effect<RunResult, SmithersError>;
Both RunOptions and RunResult are defined in Types.

Resume

Pass the original runId plus resume: true. State loads from SQLite, completed tasks are skipped, in-progress attempts older than 15 minutes are abandoned and retried.
await Effect.runPromise(runWorkflow(workflow, { input: {}, runId: "my-run-123", resume: true }));
The original input row is loaded from the DB; pass {} for input. The workflow file hash and VCS root must match the original run.

Cancel via AbortSignal

const controller = new AbortController();
setTimeout(() => controller.abort(), 5 * 60 * 1000);

const result = await Effect.runPromise(runWorkflow(workflow, { input: {...}, signal: controller.signal }));
// result.status === "cancelled"
All in-flight attempts are marked cancelled and NodeCancelled events are emitted.

Hijack handoff

If a CLI hijack happens mid-run (bunx smithers-orchestrator hijack RUN_ID), the run ends "cancelled" and the latest attempt metadata stores hijackHandoff. On resume: true, Smithers waits for a safe handoff point and continues with the persisted CLI session id (see CLI Agents) or the persisted message history (SDK agents).

result.output

Populated only when the schema passed to createSmithers() has a key literally named output. Other schema rows live in their own SQLite tables, so query them directly:
import { Database } from "bun:sqlite";
const db = new Database("smithers.db", { readonly: true });
const rows = db.query("SELECT * FROM page WHERE run_id = ? ORDER BY iteration DESC").all(result.runId);

Notes

  • On macOS, runWorkflow acquires a caffeinate lock to prevent idle sleep and releases it on completion. On other platforms this is a no-op.
  • Set SMITHERS_LOG_LEVEL=debug to enable verbose engine logging.
  • For lifecycle events, pass onProgress (see Events).