@konneal/engine 0.2.30 → 0.2.32
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.
|
@@ -1456,25 +1456,34 @@ async function verifyRoute(c) {
|
|
|
1456
1456
|
try {
|
|
1457
1457
|
const u = await understandQuery(env.AI, roleModel(env, "understand"), query, [], []);
|
|
1458
1458
|
let lexicalBoost;
|
|
1459
|
-
let
|
|
1459
|
+
let editionSteer = null;
|
|
1460
1460
|
try {
|
|
1461
1461
|
const fam = u?.doc_number ? refCodec().familyOf(u.doc_number) : null;
|
|
1462
1462
|
if (fam) {
|
|
1463
1463
|
const row = await env.DB.prepare("SELECT edition FROM documents WHERE family = ?1 AND active = 1 ORDER BY edition DESC LIMIT 1").bind(fam).first().catch(() => null);
|
|
1464
1464
|
if (row?.edition) {
|
|
1465
1465
|
lexicalBoost = String(row.edition);
|
|
1466
|
-
|
|
1466
|
+
editionSteer = { doc_number: fam.split("-").pop() ?? "", edition: String(row.edition) };
|
|
1467
1467
|
}
|
|
1468
1468
|
}
|
|
1469
1469
|
} catch {
|
|
1470
1470
|
}
|
|
1471
1471
|
const bound = await bindModelNode(env, { query, standardKeys: entitlementScope(standardKeysFrom(body)) });
|
|
1472
1472
|
const modelGrounding = bound && !bound.gated ? modelGroundingBlock(bound) : null;
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1473
|
+
const supplied = (Array.isArray(body?.passages) ? body.passages : []).map((p) => typeof p === "string" ? p : p?.text ?? "").map((p) => p.trim()).filter(Boolean).slice(0, 8);
|
|
1474
|
+
let passages;
|
|
1475
|
+
let structured = [];
|
|
1476
|
+
if (supplied.length) {
|
|
1477
|
+
passages = supplied;
|
|
1478
|
+
structured = supplied.map((p) => ({ text: p }));
|
|
1479
|
+
} else {
|
|
1480
|
+
const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
|
|
1481
|
+
passages = retrieved.hits.map((h) => h.text);
|
|
1482
|
+
structured = retrieved.hits.map((h) => ({ text: h.text, table: h.metadata.block === "table" || void 0 }));
|
|
1483
|
+
}
|
|
1475
1484
|
const anchors = checkQuoteAnchors(answer, passages);
|
|
1476
1485
|
const refs = [...answer.matchAll(/\[\[u:([^\]]+)\]\]/g)].map((m) => m[1]);
|
|
1477
|
-
const validRefs = refs.filter((r) =>
|
|
1486
|
+
const validRefs = refs.filter((r) => supplied.length ? supplied.some((p) => p.includes(`u:${r}`)) : structured.some((h) => h.text && !h.table));
|
|
1478
1487
|
const checks = [
|
|
1479
1488
|
{ name: "quote_anchors", deterministic: true, pass: anchors.violations.length === 0, detail: `${anchors.violations.length} of ${anchors.total} quoted spans absent from the retrieved passages` },
|
|
1480
1489
|
{ name: "unit_references", deterministic: true, pass: refs.length === validRefs.length, detail: refs.length ? `${validRefs.length}/${refs.length} unit references resolve to served units` : "no unit references" },
|
|
@@ -1482,11 +1491,17 @@ async function verifyRoute(c) {
|
|
|
1482
1491
|
];
|
|
1483
1492
|
const machine = (Array.isArray(body?.blocks) ? body.blocks : []).filter((b) => b?.type === "verdict" && b?.payload).map((b) => [b.payload.check, b.payload.meaning, b.payload.definition, b.payload.violation_meaning].filter((x) => typeof x === "string" && x).join(" \u2014 ")).filter(Boolean);
|
|
1484
1493
|
if (modelGrounding) machine.unshift(modelGrounding);
|
|
1485
|
-
const faith = await scoreFaithfulness(
|
|
1494
|
+
const faith = await scoreFaithfulness(
|
|
1495
|
+
env.AI,
|
|
1496
|
+
roleModel(env, "grader"),
|
|
1497
|
+
answer,
|
|
1498
|
+
structured,
|
|
1499
|
+
machine
|
|
1500
|
+
);
|
|
1486
1501
|
return json({
|
|
1487
1502
|
checks,
|
|
1488
1503
|
judged: faith ? { name: "faithfulness", deterministic: false, score: faith.score, ungrounded_claims: faith.ungrounded_claims.slice(0, 5) } : null,
|
|
1489
|
-
passages_used:
|
|
1504
|
+
passages_used: passages.length
|
|
1490
1505
|
});
|
|
1491
1506
|
} catch (e) {
|
|
1492
1507
|
return err(502, "verify_failed", String(e).slice(0, 200));
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"playwright": "^1.62.1",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.2.
|
|
30
|
+
"version": "0.2.32",
|
|
31
31
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"type": "module",
|
|
@@ -234,7 +234,7 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
|
|
|
234
234
|
// grounding — a verify that grounds against different passages than
|
|
235
235
|
// the answer used judges a different answer
|
|
236
236
|
let lexicalBoost: string | undefined;
|
|
237
|
-
let
|
|
237
|
+
let editionSteer: { doc_number: string; edition: string } | null = null;
|
|
238
238
|
try {
|
|
239
239
|
const fam = u?.doc_number ? refCodec().familyOf(u.doc_number) : null;
|
|
240
240
|
if (fam) {
|
|
@@ -242,7 +242,7 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
|
|
|
242
242
|
.bind(fam).first().catch(() => null);
|
|
243
243
|
if (row?.edition) {
|
|
244
244
|
lexicalBoost = String(row.edition);
|
|
245
|
-
|
|
245
|
+
editionSteer = { doc_number: fam.split("-").pop() ?? "", edition: String(row.edition) };
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
} catch {
|
|
@@ -250,11 +250,33 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
|
|
|
250
250
|
}
|
|
251
251
|
const bound = await bindModelNode(env, { query, standardKeys: entitlementScope(standardKeysFrom(body)) });
|
|
252
252
|
const modelGrounding = bound && !bound.gated ? modelGroundingBlock(bound) : null;
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
// the caller's grounding WINS when present: the verify button (and
|
|
254
|
+
// the harness) hold the passages the answer was actually grounded on
|
|
255
|
+
// — verify's own fresh retrieval is a DIFFERENT pipeline (no grade,
|
|
256
|
+
// no listwise, no corrective widen) and returns different passages,
|
|
257
|
+
// which judges the answer against text it never saw
|
|
258
|
+
const supplied = (Array.isArray(body?.passages) ? body.passages : [])
|
|
259
|
+
.map((p: unknown) => (typeof p === "string" ? p : (p as any)?.text ?? ""))
|
|
260
|
+
.map((p: string) => p.trim())
|
|
261
|
+
.filter(Boolean)
|
|
262
|
+
.slice(0, 8);
|
|
263
|
+
let passages: string[];
|
|
264
|
+
let structured: { text: string; table?: boolean }[] = [];
|
|
265
|
+
if (supplied.length) {
|
|
266
|
+
passages = supplied;
|
|
267
|
+
structured = supplied.map((p: string) => ({ text: p }));
|
|
268
|
+
} else {
|
|
269
|
+
const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
|
|
270
|
+
passages = retrieved.hits.map((h: Hit) => h.text);
|
|
271
|
+
structured = retrieved.hits.map((h: Hit) => ({ text: h.text, table: (h.metadata as any).block === "table" || undefined }));
|
|
272
|
+
}
|
|
255
273
|
const anchors = checkQuoteAnchors(answer, passages);
|
|
256
274
|
const refs = [...answer.matchAll(/\[\[u:([^\]]+)\]\]/g)].map((m) => m[1]);
|
|
257
|
-
|
|
275
|
+
// unit references resolve against the grounding in use
|
|
276
|
+
const validRefs = refs.filter((r: string) =>
|
|
277
|
+
supplied.length
|
|
278
|
+
? supplied.some((p: string) => p.includes(`u:${r}`))
|
|
279
|
+
: structured.some((h) => h.text && !h.table));
|
|
258
280
|
const checks = [
|
|
259
281
|
{ name: "quote_anchors", deterministic: true, pass: anchors.violations.length === 0, detail: `${anchors.violations.length} of ${anchors.total} quoted spans absent from the retrieved passages` },
|
|
260
282
|
{ name: "unit_references", deterministic: true, pass: refs.length === validRefs.length, detail: refs.length ? `${validRefs.length}/${refs.length} unit references resolve to served units` : "no unit references" },
|
|
@@ -269,11 +291,17 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
|
|
|
269
291
|
.filter((x: unknown) => typeof x === "string" && x).join(" — "))
|
|
270
292
|
.filter(Boolean);
|
|
271
293
|
if (modelGrounding) machine.unshift(modelGrounding);
|
|
272
|
-
const faith = await scoreFaithfulness(
|
|
294
|
+
const faith = await scoreFaithfulness(
|
|
295
|
+
env.AI,
|
|
296
|
+
roleModel(env, "grader"),
|
|
297
|
+
answer,
|
|
298
|
+
structured,
|
|
299
|
+
machine,
|
|
300
|
+
);
|
|
273
301
|
return json({
|
|
274
302
|
checks,
|
|
275
303
|
judged: faith ? { name: "faithfulness", deterministic: false, score: faith.score, ungrounded_claims: faith.ungrounded_claims.slice(0, 5) } : null,
|
|
276
|
-
passages_used:
|
|
304
|
+
passages_used: passages.length,
|
|
277
305
|
});
|
|
278
306
|
} catch (e) {
|
|
279
307
|
return err(502, "verify_failed", String(e).slice(0, 200));
|