@polycode-projects/the-mechanical-code-talker 2.11.1 → 2.11.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polycode-projects/the-mechanical-code-talker",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The Mechanical Code Talker (tmct) — a tolerant, offline, $0 chat surface that guides you toward precision queries about a software repository. ELIZA/PARRY-style but domain-obsessed with code. No model calls; no codebase index of its own.",
|
package/src/services/chat.mjs
CHANGED
|
@@ -3163,6 +3163,14 @@ async function unknownAdjectiveFallback(payload, { memoryDir, sessionId, lexicon
|
|
|
3163
3163
|
if (!m) return null;
|
|
3164
3164
|
const [, det, subjectRaw, verb, objectRaw] = m;
|
|
3165
3165
|
if (PLACE_ADVERB_OBJECT_RE.test(objectRaw)) return null; // a place adverb is never a property
|
|
3166
|
+
// An ARTICLED complement ("a dog is a mammal") is a noun-phrase kind claim,
|
|
3167
|
+
// never an adjective property — but UNKNOWN_SUBJECT_RE strips the object's
|
|
3168
|
+
// article before capture, so objectRaw alone can't show the difference from
|
|
3169
|
+
// "the cache is bespoke". Without this re-check, a fact-grounded subject
|
|
3170
|
+
// silently minted the kind claim as an mgx:hasProperty garble that the isa
|
|
3171
|
+
// read-back then denied. Declining here lands on the honest teach-miss,
|
|
3172
|
+
// whose nudge already names the storable form ("every dog is a mammal").
|
|
3173
|
+
if (/\s+(?:is|are)\s+an?\s+[\w-]+[.!?]*\s*$/i.test(String(payload).trim())) return null;
|
|
3166
3174
|
const { loadLexicon, lookupNoun, lookupAdjective, classify } = await import("../domain/grammar/lexicon.mjs");
|
|
3167
3175
|
const lex = lexicon || loadLexicon();
|
|
3168
3176
|
// Y already a known NOUN or a fact-grounded CLASS term — a genuine class-
|
|
@@ -6826,7 +6834,7 @@ const FACT_ANSWER_CAP = 32;
|
|
|
6826
6834
|
* RELATION_WHO_ASK_RE's required leading "is/are/was/were" (those two live in
|
|
6827
6835
|
* the separate factReadBack, only ever reached via `factAnswer(...) ??
|
|
6828
6836
|
* factReadBack(...)` — never both). */
|
|
6829
|
-
const CAN_ASK_RE = /^(?:can|could)\s+(?:an?\s+)?([\w'-]+(?:\s+[\w'-]+)*?)\s+([a-z]+)[?.!\s]*$/i;
|
|
6837
|
+
const CAN_ASK_RE = /^(?:can|could)\s+(all\s+|every\s+)?(?:an?\s+)?([\w'-]+(?:\s+[\w'-]+)*?)\s+([a-z]+)[?.!\s]*$/i;
|
|
6830
6838
|
const DOES_HAVE_ASK_RE = /^(?:does|do)\s+(?:an?\s+|the\s+)?(.+?)\s+have\s+(?:an?\s+|the\s+)?(.+?)[?.!\s]*$/i;
|
|
6831
6839
|
const WHAT_CAN_DO_RE = /^what\s+can\s+(?:an?\s+)?(.+?)\s+do[?.!\s]*$/i;
|
|
6832
6840
|
const WHAT_HAS_RE = /^what\s+has\s+(?:an?\s+)?(.+?)[?.!\s]*$/i;
|
|
@@ -7584,14 +7592,24 @@ async function factAnswerReaders(memoryDir, query, envelope, miss, biasByBundle
|
|
|
7584
7592
|
const can = positiveQuestionSurface(q).match(CAN_ASK_RE);
|
|
7585
7593
|
if (can) {
|
|
7586
7594
|
const facts = await factRows(memoryDir, cache);
|
|
7587
|
-
const
|
|
7595
|
+
const canUniversal = can[1];
|
|
7596
|
+
const reply = capabilityReply(can[2], can[3], facts);
|
|
7597
|
+
// Quantified ("can all/every X ..."): the stored facts are generic, and a
|
|
7598
|
+
// bare "yes" would claim universality the memory can't support — the same
|
|
7599
|
+
// hedge the do-support surface applies, echoing the quantifier as typed.
|
|
7600
|
+
if (reply && canUniversal) {
|
|
7601
|
+
return {
|
|
7602
|
+
text: `I can't speak for ${canUniversal.trim()} ${can[2]} — what I remember is generic, not universal. ${reply.text}.`,
|
|
7603
|
+
replace: true,
|
|
7604
|
+
};
|
|
7605
|
+
}
|
|
7588
7606
|
if (reply) return reply;
|
|
7589
7607
|
// A KNOWN subject with capability facts, none matching: an honest,
|
|
7590
7608
|
// specific miss citing what it CAN do — the same closer the is-a ladder
|
|
7591
7609
|
// answers with, instead of the misleading structural parse wall. An
|
|
7592
7610
|
// unknown subject still declines. Never a guessed "no": absence of a
|
|
7593
7611
|
// capableOf fact proves nothing.
|
|
7594
|
-
const subj = factTermVariants(normFactTerm, can[
|
|
7612
|
+
const subj = factTermVariants(normFactTerm, can[2]);
|
|
7595
7613
|
const knownCan = facts.filter((f) => f.predicate === "mgx:capableOf" && subj.has(f.subject));
|
|
7596
7614
|
if (knownCan.length) {
|
|
7597
7615
|
const shown = knownCan.slice(0, 3).map(renderFactLine).join("; ");
|
|
@@ -7599,14 +7617,14 @@ async function factAnswerReaders(memoryDir, query, envelope, miss, biasByBundle
|
|
|
7599
7617
|
// not as the user typed it — 'teach me: "a birds can swim"' is a
|
|
7600
7618
|
// garbled hint that can't round-trip.
|
|
7601
7619
|
return {
|
|
7602
|
-
text: `I can't confirm that — nothing I remember says ${can[
|
|
7620
|
+
text: `I can't confirm that — nothing I remember says ${can[2]} can ${can[3]}. I do know: ${shown}. If it's true, teach me: "a ${knownCan[0].subject} can ${can[3]}".`,
|
|
7603
7621
|
replace: true,
|
|
7604
7622
|
miss: true,
|
|
7605
7623
|
};
|
|
7606
7624
|
}
|
|
7607
7625
|
// nothing about the subject at all — report the class base rate, and answer
|
|
7608
7626
|
// neither yes nor no
|
|
7609
|
-
return capabilityBaseRateReply(can[
|
|
7627
|
+
return capabilityBaseRateReply(can[2], can[3], facts);
|
|
7610
7628
|
}
|
|
7611
7629
|
|
|
7612
7630
|
// (b2b) "does a dog have a tail" — yes iff a remembered possession fact
|
|
@@ -7685,8 +7703,10 @@ async function factAnswerReaders(memoryDir, query, envelope, miss, biasByBundle
|
|
|
7685
7703
|
// penguin fly" can never disagree in one session
|
|
7686
7704
|
const reply = capabilityReply(doAsk[2], doAsk[3], facts);
|
|
7687
7705
|
if (reply && universal) {
|
|
7706
|
+
// Echo the quantifier as typed ("every dog", "all dogs") — "all dog"
|
|
7707
|
+
// for a singular every-question is a garbled echo.
|
|
7688
7708
|
return {
|
|
7689
|
-
text: `I can't speak for
|
|
7709
|
+
text: `I can't speak for ${doAsk[1].trim()} ${doAsk[2]} — what I remember is generic, not universal. ${reply.text}.`,
|
|
7690
7710
|
replace: true,
|
|
7691
7711
|
};
|
|
7692
7712
|
}
|