@polycode-projects/the-mechanical-code-talker 3.0.5 → 3.0.7

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.
Files changed (68) hide show
  1. package/README.md +41 -16
  2. package/bin/tmct.mjs +1 -1
  3. package/corpus/child/README.md +2 -2
  4. package/corpus/child/index.json.gz +0 -0
  5. package/corpus/child/manifest.json +74 -74
  6. package/corpus/child/shards/child-00.jsonl.gz +0 -0
  7. package/corpus/child/shards/child-01.jsonl.gz +0 -0
  8. package/corpus/child/shards/child-02.jsonl.gz +0 -0
  9. package/corpus/child/shards/child-03.jsonl.gz +0 -0
  10. package/corpus/child/shards/child-04.jsonl.gz +0 -0
  11. package/corpus/child/shards/child-05.jsonl.gz +0 -0
  12. package/corpus/child/shards/child-06.jsonl.gz +0 -0
  13. package/corpus/child/shards/child-07.jsonl.gz +0 -0
  14. package/corpus/child/shards/child-08.jsonl.gz +0 -0
  15. package/corpus/child/shards/child-09.jsonl.gz +0 -0
  16. package/corpus/child/shards/child-0a.jsonl.gz +0 -0
  17. package/corpus/child/shards/child-0b.jsonl.gz +0 -0
  18. package/corpus/child/shards/child-0c.jsonl.gz +0 -0
  19. package/corpus/child/shards/child-0d.jsonl.gz +0 -0
  20. package/corpus/child/shards/child-0e.jsonl.gz +0 -0
  21. package/corpus/child/shards/child-0f.jsonl.gz +0 -0
  22. package/corpus/child/shards/child-10.jsonl.gz +0 -0
  23. package/corpus/child/shards/child-11.jsonl.gz +0 -0
  24. package/corpus/child/shards/child-12.jsonl.gz +0 -0
  25. package/corpus/child/shards/child-13.jsonl.gz +0 -0
  26. package/corpus/child/shards/child-14.jsonl.gz +0 -0
  27. package/corpus/child/shards/child-15.jsonl.gz +0 -0
  28. package/corpus/child/shards/child-16.jsonl.gz +0 -0
  29. package/corpus/child/shards/child-17.jsonl.gz +0 -0
  30. package/corpus/child/shards/child-18.jsonl.gz +0 -0
  31. package/corpus/child/shards/child-19.jsonl.gz +0 -0
  32. package/corpus/child/shards/child-1a.jsonl.gz +0 -0
  33. package/corpus/child/shards/child-1b.jsonl.gz +0 -0
  34. package/corpus/child/shards/child-1c.jsonl.gz +0 -0
  35. package/corpus/child/shards/child-1d.jsonl.gz +0 -0
  36. package/corpus/child/shards/child-1e.jsonl.gz +0 -0
  37. package/corpus/child/shards/child-1f.jsonl.gz +0 -0
  38. package/corpus/conceptnet/quality-filter.mjs +28 -4
  39. package/corpus/tier2/generate.mjs +4 -8
  40. package/corpus/tier2/human-large.jsonl +0 -2
  41. package/corpus/tier2/human-medium.jsonl +0 -2
  42. package/corpus/tier2/manifest.json +6 -6
  43. package/data/templates/constructions/digest-sentence-structures.toml +146 -1
  44. package/package.json +18 -15
  45. package/src/adapters/corpus/digest-bank.mjs +15 -3
  46. package/src/domain/answer-variants.json +1 -1
  47. package/src/domain/ask-vocab.mjs +4 -0
  48. package/src/domain/ask.mjs +101 -12
  49. package/src/domain/codegraph.mjs +25 -8
  50. package/src/domain/digest/compose.mjs +142 -10
  51. package/src/domain/digest/config.json +5 -0
  52. package/src/domain/digest/structures.mjs +39 -14
  53. package/src/domain/interpret/normalize.mjs +2 -2
  54. package/src/domain/reference-pack.mjs +12 -3
  55. package/src/domain/router/call-validator.mjs +1 -1
  56. package/src/domain/router/drive.mjs +2 -2
  57. package/src/domain/router/set-algebra.mjs +1 -1
  58. package/src/services/adventure.mjs +34 -19
  59. package/src/services/chat-page-viz.mjs +16 -5
  60. package/src/services/chat.mjs +290 -88
  61. package/src/services/extract-facts.mjs +46 -4
  62. package/src/services/index.mjs +6 -3
  63. package/src/services/ledger-viz.mjs +1 -1
  64. package/src/services/research.mjs +80 -3
  65. package/src/surfaces/web/chat-browser-entry.mjs +23 -3
  66. package/src/surfaces/web/digest-client.mjs +8 -3
  67. package/src/surfaces/web/graph-ask-browser-entry.mjs +41 -0
  68. package/src/surfaces/web/memory-ask-browser.bundle.js +113 -113
