@skill-harness/core 0.19.0 → 0.20.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/capture-trace-types.d.ts +3 -5
- package/dist/capture-trace-types.js +3 -5
- package/dist/defaults.d.ts +20 -15
- package/dist/defaults.js +23 -15
- package/dist/execution-trace.js +2 -3
- package/dist/grade.d.ts +1 -1
- package/dist/grade.js +1 -1
- package/dist/judge-policy.d.ts +2 -2
- package/dist/judge-policy.js +9 -7
- package/dist/run.js +2 -4
- package/package.json +1 -1
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Persisted data contracts for Pi execution traces.
|
|
3
3
|
*
|
|
4
|
-
* Types only — no behavior.
|
|
5
|
-
*
|
|
6
|
-
* fixes the shapes before any parser, capture UI, or gate evaluator is written,
|
|
7
|
-
* because both shapes get persisted and a persisted shape is expensive to move.
|
|
4
|
+
* Types only — no behavior. Both shapes are versioned because persisted formats
|
|
5
|
+
* are expensive to move and readers must fail closed on unsupported versions.
|
|
8
6
|
*
|
|
9
7
|
* Both carry an explicit version. The pi event stream they derive from is not a
|
|
10
8
|
* stable public contract (measured against pi 0.83.0; see
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Persisted data contracts for Pi execution traces.
|
|
3
3
|
*
|
|
4
|
-
* Types only — no behavior.
|
|
5
|
-
*
|
|
6
|
-
* fixes the shapes before any parser, capture UI, or gate evaluator is written,
|
|
7
|
-
* because both shapes get persisted and a persisted shape is expensive to move.
|
|
4
|
+
* Types only — no behavior. Both shapes are versioned because persisted formats
|
|
5
|
+
* are expensive to move and readers must fail closed on unsupported versions.
|
|
8
6
|
*
|
|
9
7
|
* Both carry an explicit version. The pi event stream they derive from is not a
|
|
10
8
|
* stable public contract (measured against pi 0.83.0; see
|
package/dist/defaults.d.ts
CHANGED
|
@@ -1,30 +1,35 @@
|
|
|
1
|
+
import { type ModelRef } from "./adapters/types.js";
|
|
1
2
|
/**
|
|
2
|
-
* The judge used when nothing else says otherwise:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* The judge used when nothing else says otherwise: a Pi `openai-codex` model,
|
|
4
|
+
* authenticated through the user's ChatGPT subscription rather than a metered API
|
|
5
|
+
* key. Subjects and judges now share the sole supported harness executable: `pi`.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* is what changed in 0.3.3: the default was `anthropic:claude-opus-4-8`, a metered
|
|
9
|
-
* API, and it billed a corpus once by accident because nothing in the tool surface
|
|
10
|
-
* distinguishes "the flag I forgot" from "the flag I meant". A default must not be
|
|
11
|
-
* able to spend money that was not asked for. The metered path is still one flag
|
|
12
|
-
* away (`--judge anthropic:claude-opus-4-8`) for anyone who wants it — an API key
|
|
13
|
-
* scales past a subscription's rate limits, which matters for a large `--reps` run.
|
|
7
|
+
* A default must not be able to spend money that was not explicitly authorized.
|
|
8
|
+
* Direct API providers remain available only through the metered-judge opt-in.
|
|
14
9
|
*/
|
|
15
|
-
export declare const BAKED_DEFAULT_JUDGE = "
|
|
10
|
+
export declare const BAKED_DEFAULT_JUDGE = "openai-codex:gpt-5.6-sol";
|
|
16
11
|
/**
|
|
17
12
|
* Resolve the default judge: `SKILL_HARNESS_JUDGE` if set, else the baked value.
|
|
18
13
|
* An explicit `--judge` always wins over both — this is only the default.
|
|
19
14
|
*
|
|
20
15
|
* The env layer exists because this harness is built for someone who steers a
|
|
21
16
|
* process rather than typing every flag: judge policy belongs to the repo or the
|
|
22
|
-
* shell, set once. It is also how you opt *into*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
17
|
+
* shell, set once. It is also how you opt *into* a different judge deliberately
|
|
18
|
+
* instead of repeating a flag. Read through `readEnv`, so the pre-rename
|
|
19
|
+
* `SKILL_CHECK_JUDGE` keeps working
|
|
25
20
|
* with the usual one-time notice.
|
|
26
21
|
*
|
|
27
22
|
* Resolved per call, not at module load: tests and long-lived processes (the pi
|
|
28
23
|
* extension) must see an env change without a reload.
|
|
29
24
|
*/
|
|
30
25
|
export declare function defaultJudge(): string;
|
|
26
|
+
/**
|
|
27
|
+
* Choose a judge for an artifact-only operation when the caller supplied no
|
|
28
|
+
* explicit override. Retained results may name the removed direct Claude
|
|
29
|
+
* adapter; keep those files readable, but execute their next judge call through
|
|
30
|
+
* today's Pi default and let the rewrite record that current judge.
|
|
31
|
+
*/
|
|
32
|
+
export declare function recordedJudgeOrDefault(recorded?: ModelRef): {
|
|
33
|
+
judge: ModelRef;
|
|
34
|
+
migratedFrom?: ModelRef;
|
|
35
|
+
};
|
package/dist/defaults.js
CHANGED
|
@@ -1,28 +1,23 @@
|
|
|
1
|
+
import { parseModelRef } from "./adapters/types.js";
|
|
1
2
|
import { readEnv } from "./util/env.js";
|
|
2
3
|
/**
|
|
3
|
-
* The judge used when nothing else says otherwise:
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The judge used when nothing else says otherwise: a Pi `openai-codex` model,
|
|
5
|
+
* authenticated through the user's ChatGPT subscription rather than a metered API
|
|
6
|
+
* key. Subjects and judges now share the sole supported harness executable: `pi`.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* is what changed in 0.3.3: the default was `anthropic:claude-opus-4-8`, a metered
|
|
10
|
-
* API, and it billed a corpus once by accident because nothing in the tool surface
|
|
11
|
-
* distinguishes "the flag I forgot" from "the flag I meant". A default must not be
|
|
12
|
-
* able to spend money that was not asked for. The metered path is still one flag
|
|
13
|
-
* away (`--judge anthropic:claude-opus-4-8`) for anyone who wants it — an API key
|
|
14
|
-
* scales past a subscription's rate limits, which matters for a large `--reps` run.
|
|
8
|
+
* A default must not be able to spend money that was not explicitly authorized.
|
|
9
|
+
* Direct API providers remain available only through the metered-judge opt-in.
|
|
15
10
|
*/
|
|
16
|
-
export const BAKED_DEFAULT_JUDGE = "
|
|
11
|
+
export const BAKED_DEFAULT_JUDGE = "openai-codex:gpt-5.6-sol";
|
|
17
12
|
/**
|
|
18
13
|
* Resolve the default judge: `SKILL_HARNESS_JUDGE` if set, else the baked value.
|
|
19
14
|
* An explicit `--judge` always wins over both — this is only the default.
|
|
20
15
|
*
|
|
21
16
|
* The env layer exists because this harness is built for someone who steers a
|
|
22
17
|
* process rather than typing every flag: judge policy belongs to the repo or the
|
|
23
|
-
* shell, set once. It is also how you opt *into*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
18
|
+
* shell, set once. It is also how you opt *into* a different judge deliberately
|
|
19
|
+
* instead of repeating a flag. Read through `readEnv`, so the pre-rename
|
|
20
|
+
* `SKILL_CHECK_JUDGE` keeps working
|
|
26
21
|
* with the usual one-time notice.
|
|
27
22
|
*
|
|
28
23
|
* Resolved per call, not at module load: tests and long-lived processes (the pi
|
|
@@ -31,4 +26,17 @@ export const BAKED_DEFAULT_JUDGE = "claude-code:claude-opus-4-8";
|
|
|
31
26
|
export function defaultJudge() {
|
|
32
27
|
return readEnv("JUDGE") ?? BAKED_DEFAULT_JUDGE;
|
|
33
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Choose a judge for an artifact-only operation when the caller supplied no
|
|
31
|
+
* explicit override. Retained results may name the removed direct Claude
|
|
32
|
+
* adapter; keep those files readable, but execute their next judge call through
|
|
33
|
+
* today's Pi default and let the rewrite record that current judge.
|
|
34
|
+
*/
|
|
35
|
+
export function recordedJudgeOrDefault(recorded) {
|
|
36
|
+
if (!recorded)
|
|
37
|
+
return { judge: parseModelRef(defaultJudge()) };
|
|
38
|
+
if (recorded.provider !== "claude-code")
|
|
39
|
+
return { judge: recorded };
|
|
40
|
+
return { judge: parseModelRef(defaultJudge()), migratedFrom: recorded };
|
|
41
|
+
}
|
|
34
42
|
//# sourceMappingURL=defaults.js.map
|
package/dist/execution-trace.js
CHANGED
|
@@ -5,9 +5,8 @@ import { redactArgs, redactText } from "./redaction.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Parse pi's `--mode json` event stream into an `ExecutionTraceV1`.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* from that spike are baked in here and each one is a bug if removed:
|
|
8
|
+
* Pinned by the fixtures in `packages/adapters/test/fixtures/pi-json/`. Three
|
|
9
|
+
* event-shape constraints are baked in here and each one is a bug if removed:
|
|
11
10
|
*
|
|
12
11
|
* 1. **Line-at-a-time, never buffered.** `message_update` re-sends the entire
|
|
13
12
|
* accumulated message on every delta, so the stream is quadratic in output
|
package/dist/grade.d.ts
CHANGED
|
@@ -54,6 +54,6 @@ export declare function gradeTranscript(adapter: HarnessAdapter, judge: ModelRef
|
|
|
54
54
|
/**
|
|
55
55
|
* Grade a transcript in a fresh, isolated, throwaway workspace — never the
|
|
56
56
|
* subject's scenario dir — so the judge can't ingest repo context the subject
|
|
57
|
-
* left behind (matters for
|
|
57
|
+
* left behind (matters for provider CLIs that read cwd, including Pi).
|
|
58
58
|
*/
|
|
59
59
|
export declare function judgeInWorkspace(adapter: HarnessAdapter, judge: ModelRef, prompt: string, specDir: string): Promise<GradeResult>;
|
package/dist/grade.js
CHANGED
|
@@ -139,7 +139,7 @@ export async function gradeTranscript(adapter, judge, prompt, cwd) {
|
|
|
139
139
|
/**
|
|
140
140
|
* Grade a transcript in a fresh, isolated, throwaway workspace — never the
|
|
141
141
|
* subject's scenario dir — so the judge can't ingest repo context the subject
|
|
142
|
-
* left behind (matters for
|
|
142
|
+
* left behind (matters for provider CLIs that read cwd, including Pi).
|
|
143
143
|
*/
|
|
144
144
|
export async function judgeInWorkspace(adapter, judge, prompt, specDir) {
|
|
145
145
|
const ws = createWorkspace("none", { specDir });
|
package/dist/judge-policy.d.ts
CHANGED
|
@@ -31,8 +31,8 @@ export interface JudgeAllowOpts {
|
|
|
31
31
|
*
|
|
32
32
|
* That third path is latent rather than live in the corpus this was built against:
|
|
33
33
|
* checked 2026-08-05, all ~140 committed `results.yaml` in `principal-pi-skills`
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* recorded the then-supported subscription judge explicitly. The old default was
|
|
35
|
+
* reachable, not taken. Worth stating
|
|
36
36
|
* precisely — "your whole archive bills on regrade" would have been a scarier claim
|
|
37
37
|
* than the evidence supports.
|
|
38
38
|
*
|
package/dist/judge-policy.js
CHANGED
|
@@ -3,9 +3,8 @@ import { BAKED_DEFAULT_JUDGE } from "./defaults.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Judge providers that cannot bill a per-token API.
|
|
5
5
|
*
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
* the user's ChatGPT subscription (OAuth). `ollama`/`lmstudio`/`llamacpp`/`local`
|
|
6
|
+
* `openai-codex` runs through Pi and authenticates with the user's ChatGPT
|
|
7
|
+
* subscription (OAuth). `ollama`/`lmstudio`/`llamacpp`/`local`
|
|
9
8
|
* are local runtimes. Everything else — including direct `openai` — is assumed
|
|
10
9
|
* to charge.
|
|
11
10
|
*
|
|
@@ -14,7 +13,7 @@ import { BAKED_DEFAULT_JUDGE } from "./defaults.js";
|
|
|
14
13
|
* being wrong in that direction produces a surprise invoice while being wrong in
|
|
15
14
|
* this direction produces one extra flag.
|
|
16
15
|
*/
|
|
17
|
-
const FREE_JUDGE_PROVIDERS = new Set(["
|
|
16
|
+
const FREE_JUDGE_PROVIDERS = new Set(["openai-codex", "ollama", "lmstudio", "llamacpp", "local"]);
|
|
18
17
|
/** Whether judging with this ref can charge a per-token API. */
|
|
19
18
|
export function isMeteredJudge(judge) {
|
|
20
19
|
return !FREE_JUDGE_PROVIDERS.has(judge.provider);
|
|
@@ -40,8 +39,8 @@ export function allowMeteredJudge() {
|
|
|
40
39
|
*
|
|
41
40
|
* That third path is latent rather than live in the corpus this was built against:
|
|
42
41
|
* checked 2026-08-05, all ~140 committed `results.yaml` in `principal-pi-skills`
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* recorded the then-supported subscription judge explicitly. The old default was
|
|
43
|
+
* reachable, not taken. Worth stating
|
|
45
44
|
* precisely — "your whole archive bills on regrade" would have been a scarier claim
|
|
46
45
|
* than the evidence supports.
|
|
47
46
|
*
|
|
@@ -49,6 +48,9 @@ export function allowMeteredJudge() {
|
|
|
49
48
|
* is what a run *is*.
|
|
50
49
|
*/
|
|
51
50
|
export function assertJudgeAllowed(judge, opts) {
|
|
51
|
+
if (judge.provider === "claude-code") {
|
|
52
|
+
throw new Error("judge provider `claude-code` was removed; choose a provider configured in Pi, such as `openai-codex`");
|
|
53
|
+
}
|
|
52
54
|
if (!isMeteredJudge(judge))
|
|
53
55
|
return;
|
|
54
56
|
if (opts.allowMetered || allowMeteredJudge())
|
|
@@ -56,7 +58,7 @@ export function assertJudgeAllowed(judge, opts) {
|
|
|
56
58
|
const token = `${judge.provider}:${judge.model}`;
|
|
57
59
|
throw new Error(`refusing to judge with ${token}: \`${judge.provider}\` bills a per-token API key, and it came from ${opts.source}.\n` +
|
|
58
60
|
` Judging is meant to cost nothing you did not ask for.\n` +
|
|
59
|
-
` • judge on your
|
|
61
|
+
` • judge through Pi on your subscription: --judge ${BAKED_DEFAULT_JUDGE}\n` +
|
|
60
62
|
` • allow the metered API for this command: --allow-metered-judge\n` +
|
|
61
63
|
` • allow it for this repo or shell: export SKILL_HARNESS_ALLOW_METERED_JUDGE=1`);
|
|
62
64
|
}
|
package/dist/run.js
CHANGED
|
@@ -19,10 +19,8 @@ import { aggregateMetrics } from "./metrics.js";
|
|
|
19
19
|
import { providerFailureFromTranscript } from "./provider-failure.js";
|
|
20
20
|
/**
|
|
21
21
|
* The pi-daddy arm's delivery proof, by convention: `arms.yaml` points
|
|
22
|
-
* `PI_GRANTS_LEDGER` at exactly this filename inside the run
|
|
23
|
-
*
|
|
24
|
-
* a fixed name here is what makes the count readable without parsing the arm's
|
|
25
|
-
* own `env` map back out.
|
|
22
|
+
* `PI_GRANTS_LEDGER` at exactly this filename inside the run directory. A fixed
|
|
23
|
+
* name keeps the count readable without parsing the arm's `env` map back out.
|
|
26
24
|
*/
|
|
27
25
|
const LEDGER_FILENAME = "pi-daddy.ledger.jsonl";
|
|
28
26
|
/**
|