@konneal/engine 0.2.57 → 0.2.59

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-MNEUEHO7.js";
3
+ } from "./chunk-TZOED2YR.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-Z6JAGZAM.js";
9
+ import "./chunk-FHOOFPJW.js";
10
10
  import "./chunk-3FYJM7LH.js";
11
11
  export {
12
12
  handleAsk
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  buildRegisterQuery,
3
+ certificateLinks,
3
4
  isRegisterShaped,
4
5
  queryFamily,
5
6
  registerNote,
6
7
  registerTokens,
7
8
  searchRegister
8
- } from "./chunk-Z6JAGZAM.js";
9
+ } from "./chunk-FHOOFPJW.js";
9
10
  import "./chunk-3FYJM7LH.js";
10
11
  export {
11
12
  buildRegisterQuery,
13
+ certificateLinks,
12
14
  isRegisterShaped,
13
15
  queryFamily,
14
16
  registerNote,
@@ -5,6 +5,7 @@ export interface RegisterRow {
5
5
  model: string;
6
6
  year: string;
7
7
  status: string;
8
+ pdf_key?: string | null;
8
9
  }
9
10
  /** A question is register-shaped when it asks about certification
10
11
  * standing of an identifiable model or holder — the deterministic
@@ -37,3 +38,7 @@ export declare function searchRegister(db: any, query: string): Promise<{
37
38
  tokens: string[];
38
39
  } | null>;
39
40
  export declare function registerNote(rows: RegisterRow[]): string;
41
+ /** Each certificate's location rides the note as a link when its PDF
42
+ * is in the R2 plane (TODO 7) — the user gets the document, not just
43
+ * the fact. */
44
+ export declare function certificateLinks(rows: RegisterRow[]): string;
@@ -84,7 +84,7 @@ function buildRegisterQuery(tokens) {
84
84
  return `(holder LIKE ?${n} OR model LIKE ?${n} OR num LIKE ?${n})`;
85
85
  });
86
86
  return {
87
- sql: `SELECT num, family, holder, model, year, status FROM certificates WHERE ${clauses.join(" OR ")} LIMIT 6`,
87
+ sql: `SELECT num, family, holder, model, year, status, pdf_key FROM certificates WHERE ${clauses.join(" OR ")} LIMIT 6`,
88
88
  params
89
89
  };
90
90
  }
