@konneal/engine 0.2.67 → 0.2.69

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,6 +1,6 @@
1
1
  import {
2
2
  handleAsk
3
- } from "./chunk-67VVH7CX.js";
3
+ } from "./chunk-PENTOBUO.js";
4
4
  import "./chunk-TPV5GPY2.js";
5
5
  import "./chunk-SPKPH54J.js";
6
6
  import "./chunk-A3QHHUN5.js";
@@ -1902,6 +1902,26 @@ function toolNote(r) {
1902
1902
  ${r.output}`;
1903
1903
  }
1904
1904
 
1905
+ // workers/worker_public/src/operations.ts
1906
+ function isOperationIntent(query) {
1907
+ return /\b(operations?|endpoints?)\b/i.test(query);
1908
+ }
1909
+ function catalogNote(anchors) {
1910
+ 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):
1912
+ ${anchors.map((a) => `- ${a}`).join("\n")}`;
1913
+ }
1914
+ async function operationsCatalogNote(db, query) {
1915
+ if (!isOperationIntent(query)) return void 0;
1916
+ 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;
1920
+ } catch {
1921
+ return void 0;
1922
+ }
1923
+ }
1924
+
1905
1925
  // workers/worker_public/prompts/nameplate.md
1906
1926
  var nameplate_default = `You read instrument nameplates. From the photograph, extract the
1907
1927
  manufacturer's name exactly as printed and the model designation exactly
@@ -2319,6 +2339,7 @@ async function handleAsk(env, ctx, req, tier, key) {
2319
2339
  }
2320
2340
  console.log("register-search:", JSON.stringify({ shaped: !!register, tokens: register?.tokens ?? null, rows: register?.rows?.length ?? null, first: register?.rows?.[0]?.num ?? null }));
2321
2341
  const regNote = register ? [registerNote(register.rows), certificateLinks(register.rows)].filter(Boolean).join("\n") : void 0;
2342
+ const opsCatalog = await operationsCatalogNote(env.DB, q.query);
2322
2343
  if (understanding?.intent === "conversational") {
2323
2344
  const queryHash2 = await sha256Hex(q.query);
2324
2345
  const messages2 = [
@@ -2665,11 +2686,12 @@ Answer account questions from these records ONLY: name the record when you use i
2665
2686
  q.lang,
2666
2687
  keptHistory,
2667
2688
  // stage-extracted graph facts (GraphRAG) ride the same note channel
2668
- [processNote, eNote, regNote, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...retrieved.notes ?? []].filter(Boolean).join("\n") || void 0,
2689
+ [processNote, eNote, regNote, opsCatalog, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...retrieved.notes ?? []].filter(Boolean).join("\n") || void 0,
2669
2690
  summary,
2670
2691
  budget
2671
2692
  );
2672
2693
  await attachFigureImages(env, messages, usedHits, q.query);
2694
+ const pendingTools = [];
2673
2695
  if (/certificate|certified|certification/i.test(q.query) && env.DB) {
2674
2696
  try {
2675
2697
  const probe = await env.AI.run(model, {
@@ -2685,6 +2707,7 @@ ${q.query}` }],
2685
2707
  const result = await runTool(env.DB, call);
2686
2708
  if (result) {
2687
2709
  messages.push({ role: "system", content: toolNote(result) });
2710
+ pendingTools.push(result);
2688
2711
  console.log("agent-tool:", result.name, JSON.stringify(result.query), "->", result.output.slice(0, 80));
2689
2712
  }
2690
2713
  }
@@ -2718,6 +2741,12 @@ ${q.query}` }],
2718
2741
  const send = (obj) => controller.enqueue(encoder.encode(`data: ${JSON.stringify(obj)}
2719
2742
 
