@konneal/engine 0.2.136 → 0.2.138
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-N5I35VCK.js → ask-UL5NL5O7.js} +6 -5
- package/dist/{chunk-YLBPABDQ.js → chunk-4GNKOTIK.js} +48 -38
- package/dist/{chunk-MWOY24B6.js → chunk-5WITTJQD.js} +4 -4
- package/dist/{chunk-TH5XGPD5.js → chunk-LSZTJI7V.js} +28 -56
- package/dist/chunk-NI4CIK6W.js +57 -0
- package/dist/{chunk-J6LBR6GI.js → chunk-RKNN3WAV.js} +316 -20
- package/dist/{chunk-7AXXR7GD.js → chunk-XH5QGX2O.js} +7 -5
- package/dist/dbtools.d.ts +67 -0
- package/dist/env-LMHGNJTN.js +18 -0
- package/dist/mcp-proto.d.ts +6 -0
- package/dist/{search-LFS5HHMZ.js → search-VEGQBEFC.js} +4 -3
- package/dist/{tools-O4JYGVSR.js → tools-EZRLYLTM.js} +3 -2
- package/dist/tools.d.ts +4 -3
- package/dist/worker_public/src/index.js +38 -15
- package/package.json +1 -1
- package/workers/worker_public/src/ask.ts +42 -18
- package/workers/worker_public/src/dbtools.ts +343 -0
- package/workers/worker_public/src/mcp-proto.ts +36 -4
- package/workers/worker_public/src/tools.ts +60 -14
|
@@ -17,19 +17,21 @@ export interface ToolResult {
|
|
|
17
17
|
output: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/** The strict protocol: a line `TOOL
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
/** The strict protocol: a line `TOOL <name> {…json…}`. Line-anchored,
|
|
21
|
+
* case-sensitive (prose never trips it); the args are the WHOLE rest
|
|
22
|
+
* of the line parsed as JSON — nested objects (db.find predicates)
|
|
23
|
+
* are legal, and a malformed or unterminated object is not a call. */
|
|
23
24
|
export function parseToolCall(text: string): ToolCall | null {
|
|
24
|
-
const m = /^TOOL\s+([a-z_.]+)\
|
|
25
|
+
const m = /^TOOL\s+([a-z_.]+)[ \t]*(\{.*)?$/m.exec(String(text ?? ""));
|
|
25
26
|
if (!m) return null;
|
|
26
|
-
|
|
27
|
-
if (m[
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
27
|
+
const rest = (m[2] ?? "").trim();
|
|
28
|
+
if (!rest) return { name: m[1].toLowerCase(), args: {} };
|
|
29
|
+
if (!rest.startsWith("{")) return null;
|
|
30
|
+
try {
|
|
31
|
+
return { name: m[1].toLowerCase(), args: JSON.parse(rest) };
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
31
34
|
}
|
|
32
|
-
return { name: m[1].toLowerCase(), args };
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
// ── the tool registry (OCP, the owner's 2026-10-04 direction) ────────
|
|
@@ -65,19 +67,63 @@ const certificatesSearch: ToolSpec = {
|
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
import { unitsGet, graphCites, docsSection, glossaryLookup, documentsFamily, licensedSection, verdictEvaluate, conditionsCheck, bibEntry, unitsLookup, unitsConvert } from "./tools-content.ts";
|
|
70
|
+
import { runFind, runSchema } from "./dbtools.ts";
|
|
71
|
+
|
|
72
|
+
// the data-plane grammar (dbtools.ts): the model composes typed
|
|
73
|
+
// predicates over the PUBLISHED schema — no operation menus, no raw SQL
|
|
74
|
+
const dbSchema: ToolSpec = {
|
|
75
|
+
name: "db.schema",
|
|
76
|
+
description:
|
|
77
|
+
"The published data map: every queryable table (the certificate register, the document registry, the citation graph, the model plane, typed units, the corpus chunks) with its columns, types, and meanings. Call this first whenever a question turns on structured data; then compose db.find.",
|
|
78
|
+
params: [{ key: "table", required: false, description: "one table's detail; omit for the whole catalog" }],
|
|
79
|
+
audiences: ["agent", "mcp"],
|
|
80
|
+
handler: async (_env, args) => {
|
|
81
|
+
const t = args?.table ? String(args.table) : undefined;
|
|
82
|
+
return runSchema(t);
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const dbFind: ToolSpec = {
|
|
87
|
+
name: "db.find",
|
|
88
|
+
description:
|
|
89
|
+
"Query a published table with typed predicates you compose: where: [{col, op, value}] with ops eq|ne|lt|le|gt|ge|in|like|between, optional select, order_by {col, dir}, limit (≤25), group_by + agg {fn: count|sum|avg|min|max, col}. Values bind safely; identifiers validate against the schema (errors name the valid columns). Returns the matching rows or aggregate with the query echoed.",
|
|
90
|
+
params: [
|
|
91
|
+
{ key: "table", required: true, description: "a published table (db.schema lists them)" },
|
|
92
|
+
{ key: "where", required: false, description: "[{col, op, value}] predicates, ANDed" },
|
|
93
|
+
{ key: "select", required: false, description: "columns to return; default per table" },
|
|
94
|
+
{ key: "order_by", required: false, description: "{col, dir: asc|desc}" },
|
|
95
|
+
{ key: "limit", required: false, description: "row cap, ≤25" },
|
|
96
|
+
{ key: "agg", required: false, description: "{fn, col?} aggregate instead of rows; with group_by: [cols]" },
|
|
97
|
+
],
|
|
98
|
+
audiences: ["agent", "mcp"],
|
|
99
|
+
handler: async (env, args) => {
|
|
100
|
+
const findArgs = {
|
|
101
|
+
table: String(args?.table ?? ""),
|
|
102
|
+
where: Array.isArray(args?.where) ? args.where : [],
|
|
103
|
+
select: Array.isArray(args?.select) ? args.select : undefined,
|
|
104
|
+
order_by: args?.order_by && typeof args.order_by === "object" ? (args.order_by as { col: string; dir?: "asc" | "desc" }) : undefined,
|
|
105
|
+
limit: args?.limit != null ? Number(args.limit) : undefined,
|
|
106
|
+
group_by: Array.isArray(args?.group_by) ? args.group_by : undefined,
|
|
107
|
+
agg: args?.agg && typeof args.agg === "object" ? (args.agg as { fn: "count" | "sum" | "avg" | "min" | "max"; col?: string }) : undefined,
|
|
108
|
+
};
|
|
109
|
+
if (!findArgs.table) return null;
|
|
110
|
+
return runFind(env, findArgs);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const TOOLS_REGISTRY: ToolSpec[] = [dbSchema, dbFind, certificatesSearch, unitsGet, graphCites, docsSection, glossaryLookup, documentsFamily, licensedSection, verdictEvaluate, conditionsCheck, bibEntry, unitsLookup, unitsConvert];
|
|
68
115
|
|
|
69
|
-
export const TOOLS_REGISTRY: ToolSpec[] = [certificatesSearch, unitsGet, graphCites, docsSection, glossaryLookup, documentsFamily, licensedSection, verdictEvaluate, conditionsCheck, bibEntry, unitsLookup, unitsConvert];
|
|
70
116
|
|
|
71
117
|
/** The agent loop's protocol declaration, GENERATED from the registry —
|
|
72
118
|
* the model's tool vocabulary is always the registry's, never a
|
|
73
119
|
* hand-maintained literal. */
|
|
74
120
|
export const TOOL_DECLARATION = [
|
|
75
|
-
"You may
|
|
121
|
+
"You may query data before answering, by writing ONE line per call:",
|
|
76
122
|
...TOOLS_REGISTRY.filter((t) => t.audiences.includes("agent")).map((t) => {
|
|
77
|
-
const shape = `{${t.params.map((p) => `"${p.key}":
|
|
123
|
+
const shape = `{${t.params.map((p) => `"${p.key}": <${p.description}>`).join(", ")}}`;
|
|
78
124
|
return `TOOL ${t.name} ${shape}`;
|
|
79
125
|
}),
|
|
80
|
-
"The worker runs
|
|
126
|
+
"The worker runs each call and returns the result attributed; you may issue up to three calls across the turns, one per turn, each on its own single line (compact JSON, no line breaks). Structured questions — counts, latest, filters, per-holder or per-year breakdowns over the register, document editions, model-plane requirements — start from TOOL db.schema (it lists the queryable tables and their columns), then compose TOOL db.find predicates. Each result arrives attributed: phrase it as what the tool returned, with your query visible in the answer. When you have enough, answer WITHOUT a TOOL line; if no tool helps, answer directly.",
|
|
81
127
|
].join("\n");
|
|
82
128
|
|
|
83
129
|
/** Dispatch by LOOKUP — a tool name is never hard-coded at a call site.
|