@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.
- package/dist/{ask-O2ZWIV2Y.js → ask-UC5IVQDH.js} +1 -1
- package/dist/{chunk-67VVH7CX.js → chunk-PENTOBUO.js} +30 -1
- package/dist/operations.d.ts +3 -0
- package/dist/worker_public/src/index.js +2 -2
- package/package.json +1 -1
- package/workers/worker_public/src/ask.ts +11 -2
- package/workers/worker_public/src/operations.ts +27 -0
|
@@ -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 });
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
modelGroundingBlock,
|
|
7
7
|
scoreFaithfulness,
|
|
8
8
|
scoreJudge
|
|
9
|
-
} from "../../chunk-
|
|
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-
|
|
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.
|
|
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
|
+
}
|