2720
2743
  `));
2744
+ for (const t of pendingTools) {
2745
+ try {
2746
+ send({ type: "tool", name: t.name, query: t.query });
2747
+ } catch {
2748
+ }
2749
+ }
2721
2750
  send({ type: "read", read: readAs() });
2722
2751
  const sourceQuality = answerQuality(cites.map((c) => c.quality));
2723
2752
  send({ type: "citations", citations: cites, context_applied: ctxApplied, ...sourceQuality ? { source_quality: sourceQuality, confidence_note: qualityNote(sourceQuality), ...sourceQuality === "ocr" ? { experimental_sources: experimentalSourceLabels(cites) } : {} } : {}, ...liveRecords ? { records: liveRecords } : {}, quota });
@@ -0,0 +1,3 @@
1
+ export declare function isOperationIntent(query: string): boolean;
2
+ export declare function catalogNote(anchors: string[]): string;
3
+ 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-67VVH7CX.js";
9
+ } from "../../chunk-PENTOBUO.js";
10
10
  import {
11
11
  handleSearch
12
12
  } from "../../chunk-FLNX4O7C.js";
@@ -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-O2ZWIV2Y.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-UC5IVQDH.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.67",
30
+ "version": "0.2.69",
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",
@@ -41,6 +41,7 @@ import { clientIp, checkQuota, telemetry } from "./quota";
41
41
  import { graphExpand, editionNote } from "./graph";
42
42
  import { registerNote, searchRegister, certificateLinks } from "./certificates";
43
43
  import { TOOL_DECLARATION, parseToolCall, runTool, toolNote } from "./tools";
44
+ import { operationsCatalogNote } from "./operations.ts";
44
45
  import { extractNameplate, nameplateRegisterQuery } from "./nameplate.ts";
45
46
  import { P } from "./profile.ts";
46
47
 
@@ -641,6 +642,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
641
642
  }
642
643
  console.log("register-search:", JSON.stringify({ shaped: !!register, tokens: register?.tokens ?? null, rows: register?.rows?.length ?? null, first: register?.rows?.[0]?.num ?? null }));
643
644
  const regNote = register ? [registerNote(register.rows), certificateLinks(register.rows)].filter(Boolean).join("\n") : undefined;
645
+ const opsCatalog = await operationsCatalogNote(env.DB, q.query);
644
646
 
645
647
  // Conversational route, decided by query UNDERSTANDING (any language, any
646
648
  // phrasing) — not string matching. No retrieval: nothing in the corpus
@@ -1146,7 +1148,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1146
1148
  q.lang,
1147
1149
  keptHistory,
1148
1150
  // stage-extracted graph facts (GraphRAG) ride the same note channel
1149
- [processNote, eNote, regNote, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...(retrieved.notes ?? [])].filter(Boolean).join("\n") || undefined,
1151
+ [processNote, eNote, regNote, opsCatalog, contextNote(declaredCtx, docScope), accountNote, modelNote, vocabNote, memNote, machineNote, conditionNote, aggregationNote, boundaryNote, licenseNote, ...(retrieved.notes ?? [])].filter(Boolean).join("\n") || undefined,
1150
1152
  summary,
1151
1153
  budget,
1152
1154
  );
@@ -1155,7 +1157,10 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1155
1157
  // round, armed only where a tool can help. The model may call
1156
1158
  // register_search through the strict line protocol; the worker
1157
1159
  // executes it deterministically and the ATTRIBUTED result joins the
1158
- // messages — what the tool returned, for the string it asked.
1160
+ // messages — what the tool returned, for the string it asked. The
1161
+ // invocations record into pendingTools; the stream emits them as its
1162
+ // first events (the UI shows what the agent consulted).
1163
+ const pendingTools: { name: string; query: string; output: string }[] = [];
1159
1164
  if (/certificate|certified|certification/i.test(q.query) && env.DB) {
1160
1165
  try {
1161
1166
  const probe = await (env as any).AI.run(model, {
@@ -1169,6 +1174,7 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1169
1174
  const result = await runTool(env.DB, call);
1170
1175
  if (result) {
1171
1176
  messages.push({ role: "system", content: toolNote(result) });
1177
+ pendingTools.push(result);
1172
1178
  console.log("agent-tool:", result.name, JSON.stringify(result.query), "->", result.output.slice(0, 80));
1173
1179
  }
1174
1180
  }
@@ -1215,6 +1221,9 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
1215
1221
  const send = (obj: unknown) => controller.enqueue(encoder.encode(`data: ${JSON.stringify(obj)}\n\n`));
1216
1222
  // the reading arrives first: the interpretation that steered
1217
1223
  // retrieval, before a single token of the answer
1224
+ for (const t of pendingTools) {
1225
+ try { send({ type: "tool", name: t.name, query: t.query }); } catch { /* never block the answer */ }
1226
+ }
1218
1227
  send({ type: "read", read: readAs() });
1219
1228
  const sourceQuality = answerQuality(cites.map((c: any) => c.quality));
1220
1229
  send({ type: "citations", citations: cites, context_applied: ctxApplied, ...(sourceQuality ? { source_quality: sourceQuality, confidence_note: qualityNote(sourceQuality), ...(sourceQuality === "ocr" ? { experimental_sources: experimentalSourceLabels(cites) } : {}) } : {}), ...(liveRecords ? { records: liveRecords } : {}), quota, });
@@ -0,0 +1,27 @@
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.
8
+
9
+ export function isOperationIntent(query: string): boolean {
10
+ return /\b(operations?|endpoints?)\b/i.test(query);
11
+ }
12
+
13
+ export function catalogNote(anchors: string[]): string {
14
+ 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")}`;
16
+ }
17
+
18
+ export async function operationsCatalogNote(db: any, query: string): Promise<string | undefined> {
19
+ if (!isOperationIntent(query)) return undefined;
20
+ 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;
24
+ } catch {
25
+ return undefined; // the lane is optional
26
+ }
27
+ }