@relayflows/sdk 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authored-flow-error.d.ts +9 -0
- package/dist/authored-flow-error.d.ts.map +1 -0
- package/dist/authored-flow-error.js +13 -0
- package/dist/authored-flow-error.js.map +1 -0
- package/dist/authored-flow-executor.d.ts +28 -0
- package/dist/authored-flow-executor.d.ts.map +1 -0
- package/dist/authored-flow-executor.js +203 -0
- package/dist/authored-flow-executor.js.map +1 -0
- package/dist/authored-flow-lifecycle.d.ts +61 -0
- package/dist/authored-flow-lifecycle.d.ts.map +1 -0
- package/dist/authored-flow-lifecycle.js +284 -0
- package/dist/authored-flow-lifecycle.js.map +1 -0
- package/dist/authored-flow-loader.d.ts +7 -0
- package/dist/authored-flow-loader.d.ts.map +1 -0
- package/dist/authored-flow-loader.js +39 -0
- package/dist/authored-flow-loader.js.map +1 -0
- package/dist/authored-flow-operation.d.ts +43 -0
- package/dist/authored-flow-operation.d.ts.map +1 -0
- package/dist/authored-flow-operation.js +176 -0
- package/dist/authored-flow-operation.js.map +1 -0
- package/dist/authored-flow.d.ts +12 -0
- package/dist/authored-flow.d.ts.map +1 -0
- package/dist/authored-flow.js +13 -0
- package/dist/authored-flow.js.map +1 -0
- package/dist/authored-promise-graph.d.ts +67 -0
- package/dist/authored-promise-graph.d.ts.map +1 -0
- package/dist/authored-promise-graph.js +206 -0
- package/dist/authored-promise-graph.js.map +1 -0
- package/dist/backlog-picker.d.ts +55 -0
- package/dist/backlog-picker.d.ts.map +1 -0
- package/dist/backlog-picker.js +117 -0
- package/dist/backlog-picker.js.map +1 -0
- package/dist/canonical.d.ts +18 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +55 -0
- package/dist/canonical.js.map +1 -0
- package/dist/cli/check.d.ts +30 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +324 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/direct-run.d.ts +3 -0
- package/dist/cli/direct-run.d.ts.map +1 -0
- package/dist/cli/direct-run.js +69 -0
- package/dist/cli/direct-run.js.map +1 -0
- package/dist/cli/hn-monitor.d.ts +107 -0
- package/dist/cli/hn-monitor.d.ts.map +1 -0
- package/dist/cli/hn-monitor.js +220 -0
- package/dist/cli/hn-monitor.js.map +1 -0
- package/dist/cli/interruptible-sleep.d.ts +13 -0
- package/dist/cli/interruptible-sleep.d.ts.map +1 -0
- package/dist/cli/interruptible-sleep.js +31 -0
- package/dist/cli/interruptible-sleep.js.map +1 -0
- package/dist/cli/run.d.ts +54 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +316 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/tick-runner.d.ts +151 -0
- package/dist/cli/tick-runner.d.ts.map +1 -0
- package/dist/cli/tick-runner.js +258 -0
- package/dist/cli/tick-runner.js.map +1 -0
- package/dist/cli-adapter.d.ts +29 -0
- package/dist/cli-adapter.d.ts.map +1 -0
- package/dist/cli-adapter.js +92 -0
- package/dist/cli-adapter.js.map +1 -0
- package/dist/cli-executable.d.ts +3 -0
- package/dist/cli-executable.d.ts.map +1 -0
- package/dist/cli-executable.js +10 -0
- package/dist/cli-executable.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +348 -0
- package/dist/cli.js.map +1 -0
- package/dist/compile.d.ts +42 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +515 -0
- package/dist/compile.js.map +1 -0
- package/dist/demo-hn-monitor.d.ts +2 -0
- package/dist/demo-hn-monitor.d.ts.map +1 -0
- package/dist/demo-hn-monitor.js +118 -0
- package/dist/demo-hn-monitor.js.map +1 -0
- package/dist/dir-watcher-poller.d.ts +73 -0
- package/dist/dir-watcher-poller.d.ts.map +1 -0
- package/dist/dir-watcher-poller.js +80 -0
- package/dist/dir-watcher-poller.js.map +1 -0
- package/dist/direct-input.d.ts +10 -0
- package/dist/direct-input.d.ts.map +1 -0
- package/dist/direct-input.js +61 -0
- package/dist/direct-input.js.map +1 -0
- package/dist/failure-kinds.d.ts +25 -0
- package/dist/failure-kinds.d.ts.map +1 -0
- package/dist/failure-kinds.js +64 -0
- package/dist/failure-kinds.js.map +1 -0
- package/dist/gate-contract.d.ts +24 -0
- package/dist/gate-contract.d.ts.map +1 -0
- package/dist/gate-contract.js +50 -0
- package/dist/gate-contract.js.map +1 -0
- package/dist/hn-poller.d.ts +50 -0
- package/dist/hn-poller.d.ts.map +1 -0
- package/dist/hn-poller.js +79 -0
- package/dist/hn-poller.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/journal-client.d.ts +122 -0
- package/dist/journal-client.d.ts.map +1 -0
- package/dist/journal-client.js +277 -0
- package/dist/journal-client.js.map +1 -0
- package/dist/json-schema-bound.d.ts +7 -0
- package/dist/json-schema-bound.d.ts.map +1 -0
- package/dist/json-schema-bound.js +353 -0
- package/dist/json-schema-bound.js.map +1 -0
- package/dist/json-schema.d.ts +5 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +72 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/json-value.d.ts +6 -0
- package/dist/json-value.d.ts.map +1 -0
- package/dist/json-value.js +94 -0
- package/dist/json-value.js.map +1 -0
- package/dist/model-name.d.ts +7 -0
- package/dist/model-name.d.ts.map +1 -0
- package/dist/model-name.js +21 -0
- package/dist/model-name.js.map +1 -0
- package/dist/output-schema.d.ts +8 -0
- package/dist/output-schema.d.ts.map +1 -0
- package/dist/output-schema.js +28 -0
- package/dist/output-schema.js.map +1 -0
- package/dist/preflight.d.ts +80 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +361 -0
- package/dist/preflight.js.map +1 -0
- package/dist/protocol.d.ts +359 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +15 -0
- package/dist/protocol.js.map +1 -0
- package/dist/spec.d.ts +294 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +13 -0
- package/dist/spec.js.map +1 -0
- package/dist/step-dependencies.d.ts +2 -0
- package/dist/step-dependencies.d.ts.map +1 -0
- package/dist/step-dependencies.js +88 -0
- package/dist/step-dependencies.js.map +1 -0
- package/dist/step-fields.d.ts +17 -0
- package/dist/step-fields.d.ts.map +1 -0
- package/dist/step-fields.js +32 -0
- package/dist/step-fields.js.map +1 -0
- package/dist/tick-source.d.ts +205 -0
- package/dist/tick-source.d.ts.map +1 -0
- package/dist/tick-source.js +234 -0
- package/dist/tick-source.js.map +1 -0
- package/dist/unknown-keys.d.ts +7 -0
- package/dist/unknown-keys.d.ts.map +1 -0
- package/dist/unknown-keys.js +47 -0
- package/dist/unknown-keys.js.map +1 -0
- package/dist/validate.d.ts +7 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +458 -0
- package/dist/validate.js.map +1 -0
- package/dist/work-package-consumer.d.ts +33 -0
- package/dist/work-package-consumer.d.ts.map +1 -0
- package/dist/work-package-consumer.js +44 -0
- package/dist/work-package-consumer.js.map +1 -0
- package/dist/work-package-validator.d.ts +15 -0
- package/dist/work-package-validator.d.ts.map +1 -0
- package/dist/work-package-validator.js +72 -0
- package/dist/work-package-validator.js.map +1 -0
- package/dist/worker-cli.d.ts +16 -0
- package/dist/worker-cli.d.ts.map +1 -0
- package/dist/worker-cli.js +77 -0
- package/dist/worker-cli.js.map +1 -0
- package/dist/worker.d.ts +57 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +129 -0
- package/dist/worker.js.map +1 -0
- package/dist/wrapper-runtime.d.ts +10 -0
- package/dist/wrapper-runtime.d.ts.map +1 -0
- package/dist/wrapper-runtime.js +83 -0
- package/dist/wrapper-runtime.js.map +1 -0
- package/dist/wrapper-session.d.ts +16 -0
- package/dist/wrapper-session.d.ts.map +1 -0
- package/dist/wrapper-session.js +244 -0
- package/dist/wrapper-session.js.map +1 -0
- package/package.json +50 -0
- package/src/authored-flow-error.ts +31 -0
- package/src/authored-flow-executor.ts +365 -0
- package/src/authored-flow-lifecycle.ts +344 -0
- package/src/authored-flow-loader.ts +44 -0
- package/src/authored-flow-operation.ts +252 -0
- package/src/authored-flow.ts +21 -0
- package/src/authored-promise-graph.ts +196 -0
- package/src/backlog-picker.ts +153 -0
- package/src/canonical.ts +57 -0
- package/src/cli/check.ts +391 -0
- package/src/cli/direct-run.ts +86 -0
- package/src/cli/hn-monitor.ts +286 -0
- package/src/cli/interruptible-sleep.ts +27 -0
- package/src/cli/run.ts +439 -0
- package/src/cli/tick-runner.ts +378 -0
- package/src/cli-adapter.ts +115 -0
- package/src/cli-executable.ts +12 -0
- package/src/cli.ts +364 -0
- package/src/compile.ts +573 -0
- package/src/demo-hn-monitor.ts +132 -0
- package/src/dir-watcher-poller.ts +122 -0
- package/src/direct-input.ts +69 -0
- package/src/failure-kinds.ts +77 -0
- package/src/gate-contract.ts +72 -0
- package/src/hn-poller.ts +104 -0
- package/src/index.ts +195 -0
- package/src/journal-client.ts +379 -0
- package/src/json-schema-bound.ts +357 -0
- package/src/json-schema.ts +65 -0
- package/src/json-value.ts +110 -0
- package/src/model-name.ts +20 -0
- package/src/output-schema.ts +33 -0
- package/src/preflight.ts +482 -0
- package/src/protocol.ts +364 -0
- package/src/spec.ts +343 -0
- package/src/step-dependencies.ts +100 -0
- package/src/step-fields.ts +36 -0
- package/src/tick-source.ts +334 -0
- package/src/unknown-keys.ts +52 -0
- package/src/validate.ts +503 -0
- package/src/work-package-consumer.ts +73 -0
- package/src/work-package-validator.ts +90 -0
- package/src/worker-cli.ts +110 -0
- package/src/worker.ts +150 -0
- package/src/wrapper-runtime.ts +93 -0
- package/src/wrapper-session.ts +287 -0
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
// Journal protocol v0 — the SDK boundary (kernel DESIGN.md §5).
|
|
2
|
+
//
|
|
3
|
+
// Transport: newline-delimited JSON over a unix socket at
|
|
4
|
+
// `<data-dir>/relayflowd.sock`. Requests `{id, verb, params}`; responses
|
|
5
|
+
// `{id, ok: true, result}` or `{id, ok: false, error: {code, message}}`;
|
|
6
|
+
// server-pushed events `{event, data}` (no `id`). Any verb whose journal
|
|
7
|
+
// append fails returns `error{code: "journal_write_failed"}` and the affected
|
|
8
|
+
// step fails — the protocol is fail-closed like everything behind it.
|
|
9
|
+
//
|
|
10
|
+
// This module is the typed wire surface; `journal-client.ts` implements it.
|
|
11
|
+
|
|
12
|
+
import type { KernelRunSpec, StepType } from './spec.js';
|
|
13
|
+
|
|
14
|
+
/** Stamped per segment; readers read every past version, writers write newest. */
|
|
15
|
+
export const PROTOCOL_VERSION = 0 as const;
|
|
16
|
+
|
|
17
|
+
/** A journal append that fails fails the step (AGENTS.md rule 4). */
|
|
18
|
+
export const JOURNAL_WRITE_FAILED = 'journal_write_failed' as const;
|
|
19
|
+
|
|
20
|
+
export type ProtocolError = { code: string; message: string };
|
|
21
|
+
|
|
22
|
+
/** Client -> server. */
|
|
23
|
+
export interface Request<P = unknown> {
|
|
24
|
+
id: string;
|
|
25
|
+
verb: string;
|
|
26
|
+
params: P;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Server -> client response, correlated by `id`. */
|
|
30
|
+
export type Response<R = unknown> =
|
|
31
|
+
| { id: string; ok: true; result: R }
|
|
32
|
+
| { id: string; ok: false; error: ProtocolError };
|
|
33
|
+
|
|
34
|
+
/** Server -> client push (no `id`). */
|
|
35
|
+
export interface ServerEvent {
|
|
36
|
+
event: string;
|
|
37
|
+
data: unknown;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// --- Verb set (gate 1 minimal) ---------------------------------------------
|
|
41
|
+
// Verb names mirror kernel DESIGN.md §5 verbatim.
|
|
42
|
+
|
|
43
|
+
export type Verb =
|
|
44
|
+
| 'hello'
|
|
45
|
+
| 'run.start'
|
|
46
|
+
| 'run.resume'
|
|
47
|
+
| 'run.cancel'
|
|
48
|
+
| 'run.get'
|
|
49
|
+
| 'run.watch'
|
|
50
|
+
| 'worker.attach'
|
|
51
|
+
| 'step.heartbeat'
|
|
52
|
+
| 'effect.record'
|
|
53
|
+
| 'effect.confirm'
|
|
54
|
+
| 'step.complete'
|
|
55
|
+
| 'event.emit'
|
|
56
|
+
| 'event.submit'
|
|
57
|
+
| 'stream.append'
|
|
58
|
+
| 'stream.read'
|
|
59
|
+
| 'journal.read';
|
|
60
|
+
|
|
61
|
+
// --- Typed params / results -------------------------------------------------
|
|
62
|
+
|
|
63
|
+
export interface HelloParams {
|
|
64
|
+
protocol: 0;
|
|
65
|
+
client: string;
|
|
66
|
+
}
|
|
67
|
+
export interface HelloResult {
|
|
68
|
+
protocol: 0;
|
|
69
|
+
server: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface RunStartParams {
|
|
73
|
+
/**
|
|
74
|
+
* The kernel spec dialect — the ONE boundary shape `RunSpec::parse`
|
|
75
|
+
* accepts (snake_case, flat v0 verification, defaults materialized).
|
|
76
|
+
* The authoring `FlowSpec` never crosses the wire; `JournalClient.runStart`
|
|
77
|
+
* converts via `toKernelSpec`.
|
|
78
|
+
*/
|
|
79
|
+
spec: KernelRunSpec;
|
|
80
|
+
}
|
|
81
|
+
export type RunStatus = 'running' | 'completed' | 'failed' | 'interrupted' | 'parked';
|
|
82
|
+
export type RunCompletionReason = 'success' | 'step_failed' | 'canceled' | 'budget_exceeded';
|
|
83
|
+
|
|
84
|
+
export interface RunOutcome {
|
|
85
|
+
run_id: string;
|
|
86
|
+
status: RunStatus;
|
|
87
|
+
completion_reason: RunCompletionReason | null;
|
|
88
|
+
completed_steps: number;
|
|
89
|
+
}
|
|
90
|
+
export type RunStartResult = RunOutcome;
|
|
91
|
+
|
|
92
|
+
export interface RunResumeParams {
|
|
93
|
+
run_id: string;
|
|
94
|
+
}
|
|
95
|
+
export type RunResumeResult = RunOutcome;
|
|
96
|
+
|
|
97
|
+
export interface RunCancelParams {
|
|
98
|
+
run_id: string;
|
|
99
|
+
}
|
|
100
|
+
export type RunCancelResult = RunOutcome;
|
|
101
|
+
|
|
102
|
+
export interface RunGetParams {
|
|
103
|
+
run_id: string;
|
|
104
|
+
}
|
|
105
|
+
export type StepStatus =
|
|
106
|
+
| 'pending'
|
|
107
|
+
| 'runnable'
|
|
108
|
+
| 'running'
|
|
109
|
+
| 'backoff'
|
|
110
|
+
| 'waiting'
|
|
111
|
+
| 'needs_human'
|
|
112
|
+
| 'done';
|
|
113
|
+
export interface StepSnapshot {
|
|
114
|
+
type: StepType;
|
|
115
|
+
state: StepStatus;
|
|
116
|
+
lease_deadline_ms?: number;
|
|
117
|
+
}
|
|
118
|
+
export interface RunGetResult {
|
|
119
|
+
run_id: string;
|
|
120
|
+
status: RunStatus;
|
|
121
|
+
steps: Record<string, StepSnapshot>;
|
|
122
|
+
budget: { tokens_in: number; tokens_out: number; dollars: string };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface RunWatchParams {
|
|
126
|
+
run_id: string;
|
|
127
|
+
}
|
|
128
|
+
export interface RunWatchResult {
|
|
129
|
+
watching: string;
|
|
130
|
+
}
|
|
131
|
+
/** `run.watch` opens a push stream of `{event: "entry", data: Entry}`. */
|
|
132
|
+
|
|
133
|
+
export interface WorkerAttachParams {
|
|
134
|
+
worker_id: string;
|
|
135
|
+
step_types: StepType[];
|
|
136
|
+
/** Maximum concurrent assignments. Omitted means the conservative default 1. */
|
|
137
|
+
capacity?: number;
|
|
138
|
+
/**
|
|
139
|
+
* The surfaces this worker holds, as opaque revisions/offsets. Required when
|
|
140
|
+
* `step_types` includes `agent` — an agent attempt's start pins come from
|
|
141
|
+
* here (Appendix A rule 2), so an agent worker with no pins is refused at
|
|
142
|
+
* attach rather than failing in the middle of a run.
|
|
143
|
+
*/
|
|
144
|
+
pins?: Pins;
|
|
145
|
+
}
|
|
146
|
+
export interface WorkerAttachResult {
|
|
147
|
+
worker_id: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Wake-context payload assembled kernel-side at `subscription.matched`.
|
|
151
|
+
* The two fields typed below are the ones every current consumer keys
|
|
152
|
+
* against; additional kernel-side fields flow through as extra
|
|
153
|
+
* properties without breaking this type.
|
|
154
|
+
*/
|
|
155
|
+
export interface WakeContext {
|
|
156
|
+
triggering_event?: {
|
|
157
|
+
type: string;
|
|
158
|
+
payload?: unknown;
|
|
159
|
+
};
|
|
160
|
+
epoch_summary?: {
|
|
161
|
+
open_steps?: string[];
|
|
162
|
+
};
|
|
163
|
+
[additionalKernelFields: string]: unknown;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Server then pushes `step.dispatch` events to the attached worker. */
|
|
167
|
+
export interface StepDispatchEvent {
|
|
168
|
+
run_id: string;
|
|
169
|
+
step_id: string;
|
|
170
|
+
attempt: number;
|
|
171
|
+
step_type: StepType;
|
|
172
|
+
spec: unknown;
|
|
173
|
+
lease_id: string;
|
|
174
|
+
idempotency_key: string;
|
|
175
|
+
pins: Pins;
|
|
176
|
+
/**
|
|
177
|
+
* The `wake_context` payload from the run's `subscription.matched`
|
|
178
|
+
* journal entry — carries the triggering event and any epoch summary
|
|
179
|
+
* the flow needs to know why this step is running. Present when the
|
|
180
|
+
* run was spawned by an event; `undefined` for runs started directly
|
|
181
|
+
* (no trigger fired). A real agent needs this to see the event
|
|
182
|
+
* payload (e.g. the HN story ID).
|
|
183
|
+
*
|
|
184
|
+
* Shape is assembled kernel-side in
|
|
185
|
+
* `kernel/relayflowd/src/engine/wake.rs` (grep for
|
|
186
|
+
* `wake_context` — the Rust field is written with quoted
|
|
187
|
+
* JSON keys so `"wake_context":` hits the assembly site
|
|
188
|
+
* directly). The narrow type below pins the two fields
|
|
189
|
+
* every consumer currently reads —
|
|
190
|
+
* `triggering_event.type`/`payload` and `epoch_summary` — while
|
|
191
|
+
* keeping the container `unknown`-permissive so a kernel-side
|
|
192
|
+
* addition (a new nested field) does not break the SDK type. A
|
|
193
|
+
* kernel-side RENAME of these two fields does break every
|
|
194
|
+
* consumer; that is deliberate and preferable to silent drift.
|
|
195
|
+
*/
|
|
196
|
+
wake_context?: WakeContext;
|
|
197
|
+
recovery?: {
|
|
198
|
+
mode: 'reset' | 'inspect' | 'manual';
|
|
199
|
+
restore_pins?: Pins;
|
|
200
|
+
previous_completion_reason?: CompletionReason;
|
|
201
|
+
trajectory_tail?: unknown;
|
|
202
|
+
};
|
|
203
|
+
lease_deadline_ms: number;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface StepHeartbeatParams {
|
|
207
|
+
run_id: string;
|
|
208
|
+
step_id: string;
|
|
209
|
+
attempt: number;
|
|
210
|
+
lease_id: string;
|
|
211
|
+
}
|
|
212
|
+
export interface StepHeartbeatResult {
|
|
213
|
+
lease_deadline_ms: number;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** completionReason mirrors kernel DESIGN.md §1.3. */
|
|
217
|
+
export type CompletionReason =
|
|
218
|
+
| 'success'
|
|
219
|
+
| 'verification_failed'
|
|
220
|
+
| 'retries_exhausted'
|
|
221
|
+
| 'lease_expired'
|
|
222
|
+
| 'crashed'
|
|
223
|
+
| 'timeout'
|
|
224
|
+
| 'worker_error'
|
|
225
|
+
| 'budget_exceeded'
|
|
226
|
+
| 'canceled';
|
|
227
|
+
|
|
228
|
+
export interface Pins {
|
|
229
|
+
workspace?: { surface: string; revision_id: string }[];
|
|
230
|
+
streams?: { stream: string; read_offset: number }[];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface EffectRef {
|
|
234
|
+
surface_path: string;
|
|
235
|
+
idempotency_key: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface EffectRecordParams {
|
|
239
|
+
run_id: string;
|
|
240
|
+
step_id: string;
|
|
241
|
+
attempt: number;
|
|
242
|
+
idempotency_key: string;
|
|
243
|
+
surface_path: string;
|
|
244
|
+
revision_before: string;
|
|
245
|
+
revision_after: string;
|
|
246
|
+
}
|
|
247
|
+
export interface EffectRecordResult {
|
|
248
|
+
/**
|
|
249
|
+
* True only when a *confirmed* election already covers this
|
|
250
|
+
* `(step_id, idempotency_key, surface_path)`: the writeback provably
|
|
251
|
+
* happened, so this attempt must not call the provider. An election that was
|
|
252
|
+
* never confirmed does not dedupe — this attempt reclaims it and owes the
|
|
253
|
+
* call, which is what keeps an effect from being lost to a worker that died
|
|
254
|
+
* between recording and performing.
|
|
255
|
+
*/
|
|
256
|
+
deduped: boolean;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Phase two: the elected attempt performed the writeback. */
|
|
260
|
+
export interface EffectConfirmParams {
|
|
261
|
+
run_id: string;
|
|
262
|
+
step_id: string;
|
|
263
|
+
attempt: number;
|
|
264
|
+
idempotency_key: string;
|
|
265
|
+
surface_path: string;
|
|
266
|
+
}
|
|
267
|
+
export interface EffectConfirmResult {
|
|
268
|
+
confirmed: string;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface StepCompleteParams {
|
|
272
|
+
run_id: string;
|
|
273
|
+
step_id: string;
|
|
274
|
+
attempt: number;
|
|
275
|
+
idempotency_key: string;
|
|
276
|
+
completionReason: CompletionReason;
|
|
277
|
+
output?: unknown;
|
|
278
|
+
usage?: { tokens_in: number; tokens_out: number; dollars: string };
|
|
279
|
+
started_pins?: Pins;
|
|
280
|
+
end_pins?: Pins;
|
|
281
|
+
effects?: EffectRef[];
|
|
282
|
+
/** `inspect` evidence for the next attempt. Rejected over 16 KiB of JSON. */
|
|
283
|
+
trajectory_tail?: unknown;
|
|
284
|
+
}
|
|
285
|
+
export type StepCompleteResult = RunOutcome;
|
|
286
|
+
|
|
287
|
+
export interface EventEmitParams {
|
|
288
|
+
run_id: string;
|
|
289
|
+
event_key: string;
|
|
290
|
+
payload: unknown;
|
|
291
|
+
}
|
|
292
|
+
export interface EventEmitResult {
|
|
293
|
+
matched: number;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Submit an external event to a flow that declares an event trigger. The
|
|
298
|
+
* kernel matches it against the spec's subscriptions and, on a first match,
|
|
299
|
+
* spawns a run; a repeat of the same (flow, subscription, key) is deduped.
|
|
300
|
+
*/
|
|
301
|
+
export interface EventSubmitParams {
|
|
302
|
+
spec: unknown;
|
|
303
|
+
event: {
|
|
304
|
+
type: string;
|
|
305
|
+
payload?: unknown;
|
|
306
|
+
/** Overrides the subscription's dedupeKeyTemplate when supplied. */
|
|
307
|
+
key?: string;
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
export interface EventSubmitResult {
|
|
311
|
+
matched: boolean;
|
|
312
|
+
deduped: boolean;
|
|
313
|
+
subscription_id?: string | null;
|
|
314
|
+
run?: unknown;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export interface StreamAppendParams {
|
|
318
|
+
run_id: string;
|
|
319
|
+
stream: string;
|
|
320
|
+
message: unknown;
|
|
321
|
+
}
|
|
322
|
+
export interface StreamAppendResult {
|
|
323
|
+
offset: number;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface StreamReadParams {
|
|
327
|
+
run_id: string;
|
|
328
|
+
stream: string;
|
|
329
|
+
from_offset: number;
|
|
330
|
+
limit?: number;
|
|
331
|
+
}
|
|
332
|
+
export interface StreamReadResult {
|
|
333
|
+
messages: unknown[];
|
|
334
|
+
next_offset: number;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export interface JournalReadParams {
|
|
338
|
+
run_id: string;
|
|
339
|
+
from_seq: number;
|
|
340
|
+
limit?: number;
|
|
341
|
+
}
|
|
342
|
+
export interface JournalReadResult {
|
|
343
|
+
entries: unknown[];
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Typed map of verb -> { params, result }. Used by the client for type-safety. */
|
|
347
|
+
export interface VerbContract {
|
|
348
|
+
hello: { params: HelloParams; result: HelloResult };
|
|
349
|
+
'run.start': { params: RunStartParams; result: RunStartResult };
|
|
350
|
+
'run.resume': { params: RunResumeParams; result: RunResumeResult };
|
|
351
|
+
'run.cancel': { params: RunCancelParams; result: RunCancelResult };
|
|
352
|
+
'run.get': { params: RunGetParams; result: RunGetResult };
|
|
353
|
+
'run.watch': { params: RunWatchParams; result: RunWatchResult };
|
|
354
|
+
'worker.attach': { params: WorkerAttachParams; result: WorkerAttachResult };
|
|
355
|
+
'step.heartbeat': { params: StepHeartbeatParams; result: StepHeartbeatResult };
|
|
356
|
+
'effect.record': { params: EffectRecordParams; result: EffectRecordResult };
|
|
357
|
+
'effect.confirm': { params: EffectConfirmParams; result: EffectConfirmResult };
|
|
358
|
+
'step.complete': { params: StepCompleteParams; result: StepCompleteResult };
|
|
359
|
+
'event.emit': { params: EventEmitParams; result: EventEmitResult };
|
|
360
|
+
'event.submit': { params: EventSubmitParams; result: EventSubmitResult };
|
|
361
|
+
'stream.append': { params: StreamAppendParams; result: StreamAppendResult };
|
|
362
|
+
'stream.read': { params: StreamReadParams; result: StreamReadResult };
|
|
363
|
+
'journal.read': { params: JournalReadParams; result: JournalReadResult };
|
|
364
|
+
}
|
package/src/spec.ts
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
// Spec types for Relayflows — data, not code (RFC-0001 settled decision #5).
|
|
2
|
+
//
|
|
3
|
+
// Mirrors RFC-0001 §1's ladder. Every rung is a legal relayflow:
|
|
4
|
+
// deterministic step # a pure script — no LLM anywhere (legal)
|
|
5
|
+
// + llm step # a bare model call — prompt in, verified output out
|
|
6
|
+
// + agent step # a harnessed agent in a workspace — artifact + diff + trajectory
|
|
7
|
+
//
|
|
8
|
+
// Step types are exactly `deterministic | llm | agent` (AGENTS.md rule 7).
|
|
9
|
+
// Zero-agent flows are legal: a spec with only `deterministic` (and/or `llm`)
|
|
10
|
+
// steps is valid. Nothing here requires an `agent` step.
|
|
11
|
+
|
|
12
|
+
import type { JsonOutputSchema } from './output-schema.js';
|
|
13
|
+
export type { JsonOutputSchema } from './output-schema.js';
|
|
14
|
+
|
|
15
|
+
/** The three rungs of the ladder (RFC §1; AGENTS.md rule 7). */
|
|
16
|
+
export type StepType = 'deterministic' | 'llm' | 'agent';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Verification is control flow, not decoration (kernel DESIGN.md §3).
|
|
20
|
+
* v0 gates are deterministic so verification is kernel-side and replayable.
|
|
21
|
+
*/
|
|
22
|
+
export type VerificationGateType = 'exit_code' | 'output_contains' | 'json_schema';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* `exit_code == 0` — the implicit gate for deterministic steps. v0 judges
|
|
26
|
+
* exactly zero (kernel DESIGN.md §4); it is not configurable, so this gate
|
|
27
|
+
* carries no parameters. Writing it explicitly is allowed and compiles to the
|
|
28
|
+
* same kernel spec as omitting it.
|
|
29
|
+
*/
|
|
30
|
+
export interface ExitCodeGate {
|
|
31
|
+
type: 'exit_code';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Step output (stdout_tail / llm value, stringified) contains `value`. */
|
|
35
|
+
export interface OutputContainsGate {
|
|
36
|
+
type: 'output_contains';
|
|
37
|
+
value: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Step output validates against a JSON Schema. Used for `llm` structured output. */
|
|
41
|
+
export interface JsonSchemaGate {
|
|
42
|
+
type: 'json_schema';
|
|
43
|
+
schema: boolean | Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type VerificationSpec = ExitCodeGate | OutputContainsGate | JsonSchemaGate;
|
|
47
|
+
export type OutputVerificationSpec = OutputContainsGate | JsonSchemaGate;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Agent-step recovery modes (RFC Appendix A rule 4). Default is `reset`.
|
|
51
|
+
* `deterministic` / `llm` steps have no workspace, so these do not apply.
|
|
52
|
+
*/
|
|
53
|
+
export type RecoveryMode = 'reset' | 'inspect' | 'manual';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Declared mutable surfaces for an agent step (RFC Appendix A rule 1).
|
|
57
|
+
* Anything undeclared is outside the contract and outside the step's
|
|
58
|
+
* permissions (gate 8 makes this enforceable, not advisory).
|
|
59
|
+
*/
|
|
60
|
+
export interface WorkspaceSurface {
|
|
61
|
+
/** Relayfile mount path, or a named worktree. */
|
|
62
|
+
surface: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface StreamSurface {
|
|
66
|
+
/** Durable channel the agent may write (kernel DESIGN.md §1.8). */
|
|
67
|
+
stream: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface AgentSurfaces {
|
|
71
|
+
workspace?: WorkspaceSurface[];
|
|
72
|
+
streams?: StreamSurface[];
|
|
73
|
+
/** Integration writeback paths — mount writes per gate 6. */
|
|
74
|
+
external?: string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Permission model for an agent step (gate 8). `readonly` provably cannot write. */
|
|
78
|
+
export interface PermissionsSpec {
|
|
79
|
+
fileGlobs?: string[];
|
|
80
|
+
networkAllowlist?: string[];
|
|
81
|
+
accessPreset?: 'readonly' | 'readwrite';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Budget envelope. Per decision #10 every token has exactly one owner: an
|
|
86
|
+
* injected context pack spends the consuming step's budget. Money is a decimal
|
|
87
|
+
* string at the boundary (kernel DESIGN.md §1: no floats for money); tokens
|
|
88
|
+
* are integers.
|
|
89
|
+
*/
|
|
90
|
+
export interface BudgetSpec {
|
|
91
|
+
maxTokensIn?: number;
|
|
92
|
+
maxTokensOut?: number;
|
|
93
|
+
/** Decimal string, e.g. "1.50". */
|
|
94
|
+
maxDollars?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Fields shared by every step on the ladder. */
|
|
98
|
+
export interface BaseStepSpec {
|
|
99
|
+
/** Stable step identity; journaled as `step_id` and hashed into the idempotency key. */
|
|
100
|
+
id: string;
|
|
101
|
+
type: StepType;
|
|
102
|
+
/** Step dependencies — a step runs only after these complete. */
|
|
103
|
+
dependsOn?: string[];
|
|
104
|
+
/** Semantic retry bound (kernel DESIGN.md §1.2 `max_iterations`). Default 1. */
|
|
105
|
+
maxIterations?: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Rung 1 — a pure script. Executed by the `relayflowd` binary: spawn command,
|
|
110
|
+
* capture stdout/exit code. Output = `{exit_code, stdout_tail}`. Gate-1
|
|
111
|
+
* deterministic steps are pure (no pins).
|
|
112
|
+
*/
|
|
113
|
+
export interface DeterministicStepSpec extends BaseStepSpec {
|
|
114
|
+
type: 'deterministic';
|
|
115
|
+
command: string;
|
|
116
|
+
/** Wall-clock command timeout; worker-backed verbs own their dispatch timeout. */
|
|
117
|
+
timeoutMs?: number;
|
|
118
|
+
/** Omit to get the implicit `exit_code` gate. */
|
|
119
|
+
verification?: VerificationSpec;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Rung 2 — a bare model call. No workspace, output is a value. The kernel
|
|
124
|
+
* never calls a model: it dispatches to an attached SDK worker (§5) which
|
|
125
|
+
* returns `{output, usage}`; the kernel then runs the verification gate.
|
|
126
|
+
*/
|
|
127
|
+
export interface LlmStepSpec extends BaseStepSpec {
|
|
128
|
+
type: 'llm';
|
|
129
|
+
prompt: string;
|
|
130
|
+
verification?: OutputVerificationSpec;
|
|
131
|
+
model?: string;
|
|
132
|
+
/** Inert preflight declaration; overrides the flow/project CLI default. */
|
|
133
|
+
cli?: string;
|
|
134
|
+
/**
|
|
135
|
+
* Structured-output authoring sugar. Compiles to the existing `json_schema`
|
|
136
|
+
* verification primitive and is removed before the kernel boundary.
|
|
137
|
+
*/
|
|
138
|
+
output?: JsonOutputSchema;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Rung 3 — a harnessed agent in a workspace. Dispatched like `llm`, plus
|
|
143
|
+
* Appendix A in full: pins declared workspace revisions and stream offsets;
|
|
144
|
+
* every writeback is a journaled `effect.recorded` deduped by
|
|
145
|
+
* `(step_id, idempotency_key, surface_path)`.
|
|
146
|
+
*/
|
|
147
|
+
export interface AgentStepSpec extends BaseStepSpec {
|
|
148
|
+
type: 'agent';
|
|
149
|
+
instruction: string;
|
|
150
|
+
verification?: OutputVerificationSpec;
|
|
151
|
+
/** Named authoring declaration selected from `FlowSpec.agents`. Compiled away. */
|
|
152
|
+
agent?: string;
|
|
153
|
+
/** Inert preflight declaration; overrides the flow/project CLI default. */
|
|
154
|
+
cli?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Model the declared CLI must use. Raw Claude/Codex adapters receive their
|
|
157
|
+
* real model flag; an identified Relayflows wrapper receives it in its
|
|
158
|
+
* same-process execution request. Declared here so the choice is journaled with the step
|
|
159
|
+
* instead of being ambient host state.
|
|
160
|
+
*/
|
|
161
|
+
model?: string;
|
|
162
|
+
surfaces?: AgentSurfaces;
|
|
163
|
+
recoveryMode?: RecoveryMode;
|
|
164
|
+
permissions?: PermissionsSpec;
|
|
165
|
+
/**
|
|
166
|
+
* Structured-output authoring sugar. A successful CLI JSON object is the parsed
|
|
167
|
+
* value; the kernel persists it only after `json_schema` verification.
|
|
168
|
+
*/
|
|
169
|
+
output?: JsonOutputSchema;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export type StepSpec = DeterministicStepSpec | LlmStepSpec | AgentStepSpec;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Reusable authoring declaration for an agent CLI/model pair. Both fields are
|
|
176
|
+
* required so selecting a named agent can never inherit a host model. The
|
|
177
|
+
* compiler lowers these values into the selected kernel agent step at the
|
|
178
|
+
* journal boundary; the kernel never receives this map or a new step field.
|
|
179
|
+
*/
|
|
180
|
+
export interface NamedAgentSpec {
|
|
181
|
+
cli: string;
|
|
182
|
+
model: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* A trigger is an entry condition, not a scheduler (RFC-0001 gate 2). It names
|
|
187
|
+
* the event type that wakes the flow, the payload subset that must match, the
|
|
188
|
+
* template that derives the dedupe key, and the silence budget after which the
|
|
189
|
+
* kernel's liveness sweep declares the subscription dead.
|
|
190
|
+
*
|
|
191
|
+
* The event-subscription fields were shipped in `testdata/` long before this
|
|
192
|
+
* interface described them: `hn-monitor.flow.yaml`, `dir-watcher.flow.yaml`
|
|
193
|
+
* and `event-triggered-flow.yaml` all carry `eventType`, `pattern` and
|
|
194
|
+
* `dedupeKeyTemplate`, and `validate.ts` has always accepted them. The type
|
|
195
|
+
* still said "inert gate-1 declaration" with only `id` and `executor`, so the
|
|
196
|
+
* authoring dialect disagreed with both the shipped specs and the kernel.
|
|
197
|
+
*/
|
|
198
|
+
export interface TriggerSpec {
|
|
199
|
+
id: string;
|
|
200
|
+
/** Executor registration required before this trigger may start a run. */
|
|
201
|
+
executor: string;
|
|
202
|
+
/** Event type this trigger subscribes to. Lowers to `event_type`. */
|
|
203
|
+
eventType?: string;
|
|
204
|
+
/** Recursive-subset match against the event payload. Lowers to `pattern`. */
|
|
205
|
+
pattern?: Record<string, unknown>;
|
|
206
|
+
/** Derives the dedupe key. Lowers to `dedupe_key_template`. */
|
|
207
|
+
dedupeKeyTemplate?: string;
|
|
208
|
+
/**
|
|
209
|
+
* Silence budget in milliseconds. When no matching event arrives inside it,
|
|
210
|
+
* the kernel's liveness sweep journals `subscription.stale` and emits a
|
|
211
|
+
* `relayflowd: subscription.stale ...` line
|
|
212
|
+
* (`kernel/relayflowd/src/server/liveness.rs`). Omitted means the engine
|
|
213
|
+
* default (`DEFAULT_STALE_AFTER_MS`, 5 minutes) applies — which is a
|
|
214
|
+
* decision the author did not make, not the absence of a budget.
|
|
215
|
+
*
|
|
216
|
+
* A flow that is never triggered is silently zero (RFC-0001 §"Trigger
|
|
217
|
+
* liveness"), so declaring this is how a schedule stops being able to die
|
|
218
|
+
* quietly. Lowers to `stale_after_ms`.
|
|
219
|
+
*/
|
|
220
|
+
staleAfterMs?: number;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* A Relayflow spec in the authoring shape — the composable unit (RFC settled
|
|
225
|
+
* decision #5). Schema-validated, diffable, signable (gate 8), and emittable
|
|
226
|
+
* by a step (gate 9 self-authoring). What the kernel inlines in `run.spawned`
|
|
227
|
+
* is this spec mapped to the kernel dialect (`toKernelSpec`).
|
|
228
|
+
*/
|
|
229
|
+
export interface FlowSpec {
|
|
230
|
+
/** Spec schema semver (RFC §7). Compilers always emit latest. */
|
|
231
|
+
version: string;
|
|
232
|
+
name?: string;
|
|
233
|
+
description?: string;
|
|
234
|
+
/** Inert preflight default for llm/agent steps that do not declare a CLI. */
|
|
235
|
+
cli?: string;
|
|
236
|
+
/** Named authoring declarations. Compiled into agent steps, never journaled as a new primitive. */
|
|
237
|
+
agents?: Record<string, NamedAgentSpec>;
|
|
238
|
+
/** Declarations checked by preflight; gate 1 never dispatches them. */
|
|
239
|
+
triggers?: TriggerSpec[];
|
|
240
|
+
steps: StepSpec[];
|
|
241
|
+
budget?: BudgetSpec;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** Current spec schema version emitted by this SDK. */
|
|
245
|
+
export const SPEC_SCHEMA_VERSION = '0.1.0';
|
|
246
|
+
|
|
247
|
+
// --- The kernel dialect ------------------------------------------------------
|
|
248
|
+
//
|
|
249
|
+
// The authoring types above are TypeScript-idiomatic (camelCase, tagged
|
|
250
|
+
// verification sugar). The *boundary artifact* is singular: the kernel's spec
|
|
251
|
+
// dialect — snake_case keys, semver `version`, flat v0 verification, defaults
|
|
252
|
+
// materialized. `toKernelSpec` (compile.ts) maps authoring → kernel; parity
|
|
253
|
+
// with `kernel/relayflowd-core/src/spec.rs` is pinned bit-for-bit by
|
|
254
|
+
// `tests/spec-parity.test.ts` and the kernel's `tests/spec_parity.rs` over the
|
|
255
|
+
// shared `testdata/` fixture.
|
|
256
|
+
|
|
257
|
+
export interface KernelRetryPolicy {
|
|
258
|
+
initial_backoff_ms: number;
|
|
259
|
+
max_backoff_ms: number;
|
|
260
|
+
multiplier: number;
|
|
261
|
+
jitter_percent: number;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Flat v0 gates (kernel DESIGN.md §4): `exit_code == 0` is implicit for
|
|
266
|
+
* deterministic steps; these two are optional and combinable. An empty object
|
|
267
|
+
* means "implicit gates only".
|
|
268
|
+
*/
|
|
269
|
+
export interface KernelVerificationSpec {
|
|
270
|
+
output_contains?: string;
|
|
271
|
+
json_schema?: boolean | Record<string, unknown>;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface KernelStepCommon {
|
|
275
|
+
id: string;
|
|
276
|
+
depends_on: string[];
|
|
277
|
+
max_iterations: number;
|
|
278
|
+
retry: KernelRetryPolicy;
|
|
279
|
+
verification: KernelVerificationSpec;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface KernelDeterministicStep extends KernelStepCommon {
|
|
283
|
+
type: 'deterministic';
|
|
284
|
+
command: string;
|
|
285
|
+
timeout_ms?: number;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export interface KernelLlmStep extends KernelStepCommon {
|
|
289
|
+
type: 'llm';
|
|
290
|
+
prompt: string;
|
|
291
|
+
model?: string;
|
|
292
|
+
cli?: string;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export interface KernelAgentSurfaces {
|
|
296
|
+
workspace?: { surface: string }[];
|
|
297
|
+
streams?: { stream: string }[];
|
|
298
|
+
external?: string[];
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface KernelPermissionsSpec {
|
|
302
|
+
file_globs?: string[];
|
|
303
|
+
network_allowlist?: string[];
|
|
304
|
+
access_preset?: 'readonly' | 'readwrite';
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface KernelAgentStep extends KernelStepCommon {
|
|
308
|
+
type: 'agent';
|
|
309
|
+
instruction: string;
|
|
310
|
+
cli?: string;
|
|
311
|
+
model?: string;
|
|
312
|
+
recovery_mode: RecoveryMode;
|
|
313
|
+
surfaces?: KernelAgentSurfaces;
|
|
314
|
+
permissions?: KernelPermissionsSpec;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export type KernelStepSpec = KernelDeterministicStep | KernelLlmStep | KernelAgentStep;
|
|
318
|
+
|
|
319
|
+
export interface KernelBudgetSpec {
|
|
320
|
+
max_tokens_in?: number;
|
|
321
|
+
max_tokens_out?: number;
|
|
322
|
+
max_dollars?: string;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export interface KernelTriggerSpec {
|
|
326
|
+
id: string;
|
|
327
|
+
executor: string;
|
|
328
|
+
event_type?: string;
|
|
329
|
+
pattern?: Record<string, unknown>;
|
|
330
|
+
dedupe_key_template?: string;
|
|
331
|
+
stale_after_ms?: number;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/** The compiled spec as the kernel parses, journals, and hashes it. */
|
|
335
|
+
export interface KernelRunSpec {
|
|
336
|
+
version: string;
|
|
337
|
+
name?: string;
|
|
338
|
+
description?: string;
|
|
339
|
+
cli?: string;
|
|
340
|
+
triggers?: KernelTriggerSpec[];
|
|
341
|
+
steps: KernelStepSpec[];
|
|
342
|
+
budget?: KernelBudgetSpec;
|
|
343
|
+
}
|