lastlight-workflow-engine 0.2.0 → 0.3.1
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/core/loop-eval.d.ts +18 -1
- package/dist/core/loop-eval.js +32 -4
- package/dist/core/loop-eval.js.map +1 -1
- package/dist/core/phase-executor.d.ts +27 -0
- package/dist/core/phase-executor.js +167 -15
- package/dist/core/phase-executor.js.map +1 -1
- package/dist/core/phase-ref.d.ts +12 -4
- package/dist/core/phase-ref.js +18 -3
- package/dist/core/phase-ref.js.map +1 -1
- package/dist/core/scheduler.js +38 -6
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/schema.d.ts +28 -5
- package/dist/core/schema.js +92 -4
- package/dist/core/schema.js.map +1 -1
- package/dist/core/templated-number.d.ts +78 -0
- package/dist/core/templated-number.js +100 -0
- package/dist/core/templated-number.js.map +1 -0
- package/dist/core/templates.d.ts +11 -0
- package/dist/core/templates.js +29 -21
- package/dist/core/templates.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/test-support/fakes.d.ts +42 -1
- package/dist/test-support/fakes.js +0 -0
- package/dist/test-support/fakes.js.map +1 -1
- package/package.json +1 -1
package/dist/core/phase-ref.d.ts
CHANGED
|
@@ -15,15 +15,20 @@
|
|
|
15
15
|
* cycle n re-review → reviewer_recheck_n
|
|
16
16
|
* generic-loop iteration n → reviewer_iter_n
|
|
17
17
|
* generic-loop retry of n → reviewer_iter_n_retry
|
|
18
|
+
* generic-loop check of n → reviewer_iter_n_check
|
|
18
19
|
*
|
|
19
20
|
* `n` is the 1-based cycle; `fix_k` and `recheck_k` pair within a cycle. The
|
|
20
21
|
* `_retry` suffix is the one-shot re-run of a generic-loop iteration whose first
|
|
21
22
|
* attempt came back empty (a "soft" outcome); it gets its own ledger row so
|
|
22
23
|
* resume/dedup doesn't skip it, and the dashboard's longest-prefix grouping
|
|
23
|
-
* still nests it under the same parent. The
|
|
24
|
-
*
|
|
24
|
+
* still nests it under the same parent. The `_check` suffix is the
|
|
25
|
+
* `generic_loop.until_bash` exit-condition run for iteration n — a real sandbox
|
|
26
|
+
* command that can take minutes, so it gets its own ledger row too and is
|
|
27
|
+
* therefore visible (with a start time and a duration) while it is in flight.
|
|
28
|
+
* The legacy bare-numeric re-review form (`reviewer_2`) is dropped entirely —
|
|
29
|
+
* it is neither produced nor recognized.
|
|
25
30
|
*/
|
|
26
|
-
export type PhaseKind = "phase" | "fix" | "recheck" | "iter" | "retry";
|
|
31
|
+
export type PhaseKind = "phase" | "fix" | "recheck" | "iter" | "retry" | "check";
|
|
27
32
|
export declare class PhaseRef {
|
|
28
33
|
readonly base: string;
|
|
29
34
|
readonly kind: PhaseKind;
|
|
@@ -39,10 +44,13 @@ export declare class PhaseRef {
|
|
|
39
44
|
static iter(base: string, n: number): PhaseRef;
|
|
40
45
|
/** The one-shot retry of generic-loop iteration `n` after a soft outcome. */
|
|
41
46
|
static iterRetry(base: string, n: number): PhaseRef;
|
|
47
|
+
/** The `until_bash` exit-condition run that follows generic-loop iteration `n`. */
|
|
48
|
+
static iterCheck(base: string, n: number): PhaseRef;
|
|
42
49
|
format(): string;
|
|
43
50
|
/**
|
|
44
51
|
* Parse a label back into a PhaseRef. Recognizes only the generated
|
|
45
|
-
* `_fix_N` / `_recheck_N` / `_iter_N`
|
|
52
|
+
* `_fix_N` / `_recheck_N` / `_iter_N` / `_iter_N_retry` / `_iter_N_check`
|
|
53
|
+
* suffixes; anything else (including a
|
|
46
54
|
* bare declared name or the dropped legacy `_N` form) parses as a plain
|
|
47
55
|
* `phase` whose base is the whole string.
|
|
48
56
|
*/
|
package/dist/core/phase-ref.js
CHANGED
|
@@ -15,13 +15,18 @@
|
|
|
15
15
|
* cycle n re-review → reviewer_recheck_n
|
|
16
16
|
* generic-loop iteration n → reviewer_iter_n
|
|
17
17
|
* generic-loop retry of n → reviewer_iter_n_retry
|
|
18
|
+
* generic-loop check of n → reviewer_iter_n_check
|
|
18
19
|
*
|
|
19
20
|
* `n` is the 1-based cycle; `fix_k` and `recheck_k` pair within a cycle. The
|
|
20
21
|
* `_retry` suffix is the one-shot re-run of a generic-loop iteration whose first
|
|
21
22
|
* attempt came back empty (a "soft" outcome); it gets its own ledger row so
|
|
22
23
|
* resume/dedup doesn't skip it, and the dashboard's longest-prefix grouping
|
|
23
|
-
* still nests it under the same parent. The
|
|
24
|
-
*
|
|
24
|
+
* still nests it under the same parent. The `_check` suffix is the
|
|
25
|
+
* `generic_loop.until_bash` exit-condition run for iteration n — a real sandbox
|
|
26
|
+
* command that can take minutes, so it gets its own ledger row too and is
|
|
27
|
+
* therefore visible (with a start time and a duration) while it is in flight.
|
|
28
|
+
* The legacy bare-numeric re-review form (`reviewer_2`) is dropped entirely —
|
|
29
|
+
* it is neither produced nor recognized.
|
|
25
30
|
*/
|
|
26
31
|
export class PhaseRef {
|
|
27
32
|
base;
|
|
@@ -52,6 +57,10 @@ export class PhaseRef {
|
|
|
52
57
|
static iterRetry(base, n) {
|
|
53
58
|
return new PhaseRef(base, "retry", n);
|
|
54
59
|
}
|
|
60
|
+
/** The `until_bash` exit-condition run that follows generic-loop iteration `n`. */
|
|
61
|
+
static iterCheck(base, n) {
|
|
62
|
+
return new PhaseRef(base, "check", n);
|
|
63
|
+
}
|
|
55
64
|
format() {
|
|
56
65
|
switch (this.kind) {
|
|
57
66
|
case "phase":
|
|
@@ -64,11 +73,14 @@ export class PhaseRef {
|
|
|
64
73
|
return `${this.base}_iter_${this.index}`;
|
|
65
74
|
case "retry":
|
|
66
75
|
return `${this.base}_iter_${this.index}_retry`;
|
|
76
|
+
case "check":
|
|
77
|
+
return `${this.base}_iter_${this.index}_check`;
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
/**
|
|
70
81
|
* Parse a label back into a PhaseRef. Recognizes only the generated
|
|
71
|
-
* `_fix_N` / `_recheck_N` / `_iter_N`
|
|
82
|
+
* `_fix_N` / `_recheck_N` / `_iter_N` / `_iter_N_retry` / `_iter_N_check`
|
|
83
|
+
* suffixes; anything else (including a
|
|
72
84
|
* bare declared name or the dropped legacy `_N` form) parses as a plain
|
|
73
85
|
* `phase` whose base is the whole string.
|
|
74
86
|
*/
|
|
@@ -76,6 +88,9 @@ export class PhaseRef {
|
|
|
76
88
|
let m = label.match(/^(.*)_iter_(\d+)_retry$/);
|
|
77
89
|
if (m)
|
|
78
90
|
return new PhaseRef(m[1], "retry", Number(m[2]));
|
|
91
|
+
m = label.match(/^(.*)_iter_(\d+)_check$/);
|
|
92
|
+
if (m)
|
|
93
|
+
return new PhaseRef(m[1], "check", Number(m[2]));
|
|
79
94
|
m = label.match(/^(.*)_fix_(\d+)$/);
|
|
80
95
|
if (m)
|
|
81
96
|
return new PhaseRef(m[1], "fix", Number(m[2]));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phase-ref.js","sourceRoot":"","sources":["../../src/core/phase-ref.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"phase-ref.js","sourceRoot":"","sources":["../../src/core/phase-ref.ts"],"names":[],"mappings":"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"}
|
package/dist/core/scheduler.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { phaseSkipIfExpressions } from "./schema.js";
|
|
1
2
|
import { renderTemplate } from "./templates.js";
|
|
3
|
+
import { evalSkipIf } from "./loop-eval.js";
|
|
2
4
|
import { buildDag, getReadyNodes, getNodesToSkip, isComplete } from "./dag.js";
|
|
3
5
|
import { PhaseExecutor } from "./phase-executor.js";
|
|
4
6
|
import { OPENINFERENCE_CHAIN, OPENINFERENCE_SPAN_KIND } from "./types.js";
|
|
@@ -49,13 +51,29 @@ outputs = {}) {
|
|
|
49
51
|
const phaseByName = new Map(definition.phases.map((p) => [p.name, p]));
|
|
50
52
|
const activeBackend = config.sandbox ?? "gondolin";
|
|
51
53
|
while (!isComplete(dag)) {
|
|
52
|
-
// Honour a cancel that landed during the previous phase's execution
|
|
54
|
+
// Honour a cancel that landed during the previous phase's execution, and
|
|
55
|
+
// re-read the run row's scratch while we are here.
|
|
53
56
|
if (db && workflowId) {
|
|
54
57
|
const latest = db.runs.getRun(workflowId);
|
|
55
58
|
if (latest?.status === "cancelled") {
|
|
56
59
|
console.log(`[runner] ${definition.name} cancelled — stopping`);
|
|
57
60
|
return { success: false, phases };
|
|
58
61
|
}
|
|
62
|
+
// `runScope.scratch` is loaded ONCE, before the first phase. The HOST also
|
|
63
|
+
// writes to the row mid-run through `mergeScratch` from its `onPhaseEnd`
|
|
64
|
+
// hook — lastlight-core's fix-marker harvest does exactly that — and this
|
|
65
|
+
// process cannot see those writes. So the `skip_if` gate below would
|
|
66
|
+
// evaluate `scratch.*` against the pre-run snapshot on a fresh run and only
|
|
67
|
+
// see the real value across a resume (where the row is re-read at startup):
|
|
68
|
+
// a guard that silently does nothing on the path it was written for, which
|
|
69
|
+
// is the failure shape `skip_if` exists to avoid.
|
|
70
|
+
//
|
|
71
|
+
// Mutated in place, never replaced: `ctx.scratch` aliases this object so
|
|
72
|
+
// `{{scratch.*}}` templates and the loop nodes' own slots keep resolving.
|
|
73
|
+
// The row is authoritative because every in-engine scratch write is paired
|
|
74
|
+
// with a `mergeScratch` of the same value.
|
|
75
|
+
if (latest?.scratch)
|
|
76
|
+
Object.assign(runScope.scratch, latest.scratch);
|
|
59
77
|
}
|
|
60
78
|
// Skip nodes whose trigger rule fails (deps terminal, rule unsatisfied).
|
|
61
79
|
// This is how a failure cascades to the end of a chain as skips. Skips are
|
|
@@ -69,15 +87,21 @@ outputs = {}) {
|
|
|
69
87
|
await reportStep(node.name, "skipped");
|
|
70
88
|
}
|
|
71
89
|
const ready = getReadyNodes(dag);
|
|
72
|
-
// Capability gate: skip any ready node
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
90
|
+
// Capability / conditional gate: skip any ready node that shouldn't run.
|
|
91
|
+
// Safe-by-default graceful degradation — a gated phase (e.g. the browser-QA
|
|
92
|
+
// step that needs the docker image) silently no-ops instead of failing the
|
|
93
|
+
// workflow. Three reasons trigger a skip:
|
|
76
94
|
// 1. `requires_sandbox` names a backend other than the one running.
|
|
77
95
|
// 2. `sandbox_image: qa` but the browser-QA image isn't built here (only
|
|
78
96
|
// checked on docker — on other backends the field is inert).
|
|
97
|
+
// 3. `skip_if` matches the run's render context — the phase is not
|
|
98
|
+
// *unavailable*, it is *unnecessary* (the fix phase after a diagnosis
|
|
99
|
+
// that says there is nothing to fix here). Evaluated only once the
|
|
100
|
+
// node is ready, so an upstream phase's output is already in `outputs`.
|
|
79
101
|
// Uses the same non-failing skip mechanics as the trigger-rule skip above,
|
|
80
|
-
// plus the phase's `on_skipped_done` message so the user sees why.
|
|
102
|
+
// plus the phase's `on_skipped_done` message so the user sees why. All
|
|
103
|
+
// three keep the RUN `succeeded`: a correct "nothing to do" is not a
|
|
104
|
+
// failure (see `skip_if` in core/schema.ts for why that matters).
|
|
81
105
|
const gatedSkip = [];
|
|
82
106
|
for (const node of ready) {
|
|
83
107
|
const phaseDef = phaseByName.get(node.name);
|
|
@@ -90,6 +114,14 @@ outputs = {}) {
|
|
|
90
114
|
!capabilities.qaImageAvailable()) {
|
|
91
115
|
gatedSkip.push({ node, reason: `requires the ${capabilities.qaImageName} image, not built on this host` });
|
|
92
116
|
}
|
|
117
|
+
else if (phaseDef) {
|
|
118
|
+
const exprs = phaseSkipIfExpressions(phaseDef);
|
|
119
|
+
const matched = exprs.length
|
|
120
|
+
? evalSkipIf(exprs, { ...ctx, phaseOutputs: outputs, scratch: runScope.scratch, output: "" })
|
|
121
|
+
: undefined;
|
|
122
|
+
if (matched)
|
|
123
|
+
gatedSkip.push({ node, reason: `skip_if matched: ${matched}` });
|
|
124
|
+
}
|
|
93
125
|
}
|
|
94
126
|
if (gatedSkip.length > 0) {
|
|
95
127
|
for (const { node, reason } of gatedSkip) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/core/schema.d.ts
CHANGED
|
@@ -31,7 +31,10 @@ declare const PhaseLoopSchema: z.ZodObject<{
|
|
|
31
31
|
}, z.core.$strip>>;
|
|
32
32
|
}, z.core.$strip>;
|
|
33
33
|
declare const GenericLoopSchema: z.ZodObject<{
|
|
34
|
-
max_iterations: z.ZodNumber
|
|
34
|
+
max_iterations: z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
|
|
35
|
+
from: z.ZodString;
|
|
36
|
+
default: z.ZodNumber;
|
|
37
|
+
}, z.core.$strict>]>;
|
|
35
38
|
until: z.ZodOptional<z.ZodString>;
|
|
36
39
|
until_bash: z.ZodOptional<z.ZodString>;
|
|
37
40
|
interactive: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -67,7 +70,10 @@ declare const PhaseDefinitionSchema: z.ZodObject<{
|
|
|
67
70
|
ts: "ts";
|
|
68
71
|
python: "python";
|
|
69
72
|
}>>;
|
|
70
|
-
timeout_seconds: z.ZodOptional<z.ZodNumber
|
|
73
|
+
timeout_seconds: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
|
|
74
|
+
from: z.ZodString;
|
|
75
|
+
default: z.ZodNumber;
|
|
76
|
+
}, z.core.$strict>]>>;
|
|
71
77
|
prompt: z.ZodOptional<z.ZodString>;
|
|
72
78
|
skill: z.ZodOptional<z.ZodString>;
|
|
73
79
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -80,6 +86,7 @@ declare const PhaseDefinitionSchema: z.ZodObject<{
|
|
|
80
86
|
docker: "docker";
|
|
81
87
|
none: "none";
|
|
82
88
|
}>>;
|
|
89
|
+
skip_if: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
83
90
|
sandbox_image: z.ZodOptional<z.ZodEnum<{
|
|
84
91
|
default: "default";
|
|
85
92
|
qa: "qa";
|
|
@@ -116,7 +123,10 @@ declare const PhaseDefinitionSchema: z.ZodObject<{
|
|
|
116
123
|
}, z.core.$strip>>;
|
|
117
124
|
}, z.core.$strip>>;
|
|
118
125
|
generic_loop: z.ZodOptional<z.ZodObject<{
|
|
119
|
-
max_iterations: z.ZodNumber
|
|
126
|
+
max_iterations: z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
|
|
127
|
+
from: z.ZodString;
|
|
128
|
+
default: z.ZodNumber;
|
|
129
|
+
}, z.core.$strict>]>;
|
|
120
130
|
until: z.ZodOptional<z.ZodString>;
|
|
121
131
|
until_bash: z.ZodOptional<z.ZodString>;
|
|
122
132
|
interactive: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -179,6 +189,11 @@ export type PhaseDefinition = z.infer<typeof PhaseDefinitionSchema>;
|
|
|
179
189
|
* (e.g. `prompt:`-only or `context:` phases).
|
|
180
190
|
*/
|
|
181
191
|
export declare function phaseSkillNames(phase: PhaseDefinition): string[];
|
|
192
|
+
/**
|
|
193
|
+
* Normalize a phase's `skip_if` declaration to a list of expressions.
|
|
194
|
+
* Returns `[]` for phases with no guard. Mirrors {@link phaseSkillNames}.
|
|
195
|
+
*/
|
|
196
|
+
export declare function phaseSkipIfExpressions(phase: PhaseDefinition): string[];
|
|
182
197
|
export type PhaseLoop = z.infer<typeof PhaseLoopSchema>;
|
|
183
198
|
export type GenericLoop = z.infer<typeof GenericLoopSchema>;
|
|
184
199
|
export type OutputRule = z.infer<typeof OutputRuleSchema>;
|
|
@@ -200,6 +215,7 @@ export declare const AgentWorkflowSchema: z.ZodObject<{
|
|
|
200
215
|
name: z.ZodString;
|
|
201
216
|
description: z.ZodOptional<z.ZodString>;
|
|
202
217
|
trigger: z.ZodOptional<z.ZodString>;
|
|
218
|
+
pr_scoped: z.ZodOptional<z.ZodBoolean>;
|
|
203
219
|
status_checklist: z.ZodOptional<z.ZodBoolean>;
|
|
204
220
|
final_message: z.ZodOptional<z.ZodString>;
|
|
205
221
|
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -225,7 +241,10 @@ export declare const AgentWorkflowSchema: z.ZodObject<{
|
|
|
225
241
|
ts: "ts";
|
|
226
242
|
python: "python";
|
|
227
243
|
}>>;
|
|
228
|
-
timeout_seconds: z.ZodOptional<z.ZodNumber
|
|
244
|
+
timeout_seconds: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
|
|
245
|
+
from: z.ZodString;
|
|
246
|
+
default: z.ZodNumber;
|
|
247
|
+
}, z.core.$strict>]>>;
|
|
229
248
|
prompt: z.ZodOptional<z.ZodString>;
|
|
230
249
|
skill: z.ZodOptional<z.ZodString>;
|
|
231
250
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -238,6 +257,7 @@ export declare const AgentWorkflowSchema: z.ZodObject<{
|
|
|
238
257
|
docker: "docker";
|
|
239
258
|
none: "none";
|
|
240
259
|
}>>;
|
|
260
|
+
skip_if: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
241
261
|
sandbox_image: z.ZodOptional<z.ZodEnum<{
|
|
242
262
|
default: "default";
|
|
243
263
|
qa: "qa";
|
|
@@ -274,7 +294,10 @@ export declare const AgentWorkflowSchema: z.ZodObject<{
|
|
|
274
294
|
}, z.core.$strip>>;
|
|
275
295
|
}, z.core.$strip>>;
|
|
276
296
|
generic_loop: z.ZodOptional<z.ZodObject<{
|
|
277
|
-
max_iterations: z.ZodNumber
|
|
297
|
+
max_iterations: z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
|
|
298
|
+
from: z.ZodString;
|
|
299
|
+
default: z.ZodNumber;
|
|
300
|
+
}, z.core.$strict>]>;
|
|
278
301
|
until: z.ZodOptional<z.ZodString>;
|
|
279
302
|
until_bash: z.ZodOptional<z.ZodString>;
|
|
280
303
|
interactive: z.ZodDefault<z.ZodBoolean>;
|
package/dist/core/schema.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { TemplatedNumberSchema } from "./templated-number.js";
|
|
2
3
|
// ── Output rules ──────────────────────────────────────────────────────
|
|
3
4
|
const OutputRuleSchema = z.object({
|
|
4
5
|
action: z.enum(["fail", "continue", "pause"]),
|
|
@@ -57,7 +58,11 @@ const PhaseLoopSchema = z.object({
|
|
|
57
58
|
});
|
|
58
59
|
const GenericLoopSchema = z
|
|
59
60
|
.object({
|
|
60
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Iteration bound. Accepts `{ from: <ctx path>, default: N }` — see
|
|
63
|
+
* {@link TemplatedNumberSchema}; the fix loop reads `fix.localIterations`.
|
|
64
|
+
*/
|
|
65
|
+
max_iterations: TemplatedNumberSchema,
|
|
61
66
|
/** Expression to evaluate for completion: "output.contains('PASS')" or "verdict == 'APPROVED'" */
|
|
62
67
|
until: z.string().optional(),
|
|
63
68
|
/** Shell command: exit 0 = loop complete, non-zero = continue */
|
|
@@ -165,10 +170,17 @@ const PhaseDefinitionSchema = z
|
|
|
165
170
|
*/
|
|
166
171
|
runtime: z.enum(["js", "ts", "python"]).optional(),
|
|
167
172
|
/**
|
|
168
|
-
* Per-step timeout in seconds for `bash`/`script` phases
|
|
169
|
-
*
|
|
173
|
+
* Per-step timeout in seconds for `bash`/`script` phases, and for an agent
|
|
174
|
+
* phase's `generic_loop.until_bash` gate. Defaults to the sandbox's
|
|
175
|
+
* configured timeout (fallback 300s for deterministic steps, 30s for a
|
|
176
|
+
* loop condition).
|
|
177
|
+
*
|
|
178
|
+
* Accepts `{ from: <ctx path>, default: N }` — see
|
|
179
|
+
* {@link TemplatedNumberSchema}. `pr-fix` / `dependabot-ci-fix` read
|
|
180
|
+
* `fix.gateTimeoutSeconds` that way, so the repo-clamped config value is
|
|
181
|
+
* what actually bounds the gate.
|
|
170
182
|
*/
|
|
171
|
-
timeout_seconds:
|
|
183
|
+
timeout_seconds: TemplatedNumberSchema.optional(),
|
|
172
184
|
/**
|
|
173
185
|
* Path to a prompt template file (relative to workflowDir).
|
|
174
186
|
* Mutually exclusive with `skill`.
|
|
@@ -268,6 +280,47 @@ const PhaseDefinitionSchema = z
|
|
|
268
280
|
* to surface why the phase was skipped.
|
|
269
281
|
*/
|
|
270
282
|
requires_sandbox: z.enum(["docker", "gondolin", "none"]).optional(),
|
|
283
|
+
/**
|
|
284
|
+
* Conditional gate: skip this phase when any of these expressions matches
|
|
285
|
+
* the run's render context. One string, or a list (OR-ed).
|
|
286
|
+
*
|
|
287
|
+
* Same non-failing skip as `requires_sandbox` above — the node goes
|
|
288
|
+
* `skipped`, a `recordSkippedPhase` row lands, `messages.on_skipped_done`
|
|
289
|
+
* is surfaced, and the **run still records `succeeded`**. That last part is
|
|
290
|
+
* the whole point, and is why this exists rather than being expressed with
|
|
291
|
+
* the pre-existing `on_output.contains_BLOCKED: { action: fail }`: a phase
|
|
292
|
+
* whose *correct* outcome is "there is nothing for the next phase to do"
|
|
293
|
+
* must not paint the run red. A red run posts `messages.on_failure` to the
|
|
294
|
+
* PR, offers the dashboard's Retry button for something that cannot
|
|
295
|
+
* succeed, pollutes the cost/failure stats, and — because
|
|
296
|
+
* `latestSucceededForTrigger` ignores failed runs — defeats the
|
|
297
|
+
* already-handled-this-SHA dedup, so the same dead end is re-diagnosed on
|
|
298
|
+
* every webhook re-fire.
|
|
299
|
+
*
|
|
300
|
+
* Expressions use the `until:` grammar (see `core/loop-eval.ts`) evaluated
|
|
301
|
+
* against `{ ...ctx, phaseOutputs, scratch }` — the same values a prompt
|
|
302
|
+
* template can render. `output` is empty here (the phase has not run), so
|
|
303
|
+
* only bare `output.contains(...)` is meaningless; read what an upstream
|
|
304
|
+
* phase left behind instead. Prefer a value a phase already PARSED into
|
|
305
|
+
* `scratch` (e.g. `scratch.fixMarkers.diagnosis.class == 'flaky'`) over a
|
|
306
|
+
* `.contains()` against `phaseOutputs.<phase>`: the latter is a substring
|
|
307
|
+
* match on the agent's whole free-form output, so prose that merely
|
|
308
|
+
* mentions the needle matches it, and it is empty across a resume boundary
|
|
309
|
+
* (below) where it then fails open.
|
|
310
|
+
*
|
|
311
|
+
* Two scoping notes:
|
|
312
|
+
* - `phaseOutputs` is empty across a **resume** boundary (a phase skipped
|
|
313
|
+
* as already-`done` contributes nothing to the in-memory map), so a
|
|
314
|
+
* guard that must survive resume should read `scratch`, which the run
|
|
315
|
+
* store rehydrates.
|
|
316
|
+
* - The guard is evaluated when the node becomes *ready*, i.e. after its
|
|
317
|
+
* dependencies are terminal — which is what makes reading an upstream
|
|
318
|
+
* phase's output well-defined.
|
|
319
|
+
*
|
|
320
|
+
* A skipped node is not `succeeded`, so the same `trigger_rule` caveat as
|
|
321
|
+
* `requires_sandbox` applies to anything downstream of a guarded phase.
|
|
322
|
+
*/
|
|
323
|
+
skip_if: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(),
|
|
271
324
|
/**
|
|
272
325
|
* Which docker sandbox image this phase runs in. `default` (or omitted) uses
|
|
273
326
|
* the lean `lastlight-sandbox:latest`; `qa` uses the heavier
|
|
@@ -364,6 +417,15 @@ export function phaseSkillNames(phase) {
|
|
|
364
417
|
return [phase.skill];
|
|
365
418
|
return [];
|
|
366
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* Normalize a phase's `skip_if` declaration to a list of expressions.
|
|
422
|
+
* Returns `[]` for phases with no guard. Mirrors {@link phaseSkillNames}.
|
|
423
|
+
*/
|
|
424
|
+
export function phaseSkipIfExpressions(phase) {
|
|
425
|
+
if (phase.skip_if === undefined)
|
|
426
|
+
return [];
|
|
427
|
+
return typeof phase.skip_if === "string" ? [phase.skip_if] : phase.skip_if;
|
|
428
|
+
}
|
|
367
429
|
// ── Agent workflow ────────────────────────────────────────────────────
|
|
368
430
|
//
|
|
369
431
|
// "Agent workflows" are the unified definition for everything Last Light does
|
|
@@ -403,6 +465,32 @@ export const AgentWorkflowSchema = z.object({
|
|
|
403
465
|
description: z.string().optional(),
|
|
404
466
|
/** What can trigger this workflow (informational; routing is in code). */
|
|
405
467
|
trigger: z.string().optional(),
|
|
468
|
+
/**
|
|
469
|
+
* This workflow is dispatched against a PULL REQUEST, and must therefore
|
|
470
|
+
* cross the PR-scoped dispatch gate.
|
|
471
|
+
*
|
|
472
|
+
* Unlike `kind` (a dashboard label the runner ignores) this one is
|
|
473
|
+
* load-bearing. Declaring it puts the workflow inside:
|
|
474
|
+
*
|
|
475
|
+
* - the **PR-scoped run lock** — one PR-scoped run per PR at a time, across
|
|
476
|
+
* every member, so two agents never clone and push the same branch;
|
|
477
|
+
* - the **already-assessed-at-this-head-SHA dedup**, per workflow;
|
|
478
|
+
* - **escalation** — a terminal skip labels the PR and comments once,
|
|
479
|
+
* rather than being dropped silently;
|
|
480
|
+
* - the resolved **`PrState` snapshot** on `context.prState`, which is what
|
|
481
|
+
* the fix prompts, the PR journal and the admin panel all render from.
|
|
482
|
+
*
|
|
483
|
+
* It is metadata on the workflow because that is where the fact lives. The
|
|
484
|
+
* harness used to carry a hardcoded set of four names while the handlers are
|
|
485
|
+
* operator-configurable through `routes.github.*`, so remapping a route to a
|
|
486
|
+
* forked workflow silently dropped the whole gate for it — no lock, no dedup,
|
|
487
|
+
* no escalation, and no warning (issue #256). `validateAssets` now warns when
|
|
488
|
+
* a configured `routes.github.pr_*` target does not declare this.
|
|
489
|
+
*
|
|
490
|
+
* The consuming set is `prScopedWorkflows()` in
|
|
491
|
+
* `apps/server/src/workflows/pr-scope.ts`.
|
|
492
|
+
*/
|
|
493
|
+
pr_scoped: z.boolean().optional(),
|
|
406
494
|
/**
|
|
407
495
|
* Render progress as a single in-place "task list" comment/message that is
|
|
408
496
|
* edited as phases run, instead of posting a new comment per phase. When
|
package/dist/core/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A numeric phase budget that may be READ FROM THE RUN'S CONTEXT rather than
|
|
3
|
+
* frozen in the YAML.
|
|
4
|
+
*
|
|
5
|
+
* ## Why this exists
|
|
6
|
+
*
|
|
7
|
+
* `fix.localIterations` and `fix.gateTimeoutSeconds` were parsed, typed,
|
|
8
|
+
* clamped per repository, displayed by the CLI and documented on both doc
|
|
9
|
+
* surfaces — and read by nothing (issue #256). The two numbers that actually
|
|
10
|
+
* governed the fix loop were the literals in `workflows/pr-fix.yaml` and
|
|
11
|
+
* `workflows/dependabot-ci-fix.yaml`, whose comments asked the reader to "keep
|
|
12
|
+
* the two in step by hand". A config key whose only effect is to disagree with
|
|
13
|
+
* the running value is worse than no key: the admin panel, `lastlight repo
|
|
14
|
+
* config show` and a repo's `.lastlight/lastlight.yml` all reported a budget
|
|
15
|
+
* the loop was not running under.
|
|
16
|
+
*
|
|
17
|
+
* ## The shape, and why it is not a bare `{{template}}`
|
|
18
|
+
*
|
|
19
|
+
* ```yaml
|
|
20
|
+
* timeout_seconds: { from: fix.gateTimeoutSeconds, default: 900 }
|
|
21
|
+
* generic_loop:
|
|
22
|
+
* max_iterations: { from: fix.localIterations, default: 2 }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* A bare `"{{fix.gateTimeoutSeconds}}"` would have been shorter and worse.
|
|
26
|
+
* `renderTemplate` resolves an absent key to the EMPTY STRING, so every
|
|
27
|
+
* unresolvable reference would need an invented fallback somewhere in the
|
|
28
|
+
* engine — a made-up number for a phase's kill timeout, chosen far from the
|
|
29
|
+
* workflow that depends on it. Here the fallback is stated by the workflow
|
|
30
|
+
* itself, next to the reference, and it is the packaged value: the YAML still
|
|
31
|
+
* says what this loop does out of the box, and the `from:` says where a
|
|
32
|
+
* deployment or a repository may move it. (It also keeps `{{` out of a field
|
|
33
|
+
* neighbouring `generic_loop.until_bash`, which `validateShellCommand` rejects
|
|
34
|
+
* outright.)
|
|
35
|
+
*
|
|
36
|
+
* ## What resolution guarantees
|
|
37
|
+
*
|
|
38
|
+
* The `from:` path is looked up in the run's template context — the same
|
|
39
|
+
* two-level dot walk `{{a.b}}` uses, so `fix.localIterations` resolves against
|
|
40
|
+
* the EFFECTIVE, already repo-clamped `fix` block seeded on the context by the
|
|
41
|
+
* runner. A repo that lowered its own budget is honoured for free; a repo that
|
|
42
|
+
* tried to raise it was clamped before it ever reached here.
|
|
43
|
+
*
|
|
44
|
+
* Anything else — key absent, non-numeric, zero, negative, `NaN` — falls back
|
|
45
|
+
* to `default` and warns. It never throws and never yields a non-positive
|
|
46
|
+
* number, because both consumers are a kill timeout and a loop bound, where
|
|
47
|
+
* `0` means "never run" and a negative means nothing at all.
|
|
48
|
+
*/
|
|
49
|
+
import { z } from "zod";
|
|
50
|
+
import { type TemplateContext } from "./templates.js";
|
|
51
|
+
/**
|
|
52
|
+
* A phase budget: a literal, or a reference into the run context with the
|
|
53
|
+
* packaged value as its declared fallback.
|
|
54
|
+
*
|
|
55
|
+
* `.strict()` on the object arm so a typo (`form:`, `defaults:`) is a load
|
|
56
|
+
* error naming the workflow, not a silent fall back to a default the author
|
|
57
|
+
* never meant to be operative.
|
|
58
|
+
*/
|
|
59
|
+
export declare const TemplatedNumberSchema: z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
|
|
60
|
+
from: z.ZodString;
|
|
61
|
+
default: z.ZodNumber;
|
|
62
|
+
}, z.core.$strict>]>;
|
|
63
|
+
export type TemplatedNumber = z.infer<typeof TemplatedNumberSchema>;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a {@link TemplatedNumber} against a run's context.
|
|
66
|
+
*
|
|
67
|
+
* `undefined` in, `undefined` out — the fields this governs are optional and
|
|
68
|
+
* their callers supply their own absent-value behaviour (`?? 30` for a
|
|
69
|
+
* command phase's timeout).
|
|
70
|
+
*
|
|
71
|
+
* A resolved non-integer is rounded UP rather than rejected: the only duration
|
|
72
|
+
* key that reaches here (`fix.gateTimeoutSeconds`) is documented as accepting
|
|
73
|
+
* any positive number, and truncating a test-suite budget downward is the one
|
|
74
|
+
* rounding direction that can turn a passing gate red.
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveTemplatedNumber(value: TemplatedNumber | undefined, ctx: TemplateContext,
|
|
77
|
+
/** Names the phase/field in the warning, e.g. `fix.timeout_seconds`. */
|
|
78
|
+
where: string): number | undefined;
|