Authoring API reference
This reference covers the stable root authoring namespace exported by
@dromio/workflow beta. Import advanced contracts and adapters from the
documented package subpaths only when the root API does not expose them.
Core definitions
step(input)
Defines app-owned contracted behavior. Required fields are id and run.
Common options are input, output, label, description, maxRetries,
config, sideEffects, capabilities, intents, tags, and verbs.
run({input, config, artifacts, model, step, emit}) may return the declared
output directly or an advanced done, ask, wait, retry, goto, or
fail result from @dromio/workflow/core.
catalog(items)
Creates a searchable executable catalog from authored step definitions.
workflow() accepts the definitions directly; call catalog() when you also
need search or createStep() outside document compilation.
workflow(input)
Compiles a workflow document against catalog. Required fields are catalog
and document. Optional fields include input, output, config, model,
triggers, use, and workflows. The returned workflow exposes start(),
hydrate(), graph(), configure(), document, catalog, workspace, and
its boundary contracts.
triggerspublishes manual, schedule, webhook, or other app trigger descriptors; it does not alter the document's trigger boundary.useis an application-owned dependency value exposed ascontext.useto runtime steps.workflowsregisters authored child sources needed for nested compilation and graph projection.graph()returns the document-backed workflow projection.configure(config)recompiles placements with typed workflow configuration; it does not create a new authored identity.start()andhydrate()create the session described in Execution and durability.
The callable workflow namespace also provides three reusable workflow
bundles. Their internal phases are real graph nodes:
workflow.judge()composes one assessor with one deterministic score gate.workflow.judgeUntil()composes produce, judge, route, revise, and complete with a requiredmaxAttemptsbound.workflow.clarifyUntil()composes resolve, judge, route, ask, merge, revise, and complete with a requiredmaxRoundsbound.
workflowApp(input)
Registers one or more authored workflows for executable surfaces. Required
fields are id and non-empty workflows; title and defaultWorkflow are
optional.
Work primitives
step.model(input)
Runs exactly one schema-constrained model operation. Requires id, input,
output, and prompt; accepts model, operation, and buildPrompt. The
worker returns JSON, then the SDK parses and validates every output key. A
placement model or workflow-level model overrides the definition default.
step.delegate(input)
Creates a durable handoff_requested hook for work owned by an external
harness. Requires id, input, output, and non-empty instructions.
instructions, context, artifacts, title, and summary may be static or
resolved from typed input. capabilities declares requirements. The hook adds
run, workflow, step, and attempt identity plus a JSON Schema derived from the
output contracts and a resume token.
Resuming through controlPlane.resumeHook() or the canonical MCP tool
dromio.resume_hook validates output before completing the step. Validation
failure preserves the waiting hook; duplicate delivery of a consumed token is
idempotent.
step.evaluate(input)
Deprecated compatibility wrapper. Builds an inspectable model assessor plus
deterministic score gate. Requires
id, input, evaluator, and policy. Use .eject() when the generated
evaluation workflow must become explicit authored topology. New code uses
workflow.judge().
step.gate(input)
Applies the CandidateScorePolicy returned by defineScorePolicy() to an
evaluation input. Requires id, an
input containing evaluation, and policy. Outputs both decision and the
original evaluation; it does not call a model.
Score gates are evaluated from highest minScore to lowest, regardless of
array order. If the evaluation requests a gateId and meets its threshold,
that gate wins. nextAction is one of ask, suggest, confirm, revise,
execute, complete, or cancel; evaluation status is pass, needs_input,
revise, or fail. defineEvaluationBar() from the core subpath constructs
the normalized bar used by advanced evaluation flows.
step.promptedContract(input)
Deprecated compatibility wrapper. Runs the canonical resolve, assess, gate,
clarify, merge, revise, and rescore
loop as one visible composite. Requires contract, definition, input,
output, and mapCompleted. Use inspect() for its generated catalog and
workflow document. New contract loops use workflow.clarifyUntil().
Human and time primitives
step.ask(input)
Always presents one human question and waits. Requires answer, question,
mapAnswer, and the usual id, input, and output. The answer contract is
validated before mapping. Put conditional branching before this step.
step.approval(input)
Creates a typed durable approval hook. Requires decision, request,
mapDecision, id, input, and output. reject() may convert a decision
into a failed run. hookId, title, and render customize the host-facing
request.
step.waitFor(input)
Waits for a typed signal declared by defineSignal(). Requires id, input,
signal, and a correlation() mapper. Outputs occurrenceId, occurredAt,
and the validated signal payload.
step.sleep(input)
Waits on the canonical timer hook without holding a worker. Requires id,
input, output, timerId, schedule, and mapFired. schedule returns
either {ms} or {until}. The host is responsible for durable timer delivery.
Composition primitives
step.workflow(input)
Places one authored child workflow as a step. Requires id and workflow.
Input and output contracts come from the child. Questions, waits, events,
traces, and failures retain child identity.
All composition workflow, routes, and branches values are compiled
AuthoredWorkflow objects returned by workflow(), not raw documents. The
composite definition carries child sources into the parent catalog; pass the
same workflows explicitly to the parent's workflows array only when nested
compilation needs additional sources. See Composition.
step.router(input)
Selects exactly one of at least two compatible child workflows. Requires
id, routes, and select. All routes must have identical output contracts
and compatible default inputs. Supply explicit input plus mapInput when the
router boundary differs from its children. Selecting an undeclared route or a
different route during resume fails.
step.fork(input)
Runs at least two independently startable child workflows and joins all of
them. Requires id and branches. Shared input keys must have compatible
contracts; output keys must not collide. The current join policy is all.
step.forEach(input)
The simple form requires string keys items and collect plus one child
workflow; it derives array contracts from a single-input, single-output
child. The advanced form declares input, output, items(), childInput(),
prepare(), collect(), and optional item metadata, child configuration,
lifecycle callbacks, and continueOnError.
Supporting authoring APIs
defineSignal()declares typed correlation and payload contracts.promptFile()loads a model prompt relative to the module URL.createWorkflowAppHost()creates an in-process durable Workflow App host.runWorkflowCli(),runWorkflowTui(),runWorkflowGui(), andrunWorkflowSvg()select packaged application surfaces.runWorkflowServer()serves the Workflow App host and signal control plane.createWorkflowControlPlaneMcpProvider()exposes registered workflows, triggers, runs, and canonical hook resumption to external harnesses.
createWorkflowAppHost().runtime.startRun() returns a WorkflowAppRun; its
session is the underlying workflow session, while the wrapper adds app input,
workflow ID, events, artifacts, and status. Use runtime methods for hosted
answers, hook delivery, resumption, and checkpoint reruns so state is persisted.
Session API
workflow.start(input, options?) resolves to a session. options accepts
runId, initial answers, onEvent, question resolvers, and a core
LoopStore. Important members are:
session.status;
session.state;
session.events;
session.checkpoints;
session.pendingQuestions;
session.pendingHooks;
session.answer({questionId, value});
session.resume();
session.resumeHook({token, value});
session.snapshot();
session.pause({reason});
session.cancel({reason});
session.rerunFromCheckpoint({checkpointId});
Questions use answer() followed by resume(). Hook delivery resumes within
resumeHook(). Approval values match the step's decision contract; signal
values are {occurrenceId, occurredAt, payload}; timer delivery is host-owned.
See Human input and waits for examples.
Execution kind and workflow role
kind controls runtime execution; a role such as assess, revise, or
judge explains the node's meaning inside a workflow or generated bundle. For
the canonical explanation and role table, see Composition.
Model worker contract
Custom workers implement ModelWorkerPort from @dromio/workflow/product:
type ModelWorkerPort = {
complete(input: ModelWorkerCompleteInput): Promise<string>;
completeJson(input: ModelWorkerCompleteInput): Promise<unknown>;
};
ModelWorkerCompleteInput includes operation, prompts or messages, optional
JSON Schema, trace context, event sink, provider body, and setup-error mapping.
step.model() calls complete() once and validates the returned JSON itself;
other product adapters may use completeJson().
Plain-step run context
| Property | Meaning |
|---|---|
input | Values parsed by the declared input contracts |
config | Definition defaults resolved with placement configuration |
artifacts | Registry for files produced by the step |
model | Workflow or placement ModelWorkerSource, when supplied |
step | Run, workflow, step, attempt, correlation, and idempotency identity |
emit(event) | Append an app-defined public lifecycle event to this attempt |
const report = step({
id: "reports.publish",
input: {report: reportSchema},
output: {published: z.boolean()},
run({emit, step: attempt}) {
emit({
type: "report.publish.started",
message: `Publishing with ${attempt.idempotencyKey}`,
});
return {published: true};
},
});
The emitted EventPayload requires type and message; it may include
detail, stepId, attempt, correlation data, trace context, and other public
fields. Gate execution emits score.gate.completed, evaluation.completed,
and operation.decision.completed.
Subpath imports
| Import | Use |
|---|---|
@dromio/workflow/core | Advanced results, score policies, loop stores, event and contract types |
@dromio/workflow/product | Model workers and advanced product adapters |
@dromio/workflow/workflow-control-plane | Durable runtime and signal control-plane integration |
The root namespace is the canonical authoring API. Subpaths expose lower-level integration machinery and may evolve faster during beta.