@llm4ts/flow 2.5.0 → 2.6.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/Classified.d.ts +2 -0
- package/dist/Classified.d.ts.map +1 -1
- package/dist/Classified.js +4 -0
- package/dist/Classified.js.map +1 -1
- package/dist/CostReport.d.ts +110 -0
- package/dist/CostReport.d.ts.map +1 -0
- package/dist/CostReport.js +313 -0
- package/dist/CostReport.js.map +1 -0
- package/dist/EstimatedUsage.d.ts.map +1 -1
- package/dist/EstimatedUsage.js +4 -0
- package/dist/EstimatedUsage.js.map +1 -1
- package/dist/Flow.d.ts +14 -0
- package/dist/Flow.d.ts.map +1 -1
- package/dist/Flow.js +45 -2
- package/dist/Flow.js.map +1 -1
- package/dist/FlowContext.d.ts +7 -0
- package/dist/FlowContext.d.ts.map +1 -1
- package/dist/FlowContext.js.map +1 -1
- package/dist/FlowEvents.d.ts +44 -1
- package/dist/FlowEvents.d.ts.map +1 -1
- package/dist/FlowEvents.js +35 -0
- package/dist/FlowEvents.js.map +1 -1
- package/dist/GitTool.d.ts +7 -0
- package/dist/GitTool.d.ts.map +1 -1
- package/dist/GitTool.js +15 -1
- package/dist/GitTool.js.map +1 -1
- package/dist/Judgment.d.ts +88 -0
- package/dist/Judgment.d.ts.map +1 -0
- package/dist/Judgment.js +281 -0
- package/dist/Judgment.js.map +1 -0
- package/dist/JudgmentDataset.d.ts +79 -0
- package/dist/JudgmentDataset.d.ts.map +1 -0
- package/dist/JudgmentDataset.js +164 -0
- package/dist/JudgmentDataset.js.map +1 -0
- package/dist/JudgmentEval.d.ts +143 -0
- package/dist/JudgmentEval.d.ts.map +1 -0
- package/dist/JudgmentEval.js +242 -0
- package/dist/JudgmentEval.js.map +1 -0
- package/dist/JudgmentLog.d.ts +46 -0
- package/dist/JudgmentLog.d.ts.map +1 -0
- package/dist/JudgmentLog.js +62 -0
- package/dist/JudgmentLog.js.map +1 -0
- package/dist/JudgmentTypes.d.ts +13 -0
- package/dist/JudgmentTypes.d.ts.map +1 -0
- package/dist/JudgmentTypes.js +11 -0
- package/dist/JudgmentTypes.js.map +1 -0
- package/dist/ProgramJudge.d.ts +15 -2
- package/dist/ProgramJudge.d.ts.map +1 -1
- package/dist/ProgramJudge.js +58 -3
- package/dist/ProgramJudge.js.map +1 -1
- package/dist/Replay.d.ts.map +1 -1
- package/dist/Replay.js +9 -4
- package/dist/Replay.js.map +1 -1
- package/dist/Review.d.ts +35 -0
- package/dist/Review.d.ts.map +1 -1
- package/dist/Review.js +92 -13
- package/dist/Review.js.map +1 -1
- package/dist/Reviewer.d.ts +8 -0
- package/dist/Reviewer.d.ts.map +1 -1
- package/dist/Reviewer.js +12 -1
- package/dist/Reviewer.js.map +1 -1
- package/dist/TransientRetry.d.ts.map +1 -1
- package/dist/TransientRetry.js +1 -0
- package/dist/TransientRetry.js.map +1 -1
- package/package.json +8 -3
- package/src/Classified.ts +5 -0
- package/src/CostReport.ts +402 -0
- package/src/EstimatedUsage.ts +15 -0
- package/src/Flow.ts +77 -2
- package/src/FlowContext.ts +7 -0
- package/src/FlowEvents.ts +42 -0
- package/src/GitTool.ts +19 -1
- package/src/Judgment.ts +418 -0
- package/src/JudgmentDataset.ts +254 -0
- package/src/JudgmentEval.ts +306 -0
- package/src/JudgmentLog.ts +96 -0
- package/src/JudgmentTypes.ts +15 -0
- package/src/ProgramJudge.ts +89 -4
- package/src/Replay.ts +23 -17
- package/src/Review.ts +163 -13
- package/src/Reviewer.ts +15 -1
- package/src/TransientRetry.ts +1 -0
package/dist/Judgment.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { ProviderError } from "@llm4ts/core/Errors";
|
|
4
|
+
import { makeLlmJudgment } from "@llm4ts/core/judgment/LlmJudgment";
|
|
5
|
+
import { ChoiceAnswer, JudgmentResult, ScoreAnswer, TruthAnswer, confidenceOf, expectedScore, origins, renderState } from "@llm4ts/core/judgment/Schemas";
|
|
6
|
+
import { ParseError } from "@llm4ts/core/Errors";
|
|
7
|
+
import { FlowLlmError, PersistenceError } from "./FlowError.js";
|
|
8
|
+
import { Info } from "./FlowEvents.js";
|
|
9
|
+
import {} from "./JudgmentTypes.js";
|
|
10
|
+
export { Decision, JudgmentMode } from "./JudgmentTypes.js";
|
|
11
|
+
/**
|
|
12
|
+
* Judgment policy (ADR 0017): core answers questions and reports their
|
|
13
|
+
* origin; this module decides what a flow does with the number. Thresholds
|
|
14
|
+
* are keyed first by calibration evidence (`measured`, then `claimed`) and
|
|
15
|
+
* otherwise by extraction method, because a model that writes its own
|
|
16
|
+
* probabilities (`verbalized`) is held to a higher bar than one whose
|
|
17
|
+
* log-probabilities were read (`logprobs`), and a reasoning model's typed
|
|
18
|
+
* reply (`reasoning`) sits between. An answer whose `support` (mass the
|
|
19
|
+
* backend actually placed on the offered options) is below `minSupport` is
|
|
20
|
+
* held whatever its confidence. Jev's advice, kept: questions and
|
|
21
|
+
* thresholds in one place.
|
|
22
|
+
*/
|
|
23
|
+
export class CertaintyBands extends Schema.Class("CertaintyBands")({
|
|
24
|
+
/** At or above: act automatically. */
|
|
25
|
+
act: Schema.Number,
|
|
26
|
+
/** Below: do not act; escalate or hold. Between the two: proceed with caution. */
|
|
27
|
+
hold: Schema.Number
|
|
28
|
+
}) {
|
|
29
|
+
}
|
|
30
|
+
const thresholds = (act, hold) => CertaintyBands.pipe(Schema.withConstructorDefault(Effect.succeed(CertaintyBands.make({ act, hold }))));
|
|
31
|
+
export class JudgmentPolicy extends Schema.Class("JudgmentPolicy")({
|
|
32
|
+
/** Calibration evidence produced in this project: trusted most. */
|
|
33
|
+
measured: thresholds(0.8, 0.5),
|
|
34
|
+
/** The provider claims calibration (TypeSafe). */
|
|
35
|
+
claimed: thresholds(0.85, 0.5),
|
|
36
|
+
/** No evidence; keyed by how the numbers were extracted. */
|
|
37
|
+
logprobs: thresholds(0.9, 0.6),
|
|
38
|
+
sampled: thresholds(0.9, 0.6),
|
|
39
|
+
reasoning: thresholds(0.9, 0.6),
|
|
40
|
+
verbalized: thresholds(0.95, 0.7),
|
|
41
|
+
/** Below this share of mass on the offered options, hold regardless. */
|
|
42
|
+
minSupport: Schema.Number.pipe(Schema.withConstructorDefault(Effect.succeed(0.5)))
|
|
43
|
+
}) {
|
|
44
|
+
thresholds(origin) {
|
|
45
|
+
switch (origin.calibration) {
|
|
46
|
+
case "measured":
|
|
47
|
+
return this.measured;
|
|
48
|
+
case "claimed":
|
|
49
|
+
return this.claimed;
|
|
50
|
+
case "none":
|
|
51
|
+
return origin.method === "hosted" ? this.claimed : this[origin.method];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export const defaultJudgmentPolicy = JudgmentPolicy.make({});
|
|
56
|
+
/**
|
|
57
|
+
* How sure an answer is, whatever its kind. A Choice or Score carries its
|
|
58
|
+
* confidence (the peak probability). A Truth's certainty is its distance
|
|
59
|
+
* from even, scaled so 0.5 is 0 and either extreme is 1: `|2·truth − 1|`.
|
|
60
|
+
*/
|
|
61
|
+
export const certaintyOf = (answer) => answer.type === "truth" ? Math.abs(2 * answer.truth - 1) : answer.confidence;
|
|
62
|
+
/**
|
|
63
|
+
* The three bands Jev documents: act, proceed with caution, or hold. An
|
|
64
|
+
* answer rebuilt from too little mass on the offered options is always held.
|
|
65
|
+
*/
|
|
66
|
+
export const decide = (answer, policy = defaultJudgmentPolicy) => {
|
|
67
|
+
if (answer.support < policy.minSupport) {
|
|
68
|
+
return "hold";
|
|
69
|
+
}
|
|
70
|
+
const certainty = certaintyOf(answer);
|
|
71
|
+
const bands = policy.thresholds(answer.origin);
|
|
72
|
+
return certainty >= bands.act ? "act" : certainty < bands.hold ? "hold" : "caution";
|
|
73
|
+
};
|
|
74
|
+
/** The context's judgment service, or one derived from its reasoning seat. */
|
|
75
|
+
export const judgmentOf = (context) => context.judgment ?? makeLlmJudgment(context.reasoning);
|
|
76
|
+
const backendFailure = (error) => FlowLlmError.from(ProviderError.make({ message: error.message, cause: error }));
|
|
77
|
+
// Escalation asks a reasoning model the same question in its own words and
|
|
78
|
+
// decodes a typed reply, so the schema per kind mirrors the answer shape.
|
|
79
|
+
class EscalatedChoice extends Schema.Class("EscalatedChoice")({
|
|
80
|
+
choice: Schema.String,
|
|
81
|
+
probabilities: Schema.Record(Schema.String, Schema.Number)
|
|
82
|
+
}) {
|
|
83
|
+
}
|
|
84
|
+
class EscalatedScore extends Schema.Class("EscalatedScore")({
|
|
85
|
+
probabilities: Schema.Record(Schema.String, Schema.Number)
|
|
86
|
+
}) {
|
|
87
|
+
}
|
|
88
|
+
class EscalatedTruth extends Schema.Class("EscalatedTruth")({
|
|
89
|
+
truth: Schema.Number
|
|
90
|
+
}) {
|
|
91
|
+
}
|
|
92
|
+
const numberMap = (keys) => ({
|
|
93
|
+
type: "object",
|
|
94
|
+
properties: Object.fromEntries(keys.map((key) => [key, { type: "number" }])),
|
|
95
|
+
required: [...keys],
|
|
96
|
+
additionalProperties: false
|
|
97
|
+
});
|
|
98
|
+
const escalationPrompt = (state, question) => {
|
|
99
|
+
const header = `State:\n${renderState(state)}\n\nThink carefully, then answer with JSON only.\n`;
|
|
100
|
+
switch (question.type) {
|
|
101
|
+
case "choice":
|
|
102
|
+
return (`${header}Question: ${question.instructions}\nOptions:\n` +
|
|
103
|
+
Object.entries(question.criteria)
|
|
104
|
+
.map(([key, description]) => `- ${key}: ${JSON.stringify(description)}`)
|
|
105
|
+
.join("\n") +
|
|
106
|
+
'\nReply: {"choice": <option key>, "probabilities": {<a probability per option, summing to 1>}}');
|
|
107
|
+
case "score":
|
|
108
|
+
return (`${header}Rate: ${question.instructions}\nLevels:\n` +
|
|
109
|
+
question.criteria.map((level, index) => `- ${index}: ${JSON.stringify(level)}`).join("\n") +
|
|
110
|
+
'\nReply: {"probabilities": {<a probability per level index, summing to 1>}}');
|
|
111
|
+
case "truth":
|
|
112
|
+
return (`${header}Statement: ${question.instructions}\n` +
|
|
113
|
+
(question.criteria === undefined
|
|
114
|
+
? ""
|
|
115
|
+
: `True means: ${JSON.stringify(question.criteria.true)}\nFalse means: ${JSON.stringify(question.criteria.false)}\n`) +
|
|
116
|
+
'Reply: {"truth": <probability between 0 and 1 that the statement holds>}');
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
/** Renormalize over the offered keys; fails typed when nothing was placed on them. */
|
|
120
|
+
const normalized = (keys, raw) => {
|
|
121
|
+
const kept = keys.map((key) => [key, Math.max(0, raw[key] ?? 0)]);
|
|
122
|
+
const total = kept.reduce((sum, [, value]) => sum + value, 0);
|
|
123
|
+
return total > 0
|
|
124
|
+
? Effect.succeed(Object.fromEntries(kept.map(([key, value]) => [key, value / total])))
|
|
125
|
+
: Effect.fail(ParseError.make({
|
|
126
|
+
message: "the reasoning seat placed no probability on any offered option",
|
|
127
|
+
raw: JSON.stringify(raw)
|
|
128
|
+
}));
|
|
129
|
+
};
|
|
130
|
+
const escalate = (reasoning, backend, state, question) => {
|
|
131
|
+
const prompt = escalationPrompt(state, question);
|
|
132
|
+
const origin = origins.escalated(backend);
|
|
133
|
+
switch (question.type) {
|
|
134
|
+
case "choice": {
|
|
135
|
+
const keys = Object.keys(question.criteria);
|
|
136
|
+
return reasoning
|
|
137
|
+
.executeStructured(prompt, EscalatedChoice, {
|
|
138
|
+
type: "object",
|
|
139
|
+
properties: {
|
|
140
|
+
choice: { type: "string", enum: [...keys] },
|
|
141
|
+
probabilities: numberMap(keys)
|
|
142
|
+
},
|
|
143
|
+
required: ["choice", "probabilities"]
|
|
144
|
+
})
|
|
145
|
+
.pipe(Effect.flatMap((reply) =>
|
|
146
|
+
// A choice the model gave no mass contradicts itself: fail rather
|
|
147
|
+
// than invent certainty, and the caller keeps its earlier answer.
|
|
148
|
+
keys.includes(reply.choice) && !((reply.probabilities[reply.choice] ?? 0) > 0)
|
|
149
|
+
? Effect.fail(ParseError.make({
|
|
150
|
+
message: `the reasoning seat chose "${reply.choice}" but gave it no probability`,
|
|
151
|
+
raw: JSON.stringify(reply.probabilities)
|
|
152
|
+
}))
|
|
153
|
+
: Effect.map(normalized(keys, reply.probabilities), (probabilities) => ChoiceAnswer.make({
|
|
154
|
+
type: "choice",
|
|
155
|
+
choice: keys.includes(reply.choice) ? reply.choice : (keys[0] ?? ""),
|
|
156
|
+
probabilities,
|
|
157
|
+
confidence: confidenceOf(probabilities),
|
|
158
|
+
origin
|
|
159
|
+
}))), Effect.mapError(FlowLlmError.from));
|
|
160
|
+
}
|
|
161
|
+
case "score": {
|
|
162
|
+
const keys = question.criteria.map((_, index) => String(index));
|
|
163
|
+
return reasoning
|
|
164
|
+
.executeStructured(prompt, EscalatedScore, {
|
|
165
|
+
type: "object",
|
|
166
|
+
properties: { probabilities: numberMap(keys) },
|
|
167
|
+
required: ["probabilities"]
|
|
168
|
+
})
|
|
169
|
+
.pipe(Effect.flatMap((reply) => Effect.map(normalized(keys, reply.probabilities), (probabilities) => ScoreAnswer.make({
|
|
170
|
+
type: "score",
|
|
171
|
+
score: expectedScore(probabilities),
|
|
172
|
+
legend: Object.fromEntries(question.criteria.map((level, index) => [String(index), level])),
|
|
173
|
+
probabilities,
|
|
174
|
+
confidence: confidenceOf(probabilities),
|
|
175
|
+
origin
|
|
176
|
+
}))), Effect.mapError(FlowLlmError.from));
|
|
177
|
+
}
|
|
178
|
+
case "truth":
|
|
179
|
+
return reasoning
|
|
180
|
+
.executeStructured(prompt, EscalatedTruth, {
|
|
181
|
+
type: "object",
|
|
182
|
+
properties: { truth: { type: "number" } },
|
|
183
|
+
required: ["truth"]
|
|
184
|
+
})
|
|
185
|
+
.pipe(Effect.map((reply) => TruthAnswer.make({
|
|
186
|
+
type: "truth",
|
|
187
|
+
truth: Math.max(0, Math.min(1, reply.truth)),
|
|
188
|
+
origin
|
|
189
|
+
})), Effect.mapError(FlowLlmError.from));
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Run the judgment; every answer the policy would `hold`, and every question
|
|
194
|
+
* that failed, is asked again of the reasoning seat and replaced with an
|
|
195
|
+
* `escalated` answer. An escalation that fails keeps what it had, so the
|
|
196
|
+
* caller always sees the most informed answer available.
|
|
197
|
+
*/
|
|
198
|
+
export const judgeOrEscalate = Effect.fn("@llm4ts/flow/Judgment.judgeOrEscalate")(function* (options) {
|
|
199
|
+
const policy = options.policy ?? defaultJudgmentPolicy;
|
|
200
|
+
const result = yield* options.judgment
|
|
201
|
+
.judge(options.request)
|
|
202
|
+
.pipe(Effect.mapError(backendFailure));
|
|
203
|
+
const answers = { ...result.answers };
|
|
204
|
+
const failures = [...result.failures];
|
|
205
|
+
for (const [key, question] of Object.entries(options.request.questions)) {
|
|
206
|
+
const current = answers[key];
|
|
207
|
+
const reason = current === undefined
|
|
208
|
+
? (failures.find((failure) => failure.key === key)?.reason ?? "no answer")
|
|
209
|
+
: decide(current, policy) === "hold"
|
|
210
|
+
? current.support < policy.minSupport
|
|
211
|
+
? `${current.origin.method} support ${current.support.toFixed(2)} below ${policy.minSupport}`
|
|
212
|
+
: `${current.origin.method} certainty ${certaintyOf(current).toFixed(2)} below hold`
|
|
213
|
+
: undefined;
|
|
214
|
+
if (reason === undefined) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
yield* options.events.publish(Info.make({ message: `judgment '${key}' escalated to the reasoning seat: ${reason}` }));
|
|
218
|
+
const escalated = yield* escalate(options.reasoning, result.backend, options.request.state, question).pipe(Effect.map((answer) => answer), Effect.catch((error) => options.events
|
|
219
|
+
.publish(Info.make({
|
|
220
|
+
message: `judgment '${key}' escalation failed (${error._tag}); keeping the original answer`
|
|
221
|
+
}))
|
|
222
|
+
.pipe(Effect.as(undefined))));
|
|
223
|
+
if (escalated !== undefined) {
|
|
224
|
+
answers[key] = escalated;
|
|
225
|
+
const index = failures.findIndex((failure) => failure.key === key);
|
|
226
|
+
if (index >= 0) {
|
|
227
|
+
failures.splice(index, 1);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return JudgmentResult.make({
|
|
232
|
+
answers,
|
|
233
|
+
failures,
|
|
234
|
+
backend: result.backend,
|
|
235
|
+
...(result.usage === undefined ? {} : { usage: result.usage }),
|
|
236
|
+
...(result.model === undefined ? {} : { model: result.model })
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
class JudgmentCacheEntry extends Schema.Class("JudgmentCacheEntry")({
|
|
240
|
+
fingerprint: Schema.String,
|
|
241
|
+
result: JudgmentResult
|
|
242
|
+
}) {
|
|
243
|
+
}
|
|
244
|
+
const hexDigest = (buffer) => Array.from(new Uint8Array(buffer))
|
|
245
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
246
|
+
.join("");
|
|
247
|
+
/**
|
|
248
|
+
* A stable digest of state, questions and the judgment's identity (backend
|
|
249
|
+
* plus checkpoint): the cache key for one request. A retrained or swapped
|
|
250
|
+
* local model therefore never reuses its predecessor's answers.
|
|
251
|
+
*/
|
|
252
|
+
export const judgmentFingerprint = (request, identity) => Effect.tryPromise({
|
|
253
|
+
try: async () => hexDigest(await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify({ identity, state: request.state, questions: request.questions })))),
|
|
254
|
+
catch: (error) => PersistenceError.make({
|
|
255
|
+
message: `failed to fingerprint judgment: ${error instanceof Error ? error.message : String(error)}`,
|
|
256
|
+
cause: error
|
|
257
|
+
})
|
|
258
|
+
});
|
|
259
|
+
/**
|
|
260
|
+
* Answers persisted like `cachedReview`: a re-run re-judges only what
|
|
261
|
+
* changed (state, questions, or backend). A cached result carries the
|
|
262
|
+
* origin it was answered with, so policy still applies as before.
|
|
263
|
+
*/
|
|
264
|
+
export const cachedJudgment = Effect.fn("@llm4ts/flow/Judgment.cached")(function* (files, path, judgment, request) {
|
|
265
|
+
const fingerprint = yield* judgmentFingerprint(request, judgment.identity);
|
|
266
|
+
const contents = yield* files.read(path).pipe(Effect.catch(() => Effect.succeed(undefined)));
|
|
267
|
+
const entry = contents === undefined
|
|
268
|
+
? undefined
|
|
269
|
+
: yield* Schema.decodeUnknownEffect(Schema.fromJsonString(JudgmentCacheEntry))(contents).pipe(Effect.option, Effect.map((option) => (option._tag === "Some" ? option.value : undefined)));
|
|
270
|
+
if (entry?.fingerprint === fingerprint) {
|
|
271
|
+
return entry.result;
|
|
272
|
+
}
|
|
273
|
+
const result = yield* judgment.judge(request).pipe(Effect.mapError(backendFailure));
|
|
274
|
+
const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(JudgmentCacheEntry))(JudgmentCacheEntry.make({ fingerprint, result })).pipe(Effect.mapError((error) => PersistenceError.make({
|
|
275
|
+
message: `failed to encode judgment cache: ${String(error)}`,
|
|
276
|
+
cause: error
|
|
277
|
+
})));
|
|
278
|
+
yield* files.writeAtomic(path, encoded);
|
|
279
|
+
return result;
|
|
280
|
+
});
|
|
281
|
+
//# sourceMappingURL=Judgment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Judgment.js","sourceRoot":"","sources":["../src/Judgment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { ScoreQuestion, TruthQuestion } from "@llm4ts/core/judgment/Schemas";
|
|
4
|
+
import type { JudgmentObservation } from "./JudgmentLog.ts";
|
|
5
|
+
import type { PlainFileStoreShape } from "./Persistence.ts";
|
|
6
|
+
import type { Reviewer } from "./Reviewer.ts";
|
|
7
|
+
export declare const DatasetDecision: Schema.Literals<readonly ["review-prescreen", "satisfied-probe", "program-judge"]>;
|
|
8
|
+
export type DatasetDecision = typeof DatasetDecision.Type;
|
|
9
|
+
declare const DatasetQuestion: Schema.Union<readonly [typeof TruthQuestion, typeof ScoreQuestion]>;
|
|
10
|
+
export declare const validLabel: (question: typeof DatasetQuestion.Type, label: unknown) => boolean;
|
|
11
|
+
declare const LabelledItem_base: Schema.Class<LabelledItem, Schema.Struct<{
|
|
12
|
+
readonly label: Schema.Union<readonly [Schema.Boolean, Schema.Int]>;
|
|
13
|
+
readonly labelledBy: Schema.String;
|
|
14
|
+
/** Human-supplied ISO 8601 timestamp. */
|
|
15
|
+
readonly labelledAt: Schema.String;
|
|
16
|
+
readonly id: Schema.String;
|
|
17
|
+
readonly decision: Schema.Literals<readonly ["review-prescreen", "satisfied-probe", "program-judge"]>;
|
|
18
|
+
readonly state: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.String>]>;
|
|
19
|
+
readonly question: Schema.Union<readonly [typeof TruthQuestion, typeof ScoreQuestion]>;
|
|
20
|
+
readonly source: Schema.String;
|
|
21
|
+
}>, {}>;
|
|
22
|
+
export declare class LabelledItem extends LabelledItem_base {
|
|
23
|
+
}
|
|
24
|
+
declare const PendingItem_base: Schema.Class<PendingItem, Schema.Struct<{
|
|
25
|
+
readonly label: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
26
|
+
readonly labelledBy: Schema.optionalKey<Schema.NullOr<Schema.String>>;
|
|
27
|
+
readonly labelledAt: Schema.optionalKey<Schema.NullOr<Schema.String>>;
|
|
28
|
+
readonly id: Schema.String;
|
|
29
|
+
readonly decision: Schema.Literals<readonly ["review-prescreen", "satisfied-probe", "program-judge"]>;
|
|
30
|
+
readonly state: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.String>]>;
|
|
31
|
+
readonly question: Schema.Union<readonly [typeof TruthQuestion, typeof ScoreQuestion]>;
|
|
32
|
+
readonly source: Schema.String;
|
|
33
|
+
}>, {}>;
|
|
34
|
+
/** Seeds omit the label; edits remain readable so promotion can report all refused ids. */
|
|
35
|
+
export declare class PendingItem extends PendingItem_base {
|
|
36
|
+
}
|
|
37
|
+
declare const DatasetParseError_base: Schema.Class<DatasetParseError, Schema.TaggedStruct<"DatasetParseError", {
|
|
38
|
+
readonly path: Schema.String;
|
|
39
|
+
readonly line: Schema.Int;
|
|
40
|
+
readonly message: Schema.String;
|
|
41
|
+
}>, import("effect/Cause").YieldableError>;
|
|
42
|
+
export declare class DatasetParseError extends DatasetParseError_base {
|
|
43
|
+
}
|
|
44
|
+
declare const PromotionRefused_base: Schema.Class<PromotionRefused, Schema.TaggedStruct<"PromotionRefused", {
|
|
45
|
+
readonly ids: Schema.$Array<Schema.String>;
|
|
46
|
+
readonly message: Schema.String;
|
|
47
|
+
}>, import("effect/Cause").YieldableError>;
|
|
48
|
+
export declare class PromotionRefused extends PromotionRefused_base {
|
|
49
|
+
}
|
|
50
|
+
/** A missing file is an empty set. Blank interior lines are malformed; a final newline is optional. */
|
|
51
|
+
export declare const readJsonLines: <A, I>(files: PlainFileStoreShape, path: string, schema: Schema.Codec<A, I, never, never>) => Effect.Effect<A[], import("./FlowError.ts").PersistenceError | DatasetParseError, never>;
|
|
52
|
+
export declare const readDataset: (files: PlainFileStoreShape, path: string) => Effect.Effect<LabelledItem[], import("./FlowError.ts").PersistenceError | DatasetParseError, never>;
|
|
53
|
+
export declare const readPending: (files: PlainFileStoreShape, path: string) => Effect.Effect<PendingItem[], import("./FlowError.ts").PersistenceError | DatasetParseError, never>;
|
|
54
|
+
export declare const appendDataset: (files: PlainFileStoreShape, path: string, items: readonly LabelledItem[]) => Effect.Effect<void, import("./FlowError.ts").PersistenceError | DatasetParseError, never>;
|
|
55
|
+
export declare const writePending: (files: PlainFileStoreShape, path: string, items: readonly PendingItem[]) => Effect.Effect<void, import("./FlowError.ts").PersistenceError | DatasetParseError, never>;
|
|
56
|
+
/** Escaping keeps source components unambiguous without a runtime-specific hash dependency. */
|
|
57
|
+
export declare const candidateId: (decision: DatasetDecision, source: string) => string;
|
|
58
|
+
export declare const reviewCandidates: (commits: ReadonlyArray<{
|
|
59
|
+
readonly sha: string;
|
|
60
|
+
readonly diff: string;
|
|
61
|
+
}>, lenses: ReadonlyArray<Reviewer>) => ReadonlyArray<PendingItem>;
|
|
62
|
+
/** Line position distinguishes repeated observations within a run, even at the same timestamp. */
|
|
63
|
+
export declare const observationCandidates: (decision: "review-prescreen" | "satisfied-probe" | "program-judge", observations: readonly JudgmentObservation[]) => Effect.Effect<PendingItem[], DatasetParseError, never>;
|
|
64
|
+
/** Existing human edits win; duplicates in the incoming batch are skipped too. */
|
|
65
|
+
export declare const mergeCandidates: (pending: ReadonlyArray<PendingItem>, dataset: ReadonlyArray<LabelledItem>, candidates: ReadonlyArray<PendingItem>) => ReadonlyArray<PendingItem>;
|
|
66
|
+
export declare const isLabelledPending: (item: PendingItem) => boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Validate the whole batch before any writes. An item nobody has labelled yet
|
|
69
|
+
* (label absent or null) simply stays pending, so labelling can proceed in
|
|
70
|
+
* batches; a label that is present but of the wrong kind or out of range
|
|
71
|
+
* refuses the whole promotion, naming the ids. Complete labels with
|
|
72
|
+
* incomplete attribution stay pending too.
|
|
73
|
+
*/
|
|
74
|
+
export declare const preparePromotion: (pending: readonly PendingItem[], dataset: readonly LabelledItem[]) => Effect.Effect<{
|
|
75
|
+
items: LabelledItem[];
|
|
76
|
+
remaining: PendingItem[];
|
|
77
|
+
}, Schema.SchemaError | PromotionRefused, never>;
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=JudgmentDataset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JudgmentDataset.d.ts","sourceRoot":"","sources":["../src/JudgmentDataset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAS,aAAa,EAAE,aAAa,EAAS,MAAM,+BAA+B,CAAA;AAC1F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,eAAO,MAAM,eAAe,oFAI1B,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAEzD,QAAA,MAAM,eAAe,qEAA+C,CAAA;AAapE,eAAO,MAAM,UAAU,GAAI,UAAU,OAAO,eAAe,CAAC,IAAI,EAAE,OAAO,OAAO,KAAG,OAM7C,CAAA;;;;IAMpC,yCAAyC;;;;;;;;AAe3C,qBAAa,YAAa,SAAQ,iBAA0D;CAAG;;;;;;;;;;;AAE/F,2FAA2F;AAC3F,qBAAa,WAAY,SAAQ,gBAOhC;CAAG;;;;;;AAEJ,qBAAa,iBAAkB,SAAQ,sBAOtC;CAAG;;;;;AAEJ,qBAAa,gBAAiB,SAAQ,qBAGpC;CAAG;AAEL,uGAAuG;AACvG,eAAO,MAAM,aAAa,GAAyD,CAAC,EAAE,CAAC,iLAoBrF,CAAA;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,mBAAmB,EAAE,MAAM,MAAM,wGAC1B,CAAA;AAC1C,eAAO,MAAM,WAAW,GAAI,OAAO,mBAAmB,EAAE,MAAM,MAAM,uGAC3B,CAAA;AAqBzC,eAAO,MAAM,aAAa,yKAUxB,CAAA;AAEF,eAAO,MAAM,YAAY,wKAOvB,CAAA;AAEF,+FAA+F;AAC/F,eAAO,MAAM,WAAW,GAAI,UAAU,eAAe,EAAE,QAAQ,MAAM,KAAG,MAC3B,CAAA;AAE7C,eAAO,MAAM,gBAAgB,GAC3B,SAAS,aAAa,CAAC;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACvE,QAAQ,aAAa,CAAC,QAAQ,CAAC,KAC9B,aAAa,CAAC,WAAW,CAYzB,CAAA;AAEH,kGAAkG;AAClG,eAAO,MAAM,qBAAqB,8KA2BhC,CAAA;AAEF,kFAAkF;AAClF,eAAO,MAAM,eAAe,GAC1B,SAAS,aAAa,CAAC,WAAW,CAAC,EACnC,SAAS,aAAa,CAAC,YAAY,CAAC,EACpC,YAAY,aAAa,CAAC,WAAW,CAAC,KACrC,aAAa,CAAC,WAAW,CAU3B,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,MAAM,WAAW,KAAG,OAA0C,CAAA;AAEhG;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;gDA4B3B,CAAA"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { State, ScoreQuestion, TruthQuestion, truth } from "@llm4ts/core/judgment/Schemas";
|
|
4
|
+
export const DatasetDecision = Schema.Literals([
|
|
5
|
+
"review-prescreen",
|
|
6
|
+
"satisfied-probe",
|
|
7
|
+
"program-judge"
|
|
8
|
+
]);
|
|
9
|
+
const Text = Schema.String.check(Schema.makeFilter((value) => value.trim().length > 0));
|
|
10
|
+
const DatasetQuestion = Schema.Union([TruthQuestion, ScoreQuestion]);
|
|
11
|
+
const baseFields = {
|
|
12
|
+
id: Text,
|
|
13
|
+
decision: DatasetDecision,
|
|
14
|
+
state: State,
|
|
15
|
+
question: DatasetQuestion,
|
|
16
|
+
source: Text
|
|
17
|
+
};
|
|
18
|
+
const correctQuestion = (item) => item.question.type === (item.decision === "program-judge" ? "score" : "truth");
|
|
19
|
+
export const validLabel = (question, label) => question.type === "truth"
|
|
20
|
+
? typeof label === "boolean"
|
|
21
|
+
: typeof label === "number" &&
|
|
22
|
+
Number.isInteger(label) &&
|
|
23
|
+
label >= 0 &&
|
|
24
|
+
label < question.criteria.length;
|
|
25
|
+
const LabelledRecord = Schema.Struct({
|
|
26
|
+
...baseFields,
|
|
27
|
+
label: Schema.Union([Schema.Boolean, Schema.Int]),
|
|
28
|
+
labelledBy: Text,
|
|
29
|
+
/** Human-supplied ISO 8601 timestamp. */
|
|
30
|
+
labelledAt: Schema.String.check(Schema.makeFilter((value) => /^\d{4}-\d{2}-\d{2}T/.test(value) && Number.isFinite(Date.parse(value))))
|
|
31
|
+
}).check(Schema.makeFilter(correctQuestion), Schema.makeFilter((item) => validLabel(item.question, item.label) ||
|
|
32
|
+
`Invalid label for ${item.id} (${item.question.type})`));
|
|
33
|
+
export class LabelledItem extends Schema.Class("LabelledItem")(LabelledRecord) {
|
|
34
|
+
}
|
|
35
|
+
/** Seeds omit the label; edits remain readable so promotion can report all refused ids. */
|
|
36
|
+
export class PendingItem extends Schema.Class("PendingItem")(Schema.Struct({
|
|
37
|
+
...baseFields,
|
|
38
|
+
label: Schema.optionalKey(Schema.Json),
|
|
39
|
+
labelledBy: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
40
|
+
labelledAt: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
41
|
+
}).check(Schema.makeFilter(correctQuestion))) {
|
|
42
|
+
}
|
|
43
|
+
export class DatasetParseError extends Schema.TaggedError()("DatasetParseError", {
|
|
44
|
+
path: Schema.String,
|
|
45
|
+
line: Schema.Int,
|
|
46
|
+
message: Schema.String
|
|
47
|
+
}) {
|
|
48
|
+
}
|
|
49
|
+
export class PromotionRefused extends Schema.TaggedError()("PromotionRefused", {
|
|
50
|
+
ids: Schema.Array(Schema.String),
|
|
51
|
+
message: Schema.String
|
|
52
|
+
}) {
|
|
53
|
+
}
|
|
54
|
+
/** A missing file is an empty set. Blank interior lines are malformed; a final newline is optional. */
|
|
55
|
+
export const readJsonLines = Effect.fn("JudgmentDataset.readJsonLines")(function* (files, path, schema) {
|
|
56
|
+
const contents = yield* files.read(path);
|
|
57
|
+
if (contents === undefined || contents === "")
|
|
58
|
+
return [];
|
|
59
|
+
const lines = contents.split("\n");
|
|
60
|
+
if (lines.at(-1) === "")
|
|
61
|
+
lines.pop();
|
|
62
|
+
return yield* Effect.forEach(lines, (line, index) => Schema.decodeUnknownEffect(Schema.fromJsonString(schema))(line).pipe(Effect.mapError(() => DatasetParseError.make({
|
|
63
|
+
path,
|
|
64
|
+
line: index + 1,
|
|
65
|
+
message: `Malformed JSONL record at ${path}:${index + 1}`
|
|
66
|
+
}))));
|
|
67
|
+
});
|
|
68
|
+
export const readDataset = (files, path) => readJsonLines(files, path, LabelledItem);
|
|
69
|
+
export const readPending = (files, path) => readJsonLines(files, path, PendingItem);
|
|
70
|
+
const encodeLines = Effect.fn("JudgmentDataset.encodeLines")(function* (path, schema, items) {
|
|
71
|
+
const lines = yield* Effect.forEach(items, (item, index) => Schema.encodeEffect(Schema.fromJsonString(schema))(item).pipe(Effect.mapError(() => DatasetParseError.make({
|
|
72
|
+
path,
|
|
73
|
+
line: index + 1,
|
|
74
|
+
message: `Invalid record for ${path}:${index + 1}`
|
|
75
|
+
}))));
|
|
76
|
+
return lines.length === 0 ? "" : `${lines.join("\n")}\n`;
|
|
77
|
+
});
|
|
78
|
+
export const appendDataset = Effect.fn("JudgmentDataset.appendDataset")(function* (files, path, items) {
|
|
79
|
+
yield* readDataset(files, path);
|
|
80
|
+
const encoded = yield* encodeLines(path, LabelledItem, items);
|
|
81
|
+
if (encoded === "")
|
|
82
|
+
return;
|
|
83
|
+
const previous = yield* files.read(path);
|
|
84
|
+
yield* files.append(path, `${previous && !previous.endsWith("\n") ? "\n" : ""}${encoded}`);
|
|
85
|
+
});
|
|
86
|
+
export const writePending = Effect.fn("JudgmentDataset.writePending")(function* (files, path, items) {
|
|
87
|
+
const encoded = yield* encodeLines(path, PendingItem, items);
|
|
88
|
+
yield* files.writeAtomic(path, encoded);
|
|
89
|
+
});
|
|
90
|
+
/** Escaping keeps source components unambiguous without a runtime-specific hash dependency. */
|
|
91
|
+
export const candidateId = (decision, source) => `${decision}:${encodeURIComponent(source)}`;
|
|
92
|
+
export const reviewCandidates = (commits, lenses) => commits.flatMap((commit) => lenses.map((lens) => {
|
|
93
|
+
const source = `commit:${commit.sha}:${lens.name}`;
|
|
94
|
+
return PendingItem.make({
|
|
95
|
+
id: candidateId("review-prescreen", source),
|
|
96
|
+
decision: "review-prescreen",
|
|
97
|
+
state: { diff: commit.diff },
|
|
98
|
+
question: truth(lens.screeningStatement),
|
|
99
|
+
source
|
|
100
|
+
});
|
|
101
|
+
}));
|
|
102
|
+
/** Line position distinguishes repeated observations within a run, even at the same timestamp. */
|
|
103
|
+
export const observationCandidates = Effect.fn("JudgmentDataset.observationCandidates")(function* (decision, observations) {
|
|
104
|
+
return yield* Effect.forEach(observations
|
|
105
|
+
.map((observation, index) => ({ observation, index }))
|
|
106
|
+
.filter(({ observation }) => observation.consumer === decision), ({ observation, index }) => {
|
|
107
|
+
const source = `observation:${encodeURIComponent(observation.runId)}:${observation.consumer}:${encodeURIComponent(observation.key)}:${observation.at}:${index + 1}`;
|
|
108
|
+
return Schema.decodeUnknownEffect(PendingItem)({
|
|
109
|
+
id: candidateId(decision, source),
|
|
110
|
+
decision,
|
|
111
|
+
state: observation.state,
|
|
112
|
+
question: observation.question,
|
|
113
|
+
source
|
|
114
|
+
}).pipe(Effect.mapError(() => DatasetParseError.make({
|
|
115
|
+
path: source,
|
|
116
|
+
line: index + 1,
|
|
117
|
+
message: `Question kind does not match decision ${decision} at ${source}`
|
|
118
|
+
})));
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
/** Existing human edits win; duplicates in the incoming batch are skipped too. */
|
|
122
|
+
export const mergeCandidates = (pending, dataset, candidates) => {
|
|
123
|
+
const seen = new Set([...pending, ...dataset].map((item) => item.id));
|
|
124
|
+
return [
|
|
125
|
+
...pending,
|
|
126
|
+
...candidates.filter((item) => {
|
|
127
|
+
if (seen.has(item.id))
|
|
128
|
+
return false;
|
|
129
|
+
seen.add(item.id);
|
|
130
|
+
return true;
|
|
131
|
+
})
|
|
132
|
+
];
|
|
133
|
+
};
|
|
134
|
+
export const isLabelledPending = (item) => Schema.is(LabelledRecord)(item);
|
|
135
|
+
/**
|
|
136
|
+
* Validate the whole batch before any writes. An item nobody has labelled yet
|
|
137
|
+
* (label absent or null) simply stays pending, so labelling can proceed in
|
|
138
|
+
* batches; a label that is present but of the wrong kind or out of range
|
|
139
|
+
* refuses the whole promotion, naming the ids. Complete labels with
|
|
140
|
+
* incomplete attribution stay pending too.
|
|
141
|
+
*/
|
|
142
|
+
export const preparePromotion = Effect.fn("JudgmentDataset.preparePromotion")(function* (pending, dataset) {
|
|
143
|
+
const ids = pending
|
|
144
|
+
.filter((item) => item.label !== undefined && item.label !== null && !validLabel(item.question, item.label))
|
|
145
|
+
.map((item) => item.id);
|
|
146
|
+
if (ids.length > 0)
|
|
147
|
+
return yield* PromotionRefused.make({
|
|
148
|
+
ids,
|
|
149
|
+
message: `Refusing promotion: missing or invalid labels for ids: ${ids.join(", ")}`
|
|
150
|
+
});
|
|
151
|
+
const ready = pending.filter(isLabelledPending);
|
|
152
|
+
const labelled = yield* Effect.forEach(ready, (item) => Schema.decodeUnknownEffect(LabelledItem)(item));
|
|
153
|
+
const existing = new Set(dataset.map((item) => item.id));
|
|
154
|
+
return {
|
|
155
|
+
items: labelled.filter((item) => {
|
|
156
|
+
if (existing.has(item.id))
|
|
157
|
+
return false;
|
|
158
|
+
existing.add(item.id);
|
|
159
|
+
return true;
|
|
160
|
+
}),
|
|
161
|
+
remaining: pending.filter((item) => !isLabelledPending(item))
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
//# sourceMappingURL=JudgmentDataset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JudgmentDataset.js","sourceRoot":"","sources":["../src/JudgmentDataset.ts"],"names":[],"mappings":"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"}
|