zelari-code 2.3.0 → 2.5.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/cli/budget/historySummary.js +40 -2
- package/dist/cli/budget/historySummary.js.map +1 -1
- package/dist/cli/budget/modelContextBuilder.js +126 -0
- package/dist/cli/budget/modelContextBuilder.js.map +1 -0
- package/dist/cli/budget/persistCompact.js +67 -0
- package/dist/cli/budget/persistCompact.js.map +1 -0
- package/dist/cli/budget/tokenBudget.js +47 -13
- package/dist/cli/budget/tokenBudget.js.map +1 -1
- package/dist/cli/compaction.js +5 -0
- package/dist/cli/compaction.js.map +1 -1
- package/dist/cli/gauntlet/blind.js +38 -0
- package/dist/cli/gauntlet/blind.js.map +1 -0
- package/dist/cli/gauntlet/complete.js +90 -0
- package/dist/cli/gauntlet/complete.js.map +1 -0
- package/dist/cli/gauntlet/decompose.js +163 -0
- package/dist/cli/gauntlet/decompose.js.map +1 -0
- package/dist/cli/gauntlet/events.js +30 -0
- package/dist/cli/gauntlet/events.js.map +1 -0
- package/dist/cli/gauntlet/loop.js +142 -0
- package/dist/cli/gauntlet/loop.js.map +1 -0
- package/dist/cli/gauntlet/policy.js +61 -0
- package/dist/cli/gauntlet/policy.js.map +1 -0
- package/dist/cli/gauntlet/prompts.js +70 -0
- package/dist/cli/gauntlet/prompts.js.map +1 -0
- package/dist/cli/gauntlet/run.js +213 -0
- package/dist/cli/gauntlet/run.js.map +1 -0
- package/dist/cli/gauntlet/schedule.js +34 -0
- package/dist/cli/gauntlet/schedule.js.map +1 -0
- package/dist/cli/gauntlet/verdict.js +58 -0
- package/dist/cli/gauntlet/verdict.js.map +1 -0
- package/dist/cli/headless.js +11 -0
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/headlessSpine.js +3 -2
- package/dist/cli/headlessSpine.js.map +1 -1
- package/dist/cli/hooks/historyCompaction.js +56 -8
- package/dist/cli/hooks/historyCompaction.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +52 -68
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/main.bundled.js +2654 -908
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/metrics.js +16 -0
- package/dist/cli/metrics.js.map +1 -1
- package/dist/cli/runHeadless.js +109 -10
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionSpine.js +65 -7
- package/dist/cli/sessionSpine.js.map +1 -1
- package/dist/cli/toolRegistry.js +13 -6
- package/dist/cli/toolRegistry.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot non-streaming JSON completion for Gauntlet decompose.
|
|
3
|
+
* Fail-fast (default 60s): a slow reasoner must not stall the loop —
|
|
4
|
+
* the caller falls back to a single piece.
|
|
5
|
+
*/
|
|
6
|
+
import { getModelForProvider, getProviderConfig } from '../providerConfig.js';
|
|
7
|
+
import { resolveApiKeyWithMeta } from '../keyStore.js';
|
|
8
|
+
import { resolveBaseUrl } from '../provider/openai-compatible.js';
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 60_000;
|
|
10
|
+
const DEFAULT_MAX_TOKENS = 2048;
|
|
11
|
+
function timeoutMs(env = process.env) {
|
|
12
|
+
const raw = env.ZELARI_GAUNTLET_DECOMPOSE_TIMEOUT_MS;
|
|
13
|
+
if (raw === undefined || raw === '')
|
|
14
|
+
return DEFAULT_TIMEOUT_MS;
|
|
15
|
+
const n = Number.parseInt(raw, 10);
|
|
16
|
+
return Number.isFinite(n) && n >= 0 ? n : DEFAULT_TIMEOUT_MS;
|
|
17
|
+
}
|
|
18
|
+
export async function gauntletComplete(args, opts) {
|
|
19
|
+
const provider = opts.provider;
|
|
20
|
+
const meta = await resolveApiKeyWithMeta(provider);
|
|
21
|
+
if (!meta?.apiKey) {
|
|
22
|
+
throw new Error(`No API key for provider '${provider}'`);
|
|
23
|
+
}
|
|
24
|
+
const baseUrl = resolveBaseUrl(provider);
|
|
25
|
+
if (!baseUrl) {
|
|
26
|
+
throw new Error(`No base URL for provider '${provider}'`);
|
|
27
|
+
}
|
|
28
|
+
const model = process.env.ZELARI_KRAKEN_PLANNER_MODEL?.trim() ||
|
|
29
|
+
opts.model ||
|
|
30
|
+
getModelForProvider(provider) ||
|
|
31
|
+
getProviderConfig().modelByProvider[provider] ||
|
|
32
|
+
'';
|
|
33
|
+
if (!model)
|
|
34
|
+
throw new Error(`No model for provider '${provider}'`);
|
|
35
|
+
const ms = timeoutMs();
|
|
36
|
+
const controller = new AbortController();
|
|
37
|
+
const onParentAbort = () => controller.abort();
|
|
38
|
+
opts.signal?.addEventListener('abort', onParentAbort, { once: true });
|
|
39
|
+
let timedOut = false;
|
|
40
|
+
const timer = ms > 0
|
|
41
|
+
? setTimeout(() => {
|
|
42
|
+
timedOut = true;
|
|
43
|
+
controller.abort();
|
|
44
|
+
}, ms)
|
|
45
|
+
: undefined;
|
|
46
|
+
try {
|
|
47
|
+
const url = `${baseUrl.replace(/\/$/, '')}/chat/completions`;
|
|
48
|
+
const res = await fetch(url, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
signal: controller.signal,
|
|
51
|
+
headers: {
|
|
52
|
+
'content-type': 'application/json',
|
|
53
|
+
authorization: `Bearer ${meta.apiKey}`,
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify({
|
|
56
|
+
model,
|
|
57
|
+
temperature: 0.2,
|
|
58
|
+
max_tokens: DEFAULT_MAX_TOKENS,
|
|
59
|
+
stream: false,
|
|
60
|
+
messages: [
|
|
61
|
+
{ role: 'system', content: args.system },
|
|
62
|
+
{ role: 'user', content: args.user },
|
|
63
|
+
],
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
const errBody = await res.text().catch(() => '');
|
|
68
|
+
throw new Error(`decompose HTTP ${res.status}${errBody ? `: ${errBody.slice(0, 160)}` : ''}`);
|
|
69
|
+
}
|
|
70
|
+
const json = (await res.json());
|
|
71
|
+
const msg = json.choices?.[0]?.message;
|
|
72
|
+
const text = msg?.content?.trim() || msg?.reasoning_content?.trim() || '';
|
|
73
|
+
if (!text)
|
|
74
|
+
throw new Error('decompose: empty model response');
|
|
75
|
+
return text;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
if (timedOut) {
|
|
79
|
+
throw new Error(`decompose timed out after ${Math.round(ms / 1000)}s — using a single piece. ` +
|
|
80
|
+
'Raise ZELARI_GAUNTLET_DECOMPOSE_TIMEOUT_MS or set ZELARI_KRAKEN_PLANNER_MODEL to a fast model.');
|
|
81
|
+
}
|
|
82
|
+
throw err instanceof Error ? err : new Error(String(err));
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
if (timer)
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
opts.signal?.removeEventListener('abort', onParentAbort);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=complete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../../src/cli/gauntlet/complete.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gauntlet pieces. Structured JSON from a decomposer; never invented from
|
|
3
|
+
* free prose. Invalid/empty replies fall back to one piece = the Goal.
|
|
4
|
+
*/
|
|
5
|
+
import { extractJsonObject } from '../kraken/planner.js';
|
|
6
|
+
const MAX_LABEL = 80;
|
|
7
|
+
const MAX_PROMPT = 8_000;
|
|
8
|
+
const MAX_ACCEPTANCE = 8;
|
|
9
|
+
export function fallbackPieces(goal) {
|
|
10
|
+
const prompt = goal.trim() || 'Complete the user Goal.';
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
id: 'g1',
|
|
14
|
+
label: labelFromGoal(prompt),
|
|
15
|
+
prompt,
|
|
16
|
+
acceptance: [],
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
export function labelFromGoal(goal) {
|
|
21
|
+
const line = goal.trim().split(/\r?\n/, 1)[0] ?? 'Goal';
|
|
22
|
+
return line.slice(0, MAX_LABEL) || 'Goal';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse `{ pieces: [...] }` or `{ nodes: [...] }` from a model reply.
|
|
26
|
+
* Invalid / empty → null (caller falls back).
|
|
27
|
+
*/
|
|
28
|
+
export function parsePiecesJson(raw, maxPieces) {
|
|
29
|
+
if (!raw || typeof raw !== 'object')
|
|
30
|
+
return null;
|
|
31
|
+
const rec = raw;
|
|
32
|
+
const list = rec.pieces ?? rec.nodes;
|
|
33
|
+
if (!Array.isArray(list) || list.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
const out = [];
|
|
36
|
+
for (let i = 0; i < list.length && out.length < maxPieces; i++) {
|
|
37
|
+
const item = list[i];
|
|
38
|
+
if (!item || typeof item !== 'object')
|
|
39
|
+
continue;
|
|
40
|
+
const row = item;
|
|
41
|
+
const prompt = typeof row.prompt === 'string'
|
|
42
|
+
? row.prompt.trim()
|
|
43
|
+
: typeof row.goal === 'string'
|
|
44
|
+
? row.goal.trim()
|
|
45
|
+
: '';
|
|
46
|
+
if (!prompt)
|
|
47
|
+
continue;
|
|
48
|
+
const id = typeof row.id === 'string' && row.id.trim()
|
|
49
|
+
? row.id.trim().slice(0, 32)
|
|
50
|
+
: `g${out.length + 1}`;
|
|
51
|
+
const label = typeof row.label === 'string' && row.label.trim()
|
|
52
|
+
? row.label.trim().slice(0, MAX_LABEL)
|
|
53
|
+
: labelFromGoal(prompt);
|
|
54
|
+
const acceptance = Array.isArray(row.acceptance)
|
|
55
|
+
? row.acceptance
|
|
56
|
+
.filter((a) => typeof a === 'string' && a.trim().length > 0)
|
|
57
|
+
.map((a) => a.trim())
|
|
58
|
+
.slice(0, MAX_ACCEPTANCE)
|
|
59
|
+
: [];
|
|
60
|
+
const scope = Array.isArray(row.scope)
|
|
61
|
+
? row.scope
|
|
62
|
+
.filter((s) => typeof s === 'string' && s.trim().length > 0)
|
|
63
|
+
.map((s) => s.trim())
|
|
64
|
+
.slice(0, 16)
|
|
65
|
+
: undefined;
|
|
66
|
+
const bar = Array.isArray(row.bar)
|
|
67
|
+
? row.bar
|
|
68
|
+
.filter((s) => typeof s === 'string' && s.trim().length > 0)
|
|
69
|
+
.map((s) => s.trim())
|
|
70
|
+
.slice(0, 4)
|
|
71
|
+
: undefined;
|
|
72
|
+
out.push({
|
|
73
|
+
id: uniqueId(id, out),
|
|
74
|
+
label,
|
|
75
|
+
prompt: prompt.slice(0, MAX_PROMPT),
|
|
76
|
+
acceptance,
|
|
77
|
+
...(scope && scope.length > 0 ? { scope } : {}),
|
|
78
|
+
...(bar && bar.length > 0 ? { bar } : {}),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return out.length > 0 ? out : null;
|
|
82
|
+
}
|
|
83
|
+
export const GAUNTLET_DECOMPOSE_SYSTEM = [
|
|
84
|
+
'Decompose the user Goal into independently shippable Gauntlet pieces.',
|
|
85
|
+
'Return ONLY JSON (no markdown, no prose):',
|
|
86
|
+
'{ "pieces": [ { "id": string, "label": string, "prompt": string, "scope"?: string[], "acceptance"?: string[], "bar"?: string[] } ] }',
|
|
87
|
+
'Rules:',
|
|
88
|
+
'- 1 to N pieces (N is given in the user message). Prefer fewer. One piece is valid when the goal is atomic.',
|
|
89
|
+
'- "prompt" is self-contained: the builder will not see this conversation.',
|
|
90
|
+
'- "scope" is a path allowlist so disjoint pieces can run in parallel. Omit if unsure (forces sequential).',
|
|
91
|
+
'- "acceptance" is checkable (file, command, observable). Never subjective ("elegant").',
|
|
92
|
+
'- "bar" (optional) is on-disk reference path(s) the critic compares against blindly (gold file, screenshot, test).',
|
|
93
|
+
'- Use paths from the workspace listing. Do not invent a tree.',
|
|
94
|
+
'- Decompose the USER GOAL literally. Do not enlarge it into a different project.',
|
|
95
|
+
].join('\n');
|
|
96
|
+
export function formatHistoryNote(messages, maxMessages = 4, each = 400) {
|
|
97
|
+
const slice = messages
|
|
98
|
+
.filter((m) => m.role === 'user' || m.role === 'assistant')
|
|
99
|
+
.slice(-maxMessages);
|
|
100
|
+
if (slice.length === 0)
|
|
101
|
+
return '';
|
|
102
|
+
return slice
|
|
103
|
+
.map((m) => {
|
|
104
|
+
const body = m.content.replace(/\s+/g, ' ').trim().slice(0, each);
|
|
105
|
+
return `${m.role}: ${body}`;
|
|
106
|
+
})
|
|
107
|
+
.join('\n');
|
|
108
|
+
}
|
|
109
|
+
export function buildDecomposeUser(opts) {
|
|
110
|
+
const parts = [
|
|
111
|
+
`Max pieces: ${opts.maxPieces}`,
|
|
112
|
+
'',
|
|
113
|
+
'## Goal',
|
|
114
|
+
opts.goal.trim() || '(empty)',
|
|
115
|
+
];
|
|
116
|
+
if (opts.historyNote?.trim()) {
|
|
117
|
+
parts.push('', '## Prior turns (context only — the Goal above is authoritative)', opts.historyNote.trim());
|
|
118
|
+
}
|
|
119
|
+
if (opts.workspace?.trim()) {
|
|
120
|
+
parts.push('', '## Workspace', opts.workspace.trim());
|
|
121
|
+
}
|
|
122
|
+
return parts.join('\n');
|
|
123
|
+
}
|
|
124
|
+
export function piecesFromModelText(text, maxPieces) {
|
|
125
|
+
try {
|
|
126
|
+
const json = extractJsonObject(text, { requireKey: 'pieces' });
|
|
127
|
+
return parsePiecesJson(json, maxPieces);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export async function decomposeGoal(opts) {
|
|
134
|
+
const fallback = fallbackPieces(opts.goal);
|
|
135
|
+
if (!opts.complete)
|
|
136
|
+
return { pieces: fallback, source: 'fallback' };
|
|
137
|
+
try {
|
|
138
|
+
const text = await opts.complete({
|
|
139
|
+
system: GAUNTLET_DECOMPOSE_SYSTEM,
|
|
140
|
+
user: buildDecomposeUser(opts),
|
|
141
|
+
});
|
|
142
|
+
const parsed = piecesFromModelText(text, opts.maxPieces);
|
|
143
|
+
if (parsed && parsed.length > 0)
|
|
144
|
+
return { pieces: parsed, source: 'llm' };
|
|
145
|
+
return { pieces: fallback, source: 'fallback', error: 'decompose JSON unusable' };
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
return {
|
|
149
|
+
pieces: fallback,
|
|
150
|
+
source: 'fallback',
|
|
151
|
+
error: err instanceof Error ? err.message : String(err),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function uniqueId(id, existing) {
|
|
156
|
+
if (!existing.some((p) => p.id === id))
|
|
157
|
+
return id;
|
|
158
|
+
let n = 2;
|
|
159
|
+
while (existing.some((p) => p.id === `${id}-${n}`))
|
|
160
|
+
n += 1;
|
|
161
|
+
return `${id}-${n}`;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=decompose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../../src/cli/gauntlet/decompose.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAYzD,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,UAAU,GAAG,KAAK,CAAC;AACzB,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,yBAAyB,CAAC;IACxD,OAAO;QACL;YACE,EAAE,EAAE,IAAI;YACR,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC;YAC5B,MAAM;YACN,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACxD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,SAAiB;IAC7D,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,SAAS;QAChD,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,MAAM,MAAM,GACV,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ;YAC5B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;YACnB,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAC5B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;gBACjB,CAAC,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,EAAE,GACN,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;YACzC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5B,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,GACT,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;YAC/C,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;YACtC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAC9C,CAAC,CAAC,GAAG,CAAC,UAAU;iBACX,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;iBACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC;YAC7B,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YACpC,CAAC,CAAC,GAAG,CAAC,KAAK;iBACN,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;iBACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YACjB,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAChC,CAAC,CAAC,GAAG,CAAC,GAAG;iBACJ,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;iBACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAChB,CAAC,CAAC,SAAS,CAAC;QACd,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;YACrB,KAAK;YACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;YACnC,UAAU;YACV,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,uEAAuE;IACvE,2CAA2C;IAC3C,sIAAsI;IACtI,QAAQ;IACR,6GAA6G;IAC7G,2EAA2E;IAC3E,2GAA2G;IAC3G,wFAAwF;IACxF,oHAAoH;IACpH,+DAA+D;IAC/D,kFAAkF;CACnF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,UAAU,iBAAiB,CAC/B,QAA0D,EAC1D,WAAW,GAAG,CAAC,EACf,IAAI,GAAG,GAAG;IAEV,MAAM,KAAK,GAAG,QAAQ;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC;SAC1D,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;IACvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAClE,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;IAC9B,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAKlC;IACC,MAAM,KAAK,GAAG;QACZ,eAAe,IAAI,CAAC,SAAS,EAAE;QAC/B,EAAE;QACF,SAAS;QACT,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,SAAS;KAC9B,CAAC;IACF,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,iEAAiE,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7G,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,SAAiB;IACjE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,OAAO,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAMnC;IACC,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACpE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;YAC/B,MAAM,EAAE,yBAAyB;YACjC,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC;SAC/B,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC1E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IACpF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAU,EAAE,QAAyB;IACrD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAAE,OAAO,EAAE,CAAC;IAClD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;QAAE,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function gauntletProgressEvent(sessionId, progress) {
|
|
2
|
+
return {
|
|
3
|
+
type: 'gauntlet_progress',
|
|
4
|
+
sessionId,
|
|
5
|
+
ts: Date.now(),
|
|
6
|
+
progress,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function formatGauntletSummary(results, opts) {
|
|
10
|
+
if (results.length === 0) {
|
|
11
|
+
if (opts?.timedOut)
|
|
12
|
+
return 'Gauntlet stopped: wall clock. No pieces finished.';
|
|
13
|
+
if (opts?.cancelled)
|
|
14
|
+
return 'Gauntlet cancelled. No pieces finished.';
|
|
15
|
+
return 'Gauntlet: no pieces ran.';
|
|
16
|
+
}
|
|
17
|
+
const head = opts?.timedOut
|
|
18
|
+
? 'Gauntlet stopped: wall clock.'
|
|
19
|
+
: opts?.cancelled
|
|
20
|
+
? 'Gauntlet cancelled.'
|
|
21
|
+
: 'Gauntlet finished.';
|
|
22
|
+
const lines = [head, ''];
|
|
23
|
+
for (const r of results) {
|
|
24
|
+
const gap = r.gap ? ` — ${r.gap}` : '';
|
|
25
|
+
const win = r.winner ? ` [A/B ${r.winner}]` : '';
|
|
26
|
+
lines.push(`- ${r.label} (${r.id}): ${r.verdict} after ${r.rounds} round(s)${win}${gap}`);
|
|
27
|
+
}
|
|
28
|
+
return lines.join('\n');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/cli/gauntlet/events.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,qBAAqB,CACnC,SAAiB,EACjB,QAA8B;IAE9B,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,SAAS;QACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;QACd,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAOE,EACF,IAAkD;IAElD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,IAAI,EAAE,QAAQ;YAAE,OAAO,mDAAmD,CAAC;QAC/E,IAAI,IAAI,EAAE,SAAS;YAAE,OAAO,yCAAyC,CAAC;QACtE,OAAO,0BAA0B,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,EAAE,QAAQ;QACzB,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,IAAI,EAAE,SAAS;YACf,CAAC,CAAC,qBAAqB;YACvB,CAAC,CAAC,oBAAoB,CAAC;IAC3B,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,YAAY,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-driven Gauntlet loop: builder tentacle → isolated critic → GAP
|
|
3
|
+
* or PASS, capped. No parent writes. No "until critics win".
|
|
4
|
+
*/
|
|
5
|
+
import { parseBlindWinner } from './blind.js';
|
|
6
|
+
import { DEFAULT_WALL_MS } from './policy.js';
|
|
7
|
+
import { parseGauntletVerdict } from './verdict.js';
|
|
8
|
+
import { builderUserPrompt, criticUserPrompt, GAUNTLET_CRITIC_SYSTEM } from './prompts.js';
|
|
9
|
+
import { scheduleWaves } from './schedule.js';
|
|
10
|
+
import { formatGauntletSummary, gauntletProgressEvent, } from './events.js';
|
|
11
|
+
export async function runGauntletLoop(args) {
|
|
12
|
+
const { caps, deps } = args;
|
|
13
|
+
const pieces = args.pieces.slice(0, caps.maxPieces);
|
|
14
|
+
const started = (deps.now ?? Date.now)();
|
|
15
|
+
const results = [];
|
|
16
|
+
const emitProgress = (partial) => {
|
|
17
|
+
const progress = {
|
|
18
|
+
...partial,
|
|
19
|
+
elapsedMs: (deps.now ?? Date.now)() - started,
|
|
20
|
+
};
|
|
21
|
+
deps.emit(gauntletProgressEvent(deps.sessionId, progress));
|
|
22
|
+
deps.note?.('gauntlet.progress', progress);
|
|
23
|
+
};
|
|
24
|
+
const wall = caps.wallClockMs === undefined ? DEFAULT_WALL_MS : caps.wallClockMs;
|
|
25
|
+
const expired = () => wall > 0 && (deps.now ?? Date.now)() - started >= wall;
|
|
26
|
+
const aborted = () => Boolean(deps.signal?.aborted);
|
|
27
|
+
const stop = () => aborted() || expired();
|
|
28
|
+
const indexOf = (piece) => pieces.findIndex((p) => p.id === piece.id);
|
|
29
|
+
const runOnePiece = async (piece) => {
|
|
30
|
+
let last = {
|
|
31
|
+
kind: 'BLOCKED',
|
|
32
|
+
gap: 'no round ran',
|
|
33
|
+
evidence: false,
|
|
34
|
+
};
|
|
35
|
+
let gap;
|
|
36
|
+
let winner;
|
|
37
|
+
let rounds = 0;
|
|
38
|
+
const i = Math.max(0, indexOf(piece));
|
|
39
|
+
for (let round = 1; round <= caps.maxRounds; round++) {
|
|
40
|
+
if (stop())
|
|
41
|
+
break;
|
|
42
|
+
rounds = round;
|
|
43
|
+
const phase = gap ? 'repairing' : 'building';
|
|
44
|
+
emitProgress({
|
|
45
|
+
phase,
|
|
46
|
+
pieceId: piece.id,
|
|
47
|
+
pieceLabel: piece.label,
|
|
48
|
+
pieceIndex: i,
|
|
49
|
+
pieceCount: pieces.length,
|
|
50
|
+
round,
|
|
51
|
+
maxRounds: caps.maxRounds,
|
|
52
|
+
});
|
|
53
|
+
const built = await deps.runBuilder({
|
|
54
|
+
piece,
|
|
55
|
+
prompt: builderUserPrompt(piece, gap, deps.briefing),
|
|
56
|
+
round,
|
|
57
|
+
});
|
|
58
|
+
if (stop())
|
|
59
|
+
break;
|
|
60
|
+
emitProgress({
|
|
61
|
+
phase: 'critiquing',
|
|
62
|
+
pieceId: piece.id,
|
|
63
|
+
pieceLabel: piece.label,
|
|
64
|
+
pieceIndex: i,
|
|
65
|
+
pieceCount: pieces.length,
|
|
66
|
+
round,
|
|
67
|
+
maxRounds: caps.maxRounds,
|
|
68
|
+
});
|
|
69
|
+
const criticized = await deps.runCritic({
|
|
70
|
+
piece,
|
|
71
|
+
prompt: criticUserPrompt(piece, round),
|
|
72
|
+
systemPrompt: GAUNTLET_CRITIC_SYSTEM,
|
|
73
|
+
round,
|
|
74
|
+
});
|
|
75
|
+
last = parseGauntletVerdict(criticized.result, {
|
|
76
|
+
toolTraceCount: criticized.toolTraceCount ?? 0,
|
|
77
|
+
builderFailed: !built.ok,
|
|
78
|
+
builderError: built.error,
|
|
79
|
+
});
|
|
80
|
+
winner = parseBlindWinner(criticized.result) ?? winner;
|
|
81
|
+
emitProgress({
|
|
82
|
+
phase: last.kind === 'PASS' ? 'settled' : last.kind === 'BLOCKED' ? 'blocked' : 'repairing',
|
|
83
|
+
pieceId: piece.id,
|
|
84
|
+
pieceLabel: piece.label,
|
|
85
|
+
pieceIndex: i,
|
|
86
|
+
pieceCount: pieces.length,
|
|
87
|
+
round,
|
|
88
|
+
maxRounds: caps.maxRounds,
|
|
89
|
+
verdict: last.kind,
|
|
90
|
+
gap: last.gap,
|
|
91
|
+
winner,
|
|
92
|
+
});
|
|
93
|
+
if (last.kind === 'PASS' || last.kind === 'BLOCKED')
|
|
94
|
+
break;
|
|
95
|
+
gap = last.gap;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
id: piece.id,
|
|
99
|
+
label: piece.label,
|
|
100
|
+
verdict: last,
|
|
101
|
+
rounds,
|
|
102
|
+
...(winner ? { winner } : {}),
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
for (const wave of scheduleWaves(pieces, caps.maxParallel)) {
|
|
106
|
+
if (stop())
|
|
107
|
+
return finish(results, { cancelled: aborted(), timedOut: expired() });
|
|
108
|
+
if (wave.length === 1) {
|
|
109
|
+
results.push(await runOnePiece(wave[0]));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const waveResults = await Promise.all(wave.map((p) => runOnePiece(p)));
|
|
113
|
+
results.push(...waveResults);
|
|
114
|
+
}
|
|
115
|
+
if (stop())
|
|
116
|
+
return finish(results, { cancelled: aborted(), timedOut: expired() });
|
|
117
|
+
}
|
|
118
|
+
return finish(results, { cancelled: aborted(), timedOut: expired() });
|
|
119
|
+
}
|
|
120
|
+
function finish(results, flags) {
|
|
121
|
+
const cancelled = flags.timedOut ? false : flags.cancelled;
|
|
122
|
+
const timedOut = flags.timedOut;
|
|
123
|
+
const settled = !cancelled &&
|
|
124
|
+
!timedOut &&
|
|
125
|
+
results.length > 0 &&
|
|
126
|
+
results.every((r) => r.verdict.kind === 'PASS');
|
|
127
|
+
return {
|
|
128
|
+
settled,
|
|
129
|
+
cancelled,
|
|
130
|
+
timedOut,
|
|
131
|
+
pieces: results,
|
|
132
|
+
summary: formatGauntletSummary(results.map((r) => ({
|
|
133
|
+
id: r.id,
|
|
134
|
+
label: r.label,
|
|
135
|
+
verdict: r.verdict.kind,
|
|
136
|
+
rounds: r.rounds,
|
|
137
|
+
gap: r.verdict.gap,
|
|
138
|
+
winner: r.winner,
|
|
139
|
+
})), { timedOut, cancelled }),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/cli/gauntlet/loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gauntlet policy — caps and enablement. Host-enforced (P2): these are not
|
|
3
|
+
* prompt promises. Override via env; Desktop forwards --gauntlet.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_MAX_PIECES = 6;
|
|
6
|
+
export const DEFAULT_MAX_ROUNDS = 3;
|
|
7
|
+
export const DEFAULT_MAX_PARALLEL = 2;
|
|
8
|
+
/** Host-loop wall clock. 0 disables. Override ZELARI_GAUNTLET_WALL_MS. */
|
|
9
|
+
export const DEFAULT_WALL_MS = 45 * 60 * 1000;
|
|
10
|
+
/** Mutators the gauntlet parent (conductor) must not expose. */
|
|
11
|
+
export const GAUNTLET_PARENT_BLOCKED_TOOLS = [
|
|
12
|
+
'write_file',
|
|
13
|
+
'edit_file',
|
|
14
|
+
'apply_diff',
|
|
15
|
+
'bash',
|
|
16
|
+
];
|
|
17
|
+
function envInt(raw, fallback, min, max) {
|
|
18
|
+
if (raw === undefined || raw === '')
|
|
19
|
+
return fallback;
|
|
20
|
+
const n = Number.parseInt(raw, 10);
|
|
21
|
+
if (!Number.isFinite(n))
|
|
22
|
+
return fallback;
|
|
23
|
+
return Math.min(max, Math.max(min, n));
|
|
24
|
+
}
|
|
25
|
+
export function isGauntletFlagOn(explicit, env = process.env) {
|
|
26
|
+
if (explicit === true)
|
|
27
|
+
return true;
|
|
28
|
+
if (explicit === false)
|
|
29
|
+
return false;
|
|
30
|
+
const raw = env.ZELARI_GAUNTLET;
|
|
31
|
+
if (!raw)
|
|
32
|
+
return false;
|
|
33
|
+
return raw === '1' || raw.toLowerCase() === 'true';
|
|
34
|
+
}
|
|
35
|
+
export function resolveGauntletCaps(env = process.env) {
|
|
36
|
+
const wallRaw = env.ZELARI_GAUNTLET_WALL_MS;
|
|
37
|
+
let wallClockMs = DEFAULT_WALL_MS;
|
|
38
|
+
if (wallRaw !== undefined && wallRaw !== '') {
|
|
39
|
+
const n = Number.parseInt(wallRaw, 10);
|
|
40
|
+
if (Number.isFinite(n) && n >= 0)
|
|
41
|
+
wallClockMs = n;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
maxPieces: envInt(env.ZELARI_GAUNTLET_MAX_PIECES, DEFAULT_MAX_PIECES, 1, 16),
|
|
45
|
+
maxRounds: envInt(env.ZELARI_GAUNTLET_MAX_ROUNDS, DEFAULT_MAX_ROUNDS, 1, 8),
|
|
46
|
+
maxParallel: envInt(env.ZELARI_GAUNTLET_MAX_PARALLEL, DEFAULT_MAX_PARALLEL, 1, 4),
|
|
47
|
+
wallClockMs,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** True when the headless single-agent BUILD path should run the host loop. */
|
|
51
|
+
export function shouldRunGauntletHostLoop(opts) {
|
|
52
|
+
if (!isGauntletFlagOn(opts.gauntlet))
|
|
53
|
+
return false;
|
|
54
|
+
if (opts.krakenGraph)
|
|
55
|
+
return false;
|
|
56
|
+
if (opts.useCouncil || opts.mode === 'council' || opts.mode === 'zelari')
|
|
57
|
+
return false;
|
|
58
|
+
const phase = opts.phase ?? 'build';
|
|
59
|
+
return phase !== 'plan';
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/cli/gauntlet/policy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C,gEAAgE;AAChE,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,MAAM;CACE,CAAC;AAUX,SAAS,MAAM,CAAC,GAAuB,EAAE,QAAgB,EAAE,GAAW,EAAE,GAAW;IACjF,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IACrD,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAAkB,EAClB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,QAAQ,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,CAAC;IAC5C,IAAI,WAAW,GAAG,eAAe,CAAC;IAClC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,WAAW,GAAG,CAAC,CAAC;IACpD,CAAC;IACD,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,kBAAkB,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5E,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,4BAA4B,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAC,CAAC;QACjF,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,yBAAyB,CAAC,IAMzC;IACC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACvF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC;IACpC,OAAO,KAAK,KAAK,MAAM,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builder / critic prompts for the host-driven Gauntlet loop.
|
|
3
|
+
* Critic isolation is mechanical (fresh tentacle); the text must not
|
|
4
|
+
* include the builder's chain-of-thought.
|
|
5
|
+
*/
|
|
6
|
+
import { qualityBarSection } from './blind.js';
|
|
7
|
+
export const GAUNTLET_CRITIC_SYSTEM = [
|
|
8
|
+
'You are a ruthless VERIFY critic in a Gauntlet Loop.',
|
|
9
|
+
'Inspect the REAL files and commands on disk. Do not trust a builder self-report.',
|
|
10
|
+
'You have no builder transcript — only the Goal, Scope, Acceptance, and the tree.',
|
|
11
|
+
'OBSERVATION INTEGRITY: unknown ≠ pass. EMPTY/degraded tools are not evidence.',
|
|
12
|
+
'Name at most ONE biggest remaining gap. Do not write a laundry list.',
|
|
13
|
+
'You may read files and run test/build commands via bash. Prefer targeted checks.',
|
|
14
|
+
'',
|
|
15
|
+
'End with BOTH:',
|
|
16
|
+
'1. One <verify-report> block per acceptance criterion:',
|
|
17
|
+
'<verify-report>',
|
|
18
|
+
'check: <criterion text as given>',
|
|
19
|
+
'status: pass | fail | unknown',
|
|
20
|
+
'note: <one line of evidence (command or file + outcome)>',
|
|
21
|
+
'</verify-report>',
|
|
22
|
+
'2. A trailer on its own lines:',
|
|
23
|
+
'VERDICT: PASS | GAP | BLOCKED',
|
|
24
|
+
'GAP: <single biggest remaining gap; omit on PASS>',
|
|
25
|
+
'3. If a Blind A/B section is present, also emit WINNER: A | B | TIE',
|
|
26
|
+
].join('\n');
|
|
27
|
+
export function builderUserPrompt(piece, gap, briefing) {
|
|
28
|
+
const parts = [
|
|
29
|
+
`You are the BUILDER for one Gauntlet piece. Implement it on disk.`,
|
|
30
|
+
`Do not spawn sub-agents. Stay inside Scope if provided.`,
|
|
31
|
+
];
|
|
32
|
+
if (briefing?.trim()) {
|
|
33
|
+
parts.push('', '## Workspace briefing (do not treat as already-done work)', briefing.trim());
|
|
34
|
+
}
|
|
35
|
+
parts.push('', `## Piece: ${piece.label}`, piece.prompt.trim());
|
|
36
|
+
if (piece.scope && piece.scope.length > 0) {
|
|
37
|
+
parts.push('', '## Scope', ...piece.scope.map((s) => `- ${s}`));
|
|
38
|
+
}
|
|
39
|
+
if (piece.acceptance.length > 0) {
|
|
40
|
+
parts.push('', '## Acceptance', ...piece.acceptance.map((a) => `- ${a}`));
|
|
41
|
+
}
|
|
42
|
+
if (gap && gap.trim()) {
|
|
43
|
+
parts.push('', '## Previous critic GAP (fix ONLY this)', gap.trim(), 'Do not widen scope. Re-check the acceptance after the fix.');
|
|
44
|
+
}
|
|
45
|
+
parts.push('', 'Return: files touched, what changed, residual risks.');
|
|
46
|
+
return parts.join('\n');
|
|
47
|
+
}
|
|
48
|
+
export function criticUserPrompt(piece, round, rand) {
|
|
49
|
+
const parts = [
|
|
50
|
+
`Round ${round}. Inspect the current tree against this piece.`,
|
|
51
|
+
'Do not edit files. Do not take the builder\'s word — open files / run checks.',
|
|
52
|
+
'',
|
|
53
|
+
`## Piece: ${piece.label}`,
|
|
54
|
+
piece.prompt.trim(),
|
|
55
|
+
];
|
|
56
|
+
if (piece.scope && piece.scope.length > 0) {
|
|
57
|
+
parts.push('', '## Scope', ...piece.scope.map((s) => `- ${s}`));
|
|
58
|
+
}
|
|
59
|
+
if (piece.acceptance.length > 0) {
|
|
60
|
+
parts.push('', '## Acceptance (check each)', ...piece.acceptance.map((a) => `- ${a}`));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
parts.push('', '## Acceptance', '- The piece prompt is satisfied by files on disk.', '- Relevant typecheck/tests pass when the project has them.');
|
|
64
|
+
}
|
|
65
|
+
const bar = qualityBarSection(piece.bar, rand);
|
|
66
|
+
if (bar)
|
|
67
|
+
parts.push('', bar);
|
|
68
|
+
return parts.join('\n');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/cli/gauntlet/prompts.ts"],"names":[],"mappings":"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"}
|