@@ -97,7 +97,7 @@ async function searchRegister(db, query) {
97
97
  const family = queryFamily(query);
98
98
  if (family) {
99
99
  sql = sql.replace(" WHERE ", " WHERE family = ?0 AND ");
100
- params.unshift(family);
100
+ params.unshift(family.replace(/^[A-Za-z]+/, ""));
101
101
  }
102
102
  try {
103
103
  const res = await db.prepare(sql).bind(...params).all();
@@ -116,6 +116,11 @@ function registerNote(rows) {
116
116
  ...lines
117
117
  ].join("\n");
118
118
  }
119
+ function certificateLinks(rows) {
120
+ const links = rows.filter((r) => r.pdf_key).map((r) => `- ${r.num}: https://www.oimlsmart.org/cert-pdf/${r.pdf_key}`);
121
+ return links.length ? `The certificates' documents:
122
+ ${links.join("\n")}` : "";
123
+ }
119
124
 
120
125
  export {
121
126
  isRegisterShaped,
@@ -123,5 +128,6 @@ export {
123
128
  registerTokens,
124
129
  buildRegisterQuery,
125
130
  searchRegister,
126
- registerNote
131
+ registerNote,
132
+ certificateLinks
127
133
  };
@@ -65,9 +65,10 @@ import {
65
65
  sha256Hex
66
66
  } from "./chunk-2PCUAJJO.js";
67
67
  import {
68
+ certificateLinks,
68
69
  registerNote,
69
70
  searchRegister
70
- } from "./chunk-Z6JAGZAM.js";
71
+ } from "./chunk-FHOOFPJW.js";
71
72
  import {
72
73
  P
73
74
  } from "./chunk-3FYJM7LH.js";
@@ -1891,7 +1892,7 @@ async function runTool(db, call) {
1891
1892
  if (call.name !== "register_search") return null;
1892
1893
  const query = String(call.args?.query ?? "").trim().slice(0, 160);
1893
1894
  if (!query) return null;
1894
- const { searchRegister: searchRegister2, registerNote: registerNote2 } = await import("./certificates-DZJJLRGU.js");
1895
+ const { searchRegister: searchRegister2, registerNote: registerNote2 } = await import("./certificates-CUGV2FIW.js");
1895
1896
  const reg = await searchRegister2(db, query);
1896
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.`;
1897
1898
  return { name: call.name, query, output };
@@ -2313,7 +2314,7 @@ async function handleAsk(env, ctx, req, tier, key) {
2313
2314
  }
2314
2315
  }
2315
2316
  console.log("register-search:", JSON.stringify({ shaped: !!register, tokens: register?.tokens ?? null, rows: register?.rows?.length ?? null, first: register?.rows?.[0]?.num ?? null }));
2316
- const regNote = register ? registerNote(register.rows) : void 0;
2317
+ const regNote = register ? [registerNote(register.rows), certificateLinks(register.rows)].filter(Boolean).join("\n") : void 0;
2317
2318
  if (understanding?.intent === "conversational") {
2318
2319
  const queryHash2 = await sha256Hex(q.query);
2319
2320
  const messages2 = [
@@ -6,7 +6,7 @@ import {
6
6
  modelGroundingBlock,
7
7
  scoreFaithfulness,
8
8
  scoreJudge
9
- } from "../../chunk-MNEUEHO7.js";
9
+ } from "../../chunk-TZOED2YR.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-Z6JAGZAM.js";
66
+ import "../../chunk-FHOOFPJW.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-26DGSVFW.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-7J4A3PSP.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.57",
30
+ "version": "0.2.59",
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",
@@ -39,7 +39,7 @@ export type { Env };
39
39
  import { json, err, corsHeaders, readJson, validateQuery, type ApiKey } from "./lib/http";
40
40
  import { clientIp, checkQuota, telemetry } from "./quota";
41
41
  import { graphExpand, editionNote } from "./graph";
42
- import { registerNote, searchRegister } from "./certificates";
42
+ import { registerNote, searchRegister, certificateLinks } from "./certificates";
43
43
  import { TOOL_DECLARATION, parseToolCall, runTool, toolNote } from "./tools";
44
44
  import { extractNameplate, nameplateRegisterQuery } from "./nameplate.ts";
45
45
  import { P } from "./profile.ts";
@@ -637,7 +637,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
637
637
  }
638
638
  }
639
639
  console.log("register-search:", JSON.stringify({ shaped: !!register, tokens: register?.tokens ?? null, rows: register?.rows?.length ?? null, first: register?.rows?.[0]?.num ?? null }));
640
- const regNote = register ? registerNote(register.rows) : undefined;
640
+ const regNote = register ? [registerNote(register.rows), certificateLinks(register.rows)].filter(Boolean).join("\n") : undefined;
641
641
 
642
642
  // Conversational route, decided by query UNDERSTANDING (any language, any
643
643
  // phrasing) — not string matching. No retrieval: nothing in the corpus
@@ -15,6 +15,7 @@ export interface RegisterRow {
15
15
  model: string;
16
16
  year: string;
17
17
  status: string;
18
+ pdf_key?: string | null;
18
19
  }
19
20
 
20
21
  /** A question is register-shaped when it asks about certification
@@ -83,7 +84,7 @@ export function buildRegisterQuery(tokens: string[]): { sql: string; params: str
83
84
  return `(holder LIKE ?${n} OR model LIKE ?${n} OR num LIKE ?${n})`;
84
85
  });
85
86
  return {
86
- sql: `SELECT num, family, holder, model, year, status FROM certificates WHERE ${clauses.join(" OR ")} LIMIT 6`,
87
+ sql: `SELECT num, family, holder, model, year, status, pdf_key FROM certificates WHERE ${clauses.join(" OR ")} LIMIT 6`,
87
88
  params,
88
89
  };
89
90
  }
@@ -96,8 +97,10 @@ export async function searchRegister(db: any, query: string): Promise<{ rows: Re
96
97
  let { sql, params } = built;
97
98
  const family = queryFamily(query);
98
99
  if (family) {
100
+ // the register's family column is the DIGITS ONLY ("60", "105") —
101
+ // the letter+padding form ("R60") never matched a single row
99
102
  sql = sql.replace(" WHERE ", " WHERE family = ?0 AND ");
100
- params.unshift(family);
103
+ params.unshift(family.replace(/^[A-Za-z]+/, ""));
101
104
  }
102
105
  try {
103
106
  const res = await db.prepare(sql).bind(...params).all();
@@ -118,3 +121,11 @@ export function registerNote(rows: RegisterRow[]): string {
118
121
  ...lines,
119
122
  ].join("\n");
120
123
  }
124
+ /** Each certificate's location rides the note as a link when its PDF
125
+ * is in the R2 plane (TODO 7) — the user gets the document, not just
126
+ * the fact. */
127
+ export function certificateLinks(rows: RegisterRow[]): string {
128
+ const links = rows.filter((r) => r.pdf_key).map((r) => `- ${r.num}: https://www.oimlsmart.org/cert-pdf/${r.pdf_key}`);
129
+ return links.length ? `The certificates' documents:\n${links.join("\n")}` : "";
130
+ }
131
+