@konneal/engine 0.2.112 → 0.2.113
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-FFDCQXAA.js → ask-645ZWTEQ.js} +2 -2
- package/dist/{chunk-2R7OVYAO.js → chunk-NO4WHD3K.js} +189 -181
- package/dist/{chunk-25VMZ7WE.js → chunk-PSI5SR2A.js} +1 -1
- package/dist/{chunk-HAU5INEJ.js → chunk-WUD4XR7Y.js} +1 -1
- package/dist/context.d.ts +12 -0
- package/dist/{search-HKGN7F3O.js → search-6J5FUJOC.js} +2 -2
- package/dist/worker_public/src/index.js +4 -4
- package/package.json +1 -1
- package/workers/worker_public/src/context.ts +20 -0
- package/workers/worker_public/src/pipeline.ts +2 -1
- package/workers/worker_public/src/stages/seal.ts +2 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleAsk
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PSI5SR2A.js";
|
|
4
4
|
import "./chunk-32UDKBA2.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-NO4WHD3K.js";
|
|
6
6
|
import "./chunk-TH5XGPD5.js";
|
|
7
7
|
import "./chunk-DJ65EF5G.js";
|
|
8
8
|
import "./chunk-A3QHHUN5.js";
|
|
@@ -24,181 +24,6 @@ import {
|
|
|
24
24
|
P
|
|
25
25
|
} from "./chunk-3FYJM7LH.js";
|
|
26
26
|
|
|
27
|
-
// workers/worker_public/src/quality.ts
|
|
28
|
-
var ORDER = { verified: 0, curated: 1, ocr: 2 };
|
|
29
|
-
function hitQuality(m) {
|
|
30
|
-
if (m.model_node || m.model_version || m.producer === "primmel") return "verified";
|
|
31
|
-
if (m.tier === "curated") return "curated";
|
|
32
|
-
return "ocr";
|
|
33
|
-
}
|
|
34
|
-
function answerQuality(qualities) {
|
|
35
|
-
let worst = null;
|
|
36
|
-
for (const q of qualities) {
|
|
37
|
-
if (!q) continue;
|
|
38
|
-
if (!worst || ORDER[q] > ORDER[worst]) worst = q;
|
|
39
|
-
}
|
|
40
|
-
return worst;
|
|
41
|
-
}
|
|
42
|
-
function qualityNote(q) {
|
|
43
|
-
if (q === "verified") return "High confidence: this publication's requirements ride a machine-checkable data model.";
|
|
44
|
-
if (q === "curated") return "Established sources: Metanorma-edited documents, chunked at clause boundaries.";
|
|
45
|
-
return "WARNING: Partly grounded in experimental data source that was derived from OCR content. Please verify content against official publications.";
|
|
46
|
-
}
|
|
47
|
-
function experimentalSourceLabels(cites, cap = 6) {
|
|
48
|
-
const labels = [];
|
|
49
|
-
for (const c of cites) {
|
|
50
|
-
if (c.quality !== "ocr") continue;
|
|
51
|
-
const id = String(c.docidentifier || c.doc_id || "source");
|
|
52
|
-
const anchor = String(c.clause_anchor ?? "");
|
|
53
|
-
const garbage = /^[0-9a-f]{8}-[0-9a-f]{4}-/i.test(anchor) || anchor.startsWith("_") && anchor.length > 12;
|
|
54
|
-
labels.push(garbage || !anchor || anchor === "overview" ? id : `${id} \xA7${anchor}`);
|
|
55
|
-
if (labels.length >= cap) break;
|
|
56
|
-
}
|
|
57
|
-
return labels;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// workers/worker_public/src/lexical.ts
|
|
61
|
-
var LEXICAL_K = 40;
|
|
62
|
-
function ftsMatchQuery(query) {
|
|
63
|
-
const terms = query.toLowerCase().replace(/[^\p{L}\p{N}\s_-]/gu, " ").split(/\s+/).map((t) => t.trim()).filter((t) => t.length >= 2 && t.length <= 40).filter((t) => !STOP.has(t));
|
|
64
|
-
const uniq = [...new Set(terms)].slice(0, 12);
|
|
65
|
-
if (!uniq.length) return null;
|
|
66
|
-
return uniq.map((t) => `"${t.replace(/"/g, "")}"`).join(" OR ");
|
|
67
|
-
}
|
|
68
|
-
var STOP = /* @__PURE__ */ new Set([
|
|
69
|
-
"the",
|
|
70
|
-
"a",
|
|
71
|
-
"an",
|
|
72
|
-
"of",
|
|
73
|
-
"and",
|
|
74
|
-
"or",
|
|
75
|
-
"to",
|
|
76
|
-
"in",
|
|
77
|
-
"for",
|
|
78
|
-
"on",
|
|
79
|
-
"is",
|
|
80
|
-
"are",
|
|
81
|
-
"was",
|
|
82
|
-
"were",
|
|
83
|
-
"be",
|
|
84
|
-
"by",
|
|
85
|
-
"with",
|
|
86
|
-
"as",
|
|
87
|
-
"at",
|
|
88
|
-
"from",
|
|
89
|
-
"that",
|
|
90
|
-
"this",
|
|
91
|
-
"what",
|
|
92
|
-
"how",
|
|
93
|
-
"when",
|
|
94
|
-
"where",
|
|
95
|
-
"which",
|
|
96
|
-
"who",
|
|
97
|
-
"does",
|
|
98
|
-
"do",
|
|
99
|
-
"did",
|
|
100
|
-
"can",
|
|
101
|
-
"could",
|
|
102
|
-
"should",
|
|
103
|
-
"would",
|
|
104
|
-
"may",
|
|
105
|
-
"might",
|
|
106
|
-
"shall",
|
|
107
|
-
"must",
|
|
108
|
-
"about",
|
|
109
|
-
"into",
|
|
110
|
-
"than",
|
|
111
|
-
"then",
|
|
112
|
-
"its",
|
|
113
|
-
"it",
|
|
114
|
-
"their",
|
|
115
|
-
"there"
|
|
116
|
-
]);
|
|
117
|
-
function rowMeta(r) {
|
|
118
|
-
return {
|
|
119
|
-
doc_id: String(r.doc_id ?? ""),
|
|
120
|
-
docidentifier: String(r.docidentifier ?? ""),
|
|
121
|
-
doctype: String(r.doctype ?? ""),
|
|
122
|
-
doc_number: String(r.doc_number ?? ""),
|
|
123
|
-
edition: String(r.edition ?? ""),
|
|
124
|
-
language: String(r.language ?? "en"),
|
|
125
|
-
clause_anchor: String(r.clause_anchor ?? ""),
|
|
126
|
-
clause_title: String(r.clause_title ?? ""),
|
|
127
|
-
tier: String(r.tier ?? ""),
|
|
128
|
-
corpus: String(r.corpus ?? ""),
|
|
129
|
-
text_ref: "",
|
|
130
|
-
status: String(r.status ?? "unknown"),
|
|
131
|
-
superseded_by: String(r.superseded_by ?? ""),
|
|
132
|
-
// contract v2 over the lexical lane: typed chunks arriving via BM25
|
|
133
|
-
// keep their unit identity ([[u:…]] refs, typed pin, retyping check)
|
|
134
|
-
unit_id: String(r.unit_id ?? "") || void 0,
|
|
135
|
-
block: String(r.block ?? "") || void 0
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
function rowsToHits(rows) {
|
|
139
|
-
return rows.map((r) => {
|
|
140
|
-
const bm25 = typeof r.rank === "number" ? r.rank : 0;
|
|
141
|
-
return {
|
|
142
|
-
id: String(r.id),
|
|
143
|
-
score: 1 / (1 + Math.max(0, bm25)),
|
|
144
|
-
metadata: rowMeta(r),
|
|
145
|
-
text: String(r.text ?? "")
|
|
146
|
-
};
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
function rowsToMatches(rows) {
|
|
150
|
-
return rows.map((r) => {
|
|
151
|
-
const bm25 = typeof r.rank === "number" ? Math.max(0, r.rank) : 0;
|
|
152
|
-
return {
|
|
153
|
-
id: String(r.id),
|
|
154
|
-
score: 1 / (1 + bm25),
|
|
155
|
-
metadata: { ...rowMeta(r), chunk_text: String(r.text ?? "") }
|
|
156
|
-
};
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
async function lexicalWithin(env, query, docNumbers, k = 12) {
|
|
160
|
-
const match2 = ftsMatchQuery(query);
|
|
161
|
-
if (!match2 || !docNumbers.length) return [];
|
|
162
|
-
try {
|
|
163
|
-
const placeholders = docNumbers.map((_, i) => `?${i + 2}`).join(",");
|
|
164
|
-
const res = await env.DB.prepare(
|
|
165
|
-
`SELECT c.id, c.doc_id, c.docidentifier, c.doctype, c.doc_number, c.edition,
|
|
166
|
-
c.language, c.clause_anchor, c.clause_title, c.status, c.superseded_by,
|
|
167
|
-
c.corpus, c.tier, c.text, c.unit_id, c.block, bm25(chunks_fts) AS rank
|
|
168
|
-
FROM chunks_fts
|
|
169
|
-
JOIN chunks c ON c.rowid = chunks_fts.rowid
|
|
170
|
-
WHERE chunks_fts MATCH ?1 AND c.doc_number IN (${placeholders})
|
|
171
|
-
ORDER BY rank
|
|
172
|
-
LIMIT ?${docNumbers.length + 2}`
|
|
173
|
-
).bind(match2, ...docNumbers, k).all();
|
|
174
|
-
return rowsToMatches(res.results ?? []);
|
|
175
|
-
} catch (e) {
|
|
176
|
-
console.log("lexical-within failed:", String(e).slice(0, 200));
|
|
177
|
-
return [];
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
async function lexicalPrefilter(env, query, k = LEXICAL_K) {
|
|
181
|
-
const match2 = ftsMatchQuery(query);
|
|
182
|
-
if (!match2) return [];
|
|
183
|
-
try {
|
|
184
|
-
const res = await env.DB.prepare(
|
|
185
|
-
`SELECT c.id, c.doc_id, c.docidentifier, c.doctype, c.doc_number, c.edition,
|
|
186
|
-
c.language, c.clause_anchor, c.clause_title, c.status, c.superseded_by,
|
|
187
|
-
c.corpus, c.tier, c.text, c.unit_id, c.block, bm25(chunks_fts) AS rank
|
|
188
|
-
FROM chunks_fts
|
|
189
|
-
JOIN chunks c ON c.rowid = chunks_fts.rowid
|
|
190
|
-
WHERE chunks_fts MATCH ?1
|
|
191
|
-
ORDER BY rank
|
|
192
|
-
LIMIT ?2`
|
|
193
|
-
).bind(match2, k).all();
|
|
194
|
-
const rows = res.results ?? [];
|
|
195
|
-
return rowsToHits(rows);
|
|
196
|
-
} catch (e) {
|
|
197
|
-
console.log("lexical prefilter failed:", String(e).slice(0, 200));
|
|
198
|
-
return [];
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
27
|
// node_modules/@pubid/pubid/dist/grammar/engine.js
|
|
203
28
|
var ParseFailed = class extends Error {
|
|
204
29
|
pos;
|
|
@@ -22029,6 +21854,14 @@ function parseDocRef(doc, edition) {
|
|
|
22029
21854
|
function namedDocumentIn(query) {
|
|
22030
21855
|
return refCodec().scanQuestion(query);
|
|
22031
21856
|
}
|
|
21857
|
+
function matchesDocScope(meta, scopeDocNumber) {
|
|
21858
|
+
if (meta.doc_number === scopeDocNumber) return true;
|
|
21859
|
+
if (!scopeDocNumber.includes("-")) return false;
|
|
21860
|
+
if (meta.doc_number !== scopeDocNumber.split("-")[0]) return false;
|
|
21861
|
+
const stem = (meta.docidentifier ?? "").replace(/\s*\([A-Z]\)\s*$/, "").replace(/:\d+$/, "").trim();
|
|
21862
|
+
const last = stem.split(/\s+/).pop()?.toLowerCase();
|
|
21863
|
+
return last === scopeDocNumber.toLowerCase();
|
|
21864
|
+
}
|
|
22032
21865
|
async function resolveDocScope(env, ctx) {
|
|
22033
21866
|
if (!ctx.doc) return null;
|
|
22034
21867
|
const parsed = parseDocRef(ctx.doc, ctx.edition);
|
|
@@ -22104,6 +21937,181 @@ function syntheticUnderstanding(scope) {
|
|
|
22104
21937
|
};
|
|
22105
21938
|
}
|
|
22106
21939
|
|
|
21940
|
+
// workers/worker_public/src/quality.ts
|
|
21941
|
+
var ORDER = { verified: 0, curated: 1, ocr: 2 };
|
|
21942
|
+
function hitQuality(m) {
|
|
21943
|
+
if (m.model_node || m.model_version || m.producer === "primmel") return "verified";
|
|
21944
|
+
if (m.tier === "curated") return "curated";
|
|
21945
|
+
return "ocr";
|
|
21946
|
+
}
|
|
21947
|
+
function answerQuality(qualities) {
|
|
21948
|
+
let worst = null;
|
|
21949
|
+
for (const q of qualities) {
|
|
21950
|
+
if (!q) continue;
|
|
21951
|
+
if (!worst || ORDER[q] > ORDER[worst]) worst = q;
|
|
21952
|
+
}
|
|
21953
|
+
return worst;
|
|
21954
|
+
}
|
|
21955
|
+
function qualityNote(q) {
|
|
21956
|
+
if (q === "verified") return "High confidence: this publication's requirements ride a machine-checkable data model.";
|
|
21957
|
+
if (q === "curated") return "Established sources: Metanorma-edited documents, chunked at clause boundaries.";
|
|
21958
|
+
return "WARNING: Partly grounded in experimental data source that was derived from OCR content. Please verify content against official publications.";
|
|
21959
|
+
}
|
|
21960
|
+
function experimentalSourceLabels(cites, cap = 6) {
|
|
21961
|
+
const labels = [];
|
|
21962
|
+
for (const c of cites) {
|
|
21963
|
+
if (c.quality !== "ocr") continue;
|
|
21964
|
+
const id = String(c.docidentifier || c.doc_id || "source");
|
|
21965
|
+
const anchor = String(c.clause_anchor ?? "");
|
|
21966
|
+
const garbage = /^[0-9a-f]{8}-[0-9a-f]{4}-/i.test(anchor) || anchor.startsWith("_") && anchor.length > 12;
|
|
21967
|
+
labels.push(garbage || !anchor || anchor === "overview" ? id : `${id} \xA7${anchor}`);
|
|
21968
|
+
if (labels.length >= cap) break;
|
|
21969
|
+
}
|
|
21970
|
+
return labels;
|
|
21971
|
+
}
|
|
21972
|
+
|
|
21973
|
+
// workers/worker_public/src/lexical.ts
|
|
21974
|
+
var LEXICAL_K = 40;
|
|
21975
|
+
function ftsMatchQuery(query) {
|
|
21976
|
+
const terms = query.toLowerCase().replace(/[^\p{L}\p{N}\s_-]/gu, " ").split(/\s+/).map((t) => t.trim()).filter((t) => t.length >= 2 && t.length <= 40).filter((t) => !STOP.has(t));
|
|
21977
|
+
const uniq = [...new Set(terms)].slice(0, 12);
|
|
21978
|
+
if (!uniq.length) return null;
|
|
21979
|
+
return uniq.map((t) => `"${t.replace(/"/g, "")}"`).join(" OR ");
|
|
21980
|
+
}
|
|
21981
|
+
var STOP = /* @__PURE__ */ new Set([
|
|
21982
|
+
"the",
|
|
21983
|
+
"a",
|
|
21984
|
+
"an",
|
|
21985
|
+
"of",
|
|
21986
|
+
"and",
|
|
21987
|
+
"or",
|
|
21988
|
+
"to",
|
|
21989
|
+
"in",
|
|
21990
|
+
"for",
|
|
21991
|
+
"on",
|
|
21992
|
+
"is",
|
|
21993
|
+
"are",
|
|
21994
|
+
"was",
|
|
21995
|
+
"were",
|
|
21996
|
+
"be",
|
|
21997
|
+
"by",
|
|
21998
|
+
"with",
|
|
21999
|
+
"as",
|
|
22000
|
+
"at",
|
|
22001
|
+
"from",
|
|
22002
|
+
"that",
|
|
22003
|
+
"this",
|
|
22004
|
+
"what",
|
|
22005
|
+
"how",
|
|
22006
|
+
"when",
|
|
22007
|
+
"where",
|
|
22008
|
+
"which",
|
|
22009
|
+
"who",
|
|
22010
|
+
"does",
|
|
22011
|
+
"do",
|
|
22012
|
+
"did",
|
|
22013
|
+
"can",
|
|
22014
|
+
"could",
|
|
22015
|
+
"should",
|
|
22016
|
+
"would",
|
|
22017
|
+
"may",
|
|
22018
|
+
"might",
|
|
22019
|
+
"shall",
|
|
22020
|
+
"must",
|
|
22021
|
+
"about",
|
|
22022
|
+
"into",
|
|
22023
|
+
"than",
|
|
22024
|
+
"then",
|
|
22025
|
+
"its",
|
|
22026
|
+
"it",
|
|
22027
|
+
"their",
|
|
22028
|
+
"there"
|
|
22029
|
+
]);
|
|
22030
|
+
function rowMeta(r) {
|
|
22031
|
+
return {
|
|
22032
|
+
doc_id: String(r.doc_id ?? ""),
|
|
22033
|
+
docidentifier: String(r.docidentifier ?? ""),
|
|
22034
|
+
doctype: String(r.doctype ?? ""),
|
|
22035
|
+
doc_number: String(r.doc_number ?? ""),
|
|
22036
|
+
edition: String(r.edition ?? ""),
|
|
22037
|
+
language: String(r.language ?? "en"),
|
|
22038
|
+
clause_anchor: String(r.clause_anchor ?? ""),
|
|
22039
|
+
clause_title: String(r.clause_title ?? ""),
|
|
22040
|
+
tier: String(r.tier ?? ""),
|
|
22041
|
+
corpus: String(r.corpus ?? ""),
|
|
22042
|
+
text_ref: "",
|
|
22043
|
+
status: String(r.status ?? "unknown"),
|
|
22044
|
+
superseded_by: String(r.superseded_by ?? ""),
|
|
22045
|
+
// contract v2 over the lexical lane: typed chunks arriving via BM25
|
|
22046
|
+
// keep their unit identity ([[u:…]] refs, typed pin, retyping check)
|
|
22047
|
+
unit_id: String(r.unit_id ?? "") || void 0,
|
|
22048
|
+
block: String(r.block ?? "") || void 0
|
|
22049
|
+
};
|
|
22050
|
+
}
|
|
22051
|
+
function rowsToHits(rows) {
|
|
22052
|
+
return rows.map((r) => {
|
|
22053
|
+
const bm25 = typeof r.rank === "number" ? r.rank : 0;
|
|
22054
|
+
return {
|
|
22055
|
+
id: String(r.id),
|
|
22056
|
+
score: 1 / (1 + Math.max(0, bm25)),
|
|
22057
|
+
metadata: rowMeta(r),
|
|
22058
|
+
text: String(r.text ?? "")
|
|
22059
|
+
};
|
|
22060
|
+
});
|
|
22061
|
+
}
|
|
22062
|
+
function rowsToMatches(rows) {
|
|
22063
|
+
return rows.map((r) => {
|
|
22064
|
+
const bm25 = typeof r.rank === "number" ? Math.max(0, r.rank) : 0;
|
|
22065
|
+
return {
|
|
22066
|
+
id: String(r.id),
|
|
22067
|
+
score: 1 / (1 + bm25),
|
|
22068
|
+
metadata: { ...rowMeta(r), chunk_text: String(r.text ?? "") }
|
|
22069
|
+
};
|
|
22070
|
+
});
|
|
22071
|
+
}
|
|
22072
|
+
async function lexicalWithin(env, query, docNumbers, k = 12) {
|
|
22073
|
+
const match2 = ftsMatchQuery(query);
|
|
22074
|
+
if (!match2 || !docNumbers.length) return [];
|
|
22075
|
+
try {
|
|
22076
|
+
const placeholders = docNumbers.map((_, i) => `?${i + 2}`).join(",");
|
|
22077
|
+
const res = await env.DB.prepare(
|
|
22078
|
+
`SELECT c.id, c.doc_id, c.docidentifier, c.doctype, c.doc_number, c.edition,
|
|
22079
|
+
c.language, c.clause_anchor, c.clause_title, c.status, c.superseded_by,
|
|
22080
|
+
c.corpus, c.tier, c.text, c.unit_id, c.block, bm25(chunks_fts) AS rank
|
|
22081
|
+
FROM chunks_fts
|
|
22082
|
+
JOIN chunks c ON c.rowid = chunks_fts.rowid
|
|
22083
|
+
WHERE chunks_fts MATCH ?1 AND c.doc_number IN (${placeholders})
|
|
22084
|
+
ORDER BY rank
|
|
22085
|
+
LIMIT ?${docNumbers.length + 2}`
|
|
22086
|
+
).bind(match2, ...docNumbers, k).all();
|
|
22087
|
+
return rowsToMatches(res.results ?? []);
|
|
22088
|
+
} catch (e) {
|
|
22089
|
+
console.log("lexical-within failed:", String(e).slice(0, 200));
|
|
22090
|
+
return [];
|
|
22091
|
+
}
|
|
22092
|
+
}
|
|
22093
|
+
async function lexicalPrefilter(env, query, k = LEXICAL_K) {
|
|
22094
|
+
const match2 = ftsMatchQuery(query);
|
|
22095
|
+
if (!match2) return [];
|
|
22096
|
+
try {
|
|
22097
|
+
const res = await env.DB.prepare(
|
|
22098
|
+
`SELECT c.id, c.doc_id, c.docidentifier, c.doctype, c.doc_number, c.edition,
|
|
22099
|
+
c.language, c.clause_anchor, c.clause_title, c.status, c.superseded_by,
|
|
22100
|
+
c.corpus, c.tier, c.text, c.unit_id, c.block, bm25(chunks_fts) AS rank
|
|
22101
|
+
FROM chunks_fts
|
|
22102
|
+
JOIN chunks c ON c.rowid = chunks_fts.rowid
|
|
22103
|
+
WHERE chunks_fts MATCH ?1
|
|
22104
|
+
ORDER BY rank
|
|
22105
|
+
LIMIT ?2`
|
|
22106
|
+
).bind(match2, k).all();
|
|
22107
|
+
const rows = res.results ?? [];
|
|
22108
|
+
return rowsToHits(rows);
|
|
22109
|
+
} catch (e) {
|
|
22110
|
+
console.log("lexical prefilter failed:", String(e).slice(0, 200));
|
|
22111
|
+
return [];
|
|
22112
|
+
}
|
|
22113
|
+
}
|
|
22114
|
+
|
|
22107
22115
|
// workers/shared/chunk.ts
|
|
22108
22116
|
function toHits(matches) {
|
|
22109
22117
|
return matches.map((m) => ({
|
|
@@ -22693,7 +22701,7 @@ var seal = {
|
|
|
22693
22701
|
const before = c.hits.length;
|
|
22694
22702
|
const scope = c.opts.sealScope;
|
|
22695
22703
|
if (scope) {
|
|
22696
|
-
c.hits = c.hits.filter((h) => h.metadata
|
|
22704
|
+
c.hits = c.hits.filter((h) => matchesDocScope(h.metadata, scope.doc_number) && (!scope.edition || h.metadata.edition === scope.edition));
|
|
22697
22705
|
console.log("context seal:", before, "\u2192", c.hits.length, "candidates within", `doc#${scope.doc_number}${scope.edition ? "@" + scope.edition : ""}`);
|
|
22698
22706
|
return;
|
|
22699
22707
|
}
|
|
@@ -23471,7 +23479,7 @@ async function retrieve(env, query, opts = {}) {
|
|
|
23471
23479
|
const lexicalP = lexicalPrefilter(env, opts.lexicalBoost ? `${rq} ${opts.lexicalBoost}` : rq).catch(() => []);
|
|
23472
23480
|
const [vector, lexicalHits0] = await Promise.all([vectorP, lexicalP]);
|
|
23473
23481
|
const lexicalHits = opts.sealScope || opts.standardKeys ? lexicalHits0.filter(
|
|
23474
|
-
(h) => (!opts.sealScope || h.metadata
|
|
23482
|
+
(h) => (!opts.sealScope || matchesDocScope(h.metadata, opts.sealScope.doc_number) && (!opts.sealScope.edition || h.metadata.edition === opts.sealScope.edition)) && standardKeyAllowed(h.metadata, opts.standardKeys)
|
|
23475
23483
|
) : lexicalHits0;
|
|
23476
23484
|
if (lexicalHits.length) console.log("lexical prefilter:", lexicalHits.length, "hits");
|
|
23477
23485
|
const ctx = {
|
|
@@ -24735,10 +24743,6 @@ async function editionNote(env, u) {
|
|
|
24735
24743
|
}
|
|
24736
24744
|
|
|
24737
24745
|
export {
|
|
24738
|
-
answerQuality,
|
|
24739
|
-
qualityNote,
|
|
24740
|
-
experimentalSourceLabels,
|
|
24741
|
-
ftsMatchQuery,
|
|
24742
24746
|
refCodec,
|
|
24743
24747
|
NO_CONTEXT,
|
|
24744
24748
|
machineOffers,
|
|
@@ -24749,6 +24753,10 @@ export {
|
|
|
24749
24753
|
parseAppliedContext,
|
|
24750
24754
|
contextNote,
|
|
24751
24755
|
syntheticUnderstanding,
|
|
24756
|
+
answerQuality,
|
|
24757
|
+
qualityNote,
|
|
24758
|
+
experimentalSourceLabels,
|
|
24759
|
+
ftsMatchQuery,
|
|
24752
24760
|
STAGE_NAMES,
|
|
24753
24761
|
promptVars,
|
|
24754
24762
|
fill,
|
package/dist/context.d.ts
CHANGED
|
@@ -111,6 +111,18 @@ export declare function namedDocumentIn(query: string): DocScope | null;
|
|
|
111
111
|
* scoped_to stays null). A registry READ failure proceeds with the
|
|
112
112
|
* parsed scope — a scoped refusal is more honest than silently
|
|
113
113
|
* widening to the whole corpus. */
|
|
114
|
+
/** The seal's grain fix (the 2026-10-09 gate): the corpus stores PART
|
|
115
|
+
* publications at family grain — R 60-1:2021's chunks carry
|
|
116
|
+
* doc_number "60" with the part identity only in the docidentifier —
|
|
117
|
+
* so a scope naming a part ("60-1") admits a family-grain chunk only
|
|
118
|
+
* when the chunk's OWN identifier stem names the same part (the
|
|
119
|
+
* stem's last token is the number, edition and language markers
|
|
120
|
+
* stripped). Exact grain agreement always matches; R 60-2 never
|
|
121
|
+
* passes an R 60-1 chip. */
|
|
122
|
+
export declare function matchesDocScope(meta: {
|
|
123
|
+
doc_number?: string;
|
|
124
|
+
docidentifier?: string;
|
|
125
|
+
}, scopeDocNumber: string): boolean;
|
|
114
126
|
export declare function resolveDocScope(env: any, ctx: DeclaredContext): Promise<DocScope | null>;
|
|
115
127
|
export declare function appliedContext(declared: DeclaredContext | null, scope: DocScope | null, note?: AppliedContext["note"], live?: LiveEcho): AppliedContext;
|
|
116
128
|
/** Validate a context_applied object arriving from a client (the
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
handleMemories,
|
|
5
5
|
scoreFaithfulness,
|
|
6
6
|
scoreJudge
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-PSI5SR2A.js";
|
|
8
8
|
import {
|
|
9
9
|
TOOLS_REGISTRY,
|
|
10
10
|
bindModelNode,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "../../chunk-32UDKBA2.js";
|
|
13
13
|
import {
|
|
14
14
|
handleSearch
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-WUD4XR7Y.js";
|
|
16
16
|
import {
|
|
17
17
|
buildMessages,
|
|
18
18
|
citations,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
sessionFrom,
|
|
35
35
|
telemetry,
|
|
36
36
|
understandQuery
|
|
37
|
-
} from "../../chunk-
|
|
37
|
+
} from "../../chunk-NO4WHD3K.js";
|
|
38
38
|
import {
|
|
39
39
|
cfBlobs,
|
|
40
40
|
embed,
|
|
@@ -1000,7 +1000,7 @@ async function callToolOnce(env, ctx, _req, tier, key, name, args, t0) {
|
|
|
1000
1000
|
const r = await runTool({ ...env, DB: env.DB }, { name, args }, "mcp");
|
|
1001
1001
|
payload = r ? { tool: r.name, query: r.query, result: r.output } : { error: { message: `tool ${name} returned nothing for the given arguments` } };
|
|
1002
1002
|
} else {
|
|
1003
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
1003
|
+
const res = name === "ask" ? await (await import("../../ask-645ZWTEQ.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-6J5FUJOC.js")).handleSearch(env, ctx, inner, tier, key);
|
|
1004
1004
|
payload = await res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
1005
1005
|
}
|
|
1006
1006
|
telemetry(env, ctx, tier, `mcp:${name}`, null, !payload?.error, JSON.stringify(payload).length, await sha256Hex(`${name}:${JSON.stringify(args ?? {})}`), void 0, void 0, { durationMs: Date.now() - t0 });
|
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.113",
|
|
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",
|
|
@@ -170,6 +170,26 @@ export function namedDocumentIn(query: string): DocScope | null {
|
|
|
170
170
|
* scoped_to stays null). A registry READ failure proceeds with the
|
|
171
171
|
* parsed scope — a scoped refusal is more honest than silently
|
|
172
172
|
* widening to the whole corpus. */
|
|
173
|
+
/** The seal's grain fix (the 2026-10-09 gate): the corpus stores PART
|
|
174
|
+
* publications at family grain — R 60-1:2021's chunks carry
|
|
175
|
+
* doc_number "60" with the part identity only in the docidentifier —
|
|
176
|
+
* so a scope naming a part ("60-1") admits a family-grain chunk only
|
|
177
|
+
* when the chunk's OWN identifier stem names the same part (the
|
|
178
|
+
* stem's last token is the number, edition and language markers
|
|
179
|
+
* stripped). Exact grain agreement always matches; R 60-2 never
|
|
180
|
+
* passes an R 60-1 chip. */
|
|
181
|
+
export function matchesDocScope(
|
|
182
|
+
meta: { doc_number?: string; docidentifier?: string },
|
|
183
|
+
scopeDocNumber: string,
|
|
184
|
+
): boolean {
|
|
185
|
+
if (meta.doc_number === scopeDocNumber) return true;
|
|
186
|
+
if (!scopeDocNumber.includes("-")) return false;
|
|
187
|
+
if (meta.doc_number !== scopeDocNumber.split("-")[0]) return false;
|
|
188
|
+
const stem = (meta.docidentifier ?? "").replace(/\s*\([A-Z]\)\s*$/, "").replace(/:\d+$/, "").trim();
|
|
189
|
+
const last = stem.split(/\s+/).pop()?.toLowerCase();
|
|
190
|
+
return last === scopeDocNumber.toLowerCase();
|
|
191
|
+
}
|
|
192
|
+
|
|
173
193
|
export async function resolveDocScope(env: any, ctx: DeclaredContext): Promise<DocScope | null> {
|
|
174
194
|
if (!ctx.doc) return null;
|
|
175
195
|
const parsed = parseDocRef(ctx.doc, ctx.edition);
|
|
@@ -33,6 +33,7 @@ export function fill(template: string, vars: Record<string, string>): string {
|
|
|
33
33
|
return template.replace(/\{\{(\w+)\}\}/g, (_m, k: string) => (k in vars ? vars[k] : ""));
|
|
34
34
|
}
|
|
35
35
|
import { QueryFilters, toVectorizeFilter, standardKeyAllowed } from "./selfquery";
|
|
36
|
+
import { matchesDocScope } from "./context";
|
|
36
37
|
import { hitQuality } from "./quality";
|
|
37
38
|
import { lexicalPrefilter } from "./lexical";
|
|
38
39
|
import { positionOrder } from "./structural";
|
|
@@ -133,7 +134,7 @@ export async function retrieve(
|
|
|
133
134
|
? lexicalHits0.filter(
|
|
134
135
|
(h) =>
|
|
135
136
|
(!opts.sealScope ||
|
|
136
|
-
(h.metadata
|
|
137
|
+
(matchesDocScope(h.metadata, opts.sealScope!.doc_number) &&
|
|
137
138
|
(!opts.sealScope!.edition || h.metadata.edition === opts.sealScope!.edition))) &&
|
|
138
139
|
standardKeyAllowed(h.metadata, opts.standardKeys),
|
|
139
140
|
)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// after every lane has merged, before rerank + the top-N cut. Nothing
|
|
3
3
|
// outside the declared family competes for the window; everything
|
|
4
4
|
// inside it does.
|
|
5
|
+
import { matchesDocScope } from "../context.ts";
|
|
5
6
|
import type { Stage } from "./types.ts";
|
|
6
7
|
|
|
7
8
|
export const seal: Stage = {
|
|
@@ -11,7 +12,7 @@ export const seal: Stage = {
|
|
|
11
12
|
const before = c.hits.length;
|
|
12
13
|
const scope = c.opts.sealScope!;
|
|
13
14
|
if (scope) {
|
|
14
|
-
c.hits = c.hits.filter((h) => h.metadata
|
|
15
|
+
c.hits = c.hits.filter((h) => matchesDocScope(h.metadata, scope.doc_number) && (!scope.edition || h.metadata.edition === scope.edition));
|
|
15
16
|
console.log("context seal:", before, "→", c.hits.length, "candidates within", `doc#${scope.doc_number}${scope.edition ? "@" + scope.edition : ""}`);
|
|
16
17
|
return;
|
|
17
18
|
}
|