@mnmal-ai/substrate-nl 1.0.0-alpha.1 → 1.0.0-alpha.10

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 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/ask/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,KAAK,KAAK,EAAqC,MAAM,mBAAmB,CAAC;AAElF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAa,MAAM,aAAa,CAAC;AAElE,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AA+ED,wBAAuB,MAAM,CAC3B,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,OAAO,GACZ,cAAc,CAAC,OAAO,CAAC,CA8GzB"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/ask/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,KAAK,KAAK,EAAqC,MAAM,mBAAmB,CAAC;AAElF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAa,MAAM,aAAa,CAAC;AAElE,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAkID,wBAAuB,MAAM,CAC3B,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,OAAO,GACZ,cAAc,CAAC,OAAO,CAAC,CAqHzB"}
@@ -1,4 +1,4 @@
1
- import { defineBootstrap, error400, jsonResponse, parseJsonBody } from "@mnmal-ai/substrate/sdk";
1
+ import { defineBootstrap, error400, jsonResponse, parseJsonBody, trimTrailingSlashes } from "@mnmal-ai/substrate/sdk";
2
2
  import { z } from "zod";
3
3
  import { createHash } from "node:crypto";
4
4
 
@@ -800,7 +800,10 @@ function buildJudgePrompt(question, result, pack, rulings = {}, rejected = []) {
800
800
  ]
801
801
  }
802
802
  })] : [],
803
- branch("recall"),
803
+ branch("recall", { type: {
804
+ type: "string",
805
+ enum: allTypes
806
+ } }),
804
807
  branch("clarify"),
805
808
  branch("refuse"),
806
809
  branch("escalate")
