taskflow-core 0.1.3 → 0.1.5
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 +861 -0
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +5 -1
- package/dist/compile.js.map +1 -1
- package/dist/contract.d.ts +39 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +150 -0
- package/dist/contract.js.map +1 -0
- package/dist/detached-runner.js +17 -0
- package/dist/detached-runner.js.map +1 -1
- package/dist/host/runner-types.d.ts +3 -0
- package/dist/host/runner-types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interpolate.d.ts +5 -0
- package/dist/interpolate.d.ts.map +1 -1
- package/dist/interpolate.js +14 -3
- package/dist/interpolate.js.map +1 -1
- package/dist/peek.d.ts +39 -0
- package/dist/peek.d.ts.map +1 -0
- package/dist/peek.js +119 -0
- package/dist/peek.js.map +1 -0
- package/dist/reflexion.d.ts +46 -0
- package/dist/reflexion.d.ts.map +1 -0
- package/dist/reflexion.js +100 -0
- package/dist/reflexion.js.map +1 -0
- package/dist/runner-core.d.ts.map +1 -1
- package/dist/runner-core.js +3 -0
- package/dist/runner-core.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +589 -23
- package/dist/runtime.js.map +1 -1
- package/dist/schema.d.ts +21 -7
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +177 -4
- package/dist/schema.js.map +1 -1
- package/dist/scorer-runtime.d.ts +30 -0
- package/dist/scorer-runtime.d.ts.map +1 -0
- package/dist/scorer-runtime.js +134 -0
- package/dist/scorer-runtime.js.map +1 -0
- package/dist/scorers.d.ts +120 -0
- package/dist/scorers.d.ts.map +1 -0
- package/dist/scorers.js +313 -0
- package/dist/scorers.js.map +1 -0
- package/dist/store.d.ts +28 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/dist/verify.d.ts +1 -1
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +59 -0
- package/dist/verify.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Impure scorers — the runtime half of the scoring-gate seam.
|
|
3
|
+
*
|
|
4
|
+
* `code-compiles` spawns a real compiler and therefore cannot live in the
|
|
5
|
+
* pure scorers.ts module (mirrors the contract.ts ↔ runtime.ts split). The
|
|
6
|
+
* runtime dispatches here for impure scorer types; everything else goes to
|
|
7
|
+
* `evaluatePureScorer`.
|
|
8
|
+
*
|
|
9
|
+
* Fail semantics: an unavailable compiler, a spawn error, or a timeout is a
|
|
10
|
+
* FAILED scorer (passed:false with a detail) — never a throw. The gate's
|
|
11
|
+
* fail-open path (judge / task fallback) then decides what a failed check
|
|
12
|
+
* means; a missing toolchain must not crash the run.
|
|
13
|
+
*/
|
|
14
|
+
import { spawn } from "node:child_process";
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
import * as os from "node:os";
|
|
17
|
+
import * as path from "node:path";
|
|
18
|
+
import { scorerName } from "./scorers.js";
|
|
19
|
+
/** Wall-clock cap for one compiler invocation. */
|
|
20
|
+
export const CODE_COMPILES_TIMEOUT_MS = 30_000;
|
|
21
|
+
/**
|
|
22
|
+
* Check that the target parses/compiles for the scorer's `language`.
|
|
23
|
+
* - javascript: `node --check <file>` (syntax check; no execution, no deps)
|
|
24
|
+
* - typescript: `npx --no-install tsc --noEmit <file>` (types + syntax;
|
|
25
|
+
* requires a resolvable `tsc` — its absence FAILS the scorer with detail)
|
|
26
|
+
*
|
|
27
|
+
* If the target contains a single fenced code block, its body is compiled
|
|
28
|
+
* (model outputs usually wrap code in fences); otherwise the raw target is.
|
|
29
|
+
*
|
|
30
|
+
* The compiler runs inside an isolated temp dir (not the phase's cwd) so it
|
|
31
|
+
* cannot resolve a repo-planted `node_modules/.bin/tsc` — hence no `cwd` arg.
|
|
32
|
+
*/
|
|
33
|
+
export async function runCodeCompilesScorer(scorer, index, target) {
|
|
34
|
+
const name = scorerName(scorer, index);
|
|
35
|
+
const mk = (passed, detail) => ({
|
|
36
|
+
name,
|
|
37
|
+
type: scorer.type,
|
|
38
|
+
passed,
|
|
39
|
+
score: passed ? 1 : 0,
|
|
40
|
+
detail,
|
|
41
|
+
});
|
|
42
|
+
const lang = scorer.language;
|
|
43
|
+
if (lang !== "javascript" && lang !== "typescript") {
|
|
44
|
+
return mk(false, `unsupported language '${String(lang)}' (expected javascript|typescript)`);
|
|
45
|
+
}
|
|
46
|
+
const code = extractCode(target);
|
|
47
|
+
const ext = lang === "typescript" ? ".ts" : ".mjs";
|
|
48
|
+
// Isolated temp DIR (not a bare temp file): mkdtempSync creates a fresh
|
|
49
|
+
// 0700 directory atomically, closing the predictable-name symlink/TOCTOU race
|
|
50
|
+
// on shared /tmp (issue #18). The compiler is also run WITH THIS DIR AS CWD
|
|
51
|
+
// (not the phase's effCwd) so `npx --no-install tsc` cannot resolve a
|
|
52
|
+
// repo-planted `node_modules/.bin/tsc` from the working directory —
|
|
53
|
+
// defense-in-depth beyond the dynamic-flow scorer block.
|
|
54
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "taskflow-scorer-"));
|
|
55
|
+
const file = path.join(dir, `snippet${ext}`);
|
|
56
|
+
try {
|
|
57
|
+
fs.writeFileSync(file, code, "utf-8");
|
|
58
|
+
const [cmd, args] = lang === "typescript"
|
|
59
|
+
? ["npx", ["--no-install", "tsc", "--noEmit", "--skipLibCheck", file]]
|
|
60
|
+
: [process.execPath, ["--check", file]];
|
|
61
|
+
const r = await runProcess(cmd, args, dir);
|
|
62
|
+
if (r.timedOut)
|
|
63
|
+
return mk(false, `compiler timed out after ${CODE_COMPILES_TIMEOUT_MS}ms`);
|
|
64
|
+
if (r.spawnError)
|
|
65
|
+
return mk(false, `compiler unavailable: ${r.spawnError}`);
|
|
66
|
+
if (r.code === 0)
|
|
67
|
+
return mk(true);
|
|
68
|
+
const diag = (r.stderr || r.stdout).trim().split("\n").slice(0, 5).join("\n");
|
|
69
|
+
return mk(false, diag || `compiler exited ${r.code}`);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
return mk(false, `scorer error: ${e instanceof Error ? e.message : String(e)}`);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
try {
|
|
76
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
/* best-effort cleanup */
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** If the target contains exactly one fenced code block, compile its body;
|
|
84
|
+
* otherwise compile the raw target. Multiple fences → raw target (we cannot
|
|
85
|
+
* guess which block the author meant; a syntax error will say so). */
|
|
86
|
+
function extractCode(target) {
|
|
87
|
+
const fences = [...target.matchAll(/```\w*[ \t]*\r?\n([\s\S]*?)```/g)];
|
|
88
|
+
if (fences.length === 1)
|
|
89
|
+
return fences[0][1];
|
|
90
|
+
return target;
|
|
91
|
+
}
|
|
92
|
+
function runProcess(cmd, args, cwd) {
|
|
93
|
+
return new Promise((resolve) => {
|
|
94
|
+
let stdout = "";
|
|
95
|
+
let stderr = "";
|
|
96
|
+
let timedOut = false;
|
|
97
|
+
let settled = false;
|
|
98
|
+
let timer;
|
|
99
|
+
const finish = (r) => {
|
|
100
|
+
if (settled)
|
|
101
|
+
return;
|
|
102
|
+
settled = true;
|
|
103
|
+
if (timer)
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
resolve({ code: r.code, stdout, stderr, timedOut, spawnError: r.spawnError });
|
|
106
|
+
};
|
|
107
|
+
let child;
|
|
108
|
+
try {
|
|
109
|
+
child = spawn(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
resolve({ code: null, stdout, stderr, timedOut: false, spawnError: e instanceof Error ? e.message : String(e) });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
timer = setTimeout(() => {
|
|
116
|
+
timedOut = true;
|
|
117
|
+
try {
|
|
118
|
+
child.kill("SIGKILL");
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
/* already dead */
|
|
122
|
+
}
|
|
123
|
+
}, CODE_COMPILES_TIMEOUT_MS);
|
|
124
|
+
child.stdout?.on("data", (c) => {
|
|
125
|
+
stdout += c.toString();
|
|
126
|
+
});
|
|
127
|
+
child.stderr?.on("data", (c) => {
|
|
128
|
+
stderr += c.toString();
|
|
129
|
+
});
|
|
130
|
+
child.on("error", (e) => finish({ code: null, spawnError: e.message }));
|
|
131
|
+
child.on("close", (code) => finish({ code }));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=scorer-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorer-runtime.js","sourceRoot":"","sources":["../src/scorer-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoring gates (`score`) — deterministic, composable output scorers.
|
|
3
|
+
*
|
|
4
|
+
* A `gate` phase may declare `score`: a list of zero-token deterministic
|
|
5
|
+
* scorers (exact-match, contains, regex, json-schema, length-range,
|
|
6
|
+
* code-compiles) evaluated against a target string, combined via
|
|
7
|
+
* `all`/`any`/`weighted` against a threshold. When the deterministic
|
|
8
|
+
* combination passes, the gate auto-passes with NO LLM call (mirroring the
|
|
9
|
+
* `eval` fast-path); when it fails, control falls to the optional `llm-judge`
|
|
10
|
+
* (`score.judge`) or the gate's regular `task`.
|
|
11
|
+
*
|
|
12
|
+
* This module is the PURE half (mirrors contract.ts): shape validation,
|
|
13
|
+
* the 5 string scorers, combination, and report formatting. The impure
|
|
14
|
+
* `code-compiles` scorer (spawns a compiler) lives in scorer-runtime.ts and
|
|
15
|
+
* is dispatched by the runtime — never imported here.
|
|
16
|
+
*/
|
|
17
|
+
export declare const SCORER_TYPES: readonly ["exact-match", "contains", "regex", "json-schema", "length-range", "code-compiles"];
|
|
18
|
+
export type ScorerType = (typeof SCORER_TYPES)[number];
|
|
19
|
+
export declare const SCORE_COMBINE_MODES: readonly ["all", "any", "weighted"];
|
|
20
|
+
export type ScoreCombineMode = (typeof SCORE_COMBINE_MODES)[number];
|
|
21
|
+
/** Default weighted-combine threshold (used when `score.threshold` is omitted). */
|
|
22
|
+
export declare const SCORE_DEFAULT_THRESHOLD = 0.5;
|
|
23
|
+
/** Languages the code-compiles scorer can check (see scorer-runtime.ts). */
|
|
24
|
+
export declare const CODE_COMPILES_LANGUAGES: readonly ["javascript", "typescript"];
|
|
25
|
+
export interface Scorer {
|
|
26
|
+
type: ScorerType;
|
|
27
|
+
/** Result label; defaults to `<type>-<index>`. */
|
|
28
|
+
name?: string;
|
|
29
|
+
/** [exact-match|contains] The string to compare/find. */
|
|
30
|
+
value?: string;
|
|
31
|
+
/** [regex] JS RegExp source. An invalid pattern fails the scorer (with detail). */
|
|
32
|
+
pattern?: string;
|
|
33
|
+
/** [regex] Invert the match result. */
|
|
34
|
+
negate?: boolean;
|
|
35
|
+
/** [json-schema] An `expect`-style contract for the parsed target. */
|
|
36
|
+
schema?: unknown;
|
|
37
|
+
/** [length-range] Inclusive bounds on target length (chars). */
|
|
38
|
+
min?: number;
|
|
39
|
+
max?: number;
|
|
40
|
+
/** [code-compiles] Which compiler to run. */
|
|
41
|
+
language?: (typeof CODE_COMPILES_LANGUAGES)[number];
|
|
42
|
+
}
|
|
43
|
+
export interface ScorerResult {
|
|
44
|
+
name: string;
|
|
45
|
+
type: ScorerType;
|
|
46
|
+
passed: boolean;
|
|
47
|
+
/** 0 or 1 for deterministic scorers; the judge's [0,1] score when present. */
|
|
48
|
+
score: number;
|
|
49
|
+
detail?: string;
|
|
50
|
+
}
|
|
51
|
+
/** The `score` field's shape (validated by scorerShapeErrors, not TypeBox —
|
|
52
|
+
* keeps diagnostics precise and the surface documented in one place). */
|
|
53
|
+
export interface ScoreConfig {
|
|
54
|
+
/** Interpolation ref for the scored string. Default: "{previous.output}". */
|
|
55
|
+
target?: string;
|
|
56
|
+
scorers: Scorer[];
|
|
57
|
+
combine?: ScoreCombineMode;
|
|
58
|
+
/** [weighted] Aligned to scorers (+1 trailing judge weight when judge present). */
|
|
59
|
+
weights?: number[];
|
|
60
|
+
/** [weighted] Combined score cutoff in (0, 1]. Default 0.5. */
|
|
61
|
+
threshold?: number;
|
|
62
|
+
/** Optional LLM-as-judge fallback, run only when the deterministics fail. */
|
|
63
|
+
judge?: {
|
|
64
|
+
agent?: string;
|
|
65
|
+
task: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Statically check an author-written `score` value. Returns human-readable
|
|
70
|
+
* shape errors ([] = valid). Total: never throws on arbitrary JSON-valid
|
|
71
|
+
* input. Mirrors contractShapeErrors (the `expect` validator).
|
|
72
|
+
*/
|
|
73
|
+
export declare function scorerShapeErrors(score: unknown, path?: string): string[];
|
|
74
|
+
/** Default result label for a scorer. */
|
|
75
|
+
export declare function scorerName(s: Scorer, index: number): string;
|
|
76
|
+
/**
|
|
77
|
+
* Evaluate one PURE scorer against the target string. Total: never throws —
|
|
78
|
+
* an invalid configuration (e.g. a bad regex) fails the scorer with a detail.
|
|
79
|
+
* `code-compiles` is NOT handled here (impure — see scorer-runtime.ts).
|
|
80
|
+
*/
|
|
81
|
+
export declare function evaluatePureScorer(scorer: Scorer, index: number, target: string): ScorerResult;
|
|
82
|
+
/**
|
|
83
|
+
* Combine deterministic scorer results per the combine mode. `judgeWeight`
|
|
84
|
+
* (weighted mode, judge configured but NOT yet run) enlarges the denominator
|
|
85
|
+
* so the deterministic-only combination is a LOWER BOUND: when it already
|
|
86
|
+
* clears the threshold, the judge's score could not change the outcome and
|
|
87
|
+
* the gate may auto-pass without spending judge tokens.
|
|
88
|
+
*/
|
|
89
|
+
export declare function combineScores(results: ScorerResult[], combine: ScoreCombineMode, weights?: number[], threshold?: number, judgeWeight?: number): {
|
|
90
|
+
combined: number;
|
|
91
|
+
passed: boolean;
|
|
92
|
+
};
|
|
93
|
+
/** Fold a completed judge result into a weighted combination (judge = last weight). */
|
|
94
|
+
export declare function combineWithJudge(results: ScorerResult[], weights: number[] | undefined, threshold: number, judgeScore: number): {
|
|
95
|
+
combined: number;
|
|
96
|
+
passed: boolean;
|
|
97
|
+
};
|
|
98
|
+
/** Human-readable scorer report — appended to the judge/gate prompt so the
|
|
99
|
+
* LLM sees exactly which deterministic checks failed and why. */
|
|
100
|
+
export declare function formatScorerReport(results: ScorerResult[], combined: number, threshold?: number): string;
|
|
101
|
+
/** The structured score result stored as the gate's `ps.json` — reachable
|
|
102
|
+
* downstream via `{steps.<gate>.json.combined}` / `...json.results.0.passed`. */
|
|
103
|
+
export declare function scoreResultJSON(results: ScorerResult[], combined: number, verdict: "pass" | "block", threshold?: number, judge?: {
|
|
104
|
+
score: number;
|
|
105
|
+
reason?: string;
|
|
106
|
+
}): Record<string, unknown>;
|
|
107
|
+
/**
|
|
108
|
+
* Parse an LLM judge's output into a score + verdict. Accepts JSON
|
|
109
|
+
* ({score: 0..1, verdict?, reason?}), bare {verdict}, or a text
|
|
110
|
+
* `SCORE: 0.x` / `VERDICT: PASS|BLOCK` marker. Fail-open per the project
|
|
111
|
+
* invariant: unparseable output PASSES with score 1 (ambiguity must not
|
|
112
|
+
* block the flow — same stance as parseGateVerdict).
|
|
113
|
+
*/
|
|
114
|
+
export declare function parseJudgeOutput(output: string): {
|
|
115
|
+
score: number;
|
|
116
|
+
verdict: "pass" | "block";
|
|
117
|
+
reason?: string;
|
|
118
|
+
parsed: boolean;
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=scorers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorers.d.ts","sourceRoot":"","sources":["../src/scorers.ts"],"names":[],"mappings":"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"}
|
package/dist/scorers.js
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoring gates (`score`) — deterministic, composable output scorers.
|
|
3
|
+
*
|
|
4
|
+
* A `gate` phase may declare `score`: a list of zero-token deterministic
|
|
5
|
+
* scorers (exact-match, contains, regex, json-schema, length-range,
|
|
6
|
+
* code-compiles) evaluated against a target string, combined via
|
|
7
|
+
* `all`/`any`/`weighted` against a threshold. When the deterministic
|
|
8
|
+
* combination passes, the gate auto-passes with NO LLM call (mirroring the
|
|
9
|
+
* `eval` fast-path); when it fails, control falls to the optional `llm-judge`
|
|
10
|
+
* (`score.judge`) or the gate's regular `task`.
|
|
11
|
+
*
|
|
12
|
+
* This module is the PURE half (mirrors contract.ts): shape validation,
|
|
13
|
+
* the 5 string scorers, combination, and report formatting. The impure
|
|
14
|
+
* `code-compiles` scorer (spawns a compiler) lives in scorer-runtime.ts and
|
|
15
|
+
* is dispatched by the runtime — never imported here.
|
|
16
|
+
*/
|
|
17
|
+
import { contractShapeErrors, contractViolations } from "./contract.js";
|
|
18
|
+
import { safeParse } from "./interpolate.js";
|
|
19
|
+
export const SCORER_TYPES = ["exact-match", "contains", "regex", "json-schema", "length-range", "code-compiles"];
|
|
20
|
+
export const SCORE_COMBINE_MODES = ["all", "any", "weighted"];
|
|
21
|
+
/** Default weighted-combine threshold (used when `score.threshold` is omitted). */
|
|
22
|
+
export const SCORE_DEFAULT_THRESHOLD = 0.5;
|
|
23
|
+
/** Languages the code-compiles scorer can check (see scorer-runtime.ts). */
|
|
24
|
+
export const CODE_COMPILES_LANGUAGES = ["javascript", "typescript"];
|
|
25
|
+
/** Fields every scorer may carry, plus the per-type applicable ones. A field
|
|
26
|
+
* set on a scorer whose type ignores it is a shape error — silently dropping
|
|
27
|
+
* `{type:"contains", negate:true}` would let the author believe negation
|
|
28
|
+
* happened. */
|
|
29
|
+
const SCORER_COMMON_KEYS = ["type", "name"];
|
|
30
|
+
const SCORER_TYPE_KEYS = {
|
|
31
|
+
"exact-match": ["value"],
|
|
32
|
+
contains: ["value"],
|
|
33
|
+
regex: ["pattern", "negate"],
|
|
34
|
+
"json-schema": ["schema"],
|
|
35
|
+
"length-range": ["min", "max"],
|
|
36
|
+
"code-compiles": ["language"],
|
|
37
|
+
};
|
|
38
|
+
function isPlainObject(v) {
|
|
39
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Statically check an author-written `score` value. Returns human-readable
|
|
43
|
+
* shape errors ([] = valid). Total: never throws on arbitrary JSON-valid
|
|
44
|
+
* input. Mirrors contractShapeErrors (the `expect` validator).
|
|
45
|
+
*/
|
|
46
|
+
export function scorerShapeErrors(score, path = "score") {
|
|
47
|
+
if (!isPlainObject(score))
|
|
48
|
+
return [`${path}: must be an object ({scorers: [...], combine?, threshold?, judge?})`];
|
|
49
|
+
const errors = [];
|
|
50
|
+
if (score.target !== undefined && typeof score.target !== "string")
|
|
51
|
+
errors.push(`${path}.target: must be a string interpolation ref (e.g. "{steps.gen.output}")`);
|
|
52
|
+
if (!Array.isArray(score.scorers) || score.scorers.length === 0) {
|
|
53
|
+
errors.push(`${path}.scorers: must be a non-empty array of scorers`);
|
|
54
|
+
return errors; // scorer-dependent checks below would be noise
|
|
55
|
+
}
|
|
56
|
+
score.scorers.forEach((s, i) => {
|
|
57
|
+
const p = `${path}.scorers[${i}]`;
|
|
58
|
+
if (!isPlainObject(s)) {
|
|
59
|
+
errors.push(`${p}: must be an object with a 'type'`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const t = s.type;
|
|
63
|
+
if (typeof t !== "string" || !SCORER_TYPES.includes(t)) {
|
|
64
|
+
errors.push(`${p}.type: must be one of ${SCORER_TYPES.join("|")}`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Reject fields the scorer's type ignores (and unknown fields outright).
|
|
68
|
+
const allowed = new Set([...SCORER_COMMON_KEYS, ...SCORER_TYPE_KEYS[t]]);
|
|
69
|
+
for (const k of Object.keys(s)) {
|
|
70
|
+
if (!allowed.has(k))
|
|
71
|
+
errors.push(`${p}.${k}: not applicable to '${t}' scorers (allowed: ${[...allowed].join(", ")})`);
|
|
72
|
+
}
|
|
73
|
+
if (s.name !== undefined && typeof s.name !== "string")
|
|
74
|
+
errors.push(`${p}.name: must be a string`);
|
|
75
|
+
if ((t === "exact-match" || t === "contains") && typeof s.value !== "string")
|
|
76
|
+
errors.push(`${p}.value: required string for '${t}'`);
|
|
77
|
+
if (t === "regex") {
|
|
78
|
+
if (typeof s.pattern !== "string")
|
|
79
|
+
errors.push(`${p}.pattern: required string for 'regex'`);
|
|
80
|
+
if (s.negate !== undefined && typeof s.negate !== "boolean")
|
|
81
|
+
errors.push(`${p}.negate: must be a boolean`);
|
|
82
|
+
}
|
|
83
|
+
if (t === "json-schema") {
|
|
84
|
+
if (s.schema === undefined)
|
|
85
|
+
errors.push(`${p}.schema: required for 'json-schema'`);
|
|
86
|
+
else
|
|
87
|
+
errors.push(...contractShapeErrors(s.schema, `${p}.schema`));
|
|
88
|
+
}
|
|
89
|
+
if (t === "length-range") {
|
|
90
|
+
if (s.min === undefined && s.max === undefined)
|
|
91
|
+
errors.push(`${p}: 'length-range' requires 'min' and/or 'max'`);
|
|
92
|
+
if (s.min !== undefined && (typeof s.min !== "number" || s.min < 0))
|
|
93
|
+
errors.push(`${p}.min: must be a number >= 0`);
|
|
94
|
+
if (s.max !== undefined && (typeof s.max !== "number" || s.max < 0))
|
|
95
|
+
errors.push(`${p}.max: must be a number >= 0`);
|
|
96
|
+
if (typeof s.min === "number" && typeof s.max === "number" && s.min > s.max)
|
|
97
|
+
errors.push(`${p}: min (${s.min}) must be <= max (${s.max})`);
|
|
98
|
+
}
|
|
99
|
+
if (t === "code-compiles") {
|
|
100
|
+
if (typeof s.language !== "string" || !CODE_COMPILES_LANGUAGES.includes(s.language))
|
|
101
|
+
errors.push(`${p}.language: must be one of ${CODE_COMPILES_LANGUAGES.join("|")}`);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const combine = score.combine ?? "all";
|
|
105
|
+
if (typeof combine !== "string" || !SCORE_COMBINE_MODES.includes(combine)) {
|
|
106
|
+
errors.push(`${path}.combine: must be one of ${SCORE_COMBINE_MODES.join("|")}`);
|
|
107
|
+
}
|
|
108
|
+
else if (combine === "weighted") {
|
|
109
|
+
const judgeCount = isPlainObject(score.judge) ? 1 : 0;
|
|
110
|
+
const expected = score.scorers.length + judgeCount;
|
|
111
|
+
if (!Array.isArray(score.weights)) {
|
|
112
|
+
errors.push(`${path}.weights: required array for combine:"weighted" (${expected} entries${judgeCount ? " — last one is the judge's weight" : ""})`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
if (score.weights.length !== expected)
|
|
116
|
+
errors.push(`${path}.weights: expected ${expected} entries (scorers${judgeCount ? " + judge" : ""}), got ${score.weights.length}`);
|
|
117
|
+
score.weights.forEach((w, i) => {
|
|
118
|
+
if (typeof w !== "number" || !Number.isFinite(w) || w <= 0)
|
|
119
|
+
errors.push(`${path}.weights[${i}]: must be a number > 0`);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (score.threshold !== undefined && (typeof score.threshold !== "number" || !(score.threshold > 0) || score.threshold > 1))
|
|
123
|
+
errors.push(`${path}.threshold: must be a number in (0, 1]`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
if (score.weights !== undefined)
|
|
127
|
+
errors.push(`${path}.weights: only valid with combine:"weighted"`);
|
|
128
|
+
if (score.threshold !== undefined)
|
|
129
|
+
errors.push(`${path}.threshold: only valid with combine:"weighted"`);
|
|
130
|
+
}
|
|
131
|
+
if (score.judge !== undefined) {
|
|
132
|
+
if (!isPlainObject(score.judge))
|
|
133
|
+
errors.push(`${path}.judge: must be an object ({agent?, task})`);
|
|
134
|
+
else {
|
|
135
|
+
if (typeof score.judge.task !== "string" || !score.judge.task.trim())
|
|
136
|
+
errors.push(`${path}.judge.task: required non-empty string`);
|
|
137
|
+
if (score.judge.agent !== undefined && typeof score.judge.agent !== "string")
|
|
138
|
+
errors.push(`${path}.judge.agent: must be a string agent name`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const k of Object.keys(score)) {
|
|
142
|
+
if (!["target", "scorers", "combine", "weights", "threshold", "judge"].includes(k))
|
|
143
|
+
errors.push(`${path}.${k}: unknown score keyword (supported: target, scorers, combine, weights, threshold, judge)`);
|
|
144
|
+
}
|
|
145
|
+
return errors;
|
|
146
|
+
}
|
|
147
|
+
/** Default result label for a scorer. */
|
|
148
|
+
export function scorerName(s, index) {
|
|
149
|
+
return typeof s.name === "string" && s.name.trim() ? s.name.trim() : `${s.type}-${index}`;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Evaluate one PURE scorer against the target string. Total: never throws —
|
|
153
|
+
* an invalid configuration (e.g. a bad regex) fails the scorer with a detail.
|
|
154
|
+
* `code-compiles` is NOT handled here (impure — see scorer-runtime.ts).
|
|
155
|
+
*/
|
|
156
|
+
export function evaluatePureScorer(scorer, index, target) {
|
|
157
|
+
const name = scorerName(scorer, index);
|
|
158
|
+
const mk = (passed, detail) => ({
|
|
159
|
+
name,
|
|
160
|
+
type: scorer.type,
|
|
161
|
+
passed,
|
|
162
|
+
score: passed ? 1 : 0,
|
|
163
|
+
detail,
|
|
164
|
+
});
|
|
165
|
+
switch (scorer.type) {
|
|
166
|
+
case "exact-match": {
|
|
167
|
+
const passed = target === (scorer.value ?? "");
|
|
168
|
+
return mk(passed, passed ? undefined : `target (${target.length} chars) !== value (${(scorer.value ?? "").length} chars)`);
|
|
169
|
+
}
|
|
170
|
+
case "contains": {
|
|
171
|
+
const passed = target.includes(scorer.value ?? "");
|
|
172
|
+
return mk(passed, passed ? undefined : `target does not contain ${JSON.stringify(truncate(scorer.value ?? "", 80))}`);
|
|
173
|
+
}
|
|
174
|
+
case "regex": {
|
|
175
|
+
let re;
|
|
176
|
+
try {
|
|
177
|
+
re = new RegExp(scorer.pattern ?? "");
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
return mk(false, `invalid pattern: ${e instanceof Error ? e.message : String(e)}`);
|
|
181
|
+
}
|
|
182
|
+
const matched = re.test(target);
|
|
183
|
+
const passed = scorer.negate === true ? !matched : matched;
|
|
184
|
+
return mk(passed, passed ? undefined : `/${scorer.pattern}/ ${scorer.negate ? "matched (negated)" : "did not match"}`);
|
|
185
|
+
}
|
|
186
|
+
case "json-schema": {
|
|
187
|
+
// Same lenient parse as the `expect` contract path (fence-extraction
|
|
188
|
+
// included) so a json-schema scorer and an expect contract agree on
|
|
189
|
+
// what "the JSON output" is.
|
|
190
|
+
const parsed = safeParse(target);
|
|
191
|
+
if (parsed === undefined)
|
|
192
|
+
return mk(false, "target is not valid JSON");
|
|
193
|
+
const violations = contractViolations(parsed, scorer.schema);
|
|
194
|
+
return mk(violations.length === 0, violations.length ? violations.join("; ") : undefined);
|
|
195
|
+
}
|
|
196
|
+
case "length-range": {
|
|
197
|
+
const len = target.length;
|
|
198
|
+
const min = typeof scorer.min === "number" ? scorer.min : 0;
|
|
199
|
+
const max = typeof scorer.max === "number" ? scorer.max : Infinity;
|
|
200
|
+
const passed = len >= min && len <= max;
|
|
201
|
+
return mk(passed, passed ? undefined : `length ${len} outside [${min}, ${max === Infinity ? "∞" : max}]`);
|
|
202
|
+
}
|
|
203
|
+
case "code-compiles":
|
|
204
|
+
// Dispatched by the runtime to scorer-runtime.ts; reaching here means
|
|
205
|
+
// the dispatch was missed — fail visibly rather than fake a pass.
|
|
206
|
+
return mk(false, "code-compiles must be evaluated by the runtime (impure scorer)");
|
|
207
|
+
default:
|
|
208
|
+
return mk(false, `unknown scorer type '${scorer.type}'`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Combine deterministic scorer results per the combine mode. `judgeWeight`
|
|
213
|
+
* (weighted mode, judge configured but NOT yet run) enlarges the denominator
|
|
214
|
+
* so the deterministic-only combination is a LOWER BOUND: when it already
|
|
215
|
+
* clears the threshold, the judge's score could not change the outcome and
|
|
216
|
+
* the gate may auto-pass without spending judge tokens.
|
|
217
|
+
*/
|
|
218
|
+
export function combineScores(results, combine, weights, threshold = SCORE_DEFAULT_THRESHOLD, judgeWeight = 0) {
|
|
219
|
+
if (results.length === 0)
|
|
220
|
+
return { combined: 0, passed: false };
|
|
221
|
+
if (combine === "any") {
|
|
222
|
+
const passed = results.some((r) => r.passed);
|
|
223
|
+
return { combined: passed ? 1 : 0, passed };
|
|
224
|
+
}
|
|
225
|
+
if (combine === "weighted") {
|
|
226
|
+
const w = Array.isArray(weights) && weights.length >= results.length ? weights : results.map(() => 1);
|
|
227
|
+
let sum = 0;
|
|
228
|
+
let total = judgeWeight;
|
|
229
|
+
for (let i = 0; i < results.length; i++) {
|
|
230
|
+
const wi = typeof w[i] === "number" && w[i] > 0 ? w[i] : 1;
|
|
231
|
+
sum += results[i].score * wi;
|
|
232
|
+
total += wi;
|
|
233
|
+
}
|
|
234
|
+
const combined = total > 0 ? sum / total : 0;
|
|
235
|
+
return { combined, passed: combined >= threshold };
|
|
236
|
+
}
|
|
237
|
+
// "all" (default)
|
|
238
|
+
const passed = results.every((r) => r.passed);
|
|
239
|
+
return { combined: passed ? 1 : 0, passed };
|
|
240
|
+
}
|
|
241
|
+
/** Fold a completed judge result into a weighted combination (judge = last weight). */
|
|
242
|
+
export function combineWithJudge(results, weights, threshold, judgeScore) {
|
|
243
|
+
const w = Array.isArray(weights) && weights.length === results.length + 1 ? weights : [...results.map(() => 1), 1];
|
|
244
|
+
let sum = 0;
|
|
245
|
+
let total = 0;
|
|
246
|
+
for (let i = 0; i < results.length; i++) {
|
|
247
|
+
sum += results[i].score * w[i];
|
|
248
|
+
total += w[i];
|
|
249
|
+
}
|
|
250
|
+
const jw = w[results.length];
|
|
251
|
+
sum += Math.max(0, Math.min(1, judgeScore)) * jw;
|
|
252
|
+
total += jw;
|
|
253
|
+
const combined = total > 0 ? sum / total : 0;
|
|
254
|
+
return { combined, passed: combined >= threshold };
|
|
255
|
+
}
|
|
256
|
+
/** Human-readable scorer report — appended to the judge/gate prompt so the
|
|
257
|
+
* LLM sees exactly which deterministic checks failed and why. */
|
|
258
|
+
export function formatScorerReport(results, combined, threshold) {
|
|
259
|
+
const lines = results.map((r) => `- [${r.passed ? "PASS" : "FAIL"}] ${r.name} (${r.type})${r.detail ? `: ${r.detail}` : ""}`);
|
|
260
|
+
const summary = threshold !== undefined
|
|
261
|
+
? `Combined score: ${combined.toFixed(3)} (threshold ${threshold})`
|
|
262
|
+
: `Combined score: ${combined.toFixed(3)}`;
|
|
263
|
+
return `## Deterministic scorer report\n${lines.join("\n")}\n${summary}`;
|
|
264
|
+
}
|
|
265
|
+
/** The structured score result stored as the gate's `ps.json` — reachable
|
|
266
|
+
* downstream via `{steps.<gate>.json.combined}` / `...json.results.0.passed`. */
|
|
267
|
+
export function scoreResultJSON(results, combined, verdict, threshold, judge) {
|
|
268
|
+
const out = { verdict, combined, results };
|
|
269
|
+
if (threshold !== undefined)
|
|
270
|
+
out.threshold = threshold;
|
|
271
|
+
if (judge)
|
|
272
|
+
out.judge = judge;
|
|
273
|
+
return out;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Parse an LLM judge's output into a score + verdict. Accepts JSON
|
|
277
|
+
* ({score: 0..1, verdict?, reason?}), bare {verdict}, or a text
|
|
278
|
+
* `SCORE: 0.x` / `VERDICT: PASS|BLOCK` marker. Fail-open per the project
|
|
279
|
+
* invariant: unparseable output PASSES with score 1 (ambiguity must not
|
|
280
|
+
* block the flow — same stance as parseGateVerdict).
|
|
281
|
+
*/
|
|
282
|
+
export function parseJudgeOutput(output) {
|
|
283
|
+
const clamp = (n) => Math.max(0, Math.min(1, n));
|
|
284
|
+
const json = safeParse(output);
|
|
285
|
+
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
286
|
+
const o = json;
|
|
287
|
+
const reason = typeof o.reason === "string" && o.reason.trim() ? o.reason.trim() : undefined;
|
|
288
|
+
const rawScore = typeof o.score === "number" ? o.score : typeof o.score === "string" ? Number(o.score) : NaN;
|
|
289
|
+
const hasScore = Number.isFinite(rawScore);
|
|
290
|
+
if (typeof o.verdict === "string") {
|
|
291
|
+
const block = /block|fail|stop|reject|halt/i.test(o.verdict);
|
|
292
|
+
return { score: hasScore ? clamp(rawScore) : block ? 0 : 1, verdict: block ? "block" : "pass", reason, parsed: true };
|
|
293
|
+
}
|
|
294
|
+
if (hasScore) {
|
|
295
|
+
const s = clamp(rawScore);
|
|
296
|
+
return { score: s, verdict: s >= 0.5 ? "pass" : "block", reason, parsed: true };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const scoreMatches = [...output.matchAll(/SCORE\s*[:=]\s*([01](?:\.\d+)?)/gi)];
|
|
300
|
+
const verdictMatches = [...output.matchAll(/VERDICT\s*[:=]\s*(PASS|BLOCK|FAIL|STOP|OK|REJECT|HALT)/gi)];
|
|
301
|
+
if (scoreMatches.length || verdictMatches.length) {
|
|
302
|
+
const s = scoreMatches.length ? clamp(Number(scoreMatches[scoreMatches.length - 1][1])) : undefined;
|
|
303
|
+
const v = verdictMatches.length ? verdictMatches[verdictMatches.length - 1][1].toUpperCase() : undefined;
|
|
304
|
+
const blocked = v !== undefined ? !(v === "PASS" || v === "OK") : (s ?? 1) < 0.5;
|
|
305
|
+
return { score: s ?? (blocked ? 0 : 1), verdict: blocked ? "block" : "pass", parsed: true };
|
|
306
|
+
}
|
|
307
|
+
// Fail-open: ambiguous judge output must not block the flow.
|
|
308
|
+
return { score: 1, verdict: "pass", reason: "unparseable judge output (fail-open pass)", parsed: false };
|
|
309
|
+
}
|
|
310
|
+
function truncate(s, n) {
|
|
311
|
+
return s.length <= n ? s : `${s.slice(0, n)}…`;
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=scorers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorers.js","sourceRoot":"","sources":["../src/scorers.ts"],"names":[],"mappings":"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"}
|