@konneal/engine 0.2.28 → 0.2.29
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/{ask-KELYM6RJ.js → ask-UAJHC6U7.js} +2 -2
- package/dist/{chunk-4G5OGWXY.js → chunk-BHWG556Q.js} +15 -3
- package/dist/{chunk-INCFGVH3.js → chunk-ODHIVW3M.js} +2 -2
- package/dist/{chunk-5LCPKJ6V.js → chunk-RI2SRLZY.js} +1 -1
- package/dist/faithfulness-context.d.ts +4 -1
- package/dist/faithfulness.d.ts +4 -1
- package/dist/{search-4UK3RBEQ.js → search-ICNVGXUY.js} +2 -2
- package/dist/worker_public/src/index.js +16 -8
- package/package.json +1 -1
- package/workers/worker_public/src/ask.ts +1 -1
- package/workers/worker_public/src/faithfulness-context.ts +11 -2
- package/workers/worker_public/src/faithfulness.ts +1 -1
- package/workers/worker_public/src/index.ts +7 -3
- package/workers/worker_public/src/stages/seal.ts +14 -2
- package/workers/worker_public/src/stages/types.ts +5 -0
|
@@ -22747,12 +22747,24 @@ var federate = {
|
|
|
22747
22747
|
// workers/worker_public/src/stages/seal.ts
|
|
22748
22748
|
var seal = {
|
|
22749
22749
|
name: "seal",
|
|
22750
|
-
when: (c) => !!c.opts.sealScope,
|
|
22750
|
+
when: (c) => !!c.opts.sealScope || !!c.opts.editionSteer,
|
|
22751
22751
|
run: (c) => {
|
|
22752
22752
|
const before = c.hits.length;
|
|
22753
22753
|
const scope = c.opts.sealScope;
|
|
22754
|
-
|
|
22755
|
-
|
|
22754
|
+
if (scope) {
|
|
22755
|
+
c.hits = c.hits.filter((h) => h.metadata.doc_number === scope.doc_number && (!scope.edition || h.metadata.edition === scope.edition));
|
|
22756
|
+
console.log("context seal:", before, "\u2192", c.hits.length, "candidates within", `doc#${scope.doc_number}${scope.edition ? "@" + scope.edition : ""}`);
|
|
22757
|
+
return;
|
|
22758
|
+
}
|
|
22759
|
+
const steer = c.opts.editionSteer;
|
|
22760
|
+
const current = [];
|
|
22761
|
+
const superseded = [];
|
|
22762
|
+
for (const h of c.hits) {
|
|
22763
|
+
const same = h.metadata.doc_number === steer.doc_number;
|
|
22764
|
+
(same && h.metadata.edition !== steer.edition ? superseded : current).push(h);
|
|
22765
|
+
}
|
|
22766
|
+
c.hits = [...current, ...superseded];
|
|
22767
|
+
console.log("edition steer:", superseded.length, "superseded candidates demoted behind", current.length, "current-edition candidates of", `doc#${steer.doc_number}@${steer.edition}`);
|
|
22756
22768
|
}
|
|
22757
22769
|
};
|
|
22758
22770
|
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
syntheticUnderstanding,
|
|
29
29
|
telemetry,
|
|
30
30
|
understandQuery
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-BHWG556Q.js";
|
|
32
32
|
import {
|
|
33
33
|
corsHeaders,
|
|
34
34
|
err,
|
|
@@ -2188,7 +2188,7 @@ Answer account questions from these records ONLY: name the record when you use i
|
|
|
2188
2188
|
// the evidence view's ground truth: the exact passages this
|
|
2189
2189
|
// answer was built from, compact — cache hits carry none,
|
|
2190
2190
|
// because the cache stores the answer and never the passages
|
|
2191
|
-
passages: usedHits.slice(0, 8).map((h) => ({ d: h.metadata.docidentifier ?? "", a: h.metadata.clause_anchor ?? "", t: (h.text ?? "").slice(0, 600), ...h.metadata.table_selection ? { s: h.metadata.table_selection } : {} }))
|
|
2191
|
+
passages: usedHits.slice(0, 8).map((h) => ({ d: h.metadata.docidentifier ?? "", a: h.metadata.clause_anchor ?? "", t: (h.text ?? "").slice(0, h.metadata.block === "table" ? 1400 : 600), b: h.metadata.block === "table" || void 0, ...h.metadata.table_selection ? { s: h.metadata.table_selection } : {} }))
|
|
2192
2192
|
});
|
|
2193
2193
|
telemetry(env, ctx, tier, "ask", model, true, c2.text.length, queryHash, q.lang, void 0, telemetryMeta());
|
|
2194
2194
|
const canonical = c2.text;
|
package/dist/faithfulness.d.ts
CHANGED
|
@@ -3,4 +3,7 @@ export interface FaithfulnessResult {
|
|
|
3
3
|
score: number;
|
|
4
4
|
ungrounded_claims: string[];
|
|
5
5
|
}
|
|
6
|
-
export declare function scoreFaithfulness(ai: any, model: string, answer: string, passages: string
|
|
6
|
+
export declare function scoreFaithfulness(ai: any, model: string, answer: string, passages: (string | {
|
|
7
|
+
text: string;
|
|
8
|
+
table?: boolean;
|
|
9
|
+
})[], machine?: string[]): Promise<FaithfulnessResult | null>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleSearch
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-RI2SRLZY.js";
|
|
4
4
|
import {
|
|
5
5
|
bindModelNode,
|
|
6
6
|
checkQuoteAnchors,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
modelGroundingBlock,
|
|
10
10
|
scoreJudge,
|
|
11
11
|
standardForDocNumber
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-ODHIVW3M.js";
|
|
13
13
|
import {
|
|
14
14
|
buildMessages,
|
|
15
15
|
citations,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
sessionFrom,
|
|
33
33
|
telemetry,
|
|
34
34
|
understandQuery
|
|
35
|
-
} from "../../chunk-
|
|
35
|
+
} from "../../chunk-BHWG556Q.js";
|
|
36
36
|
import {
|
|
37
37
|
authenticate,
|
|
38
38
|
corsHeaders,
|
|
@@ -393,7 +393,11 @@ function parseVerdict(text) {
|
|
|
393
393
|
|
|
394
394
|
// workers/worker_public/src/faithfulness-context.ts
|
|
395
395
|
function buildJudgeContext(passages, machine = []) {
|
|
396
|
-
const context = passages.slice(0, 8).map((p, i) =>
|
|
396
|
+
const context = passages.slice(0, 8).map((p, i) => {
|
|
397
|
+
const text = typeof p === "string" ? p : p.text;
|
|
398
|
+
const limit = typeof p !== "string" && p.table ? 2400 : 1400;
|
|
399
|
+
return `[${i + 1}] ${text.replace(/\s+/g, " ").slice(0, limit)}`;
|
|
400
|
+
}).join("\n");
|
|
397
401
|
const machineContext = machine.length ? "\n" + machine.slice(0, 6).map((m) => `[M] ${m.replace(/\s+/g, " ").slice(0, 400)}`).join("\n") : "";
|
|
398
402
|
return context + machineContext;
|
|
399
403
|
}
|
|
@@ -992,7 +996,7 @@ async function handleMcp(env, ctx, req, tier, key) {
|
|
|
992
996
|
// stream:false forces the JSON lane (anon defaults to SSE)
|
|
993
997
|
body: JSON.stringify({ ...args, stream: false })
|
|
994
998
|
});
|
|
995
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
999
|
+
const res = name === "ask" ? await (await import("../../ask-UAJHC6U7.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-ICNVGXUY.js")).handleSearch(env, ctx, inner, tier, key);
|
|
996
1000
|
return res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
997
1001
|
});
|
|
998
1002
|
if (out.ok && "accepted" in out) return new Response(null, { status: 202 });
|
|
@@ -1452,17 +1456,21 @@ async function verifyRoute(c) {
|
|
|
1452
1456
|
try {
|
|
1453
1457
|
const u = await understandQuery(env.AI, roleModel(env, "understand"), query, [], []);
|
|
1454
1458
|
let lexicalBoost;
|
|
1459
|
+
let editionSteer = null;
|
|
1455
1460
|
try {
|
|
1456
1461
|
const fam = u?.doc_number ? refCodec().familyOf(u.doc_number) : null;
|
|
1457
1462
|
if (fam) {
|
|
1458
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);
|
|
1459
|
-
if (row?.edition)
|
|
1464
|
+
if (row?.edition) {
|
|
1465
|
+
lexicalBoost = String(row.edition);
|
|
1466
|
+
editionSteer = { doc_number: fam.split("-").pop() ?? "", edition: String(row.edition) };
|
|
1467
|
+
}
|
|
1460
1468
|
}
|
|
1461
1469
|
} catch {
|
|
1462
1470
|
}
|
|
1463
1471
|
const bound = await bindModelNode(env, { query, standardKeys: entitlementScope(standardKeysFrom(body)) });
|
|
1464
1472
|
const modelGrounding = bound && !bound.gated ? modelGroundingBlock(bound) : null;
|
|
1465
|
-
const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost });
|
|
1473
|
+
const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
|
|
1466
1474
|
const passages = retrieved.hits.map((h) => h.text);
|
|
1467
1475
|
const anchors = checkQuoteAnchors(answer, passages);
|
|
1468
1476
|
const refs = [...answer.matchAll(/\[\[u:([^\]]+)\]\]/g)].map((m) => m[1]);
|
|
@@ -1474,7 +1482,7 @@ async function verifyRoute(c) {
|
|
|
1474
1482
|
];
|
|
1475
1483
|
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);
|
|
1476
1484
|
if (modelGrounding) machine.unshift(modelGrounding);
|
|
1477
|
-
const faith = await scoreFaithfulness(env.AI, roleModel(env, "grader"), answer, retrieved.hits.map((h) => h.text), machine);
|
|
1485
|
+
const faith = await scoreFaithfulness(env.AI, roleModel(env, "grader"), answer, retrieved.hits.map((h) => ({ text: h.text, table: h.metadata.block === "table" || void 0 })), machine);
|
|
1478
1486
|
return json({
|
|
1479
1487
|
checks,
|
|
1480
1488
|
judged: faith ? { name: "faithfulness", deterministic: false, score: faith.score, ungrounded_claims: faith.ungrounded_claims.slice(0, 5) } : null,
|
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.29",
|
|
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",
|
|
@@ -1098,7 +1098,7 @@ async function handleAsk(
|
|
|
1098
1098
|
// the evidence view's ground truth: the exact passages this
|
|
1099
1099
|
// answer was built from, compact — cache hits carry none,
|
|
1100
1100
|
// because the cache stores the answer and never the passages
|
|
1101
|
-
passages: usedHits.slice(0, 8).map((h: Hit) => ({ d: h.metadata.docidentifier ?? "", a: h.metadata.clause_anchor ?? "", t: (h.text ?? "").slice(0, 600), ...((h.metadata as any).table_selection ? { s: (h.metadata as any).table_selection } : {}) })) });
|
|
1101
|
+
passages: usedHits.slice(0, 8).map((h: Hit) => ({ d: h.metadata.docidentifier ?? "", a: h.metadata.clause_anchor ?? "", t: (h.text ?? "").slice(0, (h.metadata as any).block === "table" ? 1400 : 600), b: (h.metadata as any).block === "table" || undefined, ...((h.metadata as any).table_selection ? { s: (h.metadata as any).table_selection } : {}) })) });
|
|
1102
1102
|
telemetry(env, ctx, tier, "ask", model, true, c2.text.length, queryHash, q.lang, undefined, telemetryMeta());
|
|
1103
1103
|
const canonical = c2.text;
|
|
1104
1104
|
// streamed answers can't be regenerated mid-flight; enforcement
|
|
@@ -4,10 +4,19 @@
|
|
|
4
4
|
// service's own machine-computed model data: a machine-grounded answer
|
|
5
5
|
// quotes it legitimately, so the judge must see it.
|
|
6
6
|
|
|
7
|
-
export function buildJudgeContext(
|
|
7
|
+
export function buildJudgeContext(
|
|
8
|
+
passages: (string | { text: string; table?: boolean })[],
|
|
9
|
+
machine: string[] = [],
|
|
10
|
+
): string {
|
|
8
11
|
const context = passages
|
|
9
12
|
.slice(0, 8)
|
|
10
|
-
.map((p, i) =>
|
|
13
|
+
.map((p, i) => {
|
|
14
|
+
const text = typeof p === "string" ? p : p.text;
|
|
15
|
+
// a table's evidence lives across its whole row set — a truncated
|
|
16
|
+
// table hides the very rows the answer computed from
|
|
17
|
+
const limit = typeof p !== "string" && p.table ? 2400 : 1400;
|
|
18
|
+
return `[${i + 1}] ${text.replace(/\s+/g, " ").slice(0, limit)}`;
|
|
19
|
+
})
|
|
11
20
|
.join("\n");
|
|
12
21
|
const machineContext = machine.length
|
|
13
22
|
? "\n" + machine.slice(0, 6).map((m) => `[M] ${m.replace(/\s+/g, " ").slice(0, 400)}`).join("\n")
|
|
@@ -19,7 +19,7 @@ export async function scoreFaithfulness(
|
|
|
19
19
|
ai: any,
|
|
20
20
|
model: string,
|
|
21
21
|
answer: string,
|
|
22
|
-
passages: string[],
|
|
22
|
+
passages: (string | { text: string; table?: boolean })[],
|
|
23
23
|
machine: string[] = [],
|
|
24
24
|
): Promise<FaithfulnessResult | null> {
|
|
25
25
|
if (!answer || !passages.length) return null;
|
|
@@ -234,19 +234,23 @@ 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 editionSteer: { doc_number: string; edition: string } | null = null;
|
|
237
238
|
try {
|
|
238
239
|
const fam = u?.doc_number ? refCodec().familyOf(u.doc_number) : null;
|
|
239
240
|
if (fam) {
|
|
240
241
|
const row = await env.DB.prepare("SELECT edition FROM documents WHERE family = ?1 AND active = 1 ORDER BY edition DESC LIMIT 1")
|
|
241
242
|
.bind(fam).first().catch(() => null);
|
|
242
|
-
if (row?.edition)
|
|
243
|
+
if (row?.edition) {
|
|
244
|
+
lexicalBoost = String(row.edition);
|
|
245
|
+
editionSteer = { doc_number: fam.split("-").pop() ?? "", edition: String(row.edition) };
|
|
246
|
+
}
|
|
243
247
|
}
|
|
244
248
|
} catch {
|
|
245
249
|
// degrade to unsteered retrieval
|
|
246
250
|
}
|
|
247
251
|
const bound = await bindModelNode(env, { query, standardKeys: entitlementScope(standardKeysFrom(body)) });
|
|
248
252
|
const modelGrounding = bound && !bound.gated ? modelGroundingBlock(bound) : null;
|
|
249
|
-
const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost });
|
|
253
|
+
const retrieved = await retrieve(env, query, { understanding: u, standardKeys: entitlementScope(standardKeysFrom(body)), lexicalBoost, editionSteer });
|
|
250
254
|
const passages = retrieved.hits.map((h: Hit) => h.text);
|
|
251
255
|
const anchors = checkQuoteAnchors(answer, passages);
|
|
252
256
|
const refs = [...answer.matchAll(/\[\[u:([^\]]+)\]\]/g)].map((m) => m[1]);
|
|
@@ -265,7 +269,7 @@ async function verifyRoute(c: RouteContext): Promise<Response> {
|
|
|
265
269
|
.filter((x: unknown) => typeof x === "string" && x).join(" — "))
|
|
266
270
|
.filter(Boolean);
|
|
267
271
|
if (modelGrounding) machine.unshift(modelGrounding);
|
|
268
|
-
const faith = await scoreFaithfulness(env.AI, roleModel(env, "grader"), answer, retrieved.hits.map((h: Hit) => h.text), machine);
|
|
272
|
+
const faith = await scoreFaithfulness(env.AI, roleModel(env, "grader"), answer, retrieved.hits.map((h: Hit) => ({ text: h.text, table: (h.metadata as any).block === "table" || undefined })), machine);
|
|
269
273
|
return json({
|
|
270
274
|
checks,
|
|
271
275
|
judged: faith ? { name: "faithfulness", deterministic: false, score: faith.score, ungrounded_claims: faith.ungrounded_claims.slice(0, 5) } : null,
|
|
@@ -6,11 +6,23 @@ import type { Stage } from "./types.ts";
|
|
|
6
6
|
|
|
7
7
|
export const seal: Stage = {
|
|
8
8
|
name: "seal",
|
|
9
|
-
when: (c) => !!c.opts.sealScope,
|
|
9
|
+
when: (c) => !!c.opts.sealScope || !!c.opts.editionSteer,
|
|
10
10
|
run: (c) => {
|
|
11
11
|
const before = c.hits.length;
|
|
12
12
|
const scope = c.opts.sealScope!;
|
|
13
|
+
if (scope) {
|
|
13
14
|
c.hits = c.hits.filter((h) => h.metadata.doc_number === scope.doc_number && (!scope.edition || h.metadata.edition === scope.edition));
|
|
14
|
-
|
|
15
|
+
console.log("context seal:", before, "→", c.hits.length, "candidates within", `doc#${scope.doc_number}${scope.edition ? "@" + scope.edition : ""}`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const steer = c.opts.editionSteer!;
|
|
19
|
+
const current: typeof c.hits = [];
|
|
20
|
+
const superseded: typeof c.hits = [];
|
|
21
|
+
for (const h of c.hits) {
|
|
22
|
+
const same = h.metadata.doc_number === steer.doc_number;
|
|
23
|
+
(same && h.metadata.edition !== steer.edition ? superseded : current).push(h);
|
|
24
|
+
}
|
|
25
|
+
c.hits = [...current, ...superseded];
|
|
26
|
+
console.log("edition steer:", superseded.length, "superseded candidates demoted behind", current.length, "current-edition candidates of", `doc#${steer.doc_number}@${steer.edition}`);
|
|
15
27
|
},
|
|
16
28
|
};
|
|
@@ -29,6 +29,11 @@ export interface RetrieveOptions {
|
|
|
29
29
|
* in-family passage out of the final hits, sealing the answer to
|
|
30
30
|
* zero despite a healthy in-family pool. */
|
|
31
31
|
sealScope?: { doc_number: string; edition?: string } | null;
|
|
32
|
+
/** Verify's grounding steer (demote-not-exclude): hits of the named
|
|
33
|
+
* document whose edition differs from the active one move to the END
|
|
34
|
+
* of the candidate pool — superseded passages stay servable but stop
|
|
35
|
+
* competing for the window against the current edition. */
|
|
36
|
+
editionSteer?: { doc_number: string; edition: string } | null;
|
|
32
37
|
/** Option C: dense-lane results computed concurrently with
|
|
33
38
|
* understanding (same folded-query vector, retrieve's exact query
|
|
34
39
|
* parameters). With no filter they REPLACE the primary dense query;
|