@@ -824,7 +827,7 @@ function buildJudgePrompt(question, result, pack, rulings = {}, rejected = []) {
824
827
  " of a name or id, contains = a word inside a title or subject. Never bind a word that only",
825
828
  " describes the question (e.g. \"status\", \"called\").",
826
829
  "- recall: the question asks what is known ABOUT a topic (free-text subject words, not field values);",
827
- " semantic search over the text answers it.",
830
+ " semantic search over the text answers it. Name the type whose rows hold that knowledge.",
828
831
  "- clarify: RARE. Only when the question has two specific readings and nothing in it chooses one.",
829
832
  " Missing detail is not ambiguity: if a type or a topic fits, choose type or recall.",
830
833
  "- refuse: the question is not about this store at all, or asks to change data.",
@@ -942,6 +945,7 @@ async function parseWithJudge(question, pack, ctx, judge, opts = {}) {
942
945
  case "recall": return {
943
946
  status: "recall",
944
947
  query: question,
948
+ type: checked.type,
945
949
  trail
946
950
  };
947
951
  case "clarify":
@@ -1007,22 +1011,59 @@ async function rows(c, source, http, deps, handoff) {
1007
1011
  const frame = executable(c, deps.pack);
1008
1012
  const key = Object.keys(frame)[0];
1009
1013
  const env = await deps.engine.query(frame, http);
1010
- const present = env.data !== void 0 && key in env.data;
1014
+ const data = env.data !== void 0 && key in env.data ? env.data?.[key] : void 0;
1015
+ const errors = [...env.errors ?? []];
1016
+ let count;
1017
+ if (c.answer === "count" && Array.isArray(data)) {
1018
+ const counted = await countRest(frame, key, data.length, env, http, deps);
1019
+ if (typeof counted === "number") count = counted;
1020
+ else errors.push(counted);
1021
+ }
1011
1022
  return {
1012
1023
  kind: "rows",
1013
1024
  frame,
1014
1025
  answer: c.answer,
1015
- data: present ? env.data?.[key] : void 0,
1016
- ...env.errors !== void 0 && env.errors.length > 0 ? { errors: env.errors } : {},
1026
+ data,
1027
+ ...count !== void 0 ? { count } : {},
1028
+ ...errors.length > 0 ? { errors } : {},
1017
1029
  source,
1018
1030
  ...handoff !== void 0 ? { handoff } : {}
1019
1031
  };
1020
1032
  }
1021
- async function recall(query, ns, http, deps) {
1033
+ const MAX_COUNT_PAGES = 1e3;
1034
+ /** The population a count candidate matches: `seen` rows from page one, then id-only pages after its cursor. */
1035
+ async function countRest(frame, key, seen, first, http, deps) {
1036
+ const params = frame[key]?.params ?? {};
1037
+ let count = seen;
1038
+ let page = first._pagination?.[key];
1039
+ for (let pages = 1; page?.hasMore === true; pages++) {
1040
+ if (pages >= MAX_COUNT_PAGES || page.nextCursor === void 0 || isAborted(http)) return {
1041
+ code: "count_incomplete",
1042
+ message: `counted ${count} rows and stopped before the end; the true count is higher`
1043
+ };
1044
+ const env = await deps.engine.query({ [key]: {
1045
+ params: {
1046
+ ...params,
1047
+ cursor: page.nextCursor
1048
+ },
1049
+ fields: { id: true }
1050
+ } }, http);
1051
+ const rows = env.data?.[key];
1052
+ if (!Array.isArray(rows)) return {
1053
+ code: "count_incomplete",
1054
+ message: `counted ${count} rows, then a page failed: ${JSON.stringify(env.errors ?? [])}`
1055
+ };
1056
+ count += rows.length;
1057
+ page = env._pagination?.[key];
1058
+ }
1059
+ return count;
1060
+ }
1061
+ async function recall(query, ns, type, http, deps) {
1022
1062
  const frame = { "recall/Hit": {
1023
1063
  params: {
1024
1064
  to: query,
1025
1065
  namespace: ns,
1066
+ type,
1026
1067
  k: RECALL_K
1027
1068
  },
1028
1069
  fields: {
@@ -1142,7 +1183,7 @@ async function* runAsk(req, http, deps) {
1142
1183
  outcome = await rows(judged.candidate, "judge", http, deps);
1143
1184
  break;
1144
1185
  case "recall":
1145
- outcome = await recall(judged.query, deps.pack.namespace, http, deps);
1186
+ outcome = await recall(judged.query, deps.pack.namespace, ctx.forceType ?? judged.type, http, deps);
1146
1187
  break;
1147
1188
  case "refuse":
1148
1189
  outcome = {
@@ -1178,7 +1219,7 @@ var OllamaJudge = class {
1178
1219
  constructor(config) {
1179
1220
  this.#config = {
1180
1221
  ...config,
1181
- baseUrl: config.baseUrl.replace(/\/+$/, "")
1222
+ baseUrl: trimTrailingSlashes(config.baseUrl)
1182
1223
  };
1183
1224
  }
1184
1225
  async decide(prompt, signal) {
@@ -1372,7 +1413,7 @@ function packField(name, def, operators) {
1372
1413
  name,
1373
1414
  kind: "scalar",
1374
1415
  valueType: def.type,
1375
- indexed: def.indexed === true,
1416
+ indexed: def.indexed !== false,
1376
1417
  operators: [...operators[`scalar.${def.type}`] ?? []],
1377
1418
  phrases,
1378
1419
  ...def.enum !== void 0 ? { enum: [...def.enum] } : {},
@@ -1492,7 +1533,7 @@ async function profileNamespace(input) {
1492
1533
  return { types };
1493
1534
  }
1494
1535
  function profiled(def) {
1495
- if (def.kind === "scalar") return def.type === "string" && def.indexed === true;
1536
+ if (def.kind === "scalar") return def.type === "string" && def.indexed !== false;
1496
1537
  return def.kind === "list" && def.indexed === true && def.of.kind === "scalar" && def.of.type === "string";
1497
1538
  }
1498
1539
 
package/dist/bootstrap.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as bootstrap, t as NlBootstrapConfigSchema } from "./bootstrap-BpKUloR3.js";
1
+ import { n as bootstrap, t as NlBootstrapConfigSchema } from "./bootstrap-BDi2fdbS.js";
2
2
 
3
3
  export { NlBootstrapConfigSchema, bootstrap, bootstrap as default };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as askHandler, c as profileNamespace, d as mergeRulings, f as readRulings, g as parseQuestion, h as parseWithJudge, i as createNlPlugin, l as buildNamespacePack, m as runAsk, n as bootstrap, o as packHandler, p as OllamaJudge, r as CONTRACT_VERSION, s as PackService, t as NlBootstrapConfigSchema, u as NamespaceRulingsSchema } from "./bootstrap-BpKUloR3.js";
1
+ import { a as askHandler, c as profileNamespace, d as mergeRulings, f as readRulings, g as parseQuestion, h as parseWithJudge, i as createNlPlugin, l as buildNamespacePack, m as runAsk, n as bootstrap, o as packHandler, p as OllamaJudge, r as CONTRACT_VERSION, s as PackService, t as NlBootstrapConfigSchema, u as NamespaceRulingsSchema } from "./bootstrap-BDi2fdbS.js";
2
2
  import { complete } from "./complete.js";
3
3
 
4
4
  export { CONTRACT_VERSION, NamespaceRulingsSchema, NlBootstrapConfigSchema, OllamaJudge, PackService, askHandler, bootstrap, buildNamespacePack, complete, createNlPlugin, mergeRulings, packHandler, parseQuestion, parseWithJudge, profileNamespace, readRulings, runAsk };
@@ -30,6 +30,7 @@ export type JudgedResult = {
30
30
  } | {
31
31
  status: 'recall';
32
32
  query: string;
33
+ type: string;
33
34
  trail: JudgeStep[];
34
35
  } | {
35
36
  status: 'clarify' | 'refuse';
@@ -1 +1 @@
1
- {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/judge/judge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEzF,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EAEjB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;AAExC,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,6EAA6E;AAC7E,MAAM,WAAW,KAAK;IACpB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACrE;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC;AAEpC,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GAChE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GACpE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC;AAarE,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,gBAAqB,EAC9B,QAAQ,GAAE,MAAM,EAAO,GACtB,WAAW,CAqFb;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAkBrF;AAkBD,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAmCD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,KAAK,EACZ,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,YAAY,CAAC,CA+DvB"}
1
+ {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/judge/judge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEzF,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EAEjB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;AAExC,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,6EAA6E;AAC7E,MAAM,WAAW,KAAK;IACpB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACrE;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC;AAEpC,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GAChE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GACpE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC;AAarE,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,gBAAqB,EAC9B,QAAQ,GAAE,MAAM,EAAO,GACtB,WAAW,CAsFb;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAkBrF;AAkBD,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAmCD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,KAAK,EACZ,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,YAAY,CAAC,CA+DvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/judge/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,YAAW,KAAK;;IAGvC,YAAY,MAAM,EAAE,iBAAiB,EAEpC;IAEK,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBxE;CACF"}
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/judge/ollama.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,YAAW,KAAK;;IAGvC,YAAY,MAAM,EAAE,iBAAiB,EAEpC;IAEK,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBxE;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnmal-ai/substrate-nl",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.10",
4
4
  "description": "Natural-language questions for Substrate — a deterministic parser with an optional constrained judge, served at POST /substrate/v1/nl and GET /substrate/v1/nl/pack/:ns, plus browser-safe completion.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -36,9 +36,9 @@
36
36
  "zod": "^4.6.5"
37
37
  },
38
38
  "devDependencies": {
39
- "@biomejs/biome": "^2.5.15",
40
- "@mnmal-ai/substrate": "1.0.0-alpha.1",
41
- "@mnmal-ai/substrate-config": "1.0.0-alpha.1",
39
+ "@biomejs/biome": "2.6.2",
40
+ "@mnmal-ai/substrate": "1.0.0-alpha.10",
41
+ "@mnmal-ai/substrate-config": "1.0.0-alpha.10",
42
42
  "@types/node": "^26.6.4",
43
43
  "tsdown": "^0.23.0",
44
44
  "typescript": "^7.0.2",
@@ -48,7 +48,7 @@
48
48
  "@mnmal-ai/substrate": ">=1.0.0-alpha.0 <2.0.0"
49
49
  },
50
50
  "engines": {
51
- "node": ">=26.2.0"
51
+ "node": ">=26.12.1"
52
52
  },
53
53
  "substrate": {
54
54
  "tier": "kernel",