@zephyrdeng/pi-review 0.15.0 → 0.15.2
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 +22 -4
- package/README.zh-CN.md +22 -5
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +22 -0
- package/dist/args.js.map +1 -1
- package/dist/child-isolation.test.js +4 -1
- package/dist/child-isolation.test.js.map +1 -1
- package/dist/classify.d.ts +36 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +173 -0
- package/dist/classify.js.map +1 -0
- package/dist/classify.test.d.ts +2 -0
- package/dist/classify.test.d.ts.map +1 -0
- package/dist/classify.test.js +93 -0
- package/dist/classify.test.js.map +1 -0
- package/dist/cli-exit.test.js +8 -0
- package/dist/cli-exit.test.js.map +1 -1
- package/dist/cli.js +34 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/jev.d.ts +117 -0
- package/dist/jev.d.ts.map +1 -0
- package/dist/jev.js +294 -0
- package/dist/jev.js.map +1 -0
- package/dist/jev.test.d.ts +2 -0
- package/dist/jev.test.d.ts.map +1 -0
- package/dist/jev.test.js +206 -0
- package/dist/jev.test.js.map +1 -0
- package/dist/loop.d.ts +18 -1
- package/dist/loop.d.ts.map +1 -1
- package/dist/loop.js +39 -0
- package/dist/loop.js.map +1 -1
- package/dist/loop.test.js +36 -0
- package/dist/loop.test.js.map +1 -1
- package/dist/matcher.d.ts +16 -3
- package/dist/matcher.d.ts.map +1 -1
- package/dist/matcher.js +31 -12
- package/dist/matcher.js.map +1 -1
- package/dist/matcher.test.js +30 -6
- package/dist/matcher.test.js.map +1 -1
- package/dist/meta-footer.d.ts.map +1 -1
- package/dist/meta-footer.js +6 -2
- package/dist/meta-footer.js.map +1 -1
- package/dist/panel-cli.test.js +145 -3
- package/dist/panel-cli.test.js.map +1 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +48 -4
- package/dist/panel.js.map +1 -1
- package/dist/pi-config.d.ts +7 -0
- package/dist/pi-config.d.ts.map +1 -1
- package/dist/pi-config.js +15 -1
- package/dist/pi-config.js.map +1 -1
- package/dist/pi-config.test.js +6 -0
- package/dist/pi-config.test.js.map +1 -1
- package/dist/round-compare.d.ts +23 -0
- package/dist/round-compare.d.ts.map +1 -0
- package/dist/round-compare.js +45 -0
- package/dist/round-compare.js.map +1 -0
- package/dist/round-compare.test.d.ts +2 -0
- package/dist/round-compare.test.d.ts.map +1 -0
- package/dist/round-compare.test.js +63 -0
- package/dist/round-compare.test.js.map +1 -0
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/extensions/rv-config.test.ts +10 -0
- package/extensions/rv-config.ts +23 -0
- package/package.json +1 -1
- package/resources/providers/orcarouter.json +7 -4
- package/resources/providers/orcarouter.toml +11 -0
- package/skills/pi-review/SKILL.md +14 -1
- package/dist/extensions/review.d.ts +0 -2
- package/dist/extensions/review.js +0 -22
- package/dist/extensions/rv-prompts.d.ts +0 -19
- package/dist/extensions/rv-prompts.js +0 -132
package/dist/jev.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// Jev (TypeSafe System One) typed-decision backend — enhancement mode.
|
|
2
|
+
//
|
|
3
|
+
// pi-review keeps generation with the big models: reviewers produce findings,
|
|
4
|
+
// evidence, and prose. The typed micro-decisions that used to require a whole
|
|
5
|
+
// review-only Pi child session route to Jev instead. Today that is panel
|
|
6
|
+
// consensus adjudication: deciding which same-path findings describe the same
|
|
7
|
+
// underlying issue. Jev never sees the repository — only the structured
|
|
8
|
+
// candidate findings the deterministic matcher could not separate — and its
|
|
9
|
+
// probabilities flow through the same confidence threshold the LLM
|
|
10
|
+
// adjudicator's merges used (SemanticMatcher re-validates every merge).
|
|
11
|
+
export const DEFAULT_JEV_BASE_URL = "https://api.typesafe.ai";
|
|
12
|
+
export const DEFAULT_JEV_MODEL = "jev-latest";
|
|
13
|
+
export const JEV_TIMEOUT_MS = 15_000;
|
|
14
|
+
/** True when a TypeSafe API key is available in the environment. */
|
|
15
|
+
export function hasJevApiKey(env = process.env) {
|
|
16
|
+
return Boolean(env.TYPESAFE_API_KEY?.trim());
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Enhancement mode resolution, mirroring resolveChildExtensions:
|
|
20
|
+
* PI_REVIEW_JEV (1/true/on enable, any other set value disables) overrides the
|
|
21
|
+
* config file `jev` key, which overrides the default of "on when
|
|
22
|
+
* TYPESAFE_API_KEY is present".
|
|
23
|
+
*/
|
|
24
|
+
export function resolveJev(env, cfg) {
|
|
25
|
+
const raw = env.PI_REVIEW_JEV?.trim().toLowerCase();
|
|
26
|
+
if (raw === "1" || raw === "true" || raw === "on")
|
|
27
|
+
return { enabled: true, source: "env" };
|
|
28
|
+
if (raw !== undefined && raw !== "")
|
|
29
|
+
return { enabled: false, source: "env" };
|
|
30
|
+
if (cfg.jev !== undefined)
|
|
31
|
+
return { enabled: cfg.jev, source: "config" };
|
|
32
|
+
return { enabled: hasJevApiKey(env), source: "default" };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolve connection parameters, or undefined when no key is configured.
|
|
36
|
+
* The key comes from TYPESAFE_API_KEY only; it is never logged or persisted.
|
|
37
|
+
* TYPESAFE_BASE_URL allows pointing at a compatible endpoint (e.g. an
|
|
38
|
+
* openjev-style local server), PI_REVIEW_JEV_MODEL pins the model id.
|
|
39
|
+
*/
|
|
40
|
+
export function resolveJevConnection(env = process.env) {
|
|
41
|
+
const apiKey = env.TYPESAFE_API_KEY?.trim();
|
|
42
|
+
if (!apiKey)
|
|
43
|
+
return undefined;
|
|
44
|
+
return {
|
|
45
|
+
apiKey,
|
|
46
|
+
baseUrl: env.TYPESAFE_BASE_URL?.trim() || DEFAULT_JEV_BASE_URL,
|
|
47
|
+
model: env.PI_REVIEW_JEV_MODEL?.trim() || DEFAULT_JEV_MODEL,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export class JevError extends Error {
|
|
51
|
+
constructor(message) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = "JevError";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const NOUL_CRITERIA = {
|
|
57
|
+
true: "Both findings describe the same underlying issue (same root cause), even if worded differently.",
|
|
58
|
+
false: "The findings are distinct issues, or merely share a file or symptom category.",
|
|
59
|
+
};
|
|
60
|
+
/** Shared transport: one POST to /v1/systemone with the given typed questions. */
|
|
61
|
+
async function callSystemOne(connection, state, questionBody, fetchImpl) {
|
|
62
|
+
let response;
|
|
63
|
+
try {
|
|
64
|
+
response = await fetchImpl(`${connection.baseUrl}/v1/systemone`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: {
|
|
67
|
+
authorization: `Bearer ${connection.apiKey}`,
|
|
68
|
+
"content-type": "application/json",
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify({ model: connection.model, state, questions: questionBody }),
|
|
71
|
+
signal: AbortSignal.timeout(JEV_TIMEOUT_MS),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw new JevError(`typesafe api request failed: ${error.message}`);
|
|
76
|
+
}
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new JevError(`typesafe api http ${response.status}`);
|
|
79
|
+
}
|
|
80
|
+
let body;
|
|
81
|
+
try {
|
|
82
|
+
body = await response.json();
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new JevError("typesafe api returned non-JSON body");
|
|
86
|
+
}
|
|
87
|
+
const record = body;
|
|
88
|
+
const answers = record.answers;
|
|
89
|
+
if (!answers || typeof answers !== "object" || Array.isArray(answers)) {
|
|
90
|
+
throw new JevError("typesafe api response is missing the answers object");
|
|
91
|
+
}
|
|
92
|
+
const usageRaw = record.usage;
|
|
93
|
+
const usage = usageRaw && typeof usageRaw.input_tokens === "number"
|
|
94
|
+
? { inputTokens: usageRaw.input_tokens, outputTokens: typeof usageRaw.output_tokens === "number" ? usageRaw.output_tokens : 0 }
|
|
95
|
+
: undefined;
|
|
96
|
+
return {
|
|
97
|
+
answers: answers,
|
|
98
|
+
...(usage ? { usage } : {}),
|
|
99
|
+
...(typeof record.model === "string" ? { model: record.model } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* One System One call fanning out every Noul question in parallel. Throws
|
|
104
|
+
* JevError on transport, HTTP, or envelope-level failures; individual missing
|
|
105
|
+
* answers are reported in `missing` instead (treated as "no" by callers).
|
|
106
|
+
*/
|
|
107
|
+
export async function evaluateNouls(connection, state, questions, fetchImpl = fetch) {
|
|
108
|
+
const questionBody = Object.fromEntries(Object.entries(questions).map(([id, instructions]) => [
|
|
109
|
+
id,
|
|
110
|
+
{ type: "noul", instructions, criteria: { ...NOUL_CRITERIA } },
|
|
111
|
+
]));
|
|
112
|
+
const envelope = await callSystemOne(connection, state, questionBody, fetchImpl);
|
|
113
|
+
const probabilities = {};
|
|
114
|
+
const missing = [];
|
|
115
|
+
for (const id of Object.keys(questions)) {
|
|
116
|
+
const answer = envelope.answers[id];
|
|
117
|
+
const noul = answer?.noul;
|
|
118
|
+
if (answer?.type === "noul" && typeof noul === "number" && Number.isFinite(noul) && noul >= 0 && noul <= 1) {
|
|
119
|
+
probabilities[id] = noul;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
missing.push(id);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
probabilities,
|
|
127
|
+
missing,
|
|
128
|
+
...(envelope.usage ? { usage: envelope.usage } : {}),
|
|
129
|
+
...(envelope.model ? { model: envelope.model } : {}),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* One System One call fanning out Choice questions. `criteria` maps each
|
|
134
|
+
* option id to its plain-language description; an explicit escape option
|
|
135
|
+
* (e.g. "other") belongs in the caller's criteria, per the Jev docs' advice.
|
|
136
|
+
*/
|
|
137
|
+
export async function evaluateChoices(connection, state, questions, fetchImpl = fetch) {
|
|
138
|
+
const questionBody = Object.fromEntries(Object.entries(questions).map(([id, question]) => [
|
|
139
|
+
id,
|
|
140
|
+
{ type: "choice", instructions: question.instructions, criteria: question.criteria },
|
|
141
|
+
]));
|
|
142
|
+
const envelope = await callSystemOne(connection, state, questionBody, fetchImpl);
|
|
143
|
+
const answers = {};
|
|
144
|
+
const missing = [];
|
|
145
|
+
for (const id of Object.keys(questions)) {
|
|
146
|
+
const answer = envelope.answers[id];
|
|
147
|
+
const choice = answer?.choice;
|
|
148
|
+
const confidence = answer?.confidence;
|
|
149
|
+
if (answer?.type === "choice" &&
|
|
150
|
+
typeof choice === "string" &&
|
|
151
|
+
// own-property check: `in` walks the prototype chain, so "constructor" /
|
|
152
|
+
// "__proto__" would pass validation and crash the downstream bucket map.
|
|
153
|
+
Object.hasOwn(questions[id].criteria, choice) &&
|
|
154
|
+
typeof confidence === "number" &&
|
|
155
|
+
Number.isFinite(confidence) &&
|
|
156
|
+
confidence >= 0 &&
|
|
157
|
+
confidence <= 1) {
|
|
158
|
+
answers[id] = { choice, confidence };
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
missing.push(id);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
answers,
|
|
166
|
+
missing,
|
|
167
|
+
...(envelope.usage ? { usage: envelope.usage } : {}),
|
|
168
|
+
...(envelope.model ? { model: envelope.model } : {}),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Jev-backed SemanticAdjudicator. Every unordered finding pair inside a
|
|
173
|
+
* candidate group becomes one Noul question; all pairs across all groups go
|
|
174
|
+
* out in a single System One call. Each pair above the no-merge floor becomes
|
|
175
|
+
* a proposed merge whose confidence is the pair probability — the matcher's
|
|
176
|
+
* union-find and SEMANTIC_MATCH_CONFIDENCE_THRESHOLD stay the single policy
|
|
177
|
+
* point, and its provenance validation re-checks every id we emit.
|
|
178
|
+
*/
|
|
179
|
+
export function createJevAdjudicator(connection, options = {}) {
|
|
180
|
+
return {
|
|
181
|
+
async adjudicate(request) {
|
|
182
|
+
const questions = {};
|
|
183
|
+
// question id -> [aId, bId]; pairs never span candidate groups, so no
|
|
184
|
+
// merge can cross a path anchor by construction.
|
|
185
|
+
const pairs = new Map();
|
|
186
|
+
request.candidates.forEach((candidate, groupIndex) => {
|
|
187
|
+
const findings = candidate.findings;
|
|
188
|
+
for (let i = 0; i < findings.length; i += 1) {
|
|
189
|
+
for (let j = i + 1; j < findings.length; j += 1) {
|
|
190
|
+
const a = findings[i];
|
|
191
|
+
const b = findings[j];
|
|
192
|
+
const id = `g${groupIndex}p${i}_${j}`;
|
|
193
|
+
questions[id] =
|
|
194
|
+
`Do findings ${a.id} and ${b.id} describe the same underlying issue? ` +
|
|
195
|
+
"Merge only when they share a root cause, not when they merely mention the same file or symptom category.";
|
|
196
|
+
pairs.set(id, [a.id, b.id]);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (pairs.size === 0)
|
|
201
|
+
return { merges: [] };
|
|
202
|
+
const state = {
|
|
203
|
+
candidates: request.candidates.map((candidate) => ({
|
|
204
|
+
anchorPath: candidate.anchorPath,
|
|
205
|
+
findings: candidate.findings.map((sf) => ({
|
|
206
|
+
id: sf.id,
|
|
207
|
+
reviewer: sf.reviewerId,
|
|
208
|
+
path: sf.finding.path ?? null,
|
|
209
|
+
summary: sf.finding.summary,
|
|
210
|
+
actionable: sf.finding.actionable,
|
|
211
|
+
})),
|
|
212
|
+
})),
|
|
213
|
+
};
|
|
214
|
+
const result = await evaluateNouls(connection, state, questions, options.fetchImpl);
|
|
215
|
+
const merges = [];
|
|
216
|
+
for (const [questionId, [aId, bId]] of pairs) {
|
|
217
|
+
const probability = result.probabilities[questionId];
|
|
218
|
+
if (probability === undefined)
|
|
219
|
+
continue; // missing answer: conservative no-merge
|
|
220
|
+
merges.push({ sourceFindingIds: [aId, bId], confidence: probability });
|
|
221
|
+
}
|
|
222
|
+
return { merges };
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Borderline band: Jev probabilities inside [low, high] are too close to the
|
|
228
|
+
* matcher's 0.6 merge threshold to trust blindly — a small calibration slip
|
|
229
|
+
* flips the decision. Those pairs get re-judged by the Pi adjudicator.
|
|
230
|
+
*/
|
|
231
|
+
export const JEV_ESCALATION_BAND = { low: 0.3, high: 0.7 };
|
|
232
|
+
function pairKey(ids) {
|
|
233
|
+
return [...ids].sort().join("\u0000");
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Cascade wrapper: run the fast Jev tier over every pair, then re-judge only
|
|
237
|
+
* the borderline band with the strong (Pi) tier in a single extra call.
|
|
238
|
+
* Clear cases never pay for an LLM; uncertain cases get a second opinion.
|
|
239
|
+
* A strong-tier failure keeps the fast tier's judgments — escalation is an
|
|
240
|
+
* accuracy upgrade, never a new failure mode.
|
|
241
|
+
*/
|
|
242
|
+
export function withUncertaintyEscalation(fast, strong, onEscalation) {
|
|
243
|
+
return {
|
|
244
|
+
async adjudicate(request) {
|
|
245
|
+
const response = await fast.adjudicate(request);
|
|
246
|
+
const borderline = response.merges.filter((merge) => merge.confidence >= JEV_ESCALATION_BAND.low && merge.confidence <= JEV_ESCALATION_BAND.high);
|
|
247
|
+
if (borderline.length === 0)
|
|
248
|
+
return response;
|
|
249
|
+
const escalatedIds = new Set(borderline.flatMap((merge) => merge.sourceFindingIds));
|
|
250
|
+
// Pairs never span candidate groups by construction, so filtering each
|
|
251
|
+
// group to the escalated findings preserves the no-cross-anchor rule.
|
|
252
|
+
const subCandidates = request.candidates
|
|
253
|
+
.map((candidate) => ({ ...candidate, findings: candidate.findings.filter((sf) => escalatedIds.has(sf.id)) }))
|
|
254
|
+
.filter((candidate) => candidate.findings.length > 0);
|
|
255
|
+
try {
|
|
256
|
+
const strongResponse = await strong.adjudicate({ candidates: subCandidates });
|
|
257
|
+
const replaced = new Set(borderline.map((merge) => pairKey(merge.sourceFindingIds)));
|
|
258
|
+
const kept = response.merges.filter((merge) => !replaced.has(pairKey(merge.sourceFindingIds)));
|
|
259
|
+
onEscalation?.(`escalated ${borderline.length} borderline pair(s) (probability ${JEV_ESCALATION_BAND.low}-${JEV_ESCALATION_BAND.high}) to the Pi adjudicator`);
|
|
260
|
+
return { merges: [...kept, ...strongResponse.merges] };
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return response;
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Enhancement wrapper: try the Jev adjudicator first; on any failure degrade
|
|
270
|
+
* to the Pi adjudicator so a Jev outage can never make a panel worse than the
|
|
271
|
+
* pre-Jev behavior. The engine/note getters settle after adjudication ran.
|
|
272
|
+
*/
|
|
273
|
+
export function withAdjudicationFallback(primary, fallback, onFallback) {
|
|
274
|
+
let engine = "jev";
|
|
275
|
+
let note;
|
|
276
|
+
return {
|
|
277
|
+
engine: () => engine,
|
|
278
|
+
note: () => note,
|
|
279
|
+
adjudicator: {
|
|
280
|
+
async adjudicate(request) {
|
|
281
|
+
try {
|
|
282
|
+
return await primary.adjudicate(request);
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
engine = "pi";
|
|
286
|
+
note = `jev adjudication failed (${error.message}); fell back to the Pi adjudicator`;
|
|
287
|
+
onFallback?.(note);
|
|
288
|
+
return fallback.adjudicate(request);
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=jev.js.map
|
package/dist/jev.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jev.js","sourceRoot":"","sources":["../src/jev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jev.test.d.ts","sourceRoot":"","sources":["../src/jev.test.ts"],"names":[],"mappings":""}
|
package/dist/jev.test.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
import { createJevAdjudicator, evaluateNouls, hasJevApiKey, resolveJev, resolveJevConnection, withAdjudicationFallback, withUncertaintyEscalation, JevError, } from "./jev.js";
|
|
4
|
+
const CONN = { apiKey: "test-key", baseUrl: "https://example.test", model: "jev-test" };
|
|
5
|
+
function env(overrides) {
|
|
6
|
+
return { ...overrides };
|
|
7
|
+
}
|
|
8
|
+
test("hasJevApiKey requires a non-blank TYPESAFE_API_KEY", () => {
|
|
9
|
+
assert.equal(hasJevApiKey(env({})), false);
|
|
10
|
+
assert.equal(hasJevApiKey(env({ TYPESAFE_API_KEY: " " })), false);
|
|
11
|
+
assert.equal(hasJevApiKey(env({ TYPESAFE_API_KEY: "sk-x" })), true);
|
|
12
|
+
});
|
|
13
|
+
test("resolveJev: env truthy overrides config and default", () => {
|
|
14
|
+
assert.deepEqual(resolveJev(env({ PI_REVIEW_JEV: "1" }), {}), { enabled: true, source: "env" });
|
|
15
|
+
assert.deepEqual(resolveJev(env({ PI_REVIEW_JEV: "true" }), { jev: false }), { enabled: true, source: "env" });
|
|
16
|
+
assert.deepEqual(resolveJev(env({ PI_REVIEW_JEV: "on" }), {}), { enabled: true, source: "env" });
|
|
17
|
+
});
|
|
18
|
+
test("resolveJev: any other set env value disables", () => {
|
|
19
|
+
assert.deepEqual(resolveJev(env({ PI_REVIEW_JEV: "0", TYPESAFE_API_KEY: "sk-x" }), {}), { enabled: false, source: "env" });
|
|
20
|
+
assert.deepEqual(resolveJev(env({ PI_REVIEW_JEV: "off" }), { jev: true }), { enabled: false, source: "env" });
|
|
21
|
+
});
|
|
22
|
+
test("resolveJev: config beats the key-presence default", () => {
|
|
23
|
+
assert.deepEqual(resolveJev(env({ TYPESAFE_API_KEY: "sk-x" }), { jev: false }), { enabled: false, source: "config" });
|
|
24
|
+
assert.deepEqual(resolveJev(env({}), { jev: true }), { enabled: true, source: "config" });
|
|
25
|
+
});
|
|
26
|
+
test("resolveJev: default follows key presence (enhancement mode)", () => {
|
|
27
|
+
assert.deepEqual(resolveJev(env({ TYPESAFE_API_KEY: "sk-x" }), {}), { enabled: true, source: "default" });
|
|
28
|
+
assert.deepEqual(resolveJev(env({}), {}), { enabled: false, source: "default" });
|
|
29
|
+
});
|
|
30
|
+
test("resolveJevConnection honors overrides and never logs the key", () => {
|
|
31
|
+
assert.equal(resolveJevConnection(env({})), undefined);
|
|
32
|
+
const conn = resolveJevConnection(env({ TYPESAFE_API_KEY: "sk-secret" }));
|
|
33
|
+
assert.equal(conn.baseUrl, "https://api.typesafe.ai");
|
|
34
|
+
assert.equal(conn.model, "jev-latest");
|
|
35
|
+
const custom = resolveJevConnection(env({ TYPESAFE_API_KEY: "sk", TYPESAFE_BASE_URL: "http://127.0.0.1:8787", PI_REVIEW_JEV_MODEL: "jev-1.13.0" }));
|
|
36
|
+
assert.equal(custom.baseUrl, "http://127.0.0.1:8787");
|
|
37
|
+
assert.equal(custom.model, "jev-1.13.0");
|
|
38
|
+
});
|
|
39
|
+
function mockFetch(status, body) {
|
|
40
|
+
return (async () => ({
|
|
41
|
+
ok: status >= 200 && status < 300,
|
|
42
|
+
status,
|
|
43
|
+
json: async () => body,
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
test("evaluateNouls sends one fan-out call and maps answers to probabilities", async () => {
|
|
47
|
+
let sentBody;
|
|
48
|
+
let sentAuth = "";
|
|
49
|
+
const fetchImpl = (async (_url, init) => {
|
|
50
|
+
sentBody = JSON.parse(init.body);
|
|
51
|
+
sentAuth = init.headers.authorization;
|
|
52
|
+
return {
|
|
53
|
+
ok: true,
|
|
54
|
+
status: 200,
|
|
55
|
+
json: async () => ({
|
|
56
|
+
model: "jev-1.13.0",
|
|
57
|
+
answers: { q1: { type: "noul", noul: 0.91 }, q2: { type: "noul", noul: 0.12 } },
|
|
58
|
+
usage: { input_tokens: 100, output_tokens: 8 },
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
const result = await evaluateNouls(CONN, { x: 1 }, { q1: "same?", q2: "same?" }, fetchImpl);
|
|
63
|
+
assert.equal(sentAuth, "Bearer test-key");
|
|
64
|
+
assert.equal(sentBody.model, "jev-test");
|
|
65
|
+
const questions = sentBody.questions;
|
|
66
|
+
assert.equal(questions.q1.type, "noul");
|
|
67
|
+
assert.equal(questions.q2.type, "noul");
|
|
68
|
+
assert.deepEqual(result.probabilities, { q1: 0.91, q2: 0.12 });
|
|
69
|
+
assert.deepEqual(result.missing, []);
|
|
70
|
+
assert.deepEqual(result.usage, { inputTokens: 100, outputTokens: 8 });
|
|
71
|
+
assert.equal(result.model, "jev-1.13.0");
|
|
72
|
+
});
|
|
73
|
+
test("evaluateNouls reports missing/malformed answers without failing the call", async () => {
|
|
74
|
+
const fetchImpl = mockFetch(200, { answers: { q1: { type: "noul", noul: 2 }, q3: { type: "noul", noul: 0.5 } } });
|
|
75
|
+
const result = await evaluateNouls(CONN, {}, { q1: "a", q2: "b", q3: "c" }, fetchImpl);
|
|
76
|
+
assert.deepEqual(result.probabilities, { q3: 0.5 });
|
|
77
|
+
assert.deepEqual(result.missing.sort(), ["q1", "q2"]);
|
|
78
|
+
});
|
|
79
|
+
test("evaluateNouls throws JevError on http failure and missing answers object", async () => {
|
|
80
|
+
await assert.rejects(evaluateNouls(CONN, {}, { q: "x" }, mockFetch(429, {})), JevError);
|
|
81
|
+
await assert.rejects(evaluateNouls(CONN, {}, { q: "x" }, mockFetch(200, { nope: 1 })), JevError);
|
|
82
|
+
const boom = (async () => { throw new Error("socket hangup"); });
|
|
83
|
+
await assert.rejects(evaluateNouls(CONN, {}, { q: "x" }, boom), /socket hangup/);
|
|
84
|
+
});
|
|
85
|
+
function candidate(anchorPath, ids) {
|
|
86
|
+
return {
|
|
87
|
+
anchorPath,
|
|
88
|
+
findings: ids.map((id) => ({
|
|
89
|
+
id,
|
|
90
|
+
reviewerId: id.split("#")[0],
|
|
91
|
+
finding: { summary: `summary for ${id}`, actionable: true, path: anchorPath },
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
test("createJevAdjudicator turns pair probabilities into per-pair merges", async () => {
|
|
96
|
+
const fetchImpl = (async (_url, init) => {
|
|
97
|
+
const body = JSON.parse(init.body);
|
|
98
|
+
const answers = {};
|
|
99
|
+
for (const id of Object.keys(body.questions))
|
|
100
|
+
answers[id] = { type: "noul", noul: 0.9 };
|
|
101
|
+
return { ok: true, status: 200, json: async () => ({ answers }) };
|
|
102
|
+
});
|
|
103
|
+
const adjudicator = createJevAdjudicator(CONN, { fetchImpl });
|
|
104
|
+
const response = await adjudicator.adjudicate({
|
|
105
|
+
candidates: [candidate("src/a.ts", ["r1#F1", "r2#F1", "r2#F2"])],
|
|
106
|
+
});
|
|
107
|
+
// 3 findings in one group => 3 pair questions, all merged with confidence = probability.
|
|
108
|
+
assert.equal(response.merges.length, 3);
|
|
109
|
+
assert.ok(response.merges.every((m) => m.confidence === 0.9));
|
|
110
|
+
assert.deepEqual(response.errors ?? [], []);
|
|
111
|
+
});
|
|
112
|
+
test("createJevAdjudicator: empty candidates short-circuit without a fetch", async () => {
|
|
113
|
+
let called = false;
|
|
114
|
+
const fetchImpl = (async () => { called = true; throw new Error("should not be called"); });
|
|
115
|
+
const adjudicator = createJevAdjudicator(CONN, { fetchImpl });
|
|
116
|
+
const response = await adjudicator.adjudicate({ candidates: [] });
|
|
117
|
+
assert.deepEqual(response, { merges: [] });
|
|
118
|
+
assert.equal(called, false);
|
|
119
|
+
});
|
|
120
|
+
test("createJevAdjudicator omits pairs whose answers are missing (conservative no-merge)", async () => {
|
|
121
|
+
const fetchImpl = mockFetch(200, { answers: { g0p0_1: { type: "noul", noul: 0.8 } } });
|
|
122
|
+
const adjudicator = createJevAdjudicator(CONN, { fetchImpl });
|
|
123
|
+
const response = await adjudicator.adjudicate({ candidates: [candidate("src/a.ts", ["r1#F1", "r2#F1"])] });
|
|
124
|
+
assert.equal(response.merges.length, 1);
|
|
125
|
+
assert.deepEqual(response.merges[0], { sourceFindingIds: ["r1#F1", "r2#F1"], confidence: 0.8 });
|
|
126
|
+
});
|
|
127
|
+
test("withAdjudicationFallback delegates and reports the engine switch", async () => {
|
|
128
|
+
const calls = [];
|
|
129
|
+
const primary = {
|
|
130
|
+
async adjudicate() { throw new JevError("http 500"); },
|
|
131
|
+
};
|
|
132
|
+
const fallback = {
|
|
133
|
+
async adjudicate() { calls.push("fallback"); return { merges: [] }; },
|
|
134
|
+
};
|
|
135
|
+
const notes = [];
|
|
136
|
+
const wrapped = withAdjudicationFallback(primary, fallback, (m) => notes.push(m));
|
|
137
|
+
assert.equal(wrapped.engine(), "jev");
|
|
138
|
+
const response = await wrapped.adjudicator.adjudicate({ candidates: [] });
|
|
139
|
+
assert.deepEqual(response, { merges: [] });
|
|
140
|
+
assert.deepEqual(calls, ["fallback"]);
|
|
141
|
+
assert.equal(wrapped.engine(), "pi");
|
|
142
|
+
assert.match(wrapped.note(), /jev adjudication failed/);
|
|
143
|
+
assert.equal(notes.length, 1);
|
|
144
|
+
});
|
|
145
|
+
test("withAdjudicationFallback keeps jev engine when the primary succeeds", async () => {
|
|
146
|
+
const primary = { async adjudicate() { return { merges: [{ sourceFindingIds: ["a", "b"], confidence: 0.9 }] }; } };
|
|
147
|
+
const fallback = { async adjudicate() { throw new Error("must not run"); } };
|
|
148
|
+
const wrapped = withAdjudicationFallback(primary, fallback);
|
|
149
|
+
const response = await wrapped.adjudicator.adjudicate({ candidates: [] });
|
|
150
|
+
assert.equal(response.merges.length, 1);
|
|
151
|
+
assert.equal(wrapped.engine(), "jev");
|
|
152
|
+
assert.equal(wrapped.note(), undefined);
|
|
153
|
+
});
|
|
154
|
+
test("withUncertaintyEscalation re-judges only the borderline band with the strong tier", async () => {
|
|
155
|
+
const fast = {
|
|
156
|
+
async adjudicate() {
|
|
157
|
+
return {
|
|
158
|
+
merges: [
|
|
159
|
+
{ sourceFindingIds: ["a", "b"], confidence: 0.95 }, // clear merge — untouched
|
|
160
|
+
{ sourceFindingIds: ["c", "d"], confidence: 0.1 }, // clear distinct — untouched
|
|
161
|
+
{ sourceFindingIds: ["e", "f"], confidence: 0.55 }, // borderline — escalated
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
const strongCalls = [];
|
|
167
|
+
const strong = {
|
|
168
|
+
async adjudicate(request) {
|
|
169
|
+
strongCalls.push(request.candidates.flatMap((c) => c.findings.map((f) => f.id)));
|
|
170
|
+
return { merges: [{ sourceFindingIds: ["e", "f"], confidence: 0.9 }] };
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
let note;
|
|
174
|
+
const cascade = withUncertaintyEscalation(fast, strong, (m) => { note = m; });
|
|
175
|
+
const result = await cascade.adjudicate({
|
|
176
|
+
candidates: [{
|
|
177
|
+
anchorPath: "src/x.ts",
|
|
178
|
+
findings: ["a", "b", "c", "d", "e", "f"].map((id) => ({ id, reviewerId: "r1", finding: { summary: id, actionable: true } })),
|
|
179
|
+
}],
|
|
180
|
+
});
|
|
181
|
+
// Strong tier saw ONLY the borderline findings
|
|
182
|
+
assert.deepEqual(strongCalls, [["e", "f"]]);
|
|
183
|
+
// Clear merges pass through; the borderline pair is replaced by the strong verdict
|
|
184
|
+
assert.deepEqual(result.merges.map((m) => [m.sourceFindingIds, m.confidence]), [[["a", "b"], 0.95], [["c", "d"], 0.1], [["e", "f"], 0.9]]);
|
|
185
|
+
assert.match(note, /escalated 1 borderline pair/);
|
|
186
|
+
});
|
|
187
|
+
test("withUncertaintyEscalation keeps fast-tier judgments when the strong tier fails", async () => {
|
|
188
|
+
const fast = { async adjudicate() { return { merges: [{ sourceFindingIds: ["a", "b"], confidence: 0.5 }] }; } };
|
|
189
|
+
const strong = { async adjudicate() { throw new Error("pi down"); } };
|
|
190
|
+
const cascade = withUncertaintyEscalation(fast, strong);
|
|
191
|
+
const result = await cascade.adjudicate({
|
|
192
|
+
candidates: [{ anchorPath: "x", findings: [{ id: "a", reviewerId: "r1", finding: { summary: "a", actionable: true } }, { id: "b", reviewerId: "r2", finding: { summary: "b", actionable: true } }] }],
|
|
193
|
+
});
|
|
194
|
+
assert.deepEqual(result.merges, [{ sourceFindingIds: ["a", "b"], confidence: 0.5 }]);
|
|
195
|
+
});
|
|
196
|
+
test("withUncertaintyEscalation skips the strong tier when nothing is borderline", async () => {
|
|
197
|
+
const fast = { async adjudicate() { return { merges: [{ sourceFindingIds: ["a", "b"], confidence: 0.9 }] }; } };
|
|
198
|
+
let called = false;
|
|
199
|
+
const strong = { async adjudicate() { called = true; return { merges: [] }; } };
|
|
200
|
+
const cascade = withUncertaintyEscalation(fast, strong);
|
|
201
|
+
await cascade.adjudicate({
|
|
202
|
+
candidates: [{ anchorPath: "x", findings: [{ id: "a", reviewerId: "r1", finding: { summary: "a", actionable: true } }, { id: "b", reviewerId: "r2", finding: { summary: "b", actionable: true } }] }],
|
|
203
|
+
});
|
|
204
|
+
assert.equal(called, false);
|
|
205
|
+
});
|
|
206
|
+
//# sourceMappingURL=jev.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jev.test.js","sourceRoot":"","sources":["../src/jev.test.ts"],"names":[],"mappings":"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"}
|
package/dist/loop.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { type RoundComparison } from "./round-compare.js";
|
|
2
|
+
import type { FindingMatcher } from "./matcher.js";
|
|
1
3
|
import type { ReviewRunResult, ReviewStatus, Verdict } from "./types.js";
|
|
2
|
-
export type LoopStopReason = "clean" | "budget_exhausted" | "needs_human" | "blocked";
|
|
4
|
+
export type LoopStopReason = "clean" | "budget_exhausted" | "needs_human" | "blocked" | "non_converging";
|
|
3
5
|
export type LoopUntilGoal = "clean";
|
|
4
6
|
/**
|
|
5
7
|
* Product definition of the clean gate goal.
|
|
@@ -34,6 +36,12 @@ export interface LoopRoundSummary {
|
|
|
34
36
|
usage?: import("./types.js").TokenUsage;
|
|
35
37
|
/** Present when the round evaluated a panel. */
|
|
36
38
|
panel?: LoopRoundPanelSummary;
|
|
39
|
+
/**
|
|
40
|
+
* Cross-round comparison vs the previous round's actionable findings.
|
|
41
|
+
* Present from round 2 onward when a matcher was supplied and the previous
|
|
42
|
+
* round had actionable findings. Advisory bookkeeping; never gate input.
|
|
43
|
+
*/
|
|
44
|
+
comparison?: RoundComparison;
|
|
37
45
|
}
|
|
38
46
|
export interface LoopReviewResult {
|
|
39
47
|
rounds: LoopRoundSummary[];
|
|
@@ -50,6 +58,15 @@ export interface RunReviewLoopOptions {
|
|
|
50
58
|
maxRounds: number;
|
|
51
59
|
/** When set to clean, the loop's declared goal is the clean gate (still hard-capped by maxRounds). */
|
|
52
60
|
until?: LoopUntilGoal;
|
|
61
|
+
/**
|
|
62
|
+
* Matcher for cross-round finding comparison. When supplied, each round
|
|
63
|
+
* after the first is diffed against the previous round's actionable
|
|
64
|
+
* findings (persisting / added / resolved), and an until-clean loop stops
|
|
65
|
+
* early as non_converging once the actionable set is identical across two
|
|
66
|
+
* consecutive rounds — the tree does not change between rounds, so further
|
|
67
|
+
* rounds are dice rolls, not progress.
|
|
68
|
+
*/
|
|
69
|
+
matcher?: FindingMatcher;
|
|
53
70
|
}
|
|
54
71
|
export declare function formatLoopSummary(result: LoopReviewResult): string;
|
|
55
72
|
/**
|
package/dist/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../src/loop.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA+B,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEtG,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../src/loop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAA+B,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEtG,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,kBAAkB,GAAG,aAAa,GAAG,SAAS,GAAG,gBAAgB,CAAC;AACzG,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,eAAe;;IAE1B,2DAA2D;;IAG3D,0CAA0C;;CAUlC,CAAC;AAEX,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,YAAY,EAAE,UAAU,CAAC;IACxC,gDAAgD;IAChD,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,WAAW,EAAE,YAAY,CAAC;IAC1B,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,sGAAsG;IACtG,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAMD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA6BlE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,kBAAkB,EAAE,MAAM,GAAG,oBAAoB,EACjD,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAqG3B"}
|