@polycode-projects/the-mechanical-code-talker 1.5.4 → 1.8.3
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/README.md +123 -14
- package/ROADMAP.md +233 -1392
- package/bin/tmct.mjs +479 -98
- package/corpus/README.md +3 -0
- package/corpus/generated/README.md +43 -0
- package/corpus/generated/ace-surface-variants.jsonl +17 -0
- package/corpus/generated/manifest.json +9 -0
- package/corpus/tier2/generate.mjs +14668 -0
- package/corpus/tier2/human-examples-large.jsonl +1928 -0
- package/corpus/tier2/human-examples-medium.jsonl +356 -0
- package/corpus/tier2/human-examples.jsonl +120 -0
- package/corpus/tier2/human-large.jsonl +12001 -0
- package/corpus/tier2/human-medium.jsonl +944 -0
- package/corpus/tier2/human.jsonl +664 -0
- package/corpus/tier2/manifest.json +42 -0
- package/package.json +14 -8
- package/src/answer-variants.json +47 -0
- package/src/answer-variants.mjs +67 -0
- package/src/ask-browser-entry.mjs +34 -0
- package/src/ask-browser.bundle.js +5095 -0
- package/src/ask-vocab.mjs +93 -8
- package/src/ask.mjs +451 -49
- package/src/chat.mjs +1391 -141
- package/src/cli-args.mjs +164 -0
- package/src/codegraph.mjs +170 -32
- package/src/completions/graph-adapter.mjs +118 -0
- package/src/extensions.mjs +100 -19
- package/src/grammar/ace.mjs +85 -3
- package/src/grammar/lexicon-core.json +9531 -63
- package/src/grammar/lexicon.mjs +58 -8
- package/src/graph-merge.mjs +114 -0
- package/src/index.mjs +14 -0
- package/src/init.mjs +40 -14
- package/src/interpret/normalize.mjs +88 -3
- package/src/interpret/strategies/grammar.mjs +10 -0
- package/src/interpret/strategies/keywords.mjs +20 -0
- package/src/interpret/strategies/noise-strip.mjs +73 -4
- package/src/memory/core.mjs +466 -8
- package/src/router/goal-reasoner.mjs +41 -7
- package/src/router/guardrail.mjs +37 -7
- package/src/router/resolver.mjs +50 -4
- package/src/sessions.mjs +5 -1
- package/src/source.mjs +54 -1
- package/src/syllogise.mjs +398 -27
- package/src/toml-config.mjs +13 -4
- package/src/viz.mjs +541 -0
package/src/ask-vocab.mjs
CHANGED
|
@@ -324,17 +324,37 @@ const TRAILING_DISCOURSE_TAG_RE = new RegExp(
|
|
|
324
324
|
`\\s+(?:${TRAILING_DISCOURSE_TAG.join("|")})\\s*[?.!]*$`, "i",
|
|
325
325
|
);
|
|
326
326
|
|
|
327
|
-
/**
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
327
|
+
/** Trailing COMMA-delimited discourse clauses ("what is a class, please
|
|
328
|
+
* explain") — a distinct shape from TRAILING_DISCOURSE_TAG above (a bare
|
|
329
|
+
* space-led tag, no comma): an ESL follow-on clause tacked onto a
|
|
330
|
+
* meta-whatis term after a comma, meaning "please explain [it]", not part of
|
|
331
|
+
* the term itself (BENCHMARK_CONVERSATION_1.7.0.md routed backlog C1). Closed
|
|
332
|
+
* and curated exactly like TRAILING_DISCOURSE_TAG — anchored on a LITERAL
|
|
333
|
+
* comma immediately before the tag, so this can never fire mid-phrase and
|
|
334
|
+
* can never touch a term that merely contains a comma for some other reason
|
|
335
|
+
* (no real code identifier ends in ", please explain" or ", explain"). */
|
|
336
|
+
export const TRAILING_DISCOURSE_CLAUSE = Object.freeze(["please explain", "explain"]);
|
|
337
|
+
|
|
338
|
+
const TRAILING_DISCOURSE_CLAUSE_RE = new RegExp(
|
|
339
|
+
`,\\s*(?:${TRAILING_DISCOURSE_CLAUSE.join("|")})\\s*[?.!]*$`, "i",
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
/** Strip trailing bare discourse tags (TRAILING_DISCOURSE_TAG, above) AND
|
|
343
|
+
* trailing comma-delimited discourse clauses (TRAILING_DISCOURSE_CLAUSE,
|
|
344
|
+
* above) off the end of a captured meta-whatis term — "what is a component
|
|
345
|
+
* then" resolves the same term as "what is a component", and "what is a
|
|
346
|
+
* class, please explain" resolves the same term as "what is a class".
|
|
347
|
+
* Applied up to twice (a stacked "too then"/"then too" is the only worked
|
|
348
|
+
* case that ever needs a second pass; no phrasing seen so far stacks a
|
|
349
|
+
* third), mirroring stripTrailingScopeFiller's own single-clause discipline
|
|
350
|
+
* for the common single-tag case while still covering the rarer
|
|
351
|
+
* double-tag one. The comma-clause strip runs each pass too, so "class,
|
|
352
|
+
* please explain then" (an unworked but plausible stack) still resolves. */
|
|
334
353
|
export function stripTrailingDiscourseTag(text) {
|
|
335
354
|
let out = text;
|
|
336
355
|
for (let pass = 0; pass < 2; pass += 1) {
|
|
337
|
-
|
|
356
|
+
let next = out.replace(TRAILING_DISCOURSE_TAG_RE, "").trim();
|
|
357
|
+
next = next.replace(TRAILING_DISCOURSE_CLAUSE_RE, "").trim();
|
|
338
358
|
if (next === out) break;
|
|
339
359
|
out = next;
|
|
340
360
|
}
|
|
@@ -349,6 +369,48 @@ export const VERB_TO_KIND = Object.freeze(
|
|
|
349
369
|
),
|
|
350
370
|
);
|
|
351
371
|
|
|
372
|
+
/** "what is a kind of X" / "what is a subclass of X" collision fix (2026-07-11,
|
|
373
|
+
* live-repro: "boney is a dog" -> "what is a dog" -> "what is a kind of
|
|
374
|
+
* animal" hit a forced disambiguation wall instead of answering). grammar.mjs's
|
|
375
|
+
* T5 "meta-whatis" template reads "what is a/an <object>" as a literal
|
|
376
|
+
* glossary/term-definition question ("what is a Commit"). But some registered
|
|
377
|
+
* inherits verbs are THEMSELVES phrased "is a <continuation>" ("is a kind
|
|
378
|
+
* of", "is a subclass of" — RELATIONS.inherits.verbs above) — when the object
|
|
379
|
+
* T5 captures IS one of these continuations plus a real term ("kind of
|
|
380
|
+
* animal"), the sentence isn't asking to define the noun phrase "kind of
|
|
381
|
+
* animal"; it's the exact same question as "what inherits from animal", just
|
|
382
|
+
* phrased with the verb's own "is a" lead instead of "inherits". keyword-spot
|
|
383
|
+
* (keywords.mjs) already reads it that way, unambiguously — the meta reading
|
|
384
|
+
* is the spurious one, and it collides with keyword-spot's correct reading to
|
|
385
|
+
* manufacture a needless {ambiguousParse} tie (interpret/merge.mjs) over a
|
|
386
|
+
* phrasing the engine itself just used a turn earlier. Derived from
|
|
387
|
+
* VERB_TO_KIND (not hand-duplicated) so any future plain "is a/are a X of"
|
|
388
|
+
* verb phrase added to RELATIONS is covered automatically, without touching
|
|
389
|
+
* this file again.
|
|
390
|
+
*
|
|
391
|
+
* Deliberately EXCLUDES every INHERITS_REVERSE_VERBS entry ("is a superclass
|
|
392
|
+
* of", "is a parent class of") even though they match the same "is a
|
|
393
|
+
* <continuation>" shape: those verbs' subject/object are semantically
|
|
394
|
+
* SWAPPED relative to storage direction (see INHERITS_REVERSE_VERB_LIST's own
|
|
395
|
+
* comment above) — "what is a superclass of X" asks a FORWARD question
|
|
396
|
+
* (X's own supertype), not this reverse-by-object listing, and keyword-spot's
|
|
397
|
+
* decomposition only applies that swap in the two-sided "ask" shape (verb
|
|
398
|
+
* between a subject AND an object), not this "reverse"-only afterText-only
|
|
399
|
+
* shape. Suppressing the meta reading for these too would trade one honest
|
|
400
|
+
* {ambiguousParse} wall for a confusing WRONG answer (a reverse-by-object
|
|
401
|
+
* lookup with the direction backwards) — a separate, pre-existing gap in
|
|
402
|
+
* keywords.mjs, out of this fix's scope. */
|
|
403
|
+
const NON_REVERSE_VERB = (v) => !INHERITS_REVERSE_VERBS.includes(v);
|
|
404
|
+
export const ARTICLE_RELATION_CONTINUATIONS = Object.freeze([
|
|
405
|
+
...new Set(
|
|
406
|
+
Object.keys(VERB_TO_KIND)
|
|
407
|
+
.filter(NON_REVERSE_VERB)
|
|
408
|
+
.map((v) => v.match(/^(?:is|are)\s+an?\s+(.+)$/i))
|
|
409
|
+
.filter(Boolean)
|
|
410
|
+
.map((m) => m[1].toLowerCase()),
|
|
411
|
+
),
|
|
412
|
+
]);
|
|
413
|
+
|
|
352
414
|
export const ENTITY_TO_TYPE = Object.freeze({
|
|
353
415
|
function: "Function", functions: "Function",
|
|
354
416
|
method: "Method", methods: "Method",
|
|
@@ -470,6 +532,10 @@ export const MISSPELLINGS = Object.freeze({
|
|
|
470
532
|
"extands": "extends", "extneds": "extends",
|
|
471
533
|
"depnds": "depends",
|
|
472
534
|
"touchs": "touches", "tuoches": "touches", "touhced": "touched",
|
|
535
|
+
// "touchd" (BENCHMARK_CONVERSATION_1.7.0.md routed backlog C3): the
|
|
536
|
+
// dropped-vowel slip of "touched" — distinct from "touhced" above
|
|
537
|
+
// (transposed letters), same curated-typo discipline.
|
|
538
|
+
"touchd": "touched",
|
|
473
539
|
// WHERE_MARKERS typo (0.9.13 Tier-1 playtest): "defined" itself had no typo
|
|
474
540
|
// entry, so "where is it defned" fell through to the bare-object search path
|
|
475
541
|
// instead of the where-shape ("no module matching 'it defned' found").
|
|
@@ -498,6 +564,12 @@ export const MISSPELLINGS = Object.freeze({
|
|
|
498
564
|
// anchor; the correction regex's dotted-extension guard keeps a module
|
|
499
565
|
// literally named "wat.mjs" untouched, same residual trade as every entry.
|
|
500
566
|
"waht": "what", "wat": "what",
|
|
567
|
+
// "dat" (BENCHMARK_CONVERSATION_1.7.0.md routed backlog C3): the internet-
|
|
568
|
+
// casual spelling of "that" — same register as "wat"/"waht" just above,
|
|
569
|
+
// curated rather than left to the generic fuzzy tier since "that" is a
|
|
570
|
+
// load-bearing anchor word throughout this grammar (TEACH_RE's own
|
|
571
|
+
// "remember that X", relative-clause objects, etc).
|
|
572
|
+
"dat": "that",
|
|
501
573
|
"dose": "does", "doess": "does",
|
|
502
574
|
"teh": "the",
|
|
503
575
|
// aggregate/list TRIGGER words (2026-07-02, trigger-typo work) — a typo of a count
|
|
@@ -788,6 +860,7 @@ export const EDGE_NOUN_TO_METRIC = Object.freeze({
|
|
|
788
860
|
methods: { kind: "contains", dir: "out", filter: "Method" },
|
|
789
861
|
members: { kind: "contains", dir: "out" },
|
|
790
862
|
tests: { kind: "tests", dir: "in" },
|
|
863
|
+
test: { kind: "tests", dir: "in" }, // singular ("needs a test") — same edge as plural "tests"
|
|
791
864
|
subclasses: { kind: "inherits", dir: "in" },
|
|
792
865
|
connections: { kind: "*", dir: "both" },
|
|
793
866
|
edges: { kind: "*", dir: "both" },
|
|
@@ -805,6 +878,18 @@ export const EDGE_NOUN_TO_METRIC = Object.freeze({
|
|
|
805
878
|
called: { kind: "calls", dir: "in", sibling: "callsSymbol" },
|
|
806
879
|
});
|
|
807
880
|
|
|
881
|
+
/** Metric nouns whose edge kind targets exactly ONE entity class in this graph's
|
|
882
|
+
* ontology (only a Module is ever the object of a `tests` edge) — read by
|
|
883
|
+
* ask.mjs's parseSuperlative to default `entityType` when a superlative names a
|
|
884
|
+
* metric but no explicit entity noun ("what most needs a test", vs. the fully
|
|
885
|
+
* explicit "which MODULE has the most tests"). Deliberately small: a metric like
|
|
886
|
+
* "calls"/"connections" targets more than one class, so it is NOT listed here —
|
|
887
|
+
* those keep requiring an explicit entity noun, same as before this table existed. */
|
|
888
|
+
export const METRIC_IMPLIES_ENTITY = Object.freeze({
|
|
889
|
+
tests: "Module",
|
|
890
|
+
test: "Module",
|
|
891
|
+
});
|
|
892
|
+
|
|
808
893
|
/** Anaphora triggers over the PREVIOUS result set (ask()'s `prev` id array):
|
|
809
894
|
* "which of those/them/these …", "how many of those …". The pronoun refers to the
|
|
810
895
|
* last answer's ids, not a graph term — with no prev supplied it is an honest miss
|