@@ -1,7 +1,7 @@
1
1
  // src/domain/router/set-algebra.mjs — the COMPOSITION OPERATORS: pure set-algebra a
2
2
  // multi-step plan needs to fold its threaded step result-sets into ONE composed
3
3
  // answer. Shared by the product router (goal-reasoner's relative-filter fold)
4
- // and the bench result-execution layer (agentbench/results.mjs re-exports
4
+ // and the bench result-execution layer (test-benchmarks/agentbench/results.mjs re-exports
5
5
  // these) — the bench imports the product, never the other way round. The
6
6
  // resolver DRIVER picks the operator from the router's OWN HTN method
7
7
  // (relative-filter -> intersect; conditional -> fallback/guard) and applies it;
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { worldProvenanceTag } from "../domain/worlds-pack.mjs";
12
12
  import { parseImperative, OBJECT_PRONOUNS } from "../domain/grammar/ace.mjs";
13
+ import { register as registerReferent, bind as bindDiscourseForm } from "../domain/discourse.mjs";
13
14
  import { createCompletionsGraphAdapter } from "../domain/completions/graph-adapter.mjs";
14
15
  import { actionFamilies } from "../domain/router/taught.mjs";
15
16
  import { compileDomain, precondHolds, roleBinding } from "../domain/domain.mjs";
@@ -1224,14 +1225,16 @@ function renderedImperativeCommand(cmd) {
1224
1225
  return parts.join(" ");
1225
1226
  }
1226
1227
 
1227
- // ---- pronoun binding: the session focus ---------------------------------------
1228
+ // ---- pronoun binding: the session discourse record ----------------------------
1228
1229
  //
1229
1230
  // A world command may name its object with a pronoun ("examine it", "take
1230
1231
  // them", "talk to him") instead of a noun. The antecedent is not in the
1231
- // sentence — it's the last thing the player successfully acted on this
1232
- // session, the FOCUS — so the parser leaves the pronoun bare (ace.mjs's
1232
+ // sentence — it's the last adventure object the player successfully acted on
1233
+ // this session — so the parser leaves the pronoun bare (ace.mjs's
1233
1234
  // OBJECT_PRONOUNS) and the lane binds it here, through ONE seam that every
1234
- // object-taking verb passes on its way to runWorldCommand. With no focus
1235
+ // object-taking verb passes on its way to runWorldCommand. The antecedent lives
1236
+ // as one referent among N in the shared discourse record, so an adventure
1237
+ // object is bound the same way a code-graph answer's referent is. With nothing
1235
1238
  // standing, a pronoun gets an honest reference nudge, never the vocabulary
1236
1239
  // decline (a pronoun is a reference, not an unknown word).
1237
1240
 
@@ -1264,19 +1267,25 @@ async function noFocusPronounNudge(pronoun, { memoryDir }) {
1264
1267
  );
1265
1268
  }
1266
1269
 
