@robmclarty/volley 0.6.0 → 0.7.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/CHANGELOG.md +27 -0
- package/README.md +62 -11
- package/dist/cli.js +3813 -3193
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +305 -294
- package/dist/index.js +3128 -2634
- package/dist/index.js.map +1 -1
- package/package.json +23 -15
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { z } from
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Shared value and type contracts for volley.
|
|
6
|
-
*
|
|
7
|
-
* Type aliases are PascalCase; value-level identifiers are snake_case.
|
|
8
|
-
* Fascicle's usage/cost types are used verbatim so summaries carry the
|
|
9
|
-
* substrate's shapes, not a re-derivation.
|
|
10
|
-
*/
|
|
11
|
-
|
|
1
|
+
import { Engine, FinishReason, StreamChunk, Throughput, UsageTotals } from "fascicle";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/types.d.ts
|
|
12
4
|
type Verdict = 'approved' | 'changes_requested';
|
|
13
5
|
type CriticPreset = 'reviewer' | 'optimizer' | 'researcher';
|
|
14
6
|
/** Transport for the critic role. The critic is read-only + schema-constrained,
|
|
@@ -30,116 +22,128 @@ type CostSource = 'provider_reported' | 'engine_derived' | 'unknown';
|
|
|
30
22
|
* died. Recorded alongside a critic retry so a degraded run says
|
|
31
23
|
* *what* failed, not just that it retried. */
|
|
32
24
|
type CauseKind = 'provider_5xx' | 'network' | 'unknown';
|
|
33
|
-
type RunStatus = 'running' | 'success' | 'budget_exhausted' | 'cost_cap_reached'
|
|
25
|
+
type RunStatus = 'running' | 'success' | 'budget_exhausted' | 'cost_cap_reached' |
|
|
34
26
|
/** The builder edited the gate that judges it, under `--fail-on-gate-edit`:
|
|
35
27
|
* the run halts on the spot rather than iterating, because a check the builder
|
|
36
28
|
* can rewrite is not evidence the work is done. */
|
|
37
|
-
|
|
29
|
+
'gate_edit_blocked' | 'interrupted' | 'error';
|
|
38
30
|
/** User-facing configuration, before resolution (config file / flags). */
|
|
39
31
|
type VolleyConfig = {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
32
|
+
prompt: string;
|
|
33
|
+
workspace: string;
|
|
34
|
+
criteria: string;
|
|
35
|
+
check?: CheckMode;
|
|
36
|
+
builder_model?: string;
|
|
37
|
+
builder_provider?: BuilderProvider;
|
|
38
|
+
builder_url?: string;
|
|
39
|
+
builder_max_steps?: number;
|
|
40
|
+
allow_unsandboxed_builder?: boolean;
|
|
41
|
+
critic_model?: string;
|
|
42
|
+
critic_provider?: CriticProvider;
|
|
43
|
+
critic_url?: string;
|
|
44
|
+
builder_permission_mode?: BuilderPermissionMode;
|
|
45
|
+
critic?: CriticPreset | (string & {});
|
|
46
|
+
max_iterations?: number;
|
|
47
|
+
max_cost_usd?: number | null;
|
|
48
|
+
git_checkpoints?: boolean;
|
|
49
|
+
worktree?: boolean;
|
|
50
|
+
discard_worktree?: boolean;
|
|
51
|
+
gate_paths?: string[];
|
|
52
|
+
fail_on_gate_edit?: boolean;
|
|
53
|
+
sandbox_image?: string;
|
|
54
|
+
verbose?: boolean;
|
|
55
|
+
quiet?: boolean;
|
|
56
|
+
json?: boolean;
|
|
57
|
+
show_thinking?: boolean;
|
|
58
|
+
dry_run?: boolean;
|
|
65
59
|
};
|
|
66
60
|
/** Fully resolved run configuration; `.volley/config.json` mirrors this. */
|
|
67
61
|
type ResolvedConfig = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
62
|
+
version: 2;
|
|
63
|
+
run_id: string;
|
|
64
|
+
started_at: string;
|
|
65
|
+
prompt: string;
|
|
66
|
+
criteria: string;
|
|
67
|
+
check: CheckMode;
|
|
68
|
+
check_resolved: CheckRunnerKind;
|
|
69
|
+
builder_model: string;
|
|
70
|
+
builder_provider: BuilderProvider;
|
|
71
|
+
/** The builder seat's own model server base URL (`--builder-url`), as given.
|
|
72
|
+
* It is normalized, and crossed to the host LLM endpoint when contained, only
|
|
73
|
+
* where it is used, because the crossing depends on where the run executes.
|
|
74
|
+
* Null falls back to the provider's env var (`VOLLEY_OLLAMA_URL` /
|
|
75
|
+
* `VOLLEY_LMSTUDIO_URL`), then its default, never to the critic's URL. Only
|
|
76
|
+
* a provider volley reaches at a base URL (ollama, lmstudio) takes one. */
|
|
77
|
+
builder_url: string | null;
|
|
78
|
+
builder_max_steps: number;
|
|
79
|
+
/** Operator opt-out permitting a local (non-`claude_cli`) builder to run
|
|
80
|
+
* without a sandbox — it gets a real host bash. Refused by default. */
|
|
81
|
+
allow_unsandboxed_builder: boolean;
|
|
82
|
+
critic_model: string;
|
|
83
|
+
critic_provider: CriticProvider;
|
|
84
|
+
/** The critic seat's own model server base URL (`--critic-url`), as given;
|
|
85
|
+
* resolved like `builder_url`, and null never falls back to the builder's. */
|
|
86
|
+
critic_url: string | null;
|
|
87
|
+
builder_permission_mode: BuilderPermissionMode;
|
|
88
|
+
critic_preset: CriticPreset | 'custom';
|
|
89
|
+
critic_prompt_path: string | null;
|
|
90
|
+
max_iterations: number;
|
|
91
|
+
max_cost_usd: number | null;
|
|
92
|
+
git_checkpoints: boolean;
|
|
93
|
+
/** Isolate the builder run's effects in a per-run git worktree: the
|
|
94
|
+
* builder/critic file tools' containment root moves to the worktree, while
|
|
95
|
+
* `.volley/` state stays under `workspace` (the control plane). Off by
|
|
96
|
+
* default; requires the workspace to be a git repository. */
|
|
97
|
+
worktree: boolean;
|
|
98
|
+
/** Throw a `--worktree` run's effects away at teardown even when it converged:
|
|
99
|
+
* the run branch is force-deleted rather than kept, because only the
|
|
100
|
+
* verdicts are wanted. This is what `volley matrix` sweeps with — one config,
|
|
101
|
+
* many builder×critic seats, no per-seat commits or branches left anywhere.
|
|
102
|
+
* Refused without `--worktree`; `--git` still wins, so a `--worktree --git`
|
|
103
|
+
* run integrates exactly as it always has. */
|
|
104
|
+
discard_worktree: boolean;
|
|
105
|
+
/** Glob patterns naming the *gate*: the tests, fixtures, and check
|
|
106
|
+
* configuration that decide whether the builder's work passes. An edit to one
|
|
107
|
+
* is reported to the critic and recorded in the summary — and refused outright
|
|
108
|
+
* under `fail_on_gate_edit`. Defaults to `DEFAULT_GATE_PATTERNS`; a config's
|
|
109
|
+
* own list replaces it, because what counts as the gate is the task's call
|
|
110
|
+
* (a test-writing task edits tests by design). */
|
|
111
|
+
gate_paths: string[];
|
|
112
|
+
/** Halt the run when the builder edits a `gate_paths` match, instead of
|
|
113
|
+
* reporting it and continuing. Off by default: a gate edit is legitimate often
|
|
114
|
+
* enough that refusing it by default would break honest tasks, and the mark on
|
|
115
|
+
* the summary already makes it impossible to miss. */
|
|
116
|
+
fail_on_gate_edit: boolean;
|
|
117
|
+
/** Container image the local-builder Docker sandbox runs. Defaults to
|
|
118
|
+
* volley's own `Dockerfile`-built image; `--sandbox-image <tag>` /
|
|
119
|
+
* `VOLLEY_SANDBOX_IMAGE` override it. Meaningful only for a local builder —
|
|
120
|
+
* the `claude_cli` path never uses Docker. */
|
|
121
|
+
sandbox_image: string;
|
|
122
|
+
workspace: string;
|
|
123
|
+
verbose: boolean;
|
|
124
|
+
quiet: boolean;
|
|
125
|
+
json: boolean;
|
|
126
|
+
show_thinking: boolean;
|
|
123
127
|
};
|
|
124
128
|
/** One failing check slot's raw artifact, for the critic prompt. */
|
|
125
129
|
type CheckArtifact = {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
slot: string;
|
|
131
|
+
path: string | null;
|
|
132
|
+
content: string;
|
|
133
|
+
truncated: boolean;
|
|
130
134
|
};
|
|
131
135
|
type CheckResult = {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
136
|
+
ran: boolean;
|
|
137
|
+
runner: CheckRunnerKind;
|
|
138
|
+
ok: boolean;
|
|
139
|
+
exit_code: number | null;
|
|
140
|
+
duration_ms: number;
|
|
141
|
+
failing_slots: string[];
|
|
142
|
+
detail: CheckArtifact[];
|
|
143
|
+
/** Raw checkride summary JSON (when the runner is checkride). */
|
|
144
|
+
summary?: unknown;
|
|
145
|
+
/** Captured combined output (when the runner is a shell command). */
|
|
146
|
+
log?: string;
|
|
143
147
|
};
|
|
144
148
|
/** How one path changed between the run's baseline and the builder's output.
|
|
145
149
|
* `renamed` covers git's rename/copy detection (the destination path is the one
|
|
@@ -150,175 +154,184 @@ type ChangeStatus = 'added' | 'modified' | 'deleted' | 'renamed' | 'unknown';
|
|
|
150
154
|
* passes. A gate edit is not misconduct by itself (some tasks are *about* the
|
|
151
155
|
* tests); it is the fact that makes a green check prove less. */
|
|
152
156
|
type ChangedFile = {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
157
|
+
path: string;
|
|
158
|
+
status: ChangeStatus;
|
|
159
|
+
gate: boolean;
|
|
156
160
|
};
|
|
157
161
|
/** What the builder changed since the run's baseline, as the harness sees it
|
|
158
162
|
* (`src/changes.ts`). Null in `LoopState` when the build root is not a git
|
|
159
163
|
* repository — change detection is evidence, never a precondition. */
|
|
160
164
|
type ChangeSet = {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
165
|
+
/** The commit the changes are measured against — the build root's HEAD before
|
|
166
|
+
* the first iteration. Null in a repository with no commits yet, where only
|
|
167
|
+
* untracked files can be reported. */
|
|
168
|
+
baseline: string | null;
|
|
169
|
+
/** The changed paths, sorted, capped at the collection limit. */
|
|
170
|
+
files: ChangedFile[];
|
|
171
|
+
/** Every gate-matching path — computed over the *full* list before the cap,
|
|
172
|
+
* so truncation can never hide a gate edit. */
|
|
173
|
+
gate_edits: string[];
|
|
174
|
+
/** How many paths changed in total, before the cap. */
|
|
175
|
+
total: number;
|
|
176
|
+
truncated: boolean;
|
|
173
177
|
};
|
|
174
178
|
/** Per-phase record for iteration summaries. */
|
|
175
179
|
type PhaseRecord = {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
180
|
+
provider: string;
|
|
181
|
+
model: string;
|
|
182
|
+
session_id: string | null;
|
|
183
|
+
/** Wall-clock of the phase's model work, the same measure for every provider
|
|
184
|
+
* so an all-local run and an all-Claude run compare directly. The builder's is
|
|
185
|
+
* fascicle's `GenerateResult.timing`: the whole call, every turn and the tools
|
|
186
|
+
* between them. The critic's spans its whole degradation ladder, failed
|
|
187
|
+
* attempts included, since no one result's timing covers the attempts before
|
|
188
|
+
* it. Neither counts the Ollama prewarm. */
|
|
189
|
+
duration_ms: number;
|
|
190
|
+
usage: UsageTotals;
|
|
191
|
+
cost_usd: number | null;
|
|
192
|
+
cost_source: CostSource;
|
|
193
|
+
/** How the phase's generate call ended. For a local builder,
|
|
194
|
+
* `'max_steps'` is a budget cutoff surfaced as a warning, not an error. */
|
|
195
|
+
finish_reason: FinishReason;
|
|
196
|
+
/** Tool calls fascicle executed in this phase, and how many were recovered
|
|
197
|
+
* from assistant text rather than returned structurally — the raw
|
|
198
|
+
* counts behind the salvage-rate health metric. */
|
|
199
|
+
tool_calls: number;
|
|
200
|
+
salvaged_tool_calls: number;
|
|
201
|
+
/** Provider-error retries that preceded this phase's successful call
|
|
202
|
+
* — the local-critic degradation ladder's first rung: a stochastic
|
|
203
|
+
* Ollama stream death is retried once before falling back. Set on the critic
|
|
204
|
+
* record (0 when the first call succeeded); absent on the builder, which is
|
|
205
|
+
* not retried this build. Additive — old summary consumers ignore it. */
|
|
206
|
+
retries?: number;
|
|
207
|
+
/** The `cause_kind` of the retried provider error, recorded with `retries`.
|
|
208
|
+
* Absent when no retry happened. */
|
|
209
|
+
retry_cause_kind?: CauseKind;
|
|
210
|
+
/** This local-critic verdict was rendered by the tool-less fallback rung:
|
|
211
|
+
* the tool-bearing critique kept dying on the provider's stream
|
|
212
|
+
* even after the bounded retry, so the critic judged with no read access —
|
|
213
|
+
* grounded only by the criteria, the raw check artifacts, and a workspace file
|
|
214
|
+
* inventory. Set (true) on a degraded critic record; absent on a full
|
|
215
|
+
* critique and on the builder. Additive, and a degraded verdict is *always*
|
|
216
|
+
* marked so it never passes silently as a full one. */
|
|
217
|
+
critic_degraded?: boolean;
|
|
218
|
+
/** Output tokens per second over the model's own turns (tool execution and
|
|
219
|
+
* retry backoff excluded), from fascicle's per-step timing. `basis` is
|
|
220
|
+
* `decode` when every turn streamed, `blended` when any round trip counted
|
|
221
|
+
* prefill and network too — always the case for `claude_cli`, whose rate
|
|
222
|
+
* fascicle derives from the CLI's reported API time. Absent when no turn
|
|
223
|
+
* carried timing. Additive.
|
|
224
|
+
*
|
|
225
|
+
* On Ollama, `decode` holds only while a turn's first chunk arrives as its
|
|
226
|
+
* first token is generated. Ollama sends a tool call whole, so a turn whose
|
|
227
|
+
* only output is a tool call dispatches nothing until generation ends, and
|
|
228
|
+
* its tokens are divided by the last few milliseconds: a non-thinking seat's
|
|
229
|
+
* rate reads far too high until robmclarty/fascicle#12 times those turns
|
|
230
|
+
* another way. A thinking seat needs ai-sdk-ollama 4.3.0 or later, which
|
|
231
|
+
* streams the reasoning even though volley never sets `think`. */
|
|
232
|
+
throughput?: Throughput;
|
|
221
233
|
};
|
|
222
234
|
type HaltReason = 'cost_cap' | 'gate_edit' | null;
|
|
223
235
|
/** Carry-state threaded through the fascicle loop. */
|
|
224
236
|
type LoopState = {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
237
|
+
iteration: number;
|
|
238
|
+
iteration_started_at: string;
|
|
239
|
+
feedback: string | null;
|
|
240
|
+
verdict: Verdict | null;
|
|
241
|
+
unmet_criteria: string[];
|
|
242
|
+
check: CheckResult | null;
|
|
243
|
+
/** What the builder changed this iteration, measured against the run's
|
|
244
|
+
* baseline (`src/changes.ts`). Null when the build root is not a git
|
|
245
|
+
* repository, and before the first `build` step of a run. */
|
|
246
|
+
changes: ChangeSet | null;
|
|
247
|
+
builder: PhaseRecord | null;
|
|
248
|
+
critic: PhaseRecord | null;
|
|
249
|
+
total_usage: UsageTotals;
|
|
250
|
+
total_cost_usd: number;
|
|
251
|
+
builder_cost_usd: number;
|
|
252
|
+
critic_cost_usd: number;
|
|
253
|
+
check_duration_ms: number;
|
|
254
|
+
iteration_cost_usd: number;
|
|
255
|
+
halt: HaltReason;
|
|
256
|
+
cost_warned: boolean;
|
|
245
257
|
};
|
|
246
258
|
/** Projection of final loop state; `.volley/summary.json` mirrors this. */
|
|
247
259
|
type RunResult = {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
260
|
+
run_id: string;
|
|
261
|
+
status: RunStatus;
|
|
262
|
+
started_at: string;
|
|
263
|
+
completed_at: string | null;
|
|
264
|
+
iterations_completed: number;
|
|
265
|
+
total_usage: UsageTotals;
|
|
266
|
+
total_cost_usd: number;
|
|
267
|
+
builder_cost_usd: number;
|
|
268
|
+
critic_cost_usd: number;
|
|
269
|
+
check_duration_ms: number;
|
|
270
|
+
final_verdict: Verdict | null;
|
|
271
|
+
/** The run branch teardown left behind because this run's work was never
|
|
272
|
+
* integrated: under `--worktree` without `--git` a converged run has no
|
|
273
|
+
* other copy of its effects, so teardown commits them onto `volley/<run id>`
|
|
274
|
+
* and keeps the branch instead of force-deleting it. Null whenever nothing
|
|
275
|
+
* survived — every non-worktree run, every integrated run, every discarded
|
|
276
|
+
* one. `--json` consumers read it here; `.volley/summary.json` mirrors it. */
|
|
277
|
+
salvaged_branch: string | null;
|
|
266
278
|
};
|
|
267
|
-
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/config.d.ts
|
|
268
281
|
/** `@path/to/file` reads the file; any other string passes through. */
|
|
269
|
-
declare function expand_at_file(value: string, cwd: string): string;
|
|
282
|
+
export declare function expand_at_file(value: string, cwd: string): string;
|
|
270
283
|
/** Load a `volley.config.ts` / `.js` file's default export. */
|
|
271
|
-
declare function load_config_file(path: string): Promise<VolleyConfig>;
|
|
284
|
+
export declare function load_config_file(path: string): Promise<VolleyConfig>;
|
|
272
285
|
type ResolveOptions = {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
286
|
+
cwd?: string;
|
|
287
|
+
run_id?: string;
|
|
288
|
+
started_at?: string;
|
|
289
|
+
env?: Record<string, string | undefined>;
|
|
277
290
|
};
|
|
278
291
|
/** Merge, expand, and validate a raw `VolleyConfig` into a `ResolvedConfig`.
|
|
279
292
|
* `check_resolved` comes from check detection against the workspace, so the
|
|
280
293
|
* SDK and the CLI resolve `auto` and a command check the same way. */
|
|
281
|
-
declare function resolve_config(raw: VolleyConfig, options?: ResolveOptions): ResolvedConfig;
|
|
282
|
-
|
|
294
|
+
export declare function resolve_config(raw: VolleyConfig, options?: ResolveOptions): ResolvedConfig;
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/render/format.d.ts
|
|
283
297
|
type Role = 'builder' | 'critic' | 'check';
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
* Live output renderer: consumes `StreamChunk`s from each
|
|
287
|
-
* `generate` call plus volley's own phase/cost lines, and writes human
|
|
288
|
-
* progress to stderr. Streaming is a display concern only — the trajectory
|
|
289
|
-
* jsonl is the durable record.
|
|
290
|
-
*/
|
|
291
|
-
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/render/renderer.d.ts
|
|
292
300
|
type RenderMode = 'default' | 'verbose' | 'quiet' | 'json';
|
|
293
301
|
type RendererOptions = {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
302
|
+
mode: RenderMode;
|
|
303
|
+
show_thinking: boolean;
|
|
304
|
+
color: boolean;
|
|
305
|
+
max_cost_usd: number | null;
|
|
306
|
+
write?: (text: string) => void;
|
|
299
307
|
};
|
|
300
308
|
type Renderer = {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
309
|
+
builder_chunk: (chunk: StreamChunk) => void;
|
|
310
|
+
critic_chunk: (chunk: StreamChunk) => void;
|
|
311
|
+
phase_start: (iteration: number, phase: Role) => void;
|
|
312
|
+
phase_end: (iteration: number, phase: Role, ok: boolean, detail?: string) => void;
|
|
313
|
+
cost_line: (iteration: number, phase: Role, phase_cost: number | null, run_total: number) => void;
|
|
314
|
+
info: (message: string) => void;
|
|
315
|
+
warn: (message: string) => void;
|
|
316
|
+
error: (message: string) => void;
|
|
317
|
+
final_summary: (result: RunResult) => void;
|
|
310
318
|
};
|
|
311
|
-
declare function create_renderer(options: RendererOptions): Renderer;
|
|
312
|
-
|
|
319
|
+
export declare function create_renderer(options: RendererOptions): Renderer;
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/orchestrator.d.ts
|
|
313
322
|
type OrchestratorDeps = {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
323
|
+
renderer: Renderer;
|
|
324
|
+
/** An engine to run both seats on in place of the ones built from the
|
|
325
|
+
* config. It serves both seats as-is, so the seat URLs then steer only
|
|
326
|
+
* volley's own requests (prewarm and the context probe), not model calls. */
|
|
327
|
+
engine?: Engine;
|
|
328
|
+
abort?: AbortSignal;
|
|
329
|
+
install_signal_handlers?: boolean;
|
|
318
330
|
};
|
|
319
|
-
declare function run_volley(config: ResolvedConfig, deps: OrchestratorDeps, resume_from?: LoopState | null): Promise<RunResult>;
|
|
320
|
-
|
|
321
|
-
|
|
331
|
+
export declare function run_volley(config: ResolvedConfig, deps: OrchestratorDeps, resume_from?: LoopState | null): Promise<RunResult>;
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region src/loop_state.d.ts
|
|
334
|
+
export declare function initial_state(): LoopState;
|
|
322
335
|
/** All stopping conditions live here: acceptance, cost cap, the gate
|
|
323
336
|
* edit refusal, and — implicitly via `max_rounds` — the iteration budget.
|
|
324
337
|
* Success wins when it and the cap land on the same iteration.
|
|
@@ -327,34 +340,30 @@ declare function initial_state(): LoopState;
|
|
|
327
340
|
* it: the run passed a check the builder had rewritten, so the pass is exactly
|
|
328
341
|
* what is in question. It stops the run instead of iterating, because a model
|
|
329
342
|
* that just edited the gate is not a promising candidate to be asked again. */
|
|
330
|
-
declare function gate(config: ResolvedConfig, state: LoopState): {
|
|
331
|
-
|
|
332
|
-
|
|
343
|
+
export declare function gate(config: ResolvedConfig, state: LoopState): {
|
|
344
|
+
stop: boolean;
|
|
345
|
+
state: LoopState;
|
|
333
346
|
};
|
|
334
|
-
declare function status_of(value: LoopState, converged: boolean): RunStatus;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
approved: "approved";
|
|
345
|
-
changes_requested: "changes_requested";
|
|
346
|
-
}>;
|
|
347
|
-
feedback: z.ZodString;
|
|
348
|
-
unmet_criteria: z.ZodArray<z.ZodString>;
|
|
347
|
+
export declare function status_of(value: LoopState, converged: boolean): RunStatus;
|
|
348
|
+
//#endregion
|
|
349
|
+
//#region src/critic/run.d.ts
|
|
350
|
+
export declare const verdict_schema: z.ZodObject<{
|
|
351
|
+
verdict: z.ZodEnum<{
|
|
352
|
+
approved: "approved";
|
|
353
|
+
changes_requested: "changes_requested";
|
|
354
|
+
}>;
|
|
355
|
+
feedback: z.ZodString;
|
|
356
|
+
unmet_criteria: z.ZodArray<z.ZodString>;
|
|
349
357
|
}, z.core.$strip>;
|
|
350
358
|
type VerdictOutput = z.infer<typeof verdict_schema>;
|
|
351
|
-
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region src/sandbox.d.ts
|
|
352
361
|
/** Canonical identity of the allowlist bridge the examples create (`docker
|
|
353
362
|
* network create --subnet <SANDBOX_NETWORK_SUBNET> <SANDBOX_NETWORK_NAME>`) and
|
|
354
363
|
* the host `DOCKER-USER` rules scope to. Exported so the blessed examples
|
|
355
364
|
* share one spelling of the invocation spec. */
|
|
356
|
-
declare const SANDBOX_NETWORK_NAME = "volley-sandbox-net";
|
|
357
|
-
declare const SANDBOX_NETWORK_SUBNET = "172.31.99.0/24";
|
|
365
|
+
export declare const SANDBOX_NETWORK_NAME = "volley-sandbox-net";
|
|
366
|
+
export declare const SANDBOX_NETWORK_SUBNET = "172.31.99.0/24";
|
|
358
367
|
/**
|
|
359
368
|
* The container's egress posture. Under whole-process containment
|
|
360
369
|
* the model client and the `fetch` tool run inside the container, so its
|
|
@@ -390,7 +399,7 @@ type SandboxNetwork = 'none' | 'allowlist';
|
|
|
390
399
|
* collapses the allowlist targets onto the host gateway (`host.docker.internal`,
|
|
391
400
|
* the Linux-portable spelling — harmless where Docker Desktop already provides it).
|
|
392
401
|
*/
|
|
393
|
-
declare function network_run_args(network: SandboxNetwork, network_name: string): string[];
|
|
402
|
+
export declare function network_run_args(network: SandboxNetwork, network_name: string): string[];
|
|
394
403
|
/**
|
|
395
404
|
* The hardened `docker run` argv that launches volley inside its container.
|
|
396
405
|
* Pure and exported so the flag set is unit-testable without a
|
|
@@ -417,30 +426,32 @@ declare function network_run_args(network: SandboxNetwork, network_name: string)
|
|
|
417
426
|
* `--read-only` rootfs is an explicit tmpfs or volume; the bind-mounted worktree
|
|
418
427
|
* is the one host-visible write path.
|
|
419
428
|
*/
|
|
420
|
-
declare function sandbox_run_args(options: {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
429
|
+
export declare function sandbox_run_args(options: {
|
|
430
|
+
image: string;
|
|
431
|
+
build_root: string;
|
|
432
|
+
uid: number | null;
|
|
433
|
+
gid: number | null;
|
|
434
|
+
store_volume?: string | null;
|
|
435
|
+
network: SandboxNetwork;
|
|
436
|
+
network_name: string;
|
|
437
|
+
name?: string | null;
|
|
438
|
+
env?: ReadonlyArray<readonly [string, string]>;
|
|
439
|
+
labels?: ReadonlyArray<readonly [string, string]>;
|
|
440
|
+
entrypoint?: string | null;
|
|
441
|
+
command?: ReadonlyArray<string>;
|
|
433
442
|
}): string[];
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
declare const
|
|
437
|
-
declare const
|
|
438
|
-
declare const
|
|
439
|
-
declare const
|
|
440
|
-
declare const
|
|
441
|
-
declare const
|
|
442
|
-
declare const
|
|
443
|
-
declare
|
|
444
|
-
declare function
|
|
445
|
-
|
|
446
|
-
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region src/exit_codes.d.ts
|
|
445
|
+
export declare const EXIT_SUCCESS = 0;
|
|
446
|
+
export declare const EXIT_BUDGET_EXHAUSTED = 2;
|
|
447
|
+
export declare const EXIT_BUILDER_ERROR = 3;
|
|
448
|
+
export declare const EXIT_CHECK_ERROR = 4;
|
|
449
|
+
export declare const EXIT_CONFIG_ERROR = 5;
|
|
450
|
+
export declare const EXIT_CRITIC_ERROR = 6;
|
|
451
|
+
export declare const EXIT_COST_CAP = 7;
|
|
452
|
+
export declare const EXIT_INTERRUPTED = 130;
|
|
453
|
+
export declare function exit_code_for_status(status: RunStatus): number;
|
|
454
|
+
export declare function exit_code_for_error(err: unknown): number;
|
|
455
|
+
//#endregion
|
|
456
|
+
export type { BuilderPermissionMode, CheckArtifact, CheckMode, CheckResult, CheckRunnerKind, CostSource, CriticPreset, CriticProvider, HaltReason, LoopState, PhaseRecord, RenderMode, Renderer, RendererOptions, ResolvedConfig, RunResult, RunStatus, SandboxNetwork, Verdict, VerdictOutput, VolleyConfig };
|
|
457
|
+
//# sourceMappingURL=index.d.ts.map
|