@konneal/engine 0.2.103 → 0.2.109
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/ablate.d.ts +31 -0
- package/dist/ask-EAKLN77G.js +15 -0
- package/dist/{chunk-25ECO5M7.js → chunk-2R7OVYAO.js} +377 -185
- package/dist/{chunk-U4ERFUOK.js → chunk-4NXH5ZI6.js} +1 -1
- package/dist/{chunk-DTW4UW2E.js → chunk-DJ65EF5G.js} +1 -1
- package/dist/{chunk-NCZHN6QW.js → chunk-G4KBK5XZ.js} +175 -22
- package/dist/{chunk-ANUHRJ4Z.js → chunk-G56TYXNN.js} +3 -3
- package/dist/{chunk-TFGJ6NYS.js → chunk-HAU5INEJ.js} +5 -5
- package/dist/{chunk-KNCRYAX3.js → chunk-TH5XGPD5.js} +1 -1
- package/dist/{chunk-BOAITSVV.js → chunk-VT7DR6NQ.js} +11 -1
- package/dist/config.d.ts +6 -0
- package/dist/openapi-types.d.ts +24 -0
- package/dist/prompts/doc-summary.md +1 -0
- package/dist/prompts/speculative-verify.md +9 -0
- package/dist/route.d.ts +29 -0
- package/dist/search-HKGN7F3O.js +13 -0
- package/dist/speculative.d.ts +9 -0
- package/dist/{tools-EXDADNWX.js → tools-WSWEGJVQ.js} +4 -4
- package/dist/worker_mcp/src/index.js +2 -2
- package/dist/worker_public/src/config.js +1 -1
- package/dist/worker_public/src/index.js +21 -17
- package/dist/worker_public/src/requestScope.js +2 -2
- package/docs/spec-pipeline.md +12 -1
- package/package.json +1 -1
- package/workers/worker_public/openapi.yaml +53 -0
- package/workers/worker_public/prompts/doc-summary.md +1 -0
- package/workers/worker_public/prompts/speculative-verify.md +9 -0
- package/workers/worker_public/src/ablate.ts +97 -0
- package/workers/worker_public/src/admin.ts +14 -6
- package/workers/worker_public/src/ask.ts +120 -16
- package/workers/worker_public/src/config.ts +10 -0
- package/workers/worker_public/src/index.ts +6 -2
- package/workers/worker_public/src/pipeline.ts +5 -2
- package/workers/worker_public/src/route.ts +77 -0
- package/workers/worker_public/src/speculative.ts +39 -0
- package/workers/worker_public/src/stages/graphPpr.ts +189 -0
- package/workers/worker_public/src/stages/index.ts +19 -0
- package/workers/worker_public/src/stages/sectionDescent.ts +91 -7
- package/workers/worker_public/src/stages/types.ts +6 -0
- package/dist/ask-M3VRAIJB.js +0 -15
- package/dist/search-5SNP5CHL.js +0 -13
|
@@ -17,6 +17,7 @@ import { hyde } from "./hyde.ts";
|
|
|
17
17
|
import { glossary } from "./glossary.ts";
|
|
18
18
|
import { conceptGraph } from "./conceptGraph.ts";
|
|
19
19
|
import { graphLane } from "./graphLane.ts";
|
|
20
|
+
import { graphPpr } from "./graphPpr.ts";
|
|
20
21
|
import { licensedLane } from "./licensedLane.ts";
|
|
21
22
|
import { licensedCover } from "./licensedCover.ts";
|
|
22
23
|
import { multiQuery } from "./multiQuery.ts";
|
|
@@ -48,6 +49,7 @@ export const STAGES: Stage[] = [
|
|
|
48
49
|
glossary,
|
|
49
50
|
conceptGraph,
|
|
50
51
|
graphLane,
|
|
52
|
+
graphPpr,
|
|
51
53
|
licensedLane,
|
|
52
54
|
multiQuery,
|
|
53
55
|
subQuery,
|
|
@@ -75,3 +77,20 @@ export const STAGES: Stage[] = [
|
|
|
75
77
|
dedup,
|
|
76
78
|
windowFloor,
|
|
77
79
|
];
|
|
80
|
+
|
|
81
|
+
export const STAGE_NAMES: string[] = STAGES.map((s) => s.name);
|
|
82
|
+
|
|
83
|
+
/** The ablation switch (TODO.sota/09): a configuration is a stage list.
|
|
84
|
+
* The projection keeps REGISTRY order — a subset can narrow the
|
|
85
|
+
* pipeline, never reorder it (the ordering invariants are
|
|
86
|
+
* load-bearing). Unknown names throw so a typo'd configuration can
|
|
87
|
+
* never measure the wrong pipeline silently. */
|
|
88
|
+
export function projectStages(names: readonly string[]): Stage[] {
|
|
89
|
+
const wanted = new Set(names);
|
|
90
|
+
const projected = STAGES.filter((s) => wanted.has(s.name));
|
|
91
|
+
if (projected.length !== wanted.size) {
|
|
92
|
+
const known = new Set(STAGE_NAMES);
|
|
93
|
+
for (const n of wanted) if (!known.has(n)) throw new Error(`unknown stage: ${n}`);
|
|
94
|
+
}
|
|
95
|
+
return projected;
|
|
96
|
+
}
|
|
@@ -1,15 +1,60 @@
|
|
|
1
|
-
// Section-summary units → leaf evidence (FABLE multi-granularity
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
1
|
+
// Section-summary units → leaf evidence (FABLE multi-granularity, the
|
|
2
|
+
// RAPTOR extension of TODO.sota/06's catalog row 3): a ranked summary
|
|
3
|
+
// is a navigation node, not quotable evidence — the stage descends it
|
|
4
|
+
// to source clauses and retires the synthetic node. Two levels:
|
|
5
|
+
// level 1 (section summary): child_anchors are CLAUSE anchors — the
|
|
6
|
+
// same-query vector search finds the clauses within the document.
|
|
7
|
+
// level 2 (document summary): child_anchors are LEVEL-1 UNIT ids —
|
|
8
|
+
// they come back by id (the ≤20 getByIds law), and each consumed
|
|
9
|
+
// section's clauses come from the D1 corpus DIRECTLY (the l6a law:
|
|
10
|
+
// the corpus is the source of truth; the index metadata filters
|
|
11
|
+
// are dead on this index).
|
|
12
|
+
// The summary stays only when no child answered (it is then the doc's
|
|
13
|
+
// sole representative).
|
|
8
14
|
import { THRESHOLDS } from "../config.ts";
|
|
9
15
|
import type { ChunkMeta } from "../../../shared/chunk";
|
|
10
16
|
import type { Hit } from "../../../shared/chunk";
|
|
11
17
|
import type { Stage } from "./types.ts";
|
|
12
18
|
|
|
19
|
+
const CHUNK_COLS =
|
|
20
|
+
"id, doc_id, docidentifier, doctype, doc_number, edition, language, clause_anchor, clause_title, status, superseded_by, corpus, tier, text, unit_id, block";
|
|
21
|
+
|
|
22
|
+
/** A level-2 document summary's section children, by id (the ≤20
|
|
23
|
+
* getByIds law caps each read). */
|
|
24
|
+
async function sectionChildren(env: any, unitIds: string[]): Promise<Hit[]> {
|
|
25
|
+
const kids: Hit[] = [];
|
|
26
|
+
for (let i = 0; i < unitIds.length; i += 20) {
|
|
27
|
+
const got = (await env.VECTORIZE.getByIds(unitIds.slice(i, i + 20))) ?? [];
|
|
28
|
+
for (const v of got) {
|
|
29
|
+
if (!v?.metadata?.child_anchors) continue;
|
|
30
|
+
kids.push({
|
|
31
|
+
id: v.id,
|
|
32
|
+
score: 0,
|
|
33
|
+
metadata: v.metadata as ChunkMeta,
|
|
34
|
+
text: String((v.metadata as any).chunk_text ?? ""),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return kids;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** A section's child clauses, from the D1 corpus directly. */
|
|
42
|
+
async function clausesOf(env: any, docId: string, anchors: string[], limit: number): Promise<Hit[]> {
|
|
43
|
+
const marks = anchors.map(() => "?").join(",");
|
|
44
|
+
const res = await env.DB.prepare(
|
|
45
|
+
`SELECT ${CHUNK_COLS} FROM chunks WHERE doc_id = ? AND clause_anchor IN (${marks}) LIMIT ${limit}`,
|
|
46
|
+
)
|
|
47
|
+
.bind(docId, ...anchors)
|
|
48
|
+
.all()
|
|
49
|
+
.catch(() => ({ results: [] }));
|
|
50
|
+
return (res.results ?? []).map((r: any) => ({
|
|
51
|
+
id: String(r.id),
|
|
52
|
+
score: 0,
|
|
53
|
+
metadata: r as unknown as ChunkMeta,
|
|
54
|
+
text: String(r.text ?? ""),
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
|
|
13
58
|
export const sectionDescent: Stage = {
|
|
14
59
|
name: "section-descent",
|
|
15
60
|
failure: "additive",
|
|
@@ -20,6 +65,45 @@ export const sectionDescent: Stage = {
|
|
|
20
65
|
const sectionHit = c.finalHits.find(
|
|
21
66
|
(h) => h.metadata.section_summary === "1" && h.metadata.child_anchors && h.score > 0,
|
|
22
67
|
)!;
|
|
68
|
+
|
|
69
|
+
if ((sectionHit.metadata as any).summary_level === "2") {
|
|
70
|
+
// document summary → its leading section nodes → their clauses
|
|
71
|
+
const unitIds = sectionHit
|
|
72
|
+
.metadata.child_anchors!.split(",")
|
|
73
|
+
.map((s) => s.trim())
|
|
74
|
+
.filter(Boolean)
|
|
75
|
+
.slice(0, 12);
|
|
76
|
+
const kids = await sectionChildren(c.env, unitIds);
|
|
77
|
+
// document reading order (child_anchors order) is the doc-scope
|
|
78
|
+
// prior; the summaries were written in it
|
|
79
|
+
const order = new Map(unitIds.map((id, i) => [id, i]));
|
|
80
|
+
kids.sort((a, b) => (order.get(a.id) ?? 99) - (order.get(b.id) ?? 99));
|
|
81
|
+
const collected: Hit[] = [];
|
|
82
|
+
const consumed: string[] = [];
|
|
83
|
+
for (const kid of kids.slice(0, 2)) {
|
|
84
|
+
const anchors = kid.metadata.child_anchors!.split(",").map((s) => s.trim()).filter(Boolean).slice(0, 25);
|
|
85
|
+
if (!anchors.length) continue;
|
|
86
|
+
const clauses = (await clausesOf(c.env, String(kid.metadata.doc_id), anchors, 6))
|
|
87
|
+
.filter((x) => !c.finalHits.some((h) => h.id === x.id) && !collected.some((h) => h.id === x.id))
|
|
88
|
+
.slice(0, 2)
|
|
89
|
+
.map((x) => ({ ...x, score: sectionHit.score * THRESHOLDS.sectionDescentDiscount }));
|
|
90
|
+
if (clauses.length) {
|
|
91
|
+
collected.push(...clauses);
|
|
92
|
+
consumed.push(kid.id);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (collected.length) {
|
|
96
|
+
c.finalHits = [...c.finalHits.filter((h) => h !== sectionHit), ...collected];
|
|
97
|
+
console.log(
|
|
98
|
+
"section descent (doc):",
|
|
99
|
+
sectionHit.metadata.docidentifier,
|
|
100
|
+
"→",
|
|
101
|
+
collected.map((x) => "§" + x.metadata.clause_anchor).join(", "),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
23
107
|
const kids = sectionHit
|
|
24
108
|
.metadata.child_anchors!.split(",")
|
|
25
109
|
.map((s) => s.trim())
|
|
@@ -67,6 +67,12 @@ export interface RetrieveOptions {
|
|
|
67
67
|
* metadata stays). Null = the deployment declares no licensed
|
|
68
68
|
* content, the scope is inert. */
|
|
69
69
|
standardKeys?: Set<string> | null;
|
|
70
|
+
/** The ablation switch (TODO.sota/09): run the registry PROJECTED to
|
|
71
|
+
* these stage names (registry order preserved, unknown names throw —
|
|
72
|
+
* projectStages owns the semantics). Absent = the full registry.
|
|
73
|
+
* Admin-gated at the ask boundary (src/ablate.ts); a stage-subset
|
|
74
|
+
* ask never reads or writes the answer caches. */
|
|
75
|
+
stageSubset?: string[];
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
export interface GlossaryEntry {
|
package/dist/ask-M3VRAIJB.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleAsk
|
|
3
|
-
} from "./chunk-NCZHN6QW.js";
|
|
4
|
-
import "./chunk-ANUHRJ4Z.js";
|
|
5
|
-
import "./chunk-25ECO5M7.js";
|
|
6
|
-
import "./chunk-KNCRYAX3.js";
|
|
7
|
-
import "./chunk-DTW4UW2E.js";
|
|
8
|
-
import "./chunk-A3QHHUN5.js";
|
|
9
|
-
import "./chunk-U4ERFUOK.js";
|
|
10
|
-
import "./chunk-BOAITSVV.js";
|
|
11
|
-
import "./chunk-JZFXSTYX.js";
|
|
12
|
-
import "./chunk-3FYJM7LH.js";
|
|
13
|
-
export {
|
|
14
|
-
handleAsk
|
|
15
|
-
};
|
package/dist/search-5SNP5CHL.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleSearch
|
|
3
|
-
} from "./chunk-TFGJ6NYS.js";
|
|
4
|
-
import "./chunk-25ECO5M7.js";
|
|
5
|
-
import "./chunk-KNCRYAX3.js";
|
|
6
|
-
import "./chunk-DTW4UW2E.js";
|
|
7
|
-
import "./chunk-A3QHHUN5.js";
|
|
8
|
-
import "./chunk-U4ERFUOK.js";
|
|
9
|
-
import "./chunk-BOAITSVV.js";
|
|
10
|
-
import "./chunk-3FYJM7LH.js";
|
|
11
|
-
export {
|
|
12
|
-
handleSearch
|
|
13
|
-
};
|