1267
- /** Bind any pronoun object/indirect/instrument slot to the session focus.
1268
- * Returns `{ cmd }` with the pronouns rewritten to the focus term, or `{
1269
- * nudge }` (the reference nudge) when a pronoun stands but no focus does. A
1270
- * command with no pronoun passes straight through untouched. */
1271
- async function bindPronouns(cmd, { focus, memoryDir }) {
1270
+ /** Bind any pronoun object/indirect/instrument slot to the last adventure
1271
+ * object in the discourse record. Returns `{ cmd }` with the pronouns
1272
+ * rewritten to that object's term, or `{ nudge }` (the reference nudge) when a
1273
+ * pronoun stands but no adventure object does. A command with no pronoun
1274
+ * passes straight through untouched. All four surface pronouns
1275
+ * (it/them/him/her) normalize to the one `it` probe, then bind to the newest
1276
+ * referent THIS lane registered — the record may also hold code-graph
1277
+ * referents, so the bind is scoped to `lane: "adventure"`. */
1278
+ async function bindPronouns(cmd, { discourseHolder, memoryDir }) {
1272
1279
  if (!commandHasPronoun(cmd)) return { cmd };
1273
- if (!focus) {
1280
+ const probe = discourseHolder ? bindDiscourseForm(discourseHolder.record, "it") : null;
1281
+ const focusTerm = (probe?.candidates || []).find((r) => r.from?.lane === "adventure")?.label ?? null;
1282
+ if (!focusTerm) {
1274
1283
  const pronoun = PRONOUN_SLOTS.map((s) => cmd[s]).find((v) => v && OBJECT_PRONOUNS.has(v));
1275
1284
  return { nudge: await noFocusPronounNudge(pronoun, { memoryDir }) };
1276
1285
  }
1277
1286
  const bound = { ...cmd };
1278
1287
  for (const s of PRONOUN_SLOTS) {
1279
- if (bound[s] && OBJECT_PRONOUNS.has(bound[s])) bound[s] = focus;
1288
+ if (bound[s] && OBJECT_PRONOUNS.has(bound[s])) bound[s] = focusTerm;
1280
1289
  }
1281
1290
  return { cmd: bound };
1282
1291
  }
@@ -1292,7 +1301,7 @@ async function bindPronouns(cmd, { focus, memoryDir }) {
1292
1301
  * recognizer, injected so the two lanes can never disagree about what a plan
1293
1302
  * frame is.
1294
1303
  */
1295
- export async function adventureTurn(line, { planHolder, memoryDir, sessionId = "", env, lexicon = null, graph = null, cache = null, isPlanFrameLine = () => false }) {
1304
+ export async function adventureTurn(line, { planHolder, memoryDir, sessionId = "", env, lexicon = null, graph = null, cache = null, isPlanFrameLine = () => false, discourseHolder = null }) {
1296
1305
  const slot = planHolder?.state ?? null;
1297
1306
  const adventure = slot?.adventure ?? null;
1298
1307
  const opening = matchAdventureOpening(line);
@@ -1351,16 +1360,22 @@ export async function adventureTurn(line, { planHolder, memoryDir, sessionId = "
1351
1360
  if (INVENTORY_RE.test(line)) return inventoryAnswer({ memoryDir, graph });
1352
1361
  const parsed = parseImperative(line, lexicon ?? undefined);
1353
1362
  if (parsed) {
1354
- const bound = await bindPronouns(parsed, { focus: adventure.focus, memoryDir });
1363
+ const bound = await bindPronouns(parsed, { discourseHolder, memoryDir });
1355
1364
  if (bound.nudge) return bound.nudge;
1356
1365
  const cmd = bound.cmd;
1357
1366
  const result = await runWorldCommand(cmd, { world: adventure.world, memoryDir, env, graph, cache });
1358
- // The object a command SUCCESSFULLY named becomes the focus a later
1359
- // pronoun binds to — so "look lamp" then "examine it" reads the lamp, and
1360
- // "talk to housekeeper" makes "him"/"her" the housekeeper. A miss leaves
1361
- // the standing focus untouched; a bare room look or a move carries no
1362
- // object and so never disturbs it.
1363
- if (!result.miss && cmd.object) adventure.focus = cmd.object;
1367
+ // The object a command SUCCESSFULLY named registers as a discourse referent
1368
+ // a later pronoun binds to — so "look lamp" then "examine it" reads the
1369
+ // lamp, and "talk to housekeeper" makes "him"/"her" the housekeeper. A miss
1370
+ // leaves the record untouched; a bare room look or a move carries no object
1371
+ // and so never disturbs it.
1372
+ if (!result.miss && cmd.object && discourseHolder) {
1373
+ discourseHolder.record = registerReferent(discourseHolder.record, {
1374
+ kind: "entity", class: "AdventureObject", label: cmd.object,
1375
+ ids: [`adventure:${cmd.object}`], attrs: {},
1376
+ from: { turn: discourseHolder.record.turn, lane: "adventure", query: line },
1377
+ });
1378
+ }
1364
1379
  if (!cmd.corrected?.length) return result;
1365
1380
  // A fuzzy-repaired verb or direction still executes normally, but the
1366
1381
  // response says what it read the line as, so a genuine miss is never
@@ -16,7 +16,7 @@
16
16
  // chip is read straight off the SAME "(source: ...)" citation chat.mjs's own
17
17
  // factPhrase/renderFactLine convention already appends to most answers (see
18
18
  // e.g. `dog is a kind of animal (source: corpus:conceptnet ...)` — already
19
- // asserted by e2e/pages-chat-fullscreen.test.mjs against this page), never a
19
+ // asserted by test-e2e/pages-chat-fullscreen.test.mjs against this page), never a
20
20
  // second provenance computation against memory internals: `provBucketFor`
21
21
  // (ledger-viz.mjs) is spliced in unmodified and applied to whatever citation
22
22
  // text the answer already carries, so this page's chip and the ledger's own
@@ -172,10 +172,18 @@ export function transcriptMarkdown(turns, meta, headerMd, turnMd) {
172
172
  }
173
173
 
174
174
  /** The self-contained "talk to it" full-screen page. Pure — the same output
175
- * for the same `title` every time; every other piece of state (the session,
176
- * every message, every chip) is computed live in the browser once the
177
- * sibling chat bundle loads, exactly as the embedded widget already works. */
178
- export function renderChatHtml({ title = DEFAULT_TITLE } = {}) {
175
+ * for the same `title`/`digestStructures` every time; every other piece of
176
+ * state (the session, every message, every chip) is computed live in the
177
+ * browser once the sibling chat bundle loads, exactly as the embedded widget
178
+ * already works. `digestStructures` are the pre-parsed [[structure]] rows of
179
+ * the digest sentence-structure bank, embedded so a long answer can lead
180
+ * with a composed digest instead of the flat fact list — the same table
181
+ * research.html/ledger.html already embed, fed here to the chat bundle's own
182
+ * live digest-bank twin (see chat-browser-entry.mjs) rather than to a
183
+ * client-side digest panel of this page's own; an empty list degrades to the
184
+ * flat list exactly as before this page could digest at all. */
185
+ export function renderChatHtml({ title = DEFAULT_TITLE, digestStructures = [] } = {}) {
186
+ const digestStructuresJson = JSON.stringify(Array.isArray(digestStructures) ? digestStructures : []);
179
187
  const legendHtml = PROV_LEGEND.map(
180
188
  ([key, label]) => `<span class="legend-item"><i class="dot dot-${provKey(key)}"></i>${escapeHtml(label)}</span>`,
181
189
  ).join("");
@@ -421,6 +429,7 @@ ${THEME_TOKENS_CSS}
421
429
  const renderStatsPanelInto = ${renderStatsPanelInto.toString()};
422
430
  const createTicker = ${createTicker.toString()};
423
431
  const prefersReducedMotion = ${prefersReducedMotion.toString()};
432
+ const DIGEST_STRUCTURES = ${digestStructuresJson};
424
433
  const el = (id) => document.getElementById(id);
425
434
 
426
435
  if ("serviceWorker" in navigator) navigator.serviceWorker.register("./tmct-sw.js").catch(() => {});
@@ -655,6 +664,7 @@ ${THEME_TOKENS_CSS}
655
664
  liveReference: liveReferenceForMode(checkedWikiMode()),
656
665
  synthesisBudget: readSynthBudget(),
657
666
  onLiveLookup: function () { statusEl.textContent = "searching wikipedia\\u2026"; },
667
+ digestStructures: DIGEST_STRUCTURES,
658
668
  });
659
669
  }
660
670
 
@@ -1139,6 +1149,7 @@ ${THEME_TOKENS_CSS}
1139
1149
  liveReference: liveReferenceForMode(initialMode),
1140
1150
  synthesisBudget: readSynthBudget(),
1141
1151
  onLiveLookup: function () { statusEl.textContent = "searching wikipedia\\u2026"; },
1152
+ digestStructures: DIGEST_STRUCTURES,
1142
1153
  });
1143
1154
  } else {
1144
1155
  window.tmctChatSession = newSession();