DSL API Reference
This page collects the field-level contract for the workflow DSL implemented by @loop/workflow-engine.
Workflow definition
interface WorkflowDefinition {
id: string;
name: string;
version: string;
triggers?: WorkflowTrigger[];
steps: WorkflowStep[];
metadata?: Record<string, unknown>;
}Fields
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | Yes | Unique workflow identifier |
name | string | Yes | Human-readable label |
version | string | Yes | Version string |
triggers | WorkflowTrigger[] | No | Declarative activation metadata |
steps | WorkflowStep[] | Yes | Must contain at least one step |
metadata | Record<string, unknown> | No | Arbitrary extra metadata |
Triggers
interface WorkflowTrigger {
type: TriggerType;
params?: Record<string, unknown>;
}
type TriggerType =
| 'biomarker_result'
| 'schedule'
| 'manual'
| 'event';Example
triggers:
- type: biomarker_result
params:
biomarker: TSHSteps
interface WorkflowStep {
id: string;
type: StepType;
condition?: string;
action?: StepAction;
next?: string;
}Step types
type StepType =
| 'check_biomarker'
| 'recommend_supplement'
| 'order_lab'
| 'check_contraindication'
| 'send_notification'
| 'run_tool';Step fields
| Field | Type | Required | Notes |
|---|---|---|---|
id | string | Yes | Must be unique within the workflow |
type | StepType | Yes | Determines runtime handler |
condition | string | No | Safe expression language |
action | StepAction | No | Parameter bag for the handler |
next | string | No | Explicit jump target; must reference an existing step ID |
Actions
interface StepAction {
type: string;
params: Record<string, unknown>;
}Example
action:
type: recommend
params:
supplement: Selenium
dosage: 200mcgWorkflow context
interface WorkflowContext {
patientId: string;
data?: Record<string, unknown>;
tools?: string[];
}Context fields
| Field | Type | Required | Notes |
|---|---|---|---|
patientId | string | Yes | Primary workflow subject |
data | Record<string, unknown> | No | Patient and runtime context used by step handlers and conditions |
tools | string[] | No | Tool allowlist used by run_tool |
Example
const context = {
patientId: 'patient-42',
data: {
biomarker: { TSH: 4.2 },
medications: ['metformin'],
genetics: { MTHFR: 'C677T/C677T' },
},
tools: ['risk-calculator'],
};Condition language
Conditions are evaluated against:
context.data- previous step results exposed as
stepId.result - previous step success flags exposed as
stepId.success
Supported operators
| Category | Operators |
|---|---|
| Comparison | ===, !==, ==, !=, >, >=, <, <= |
| Logical | &&, ` |
Supported value styles
- numbers such as
42or2.5 - strings such as
'female' - booleans such as
true null- dot paths such as
biomarker.TSH
Examples
condition: "biomarker.TSH > 2.5"
condition: "age >= 40 && gender === 'female'"
condition: "check-tsh.result === true"
condition: "genetics.MTHFR === 'C677T/C677T'"Workflow result
interface StepResult {
stepId: string;
success: boolean;
result?: unknown;
error?: string;
}
interface Recommendation {
type: string;
details: Record<string, unknown>;
}
interface WorkflowError {
stepId: string;
code: string;
message: string;
}
interface WorkflowResult {
success: boolean;
workflowId: string;
executedSteps: string[];
stepResults: Record<string, StepResult>;
recommendations: Recommendation[];
errors: WorkflowError[];
}Example result
{
"success": true,
"workflowId": "thyroid-review-v1",
"executedSteps": ["check-tsh", "recommend-selenium"],
"stepResults": {
"check-tsh": {
"stepId": "check-tsh",
"success": true,
"result": {
"checked": true,
"biomarker": "TSH",
"value": 4.2,
"threshold": 2.5,
"operator": ">",
"result": true
}
}
},
"recommendations": [
{
"type": "supplement",
"details": {
"supplement": "Selenium",
"dosage": "200mcg"
}
}
],
"errors": []
}Built-in step handlers
| Step type | Behavior |
|---|---|
check_biomarker | Reads a biomarker from context.data and compares it to a threshold |
recommend_supplement | Appends a recommendation to the workflow state |
order_lab | Returns an order payload |
check_contraindication | Checks whether a named medication exists in context.data.medications |
send_notification | Returns a notification payload |
run_tool | Verifies tool availability and returns a stub execution payload |
Example: run_tool
- id: invoke-risk-tool
type: run_tool
action:
type: tool
params:
toolId: risk-calculator
scoreType: metabolicconst result = await workflow.execute({
patientId: 'patient-42',
tools: ['risk-calculator'],
});Validation rules
The engine rejects definitions that:
- omit
id,name, orversion - have zero steps
- use an invalid step type
- reuse a step ID
- set
nextto an unknown step
WorkflowEngine.load({
id: 'invalid',
name: 'Invalid',
version: '1.0.0',
steps: [],
});
// throws because at least one step is required