@konneal/engine 0.2.71 → 0.2.72
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-OUNG3JIC.js → ask-UOTYZ5DC.js} +2 -2
- package/dist/{certificates-DNRUOYRF.js → certificates-EMHFAUWC.js} +1 -1
- package/dist/{chunk-VGVTIPFW.js → chunk-3IRX4B7Q.js} +1 -1
- package/dist/{chunk-EOQVQBS6.js → chunk-UW5M2AXR.js} +50 -8
- package/dist/operations.d.ts +4 -0
- package/dist/worker_public/src/index.js +3 -3
- package/package.json +1 -1
- package/workers/worker_public/src/certificates.ts +1 -1
- package/workers/worker_public/src/operations.ts +44 -12
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleAsk
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UW5M2AXR.js";
|
|
4
4
|
import "./chunk-TPV5GPY2.js";
|
|
5
5
|
import "./chunk-SPKPH54J.js";
|
|
6
6
|
import "./chunk-A3QHHUN5.js";
|
|
7
7
|
import "./chunk-LVZTWUVJ.js";
|
|
8
8
|
import "./chunk-2PCUAJJO.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-3IRX4B7Q.js";
|
|
10
10
|
import "./chunk-3FYJM7LH.js";
|
|
11
11
|
export {
|
|
12
12
|
handleAsk
|
|
@@ -121,7 +121,7 @@ function registerNote(rows) {
|
|
|
121
121
|
].join("\n");
|
|
122
122
|
}
|
|
123
123
|
function certificateLinks(rows) {
|
|
124
|
-
const links = rows.filter((r) => r.pdf_key).map((r) => `- ${r.num}: https://www.
|
|
124
|
+
const links = rows.filter((r) => r.pdf_key).map((r) => `- ${r.num}: https://www.ommisa.org/cert-pdf/${r.pdf_key}`);
|
|
125
125
|
return links.length ? `The certificates' documents:
|
|
126
126
|
${links.join("\n")}` : "";
|
|
127
127
|
}
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
certificateLinks,
|
|
69
69
|
registerNote,
|
|
70
70
|
searchRegister
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-3IRX4B7Q.js";
|
|
72
72
|
import {
|
|
73
73
|
P
|
|
74
74
|
} from "./chunk-3FYJM7LH.js";
|
|
@@ -1892,7 +1892,7 @@ async function runTool(db, call) {
|
|
|
1892
1892
|
if (call.name !== "register_search") return null;
|
|
1893
1893
|
const query = String(call.args?.query ?? "").trim().slice(0, 160);
|
|
1894
1894
|
if (!query) return null;
|
|
1895
|
-
const { searchRegister: searchRegister2, registerNote: registerNote2 } = await import("./certificates-
|
|
1895
|
+
const { searchRegister: searchRegister2, registerNote: registerNote2 } = await import("./certificates-EMHFAUWC.js");
|
|
1896
1896
|
const reg = await searchRegister2(db, query, true);
|
|
1897
1897
|
const output = reg?.rows?.length ? registerNote2(reg.rows) : `No certificate was found for "${query}" in the certificates database (the register snapshot). State this as the search's result, with the searched string visible.`;
|
|
1898
1898
|
return { name: call.name, query, output };
|
|
@@ -1929,17 +1929,59 @@ var ACTION_STEMS = [
|
|
|
1929
1929
|
"announc",
|
|
1930
1930
|
"download"
|
|
1931
1931
|
];
|
|
1932
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
1933
|
+
"which",
|
|
1934
|
+
"what",
|
|
1935
|
+
"where",
|
|
1936
|
+
"when",
|
|
1937
|
+
"how",
|
|
1938
|
+
"why",
|
|
1939
|
+
"who",
|
|
1940
|
+
"does",
|
|
1941
|
+
"did",
|
|
1942
|
+
"can",
|
|
1943
|
+
"the",
|
|
1944
|
+
"and",
|
|
1945
|
+
"for",
|
|
1946
|
+
"with",
|
|
1947
|
+
"that",
|
|
1948
|
+
"this",
|
|
1949
|
+
"are",
|
|
1950
|
+
"was",
|
|
1951
|
+
"were",
|
|
1952
|
+
"has",
|
|
1953
|
+
"have",
|
|
1954
|
+
"had",
|
|
1955
|
+
"not",
|
|
1956
|
+
"but",
|
|
1957
|
+
"all",
|
|
1958
|
+
"any",
|
|
1959
|
+
"platform",
|
|
1960
|
+
"operation",
|
|
1961
|
+
"operations",
|
|
1962
|
+
"endpoint",
|
|
1963
|
+
"endpoints",
|
|
1964
|
+
"api"
|
|
1965
|
+
]);
|
|
1966
|
+
function anchorWords(anchor) {
|
|
1967
|
+
return anchor.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
1968
|
+
}
|
|
1969
|
+
var singular = (w) => w.length > 3 && w.endsWith("s") ? w.slice(0, -1) : w;
|
|
1932
1970
|
function matchOperations(query, rows) {
|
|
1933
1971
|
const q = query.toLowerCase();
|
|
1934
1972
|
const stems = ACTION_STEMS.filter((s) => q.includes(s));
|
|
1935
|
-
|
|
1973
|
+
const objects = query.toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length > 2 && !STOP_WORDS.has(w)).map(singular);
|
|
1936
1974
|
const scored = [];
|
|
1937
1975
|
for (const r of rows) {
|
|
1938
1976
|
const hay = `${r.anchor} ${r.text}`.toLowerCase();
|
|
1939
|
-
const
|
|
1940
|
-
|
|
1977
|
+
const verbScore = stems.filter((s) => hay.includes(s)).length * 3;
|
|
1978
|
+
const words = anchorWords(r.anchor).map(singular);
|
|
1979
|
+
const objectScore = objects.filter((o) => words.includes(o)).length * 10;
|
|
1980
|
+
if (objectScore + verbScore > 0) scored.push({ ...r, score: objectScore + verbScore, objectScore });
|
|
1941
1981
|
}
|
|
1942
|
-
|
|
1982
|
+
const named = scored.filter((s) => s.objectScore > 0);
|
|
1983
|
+
const pool = named.length ? named : scored;
|
|
1984
|
+
return pool.sort((a, b) => b.score - a.score).slice(0, 4);
|
|
1943
1985
|
}
|
|
1944
1986
|
function catalogNote(anchors) {
|
|
1945
1987
|
if (!anchors.length) return "";
|
|
@@ -1949,12 +1991,12 @@ ${anchors.map((a) => `- ${a}`).join("\n")}`;
|
|
|
1949
1991
|
async function operationsCatalogNote(db, query) {
|
|
1950
1992
|
if (!isOperationIntent(query)) return void 0;
|
|
1951
1993
|
try {
|
|
1952
|
-
const rows = (await db.prepare("SELECT clause_anchor AS anchor, substr(text, 1,
|
|
1994
|
+
const rows = (await db.prepare("SELECT clause_anchor AS anchor, substr(text, 1, 300) AS text FROM chunks WHERE corpus = 'smart-ops' AND clause_anchor IS NOT NULL ORDER BY clause_anchor").all()).results ?? [];
|
|
1953
1995
|
const opRows = rows.map((r) => ({ anchor: String(r.anchor ?? ""), text: String(r.text ?? "") })).filter((r) => r.anchor);
|
|
1954
1996
|
const matched = matchOperations(query, opRows);
|
|
1955
1997
|
const parts = [];
|
|
1956
1998
|
if (matched.length) {
|
|
1957
|
-
parts.push(`Operations whose description matches the question
|
|
1999
|
+
parts.push(`Operations whose name or description matches the question (AUTHORITATIVE \u2014 if one matches, the answer MUST name it and cite its line; never answer that the information is missing):
|
|
1958
2000
|
${matched.map((m) => `- ${m.text}`).join("\n")}`);
|
|
1959
2001
|
}
|
|
1960
2002
|
parts.push(catalogNote(opRows.map((r) => r.anchor)));
|
package/dist/operations.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare function isOperationIntent(query: string): boolean;
|
|
2
|
+
/** camelCase/snake anchors meet the question's words: "updates an
|
|
3
|
+
* entity record" must reach putEntityRecord even when its description
|
|
4
|
+
* words the action differently ("replaces the stored…"). */
|
|
5
|
+
export declare function anchorWords(anchor: string): string[];
|
|
2
6
|
export declare function matchOperations(query: string, rows: {
|
|
3
7
|
anchor: string;
|
|
4
8
|
text: string;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
modelGroundingBlock,
|
|
7
7
|
scoreFaithfulness,
|
|
8
8
|
scoreJudge
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-UW5M2AXR.js";
|
|
10
10
|
import {
|
|
11
11
|
handleSearch
|
|
12
12
|
} from "../../chunk-FLNX4O7C.js";
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
sha256Hex,
|
|
64
64
|
today
|
|
65
65
|
} from "../../chunk-2PCUAJJO.js";
|
|
66
|
-
import "../../chunk-
|
|
66
|
+
import "../../chunk-3IRX4B7Q.js";
|
|
67
67
|
import {
|
|
68
68
|
P,
|
|
69
69
|
setProfile
|
|
@@ -959,7 +959,7 @@ async function handleMcp(env, ctx, req, tier, key) {
|
|
|
959
959
|
// stream:false forces the JSON lane (anon defaults to SSE)
|
|
960
960
|
body: JSON.stringify({ ...args, stream: false })
|
|
961
961
|
});
|
|
962
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
962
|
+
const res = name === "ask" ? await (await import("../../ask-UOTYZ5DC.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-PBOODCMQ.js")).handleSearch(env, ctx, inner, tier, key);
|
|
963
963
|
return res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
964
964
|
});
|
|
965
965
|
if (out.ok && "accepted" in out) return new Response(null, { status: 202 });
|
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.72",
|
|
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",
|
|
@@ -134,7 +134,7 @@ export function registerNote(rows: RegisterRow[]): string {
|
|
|
134
134
|
* is in the R2 plane (TODO 7) — the user gets the document, not just
|
|
135
135
|
* the fact. */
|
|
136
136
|
export function certificateLinks(rows: RegisterRow[]): string {
|
|
137
|
-
const links = rows.filter((r) => r.pdf_key).map((r) => `- ${r.num}: https://www.
|
|
137
|
+
const links = rows.filter((r) => r.pdf_key).map((r) => `- ${r.num}: https://www.ommisa.org/cert-pdf/${r.pdf_key}`);
|
|
138
138
|
return links.length ? `The certificates' documents:\n${links.join("\n")}` : "";
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// The operations catalog lane (TODO.new-era/6's platform surface): the
|
|
2
2
|
// smart-ops corpus is SMALL (169 operations) and name-addressable. An
|
|
3
|
-
// operation-intent question gets (1) the operations whose
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// name the operation from it,
|
|
7
|
-
//
|
|
3
|
+
// operation-intent question gets (1) the operations whose NAME carries
|
|
4
|
+
// the question's object words and whose description carries its action
|
|
5
|
+
// stems — with their full lines, and (2) the complete name index. The
|
|
6
|
+
// note is AUTHORITATIVE: the model must name the operation from it,
|
|
7
|
+
// never answer from the passages' silence. Pure composition lives
|
|
8
|
+
// here; the D1 call is a thin wrapper.
|
|
8
9
|
|
|
9
10
|
export function isOperationIntent(query: string): boolean {
|
|
10
11
|
return /\b(operations?|endpoints?)\b/i.test(query);
|
|
@@ -18,17 +19,48 @@ const ACTION_STEMS = [
|
|
|
18
19
|
"confirm", "approv", "declin", "decide", "revok", "grant", "notify", "advanc", "announc", "download",
|
|
19
20
|
];
|
|
20
21
|
|
|
22
|
+
const STOP_WORDS = new Set([
|
|
23
|
+
"which", "what", "where", "when", "how", "why", "who", "does", "did", "can", "the", "and", "for",
|
|
24
|
+
"with", "that", "this", "are", "was", "were", "has", "have", "had", "not", "but", "all", "any",
|
|
25
|
+
"platform", "operation", "operations", "endpoint", "endpoints", "api",
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
/** camelCase/snake anchors meet the question's words: "updates an
|
|
29
|
+
* entity record" must reach putEntityRecord even when its description
|
|
30
|
+
* words the action differently ("replaces the stored…"). */
|
|
31
|
+
export function anchorWords(anchor: string): string[] {
|
|
32
|
+
return anchor
|
|
33
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
34
|
+
.toLowerCase()
|
|
35
|
+
.split(/[^a-z0-9]+/)
|
|
36
|
+
.filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const singular = (w: string) => (w.length > 3 && w.endsWith("s") ? w.slice(0, -1) : w);
|
|
40
|
+
|
|
21
41
|
export function matchOperations(query: string, rows: { anchor: string; text: string }[]): { anchor: string; text: string }[] {
|
|
22
42
|
const q = query.toLowerCase();
|
|
23
43
|
const stems = ACTION_STEMS.filter((s) => q.includes(s));
|
|
24
|
-
|
|
25
|
-
|
|
44
|
+
const objects = query
|
|
45
|
+
.toLowerCase()
|
|
46
|
+
.split(/[^a-z0-9]+/)
|
|
47
|
+
.filter((w) => w.length > 2 && !STOP_WORDS.has(w))
|
|
48
|
+
.map(singular);
|
|
49
|
+
const scored: { anchor: string; text: string; score: number; objectScore: number }[] = [];
|
|
26
50
|
for (const r of rows) {
|
|
27
51
|
const hay = `${r.anchor} ${r.text}`.toLowerCase();
|
|
28
|
-
const
|
|
29
|
-
|
|
52
|
+
const verbScore = stems.filter((s) => hay.includes(s)).length * 3;
|
|
53
|
+
const words = anchorWords(r.anchor).map(singular);
|
|
54
|
+
const objectScore = objects.filter((o) => words.includes(o)).length * 10;
|
|
55
|
+
if (objectScore + verbScore > 0) scored.push({ ...r, score: objectScore + verbScore, objectScore });
|
|
30
56
|
}
|
|
31
|
-
|
|
57
|
+
// A question that names its object ("entity record") has found its
|
|
58
|
+
// target by name — verb-only mentions are the noise that displaced
|
|
59
|
+
// the answer with an unrelated sibling (the 2026-09-29 "blob upload"
|
|
60
|
+
// answers).
|
|
61
|
+
const named = scored.filter((s) => s.objectScore > 0);
|
|
62
|
+
const pool = named.length ? named : scored;
|
|
63
|
+
return pool.sort((a, b) => b.score - a.score).slice(0, 4);
|
|
32
64
|
}
|
|
33
65
|
|
|
34
66
|
export function catalogNote(anchors: string[]): string {
|
|
@@ -39,12 +71,12 @@ export function catalogNote(anchors: string[]): string {
|
|
|
39
71
|
export async function operationsCatalogNote(db: any, query: string): Promise<string | undefined> {
|
|
40
72
|
if (!isOperationIntent(query)) return undefined;
|
|
41
73
|
try {
|
|
42
|
-
const rows = (await db.prepare("SELECT clause_anchor AS anchor, substr(text, 1,
|
|
74
|
+
const rows = (await db.prepare("SELECT clause_anchor AS anchor, substr(text, 1, 300) AS text FROM chunks WHERE corpus = 'smart-ops' AND clause_anchor IS NOT NULL ORDER BY clause_anchor").all()).results ?? [];
|
|
43
75
|
const opRows = (rows as any[]).map((r) => ({ anchor: String(r.anchor ?? ""), text: String(r.text ?? "") })).filter((r) => r.anchor);
|
|
44
76
|
const matched = matchOperations(query, opRows);
|
|
45
77
|
const parts: string[] = [];
|
|
46
78
|
if (matched.length) {
|
|
47
|
-
parts.push(`Operations whose description matches the question
|
|
79
|
+
parts.push(`Operations whose name or description matches the question (AUTHORITATIVE — if one matches, the answer MUST name it and cite its line; never answer that the information is missing):\n${matched.map((m) => `- ${m.text}`).join("\n")}`);
|
|
48
80
|
}
|
|
49
81
|
parts.push(catalogNote(opRows.map((r) => r.anchor)));
|
|
50
82
|
return parts.filter(Boolean).join("\n\n") || undefined;
|