@konneal/engine 0.2.100 → 0.2.102
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-KP42T6DH.js → ask-E6YJUOIP.js} +2 -2
- package/dist/{chunk-BBKAETKM.js → chunk-25ECO5M7.js} +45 -23
- package/dist/{chunk-GYCUMFOA.js → chunk-FQVP3JUA.js} +1 -1
- package/dist/{chunk-OREMF5LK.js → chunk-TFGJ6NYS.js} +1 -1
- package/dist/lexical.d.ts +1 -0
- package/dist/{search-4CBKKNBJ.js → search-5SNP5CHL.js} +2 -2
- package/dist/worker_public/src/index.js +4 -4
- package/package.json +1 -1
- package/workers/worker_public/src/lexical.ts +1 -1
- package/workers/worker_public/src/stages/conceptGraph.ts +2 -2
- package/workers/worker_public/src/stages/dense.ts +19 -14
- package/workers/worker_public/src/stages/editionCover.ts +13 -7
- package/workers/worker_public/src/stages/graphLane.ts +8 -2
- package/workers/worker_public/src/stages/index.ts +2 -0
- package/workers/worker_public/src/stages/licensedCover.ts +31 -0
- package/workers/worker_public/src/stages/licensedLane.ts +5 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleAsk
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FQVP3JUA.js";
|
|
4
4
|
import "./chunk-QNLFNEI4.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-25ECO5M7.js";
|
|
6
6
|
import "./chunk-KNCRYAX3.js";
|
|
7
7
|
import "./chunk-DTW4UW2E.js";
|
|
8
8
|
import "./chunk-A3QHHUN5.js";
|
|
@@ -22318,27 +22318,27 @@ async function runStages(stages, c) {
|
|
|
22318
22318
|
var dense = {
|
|
22319
22319
|
name: "dense",
|
|
22320
22320
|
run: async (c) => {
|
|
22321
|
-
const { env,
|
|
22321
|
+
const { env, filters, vector, opts, rq, folded } = c;
|
|
22322
22322
|
const q = { topK: LIMITS.retrieveK, returnMetadata: "all" };
|
|
22323
|
-
if (filter) q.filter = filter;
|
|
22324
22323
|
const optimistic = opts.optimisticHits ?? [];
|
|
22325
22324
|
const sameLane = rq === folded;
|
|
22326
|
-
if (!
|
|
22325
|
+
if (!filters?.doc_number && sameLane && optimistic.length) {
|
|
22327
22326
|
c.matches = optimistic.map((h) => ({ id: h.id, score: h.score, metadata: h.metadata }));
|
|
22328
22327
|
console.log("optimistic lane: reused", c.matches.length, "dense hits (no re-query)");
|
|
22329
22328
|
return;
|
|
22330
22329
|
}
|
|
22331
|
-
if (
|
|
22332
|
-
|
|
22330
|
+
if (filters?.doc_number) {
|
|
22331
|
+
const allMatches = (await env.VECTORIZE.query(vector, q)).matches ?? [];
|
|
22332
|
+
let matches = allMatches;
|
|
22333
|
+
const before = matches.length;
|
|
22334
|
+
matches = matches.filter((m) => String(m.metadata?.doc_number ?? "") === filters.doc_number);
|
|
22335
|
+
if (filters.edition) matches = matches.filter((m) => !m.metadata?.edition || String(m.metadata.edition) === filters.edition);
|
|
22336
|
+
console.log("dense scope (in code):", before, "\u2192", matches.length, "in doc", filters.doc_number, filters.edition ? `@${filters.edition}` : "");
|
|
22333
22337
|
if (filters && filters.edition && matches.length < 3) {
|
|
22334
|
-
const docOnly =
|
|
22335
|
-
|
|
22336
|
-
|
|
22337
|
-
|
|
22338
|
-
});
|
|
22339
|
-
if ((docOnly.matches ?? []).length > matches.length) {
|
|
22340
|
-
console.log("edition pin dropped:", filters.doc_number, "@", filters.edition, "\u2192", docOnly.matches?.length ?? 0, "doc-scoped hits (edition not in corpus)");
|
|
22341
|
-
matches = docOnly.matches ?? [];
|
|
22338
|
+
const docOnly = allMatches.filter((m) => String(m.metadata?.doc_number ?? "") === filters.doc_number);
|
|
22339
|
+
if (docOnly.length > matches.length) {
|
|
22340
|
+
console.log("edition pin dropped:", filters.doc_number, "@", filters.edition, "\u2192", docOnly.length, "doc-scoped hits (edition not in corpus)");
|
|
22341
|
+
matches = docOnly;
|
|
22342
22342
|
filters.edition = void 0;
|
|
22343
22343
|
}
|
|
22344
22344
|
}
|
|
@@ -22520,10 +22520,10 @@ var conceptGraph = {
|
|
|
22520
22520
|
}
|
|
22521
22521
|
}
|
|
22522
22522
|
if (numbers.size) {
|
|
22523
|
-
const gc = await lexicalWithin(c.env, c.rq || c.query, [...numbers],
|
|
22523
|
+
const gc = await lexicalWithin(c.env, c.rq || c.query, [...numbers], 6);
|
|
22524
22524
|
const seenIds0 = new Set(c.matches.map((m) => m.id));
|
|
22525
22525
|
let merged0 = 0;
|
|
22526
|
-
for (const m of gc.slice(0,
|
|
22526
|
+
for (const m of gc.slice(0, 3)) {
|
|
22527
22527
|
if (!seenIds0.has(m.id)) {
|
|
22528
22528
|
c.matches.push({ id: m.id, score: m.score * THRESHOLDS.conceptGraphDiscount, metadata: m.metadata });
|
|
22529
22529
|
seenIds0.add(m.id);
|
|
@@ -22547,9 +22547,9 @@ var graphLane = {
|
|
|
22547
22547
|
const g = await c.lane["graph-lane"];
|
|
22548
22548
|
const seenIds = new Set(c.matches.map((m) => m.id));
|
|
22549
22549
|
let merged = 0;
|
|
22550
|
-
for (const m of (g ?? []).slice(0,
|
|
22550
|
+
for (const m of (g ?? []).slice(0, 5)) {
|
|
22551
22551
|
if (!seenIds.has(m.id)) {
|
|
22552
|
-
c.matches.push({ id: m.id, score: m.score * THRESHOLDS.graphLaneDiscount, metadata: m.metadata });
|
|
22552
|
+
c.matches.push({ id: m.id, score: m.score * THRESHOLDS.graphLaneDiscount * 0.5, metadata: m.metadata });
|
|
22553
22553
|
seenIds.add(m.id);
|
|
22554
22554
|
merged++;
|
|
22555
22555
|
}
|
|
@@ -22580,17 +22580,40 @@ var licensedLane = {
|
|
|
22580
22580
|
const matches = await portIndex(c.env, "public").getByIds(ids);
|
|
22581
22581
|
const seenIds = new Set(c.matches.map((m) => m.id));
|
|
22582
22582
|
let merged = 0;
|
|
22583
|
+
const mergedIds = [];
|
|
22583
22584
|
for (const m of matches) {
|
|
22584
22585
|
if (m.metadata && !seenIds.has(m.id)) {
|
|
22585
22586
|
c.matches.push({ id: m.id, score: THRESHOLDS.licensedLaneScore, metadata: m.metadata });
|
|
22586
22587
|
seenIds.add(m.id);
|
|
22587
22588
|
merged++;
|
|
22589
|
+
mergedIds.push(m.id);
|
|
22588
22590
|
}
|
|
22589
22591
|
}
|
|
22592
|
+
c.lane["licensed-ids"] = Promise.resolve(mergedIds);
|
|
22590
22593
|
console.log("licensed lane:", ids.length, "units,", matches.length, "vectors,", merged, "merged");
|
|
22591
22594
|
}
|
|
22592
22595
|
};
|
|
22593
22596
|
|
|
22597
|
+
// workers/worker_public/src/stages/licensedCover.ts
|
|
22598
|
+
var licensedCover = {
|
|
22599
|
+
name: "licensed-cover",
|
|
22600
|
+
failure: "additive",
|
|
22601
|
+
when: (c) => !!c.opts.licensedDocNumbers?.length && c.finalHits.length > 0,
|
|
22602
|
+
run: async (c) => {
|
|
22603
|
+
const keys = new Set(c.opts.licensedDocNumbers);
|
|
22604
|
+
const present = c.finalHits.some((h) => keys.has(String(h.metadata.standard ?? "")));
|
|
22605
|
+
if (present) return;
|
|
22606
|
+
const ids = (await c.lane["licensed-ids"] ?? []).slice(0, 8);
|
|
22607
|
+
if (!ids.length) return;
|
|
22608
|
+
const matches = await portIndex(c.env, "public").getByIds(ids);
|
|
22609
|
+
const unit = matches.find((m) => m.metadata && keys.has(String(m.metadata.standard ?? "")));
|
|
22610
|
+
if (!unit) return;
|
|
22611
|
+
const hit = toHits([unit])[0];
|
|
22612
|
+
c.finalHits = [...c.finalHits, hit];
|
|
22613
|
+
console.log("licensed cover: seated", unit.id, "\u2014", unit.metadata.docidentifier);
|
|
22614
|
+
}
|
|
22615
|
+
};
|
|
22616
|
+
|
|
22594
22617
|
// workers/worker_public/src/stages/multiQuery.ts
|
|
22595
22618
|
var RRF_K = 60;
|
|
22596
22619
|
var multiQuery = {
|
|
@@ -22798,12 +22821,10 @@ var editionCover = {
|
|
|
22798
22821
|
let added = 0;
|
|
22799
22822
|
for (const w of want.slice(0, maxDocs)) {
|
|
22800
22823
|
try {
|
|
22801
|
-
const
|
|
22802
|
-
|
|
22803
|
-
|
|
22804
|
-
|
|
22805
|
-
});
|
|
22806
|
-
const hits = toHits(q.matches ?? []).map((h) => ({ ...h, score: top * THRESHOLDS.editionCoverDiscount }));
|
|
22824
|
+
const rows2 = await c.env.DB.prepare(
|
|
22825
|
+
"SELECT id, doc_id, docidentifier, doctype, doc_number, edition, language, clause_anchor, clause_title, status, superseded_by, corpus, tier, text FROM chunks WHERE docidentifier = ?1 AND edition = ?2 LIMIT 3"
|
|
22826
|
+
).bind(w.di, w.edition).all();
|
|
22827
|
+
const hits = rowsToHits(rows2.results ?? []).map((h) => ({ ...h, score: top * THRESHOLDS.editionCoverDiscount }));
|
|
22807
22828
|
c.hits.push(...hits);
|
|
22808
22829
|
added += hits.length;
|
|
22809
22830
|
console.log("edition cover:", w.di, w.edition, `+${hits.length}`);
|
|
@@ -23223,6 +23244,7 @@ var STAGES = [
|
|
|
23223
23244
|
editionSteer,
|
|
23224
23245
|
propagate,
|
|
23225
23246
|
diversity,
|
|
23247
|
+
licensedCover,
|
|
23226
23248
|
typedPin,
|
|
23227
23249
|
sectionDescent,
|
|
23228
23250
|
dedup,
|
package/dist/lexical.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Hit } from "./pipeline";
|
|
|
2
2
|
/** Build a safe FTS5 MATCH query from user text: alphanumeric tokens,
|
|
3
3
|
* joined with OR so jargon hits don't require full-phrase match. */
|
|
4
4
|
export declare function ftsMatchQuery(query: string): string | null;
|
|
5
|
+
export declare function rowsToHits(rows: any[]): Hit[];
|
|
5
6
|
/** Lexical ranking WITHIN a document set (the graph lanes' identity
|
|
6
7
|
* resolution): BM25 over the corpus's own FTS, restricted to the
|
|
7
8
|
* documents' doc_number values. This is the working substitute for
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
handleMemories,
|
|
5
5
|
scoreFaithfulness,
|
|
6
6
|
scoreJudge
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-FQVP3JUA.js";
|
|
8
8
|
import {
|
|
9
9
|
TOOLS_REGISTRY,
|
|
10
10
|
bindModelNode,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "../../chunk-QNLFNEI4.js";
|
|
13
13
|
import {
|
|
14
14
|
handleSearch
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-TFGJ6NYS.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-25ECO5M7.js";
|
|
38
38
|
import {
|
|
39
39
|
cfBlobs,
|
|
40
40
|
embed,
|
|
@@ -996,7 +996,7 @@ async function callToolOnce(env, ctx, _req, tier, key, name, args, t0) {
|
|
|
996
996
|
const r = await runTool({ ...env, DB: env.DB }, { name, args }, "mcp");
|
|
997
997
|
payload = r ? { tool: r.name, query: r.query, result: r.output } : { error: { message: `tool ${name} returned nothing for the given arguments` } };
|
|
998
998
|
} else {
|
|
999
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
999
|
+
const res = name === "ask" ? await (await import("../../ask-E6YJUOIP.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-5SNP5CHL.js")).handleSearch(env, ctx, inner, tier, key);
|
|
1000
1000
|
payload = await res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
1001
1001
|
}
|
|
1002
1002
|
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.102",
|
|
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",
|
|
@@ -53,7 +53,7 @@ function rowMeta(r: any): ChunkMeta {
|
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function rowsToHits(rows: any[]): Hit[] {
|
|
56
|
+
export function rowsToHits(rows: any[]): Hit[] {
|
|
57
57
|
return rows.map((r: any) => {
|
|
58
58
|
// rank is bm25 (lower better) → convert to positive score that RRF can ignore
|
|
59
59
|
// (RRF uses rank position, not score). score kept for logging only.
|
|
@@ -54,10 +54,10 @@ export const conceptGraph: Stage = {
|
|
|
54
54
|
// candidates rank by the corpus's own BM25 within the set — the
|
|
55
55
|
// index filter this lane used returned empty for its whole life
|
|
56
56
|
// (Vectorize metadata filtering is dead on this index)
|
|
57
|
-
const gc = await lexicalWithin(c.env, c.rq || c.query, [...numbers],
|
|
57
|
+
const gc = await lexicalWithin(c.env, c.rq || c.query, [...numbers], 6);
|
|
58
58
|
const seenIds0 = new Set(c.matches.map((m: any) => m.id));
|
|
59
59
|
let merged0 = 0;
|
|
60
|
-
for (const m of gc.slice(0,
|
|
60
|
+
for (const m of gc.slice(0, 3)) {
|
|
61
61
|
if (!seenIds0.has(m.id)) {
|
|
62
62
|
c.matches.push({ id: m.id, score: m.score * THRESHOLDS.conceptGraphDiscount, metadata: m.metadata });
|
|
63
63
|
seenIds0.add(m.id);
|
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
// saved), the doc/edition-filtered query with its guessed-pin drop and
|
|
5
5
|
// sparse-filter widen, and the plain unfiltered query.
|
|
6
6
|
import { LIMITS } from "../config.ts";
|
|
7
|
-
import { toVectorizeFilter } from "../selfquery.ts";
|
|
8
7
|
import type { Stage } from "./types.ts";
|
|
9
8
|
|
|
10
9
|
export const dense: Stage = {
|
|
11
10
|
name: "dense",
|
|
12
11
|
run: async (c) => {
|
|
13
|
-
const { env,
|
|
12
|
+
const { env, filters, vector, opts, rq, folded } = c;
|
|
13
|
+
// the index's metadata filtering is DEAD on this platform (measured
|
|
14
|
+
// 2026-10-05: filters return empty for values proven present), so
|
|
15
|
+
// the scope never rides the query — the matches filter IN CODE and
|
|
16
|
+
// the sparse widen still covers thin scopes
|
|
14
17
|
const q: any = { topK: LIMITS.retrieveK, returnMetadata: "all" };
|
|
15
|
-
if (filter) q.filter = filter;
|
|
16
18
|
const optimistic = opts.optimisticHits ?? [];
|
|
17
19
|
const sameLane = rq === folded; // optimistic vector === this lane's vector
|
|
18
|
-
if (!
|
|
20
|
+
if (!filters?.doc_number && sameLane && optimistic.length) {
|
|
19
21
|
// Option C fast path: the unfiltered dense query already ran
|
|
20
22
|
// concurrently with understanding — same vector, same topK, no
|
|
21
23
|
// filter. Reusing it skips one serial Vectorize round-trip with a
|
|
@@ -31,8 +33,13 @@ export const dense: Stage = {
|
|
|
31
33
|
// REPLACE an identical query, never dilute a better one.
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
+
if (filters?.doc_number) {
|
|
37
|
+
const allMatches: any[] = (await env.VECTORIZE.query(vector, q)).matches ?? [];
|
|
38
|
+
let matches: any[] = allMatches;
|
|
39
|
+
const before = matches.length;
|
|
40
|
+
matches = matches.filter((m) => String(m.metadata?.doc_number ?? "") === filters.doc_number);
|
|
41
|
+
if (filters.edition) matches = matches.filter((m) => !m.metadata?.edition || String(m.metadata.edition) === filters.edition);
|
|
42
|
+
console.log("dense scope (in code):", before, "→", matches.length, "in doc", filters.doc_number, filters.edition ? `@${filters.edition}` : "");
|
|
36
43
|
// an edition pin corroborated by (almost) nothing means the pin
|
|
37
44
|
// was a guess — understanding emits editions for families it
|
|
38
45
|
// mixes up (observed: R 76 pinned @2021, an R 60 year; the corpus
|
|
@@ -42,15 +49,13 @@ export const dense: Stage = {
|
|
|
42
49
|
// the doc-only filter and let family-relative steering rank
|
|
43
50
|
// editions downstream. A pin the user actually asked for
|
|
44
51
|
// survives — its edition exists in the corpus.
|
|
52
|
+
// the same guess-drop, in code: a pinned edition that starved the
|
|
53
|
+
// scoped set drops to the doc-only scope
|
|
45
54
|
if (filters && filters.edition && matches.length < 3) {
|
|
46
|
-
const docOnly =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
});
|
|
51
|
-
if ((docOnly.matches ?? []).length > matches.length) {
|
|
52
|
-
console.log("edition pin dropped:", filters.doc_number, "@", filters.edition, "→", docOnly.matches?.length ?? 0, "doc-scoped hits (edition not in corpus)");
|
|
53
|
-
matches = docOnly.matches ?? [];
|
|
55
|
+
const docOnly = allMatches.filter((m) => String(m.metadata?.doc_number ?? "") === filters.doc_number);
|
|
56
|
+
if (docOnly.length > matches.length) {
|
|
57
|
+
console.log("edition pin dropped:", filters.doc_number, "@", filters.edition, "→", docOnly.length, "doc-scoped hits (edition not in corpus)");
|
|
58
|
+
matches = docOnly;
|
|
54
59
|
filters.edition = undefined;
|
|
55
60
|
}
|
|
56
61
|
}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// left every 2021 chunk out). One registry read per query; at most
|
|
8
8
|
// `maxDocs` documents covered; additive — any failure skips.
|
|
9
9
|
import { THRESHOLDS } from "../config.ts";
|
|
10
|
-
import {
|
|
10
|
+
import type { Stage } from "./types.ts";
|
|
11
|
+
import { rowsToHits } from "../lexical.ts";
|
|
11
12
|
|
|
12
13
|
const maxDocs = 2;
|
|
13
14
|
|
|
@@ -43,12 +44,17 @@ export const editionCover: Stage = {
|
|
|
43
44
|
let added = 0;
|
|
44
45
|
for (const w of want.slice(0, maxDocs)) {
|
|
45
46
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
47
|
+
// identity resolution, not index filtering: the index's metadata
|
|
48
|
+
// filters are dead on this platform (measured 2026-10-05 — the
|
|
49
|
+
// cover's $and docidentifier/edition query returned empty for
|
|
50
|
+
// its whole life), but the D1 chunks table IS the corpus — the
|
|
51
|
+
// current edition's chunks read directly, text and all
|
|
52
|
+
const rows = await c.env.DB.prepare(
|
|
53
|
+
"SELECT id, doc_id, docidentifier, doctype, doc_number, edition, language, clause_anchor, clause_title, status, superseded_by, corpus, tier, text FROM chunks WHERE docidentifier = ?1 AND edition = ?2 LIMIT 3",
|
|
54
|
+
)
|
|
55
|
+
.bind(w.di, w.edition)
|
|
56
|
+
.all();
|
|
57
|
+
const hits = rowsToHits(rows.results ?? []).map((h) => ({ ...h, score: top * THRESHOLDS.editionCoverDiscount }));
|
|
52
58
|
c.hits.push(...hits);
|
|
53
59
|
added += hits.length;
|
|
54
60
|
console.log("edition cover:", w.di, w.edition, `+${hits.length}`);
|
|
@@ -23,9 +23,15 @@ export const graphLane: Stage = {
|
|
|
23
23
|
const g = (await c.lane["graph-lane"]!) as any;
|
|
24
24
|
const seenIds = new Set(c.matches.map((m: any) => m.id));
|
|
25
25
|
let merged = 0;
|
|
26
|
-
|
|
26
|
+
// narrow by the reverted experiment's own law (rag#137): candidate-
|
|
27
|
+
// family flooding dilutes the pool — five candidates, and at HALF
|
|
28
|
+
// the lane discount so only family text the cross-encoder genuinely
|
|
29
|
+
// prefers survives the cut (the first breathing gate measured the
|
|
30
|
+
// flood signature: faithfulness sagging across unrelated legs and
|
|
31
|
+
// the typed blocks displaced from the context)
|
|
32
|
+
for (const m of (g ?? []).slice(0, 5)) {
|
|
27
33
|
if (!seenIds.has(m.id)) {
|
|
28
|
-
c.matches.push({ id: m.id, score: m.score * THRESHOLDS.graphLaneDiscount, metadata: m.metadata });
|
|
34
|
+
c.matches.push({ id: m.id, score: m.score * THRESHOLDS.graphLaneDiscount * 0.5, metadata: m.metadata });
|
|
29
35
|
seenIds.add(m.id);
|
|
30
36
|
merged++;
|
|
31
37
|
}
|
|
@@ -18,6 +18,7 @@ import { glossary } from "./glossary.ts";
|
|
|
18
18
|
import { conceptGraph } from "./conceptGraph.ts";
|
|
19
19
|
import { graphLane } from "./graphLane.ts";
|
|
20
20
|
import { licensedLane } from "./licensedLane.ts";
|
|
21
|
+
import { licensedCover } from "./licensedCover.ts";
|
|
21
22
|
import { multiQuery } from "./multiQuery.ts";
|
|
22
23
|
import { subQuery } from "./subQuery.ts";
|
|
23
24
|
import { poolOpen } from "./poolOpen.ts";
|
|
@@ -68,6 +69,7 @@ export const STAGES: Stage[] = [
|
|
|
68
69
|
editionSteer,
|
|
69
70
|
propagate,
|
|
70
71
|
diversity,
|
|
72
|
+
licensedCover,
|
|
71
73
|
typedPin,
|
|
72
74
|
sectionDescent,
|
|
73
75
|
dedup,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Licensed cover (the seat): an entitled, topically-matched caller
|
|
2
|
+
// asked about the licensed standard, so the licensed package's own
|
|
3
|
+
// machinery must be ABLE to reach the answer — the public restatements
|
|
4
|
+
// crowd the window and the citation the golden legs assert rides this
|
|
5
|
+
// passage. When the rerank cut drops every licensed unit, the lane's
|
|
6
|
+
// best unit takes one seat at the end of the window (appended after
|
|
7
|
+
// ranking, like the section-descent children — the window floor keeps
|
|
8
|
+
// appended passages by construction). Narrow by law: one unit, only
|
|
9
|
+
// when none is present, only for an armed licensed lane.
|
|
10
|
+
import { portIndex } from "../env.ts";
|
|
11
|
+
import { toHits } from "./types.ts";
|
|
12
|
+
import type { Stage } from "./types.ts";
|
|
13
|
+
|
|
14
|
+
export const licensedCover: Stage = {
|
|
15
|
+
name: "licensed-cover",
|
|
16
|
+
failure: "additive",
|
|
17
|
+
when: (c) => !!c.opts.licensedDocNumbers?.length && c.finalHits.length > 0,
|
|
18
|
+
run: async (c) => {
|
|
19
|
+
const keys = new Set(c.opts.licensedDocNumbers!);
|
|
20
|
+
const present = c.finalHits.some((h) => keys.has(String((h.metadata as any).standard ?? "")));
|
|
21
|
+
if (present) return;
|
|
22
|
+
const ids = ((await (c.lane["licensed-ids"] as Promise<string[]> | undefined)) ?? []).slice(0, 8);
|
|
23
|
+
if (!ids.length) return;
|
|
24
|
+
const matches = await portIndex(c.env, "public").getByIds(ids);
|
|
25
|
+
const unit = matches.find((m) => m.metadata && keys.has(String((m.metadata as any).standard ?? "")));
|
|
26
|
+
if (!unit) return;
|
|
27
|
+
const hit = toHits([unit as any])[0]!;
|
|
28
|
+
c.finalHits = [...c.finalHits, hit];
|
|
29
|
+
console.log("licensed cover: seated", unit.id, "—", (unit.metadata as any).docidentifier);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -44,13 +44,18 @@ export const licensedLane: Stage = {
|
|
|
44
44
|
const matches = await portIndex(c.env, "public").getByIds(ids);
|
|
45
45
|
const seenIds = new Set(c.matches.map((m: any) => m.id));
|
|
46
46
|
let merged = 0;
|
|
47
|
+
const mergedIds: string[] = [];
|
|
47
48
|
for (const m of matches) {
|
|
48
49
|
if (m.metadata && !seenIds.has(m.id)) {
|
|
49
50
|
c.matches.push({ id: m.id, score: THRESHOLDS.licensedLaneScore, metadata: m.metadata });
|
|
50
51
|
seenIds.add(m.id);
|
|
51
52
|
merged++;
|
|
53
|
+
mergedIds.push(m.id);
|
|
52
54
|
}
|
|
53
55
|
}
|
|
56
|
+
// the cover stage's stash: the licensed units' ids, so the seat can
|
|
57
|
+
// recover a unit the rerank cut dropped
|
|
58
|
+
c.lane["licensed-ids"] = Promise.resolve(mergedIds);
|
|
54
59
|
console.log("licensed lane:", ids.length, "units,", matches.length, "vectors,", merged, "merged");
|
|
55
60
|
},
|
|
56
61
|
};
|