@aid-framework/runtime 0.0.0 → 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 +53 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/agents/deep_agents.d.ts +78 -0
- package/dist/agents/deep_agents.d.ts.map +1 -0
- package/dist/agents/deep_agents.js +477 -0
- package/dist/agents/deep_agents.js.map +1 -0
- package/dist/agents/engine.d.ts +85 -0
- package/dist/agents/engine.d.ts.map +1 -0
- package/dist/agents/engine.js +129 -0
- package/dist/agents/engine.js.map +1 -0
- package/dist/agents/gateway_chat_model.d.ts +151 -0
- package/dist/agents/gateway_chat_model.d.ts.map +1 -0
- package/dist/agents/gateway_chat_model.js +350 -0
- package/dist/agents/gateway_chat_model.js.map +1 -0
- package/dist/agents/guardrail_middleware.d.ts +57 -0
- package/dist/agents/guardrail_middleware.d.ts.map +1 -0
- package/dist/agents/guardrail_middleware.js +85 -0
- package/dist/agents/guardrail_middleware.js.map +1 -0
- package/dist/agents/guardrails.d.ts +124 -0
- package/dist/agents/guardrails.d.ts.map +1 -0
- package/dist/agents/guardrails.js +336 -0
- package/dist/agents/guardrails.js.map +1 -0
- package/dist/agents/index.d.ts +15 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +15 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/ir.d.ts +144 -0
- package/dist/agents/ir.d.ts.map +1 -0
- package/dist/agents/ir.js +513 -0
- package/dist/agents/ir.js.map +1 -0
- package/dist/agents/loop.d.ts +145 -0
- package/dist/agents/loop.d.ts.map +1 -0
- package/dist/agents/loop.js +1025 -0
- package/dist/agents/loop.js.map +1 -0
- package/dist/agents/memory.d.ts +115 -0
- package/dist/agents/memory.d.ts.map +1 -0
- package/dist/agents/memory.js +258 -0
- package/dist/agents/memory.js.map +1 -0
- package/dist/agents/state.d.ts +137 -0
- package/dist/agents/state.d.ts.map +1 -0
- package/dist/agents/state.js +255 -0
- package/dist/agents/state.js.map +1 -0
- package/dist/concurrency.d.ts +36 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +86 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/control.d.ts +116 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +281 -0
- package/dist/control.js.map +1 -0
- package/dist/cost.d.ts +95 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +161 -0
- package/dist/cost.js.map +1 -0
- package/dist/errors.d.ts +213 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +316 -0
- package/dist/errors.js.map +1 -0
- package/dist/evals/dataset.d.ts +45 -0
- package/dist/evals/dataset.d.ts.map +1 -0
- package/dist/evals/dataset.js +147 -0
- package/dist/evals/dataset.js.map +1 -0
- package/dist/evals/gate.d.ts +236 -0
- package/dist/evals/gate.d.ts.map +1 -0
- package/dist/evals/gate.js +572 -0
- package/dist/evals/gate.js.map +1 -0
- package/dist/evals/metrics.d.ts +141 -0
- package/dist/evals/metrics.d.ts.map +1 -0
- package/dist/evals/metrics.js +364 -0
- package/dist/evals/metrics.js.map +1 -0
- package/dist/evals/predicate.d.ts +79 -0
- package/dist/evals/predicate.d.ts.map +1 -0
- package/dist/evals/predicate.js +178 -0
- package/dist/evals/predicate.js.map +1 -0
- package/dist/evals/runner.d.ts +94 -0
- package/dist/evals/runner.d.ts.map +1 -0
- package/dist/evals/runner.js +202 -0
- package/dist/evals/runner.js.map +1 -0
- package/dist/gateway.d.ts +118 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +250 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/json.d.ts +44 -0
- package/dist/internal/json.d.ts.map +1 -0
- package/dist/internal/json.js +90 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/text.d.ts +17 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +22 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/pipeline.d.ts +80 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +159 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/policy.d.ts +52 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +199 -0
- package/dist/policy.js.map +1 -0
- package/dist/prompts.d.ts +86 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +337 -0
- package/dist/prompts.js.map +1 -0
- package/dist/providers/base.d.ts +19 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +13 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/fake.d.ts +98 -0
- package/dist/providers/fake.d.ts.map +1 -0
- package/dist/providers/fake.js +181 -0
- package/dist/providers/fake.js.map +1 -0
- package/dist/providers/http.d.ts +62 -0
- package/dist/providers/http.d.ts.map +1 -0
- package/dist/providers/http.js +245 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/retrieval/chunking.d.ts +88 -0
- package/dist/retrieval/chunking.d.ts.map +1 -0
- package/dist/retrieval/chunking.js +188 -0
- package/dist/retrieval/chunking.js.map +1 -0
- package/dist/retrieval/citations.d.ts +98 -0
- package/dist/retrieval/citations.d.ts.map +1 -0
- package/dist/retrieval/citations.js +134 -0
- package/dist/retrieval/citations.js.map +1 -0
- package/dist/retrieval/connectors.d.ts +74 -0
- package/dist/retrieval/connectors.d.ts.map +1 -0
- package/dist/retrieval/connectors.js +218 -0
- package/dist/retrieval/connectors.js.map +1 -0
- package/dist/retrieval/embedding.d.ts +116 -0
- package/dist/retrieval/embedding.d.ts.map +1 -0
- package/dist/retrieval/embedding.js +282 -0
- package/dist/retrieval/embedding.js.map +1 -0
- package/dist/retrieval/gate.d.ts +52 -0
- package/dist/retrieval/gate.d.ts.map +1 -0
- package/dist/retrieval/gate.js +91 -0
- package/dist/retrieval/gate.js.map +1 -0
- package/dist/retrieval/hybrid.d.ts +76 -0
- package/dist/retrieval/hybrid.d.ts.map +1 -0
- package/dist/retrieval/hybrid.js +150 -0
- package/dist/retrieval/hybrid.js.map +1 -0
- package/dist/retrieval/metrics.d.ts +126 -0
- package/dist/retrieval/metrics.d.ts.map +1 -0
- package/dist/retrieval/metrics.js +200 -0
- package/dist/retrieval/metrics.js.map +1 -0
- package/dist/retrieval/pgvector.d.ts +62 -0
- package/dist/retrieval/pgvector.d.ts.map +1 -0
- package/dist/retrieval/pgvector.js +262 -0
- package/dist/retrieval/pgvector.js.map +1 -0
- package/dist/retrieval/rerank.d.ts +61 -0
- package/dist/retrieval/rerank.d.ts.map +1 -0
- package/dist/retrieval/rerank.js +105 -0
- package/dist/retrieval/rerank.js.map +1 -0
- package/dist/retrieval/retriever.d.ts +125 -0
- package/dist/retrieval/retriever.d.ts.map +1 -0
- package/dist/retrieval/retriever.js +281 -0
- package/dist/retrieval/retriever.js.map +1 -0
- package/dist/retrieval/stores.d.ts +106 -0
- package/dist/retrieval/stores.d.ts.map +1 -0
- package/dist/retrieval/stores.js +142 -0
- package/dist/retrieval/stores.js.map +1 -0
- package/dist/retrieval/types.d.ts +314 -0
- package/dist/retrieval/types.d.ts.map +1 -0
- package/dist/retrieval/types.js +388 -0
- package/dist/retrieval/types.js.map +1 -0
- package/dist/steps.d.ts +156 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/steps.js +199 -0
- package/dist/steps.js.map +1 -0
- package/dist/structured.d.ts +91 -0
- package/dist/structured.d.ts.map +1 -0
- package/dist/structured.js +155 -0
- package/dist/structured.js.map +1 -0
- package/dist/tools.d.ts +100 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +201 -0
- package/dist/tools.js.map +1 -0
- package/dist/tracing.d.ts +104 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +155 -0
- package/dist/tracing.js.map +1 -0
- package/dist/types.d.ts +240 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +357 -0
- package/dist/types.js.map +1 -0
- package/package.json +80 -14
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eval metrics.
|
|
3
|
+
*
|
|
4
|
+
* A metric turns `(case, prediction)` into a score in `[0, 1]`. Each metric declares
|
|
5
|
+
* whether it is *deterministic*, and the gate uses that flag to refuse to be built on
|
|
6
|
+
* a metric that calls a model. This is the enforcement point for a Phase 0 decision:
|
|
7
|
+
* implement `llm-judge`, never make CI depend on it.
|
|
8
|
+
*/
|
|
9
|
+
import type { EvalCase } from './dataset.js';
|
|
10
|
+
import { type PredicateNode } from './predicate.js';
|
|
11
|
+
/** One metric's verdict on one prediction. */
|
|
12
|
+
export declare class MetricResult {
|
|
13
|
+
readonly metric: string;
|
|
14
|
+
readonly score: number;
|
|
15
|
+
readonly passed: boolean;
|
|
16
|
+
readonly detail: string;
|
|
17
|
+
constructor(init: {
|
|
18
|
+
readonly metric: string;
|
|
19
|
+
readonly score: number;
|
|
20
|
+
readonly passed: boolean;
|
|
21
|
+
readonly detail?: string;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** Scores a single prediction. */
|
|
25
|
+
export interface Metric {
|
|
26
|
+
/** Stable identifier used in baselines and thresholds. */
|
|
27
|
+
readonly name: string;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the same prediction always yields the same score.
|
|
30
|
+
*
|
|
31
|
+
* A model-backed metric is not deterministic, and the gate refuses to threshold on
|
|
32
|
+
* one: a CI signal that itself varies run to run cannot distinguish a regression
|
|
33
|
+
* from its own noise.
|
|
34
|
+
*/
|
|
35
|
+
readonly deterministic: boolean;
|
|
36
|
+
score(entry: EvalCase, prediction: string): Promise<MetricResult>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Casefold and collapse whitespace, then strip surrounding punctuation.
|
|
40
|
+
*
|
|
41
|
+
* None of this is written with a regex, and that is deliberate: a prediction is
|
|
42
|
+
* model output and therefore arbitrary-length input, while every spelling with a
|
|
43
|
+
* quantifier (`/\s+/g`, `/^[ .!?'"]+/`, `/[ .!?'"]+$/`) costs steps proportional to
|
|
44
|
+
* the run it consumes. A forward pass and a scan from each end are linear whatever
|
|
45
|
+
* arrives, and they produce exactly the strings the collapsed regexes did.
|
|
46
|
+
*/
|
|
47
|
+
export declare function normalize(text: string): string;
|
|
48
|
+
/** Normalized string equality against `case.expected`. */
|
|
49
|
+
export declare class ExactMatch implements Metric {
|
|
50
|
+
private readonly _name;
|
|
51
|
+
constructor(options?: {
|
|
52
|
+
readonly name?: string;
|
|
53
|
+
});
|
|
54
|
+
get name(): string;
|
|
55
|
+
get deterministic(): boolean;
|
|
56
|
+
score(entry: EvalCase, prediction: string): Promise<MetricResult>;
|
|
57
|
+
}
|
|
58
|
+
/** Whether the normalized prediction contains the normalized expectation. */
|
|
59
|
+
export declare class NormalizedContains implements Metric {
|
|
60
|
+
private readonly _name;
|
|
61
|
+
constructor(options?: {
|
|
62
|
+
readonly name?: string;
|
|
63
|
+
});
|
|
64
|
+
get name(): string;
|
|
65
|
+
get deterministic(): boolean;
|
|
66
|
+
score(entry: EvalCase, prediction: string): Promise<MetricResult>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether the prediction parses as JSON and satisfies the case's schema.
|
|
70
|
+
*
|
|
71
|
+
* The schema lives in the case's metadata under `json_schema` as a JSON string, which
|
|
72
|
+
* keeps datasets in a single file format.
|
|
73
|
+
*/
|
|
74
|
+
export declare class JsonSchemaValid implements Metric {
|
|
75
|
+
private readonly _name;
|
|
76
|
+
constructor(options?: {
|
|
77
|
+
readonly name?: string;
|
|
78
|
+
});
|
|
79
|
+
get name(): string;
|
|
80
|
+
get deterministic(): boolean;
|
|
81
|
+
score(entry: EvalCase, prediction: string): Promise<MetricResult>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Whether a declared predicate holds for the case and its prediction.
|
|
85
|
+
*
|
|
86
|
+
* The condition arrives as the IR's predicate AST -- the very tree the spec layer
|
|
87
|
+
* parsed and checked -- so this metric needs no parser and cannot disagree with the
|
|
88
|
+
* one that accepted the spec. A prediction that makes the predicate false scores 0.0
|
|
89
|
+
* and reports the spec's own `message` verbatim, because the point of letting the
|
|
90
|
+
* author write the message is that a failure quotes them.
|
|
91
|
+
*
|
|
92
|
+
* A predicate that cannot be decided throws instead of scoring. See `predicate.ts`
|
|
93
|
+
* for why that distinction is load-bearing.
|
|
94
|
+
*/
|
|
95
|
+
export declare class AssertMetric implements Metric {
|
|
96
|
+
readonly name: string;
|
|
97
|
+
readonly deterministic = true;
|
|
98
|
+
readonly expr: PredicateNode;
|
|
99
|
+
readonly message: string;
|
|
100
|
+
constructor(init: {
|
|
101
|
+
readonly expr: PredicateNode;
|
|
102
|
+
readonly message: string;
|
|
103
|
+
readonly name?: string;
|
|
104
|
+
});
|
|
105
|
+
score(entry: EvalCase, prediction: string): Promise<MetricResult>;
|
|
106
|
+
}
|
|
107
|
+
/** The structured output an LLM judge must return. */
|
|
108
|
+
export declare const JudgeVerdict: import("../structured.js").StructuredOutput<{
|
|
109
|
+
score: number;
|
|
110
|
+
reason: string;
|
|
111
|
+
}>;
|
|
112
|
+
/** A judge call: one prompt in, one model answer out. */
|
|
113
|
+
export type JudgeCall = (prompt: string) => Promise<string>;
|
|
114
|
+
/**
|
|
115
|
+
* Scores a prediction with a model, as a *metric only*.
|
|
116
|
+
*
|
|
117
|
+
* `deterministic` is `false` and must stay that way. Using this metric for a CI
|
|
118
|
+
* threshold would make the gate's own verdict probabilistic; the gate raises rather
|
|
119
|
+
* than allow it. It is implemented because a judge is the right way to explore quality
|
|
120
|
+
* locally and to produce a second opinion next to a deterministic gate -- not because
|
|
121
|
+
* it can be trusted as the gate.
|
|
122
|
+
*/
|
|
123
|
+
export declare class LlmJudge implements Metric {
|
|
124
|
+
private readonly _call;
|
|
125
|
+
private readonly _rubric;
|
|
126
|
+
private readonly _name;
|
|
127
|
+
private readonly _retries;
|
|
128
|
+
constructor(call: JudgeCall, options: {
|
|
129
|
+
readonly rubric: string;
|
|
130
|
+
readonly name?: string;
|
|
131
|
+
readonly retries?: number;
|
|
132
|
+
});
|
|
133
|
+
get name(): string;
|
|
134
|
+
get deterministic(): boolean;
|
|
135
|
+
score(entry: EvalCase, prediction: string): Promise<MetricResult>;
|
|
136
|
+
private buildPrompt;
|
|
137
|
+
}
|
|
138
|
+
/** The deterministic gate metrics: everything that needs no model call. */
|
|
139
|
+
export declare function defaultMetrics(): Metric[];
|
|
140
|
+
export declare function metricNames(metrics: readonly Metric[]): string[];
|
|
141
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/evals/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eval metrics.
|
|
3
|
+
*
|
|
4
|
+
* A metric turns `(case, prediction)` into a score in `[0, 1]`. Each metric declares
|
|
5
|
+
* whether it is *deterministic*, and the gate uses that flag to refuse to be built on
|
|
6
|
+
* a metric that calls a model. This is the enforcement point for a Phase 0 decision:
|
|
7
|
+
* implement `llm-judge`, never make CI depend on it.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
// biome-ignore lint/suspicious/noShadowRestrictedNames: the framework's own error name, matching the Python runtime's public surface
|
|
11
|
+
import { EvalError } from '../errors.js';
|
|
12
|
+
import { repr } from '../internal/json.js';
|
|
13
|
+
import { runStructured, structuredOutput } from '../structured.js';
|
|
14
|
+
import { evaluatePredicate } from './predicate.js';
|
|
15
|
+
/** One metric's verdict on one prediction. */
|
|
16
|
+
export class MetricResult {
|
|
17
|
+
metric;
|
|
18
|
+
score;
|
|
19
|
+
passed;
|
|
20
|
+
detail;
|
|
21
|
+
constructor(init) {
|
|
22
|
+
if (!(init.score >= 0.0 && init.score <= 1.0)) {
|
|
23
|
+
throw new RangeError('score must be between 0 and 1');
|
|
24
|
+
}
|
|
25
|
+
this.metric = init.metric;
|
|
26
|
+
this.score = init.score;
|
|
27
|
+
this.passed = init.passed;
|
|
28
|
+
this.detail = init.detail ?? '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Casefold and collapse whitespace, then strip surrounding punctuation.
|
|
33
|
+
*
|
|
34
|
+
* None of this is written with a regex, and that is deliberate: a prediction is
|
|
35
|
+
* model output and therefore arbitrary-length input, while every spelling with a
|
|
36
|
+
* quantifier (`/\s+/g`, `/^[ .!?'"]+/`, `/[ .!?'"]+$/`) costs steps proportional to
|
|
37
|
+
* the run it consumes. A forward pass and a scan from each end are linear whatever
|
|
38
|
+
* arrives, and they produce exactly the strings the collapsed regexes did.
|
|
39
|
+
*/
|
|
40
|
+
export function normalize(text) {
|
|
41
|
+
// Upper-then-lower approximates Python's `str.casefold()`, which folds further than
|
|
42
|
+
// `toLowerCase()` alone: 'ß' folds to 'ss', 'ſ' to 's', 'Σ' to 'σ'.
|
|
43
|
+
const folded = collapseWhitespace(text.trim()).toUpperCase().toLowerCase();
|
|
44
|
+
let start = 0;
|
|
45
|
+
let end = folded.length;
|
|
46
|
+
while (start < end && PUNCTUATION.has(folded[start]))
|
|
47
|
+
start += 1;
|
|
48
|
+
while (end > start && PUNCTUATION.has(folded[end - 1]))
|
|
49
|
+
end -= 1;
|
|
50
|
+
return folded.slice(start, end);
|
|
51
|
+
}
|
|
52
|
+
/** The characters stripped from either end after folding. */
|
|
53
|
+
const PUNCTUATION = new Set([' ', '.', '!', '?', "'", '"']);
|
|
54
|
+
/**
|
|
55
|
+
* The code points JavaScript's `\s` matches, as inclusive ranges.
|
|
56
|
+
*
|
|
57
|
+
* Spelled out rather than delegated to a regex so that {@link collapseWhitespace} is
|
|
58
|
+
* a single pass: the set is fixed, so a table lookup is all a collapse needs.
|
|
59
|
+
*/
|
|
60
|
+
const WHITESPACE_RANGES = [
|
|
61
|
+
[0x09, 0x0d],
|
|
62
|
+
[0x20, 0x20],
|
|
63
|
+
[0xa0, 0xa0],
|
|
64
|
+
[0x1680, 0x1680],
|
|
65
|
+
[0x2000, 0x200a],
|
|
66
|
+
[0x2028, 0x2029],
|
|
67
|
+
[0x202f, 0x202f],
|
|
68
|
+
[0x205f, 0x205f],
|
|
69
|
+
[0x3000, 0x3000],
|
|
70
|
+
[0xfeff, 0xfeff],
|
|
71
|
+
];
|
|
72
|
+
function isWhitespace(codePoint) {
|
|
73
|
+
for (const [low, high] of WHITESPACE_RANGES) {
|
|
74
|
+
if (codePoint >= low && codePoint <= high)
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
/** Collapse every internal run of whitespace to one space, in a single pass. */
|
|
80
|
+
function collapseWhitespace(text) {
|
|
81
|
+
let out = '';
|
|
82
|
+
let pending = false;
|
|
83
|
+
for (const char of text) {
|
|
84
|
+
if (isWhitespace(char.codePointAt(0))) {
|
|
85
|
+
pending = true;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (pending && out.length > 0)
|
|
89
|
+
out += ' ';
|
|
90
|
+
pending = false;
|
|
91
|
+
out += char;
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
/** Normalized string equality against `case.expected`. */
|
|
96
|
+
export class ExactMatch {
|
|
97
|
+
_name;
|
|
98
|
+
constructor(options = {}) {
|
|
99
|
+
this._name = options.name ?? 'exact-match';
|
|
100
|
+
}
|
|
101
|
+
get name() {
|
|
102
|
+
return this._name;
|
|
103
|
+
}
|
|
104
|
+
get deterministic() {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
async score(entry, prediction) {
|
|
108
|
+
if (entry.expected === null) {
|
|
109
|
+
throw new EvalError(`case ${repr(entry.id)} has no expected value for ${this.name}`);
|
|
110
|
+
}
|
|
111
|
+
const ok = normalize(prediction) === normalize(entry.expected);
|
|
112
|
+
return new MetricResult({
|
|
113
|
+
metric: this.name,
|
|
114
|
+
score: ok ? 1.0 : 0.0,
|
|
115
|
+
passed: ok,
|
|
116
|
+
detail: ok ? '' : `expected ${repr(entry.expected)}`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Whether the normalized prediction contains the normalized expectation. */
|
|
121
|
+
export class NormalizedContains {
|
|
122
|
+
_name;
|
|
123
|
+
constructor(options = {}) {
|
|
124
|
+
this._name = options.name ?? 'contains';
|
|
125
|
+
}
|
|
126
|
+
get name() {
|
|
127
|
+
return this._name;
|
|
128
|
+
}
|
|
129
|
+
get deterministic() {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
async score(entry, prediction) {
|
|
133
|
+
if (entry.expected === null) {
|
|
134
|
+
throw new EvalError(`case ${repr(entry.id)} has no expected value for ${this.name}`);
|
|
135
|
+
}
|
|
136
|
+
const ok = normalize(prediction).includes(normalize(entry.expected));
|
|
137
|
+
return new MetricResult({
|
|
138
|
+
metric: this.name,
|
|
139
|
+
score: ok ? 1.0 : 0.0,
|
|
140
|
+
passed: ok,
|
|
141
|
+
detail: ok ? '' : `missing ${repr(entry.expected)}`,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** The Python `type(value).__name__` for a JSON value. */
|
|
146
|
+
function typeName(value) {
|
|
147
|
+
if (value === null)
|
|
148
|
+
return 'NoneType';
|
|
149
|
+
if (Array.isArray(value))
|
|
150
|
+
return 'list';
|
|
151
|
+
if (typeof value === 'object')
|
|
152
|
+
return 'dict';
|
|
153
|
+
if (typeof value === 'string')
|
|
154
|
+
return 'str';
|
|
155
|
+
if (typeof value === 'boolean')
|
|
156
|
+
return 'bool';
|
|
157
|
+
if (typeof value === 'number')
|
|
158
|
+
return Number.isInteger(value) ? 'int' : 'float';
|
|
159
|
+
return typeof value;
|
|
160
|
+
}
|
|
161
|
+
function typeOk(value, declared) {
|
|
162
|
+
switch (declared) {
|
|
163
|
+
case 'object':
|
|
164
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
165
|
+
case 'array':
|
|
166
|
+
return Array.isArray(value);
|
|
167
|
+
case 'string':
|
|
168
|
+
return typeof value === 'string';
|
|
169
|
+
case 'integer':
|
|
170
|
+
return typeof value === 'number' && Number.isInteger(value);
|
|
171
|
+
case 'number':
|
|
172
|
+
return typeof value === 'number';
|
|
173
|
+
case 'boolean':
|
|
174
|
+
return typeof value === 'boolean';
|
|
175
|
+
case 'null':
|
|
176
|
+
return value === null;
|
|
177
|
+
default:
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function isObject(value) {
|
|
182
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
183
|
+
}
|
|
184
|
+
/** Check the JSON Schema subset a dataset realistically uses. */
|
|
185
|
+
function schemaProblems(schema, value, path) {
|
|
186
|
+
const problems = [];
|
|
187
|
+
if (!isObject(schema))
|
|
188
|
+
return problems;
|
|
189
|
+
const declared = schema.type;
|
|
190
|
+
if (typeof declared === 'string' && !typeOk(value, declared)) {
|
|
191
|
+
problems.push(`${path}: expected ${declared}, got ${typeName(value)}`);
|
|
192
|
+
}
|
|
193
|
+
if (isObject(value)) {
|
|
194
|
+
const required = schema.required;
|
|
195
|
+
if (Array.isArray(required)) {
|
|
196
|
+
for (const name of required) {
|
|
197
|
+
if (typeof name === 'string' && !Object.hasOwn(value, name)) {
|
|
198
|
+
problems.push(`${path}: missing required property ${repr(name)}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const properties = schema.properties;
|
|
203
|
+
if (isObject(properties)) {
|
|
204
|
+
for (const [name, subschema] of Object.entries(properties)) {
|
|
205
|
+
if (Object.hasOwn(value, name)) {
|
|
206
|
+
problems.push(...schemaProblems(subschema, value[name], `${path}.${name}`));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (Array.isArray(value) && isObject(schema.items)) {
|
|
212
|
+
for (const [index, item] of value.entries()) {
|
|
213
|
+
problems.push(...schemaProblems(schema.items, item, `${path}[${index}]`));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return problems;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Whether the prediction parses as JSON and satisfies the case's schema.
|
|
220
|
+
*
|
|
221
|
+
* The schema lives in the case's metadata under `json_schema` as a JSON string, which
|
|
222
|
+
* keeps datasets in a single file format.
|
|
223
|
+
*/
|
|
224
|
+
export class JsonSchemaValid {
|
|
225
|
+
_name;
|
|
226
|
+
constructor(options = {}) {
|
|
227
|
+
this._name = options.name ?? 'json-valid';
|
|
228
|
+
}
|
|
229
|
+
get name() {
|
|
230
|
+
return this._name;
|
|
231
|
+
}
|
|
232
|
+
get deterministic() {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
async score(entry, prediction) {
|
|
236
|
+
const schema = entry.metadata.json_schema;
|
|
237
|
+
let parsed;
|
|
238
|
+
try {
|
|
239
|
+
parsed = JSON.parse(prediction);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
243
|
+
return new MetricResult({
|
|
244
|
+
metric: this.name,
|
|
245
|
+
score: 0.0,
|
|
246
|
+
passed: false,
|
|
247
|
+
detail: `invalid JSON: ${message}`,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (schema === undefined) {
|
|
251
|
+
return new MetricResult({ metric: this.name, score: 1.0, passed: true, detail: 'parsed' });
|
|
252
|
+
}
|
|
253
|
+
const problems = schemaProblems(JSON.parse(schema), parsed, '$');
|
|
254
|
+
return new MetricResult({
|
|
255
|
+
metric: this.name,
|
|
256
|
+
score: problems.length === 0 ? 1.0 : 0.0,
|
|
257
|
+
passed: problems.length === 0,
|
|
258
|
+
detail: problems.join('; '),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Whether a declared predicate holds for the case and its prediction.
|
|
264
|
+
*
|
|
265
|
+
* The condition arrives as the IR's predicate AST -- the very tree the spec layer
|
|
266
|
+
* parsed and checked -- so this metric needs no parser and cannot disagree with the
|
|
267
|
+
* one that accepted the spec. A prediction that makes the predicate false scores 0.0
|
|
268
|
+
* and reports the spec's own `message` verbatim, because the point of letting the
|
|
269
|
+
* author write the message is that a failure quotes them.
|
|
270
|
+
*
|
|
271
|
+
* A predicate that cannot be decided throws instead of scoring. See `predicate.ts`
|
|
272
|
+
* for why that distinction is load-bearing.
|
|
273
|
+
*/
|
|
274
|
+
export class AssertMetric {
|
|
275
|
+
name;
|
|
276
|
+
deterministic = true;
|
|
277
|
+
expr;
|
|
278
|
+
message;
|
|
279
|
+
constructor(init) {
|
|
280
|
+
this.name = init.name ?? 'assert';
|
|
281
|
+
this.expr = init.expr;
|
|
282
|
+
this.message = init.message;
|
|
283
|
+
}
|
|
284
|
+
async score(entry, prediction) {
|
|
285
|
+
const ok = evaluatePredicate(this.expr, { entry, prediction });
|
|
286
|
+
return new MetricResult({
|
|
287
|
+
metric: this.name,
|
|
288
|
+
score: ok ? 1.0 : 0.0,
|
|
289
|
+
passed: ok,
|
|
290
|
+
detail: ok ? '' : this.message,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/** The structured output an LLM judge must return. */
|
|
295
|
+
export const JudgeVerdict = structuredOutput('JudgeVerdict', z.object({
|
|
296
|
+
score: z.number().min(0.0).max(1.0),
|
|
297
|
+
reason: z.string().default(''),
|
|
298
|
+
}));
|
|
299
|
+
/**
|
|
300
|
+
* Scores a prediction with a model, as a *metric only*.
|
|
301
|
+
*
|
|
302
|
+
* `deterministic` is `false` and must stay that way. Using this metric for a CI
|
|
303
|
+
* threshold would make the gate's own verdict probabilistic; the gate raises rather
|
|
304
|
+
* than allow it. It is implemented because a judge is the right way to explore quality
|
|
305
|
+
* locally and to produce a second opinion next to a deterministic gate -- not because
|
|
306
|
+
* it can be trusted as the gate.
|
|
307
|
+
*/
|
|
308
|
+
export class LlmJudge {
|
|
309
|
+
_call;
|
|
310
|
+
_rubric;
|
|
311
|
+
_name;
|
|
312
|
+
_retries;
|
|
313
|
+
constructor(call, options) {
|
|
314
|
+
this._call = call;
|
|
315
|
+
this._rubric = options.rubric;
|
|
316
|
+
this._name = options.name ?? 'llm-judge';
|
|
317
|
+
this._retries = options.retries ?? 2;
|
|
318
|
+
}
|
|
319
|
+
get name() {
|
|
320
|
+
return this._name;
|
|
321
|
+
}
|
|
322
|
+
get deterministic() {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
async score(entry, prediction) {
|
|
326
|
+
const prompt = this.buildPrompt(entry, prediction);
|
|
327
|
+
try {
|
|
328
|
+
const verdict = await runStructured(this._call, JudgeVerdict, prompt, {
|
|
329
|
+
retries: this._retries,
|
|
330
|
+
});
|
|
331
|
+
return new MetricResult({
|
|
332
|
+
metric: this.name,
|
|
333
|
+
score: verdict.score,
|
|
334
|
+
passed: verdict.score >= 0.5,
|
|
335
|
+
detail: verdict.reason,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
340
|
+
return new MetricResult({
|
|
341
|
+
metric: this.name,
|
|
342
|
+
score: 0.0,
|
|
343
|
+
passed: false,
|
|
344
|
+
detail: `judge failed: ${message}`,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
buildPrompt(entry, prediction) {
|
|
349
|
+
const expected = entry.expected ?? '<not provided>';
|
|
350
|
+
return (`${this._rubric}\n\n` +
|
|
351
|
+
`Input: ${entry.input}\n` +
|
|
352
|
+
`Reference: ${expected}\n` +
|
|
353
|
+
`Candidate: ${prediction}\n\n` +
|
|
354
|
+
'Reply with JSON: {"score": <0.0-1.0>, "reason": "<short>"}');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/** The deterministic gate metrics: everything that needs no model call. */
|
|
358
|
+
export function defaultMetrics() {
|
|
359
|
+
return [new ExactMatch(), new NormalizedContains(), new JsonSchemaValid()];
|
|
360
|
+
}
|
|
361
|
+
export function metricNames(metrics) {
|
|
362
|
+
return metrics.map((metric) => metric.name);
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/evals/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PredicateExpr evaluator an `assert` metric runs.
|
|
3
|
+
*
|
|
4
|
+
* The AST is data, not code: the IR parses and validates it, the generator emits it
|
|
5
|
+
* as a plain object literal, and this module walks it. There is no `eval` and no
|
|
6
|
+
* `new Function` anywhere on that path, so a predicate can only ever do what this
|
|
7
|
+
* file implements -- read the prediction, the case id and one metadata key, call
|
|
8
|
+
* four total string builtins, and compare. Anything else is a node kind this walker
|
|
9
|
+
* does not know, and an unknown node throws rather than passing.
|
|
10
|
+
*
|
|
11
|
+
* Throwing matters more than it looks. A false assertion and an *undecidable* one
|
|
12
|
+
* are different outcomes: `false` is a legitimate result the gate must see, while a
|
|
13
|
+
* missing metadata key or a string where a number belongs means the eval itself is
|
|
14
|
+
* misconfigured. Returning `false` for either would report a broken eval as a
|
|
15
|
+
* failing candidate, and returning `true` would hide it, so both throw `EvalError`.
|
|
16
|
+
*
|
|
17
|
+
* Both sides of `and`/`or` are always evaluated. Short-circuiting would let
|
|
18
|
+
* `case.metadata.missing == "x" or true` pass silently, which is the one failure
|
|
19
|
+
* mode this whole design exists to prevent.
|
|
20
|
+
*/
|
|
21
|
+
import type { EvalCase } from './dataset.js';
|
|
22
|
+
/**
|
|
23
|
+
* A value a predicate can carry.
|
|
24
|
+
*
|
|
25
|
+
* Numbers are a single `number` here; Python normalizes its `int` and `float` to
|
|
26
|
+
* `float` so a JSON literal `3` and `length(...)` compare equal in both. Booleans
|
|
27
|
+
* are kept apart from numbers on purpose, because `1 == true` is false here and a
|
|
28
|
+
* grammar that answered differently in each language would be worse than no grammar.
|
|
29
|
+
*/
|
|
30
|
+
export type PredicateValue = boolean | number | string;
|
|
31
|
+
/** The node shapes the IR emits. Structural, because the runtime owns no IR types. */
|
|
32
|
+
export type PredicateNode = {
|
|
33
|
+
readonly kind: 'boolean';
|
|
34
|
+
readonly value: boolean;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: 'number';
|
|
37
|
+
readonly value: number;
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: 'string';
|
|
40
|
+
readonly value: string;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: 'invalid';
|
|
43
|
+
readonly reason: string;
|
|
44
|
+
} | {
|
|
45
|
+
readonly kind: 'path';
|
|
46
|
+
readonly path: string;
|
|
47
|
+
readonly name?: string;
|
|
48
|
+
} | {
|
|
49
|
+
readonly kind: 'call';
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly args: readonly PredicateNode[];
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: 'comparison';
|
|
54
|
+
readonly op: string;
|
|
55
|
+
readonly left: PredicateNode;
|
|
56
|
+
readonly right: PredicateNode;
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: 'not';
|
|
59
|
+
readonly operand: PredicateNode;
|
|
60
|
+
} | {
|
|
61
|
+
readonly kind: 'and' | 'or';
|
|
62
|
+
readonly left: PredicateNode;
|
|
63
|
+
readonly right: PredicateNode;
|
|
64
|
+
};
|
|
65
|
+
/** The name a diagnostic uses for a value's type. */
|
|
66
|
+
export declare function typeName(value: PredicateValue): string;
|
|
67
|
+
/**
|
|
68
|
+
* Evaluate `node` against one case and prediction, or throw if it cannot be.
|
|
69
|
+
*
|
|
70
|
+
* A non-boolean result is an error rather than a truthiness test: the expression's
|
|
71
|
+
* type is fixed at build time, so a non-boolean here means the AST and the walker
|
|
72
|
+
* disagree, and guessing which one is right is exactly the kind of guess that makes
|
|
73
|
+
* a gate untrustworthy.
|
|
74
|
+
*/
|
|
75
|
+
export declare function evaluatePredicate(node: PredicateNode | undefined, context: {
|
|
76
|
+
readonly entry: EvalCase;
|
|
77
|
+
readonly prediction: string;
|
|
78
|
+
}): boolean;
|
|
79
|
+
//# sourceMappingURL=predicate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../../src/evals/predicate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,sFAAsF;AACtF,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,GACzF;IACE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;CAC/B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAIjG,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAItD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACjE,OAAO,CAMT"}
|