2.8 KiB
2.8 KiB
Orchestrator Advanced Flows — Design
Architecture
┌───────────── Step dispatch ─────────────────┐
│ │
│ Flow-runner resolves step: │
│ 1. Check trigger_rule on deps │
│ 2. Substitute $vars in prompt │
│ 3. If approval gate → pause for user │
│ 4. INSERT task row → dispatcher picks up │
│ 5. On terminal: append to event log │
│ 6. Advance next ready step │
│ │
└──────────────────────────────────────────────┘
Type Changes
apps/coder/src/conductor/types.ts
export type TriggerRule = 'all_success' | 'one_success' | 'all_done';
export interface Step {
id: string;
kind: StepKind | 'approval'; // + new kind
deps?: string[];
trigger_rule?: TriggerRule; // NEW: default 'all_success'
agent?: string;
run: (ctx: StepContext) => string | Promise<string>;
when?: (ctx: StepContext) => boolean;
}
apps/coder/src/services/flow-runner.ts
| Change | Detail |
|---|---|
| Trigger evaluation | Before dispatching a step, check deps statuses against trigger_rule. Skip if conditions not met |
| Variable substitution | Scan prompt for $word.word patterns, resolve from previous step outputs |
| Approval gate | When step.kind === 'approval', insert a tasks row with state='blocked' and publish a permission_requested WS frame. Wait for permission_resolved to unblock |
| Event log | Append-only per-step events: `{ step_id, event: 'started' |
Schema
CREATE TABLE IF NOT EXISTS flow_step_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
run_id UUID NOT NULL REFERENCES flow_runs(id),
step_id VARCHAR(64) NOT NULL,
event VARCHAR(32) NOT NULL, -- started, completed, failed, paused, resumed, skipped
payload JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp()
);
Resolution Order
- Collect all completed steps in the run
- For each unstarted step whose deps are met:
- Evaluate
trigger_ruleagainst dep statuses - If met → advance the step (with variable substitution)
- If not met → skip (for
one_success, mark it complete when any dep succeeds)
- Evaluate
- For approval gates: pause, publish frame, wait for user response
Rollback
All changes are additive to the Step type. Existing flows without trigger_rule default to all_success, preserving current behavior. Approval gates are opt-in per step definition.