@konneal/engine 0.2.89 → 0.2.90

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,7 +1,7 @@
1
1
  import {
2
2
  handleAsk
3
- } from "./chunk-NGPUMFYQ.js";
4
- import "./chunk-HVT2ZTWW.js";
3
+ } from "./chunk-KZV4I7ET.js";
4
+ import "./chunk-A7QS2X3J.js";
5
5
  import "./chunk-3BL223VD.js";
6
6
  import "./chunk-LOBYXEVD.js";
7
7
  import "./chunk-SPKPH54J.js";
@@ -78,7 +78,7 @@ var slug = (docidentifier) => docidentifier.toLowerCase().replace(/[^a-z0-9]+/g,
78
78
  var unitsGet = {
79
79
  name: "units.get",
80
80
  description: "Fetch typed Recommendation content \u2014 a table, formula or figure as structured data (columns, rows, MathML, caption), by its unit id. The machine-consumable form of a Recommendation's content, for computing with rather than reading.",
81
- params: [{ key: "unit_id", required: true, description: "the unit id, e.g. u:table-1 or u:form-3 (ids appear in answers' [[u:\u2026]] references)" }],
81
+ params: [{ key: "unit_id", required: true, description: "the unit id exactly as an answer's [[u:\u2026]] reference spells it" }],
82
82
  audiences: ["mcp"],
83
83
  handler: async (env, args) => {
84
84
  const unit_id = String(args?.unit_id ?? "").trim().replace(/^\[?\[?u:/, "u:").replace(/]?\]?$/, "");
@@ -156,6 +156,30 @@ var docsSection = {
156
156
  }
157
157
  }
158
158
  };
159
+ var documentsFamily = {
160
+ name: "documents.family",
161
+ description: "Look up the publication registry for a family: every edition with its derived status (in-force/superseded), which edition is ACTIVE (terminal of the successor chain), and supersession links. Use for current/latest-edition and edition-history questions.",
162
+ params: [{ key: "family", required: true, description: "the family key, e.g. R-60 (series letter and number)" }],
163
+ audiences: ["mcp"],
164
+ handler: async (env, args) => {
165
+ const family = String(args?.family ?? "").trim().toUpperCase();
166
+ if (!/^[A-Z]-\d{1,3}$/.test(family)) return null;
167
+ try {
168
+ const rows = await env.DB.prepare(
169
+ "SELECT d.docidentifier, d.derived_status, d.active, s.docidentifier AS succ FROM documents d LEFT JOIN documents s ON d.superseded_by = s.canonical_id WHERE d.family = ?1 ORDER BY d.part, d.edition"
170
+ ).bind(family).all();
171
+ const lines = (rows.results ?? []).map(
172
+ (r) => `${r.docidentifier} \u2014 ${r.derived_status}${r.active ? " [ACTIVE]" : ""}${r.succ ? ` \u2192 superseded by ${r.succ}` : ""}`
173
+ );
174
+ if (!lines.length) {
175
+ return { name: "documents.family", query: family, output: `No editions are registered for the family ${family}. State this plainly.` };
176
+ }
177
+ return { name: "documents.family", query: family, output: lines.join("\n") };
178
+ } catch {
179
+ return null;
180
+ }
181
+ }
182
+ };
159
183
  var glossaryLookup = {
160
184
  name: "glossary.lookup",
161
185
  description: "Look up a defined term in the terminology datasets \u2014 the concept's definition and its defining publication. Bind everyday words to the defined term before interpreting a question.",
@@ -224,7 +248,7 @@ var certificatesSearch = {
224
248
  return { name: "certificates.search", query, output };
225
249
  }
226
250
  };
227
- var TOOLS_REGISTRY = [certificatesSearch, unitsGet, graphCites, docsSection, glossaryLookup];
251
+ var TOOLS_REGISTRY = [certificatesSearch, unitsGet, graphCites, docsSection, glossaryLookup, documentsFamily];
228
252
  var TOOL_DECLARATION = [
229
253
  "You may use one tool before answering, by writing a single line:",
230
254
  ...TOOLS_REGISTRY.filter((t) => t.audiences.includes("agent")).map((t) => {
@@ -6,7 +6,7 @@ import {
6
6
  runTool,
7
7
  tableRetyped,
8
8
  toolNote
9
- } from "./chunk-HVT2ZTWW.js";
9
+ } from "./chunk-A7QS2X3J.js";
10
10
  import {
11
11
  NO_CONTEXT,
12
12
  answerQuality,
@@ -4,7 +4,7 @@ import {
4
4
  parseToolCall,
5
5
  runTool,
6
6
  toolNote
7
- } from "./chunk-HVT2ZTWW.js";
7
+ } from "./chunk-A7QS2X3J.js";
8
8
  import "./chunk-LOBYXEVD.js";
9
9
  import "./chunk-2PCUAJJO.js";
10
10
  import "./chunk-3FYJM7LH.js";
@@ -2,4 +2,5 @@ import type { ToolSpec } from "./tools.ts";
2
2
  export declare const unitsGet: ToolSpec;
3
3
  export declare const graphCites: ToolSpec;
4
4
  export declare const docsSection: ToolSpec;
5
+ export declare const documentsFamily: ToolSpec;
5
6
  export declare const glossaryLookup: ToolSpec;
@@ -6,10 +6,10 @@ import {
6
6
  modelGroundingBlock,
7
7
  scoreFaithfulness,
8
8
  scoreJudge
9
- } from "../../chunk-NGPUMFYQ.js";
9
+ } from "../../chunk-KZV4I7ET.js";
10
10
  import {
11
11
  TOOLS_REGISTRY
12
- } from "../../chunk-HVT2ZTWW.js";
12
+ } from "../../chunk-A7QS2X3J.js";
13
13
  import {
14
14
  handleSearch
15
15
  } from "../../chunk-TJTEBS4S.js";
@@ -973,12 +973,12 @@ async function handleMcp(env, ctx, req, tier, key) {
973
973
  // stream:false forces the JSON lane (anon defaults to SSE)
974
974
  body: JSON.stringify({ ...args, stream: false })
975
975
  });
