71 lines
2.8 KiB
Markdown
71 lines
2.8 KiB
Markdown
# 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`
|
|
|
|
```typescript
|
|
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'|'completed'|'failed'|'paused'|'resumed', at: timestamp }` in `flow_step_events` table |
|
|
|
|
## Schema
|
|
|
|
```sql
|
|
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
|
|
|
|
1. Collect all completed steps in the run
|
|
2. For each unstarted step whose deps are met:
|
|
- Evaluate `trigger_rule` against dep statuses
|
|
- If met → advance the step (with variable substitution)
|
|
- If not met → skip (for `one_success`, mark it complete when any dep succeeds)
|
|
3. 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.
|