@konneal/engine 0.2.70 → 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.
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  handleAsk
3
- } from "./chunk-BMC5XBJV.js";
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-VGVTIPFW.js";
9
+ import "./chunk-3IRX4B7Q.js";
10
10
  import "./chunk-3FYJM7LH.js";
11
11
  export {
12
12
  handleAsk
@@ -6,7 +6,7 @@ import {
6
6
  registerNote,
7
7
  registerTokens,
8
8
  searchRegister
9
- } from "./chunk-VGVTIPFW.js";
9
+ } from "./chunk-3IRX4B7Q.js";
10
10
  import "./chunk-3FYJM7LH.js";
11
11
  export {
12
12
  buildRegisterQuery,
@@ -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.oimlsmart.org/cert-pdf/${r.pdf_key}`);
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-VGVTIPFW.js";
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-DNRUOYRF.js");
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 };
@@ -1906,17 +1906,101 @@ ${r.output}`;
1906
1906
  function isOperationIntent(query) {
1907
1907
  return /\b(operations?|endpoints?)\b/i.test(query);
1908
1908
  }
1909
+ var ACTION_STEMS = [
1910
+ "updat",
1911
+ "upsert",
1912
+ "writ",
1913
+ "put",
1914
+ "delet",
1915
+ "remov",
1916
+ "read",
1917
+ "fetch",
1918
+ "get",
1919
+ "creat",
1920
+ "declar",
1921
+ "confirm",
1922
+ "approv",
1923
+ "declin",
1924
+ "decide",
1925
+ "revok",
1926
+ "grant",
1927
+ "notify",
1928
+ "advanc",
1929
+ "announc",
1930
+ "download"
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;
1970
+ function matchOperations(query, rows) {
1971
+ const q = query.toLowerCase();
1972
+ const stems = ACTION_STEMS.filter((s) => q.includes(s));
1973
+ const objects = query.toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length > 2 && !STOP_WORDS.has(w)).map(singular);
1974
+ const scored = [];
1975
+ for (const r of rows) {
1976
+ const hay = `${r.anchor} ${r.text}`.toLowerCase();
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 });
1981
+ }
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);
1985
+ }
1909
1986
  function catalogNote(anchors) {
1910
1987
  if (!anchors.length) return "";
1911
- return `The platform's indexed operations (the COMPLETE surface \u2014 every operation the system exposes; the answer must name the operation from this list when one matches the question):
1988
+ return `The COMPLETE name index of the platform's operations:
1912
1989
  ${anchors.map((a) => `- ${a}`).join("\n")}`;
1913
1990
  }
1914
1991
  async function operationsCatalogNote(db, query) {
1915
1992
  if (!isOperationIntent(query)) return void 0;
1916
1993
  try {
1917
- const rows = (await db.prepare("SELECT clause_anchor FROM chunks WHERE corpus = 'smart-ops' AND clause_anchor IS NOT NULL ORDER BY clause_anchor").all()).results ?? [];
1918
- const note = catalogNote(rows.map((r) => r.clause_anchor).filter(Boolean));
1919
- return note || void 0;
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 ?? [];
1995
+ const opRows = rows.map((r) => ({ anchor: String(r.anchor ?? ""), text: String(r.text ?? "") })).filter((r) => r.anchor);
1996
+ const matched = matchOperations(query, opRows);
1997
+ const parts = [];
1998
+ if (matched.length) {
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):
2000
+ ${matched.map((m) => `- ${m.text}`).join("\n")}`);
2001
+ }
2002
+ parts.push(catalogNote(opRows.map((r) => r.anchor)));
2003
+ return parts.filter(Boolean).join("\n\n") || void 0;
1920
2004
  } catch {
1921
2005
  return void 0;
1922
2006
  }
