gaunt-sloth 2.0.0-alpha.2 → 2.0.0-alpha.21
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/README.md +55 -5
- package/cli.js +43 -10
- package/dist/cli.js +33 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/adkEvalRunner.d.ts +66 -0
- package/dist/commands/adkEvalRunner.js +69 -0
- package/dist/commands/adkEvalRunner.js.map +1 -0
- package/dist/commands/agUiEvalRunner.d.ts +73 -0
- package/dist/commands/agUiEvalRunner.js +216 -0
- package/dist/commands/agUiEvalRunner.js.map +1 -0
- package/dist/commands/askCommand.d.ts +3 -2
- package/dist/commands/askCommand.js +26 -7
- package/dist/commands/askCommand.js.map +1 -1
- package/dist/commands/batchCommand.d.ts +78 -0
- package/dist/commands/batchCommand.js +245 -0
- package/dist/commands/batchCommand.js.map +1 -0
- package/dist/commands/cliOptionParsers.d.ts +12 -0
- package/dist/commands/cliOptionParsers.js +18 -0
- package/dist/commands/cliOptionParsers.js.map +1 -0
- package/dist/commands/commandIntrospection.d.ts +6 -6
- package/dist/commands/commandIntrospection.js +12 -12
- package/dist/commands/commandIntrospection.js.map +1 -1
- package/dist/commands/commandUtils.d.ts +16 -16
- package/dist/commands/commandUtils.js +20 -20
- package/dist/commands/commandUtils.js.map +1 -1
- package/dist/commands/configCommand.d.ts +24 -0
- package/dist/commands/configCommand.js +117 -0
- package/dist/commands/configCommand.js.map +1 -0
- package/dist/commands/configSetup.d.ts +1 -1
- package/dist/commands/configSetup.js +17 -2
- package/dist/commands/configSetup.js.map +1 -1
- package/dist/commands/evalCommand.d.ts +41 -0
- package/dist/commands/evalCommand.js +483 -0
- package/dist/commands/evalCommand.js.map +1 -0
- package/dist/commands/execCommand.js +4 -1
- package/dist/commands/execCommand.js.map +1 -1
- package/dist/commands/firstRunDialog.d.ts +39 -5
- package/dist/commands/firstRunDialog.js +72 -10
- package/dist/commands/firstRunDialog.js.map +1 -1
- package/dist/commands/getCommand.js +7 -7
- package/dist/commands/getCommand.js.map +1 -1
- package/dist/commands/historyCommand.d.ts +17 -0
- package/dist/commands/historyCommand.js +102 -0
- package/dist/commands/historyCommand.js.map +1 -0
- package/dist/commands/initCommand.d.ts +3 -0
- package/dist/commands/initCommand.js +9 -4
- package/dist/commands/initCommand.js.map +1 -1
- package/dist/commands/insightsCommand.d.ts +8 -0
- package/dist/commands/insightsCommand.js +32 -0
- package/dist/commands/insightsCommand.js.map +1 -0
- package/dist/commands/modelsCommand.d.ts +25 -0
- package/dist/commands/modelsCommand.js +96 -0
- package/dist/commands/modelsCommand.js.map +1 -0
- package/dist/commands/prCommand.js +14 -15
- package/dist/commands/prCommand.js.map +1 -1
- package/dist/commands/prDiscovery.d.ts +2 -2
- package/dist/commands/prDiscovery.js +27 -29
- package/dist/commands/prDiscovery.js.map +1 -1
- package/dist/commands/reviewCommand.js +15 -10
- package/dist/commands/reviewCommand.js.map +1 -1
- package/dist/commands/workflowCommand.d.ts +19 -0
- package/dist/commands/workflowCommand.js +77 -0
- package/dist/commands/workflowCommand.js.map +1 -0
- package/dist/helpers/jira/jiraLogWork.js.map +1 -1
- package/dist/modules/startSession.js +9 -7
- package/dist/modules/startSession.js.map +1 -1
- package/dist/tools/gthJiraLogWorkTool.js +3 -3
- package/dist/tools/gthJiraLogWorkTool.js.map +1 -1
- package/dist/tui/components/App.js +321 -21
- package/dist/tui/components/App.js.map +1 -1
- package/dist/tui/components/ApprovalPrompt.d.ts +18 -0
- package/dist/tui/components/ApprovalPrompt.js +26 -0
- package/dist/tui/components/ApprovalPrompt.js.map +1 -0
- package/dist/tui/components/DebugPanel.d.ts +29 -9
- package/dist/tui/components/DebugPanel.js +46 -23
- package/dist/tui/components/DebugPanel.js.map +1 -1
- package/dist/tui/components/FetchProgress.d.ts +36 -0
- package/dist/tui/components/FetchProgress.js +39 -0
- package/dist/tui/components/FetchProgress.js.map +1 -0
- package/dist/tui/components/LiveTurn.d.ts +26 -4
- package/dist/tui/components/LiveTurn.js +104 -18
- package/dist/tui/components/LiveTurn.js.map +1 -1
- package/dist/tui/components/NoticeBar.d.ts +32 -0
- package/dist/tui/components/NoticeBar.js +39 -0
- package/dist/tui/components/NoticeBar.js.map +1 -0
- package/dist/tui/components/PromptInput.d.ts +26 -1
- package/dist/tui/components/PromptInput.js +93 -7
- package/dist/tui/components/PromptInput.js.map +1 -1
- package/dist/tui/components/Rule.js.map +1 -1
- package/dist/tui/components/SelectList.d.ts +98 -9
- package/dist/tui/components/SelectList.js +209 -26
- package/dist/tui/components/SelectList.js.map +1 -1
- package/dist/tui/components/SlashCommandMenu.d.ts +20 -0
- package/dist/tui/components/SlashCommandMenu.js +28 -0
- package/dist/tui/components/SlashCommandMenu.js.map +1 -0
- package/dist/tui/components/StatusBar.d.ts +7 -1
- package/dist/tui/components/StatusBar.js +7 -3
- package/dist/tui/components/StatusBar.js.map +1 -1
- package/dist/tui/components/Transcript.js +6 -1
- package/dist/tui/components/Transcript.js.map +1 -1
- package/dist/tui/debugRender.d.ts +41 -6
- package/dist/tui/debugRender.js +126 -12
- package/dist/tui/debugRender.js.map +1 -1
- package/dist/tui/debugSearch.d.ts +40 -0
- package/dist/tui/debugSearch.js +73 -0
- package/dist/tui/debugSearch.js.map +1 -0
- package/dist/tui/markdown.js +0 -0
- package/dist/tui/markdown.js.map +1 -1
- package/dist/tui/pasteParser.d.ts +21 -0
- package/dist/tui/pasteParser.js +24 -0
- package/dist/tui/pasteParser.js.map +1 -0
- package/dist/tui/selectCancelled.d.ts +13 -0
- package/dist/tui/selectCancelled.js +17 -0
- package/dist/tui/selectCancelled.js.map +1 -0
- package/dist/tui/slashCommands.d.ts +220 -1
- package/dist/tui/slashCommands.js +408 -1
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/tuiSessionModule.js +249 -24
- package/dist/tui/tuiSessionModule.js.map +1 -1
- package/dist/tui/types.d.ts +96 -7
- package/dist/tui/viewModel.d.ts +34 -0
- package/dist/tui/viewModel.js +67 -0
- package/dist/tui/viewModel.js.map +1 -1
- package/dist/utils/stdinPolicy.d.ts +31 -0
- package/dist/utils/stdinPolicy.js +37 -0
- package/dist/utils/stdinPolicy.js.map +1 -0
- package/package.json +21 -17
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { basename, extname, join, resolve } from 'node:path';
|
|
3
|
+
import { initConfig, resolveIdentityProfileConfigPath, } from '@gaunt-sloth/core/config.js';
|
|
4
|
+
import { getAskSystemPrompt } from '#src/commands/commandIntrospection.js';
|
|
5
|
+
import { buildProductionRunCell, buildProductionRunConversation, } from '#src/commands/batchCommand.js';
|
|
6
|
+
import { parseIntOption } from '#src/commands/cliOptionParsers.js';
|
|
7
|
+
import { displayError, displaySuccess, displayWarning, } from '@gaunt-sloth/core/utils/consoleUtils.js';
|
|
8
|
+
import { getProjectDir, setExitCode } from '@gaunt-sloth/core/utils/systemUtils.js';
|
|
9
|
+
import { fileSafeLocalDate, getGslothFilePath, importExternalFile, readFileFromProjectDir, } from '@gaunt-sloth/core/utils/fileUtils.js';
|
|
10
|
+
/** Split each collected `--reporter` value on `,`, flatten, trim, drop blanks, and de-duplicate
|
|
11
|
+
* (order-preserving), so `-r junit,text` and `-r junit -r text` both yield `['junit','text']`. */
|
|
12
|
+
export function normalizeReporterNames(collected) {
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
const out = [];
|
|
15
|
+
for (const raw of collected) {
|
|
16
|
+
for (const name of raw.split(',').map((n) => n.trim())) {
|
|
17
|
+
if (name && !seen.has(name)) {
|
|
18
|
+
seen.add(name);
|
|
19
|
+
out.push(name);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build the `custom` reporter-factory map handed to `resolveReporters`. It always registers the
|
|
27
|
+
* BUNDLED JUnit reporter through the SAME public `custom` seam a user reporter uses (the point: it
|
|
28
|
+
* proves the plug-in contract from an out-of-core package), then overlays any config-declared
|
|
29
|
+
* reporters. A config reporter may reuse a built-in/bundled name — config wins on a collision, so it
|
|
30
|
+
* is added last.
|
|
31
|
+
*
|
|
32
|
+
* A config reporter's module path is resolved relative to the PROJECT dir (the same base
|
|
33
|
+
* `readFileFromProjectDir` uses) and imported via {@link importExternalFile} (which turns it into a
|
|
34
|
+
* `file://` URL and supports `.ts` through jiti). Its DEFAULT export must be an `EvalReporterFactory`
|
|
35
|
+
* (`() => EvalReporter`); a missing file, a failed import, or a non-function default export THROWS —
|
|
36
|
+
* caught by the command's outer try/catch → exit 2 (harness error). It is the user's own trusted
|
|
37
|
+
* config (already arbitrary JS), so nothing is sandboxed.
|
|
38
|
+
*/
|
|
39
|
+
async function buildCustomReporterFactories(config) {
|
|
40
|
+
const custom = {};
|
|
41
|
+
const { createJUnitReporter, JUNIT_REPORTER_NAME } = await import('@gaunt-sloth/eval-reporter-junit/index.js');
|
|
42
|
+
custom[JUNIT_REPORTER_NAME] = createJUnitReporter;
|
|
43
|
+
for (const [name, modulePath] of Object.entries(config.reporters ?? {})) {
|
|
44
|
+
const absPath = resolve(getProjectDir(), modulePath);
|
|
45
|
+
let mod;
|
|
46
|
+
try {
|
|
47
|
+
mod = await importExternalFile(absPath);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new Error(`failed to load config reporter "${name}" from "${modulePath}" (${absPath}): ` +
|
|
51
|
+
(error instanceof Error ? error.message : String(error)));
|
|
52
|
+
}
|
|
53
|
+
const factory = mod.default;
|
|
54
|
+
if (typeof factory !== 'function') {
|
|
55
|
+
throw new Error(`config reporter "${name}" (${modulePath}) must export a default function ` +
|
|
56
|
+
`(an EvalReporterFactory: () => EvalReporter); got ${typeof factory}.`);
|
|
57
|
+
}
|
|
58
|
+
custom[name] = factory;
|
|
59
|
+
}
|
|
60
|
+
return custom;
|
|
61
|
+
}
|
|
62
|
+
/** Default output dir when `-o/--output` is omitted: a timestamped dir next to other gth reports —
|
|
63
|
+
* same convention as `defaultBatchOutputDir` in `batchCommand.ts`, `_EVAL` suffix instead. */
|
|
64
|
+
export function defaultEvalOutputDir() {
|
|
65
|
+
return getGslothFilePath(`gth_${fileSafeLocalDate()}_EVAL`);
|
|
66
|
+
}
|
|
67
|
+
/** `basename(path)` with its extension removed — the per-suite output subdir name and the JUnit
|
|
68
|
+
* `<testsuites>` name. `eval/authz-matrix.yaml` → `authz-matrix`. */
|
|
69
|
+
function suiteStem(path) {
|
|
70
|
+
const base = basename(path);
|
|
71
|
+
const ext = extname(base);
|
|
72
|
+
return ext ? base.slice(0, -ext.length) : base;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Deterministically resolve the CLI `<suites...>` args into the ordered list of suites to run
|
|
76
|
+
* (BATCH-19 Task B, Deliverable 1):
|
|
77
|
+
* - A **file** (or a path that doesn't exist on disk — its read is deferred so a missing suite
|
|
78
|
+
* surfaces as that suite's own harness error, keeping the single-suite behavior byte-for-byte) →
|
|
79
|
+
* that one suite, read by the exact CLI string given.
|
|
80
|
+
* - A **directory** → its **direct-child** `*.yaml`/`*.yml` files only (NON-recursive), sorted
|
|
81
|
+
* lexicographically. An empty / no-match directory yields no suites and one harness `error` (the
|
|
82
|
+
* caller folds it into the aggregate exit → 2) instead of throwing, so any GOOD sibling inputs
|
|
83
|
+
* still run.
|
|
84
|
+
*
|
|
85
|
+
* The given arg order is preserved and each directory is expanded in place; suites are
|
|
86
|
+
* de-duplicated by **resolved absolute path** (the same file named twice, directly or via a
|
|
87
|
+
* directory, runs once).
|
|
88
|
+
*/
|
|
89
|
+
function resolveEvalSuiteInputs(inputs) {
|
|
90
|
+
const projectDir = getProjectDir();
|
|
91
|
+
const suites = [];
|
|
92
|
+
const errors = [];
|
|
93
|
+
const seen = new Set();
|
|
94
|
+
const push = (readPath, absPath) => {
|
|
95
|
+
if (seen.has(absPath))
|
|
96
|
+
return;
|
|
97
|
+
seen.add(absPath);
|
|
98
|
+
suites.push({ readPath, absPath });
|
|
99
|
+
};
|
|
100
|
+
for (const input of inputs) {
|
|
101
|
+
const abs = resolve(projectDir, input);
|
|
102
|
+
let isDirectory = false;
|
|
103
|
+
try {
|
|
104
|
+
isDirectory = statSync(abs).isDirectory();
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Non-existent path: treat as a file suite and let its read fail as that suite's own harness
|
|
108
|
+
// error (single-suite behavior preserved; a real file mock/read is keyed on the CLI string).
|
|
109
|
+
isDirectory = false;
|
|
110
|
+
}
|
|
111
|
+
if (!isDirectory) {
|
|
112
|
+
push(input, abs);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const yamlChildren = readdirSync(abs)
|
|
116
|
+
.filter((name) => {
|
|
117
|
+
const ext = extname(name).toLowerCase();
|
|
118
|
+
return ext === '.yaml' || ext === '.yml';
|
|
119
|
+
})
|
|
120
|
+
.sort();
|
|
121
|
+
if (yamlChildren.length === 0) {
|
|
122
|
+
errors.push(`eval suite directory "${input}" contains no .yaml/.yml files`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
for (const name of yamlChildren) {
|
|
126
|
+
const childAbs = resolve(abs, name);
|
|
127
|
+
push(childAbs, childAbs);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return { suites, errors };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build the production {@link JudgeFn}: grades one case's answer with `judgeEvalCase` against
|
|
134
|
+
* `config.llm`. The caller chooses *which* config this is (BATCH-10 Task 2): by default it's the
|
|
135
|
+
* SUT's own config (judge shares the SUT model, the original behavior), but when a judge identity
|
|
136
|
+
* profile is resolved (`--judge <profile>` or the suite's `judge_profile`) the action passes a
|
|
137
|
+
* *separate* `initConfig({ …, identityProfile })` here, so the judge runs under its own model — a
|
|
138
|
+
* different model can catch blind spots the SUT model shares. This function stays agnostic to that
|
|
139
|
+
* choice; it just grades against whatever `config.llm` it's handed.
|
|
140
|
+
*/
|
|
141
|
+
function buildProductionJudge(config) {
|
|
142
|
+
return async (answer, rubric) => {
|
|
143
|
+
const { judgeEvalCase } = await import('@gaunt-sloth/batch/judge.js');
|
|
144
|
+
return judgeEvalCase(answer, rubric, config.llm);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Pure resolver for the judge identity profile — kept small and side-effect-free so it's unit
|
|
149
|
+
* testable in isolation. Precedence (highest first): CLI `--judge <profile>` > suite-level
|
|
150
|
+
* `judge_profile` > none. A blank/whitespace-only value at either level counts as absent (falls
|
|
151
|
+
* through to the next level). `undefined` means "no separate judge — grade with the SUT's config".
|
|
152
|
+
*/
|
|
153
|
+
export function resolveJudgeProfile(cliJudge, suiteJudgeProfile) {
|
|
154
|
+
const cli = cliJudge?.trim();
|
|
155
|
+
if (cli)
|
|
156
|
+
return cli;
|
|
157
|
+
const suite = suiteJudgeProfile?.trim();
|
|
158
|
+
if (suite)
|
|
159
|
+
return suite;
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
/** Best-effort model name for the self-describing judge line. `BaseChatModel` doesn't standardize a
|
|
163
|
+
* public model-name field, so read `model` then `modelName`; return `undefined` if neither is a
|
|
164
|
+
* usable string (the profile name alone still describes the run). */
|
|
165
|
+
function judgeModelName(config) {
|
|
166
|
+
const llm = config.llm;
|
|
167
|
+
const name = typeof llm.model === 'string' ? llm.model : llm.modelName;
|
|
168
|
+
return typeof name === 'string' && name.length > 0 ? name : undefined;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Adds the `eval` command to the program.
|
|
172
|
+
*
|
|
173
|
+
* `gth eval <suite.yaml> [-j 8] [-o out/]` — grades a suite of cases (deterministic checks and/or
|
|
174
|
+
* an LLM judge) against the SUT agent, the way `review` grades a diff. See
|
|
175
|
+
* docs/batch-eval-cli-surface.md and docs/batch-eval-user-requirements.md for the design; this
|
|
176
|
+
* command implements the single-`prompt`, `gth-agent`-target, `config.llm`-as-judge subset — see
|
|
177
|
+
* the BATCH-2 Task 2 brief's "Not in scope" list for what's deliberately deferred.
|
|
178
|
+
*
|
|
179
|
+
* Exit-code contract (BATCH-11 / #405 his #6 — a distinct three-way code so CI can tell a product
|
|
180
|
+
* regression from a broken harness):
|
|
181
|
+
* - `0` — every case passed (mirrors `review`; unchanged contract).
|
|
182
|
+
* - `1` — the suite **ran** but ≥1 case FAILED (a deterministic check or the judge fell below
|
|
183
|
+
* threshold). A *product* signal: real, gradeable results, some below the bar.
|
|
184
|
+
* - `2` — **harness error**: the suite couldn't be meaningfully evaluated — the suite file failed
|
|
185
|
+
* to load/parse, config failed to build, or **every** case's SUT run failed (`sutOk:false`, e.g.
|
|
186
|
+
* a transport/auth/config failure produced no answer to grade). An *environment* signal.
|
|
187
|
+
*
|
|
188
|
+
* The suite-vs-harness split is anchored on `sutOk` (see `classifyEvalExit`), not the verdict: a
|
|
189
|
+
* case that ran (`sutOk:true`) but whose judge errored, or whose answer failed a check, is still a
|
|
190
|
+
* real result → exit `1`, never `2`. Unlike `batch`, which exits 0 regardless of per-cell quality.
|
|
191
|
+
*
|
|
192
|
+
* @param program - The commander program
|
|
193
|
+
* @param commandLineConfigOverrides - command line config overrides
|
|
194
|
+
*/
|
|
195
|
+
export function evalCommand(program, commandLineConfigOverrides) {
|
|
196
|
+
program
|
|
197
|
+
.command('eval')
|
|
198
|
+
.description('Grade a suite of cases against the SUT agent with deterministic checks and/or an LLM ' +
|
|
199
|
+
'judge ("pytest for prompts"). Exit code: 0 = all cases passed, 1 = a case failed, ' +
|
|
200
|
+
'2 = harness error (bad suite/config, or the SUT could not run).')
|
|
201
|
+
.argument('<suites...>', 'Eval suite YAML file(s) or directory(ies). A directory runs its direct-child *.yaml/*.yml ' +
|
|
202
|
+
'suites (non-recursive, sorted). Multiple suites report ONE aggregate exit code; each ' +
|
|
203
|
+
'writes into its own <output>/<suite-name>/ subdir (a single suite writes into <output> directly).')
|
|
204
|
+
.option('-j, --concurrency <n>', 'Max in-flight cases', parseIntOption)
|
|
205
|
+
.option('-o, --output <dir>', 'Directory to write structured per-case JSON + results.json summary to ' +
|
|
206
|
+
'(default: a timestamped dir alongside other gth reports)')
|
|
207
|
+
.option('--judge <profile>', 'Identity profile whose model judges the cases (defaults to the SUT model). ' +
|
|
208
|
+
'Overrides the suite-level judge_profile.')
|
|
209
|
+
.option('-r, --reporter <names>', 'Reporter(s) to render the run through (repeatable; comma-separated). Built-in: "text" ' +
|
|
210
|
+
'(default), "junit" (writes results.xml). REPLACES the default, so "--reporter junit" is ' +
|
|
211
|
+
'JUnit only. The always-on results.json + per-cell JSON are written regardless.', (value, previous = []) => [...previous, value])
|
|
212
|
+
.addHelpText('after', '\n' +
|
|
213
|
+
'Reporters:\n' +
|
|
214
|
+
' text (default) a human-readable PASS/FAIL summary on the console\n' +
|
|
215
|
+
' junit an Ant-JUnit results.xml (for TeamCity / CI JUnit readers)\n' +
|
|
216
|
+
' Custom reporters are declared in config under `reporters: { <name>: <module path> }`.\n' +
|
|
217
|
+
' --reporter REPLACES the default set (it does not add to it); pass every reporter you\n' +
|
|
218
|
+
' want, e.g. `--reporter text,junit`. results.json is always written, regardless.\n' +
|
|
219
|
+
'\n' +
|
|
220
|
+
'Examples:\n' +
|
|
221
|
+
' $ gsloth eval eval/js-basics.yaml\n' +
|
|
222
|
+
' $ gsloth eval eval/js-basics.yaml --judge strict-judge\n' +
|
|
223
|
+
' $ gsloth eval eval/authz-matrix.yaml -j 8 -o eval/out/authz\n' +
|
|
224
|
+
' $ gsloth eval eval/js-basics.yaml eval/authz-matrix.yaml # many suites, one exit\n' +
|
|
225
|
+
' $ gsloth eval eval/ -o eval/out --reporter junit # a whole directory\n' +
|
|
226
|
+
' $ gsloth eval eval/js-basics.yaml --reporter junit\n' +
|
|
227
|
+
' $ gsloth eval eval/js-basics.yaml --reporter text,junit\n')
|
|
228
|
+
.action(async (suitePaths, options) => {
|
|
229
|
+
try {
|
|
230
|
+
// Specific `.js` subpaths (not the bare package root), matching batchCommand.ts's
|
|
231
|
+
// convention — vitest's workspace-import resolver recognizes these and resolves straight to
|
|
232
|
+
// source, so specs exercise live `packages/batch/src` rather than a `dist/` build.
|
|
233
|
+
const { parseEvalSuite } = await import('@gaunt-sloth/batch/evalSuite.js');
|
|
234
|
+
const { runEvalSuite, classifyEvalExit } = await import('@gaunt-sloth/batch/evalRunner.js');
|
|
235
|
+
const { writeEvalOutput } = await import('@gaunt-sloth/batch/evalOutput.js');
|
|
236
|
+
const { resolveReporters } = await import('@gaunt-sloth/batch/reporters/registry.js');
|
|
237
|
+
const { driveReporters } = await import('@gaunt-sloth/batch/reporters/drive.js');
|
|
238
|
+
// The reporter selection (`--reporter`, else the default `['text']`) and the output ROOT are
|
|
239
|
+
// invocation-level — the same for every suite. REPLACES the default: the `--reporter` value
|
|
240
|
+
// when given, else `['text']`.
|
|
241
|
+
const reporterNames = options.reporter
|
|
242
|
+
? normalizeReporterNames(options.reporter)
|
|
243
|
+
: ['text'];
|
|
244
|
+
const outputRoot = options.output ?? defaultEvalOutputDir();
|
|
245
|
+
// BATCH-19 Task B: run ONE whole suite — parse, precondition-check its identities, build its
|
|
246
|
+
// configs/reporters, run, write its structured output, and drive its reporters — RETURNING
|
|
247
|
+
// its summary. THROWS on this suite's own harness error (parse/config/reporter/precondition
|
|
248
|
+
// failure), which the caller catches per suite so one bad suite never aborts the good ones.
|
|
249
|
+
//
|
|
250
|
+
// Task B, Deliverable 2 — the `-i` papercut: a MATRIX suite (declares `identities:`) must run
|
|
251
|
+
// with NO base `-i`. The per-identity configs come from the suite's `identities:` list (each
|
|
252
|
+
// pre-validated by the precondition below), so the base config used for reporters + the
|
|
253
|
+
// default judge is the FIRST identity's already-built config — the matrix path NEVER calls
|
|
254
|
+
// `initConfig` without an `identityProfile`. That is the fix: the old top-level
|
|
255
|
+
// `initConfig(overrides)` demanded a resolvable base config (a matrix-only project has none),
|
|
256
|
+
// and its terminal `exit(1)` is uncatchable, so it can't be reached at all on this path. The
|
|
257
|
+
// NON-matrix path is unchanged — the base config is still `initConfig(overrides)`. (Configs
|
|
258
|
+
// are built per suite, not cached across suites — a documented non-goal.)
|
|
259
|
+
const runOneSuite = async (suite, suiteOutputDir) => {
|
|
260
|
+
const suiteText = readFileFromProjectDir(suite.readPath);
|
|
261
|
+
const parsedSuite = parseEvalSuite(suiteText, suite.readPath);
|
|
262
|
+
// BATCH-12 PRECONDITION — trustworthy loads (no false-green): every suite-declared identity
|
|
263
|
+
// must resolve to its OWN config (`.gsloth-settings/<name>/`), not the global/plain
|
|
264
|
+
// fallback. Verify ALL of them with GS2-62's PURE, catchable helper BEFORE building any
|
|
265
|
+
// per-identity config, because handing a bad profile to `initConfig({ …, identityProfile })`
|
|
266
|
+
// would hit its uncatchable `exit(1)` and collapse the harness-vs-product (2-vs-1) exit-code
|
|
267
|
+
// distinction. A silent wrong-identity run is the worst failure for an auth matrix — so an
|
|
268
|
+
// unresolved identity throws here → per-suite catch → exit 2, and NOTHING runs.
|
|
269
|
+
const suiteIdentities = parsedSuite.identities ?? [];
|
|
270
|
+
const unresolvedIdentities = suiteIdentities.filter((identity) => !resolveIdentityProfileConfigPath(identity));
|
|
271
|
+
if (unresolvedIdentities.length > 0) {
|
|
272
|
+
throw new Error(`identity profile(s) not found: ${unresolvedIdentities.join(', ')} — each suite ` +
|
|
273
|
+
'`identities` entry must have its own config file in ' +
|
|
274
|
+
'.gsloth/.gsloth-settings/<name>/. No cases were run.');
|
|
275
|
+
}
|
|
276
|
+
const runCellOptions = {
|
|
277
|
+
command: 'ask',
|
|
278
|
+
sourcePrefix: 'EVAL',
|
|
279
|
+
wrapBlockPrefix: 'message',
|
|
280
|
+
wrapPrefix: 'user message',
|
|
281
|
+
};
|
|
282
|
+
// Build the SUT run function(s), selected by `target.type`, AND resolve the base config
|
|
283
|
+
// used for the reporters + the default (SUT-model) judge. The eval runner is
|
|
284
|
+
// target-agnostic — it just consumes an injected single-turn `runCell` and multi-turn
|
|
285
|
+
// `runConversation` — so the target only changes which builders produce them.
|
|
286
|
+
let runCell;
|
|
287
|
+
let runConversation;
|
|
288
|
+
let runCellByIdentity;
|
|
289
|
+
let runConversationByIdentity;
|
|
290
|
+
let baseConfig;
|
|
291
|
+
if (suiteIdentities.length > 0 && parsedSuite.target.type === 'gth-agent') {
|
|
292
|
+
// MATRIX (gth-agent): one runCell per identity, each from a fresh
|
|
293
|
+
// `initConfig({ …, identityProfile })` (mirrors `gth batch --models`' per-model
|
|
294
|
+
// construction — a genuinely fresh `.llm`, never a structural clone), built ONCE per
|
|
295
|
+
// identity and reused across cases by the runner. An identity profile's manual
|
|
296
|
+
// `mcpServers.<n>.headers.Authorization` (CFG-4) flows through as-is. The base config for
|
|
297
|
+
// reporters + the default judge is the FIRST identity's config (reused, not rebuilt) — so
|
|
298
|
+
// this path makes NO `initConfig` call without an `identityProfile` (Deliverable 2).
|
|
299
|
+
runCellByIdentity = new Map();
|
|
300
|
+
runConversationByIdentity = new Map();
|
|
301
|
+
let firstIdentityConfig;
|
|
302
|
+
for (const identity of suiteIdentities) {
|
|
303
|
+
const identityConfig = await initConfig({
|
|
304
|
+
...commandLineConfigOverrides,
|
|
305
|
+
identityProfile: identity,
|
|
306
|
+
});
|
|
307
|
+
if (!firstIdentityConfig)
|
|
308
|
+
firstIdentityConfig = identityConfig;
|
|
309
|
+
const identityPreamble = getAskSystemPrompt(identityConfig);
|
|
310
|
+
runCellByIdentity.set(identity, await buildProductionRunCell(identityConfig, identityPreamble, commandLineConfigOverrides, runCellOptions));
|
|
311
|
+
runConversationByIdentity.set(identity, await buildProductionRunConversation(identityConfig, identityPreamble, runCellOptions));
|
|
312
|
+
}
|
|
313
|
+
// `firstIdentityConfig` is always set here (suiteIdentities is non-empty).
|
|
314
|
+
baseConfig = firstIdentityConfig;
|
|
315
|
+
}
|
|
316
|
+
else if (parsedSuite.target.type === 'adk-agent') {
|
|
317
|
+
// BATCH-14: drive an EXTERNAL Google ADK agent over A2A. The agent runs out-of-process
|
|
318
|
+
// (its own model/tools/auth), so there is no per-identity gth config — the `identities`
|
|
319
|
+
// matrix is rejected for this target at parse time, leaving only the single-run path. The
|
|
320
|
+
// judge still grades via the local gth config, so build it from `initConfig(overrides)`.
|
|
321
|
+
baseConfig = await initConfig(commandLineConfigOverrides);
|
|
322
|
+
const { buildAdkRunCell, buildAdkRunConversation } = await import('#src/commands/adkEvalRunner.js');
|
|
323
|
+
runCell = buildAdkRunCell(parsedSuite.target);
|
|
324
|
+
runConversation = buildAdkRunConversation(parsedSuite.target);
|
|
325
|
+
}
|
|
326
|
+
else if (parsedSuite.target.type === 'ag-ui') {
|
|
327
|
+
// BATCH-15: drive an EXTERNAL AG-UI agent over HTTP/SSE. Like the ADK target, the agent
|
|
328
|
+
// runs out-of-process (its own model/tools/auth), so there is no per-identity gth config —
|
|
329
|
+
// the `identities` matrix is rejected for this target at parse time. Unlike ADK, the AG-UI
|
|
330
|
+
// wire streams tool calls, so the runner captures them and `must_call`/`must_not_call`
|
|
331
|
+
// grade normally. The judge still grades via the local gth `initConfig(overrides)` config.
|
|
332
|
+
baseConfig = await initConfig(commandLineConfigOverrides);
|
|
333
|
+
const { buildAgUiRunCell, buildAgUiRunConversation } = await import('#src/commands/agUiEvalRunner.js');
|
|
334
|
+
runCell = buildAgUiRunCell(parsedSuite.target);
|
|
335
|
+
runConversation = buildAgUiRunConversation(parsedSuite.target);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
// gth-agent, NO identities (unchanged): one runCell/runConversation under the invoked
|
|
339
|
+
// profile, from the single `initConfig(overrides)` base config (byte-for-byte as before).
|
|
340
|
+
baseConfig = await initConfig(commandLineConfigOverrides);
|
|
341
|
+
const preamble = getAskSystemPrompt(baseConfig);
|
|
342
|
+
runCell = await buildProductionRunCell(baseConfig, preamble, commandLineConfigOverrides, runCellOptions);
|
|
343
|
+
runConversation = await buildProductionRunConversation(baseConfig, preamble, runCellOptions);
|
|
344
|
+
}
|
|
345
|
+
// BATCH-19 A2: resolve the reporter selection — BEFORE the suite runs and before any output
|
|
346
|
+
// is written — so an unknown `--reporter` name (or a broken config-reporter module) fails
|
|
347
|
+
// fast → this suite's harness error (exit 2) with NOTHING run and no misleading partial
|
|
348
|
+
// output. The bundled JUnit reporter and any config-declared reporters are registered
|
|
349
|
+
// through the ONE public `custom` seam `resolveReporters` exposes (config wins on a name
|
|
350
|
+
// collision). Reporters are re-resolved per suite so each suite gets fresh reporter state
|
|
351
|
+
// (e.g. its own JUnit document). An unknown name throws (message lists the available
|
|
352
|
+
// reporters) → per-suite catch → exit 2.
|
|
353
|
+
const customReporterFactories = await buildCustomReporterFactories(baseConfig);
|
|
354
|
+
const reporters = resolveReporters(reporterNames, customReporterFactories);
|
|
355
|
+
// BATCH-10 Task 2: resolve the judge identity profile (CLI `--judge` > suite `judge_profile`
|
|
356
|
+
// > none). When set, build a SEPARATE config for it — the same supported
|
|
357
|
+
// `initConfig({ …overrides, identityProfile })` path `gth batch --models` uses to
|
|
358
|
+
// reconstruct a fresh `.llm` — so the judge runs under its own model. When unset, the judge
|
|
359
|
+
// shares the base config (the SUT's for a single run; the FIRST identity's for a matrix).
|
|
360
|
+
const judgeProfile = resolveJudgeProfile(options.judge, parsedSuite.judgeProfile);
|
|
361
|
+
if (judgeProfile && !resolveIdentityProfileConfigPath(judgeProfile)) {
|
|
362
|
+
// GS2-62 (BATCH-10 review Minor 1): pre-check the requested judge profile with the PURE
|
|
363
|
+
// helper and throw our OWN catchable error. Without this, `initConfig({ …, identityProfile
|
|
364
|
+
// })` would silently fall back to the global (or plain) config on a bad profile and the
|
|
365
|
+
// self-describing notice below would print `Judge: profile "<typo>" (model: <global>)` —
|
|
366
|
+
// asserting a profile that never loaded. The throw is caught per suite → exit 2 (harness
|
|
367
|
+
// error). We can't lean on initConfig's own hard-error here: that path calls the
|
|
368
|
+
// uncatchable `exit(1)`, which would end the process with code 1 and collapse the
|
|
369
|
+
// harness-vs-product (2-vs-1) exit-code distinction.
|
|
370
|
+
throw new Error(`judge profile "${judgeProfile}" not found: no config file in ` +
|
|
371
|
+
`.gsloth/.gsloth-settings/${judgeProfile}/`);
|
|
372
|
+
}
|
|
373
|
+
const judgeConfig = judgeProfile
|
|
374
|
+
? await initConfig({ ...commandLineConfigOverrides, identityProfile: judgeProfile })
|
|
375
|
+
: baseConfig;
|
|
376
|
+
const judge = buildProductionJudge(judgeConfig);
|
|
377
|
+
const summary = await runEvalSuite(parsedSuite, {
|
|
378
|
+
runCell,
|
|
379
|
+
runCellByIdentity,
|
|
380
|
+
runConversation,
|
|
381
|
+
runConversationByIdentity,
|
|
382
|
+
judge,
|
|
383
|
+
concurrency: options.concurrency,
|
|
384
|
+
});
|
|
385
|
+
writeEvalOutput(suiteOutputDir, summary);
|
|
386
|
+
// BATCH-19: render the run through the reporters resolved above (A1 seam + A2 selection).
|
|
387
|
+
// `writeEvalOutput` (results.json + per-cell JSON) is always-on core output, independent of
|
|
388
|
+
// any reporter — a JUnit run writes results.xml IN ADDITION, never instead. Reporters are an
|
|
389
|
+
// additional rendering layer, driven here in lifecycle order, with THIS suite's dir + path.
|
|
390
|
+
await driveReporters(reporters, summary, {
|
|
391
|
+
suitePath: suite.readPath,
|
|
392
|
+
outputDir: suiteOutputDir,
|
|
393
|
+
judgeNotice: judgeProfile
|
|
394
|
+
? { profile: judgeProfile, model: judgeModelName(judgeConfig) }
|
|
395
|
+
: undefined,
|
|
396
|
+
});
|
|
397
|
+
return summary;
|
|
398
|
+
};
|
|
399
|
+
// Deliverable 1: resolve the CLI args into the ordered, de-duplicated suite list (files as
|
|
400
|
+
// given; directories → their sorted direct-child *.yaml/*.yml). A no-match directory records
|
|
401
|
+
// a harness error but does not abort the good inputs.
|
|
402
|
+
const { suites, errors: resolutionErrors } = resolveEvalSuiteInputs(suitePaths);
|
|
403
|
+
let anyHarnessError = false;
|
|
404
|
+
for (const message of resolutionErrors) {
|
|
405
|
+
displayError(`eval harness error: ${message}`);
|
|
406
|
+
anyHarnessError = true;
|
|
407
|
+
}
|
|
408
|
+
// Exactly one resolved suite → write DIRECTLY into the output dir (byte-for-byte with the
|
|
409
|
+
// single-suite contract). Multiple → each suite writes into `<output>/<suiteStem>/`, so a CI
|
|
410
|
+
// glob collects them and suites never clobber. On a stem collision across resolved suites,
|
|
411
|
+
// disambiguate deterministically (`-2`, `-3`, … in resolved order) and WARN — never silently
|
|
412
|
+
// overwrite.
|
|
413
|
+
const single = suites.length === 1;
|
|
414
|
+
const usedStems = new Map();
|
|
415
|
+
const combinedCases = [];
|
|
416
|
+
for (const suite of suites) {
|
|
417
|
+
let suiteOutputDir = outputRoot;
|
|
418
|
+
if (!single) {
|
|
419
|
+
const stem = suiteStem(suite.readPath);
|
|
420
|
+
const priorCount = usedStems.get(stem) ?? 0;
|
|
421
|
+
usedStems.set(stem, priorCount + 1);
|
|
422
|
+
const dirName = priorCount === 0 ? stem : `${stem}-${priorCount + 1}`;
|
|
423
|
+
if (priorCount > 0) {
|
|
424
|
+
displayWarning(`eval: two suites share the output name "${stem}"; writing "${suite.readPath}" ` +
|
|
425
|
+
`output to "${dirName}/" so it does not clobber the earlier one.`);
|
|
426
|
+
}
|
|
427
|
+
suiteOutputDir = join(outputRoot, dirName);
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
const summary = await runOneSuite(suite, suiteOutputDir);
|
|
431
|
+
combinedCases.push(...summary.cases);
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
// A harness-level error for THIS suite (parse/config/reporter/precondition/unexpected).
|
|
435
|
+
// A harness error in ANY suite dominates the aggregate exit → 2 (a partial run can't be
|
|
436
|
+
// trusted), but the good suites still ran and wrote their output.
|
|
437
|
+
displayError(`eval harness error${single ? '' : ` in ${suite.readPath}`}: ` +
|
|
438
|
+
(error instanceof Error ? error.message : String(error)));
|
|
439
|
+
anyHarnessError = true;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
// Aggregate three-way exit: concatenate every successful suite's cases into ONE combined
|
|
443
|
+
// summary and call `classifyEvalExit` ONCE. A harness error in ANY suite dominates → exit 2.
|
|
444
|
+
// For N=1 this reproduces the single-suite exit EXACTLY (one summary, or one harness error →
|
|
445
|
+
// 2); `classifyEvalExit`'s own empty/all-`!sutOk` rule also yields 2 when nothing gradeable
|
|
446
|
+
// ran anywhere.
|
|
447
|
+
const passed = combinedCases.filter((result) => result.verdict === 'PASS').length;
|
|
448
|
+
const combined = {
|
|
449
|
+
total: combinedCases.length,
|
|
450
|
+
passed,
|
|
451
|
+
failed: combinedCases.length - passed,
|
|
452
|
+
cases: combinedCases,
|
|
453
|
+
};
|
|
454
|
+
// Multi-suite only: one aggregate total line AFTER every suite's own per-suite output. For
|
|
455
|
+
// N=1 print NOTHING extra — the single suite's text reporter already printed its verdict, so
|
|
456
|
+
// the output stays byte-for-byte identical to the single-suite contract.
|
|
457
|
+
if (suites.length > 1) {
|
|
458
|
+
const totalLine = `EVAL TOTAL: ${combined.passed}/${combined.total} across ${suites.length} suites, ` +
|
|
459
|
+
`${combined.failed} failed`;
|
|
460
|
+
if (combined.failed === 0 && !anyHarnessError) {
|
|
461
|
+
displaySuccess(totalLine);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
displayWarning(totalLine);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
const exitCode = anyHarnessError ? 2 : classifyEvalExit(combined);
|
|
468
|
+
if (exitCode !== 0) {
|
|
469
|
+
setExitCode(exitCode);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
catch (error) {
|
|
473
|
+
// BATCH-11: an invocation-level harness error the run never recovered from (e.g. a failed
|
|
474
|
+
// dynamic import) — distinct from a per-suite error (caught in the loop). The suites couldn't
|
|
475
|
+
// be meaningfully evaluated, so this is an *environment* signal (exit 2). Surface the reason;
|
|
476
|
+
// do NOT rethrow — an uncaught throw would surface as a generic exit 1 via the entry point,
|
|
477
|
+
// collapsing the 1-vs-2 distinction.
|
|
478
|
+
displayError(`eval harness error: ${error instanceof Error ? error.message : String(error)}`);
|
|
479
|
+
setExitCode(2);
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
//# sourceMappingURL=evalCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evalCommand.js","sourceRoot":"","sources":["../../src/commands/evalCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -94,9 +94,12 @@ export function execCommand(program, commandLineConfigOverrides) {
|
|
|
94
94
|
const execConfig = buildExecConfig(config, options);
|
|
95
95
|
const { runSingleShot } = await import('@gaunt-sloth/core/runtime/singleShot.js');
|
|
96
96
|
const { createResolvers } = await import('@gaunt-sloth/agent/resolvers.js');
|
|
97
|
+
const { resolveAgentFactory } = await import('@gaunt-sloth/agent/core/resolveAgentFactory.js');
|
|
97
98
|
let ok = false;
|
|
98
99
|
try {
|
|
99
|
-
ok = await runSingleShot('EXEC', getExecSystemPrompt(execConfig), content.join('\n'), execConfig, createResolvers(), 'exec'
|
|
100
|
+
({ ok } = await runSingleShot('EXEC', getExecSystemPrompt(execConfig), content.join('\n'), execConfig, createResolvers(), 'exec',
|
|
101
|
+
// exec defaults to the lean backend; an explicit config.agent.backend overrides it.
|
|
102
|
+
resolveAgentFactory(execConfig, 'lean')));
|
|
100
103
|
}
|
|
101
104
|
catch (error) {
|
|
102
105
|
displayError(error instanceof Error ? error.message : String(error));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execCommand.js","sourceRoot":"","sources":["../../src/commands/execCommand.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAqBvF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,OAA2B;IAC5E,MAAM,UAAU,GAAc;QAC5B,GAAG,MAAM;QACT,uEAAuE;QACvE,4BAA4B,EAAE,KAAK;QACnC,+EAA+E;QAC/E,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,KAAK;QACrD,6EAA6E;QAC7E,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5F,CAAC;IAEF,+FAA+F;IAC/F,4FAA4F;IAC5F,6EAA6E;IAC7E,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,IAAI,aAAa,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;QAC1F,UAAU,CAAC,GAA0C,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAC3F,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CACzB,OAAgB,EAChB,0BAAsD;IAEtD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CACV,8FAA8F,CAC/F;SACA,QAAQ,CAAC,UAAU,EAAE,mCAAmC,CAAC;SACzD,MAAM,CACL,sBAAsB,EACtB,kGAAkG,CACnG;SACA,MAAM,CACL,uBAAuB,EACvB,qEAAqE,CACtE;SACA,MAAM,CACL,4BAA4B,EAC5B,gEAAgE,EAChE,UAAU,CACX;SACA,MAAM,CACL,oBAAoB,EACpB,sFAAsF;QACpF,4DAA4D,EAC9D,CAAC,KAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"execCommand.js","sourceRoot":"","sources":["../../src/commands/execCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { detectProviders,
|
|
1
|
+
import { detectProviders, type DetectedProvider, type ModelDiscoveryResult, type ModelInfo, type ProviderId } from '@gaunt-sloth/core/providers/modelDiscovery.js';
|
|
2
2
|
import { ensureGslothDir, writeProjectReviewPreamble } from '#src/commands/configSetup.js';
|
|
3
3
|
/**
|
|
4
4
|
* Where the first-run dialog (CFG-2) persists the chosen provider/model config.
|
|
@@ -22,10 +22,29 @@ export type SelectFn = (title: string, options: string[], defaultIndex: number)
|
|
|
22
22
|
*/
|
|
23
23
|
export interface FirstRunDialogDeps {
|
|
24
24
|
detectProviders: typeof detectProviders;
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* CFG-21 — fetches the chosen provider's model list WITH its {@link ModelDiscoveryResult}
|
|
27
|
+
* provenance, baking in the generous interactive timeout by default. Returns `{ models, status }`
|
|
28
|
+
* so the dialog can surface an honest degrade notice when a live fetch was attempted and failed
|
|
29
|
+
* (`status: 'fallback'`) rather than silently swapping in a by-design curated list (`'curated'`).
|
|
30
|
+
*/
|
|
31
|
+
fetchModels: (providerId: ProviderId) => Promise<ModelDiscoveryResult>;
|
|
32
|
+
/**
|
|
33
|
+
* CFG-21 — runs `run` while a visible "working" indicator is shown (an Ink spinner on an
|
|
34
|
+
* interactive TTY, a plain printed line otherwise), clearing it when `run` settles. The model
|
|
35
|
+
* fetch is routed through this seam so the wait is never silent and a test can assert it fired.
|
|
36
|
+
*/
|
|
37
|
+
withProgress: <T>(label: string, run: () => Promise<T>) => Promise<T>;
|
|
26
38
|
ensureGslothDir: typeof ensureGslothDir;
|
|
27
39
|
writeProjectReviewPreamble: typeof writeProjectReviewPreamble;
|
|
28
|
-
/**
|
|
40
|
+
/** Resolves the config file path for the chosen scope (does not write). */
|
|
41
|
+
resolveConfigPath: (scope: ConfigScope) => string;
|
|
42
|
+
/** True when a config file already exists at `path`. */
|
|
43
|
+
configExists: (path: string) => boolean;
|
|
44
|
+
/**
|
|
45
|
+
* (Over)writes the config content at the scope's path and returns that path. The dialog only
|
|
46
|
+
* calls this once it has decided to write, so this always writes (never a silent no-clobber skip).
|
|
47
|
+
*/
|
|
29
48
|
writeConfig: (scope: ConfigScope, content: string) => string;
|
|
30
49
|
/** Prompts the user and resolves with their (untrimmed) answer. */
|
|
31
50
|
ask: AskFn;
|
|
@@ -44,7 +63,14 @@ export declare function orderProviders(providers: DetectedProvider[]): DetectedP
|
|
|
44
63
|
export declare function parseMenuSelection(answer: string, count: number): number | null;
|
|
45
64
|
/** The index of the first ⭐ preferred model, or 0 when none are flagged. */
|
|
46
65
|
export declare function defaultModelIndex(models: ModelInfo[]): number;
|
|
47
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Builds the `.gsloth.config.json` body for a chosen provider + model. Delegates to the shared
|
|
68
|
+
* {@link buildInitConfigContent} so the interactive first-run path stamps the same `$schema`
|
|
69
|
+
* pointer (GS2-1) as the per-provider template writers. Previously this local builder omitted
|
|
70
|
+
* `$schema`, so a config created through the first-run dialog got no editor autocomplete/validation.
|
|
71
|
+
* First-run always has an explicit model chosen, so it is written into the config (unlike a bare
|
|
72
|
+
* `init <provider>` template, which omits the model to track the curated fallback, CFG-14).
|
|
73
|
+
*/
|
|
48
74
|
export declare function buildConfigContent(providerId: ProviderId, model: string): string;
|
|
49
75
|
/** Resolves the config write path for the chosen scope (CFG-3 layering). */
|
|
50
76
|
export declare function resolveConfigWritePath(scope: ConfigScope): string;
|
|
@@ -53,6 +79,14 @@ export declare function resolveConfigWritePath(scope: ConfigScope): string;
|
|
|
53
79
|
* `✓`/blank mark read like a selection checkbox; this spells the state out instead.
|
|
54
80
|
*/
|
|
55
81
|
export declare function providerReadinessLabel(provider: DetectedProvider): string;
|
|
82
|
+
/**
|
|
83
|
+
* CFG-21 — the default {@link FirstRunDialogDeps.withProgress}: an Ink spinner while `run` is in
|
|
84
|
+
* flight when the environment can drive interactive Ink (the same activation policy as
|
|
85
|
+
* {@link makeDefaultSelect}), otherwise a plain printed line via {@link displayInfo} on the
|
|
86
|
+
* readline / non-TTY path. Either way the wait is visible, never silent. The Ink module is
|
|
87
|
+
* imported lazily so a readline-only run never loads React/Ink.
|
|
88
|
+
*/
|
|
89
|
+
export declare function makeDefaultProgress(): <T>(label: string, run: () => Promise<T>) => Promise<T>;
|
|
56
90
|
/**
|
|
57
91
|
* CFG-2 — the first-run configuration dialog.
|
|
58
92
|
*
|
|
@@ -62,5 +96,5 @@ export declare function providerReadinessLabel(provider: DetectedProvider): stri
|
|
|
62
96
|
* globally (CFG-3). Writes a minimal `{ llm: { type, model } }` config and, for
|
|
63
97
|
* the project scope, scaffolds the review/guidelines preamble.
|
|
64
98
|
*/
|
|
65
|
-
export declare function runFirstRunDialog(overrides?: Partial<FirstRunDialogDeps
|
|
99
|
+
export declare function runFirstRunDialog(overrides?: Partial<FirstRunDialogDeps>, force?: boolean): Promise<void>;
|
|
66
100
|
export {};
|