976
- const { runTool, TOOLS_REGISTRY: TOOLS_REGISTRY2 } = await import("../../tools-MVAWZZS2.js");
976
+ const { runTool, TOOLS_REGISTRY: TOOLS_REGISTRY2 } = await import("../../tools-26IJZX5M.js");
977
977
  if (TOOLS_REGISTRY2.some((t) => t.name === name && t.audiences.includes("mcp"))) {
978
978
  const r = await runTool({ ...env, DB: env.DB }, { name, args }, "mcp");
979
979
  return r ? { tool: r.name, query: r.query, result: r.output } : { error: { message: `tool ${name} returned nothing for the given arguments` } };
980
980
  }
981
- const res = name === "ask" ? await (await import("../../ask-OYW3QMOW.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-G76DK4AF.js")).handleSearch(env, ctx, inner, tier, key);
981
+ const res = name === "ask" ? await (await import("../../ask-D6JV2R2R.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-G76DK4AF.js")).handleSearch(env, ctx, inner, tier, key);
982
982
  return res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
983
983
  });
984
984
  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.89",
30
+ "version": "0.2.90",
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",
@@ -21,7 +21,7 @@ export const unitsGet: ToolSpec = {
21
21
  name: "units.get",
22
22
  description:
23
23
  "Fetch typed Recommendation content — a table, formula or figure as structured data (columns, rows, MathML, caption), by its unit id. The machine-consumable form of a Recommendation's content, for computing with rather than reading.",
24
- params: [{ key: "unit_id", required: true, description: "the unit id, e.g. u:table-1 or u:form-3 (ids appear in answers' [[u:…]] references)" }],
24
+ params: [{ key: "unit_id", required: true, description: "the unit id exactly as an answer's [[u:…]] reference spells it" }],
25
25
  audiences: ["mcp"],
26
26
  handler: async (env, args) => {
27
27
  const unit_id = String(args?.unit_id ?? "").trim().replace(/^\[?\[?u:/, "u:").replace(/]?\]?$/, "");
@@ -109,6 +109,34 @@ export const docsSection: ToolSpec = {
109
109
  },
110
110
  };
111
111
 
112
+ export const documentsFamily: ToolSpec = {
113
+ name: "documents.family",
114
+ description:
115
+ "Look up the publication registry for a family: every edition with its derived status (in-force/superseded), which edition is ACTIVE (terminal of the successor chain), and supersession links. Use for current/latest-edition and edition-history questions.",
116
+ params: [{ key: "family", required: true, description: "the family key, e.g. R-60 (series letter and number)" }],
117
+ audiences: ["mcp"],
118
+ handler: async (env, args) => {
119
+ const family = String(args?.family ?? "").trim().toUpperCase();
120
+ if (!/^[A-Z]-\d{1,3}$/.test(family)) return null;
121
+ try {
122
+ const rows = await env.DB.prepare(
123
+ "SELECT d.docidentifier, d.derived_status, d.active, s.docidentifier AS succ FROM documents d LEFT JOIN documents s ON d.superseded_by = s.canonical_id WHERE d.family = ?1 ORDER BY d.part, d.edition",
124
+ )
125
+ .bind(family)
126
+ .all();
127
+ const lines = ((rows.results ?? []) as { docidentifier: string; derived_status: string; active: number; succ: string | null }[]).map(
128
+ (r) => `${r.docidentifier} — ${r.derived_status}${r.active ? " [ACTIVE]" : ""}${r.succ ? ` → superseded by ${r.succ}` : ""}`,
129
+ );
130
+ if (!lines.length) {
131
+ return { name: "documents.family", query: family, output: `No editions are registered for the family ${family}. State this plainly.` };
132
+ }
133
+ return { name: "documents.family", query: family, output: lines.join("\n") };
134
+ } catch {
135
+ return null;
136
+ }
137
+ },
138
+ };
139
+
112
140
  export const glossaryLookup: ToolSpec = {
113
141
  name: "glossary.lookup",
114
142
  description:
@@ -64,9 +64,9 @@ const certificatesSearch: ToolSpec = {
64
64
  },
65
65
  };
66
66
 
67
- import { unitsGet, graphCites, docsSection, glossaryLookup } from "./tools-content.ts";
67
+ import { unitsGet, graphCites, docsSection, glossaryLookup, documentsFamily } from "./tools-content.ts";
68
68
 
69
- export const TOOLS_REGISTRY: ToolSpec[] = [certificatesSearch, unitsGet, graphCites, docsSection, glossaryLookup];
69
+ export const TOOLS_REGISTRY: ToolSpec[] = [certificatesSearch, unitsGet, graphCites, docsSection, glossaryLookup, documentsFamily];
70
70
 
71
71
  /** The agent loop's protocol declaration, GENERATED from the registry —
72
72
  * the model's tool vocabulary is always the registry's, never a