@polycode-projects/the-mechanical-code-talker 1.0.7 → 1.0.9
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 +51 -32
- package/ROADMAP.md +226 -79
- package/package.json +1 -1
- package/src/ask-vocab.mjs +125 -1
- package/src/ask.mjs +510 -17
- package/src/chat.mjs +1010 -64
- package/src/codegraph.mjs +1 -1
- package/src/interpret/normalize.mjs +137 -3
- package/src/interpret/strategies/grammar.mjs +44 -11
- package/src/interpret/strategies/keywords.mjs +15 -1
- package/src/memory/core.mjs +15 -1
- package/src/syllogise.mjs +0 -0
package/src/ask-vocab.mjs
CHANGED
|
@@ -31,6 +31,54 @@
|
|
|
31
31
|
* `verbs: [...]` shape) since ask.mjs only needs phrase -> kind, never the
|
|
32
32
|
* register itself. A misparsed casual phrase costs nothing beyond an honest
|
|
33
33
|
* object-miss (resolveObject never guesses), so breadth here is genuinely low-risk. */
|
|
34
|
+
// REVERSE inherits phrasings (Seonix Batch 2 Fix 2) — "is X a superclass of Y" /
|
|
35
|
+
// "is X a parent class of Y" name the SAME `inherits` relation as the forward
|
|
36
|
+
// "is X a subclass of Y" verbs above, but with subject/object semantically
|
|
37
|
+
// SWAPPED: the questioner's X is the base, not the derived class. The "a"-forms
|
|
38
|
+
// (below) are folded into RELATIONS.inherits.verbs so VERB_TO_KIND maps them to
|
|
39
|
+
// kind "inherits" exactly like every forward verb — every existing
|
|
40
|
+
// inherits-consuming template/renderer keeps working unmodified — but ALSO kept
|
|
41
|
+
// as this separate exported list so the strategies that build "ask" shapes
|
|
42
|
+
// (subject-before/object-after by regex capture POSITION, not semantic
|
|
43
|
+
// direction — see grammar.mjs T1 and keywords.mjs's decomposition) can detect a
|
|
44
|
+
// reverse verb and swap subject/object at parse time, before evaluation ever
|
|
45
|
+
// sees it.
|
|
46
|
+
//
|
|
47
|
+
// Bare "superclass"/"superclasses" (single word, no "is … of" wrapper) are ALSO
|
|
48
|
+
// folded in: keyword-spot's decomposition (keywords.mjs) finds a verb phrase as
|
|
49
|
+
// a CONTIGUOUS run of words, and the interrogative word order ("is Base a
|
|
50
|
+
// superclass of Widget") puts the subject BETWEEN "is" and "a superclass of",
|
|
51
|
+
// breaking that contiguity for the 4-word phrase — exactly mirroring why the
|
|
52
|
+
// forward direction already carries bare "subclass"/"subclasses" alongside its
|
|
53
|
+
// own "is a subclass of" (both above, in RELATIONS.inherits.verbs): the bare
|
|
54
|
+
// stem is what actually lets keyword-spot's decomposition recognize the
|
|
55
|
+
// aux-first question form ("is Foo a subclass of Bar" only resolves today via
|
|
56
|
+
// that same bare "subclass" stem — see grammar.mjs T1's own comment).
|
|
57
|
+
//
|
|
58
|
+
// The "the"-DEFINITE forms ("is the superclass of", "are the superclass of",
|
|
59
|
+
// "is the parent class of") are named in INHERITS_REVERSE_VERBS below (the
|
|
60
|
+
// caller-requested literal set) but deliberately NOT folded into
|
|
61
|
+
// RELATIONS.inherits.verbs / VERB_TO_KIND: ask.mjs's CONTENT_VOCAB is built by
|
|
62
|
+
// splitting every VERB_TO_KIND key into its individual words (wordsOf), so a
|
|
63
|
+
// verb phrase containing the bare word "the" would leak "the" itself into
|
|
64
|
+
// CONTENT_VOCAB — and the progressive-relaxation cascade's NOISE-STRIP layer
|
|
65
|
+
// treats anything in CONTENT_VOCAB as un-strippable content, not noise. Verified
|
|
66
|
+
// live: folding the "the"-forms in broke test/ask-cascade.test.mjs's pinned
|
|
67
|
+
// NOISE-STRIP/DROP-UNMATCHED/SYNONYM-NORMALISE cases (each expects "the" to stay
|
|
68
|
+
// strippable) and test/chatflow-tier2.test.mjs's ESL-pronoun case, all of which
|
|
69
|
+
// rely on the pre-existing invariant that NO verb phrase in this file's tables
|
|
70
|
+
// ever contains the bare word "the" (confirmed true before this change). So the
|
|
71
|
+
// "the"-forms stay honest misses for now — "is a superclass of"/"are a
|
|
72
|
+
// superclass of" (the forms this Batch's own tests exercise) work; reinstating
|
|
73
|
+
// the "the"-forms would need a CONTENT_VOCAB fix first, out of this fix's scope.
|
|
74
|
+
const INHERITS_REVERSE_VERB_LIST = [
|
|
75
|
+
"is a superclass of",
|
|
76
|
+
"are a superclass of",
|
|
77
|
+
"is a parent class of",
|
|
78
|
+
"are a parent class of",
|
|
79
|
+
"superclass", "superclasses",
|
|
80
|
+
];
|
|
81
|
+
|
|
34
82
|
export const RELATIONS = {
|
|
35
83
|
imports: {
|
|
36
84
|
comment: "Module -> Module: subject's import graph references object (usesComplexType).",
|
|
@@ -105,7 +153,18 @@ export const RELATIONS = {
|
|
|
105
153
|
inherits: {
|
|
106
154
|
comment: "Class -> Class: subject's declared base resolves to object (subclassOf).",
|
|
107
155
|
verbs: [
|
|
108
|
-
"inherits from", "inherit from",
|
|
156
|
+
"inherits from", "inherit from",
|
|
157
|
+
// bare "inherits"/"inherit" (Tier 6 playtest, §3b surface-variation axis):
|
|
158
|
+
// this list's own SIBLING verb "extends"/"extend" already works bare, with
|
|
159
|
+
// no "from" required, but "inherits"/"inherit" — arguably the MORE common
|
|
160
|
+
// everyday phrasing of the two ("TaskController inherits Controller",
|
|
161
|
+
// "does TaskController inherit Controller") — had no bare form at all,
|
|
162
|
+
// only the "... from" variant. VERB_ALT's longest-first sort (already
|
|
163
|
+
// relied on elsewhere in this file for the same reason) means "inherits
|
|
164
|
+
// from"/"inherit from" still win whenever "from" actually follows, so
|
|
165
|
+
// this is purely additive.
|
|
166
|
+
"inherits", "inherit",
|
|
167
|
+
"extends", "extend", "subclasses", "subclass",
|
|
109
168
|
"derives from", "derive from", "is a subclass of", "are a subclass of",
|
|
110
169
|
"is a kind of", "are a kind of", "is built off", "are built off",
|
|
111
170
|
"is built on top of", "are built on top of",
|
|
@@ -116,6 +175,12 @@ export const RELATIONS = {
|
|
|
116
175
|
// the gerund-lead check reads) are listed; longest-match-first prefers the
|
|
117
176
|
// two-word form when "from" follows.
|
|
118
177
|
"extending", "inheriting from", "inheriting", "subclassing", "extends from",
|
|
178
|
+
// REVERSE phrasings (Seonix Batch 2 Fix 2, see INHERITS_REVERSE_VERB_LIST's own
|
|
179
|
+
// comment above): "is/are a|the superclass/parent class of" — folded in here so
|
|
180
|
+
// VERB_TO_KIND maps them to "inherits" like every other verb in this list; the
|
|
181
|
+
// subject/object SWAP their direction requires is handled at parse time by the
|
|
182
|
+
// strategies that build the "ask" shape, not here.
|
|
183
|
+
...INHERITS_REVERSE_VERB_LIST,
|
|
119
184
|
],
|
|
120
185
|
},
|
|
121
186
|
touches: {
|
|
@@ -163,6 +228,13 @@ export const RELATIONS = {
|
|
|
163
228
|
// Commit->Module kind, structurally unable to match a Module subject), always
|
|
164
229
|
// producing a confidently-empty answer regardless of real cochange data.
|
|
165
230
|
"changed together with", "change together with", "changes together with",
|
|
231
|
+
// Present-tense bare form (Seonix Batch 4/5 follow-up): only the past tense
|
|
232
|
+
// "changed with" existed above — "what changes with X"/"what usually changes
|
|
233
|
+
// with X" fell through entirely (ENTITY_TO_TYPE's own "changes"->"Change"
|
|
234
|
+
// pseudo-type noun risked consuming the word first; see parseRelationalOrQualified's
|
|
235
|
+
// guard against exactly that in ask.mjs).
|
|
236
|
+
"changes with", "change with", "tends to change with", "tend to change with",
|
|
237
|
+
"usually changes with",
|
|
166
238
|
],
|
|
167
239
|
},
|
|
168
240
|
reexports: {
|
|
@@ -180,6 +252,22 @@ export const RELATIONS = {
|
|
|
180
252
|
},
|
|
181
253
|
};
|
|
182
254
|
|
|
255
|
+
/** The closed set of reverse `inherits` verb phrasings a strategy that has already
|
|
256
|
+
* matched a verb phrase can check ("was this one of the reverse ones?") to decide
|
|
257
|
+
* whether to swap subject/object before returning its parsed shape (see the
|
|
258
|
+
* comment above INHERITS_REVERSE_VERB_LIST, right before RELATIONS, for the full
|
|
259
|
+
* story). Every phrase here EXCEPT the three "the"-definite forms is ALSO folded
|
|
260
|
+
* into RELATIONS.inherits.verbs (so VERB_TO_KIND routes it to kind "inherits"
|
|
261
|
+
* like any other inherits verb) — the "the"-forms are named here for
|
|
262
|
+
* completeness (matching the originally-specified closed set) but are not yet
|
|
263
|
+
* reachable through VERB_TO_KIND, so a strategy will never actually see one as
|
|
264
|
+
* a matched verb; keeping them in this list is harmless and future-proofs the
|
|
265
|
+
* swap check for whenever the CONTENT_VOCAB constraint is lifted. */
|
|
266
|
+
export const INHERITS_REVERSE_VERBS = Object.freeze([
|
|
267
|
+
...INHERITS_REVERSE_VERB_LIST,
|
|
268
|
+
"is the superclass of", "are the superclass of", "is the parent class of",
|
|
269
|
+
]);
|
|
270
|
+
|
|
183
271
|
// ---- where/when/mentions markers (2026-07-02 query families) — the location and
|
|
184
272
|
// prose-mention questions carry NO relation verb ("where is X defined", "where is
|
|
185
273
|
// X mentioned"), so ask.mjs routes them by these marker words instead of
|
|
@@ -191,6 +279,34 @@ export const WHERE_MARKERS = Object.freeze(["defined", "declared", "located", "i
|
|
|
191
279
|
/** Prose-mention markers: "where is X <marker>" -> the prose/mentions surface. */
|
|
192
280
|
export const MENTION_MARKERS = Object.freeze(["mentioned", "referenced"]);
|
|
193
281
|
|
|
282
|
+
// ---- trailing scope filler (Seonix Batch 2 Fix 3) — a "what is a <noun phrase>"
|
|
283
|
+
// question sometimes tacks on a trailing clause that scopes the question back onto
|
|
284
|
+
// the graph/codebase ITSELF, not onto any additional term: "what is a Module in
|
|
285
|
+
// this graph" means exactly "what is a Module", not a literal lookup of the glued
|
|
286
|
+
// phrase "Module in this graph". Closed and curated like every other table here —
|
|
287
|
+
// an unlisted trailing clause is left alone (an honest literal lookup), never
|
|
288
|
+
// silently swallowed by a general heuristic. ----
|
|
289
|
+
|
|
290
|
+
/** Trailing filler clauses stripped from the END of a captured meta-whatis object,
|
|
291
|
+
* case-insensitive, before the term is used as a lookup key. */
|
|
292
|
+
export const TRAILING_SCOPE_FILLER = Object.freeze([
|
|
293
|
+
"in this graph", "in the graph", "in this codebase", "in the codebase",
|
|
294
|
+
"in this repo", "in the repo", "here",
|
|
295
|
+
]);
|
|
296
|
+
|
|
297
|
+
const TRAILING_SCOPE_FILLER_RE = new RegExp(
|
|
298
|
+
`\\s+(?:${TRAILING_SCOPE_FILLER.join("|")})\\s*[?.!]*$`, "i",
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
/** Strip ONE trailing scope-filler clause (TRAILING_SCOPE_FILLER, above) off the end
|
|
302
|
+
* of a captured meta-whatis object — "what is a Module in this graph" resolves the
|
|
303
|
+
* same term as "what is a Module". Applied once, not in a loop: no worked phrasing
|
|
304
|
+
* stacks two filler clauses. Every TRAILING_SCOPE_FILLER entry is plain words (no
|
|
305
|
+
* regex metacharacters), so no escaping is needed building the alternation. */
|
|
306
|
+
export function stripTrailingScopeFiller(text) {
|
|
307
|
+
return text.replace(TRAILING_SCOPE_FILLER_RE, "").trim();
|
|
308
|
+
}
|
|
309
|
+
|
|
194
310
|
/** relation token -> flat verb-phrase list, the shape ask.mjs's VERB_TO_KIND
|
|
195
311
|
* table needs (phrase -> kind), derived once from RELATIONS. */
|
|
196
312
|
export const VERB_TO_KIND = Object.freeze(
|
|
@@ -352,6 +468,14 @@ export const MISSPELLINGS = Object.freeze({
|
|
|
352
468
|
// curated here so the intended trigger is restored BEFORE parsing (the general
|
|
353
469
|
// bounded fuzzy path in ask.mjs's cascade is the backstop for uncurated typos).
|
|
354
470
|
"manyn": "many", "mnay": "many", "amny": "many", "mnany": "many",
|
|
471
|
+
// "hwo" (Tier 6 playtest, §3b typo axis): a transposed-letter typo of "how" —
|
|
472
|
+
// "hwo many classes are there" used to lose the aggregate/list trigger
|
|
473
|
+
// outright ("how many" only reads as a count trigger when both words are
|
|
474
|
+
// exact), same failure class as "manyn"/"mnay" just above, one word to the
|
|
475
|
+
// left of it. "how" is grammar-owned via AGGREGATE_TRIGGERS' own "how many"/
|
|
476
|
+
// "how much" entries (test/ask-vocab.test.mjs's canonical-value check
|
|
477
|
+
// splits those multi-word triggers into individual words).
|
|
478
|
+
"hwo": "how",
|
|
355
479
|
"coutn": "count", "conut": "count", "cuont": "count", "ocunt": "count",
|
|
356
480
|
"numer": "number", "nubmer": "number", "numbr": "number", "nmuber": "number",
|
|
357
481
|
"lst": "list", "lsit": "list", "ilst": "list",
|