@aid-framework/cli 0.0.0-stage → 0.1.39
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/LICENSE +201 -0
- package/README.md +45 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/args.d.ts +37 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +74 -0
- package/dist/args.js.map +1 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/eval.d.ts +44 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +257 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/gen.d.ts +42 -0
- package/dist/commands/gen.d.ts.map +1 -0
- package/dist/commands/gen.js +138 -0
- package/dist/commands/gen.js.map +1 -0
- package/dist/commands/ingest.d.ts +44 -0
- package/dist/commands/ingest.d.ts.map +1 -0
- package/dist/commands/ingest.js +238 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/init.d.ts +38 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +203 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/validate.d.ts +22 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +53 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/context.d.ts +37 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +36 -0
- package/dist/context.js.map +1 -0
- package/dist/diagnostics.d.ts +42 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +47 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/exit.d.ts +16 -0
- package/dist/exit.d.ts.map +1 -0
- package/dist/exit.js +15 -0
- package/dist/exit.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +25 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +155 -0
- package/dist/main.js.map +1 -0
- package/dist/output.d.ts +48 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +50 -0
- package/dist/output.js.map +1 -0
- package/dist/paths.d.ts +21 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -0
- package/dist/pipeline.d.ts +74 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +113 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/python.d.ts +30 -0
- package/dist/python.d.ts.map +1 -0
- package/dist/python.js +57 -0
- package/dist/python.js.map +1 -0
- package/dist/targets.d.ts +75 -0
- package/dist/targets.d.ts.map +1 -0
- package/dist/targets.js +136 -0
- package/dist/targets.js.map +1 -0
- package/dist/usage.d.ts +20 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +49 -0
- package/dist/usage.js.map +1 -0
- package/package.json +46 -3
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A hand-written parser for the flag grammar this CLI actually has.
|
|
3
|
+
*
|
|
4
|
+
* The whole grammar is a command, positional arguments, and
|
|
5
|
+
* `--flag` / `--flag=value` / `--flag value` options, with `--` ending option parsing.
|
|
6
|
+
* A CLI framework brings a plugin system, a config loader and a help renderer to that,
|
|
7
|
+
* which is more code than the grammar and more surface than the design asks for.
|
|
8
|
+
*
|
|
9
|
+
* The parser is pure: it reports a message and lets the caller decide the exit code.
|
|
10
|
+
*/
|
|
11
|
+
export interface FlagSpec {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
/** A `value` flag consumes the next argument; a `boolean` flag never does. */
|
|
14
|
+
readonly kind: 'boolean' | 'value';
|
|
15
|
+
/** The placeholder shown in help, for a `value` flag. */
|
|
16
|
+
readonly value?: string;
|
|
17
|
+
readonly summary: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function booleanFlag(name: string, summary: string): FlagSpec;
|
|
20
|
+
export declare function valueFlag(name: string, value: string, summary: string): FlagSpec;
|
|
21
|
+
/** Every command answers `--json` with one JSON document and `-h`/`--help` with usage. */
|
|
22
|
+
export declare const JSON_FLAG: FlagSpec;
|
|
23
|
+
export interface ParsedArguments {
|
|
24
|
+
readonly positionals: readonly string[];
|
|
25
|
+
readonly values: ReadonlyMap<string, string>;
|
|
26
|
+
readonly booleans: ReadonlySet<string>;
|
|
27
|
+
readonly help: boolean;
|
|
28
|
+
}
|
|
29
|
+
export type ParseOutcome = {
|
|
30
|
+
readonly ok: true;
|
|
31
|
+
readonly args: ParsedArguments;
|
|
32
|
+
} | {
|
|
33
|
+
readonly ok: false;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
};
|
|
36
|
+
export declare function parseArguments(argv: readonly string[], flags: readonly FlagSpec[]): ParseOutcome;
|
|
37
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,CAEnE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,CAEhF;AAED,0FAA0F;AAC1F,eAAO,MAAM,SAAS,UAA2D,CAAC;AAIlF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,YAAY,CA0DhG"}
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A hand-written parser for the flag grammar this CLI actually has.
|
|
3
|
+
*
|
|
4
|
+
* The whole grammar is a command, positional arguments, and
|
|
5
|
+
* `--flag` / `--flag=value` / `--flag value` options, with `--` ending option parsing.
|
|
6
|
+
* A CLI framework brings a plugin system, a config loader and a help renderer to that,
|
|
7
|
+
* which is more code than the grammar and more surface than the design asks for.
|
|
8
|
+
*
|
|
9
|
+
* The parser is pure: it reports a message and lets the caller decide the exit code.
|
|
10
|
+
*/
|
|
11
|
+
export function booleanFlag(name, summary) {
|
|
12
|
+
return { name, kind: 'boolean', summary };
|
|
13
|
+
}
|
|
14
|
+
export function valueFlag(name, value, summary) {
|
|
15
|
+
return { name, kind: 'value', value, summary };
|
|
16
|
+
}
|
|
17
|
+
/** Every command answers `--json` with one JSON document and `-h`/`--help` with usage. */
|
|
18
|
+
export const JSON_FLAG = booleanFlag('json', 'print one JSON document on stdout');
|
|
19
|
+
const HELP_FLAG = booleanFlag('help', "print this command's usage");
|
|
20
|
+
export function parseArguments(argv, flags) {
|
|
21
|
+
const known = new Map();
|
|
22
|
+
for (const flag of flags)
|
|
23
|
+
known.set(flag.name, flag);
|
|
24
|
+
known.set(HELP_FLAG.name, HELP_FLAG);
|
|
25
|
+
const positionals = [];
|
|
26
|
+
const values = new Map();
|
|
27
|
+
const booleans = new Set();
|
|
28
|
+
let optionsEnded = false;
|
|
29
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
30
|
+
const token = argv[index];
|
|
31
|
+
if (token === undefined)
|
|
32
|
+
break;
|
|
33
|
+
if (optionsEnded || !token.startsWith('-')) {
|
|
34
|
+
positionals.push(token);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (token === '--') {
|
|
38
|
+
optionsEnded = true;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (token === '-h') {
|
|
42
|
+
booleans.add(HELP_FLAG.name);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!token.startsWith('--')) {
|
|
46
|
+
return { ok: false, message: `unknown option \`${token}\`` };
|
|
47
|
+
}
|
|
48
|
+
const equals = token.indexOf('=');
|
|
49
|
+
const name = equals === -1 ? token.slice(2) : token.slice(2, equals);
|
|
50
|
+
const spec = known.get(name);
|
|
51
|
+
if (spec === undefined) {
|
|
52
|
+
return { ok: false, message: `unknown option \`--${name}\`` };
|
|
53
|
+
}
|
|
54
|
+
if (spec.kind === 'boolean') {
|
|
55
|
+
if (equals !== -1) {
|
|
56
|
+
return { ok: false, message: `\`--${name}\` does not take a value` };
|
|
57
|
+
}
|
|
58
|
+
booleans.add(name);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (equals !== -1) {
|
|
62
|
+
values.set(name, token.slice(equals + 1));
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const next = argv[index + 1];
|
|
66
|
+
if (next === undefined) {
|
|
67
|
+
return { ok: false, message: `\`--${name}\` needs a value` };
|
|
68
|
+
}
|
|
69
|
+
index += 1;
|
|
70
|
+
values.set(name, next);
|
|
71
|
+
}
|
|
72
|
+
return { ok: true, args: { positionals, values, booleans, help: booleans.has('help') } };
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The `aid` executable: the only file in this package that touches `process`.
|
|
4
|
+
*
|
|
5
|
+
* Everything it does is three lines of I/O wiring, because everything else lives behind
|
|
6
|
+
* `run(argv, context)`. Keeping the process bindings in one place is what makes the rest
|
|
7
|
+
* of the CLI testable, and the `import.meta.url` guard below is what makes importing this
|
|
8
|
+
* module a no-op: a test can import `main.js` and call `run` without the import itself
|
|
9
|
+
* deciding to read `process.argv` and start working.
|
|
10
|
+
*
|
|
11
|
+
* The exit status is set through `process.exitCode` rather than `process.exit()`. Nothing
|
|
12
|
+
* here is holding a handle open, so the process ends when the event loop drains, and
|
|
13
|
+
* `process.exit()` before that is how a CLI truncates its own stdout on a pipe.
|
|
14
|
+
*/
|
|
15
|
+
/** The real entry point: the process streams, the process environment, real children. */
|
|
16
|
+
export declare function main(argv?: readonly string[]): number;
|
|
17
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAOH,yFAAyF;AACzF,wBAAgB,IAAI,CAAC,IAAI,GAAE,SAAS,MAAM,EAA0B,GAAG,MAAM,CAE5E"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The `aid` executable: the only file in this package that touches `process`.
|
|
4
|
+
*
|
|
5
|
+
* Everything it does is three lines of I/O wiring, because everything else lives behind
|
|
6
|
+
* `run(argv, context)`. Keeping the process bindings in one place is what makes the rest
|
|
7
|
+
* of the CLI testable, and the `import.meta.url` guard below is what makes importing this
|
|
8
|
+
* module a no-op: a test can import `main.js` and call `run` without the import itself
|
|
9
|
+
* deciding to read `process.argv` and start working.
|
|
10
|
+
*
|
|
11
|
+
* The exit status is set through `process.exitCode` rather than `process.exit()`. Nothing
|
|
12
|
+
* here is holding a handle open, so the process ends when the event loop drains, and
|
|
13
|
+
* `process.exit()` before that is how a CLI truncates its own stdout on a pipe.
|
|
14
|
+
*/
|
|
15
|
+
import { pathToFileURL } from 'node:url';
|
|
16
|
+
import { createContext } from './context.js';
|
|
17
|
+
import { run } from './main.js';
|
|
18
|
+
/** The real entry point: the process streams, the process environment, real children. */
|
|
19
|
+
export function main(argv = process.argv.slice(2)) {
|
|
20
|
+
return run(argv, createContext());
|
|
21
|
+
}
|
|
22
|
+
const entry = process.argv[1];
|
|
23
|
+
if (entry !== undefined && import.meta.url === pathToFileURL(entry).href) {
|
|
24
|
+
process.exitCode = main();
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,yFAAyF;AACzF,MAAM,UAAU,IAAI,CAAC,IAAI,GAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,OAAO,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACzE,OAAO,CAAC,QAAQ,GAAG,IAAI,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid eval` — run the eval gate, or record the baseline it measures against.
|
|
3
|
+
*
|
|
4
|
+
* **What this shells out to, and why.**
|
|
5
|
+
*
|
|
6
|
+
* The assignment sketched `uv run python -m aid_runtime.evals ...`, but that module is not
|
|
7
|
+
* runnable: there is no `__main__.py`, no console script, and no `argparse` anywhere under
|
|
8
|
+
* `runtimes/python/src/aid_runtime/evals/`. The command it names does not exist.
|
|
9
|
+
*
|
|
10
|
+
* What does exist, one per eval, is the module the generator emits:
|
|
11
|
+
* `app/generated/evals/<id>.py`, with a `main()` that prints `result.summary()` and exits
|
|
12
|
+
* non-zero when the gate fails. That module is the intended surface -- it is generated code
|
|
13
|
+
* the spec already declares, and it is what the committed `app/evals/*.baseline.json` was
|
|
14
|
+
* produced by. So `aid eval` runs `python -m app.generated.evals.<id>` from the project
|
|
15
|
+
* root, which is also what a person would type by hand.
|
|
16
|
+
*
|
|
17
|
+
* The alternative was adding an entry point to `runtimes/`, and that was rejected: the
|
|
18
|
+
* runtime is a landed layer whose published surface other layers depend on, and the
|
|
19
|
+
* assignment says not to modify it. A missing runtime entry point is this layer's problem
|
|
20
|
+
* to route around, not a reason to change a shipped one.
|
|
21
|
+
*
|
|
22
|
+
* **`--baseline` delegates the sampling.** The gate is statistical (`maxRegression` against
|
|
23
|
+
* a stored distribution), so a baseline from a single run is noise shaped like a fact. The
|
|
24
|
+
* generated module's `run()` already samples the dataset `SAMPLES` times -- the N the spec
|
|
25
|
+
* declares -- so recording a baseline calls that, then the runtime's own documented recipe
|
|
26
|
+
* (`EvalBaseline.from_run(await run(), model=...).to_json()`, which is literally the string
|
|
27
|
+
* in the generated `load_baseline`'s error message). Re-sampling here would invent a second
|
|
28
|
+
* N and let the CLI and the module disagree about how many runs a baseline means.
|
|
29
|
+
*
|
|
30
|
+
* That recipe is the one place in the CLI that writes Python. It is a script piped to the
|
|
31
|
+
* interpreter over stdin rather than an API call because the runtime has no such entry
|
|
32
|
+
* point, and it is deliberately short: anything longer would be this layer reimplementing
|
|
33
|
+
* the runtime's measurement.
|
|
34
|
+
*/
|
|
35
|
+
import type { CliContext } from '../context.js';
|
|
36
|
+
import type { CommandOutcome } from '../output.js';
|
|
37
|
+
export interface EvalOptions {
|
|
38
|
+
readonly spec: string | undefined;
|
|
39
|
+
readonly target: string | undefined;
|
|
40
|
+
readonly suite: string | undefined;
|
|
41
|
+
readonly baseline: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function evaluate(context: CliContext, options: EvalOptions): CommandOutcome;
|
|
44
|
+
//# sourceMappingURL=eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAIhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAOnD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AA6DD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,cAAc,CA0LlF"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid eval` — run the eval gate, or record the baseline it measures against.
|
|
3
|
+
*
|
|
4
|
+
* **What this shells out to, and why.**
|
|
5
|
+
*
|
|
6
|
+
* The assignment sketched `uv run python -m aid_runtime.evals ...`, but that module is not
|
|
7
|
+
* runnable: there is no `__main__.py`, no console script, and no `argparse` anywhere under
|
|
8
|
+
* `runtimes/python/src/aid_runtime/evals/`. The command it names does not exist.
|
|
9
|
+
*
|
|
10
|
+
* What does exist, one per eval, is the module the generator emits:
|
|
11
|
+
* `app/generated/evals/<id>.py`, with a `main()` that prints `result.summary()` and exits
|
|
12
|
+
* non-zero when the gate fails. That module is the intended surface -- it is generated code
|
|
13
|
+
* the spec already declares, and it is what the committed `app/evals/*.baseline.json` was
|
|
14
|
+
* produced by. So `aid eval` runs `python -m app.generated.evals.<id>` from the project
|
|
15
|
+
* root, which is also what a person would type by hand.
|
|
16
|
+
*
|
|
17
|
+
* The alternative was adding an entry point to `runtimes/`, and that was rejected: the
|
|
18
|
+
* runtime is a landed layer whose published surface other layers depend on, and the
|
|
19
|
+
* assignment says not to modify it. A missing runtime entry point is this layer's problem
|
|
20
|
+
* to route around, not a reason to change a shipped one.
|
|
21
|
+
*
|
|
22
|
+
* **`--baseline` delegates the sampling.** The gate is statistical (`maxRegression` against
|
|
23
|
+
* a stored distribution), so a baseline from a single run is noise shaped like a fact. The
|
|
24
|
+
* generated module's `run()` already samples the dataset `SAMPLES` times -- the N the spec
|
|
25
|
+
* declares -- so recording a baseline calls that, then the runtime's own documented recipe
|
|
26
|
+
* (`EvalBaseline.from_run(await run(), model=...).to_json()`, which is literally the string
|
|
27
|
+
* in the generated `load_baseline`'s error message). Re-sampling here would invent a second
|
|
28
|
+
* N and let the CLI and the module disagree about how many runs a baseline means.
|
|
29
|
+
*
|
|
30
|
+
* That recipe is the one place in the CLI that writes Python. It is a script piped to the
|
|
31
|
+
* interpreter over stdin rather than an API call because the runtime has no such entry
|
|
32
|
+
* point, and it is deliberately short: anything longer would be this layer reimplementing
|
|
33
|
+
* the runtime's measurement.
|
|
34
|
+
*/
|
|
35
|
+
import { existsSync } from 'node:fs';
|
|
36
|
+
import { sortDiagnostics } from '@aid-framework/spec';
|
|
37
|
+
import { CLI_DIAGNOSTIC_CODES, cliError, cliWarning } from '../diagnostics.js';
|
|
38
|
+
import { EXIT_FAILURE, EXIT_OK, EXIT_USAGE } from '../exit.js';
|
|
39
|
+
import { outcome } from '../output.js';
|
|
40
|
+
import { absolutePath } from '../paths.js';
|
|
41
|
+
import { lowerSpec, readSpec } from '../pipeline.js';
|
|
42
|
+
import { discoverInterpreter, INTERPRETERS, interpreterCommand, invoke } from '../python.js';
|
|
43
|
+
import { resolveTarget, unknownTargetDiagnostic } from '../targets.js';
|
|
44
|
+
/** Eval ids the spec declares, or the diagnostics that stopped it from declaring any. */
|
|
45
|
+
function declaredSuites(text, specPath) {
|
|
46
|
+
const lowered = lowerSpec(text, specPath);
|
|
47
|
+
if (!lowered.ok)
|
|
48
|
+
return { ok: false, diagnostics: lowered.diagnostics };
|
|
49
|
+
const ir = lowered.ir;
|
|
50
|
+
return {
|
|
51
|
+
ok: true,
|
|
52
|
+
ids: ir.evals.map((entry) => entry.id),
|
|
53
|
+
warnings: lowered.diagnostics,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The baseline recorder, run as `python -`. `python` puts the current directory on
|
|
58
|
+
* `sys.path`, so `import app.generated.evals.<id>` resolves against the project root and
|
|
59
|
+
* each module's own `BASELINE_PATH` decides where its baseline goes -- the same path
|
|
60
|
+
* `load_baseline()` reads back, because it is the same constant.
|
|
61
|
+
*/
|
|
62
|
+
function baselineScript(modules) {
|
|
63
|
+
return [
|
|
64
|
+
'import asyncio',
|
|
65
|
+
'import importlib',
|
|
66
|
+
'import pathlib',
|
|
67
|
+
'',
|
|
68
|
+
'from aid_runtime.evals import EvalBaseline',
|
|
69
|
+
'',
|
|
70
|
+
`MODULES = ${JSON.stringify(modules)}`,
|
|
71
|
+
'',
|
|
72
|
+
'for name in MODULES:',
|
|
73
|
+
' module = importlib.import_module(name)',
|
|
74
|
+
' # run() already samples the dataset SAMPLES times, the N the spec declares.',
|
|
75
|
+
' baseline = EvalBaseline.from_run(',
|
|
76
|
+
' asyncio.run(module.run()),',
|
|
77
|
+
' model=module.MODEL,',
|
|
78
|
+
" note='recorded by `aid eval --baseline`',",
|
|
79
|
+
' )',
|
|
80
|
+
' path = pathlib.Path(module.BASELINE_PATH)',
|
|
81
|
+
' path.parent.mkdir(parents=True, exist_ok=True)',
|
|
82
|
+
' path.write_text(baseline.to_json(), encoding="utf-8")',
|
|
83
|
+
' print(f"wrote {path}")',
|
|
84
|
+
'',
|
|
85
|
+
].join('\n');
|
|
86
|
+
}
|
|
87
|
+
export function evaluate(context, options) {
|
|
88
|
+
const command = 'eval';
|
|
89
|
+
const target = resolveTarget(options.target);
|
|
90
|
+
if (target === undefined) {
|
|
91
|
+
return outcome({
|
|
92
|
+
command,
|
|
93
|
+
exitCode: EXIT_USAGE,
|
|
94
|
+
diagnostics: [unknownTargetDiagnostic(options.target ?? '')],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const specPath = options.spec ?? target.specPath;
|
|
98
|
+
const fields = { target: target.name, spec: specPath, suite: options.suite ?? null };
|
|
99
|
+
const read = readSpec(context, specPath);
|
|
100
|
+
if (!read.ok) {
|
|
101
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: read.diagnostics });
|
|
102
|
+
}
|
|
103
|
+
const declared = declaredSuites(read.text, specPath);
|
|
104
|
+
if (!declared.ok) {
|
|
105
|
+
return outcome({ command, exitCode: EXIT_FAILURE, fields, diagnostics: declared.diagnostics });
|
|
106
|
+
}
|
|
107
|
+
// `--suite` is checked against the ids the spec declares, not against filenames on
|
|
108
|
+
// disk: the set of evals is a property of the spec, so a typo is a usage error and
|
|
109
|
+
// should say which ids exist.
|
|
110
|
+
if (options.suite !== undefined && !declared.ids.includes(options.suite)) {
|
|
111
|
+
return outcome({
|
|
112
|
+
command,
|
|
113
|
+
exitCode: EXIT_USAGE,
|
|
114
|
+
fields,
|
|
115
|
+
diagnostics: [
|
|
116
|
+
cliError({
|
|
117
|
+
code: CLI_DIAGNOSTIC_CODES.suiteNotFound,
|
|
118
|
+
message: `No eval named "${options.suite}" in ${specPath}.`,
|
|
119
|
+
path: [specPath],
|
|
120
|
+
hint: declared.ids.length > 0
|
|
121
|
+
? `Declared evals: ${declared.ids.join(', ')}.`
|
|
122
|
+
: 'The spec declares no evals.',
|
|
123
|
+
}),
|
|
124
|
+
],
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const suites = options.suite === undefined ? declared.ids : [options.suite];
|
|
128
|
+
const missing = suites.filter((id) => !existsSync(absolutePath(context.cwd, target.evalModuleFile(id))));
|
|
129
|
+
if (missing.length > 0) {
|
|
130
|
+
return outcome({
|
|
131
|
+
command,
|
|
132
|
+
exitCode: EXIT_FAILURE,
|
|
133
|
+
fields: { ...fields, suites },
|
|
134
|
+
diagnostics: [
|
|
135
|
+
cliError({
|
|
136
|
+
code: CLI_DIAGNOSTIC_CODES.evalModulesMissing,
|
|
137
|
+
message: `No generated eval module for ${missing.map((id) => `"${id}"`).join(', ')}.`,
|
|
138
|
+
path: missing.map((id) => target.evalModuleFile(id)),
|
|
139
|
+
hint: 'Run `aid gen`: the evals that run are the modules the generator emits.',
|
|
140
|
+
}),
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (target.runner !== 'python') {
|
|
145
|
+
return outcome({
|
|
146
|
+
command,
|
|
147
|
+
// Exit 2, not 1: this command has no runner for this target, so no eval ran and
|
|
148
|
+
// nothing about the project was judged. `1` would read as "the evals failed".
|
|
149
|
+
exitCode: EXIT_USAGE,
|
|
150
|
+
fields: { ...fields, suites },
|
|
151
|
+
diagnostics: [
|
|
152
|
+
cliError({
|
|
153
|
+
code: CLI_DIAGNOSTIC_CODES.runnerUnsupported,
|
|
154
|
+
message: `\`aid eval\` runs generated Python modules, and ${target.name} emits TypeScript.`,
|
|
155
|
+
hint: 'The emitted eval module exports `sample()` and `evaluate(run, baseline)`; run it with Node.',
|
|
156
|
+
}),
|
|
157
|
+
],
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const interpreter = discoverInterpreter(context);
|
|
161
|
+
if (interpreter === undefined) {
|
|
162
|
+
return outcome({
|
|
163
|
+
command,
|
|
164
|
+
// Exit 2, not 1: nothing about the project was judged. The gate has no verdict when
|
|
165
|
+
// the thing that would run it cannot start, and `1` would read as "the evals failed".
|
|
166
|
+
exitCode: EXIT_USAGE,
|
|
167
|
+
fields: { ...fields, suites },
|
|
168
|
+
diagnostics: [
|
|
169
|
+
cliError({
|
|
170
|
+
code: CLI_DIAGNOSTIC_CODES.pythonMissing,
|
|
171
|
+
message: `No interpreter could import aid_runtime (tried ${INTERPRETERS.join(', ')}).`,
|
|
172
|
+
hint: 'Install the runtime into the interpreter you run with, or run the generated eval modules yourself.',
|
|
173
|
+
}),
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const modules = suites.map((id) => target.evalModule(id));
|
|
178
|
+
const base = interpreterCommand(interpreter);
|
|
179
|
+
const common = { ...fields, suites, interpreter };
|
|
180
|
+
if (options.baseline) {
|
|
181
|
+
const recorded = invoke(context, [...base, '-'], baselineScript(modules));
|
|
182
|
+
if (recorded === undefined || recorded.status !== 0) {
|
|
183
|
+
return outcome({
|
|
184
|
+
command,
|
|
185
|
+
exitCode: EXIT_FAILURE,
|
|
186
|
+
fields: common,
|
|
187
|
+
diagnostics: [
|
|
188
|
+
cliError({
|
|
189
|
+
code: CLI_DIAGNOSTIC_CODES.runnerFailed,
|
|
190
|
+
message: `Could not record a baseline with ${interpreter}.`,
|
|
191
|
+
hint: 'Recording a baseline runs the evals, so it needs whatever they need; see the output for why they did not run.',
|
|
192
|
+
}),
|
|
193
|
+
],
|
|
194
|
+
text: recorded?.stdout.trimEnd() ?? '',
|
|
195
|
+
stderr: recorded?.stderr ?? '',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return outcome({
|
|
199
|
+
command,
|
|
200
|
+
exitCode: EXIT_OK,
|
|
201
|
+
fields: common,
|
|
202
|
+
text: recorded.stdout.trimEnd(),
|
|
203
|
+
stderr: recorded.stderr,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const results = [];
|
|
207
|
+
const output = [];
|
|
208
|
+
const spoken = [];
|
|
209
|
+
const diagnostics = [...declared.warnings];
|
|
210
|
+
for (const [index, module] of modules.entries()) {
|
|
211
|
+
const run = invoke(context, [...base, '-m', module]);
|
|
212
|
+
if (run === undefined) {
|
|
213
|
+
return outcome({
|
|
214
|
+
command,
|
|
215
|
+
exitCode: EXIT_USAGE,
|
|
216
|
+
fields: common,
|
|
217
|
+
diagnostics: [
|
|
218
|
+
cliError({
|
|
219
|
+
code: CLI_DIAGNOSTIC_CODES.runnerFailed,
|
|
220
|
+
message: `Could not start ${interpreter} to run "${module}".`,
|
|
221
|
+
}),
|
|
222
|
+
],
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const suite = suites[index] ?? module;
|
|
226
|
+
results.push({ suite, module, status: run.status ?? EXIT_FAILURE });
|
|
227
|
+
if (run.stdout.trim() !== '')
|
|
228
|
+
output.push(run.stdout.trimEnd());
|
|
229
|
+
// The generated `main()` prints its summary to stdout and exits non-zero on a
|
|
230
|
+
// regression; anything on stderr is the eval reporting something that did not fit in
|
|
231
|
+
// a metric. It is surfaced rather than swallowed, because a gate that hides what it
|
|
232
|
+
// could not measure is a gate that passes for the wrong reason -- and it is surfaced
|
|
233
|
+
// on stderr, including under `--json`, because that is where the process that wrote it
|
|
234
|
+
// wrote it, and `--json` replaces stdout with a document rather than with nothing.
|
|
235
|
+
if (run.stderr.trim() !== '') {
|
|
236
|
+
spoken.push(run.stderr.trimEnd());
|
|
237
|
+
diagnostics.push(cliWarning({
|
|
238
|
+
code: CLI_DIAGNOSTIC_CODES.runnerWarned,
|
|
239
|
+
message: `"${suite}" wrote to stderr.`,
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// A non-zero exit from a generated module *is* the gate's verdict, so it propagates
|
|
244
|
+
// rather than being reinterpreted here. The CLI reports the gate; it has no opinion
|
|
245
|
+
// about the numbers, and forming one would be the second implementation of the gate
|
|
246
|
+
// that this layer exists to avoid.
|
|
247
|
+
const failed = results.some((result) => result.status !== 0);
|
|
248
|
+
return outcome({
|
|
249
|
+
command,
|
|
250
|
+
exitCode: failed ? EXIT_FAILURE : EXIT_OK,
|
|
251
|
+
fields: { ...common, results },
|
|
252
|
+
diagnostics: sortDiagnostics(diagnostics),
|
|
253
|
+
text: output.join('\n'),
|
|
254
|
+
stderr: spoken.join('\n'),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aid gen` — compile the spec and reconcile the tree with it.
|
|
3
|
+
*
|
|
4
|
+
* Every decision about *what* changes belongs to `@aid-framework/generator-sdk`: `planRegeneration`
|
|
5
|
+
* decides the actions, `regenerate` applies them, and the drift rule that refuses to
|
|
6
|
+
* overwrite an edited generated file is the SDK's. The CLI decides four things and
|
|
7
|
+
* nothing else: which target, which spec, whether to write, and what the run's exit code
|
|
8
|
+
* means. In particular it does not re-derive ownership, re-hash a file, or re-implement
|
|
9
|
+
* drift -- two implementations of that rule would eventually disagree, and the one that
|
|
10
|
+
* disagreed would be the one holding a developer's edits.
|
|
11
|
+
*
|
|
12
|
+
* One deliberate divergence from `generate-example.mjs`, noted because it is a choice: the
|
|
13
|
+
* manifest is written even when the run reports drift. `regenerate` records the *previous*
|
|
14
|
+
* hash for a file it refused to overwrite, so a run that refuses an edit and a run that
|
|
15
|
+
* discards one cannot disagree about what is on the tree; skipping the manifest write
|
|
16
|
+
* instead leaves files that this run did create unrecorded, and the next run then reports
|
|
17
|
+
* those as drift even though the generator was the one that wrote them.
|
|
18
|
+
*/
|
|
19
|
+
import type { RegenerationReport } from '@aid-framework/generator-sdk';
|
|
20
|
+
import type { CliContext } from '../context.js';
|
|
21
|
+
import type { CliDiagnostic } from '../diagnostics.js';
|
|
22
|
+
import type { CommandOutcome } from '../output.js';
|
|
23
|
+
import type { Target } from '../targets.js';
|
|
24
|
+
export interface GenerateOptions {
|
|
25
|
+
readonly spec: string | undefined;
|
|
26
|
+
readonly target: string | undefined;
|
|
27
|
+
readonly dryRun: boolean;
|
|
28
|
+
readonly force: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** A spec that compiled and a plan that was reconciled, or the reason it was not. */
|
|
31
|
+
export interface GenerateSuccess {
|
|
32
|
+
readonly target: Target;
|
|
33
|
+
readonly specPath: string;
|
|
34
|
+
readonly report: RegenerationReport;
|
|
35
|
+
readonly warnings: readonly CliDiagnostic[];
|
|
36
|
+
readonly dryRun: boolean;
|
|
37
|
+
readonly force: boolean;
|
|
38
|
+
readonly manifestWritten: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** The public entry point, and the one `aid init --gen` folds into its own report. */
|
|
41
|
+
export declare function generate(context: CliContext, options: GenerateOptions): CommandOutcome;
|
|
42
|
+
//# sourceMappingURL=gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen.d.ts","sourceRoot":"","sources":["../../src/commands/gen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAYvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAwED,sFAAsF;AACtF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,GAAG,cAAc,CAEtF"}
|