@@ -1,3 +1,14 @@
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[];
6
+ export declare function matchOperations(query: string, rows: {
7
+ anchor: string;
8
+ text: string;
9
+ }[]): {
10
+ anchor: string;
11
+ text: string;
12
+ }[];
2
13
  export declare function catalogNote(anchors: string[]): string;
3
14
  export declare function operationsCatalogNote(db: any, query: string): Promise<string | undefined>;
@@ -6,7 +6,7 @@ import {
6
6
  modelGroundingBlock,
7
7
  scoreFaithfulness,
8
8
  scoreJudge
9
- } from "../../chunk-BMC5XBJV.js";
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-VGVTIPFW.js";
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-S3SLIGA7.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-PBOODCMQ.js")).handleSearch(env, ctx, inner, tier, key);
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.70",
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.oimlsmart.org/cert-pdf/${r.pdf_key}`);
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,26 +1,85 @@
1
1
  // The operations catalog lane (TODO.new-era/6's platform surface): the
2
- // smart-ops corpus is SMALL (169 operations) and name-addressable. When
3
- // a question is operation-intent, the ENTIRE operation-name index rides
4
- // the notes channel — the model matches "updates an entity record" to
5
- // putEntityRecord semantically from the complete surface, instead of
6
- // gambling on which sibling passage retrieval happens to surface.
7
- // Pure composition lives here; the D1 call is a thin wrapper.
2
+ // smart-ops corpus is SMALL (169 operations) and name-addressable. An
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);
11
12
  }
12
13
 
14
+ /** The action stems the register's descriptions use, mapped from the
15
+ * words a question actually asks ("updates" → updat; "upserts" shares
16
+ * the stem). */
17
+ const ACTION_STEMS = [
18
+ "updat", "upsert", "writ", "put", "delet", "remov", "read", "fetch", "get", "creat", "declar",
19
+ "confirm", "approv", "declin", "decide", "revok", "grant", "notify", "advanc", "announc", "download",
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
+
41
+ export function matchOperations(query: string, rows: { anchor: string; text: string }[]): { anchor: string; text: string }[] {
42
+ const q = query.toLowerCase();
43
+ const stems = ACTION_STEMS.filter((s) => q.includes(s));
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 }[] = [];
50
+ for (const r of rows) {
51
+ const hay = `${r.anchor} ${r.text}`.toLowerCase();
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 });
56
+ }
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);
64
+ }
65
+
13
66
  export function catalogNote(anchors: string[]): string {
14
67
  if (!anchors.length) return "";
15
- return `The platform's indexed operations (the COMPLETE surface — every operation the system exposes; the answer must name the operation from this list when one matches the question):\n${anchors.map((a) => `- ${a}`).join("\n")}`;
68
+ return `The COMPLETE name index of the platform's operations:\n${anchors.map((a) => `- ${a}`).join("\n")}`;
16
69
  }
17
70
 
18
71
  export async function operationsCatalogNote(db: any, query: string): Promise<string | undefined> {
19
72
  if (!isOperationIntent(query)) return undefined;
20
73
  try {
21
- const rows = (await db.prepare("SELECT clause_anchor FROM chunks WHERE corpus = 'smart-ops' AND clause_anchor IS NOT NULL ORDER BY clause_anchor").all()).results ?? [];
22
- const note = catalogNote((rows as any[]).map((r) => r.clause_anchor).filter(Boolean));
23
- return note || undefined;
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 ?? [];
75
+ const opRows = (rows as any[]).map((r) => ({ anchor: String(r.anchor ?? ""), text: String(r.text ?? "") })).filter((r) => r.anchor);
76
+ const matched = matchOperations(query, opRows);
77
+ const parts: string[] = [];
78
+ if (matched.length) {
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")}`);
80
+ }
81
+ parts.push(catalogNote(opRows.map((r) => r.anchor)));
82
+ return parts.filter(Boolean).join("\n\n") || undefined;
24
83
  } catch {
25
84
  return undefined; // the lane is optional
26
85
  }