@polycode-projects/the-mechanical-code-talker 1.11.0 → 1.11.5
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 +13 -20
- package/ROADMAP.md +9 -12
- package/bin/tmct.mjs +82 -98
- package/data/games/river.txt +33 -0
- package/package.json +1 -1
- package/src/ask.mjs +119 -6
- package/src/chat.mjs +962 -51
- package/src/codegraph.mjs +24 -11
- package/src/domain.mjs +85 -6
- package/src/interpret/normalize.mjs +46 -0
- package/src/interpret/strategies/keywords.mjs +13 -9
- package/src/ledger-viz.mjs +31 -9
- package/src/memory/core.mjs +20 -1
- package/src/memory/shacl.mjs +4 -1
- package/src/memory-ask-browser-entry.mjs +5 -5
- package/src/memory-ask-browser.bundle.js +526 -47
- package/src/plan-viz.mjs +5 -6
- package/src/router/drive.mjs +122 -13
- package/src/router/resolver.mjs +13 -0
- package/src/router/taught.mjs +19 -8
- package/src/syllogise.mjs +154 -38
- package/src/viz-theme.mjs +19 -3
- package/src/ask-browser-entry.mjs +0 -19
- package/src/ask-browser.bundle.js +0 -5142
- package/src/viz.mjs +0 -959
|
@@ -507,7 +507,8 @@
|
|
|
507
507
|
"recursive",
|
|
508
508
|
"action-signature",
|
|
509
509
|
"action-precond",
|
|
510
|
-
"action-effect"
|
|
510
|
+
"action-effect",
|
|
511
|
+
"action-constraint"
|
|
511
512
|
]);
|
|
512
513
|
RULE_SLOT_PROPS = {
|
|
513
514
|
compose2: ["mgx:ruleBase1", "mgx:ruleBase2"],
|
|
@@ -524,6 +525,11 @@
|
|
|
524
525
|
"mgx:ruleActionEffectPredicate",
|
|
525
526
|
"mgx:ruleActionEffectSubject",
|
|
526
527
|
"mgx:ruleActionEffectObject"
|
|
528
|
+
],
|
|
529
|
+
"action-constraint": [
|
|
530
|
+
"mgx:ruleActionConstraintLeft",
|
|
531
|
+
"mgx:ruleActionConstraintRight",
|
|
532
|
+
"mgx:ruleActionConstraintGuard"
|
|
527
533
|
]
|
|
528
534
|
};
|
|
529
535
|
nonEmpty = (v) => typeof v === "string" && v.trim().length > 0;
|
|
@@ -688,19 +694,23 @@
|
|
|
688
694
|
var core_exports = {};
|
|
689
695
|
__export(core_exports, {
|
|
690
696
|
CANONICALISED_FROM_PROP: () => CANONICALISED_FROM_PROP,
|
|
697
|
+
CAPABLE_OF_PREDICATE: () => CAPABLE_OF_PREDICATE,
|
|
691
698
|
CONTRADICTION_TRUST_FLOOR: () => CONTRADICTION_TRUST_FLOOR,
|
|
692
699
|
CREATED_AT_PROP: () => CREATED_AT_PROP,
|
|
693
700
|
DEFAULT_RETENTION: () => DEFAULT_RETENTION,
|
|
694
701
|
DERIVED_FROM_PROP: () => DERIVED_FROM_PROP,
|
|
695
702
|
FACT_CLASS: () => FACT_CLASS,
|
|
703
|
+
HAS_A_PREDICATE: () => HAS_A_PREDICATE,
|
|
696
704
|
IN_REPLY_TO_PROP: () => IN_REPLY_TO_PROP,
|
|
697
705
|
MEMORY_DIR_REL: () => MEMORY_DIR_REL,
|
|
698
706
|
MEMORY_GRAPH_REL: () => MEMORY_GRAPH_REL,
|
|
699
707
|
MEMORY_MANIFEST_REL: () => MEMORY_MANIFEST_REL,
|
|
700
708
|
MEMORY_SESSION_CLASS: () => MEMORY_SESSION_CLASS,
|
|
709
|
+
MULTI_VALUED_PREDICATES: () => MULTI_VALUED_PREDICATES,
|
|
701
710
|
OPERATOR_SOURCE_ID: () => OPERATOR_SOURCE_ID,
|
|
702
711
|
RULE_CLASS: () => RULE_CLASS,
|
|
703
712
|
RULE_KINDS: () => RULE_KINDS2,
|
|
713
|
+
RULE_KIND_ACTION_CONSTRAINT: () => RULE_KIND_ACTION_CONSTRAINT,
|
|
704
714
|
RULE_KIND_ACTION_EFFECT: () => RULE_KIND_ACTION_EFFECT,
|
|
705
715
|
RULE_KIND_ACTION_PRECOND: () => RULE_KIND_ACTION_PRECOND,
|
|
706
716
|
RULE_KIND_ACTION_SIGNATURE: () => RULE_KIND_ACTION_SIGNATURE,
|
|
@@ -1765,6 +1775,7 @@
|
|
|
1765
1775
|
const rows = readFactRows(memory).filter((r) => r.trust >= floor);
|
|
1766
1776
|
const byKey = /* @__PURE__ */ new Map();
|
|
1767
1777
|
for (const r of rows) {
|
|
1778
|
+
if (MULTI_VALUED_PREDICATES.has(r.predicate)) continue;
|
|
1768
1779
|
const key = `${r.subject} ${r.predicate}`;
|
|
1769
1780
|
if (!byKey.has(key)) byKey.set(key, []);
|
|
1770
1781
|
byKey.get(key).push(r);
|
|
@@ -1777,7 +1788,7 @@
|
|
|
1777
1788
|
}
|
|
1778
1789
|
return out.sort((a, b) => `${a[0].subject} ${a[0].predicate}`.localeCompare(`${b[0].subject} ${b[0].predicate}`));
|
|
1779
1790
|
}
|
|
1780
|
-
var MEMORY_DIR_REL, MEMORY_GRAPH_REL, UTTERANCE_CLASS, FACT_CLASS, MEMORY_SESSION_CLASS, SOURCE_CLASS, RULE_CLASS, SAID_IN_SESSION_PROP, IN_REPLY_TO_PROP, DERIVED_FROM_PROP, STATED_BY_PROP, CANONICALISED_FROM_PROP, CREATED_AT_PROP, UPDATED_AT_PROP, SOURCE_RELIABILITY_PROP, OPERATOR_SOURCE_ID, TEACH_SOURCE_ID, ROLES, LABEL_CAP, TEXT_CAP, MEMORY_VOCABULARY, memoryGraphFile, BACKEND_MEMORY, BACKEND_SQLITE, SQLITE_DDL, STD_EDGE_KEYS, cloneJson, MEMORY_MANIFEST_REL, DEFAULT_RETENTION, resolveManifestFile, MEMORY_INDEX, memoryIndexOf, normText, labelOf, nowIso, sourceLabel, isSessionScopedSourceId, factIdFor, RULE_KIND_COMPOSE2, RULE_KIND_FILTER, RULE_KIND_RECURSIVE, RULE_KIND_ACTION_SIGNATURE, RULE_KIND_ACTION_PRECOND, RULE_KIND_ACTION_EFFECT, RULE_KINDS2, RULE_NAME_PROP, RULE_KIND_PROP, RULE_SLOT_SPEC, ruleIdFor, CONTRADICTION_TRUST_FLOOR;
|
|
1791
|
+
var MEMORY_DIR_REL, MEMORY_GRAPH_REL, UTTERANCE_CLASS, FACT_CLASS, MEMORY_SESSION_CLASS, SOURCE_CLASS, RULE_CLASS, SAID_IN_SESSION_PROP, IN_REPLY_TO_PROP, DERIVED_FROM_PROP, STATED_BY_PROP, CANONICALISED_FROM_PROP, CREATED_AT_PROP, UPDATED_AT_PROP, SOURCE_RELIABILITY_PROP, OPERATOR_SOURCE_ID, TEACH_SOURCE_ID, ROLES, LABEL_CAP, TEXT_CAP, MEMORY_VOCABULARY, memoryGraphFile, BACKEND_MEMORY, BACKEND_SQLITE, SQLITE_DDL, STD_EDGE_KEYS, cloneJson, MEMORY_MANIFEST_REL, DEFAULT_RETENTION, resolveManifestFile, MEMORY_INDEX, memoryIndexOf, normText, labelOf, nowIso, sourceLabel, isSessionScopedSourceId, factIdFor, RULE_KIND_COMPOSE2, RULE_KIND_FILTER, RULE_KIND_RECURSIVE, RULE_KIND_ACTION_SIGNATURE, RULE_KIND_ACTION_PRECOND, RULE_KIND_ACTION_EFFECT, RULE_KIND_ACTION_CONSTRAINT, RULE_KINDS2, RULE_NAME_PROP, RULE_KIND_PROP, RULE_SLOT_SPEC, ruleIdFor, CONTRADICTION_TRUST_FLOOR, HAS_A_PREDICATE, CAPABLE_OF_PREDICATE, MULTI_VALUED_PREDICATES;
|
|
1781
1792
|
var init_core = __esm({
|
|
1782
1793
|
"src/memory/core.mjs"() {
|
|
1783
1794
|
init_promises();
|
|
@@ -1870,13 +1881,15 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
1870
1881
|
RULE_KIND_ACTION_SIGNATURE = "action-signature";
|
|
1871
1882
|
RULE_KIND_ACTION_PRECOND = "action-precond";
|
|
1872
1883
|
RULE_KIND_ACTION_EFFECT = "action-effect";
|
|
1884
|
+
RULE_KIND_ACTION_CONSTRAINT = "action-constraint";
|
|
1873
1885
|
RULE_KINDS2 = Object.freeze([
|
|
1874
1886
|
RULE_KIND_COMPOSE2,
|
|
1875
1887
|
RULE_KIND_FILTER,
|
|
1876
1888
|
RULE_KIND_RECURSIVE,
|
|
1877
1889
|
RULE_KIND_ACTION_SIGNATURE,
|
|
1878
1890
|
RULE_KIND_ACTION_PRECOND,
|
|
1879
|
-
RULE_KIND_ACTION_EFFECT
|
|
1891
|
+
RULE_KIND_ACTION_EFFECT,
|
|
1892
|
+
RULE_KIND_ACTION_CONSTRAINT
|
|
1880
1893
|
]);
|
|
1881
1894
|
RULE_NAME_PROP = "mgx:ruleName";
|
|
1882
1895
|
RULE_KIND_PROP = "mgx:ruleKind";
|
|
@@ -1898,10 +1911,20 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
1898
1911
|
["predicate", "mgx:ruleActionEffectPredicate"],
|
|
1899
1912
|
["subjectRole", "mgx:ruleActionEffectSubject"],
|
|
1900
1913
|
["objectRole", "mgx:ruleActionEffectObject"]
|
|
1914
|
+
],
|
|
1915
|
+
// "the <left> may not be with the <right> without the <guard>" — each slot
|
|
1916
|
+
// names a class whose sole member src/domain.mjs resolves at compile time.
|
|
1917
|
+
[RULE_KIND_ACTION_CONSTRAINT]: [
|
|
1918
|
+
["left", "mgx:ruleActionConstraintLeft"],
|
|
1919
|
+
["right", "mgx:ruleActionConstraintRight"],
|
|
1920
|
+
["guard", "mgx:ruleActionConstraintGuard"]
|
|
1901
1921
|
]
|
|
1902
1922
|
};
|
|
1903
1923
|
ruleIdFor = (kind, name, slotValues) => `rule:${fnv1aHex([kind, name, ...slotValues].join("\0"))}`;
|
|
1904
1924
|
CONTRADICTION_TRUST_FLOOR = 0.5;
|
|
1925
|
+
HAS_A_PREDICATE = "mgx:hasA";
|
|
1926
|
+
CAPABLE_OF_PREDICATE = "mgx:capableOf";
|
|
1927
|
+
MULTI_VALUED_PREDICATES = /* @__PURE__ */ new Set([HAS_A_PREDICATE, CAPABLE_OF_PREDICATE]);
|
|
1905
1928
|
}
|
|
1906
1929
|
});
|
|
1907
1930
|
|
|
@@ -2835,6 +2858,14 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
2835
2858
|
if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
|
|
2836
2859
|
m = q.match(TELL_ME_WRAPPER_RE);
|
|
2837
2860
|
if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
|
|
2861
|
+
m = q.match(KNOW_WRAPPER_RE);
|
|
2862
|
+
if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
|
|
2863
|
+
m = q.match(WANT_KNOW_WRAPPER_RE);
|
|
2864
|
+
if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
|
|
2865
|
+
m = q.match(EMBEDDED_WHATIS_RE);
|
|
2866
|
+
if (m) q = `what ${m[2].toLowerCase()} ${m[1].trim()}`;
|
|
2867
|
+
m = q.match(EMBEDDED_MEANS_RE);
|
|
2868
|
+
if (m) q = `what does ${m[1].trim()} mean`;
|
|
2838
2869
|
m = q.match(SHOW_GIVE_ME_RE);
|
|
2839
2870
|
if (m) {
|
|
2840
2871
|
const rest = m[1].trim();
|
|
@@ -2923,7 +2954,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
2923
2954
|
if (!predicate) return null;
|
|
2924
2955
|
return { entWord, predicate };
|
|
2925
2956
|
}
|
|
2926
|
-
var tableRe, CONTRACTION_RE, correctionRe, MISSPELLING_RE, WRONG_WORD_RE, W_SLASH_RE, FOR_DIGIT_THANKS_RE, FOR_DIGIT_EXAMPLE_RE, KIND_NOUN_ANAPHORA_RE, VERB_ALTERNATION, FILLER_RE, RELATION_VERB_RE, INTERROGATIVE_LEAD_RE, LISTING_TAIL_KINDS, BARE_KIND_RE, isListingRemainder, GREETING_PREAMBLE_RE, THANKS_PREAMBLE_RE, ACK_PREAMBLE_RE, BROWSING_PREAMBLE_RE, HEDGE_ADVERB_PREAMBLE_RE, TROUBLE_ASIDE_RE, MODAL_WRAPPER_RE, EXPLAIN_WRAPPER_RE, TELL_ME_WRAPPER_RE, SHOW_GIVE_ME_RE, LEADING_CONNECTIVE_RE, QUESTION_AUX_LEAD_RE, TOPIC_SWITCH_PREAMBLE_RE, SUBORDINATION_FRAMES_RE, SELF_CORRECTION_RE, CONDITIONAL_VERB_GERUND, CONDITIONAL_KIND_PLURAL, CONDITIONAL_QUALIFIER_SRC, CONDITIONAL_QUALIFIER_RE, COUNTERFACTUAL_RE, PHRASING_FRAMES, NEGATION_SET_RE, STOPWORDS2, splitWords, wordsOf;
|
|
2957
|
+
var tableRe, CONTRACTION_RE, correctionRe, MISSPELLING_RE, WRONG_WORD_RE, W_SLASH_RE, FOR_DIGIT_THANKS_RE, FOR_DIGIT_EXAMPLE_RE, KIND_NOUN_ANAPHORA_RE, VERB_ALTERNATION, FILLER_RE, RELATION_VERB_RE, INTERROGATIVE_LEAD_RE, LISTING_TAIL_KINDS, BARE_KIND_RE, isListingRemainder, GREETING_PREAMBLE_RE, THANKS_PREAMBLE_RE, ACK_PREAMBLE_RE, BROWSING_PREAMBLE_RE, HEDGE_ADVERB_PREAMBLE_RE, TROUBLE_ASIDE_RE, MODAL_WRAPPER_RE, EXPLAIN_WRAPPER_RE, TELL_ME_WRAPPER_RE, KNOW_WRAPPER_RE, WANT_KNOW_WRAPPER_RE, EMBEDDED_WHATIS_RE, EMBEDDED_MEANS_RE, SHOW_GIVE_ME_RE, LEADING_CONNECTIVE_RE, QUESTION_AUX_LEAD_RE, TOPIC_SWITCH_PREAMBLE_RE, SUBORDINATION_FRAMES_RE, SELF_CORRECTION_RE, CONDITIONAL_VERB_GERUND, CONDITIONAL_KIND_PLURAL, CONDITIONAL_QUALIFIER_SRC, CONDITIONAL_QUALIFIER_RE, COUNTERFACTUAL_RE, PHRASING_FRAMES, NEGATION_SET_RE, STOPWORDS2, splitWords, wordsOf;
|
|
2927
2958
|
var init_normalize = __esm({
|
|
2928
2959
|
"src/interpret/normalize.mjs"() {
|
|
2929
2960
|
init_ask_vocab();
|
|
@@ -2983,6 +3014,10 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
2983
3014
|
MODAL_WRAPPER_RE = /^(?:can|could|would|will)\s+you\s+(?:please\s+)?(.+?)(?:[,\s]+please)?\??$/i;
|
|
2984
3015
|
EXPLAIN_WRAPPER_RE = /^explain\s+(?:to\s+me\s+|please\s+)*(.+?)\??$/i;
|
|
2985
3016
|
TELL_ME_WRAPPER_RE = /^tell\s+me\s+(.+?)\??$/i;
|
|
3017
|
+
KNOW_WRAPPER_RE = /^do\s+you\s+know\s+(.+?)\??$/i;
|
|
3018
|
+
WANT_KNOW_WRAPPER_RE = /^i(?:'d|\s+would)?\s+(?:like|want|need)\s+to\s+know\s+(.+?)\??$/i;
|
|
3019
|
+
EMBEDDED_WHATIS_RE = /^what\s+((?:an?\s+|the\s+)?[\w'-]+(?:\s+[\w'-]+){0,2})\s+(is|are)\??$/i;
|
|
3020
|
+
EMBEDDED_MEANS_RE = /^what\s+((?:an?\s+|the\s+)?[\w'-]+(?:\s+[\w'-]+){0,2})\s+means\??$/i;
|
|
2986
3021
|
SHOW_GIVE_ME_RE = /^(?:show|give)\s+me\s+(?:the\s+)?(.+?)\??$/i;
|
|
2987
3022
|
LEADING_CONNECTIVE_RE = /^(?:and|also|so|then|now|but)\s+(.+)$/i;
|
|
2988
3023
|
QUESTION_AUX_LEAD_RE = /^(?:does|do|did|is|are|was|were|has|have|had|can|could|will|would|should)\b/i;
|
|
@@ -3041,6 +3076,27 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3041
3076
|
// temporal query produces ("were" as an auxiliary never leads directly into
|
|
3042
3077
|
// a bare "is").
|
|
3043
3078
|
{ re: /^were\s+is\s+(?:the\s+)?(.+?)\s+(defined|declared|located|implemented)\??$/i, to: (m) => `where is ${m[1]} ${m[2]}` },
|
|
3079
|
+
// DESCRIBE PARAPHRASES ("what is the purpose of X", "what does X do in
|
|
3080
|
+
// this codebase") → the meta/whatis shape ("what is a <term>"), which
|
|
3081
|
+
// already answers a unique code entity via metaFallbackEntityAnswer. The
|
|
3082
|
+
// term slot refuses an a/an article or a pronoun lead so the vocabulary
|
|
3083
|
+
// phrasings ("what is the purpose of a horse", "what does it do here")
|
|
3084
|
+
// pass through untouched to their own memory-facts and context readers,
|
|
3085
|
+
// which read the raw text and must keep their turn. A leading "the" is
|
|
3086
|
+
// entity-term noise (mirrors resolveObject's own article strip). The
|
|
3087
|
+
// sibling "what is X for" paraphrase is deliberately NOT a frame: chat's
|
|
3088
|
+
// module-overview lane owns that phrasing and gates on an ask() miss, so
|
|
3089
|
+
// it lives as ask()'s own miss-gated fallback (WHATIS_FOR_FALLBACK_RE)
|
|
3090
|
+
// instead, adopted only when the meta reading actually answers.
|
|
3091
|
+
{ re: /^what\s+is\s+the\s+purpose\s+of\s+(?:the\s+)?(?!(?:an?|it|this|that|these|those)\s)(.+?)\??$/i, to: (m) => `what is a ${m[1]}` },
|
|
3092
|
+
// Scoped form only: bare "what does X do" stays unrewritten — the chat
|
|
3093
|
+
// surface's module-grain overview lane owns it and only gets its turn when
|
|
3094
|
+
// ask() misses, so claiming it here would swap that richer answer for the
|
|
3095
|
+
// one-line meta fallback.
|
|
3096
|
+
{
|
|
3097
|
+
re: new RegExp(`^what\\s+does\\s+(?:the\\s+)?(?!(?:an?|it|this|that|these|those)\\s)(.+?)\\s+do\\s+(?:${TRAILING_SCOPE_FILLER.map(escapeRegex).join("|")})\\??$`, "i"),
|
|
3098
|
+
to: (m) => `what is a ${m[1]}`
|
|
3099
|
+
},
|
|
3044
3100
|
// PREDICATIVE QUALIFIER ("which modules are untested") → the ATTRIBUTIVE form
|
|
3045
3101
|
// ("untested modules") the grammar already answers. The QUALIFIER must sit
|
|
3046
3102
|
// immediately after are/is, so "…are NOT tested" keeps its own set-complement handler.
|
|
@@ -3383,10 +3439,14 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3383
3439
|
verbHit = findPhrase(lemmaWords, VERB_TO_KIND);
|
|
3384
3440
|
if (verbHit) canonWords = lemmaWords;
|
|
3385
3441
|
}
|
|
3442
|
+
let fuzzyVerb = false;
|
|
3386
3443
|
if (!verbHit) {
|
|
3387
3444
|
const fuzzyWords = lcWords.map((w) => w.length >= 4 && eligibleForCanon(w) ? fuzzyVocabWord(w) || w : w);
|
|
3388
3445
|
verbHit = findPhrase(fuzzyWords, VERB_TO_KIND);
|
|
3389
|
-
if (verbHit)
|
|
3446
|
+
if (verbHit) {
|
|
3447
|
+
canonWords = fuzzyWords;
|
|
3448
|
+
fuzzyVerb = true;
|
|
3449
|
+
}
|
|
3390
3450
|
}
|
|
3391
3451
|
if (!verbHit && lcWords.includes("by")) {
|
|
3392
3452
|
for (let i = 0; i < lcWords.length; i += 1) {
|
|
@@ -3398,6 +3458,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3398
3458
|
}
|
|
3399
3459
|
}
|
|
3400
3460
|
if (!verbHit) return null;
|
|
3461
|
+
const stamp = (ast) => fuzzyVerb ? { ...ast, fuzzyVerb: true } : ast;
|
|
3401
3462
|
if (nlp && verbHit.end - verbHit.start === 1) {
|
|
3402
3463
|
const i = verbHit.start;
|
|
3403
3464
|
const det = lcWords[i - 1];
|
|
@@ -3405,7 +3466,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3405
3466
|
const tags = nlp.posTags(words);
|
|
3406
3467
|
if (tags[i] === "NOUN") {
|
|
3407
3468
|
const objText = words.slice(i + 2).filter((w, j) => !STOPWORDS2.has(lcWords[i + 2 + j])).join(" ").trim();
|
|
3408
|
-
if (objText) return { shape: "forward", entityType: null, modifier: "direct", kind: verbHit.kind, object: objText };
|
|
3469
|
+
if (objText) return stamp({ shape: "forward", entityType: null, modifier: "direct", kind: verbHit.kind, object: objText });
|
|
3409
3470
|
}
|
|
3410
3471
|
}
|
|
3411
3472
|
}
|
|
@@ -3435,11 +3496,11 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3435
3496
|
const modifier = modifierHit ? MODIFIER_TO_KIND[canonWords.slice(modifierHit.start, modifierHit.end).join(" ")] : "direct";
|
|
3436
3497
|
if (kind === "touches" && lcWords.includes("when")) {
|
|
3437
3498
|
const objText = beforeText || afterText;
|
|
3438
|
-
if (objText) return { shape: "when", entityType: null, modifier: "direct", kind: "touches", object: objText };
|
|
3499
|
+
if (objText) return stamp({ shape: "when", entityType: null, modifier: "direct", kind: "touches", object: objText });
|
|
3439
3500
|
}
|
|
3440
3501
|
if (kind === "touches" && lcWords.includes("who") && lcWords.includes("last")) {
|
|
3441
3502
|
const objText = beforeText || afterText;
|
|
3442
|
-
if (objText) return { shape: "whoLast", entityType: null, modifier: "direct", kind: "touches", object: objText };
|
|
3503
|
+
if (objText) return stamp({ shape: "whoLast", entityType: null, modifier: "direct", kind: "touches", object: objText });
|
|
3443
3504
|
}
|
|
3444
3505
|
const byIdx = lcWords.indexOf("by");
|
|
3445
3506
|
const hasPassiveAux = lcWords.slice(0, verbHit.start).some((w) => PASSIVE_AUX.has(w));
|
|
@@ -3459,7 +3520,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3459
3520
|
break;
|
|
3460
3521
|
}
|
|
3461
3522
|
const agentNamed = nextAfterBy != null && !WH_WORDS.has(nextAfterBy) && !ENTITY_TO_TYPE[nextAfterBy];
|
|
3462
|
-
return { shape: agentNamed ? "forward" : "reverse", entityType, modifier, kind, object };
|
|
3523
|
+
return stamp({ shape: agentNamed ? "forward" : "reverse", entityType, modifier, kind, object });
|
|
3463
3524
|
}
|
|
3464
3525
|
}
|
|
3465
3526
|
if (beforeText && afterText) {
|
|
@@ -3467,14 +3528,14 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3467
3528
|
let subject = beforeText;
|
|
3468
3529
|
let object = afterText;
|
|
3469
3530
|
if (INHERITS_REVERSE_VERBS.includes(verbPhrase)) [subject, object] = [object, subject];
|
|
3470
|
-
return { shape: "ask", entityType: null, modifier: "direct", kind, subject, object };
|
|
3531
|
+
return stamp({ shape: "ask", entityType: null, modifier: "direct", kind, subject, object });
|
|
3471
3532
|
}
|
|
3472
|
-
if (afterText) return { shape: "reverse", entityType, modifier, kind, object: afterText };
|
|
3533
|
+
if (afterText) return stamp({ shape: "reverse", entityType, modifier, kind, object: afterText });
|
|
3473
3534
|
if (kind === "inherits" && !beforeText && entityHit && entityHit.start === verbHit.end) {
|
|
3474
3535
|
const entityText = canonWords.slice(entityHit.start, entityHit.end).join(" ");
|
|
3475
|
-
if (entityText) return { shape: "reverse", entityType: null, modifier, kind, object: entityText };
|
|
3536
|
+
if (entityText) return stamp({ shape: "reverse", entityType: null, modifier, kind, object: entityText });
|
|
3476
3537
|
}
|
|
3477
|
-
if (beforeText) return { shape: "forward", entityType, modifier: "direct", kind, object: beforeText };
|
|
3538
|
+
if (beforeText) return stamp({ shape: "forward", entityType, modifier: "direct", kind, object: beforeText });
|
|
3478
3539
|
return null;
|
|
3479
3540
|
}
|
|
3480
3541
|
var PASSIVE_AUX, WH_WORDS, PLACEHOLDER_SET, keywordSpotStrategy;
|
|
@@ -3791,6 +3852,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3791
3852
|
__export(ask_exports, {
|
|
3792
3853
|
applyNegationFrames: () => applyNegationFrames,
|
|
3793
3854
|
ask: () => ask,
|
|
3855
|
+
classDisplayName: () => classDisplayName,
|
|
3794
3856
|
compositionalHint: () => compositionalHint,
|
|
3795
3857
|
degreeMetric: () => degreeMetric,
|
|
3796
3858
|
evalComposite: () => evalComposite,
|
|
@@ -3825,6 +3887,14 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
3825
3887
|
const [s, p] = PLURAL_FORMS[entityType] || ["result", "results"];
|
|
3826
3888
|
return n === 1 ? s : p;
|
|
3827
3889
|
}
|
|
3890
|
+
function classDisplayName(cls) {
|
|
3891
|
+
const s = String(cls || "");
|
|
3892
|
+
if (typeof splitIdentifierWords === "function") {
|
|
3893
|
+
const words = splitIdentifierWords(s).join(" ");
|
|
3894
|
+
if (words) return words;
|
|
3895
|
+
}
|
|
3896
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase();
|
|
3897
|
+
}
|
|
3828
3898
|
function verbFor(kind) {
|
|
3829
3899
|
return REVERSE_MISS_VERB[kind] || kind;
|
|
3830
3900
|
}
|
|
@@ -5434,6 +5504,15 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
5434
5504
|
...extra
|
|
5435
5505
|
};
|
|
5436
5506
|
}
|
|
5507
|
+
function rankEntryPointModules(graph, term) {
|
|
5508
|
+
const queryWords = new Set(String(term || "").toLowerCase().split(/[\s-]+/).filter(Boolean));
|
|
5509
|
+
return (graph.individuals || []).filter((i) => i.class === "Module" && ENTRY_POINT_BASENAMES.has(moduleStemOf(i.label))).map((ind) => ({
|
|
5510
|
+
ind,
|
|
5511
|
+
named: queryWords.has(moduleStemOf(ind.label)) ? 1 : 0,
|
|
5512
|
+
depth: String(ind.label).split("/").length,
|
|
5513
|
+
fixture: isTestFixturePath(ind.label) ? 1 : 0
|
|
5514
|
+
})).sort((a, b) => b.named - a.named || a.depth - b.depth || a.fixture - b.fixture || String(a.ind.label).localeCompare(String(b.ind.label))).map((x) => x.ind);
|
|
5515
|
+
}
|
|
5437
5516
|
function modifierIsWired(shape, kind, entityType) {
|
|
5438
5517
|
return shape === "reverse" && (kind === "imports" || kind === "calls") && (!entityType || entityType === "Module");
|
|
5439
5518
|
}
|
|
@@ -5493,6 +5572,17 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
5493
5572
|
traversal: `proseIndex word lookup for "${term}"`
|
|
5494
5573
|
};
|
|
5495
5574
|
}
|
|
5575
|
+
if (shape === "where" && ENTRY_POINT_QUERY_RE.test(String(parsed.object || "").trim())) {
|
|
5576
|
+
const ranked = rankEntryPointModules(graph, parsed.object);
|
|
5577
|
+
return {
|
|
5578
|
+
matches: ranked,
|
|
5579
|
+
objMatch: ranked[0] || null,
|
|
5580
|
+
candidates: ranked.slice(1, 5),
|
|
5581
|
+
ambiguous: false,
|
|
5582
|
+
entryPointShape: true,
|
|
5583
|
+
traversal: `Module individuals with an entry-point basename (${[...ENTRY_POINT_BASENAMES].join("/")}), ranked query-named basename first, then shallower path, then non-test path`
|
|
5584
|
+
};
|
|
5585
|
+
}
|
|
5496
5586
|
if (parsed.modifier && parsed.modifier !== "direct" && !modifierIsWired(shape, kind, entityType)) {
|
|
5497
5587
|
return {
|
|
5498
5588
|
matches: [],
|
|
@@ -5651,7 +5741,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
5651
5741
|
matchedVia,
|
|
5652
5742
|
forwardGrainMiss: true,
|
|
5653
5743
|
wantClasses: [...wantClasses],
|
|
5654
|
-
traversal: `${fwdKinds.join("+")} edges where subject = ${objMatch.label} (grain mismatch: this "${kind}" relation never targets a ${entityType})`
|
|
5744
|
+
traversal: `${fwdKinds.join("+")} edges where subject = ${objMatch.label} (grain mismatch: this "${kind}" relation never targets a ${classDisplayName(entityType)})`
|
|
5655
5745
|
};
|
|
5656
5746
|
}
|
|
5657
5747
|
}
|
|
@@ -5734,7 +5824,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
5734
5824
|
matchedVia: gMatchedVia,
|
|
5735
5825
|
wrongGrainMiss: true,
|
|
5736
5826
|
wantClass,
|
|
5737
|
-
traversal: `"${parsed.object}" resolved to ${gObjMatch.class} ${gObjMatch.label} (grain mismatch: this "${kind}" question needs a ${wantClass}, and no containing module could be found to refine to)`
|
|
5827
|
+
traversal: `"${parsed.object}" resolved to ${classDisplayName(gObjMatch.class)} ${gObjMatch.label} (grain mismatch: this "${kind}" question needs a ${classDisplayName(wantClass)}, and no containing module could be found to refine to)`
|
|
5738
5828
|
};
|
|
5739
5829
|
}
|
|
5740
5830
|
} else {
|
|
@@ -5746,7 +5836,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
5746
5836
|
matchedVia: gMatchedVia,
|
|
5747
5837
|
wrongGrainMiss: true,
|
|
5748
5838
|
wantClass,
|
|
5749
|
-
traversal: `"${parsed.object}" resolved to ${gObjMatch.class} ${gObjMatch.label} (grain mismatch: this "${kind}" question needs a ${wantClass})`
|
|
5839
|
+
traversal: `"${parsed.object}" resolved to ${classDisplayName(gObjMatch.class)} ${gObjMatch.label} (grain mismatch: this "${kind}" question needs a ${classDisplayName(wantClass)})`
|
|
5750
5840
|
};
|
|
5751
5841
|
}
|
|
5752
5842
|
}
|
|
@@ -5781,7 +5871,7 @@ CREATE INDEX IF NOT EXISTS edges_by_prop ON edges(prop);
|
|
|
5781
5871
|
} else if (entityType !== "Module" && subjects.some((s) => s.class === "Module")) {
|
|
5782
5872
|
const moduleIds = new Set(subjects.filter((s) => s.class === "Module").map((s) => s.id));
|
|
5783
5873
|
matches = refineToEntities(graph, moduleIds, entityType);
|
|
5784
|
-
grainNote = `, then ${entityType} defined in the matched module(s)`;
|
|
5874
|
+
grainNote = `, then ${classDisplayName(entityType)} defined in the matched module(s)`;
|
|
5785
5875
|
} else {
|
|
5786
5876
|
matches = [];
|
|
5787
5877
|
}
|
|
@@ -5874,7 +5964,8 @@ ${options2}
|
|
|
5874
5964
|
(ask one of these directly, or try rephrasing more specifically, to get just that reading)`,
|
|
5875
5965
|
miss: false,
|
|
5876
5966
|
ambiguous: true,
|
|
5877
|
-
candidates: parsed.candidates.map(describeParse)
|
|
5967
|
+
candidates: parsed.candidates.map(describeParse),
|
|
5968
|
+
candidateParses: parsed.candidates
|
|
5878
5969
|
};
|
|
5879
5970
|
}
|
|
5880
5971
|
const options = parsed.candidates.map((p, i) => `${i + 1}) ${describeParse(p)}`).join(" or ");
|
|
@@ -5882,7 +5973,8 @@ ${options2}
|
|
|
5882
5973
|
content: `this could mean more than one thing: ${options} \u2014 try rephrasing more specifically.`,
|
|
5883
5974
|
miss: false,
|
|
5884
5975
|
ambiguous: true,
|
|
5885
|
-
candidates: parsed.candidates.map(describeParse)
|
|
5976
|
+
candidates: parsed.candidates.map(describeParse),
|
|
5977
|
+
candidateParses: parsed.candidates
|
|
5886
5978
|
};
|
|
5887
5979
|
}
|
|
5888
5980
|
if (result.unresolvedPronoun) {
|
|
@@ -5948,6 +6040,26 @@ ${options2}
|
|
|
5948
6040
|
matches: result.matches
|
|
5949
6041
|
};
|
|
5950
6042
|
}
|
|
6043
|
+
if (result.entryPointShape) {
|
|
6044
|
+
if (!result.matches.length) {
|
|
6045
|
+
return {
|
|
6046
|
+
content: `no entry-point module found in the index \u2014 no module basename matches ${listJoin([...ENTRY_POINT_BASENAMES])}.`,
|
|
6047
|
+
miss: true,
|
|
6048
|
+
ambiguous: false,
|
|
6049
|
+
candidates: []
|
|
6050
|
+
};
|
|
6051
|
+
}
|
|
6052
|
+
const [top, ...rest] = result.matches;
|
|
6053
|
+
const shownRest = rest.slice(0, OVERFLOW_CAP).map((i) => i.label);
|
|
6054
|
+
const extra2 = rest.length > OVERFLOW_CAP ? `, \u2026and ${rest.length - OVERFLOW_CAP} more` : "";
|
|
6055
|
+
const also = rest.length ? ` \u2014 also matched: ${listJoin(shownRest)}${extra2}` : "";
|
|
6056
|
+
return {
|
|
6057
|
+
content: `ranked ${result.matches.length} entry-point match${result.matches.length === 1 ? "" : "es"}; top: ${top.label}${also}.`,
|
|
6058
|
+
miss: false,
|
|
6059
|
+
ambiguous: false,
|
|
6060
|
+
matches: result.matches
|
|
6061
|
+
};
|
|
6062
|
+
}
|
|
5951
6063
|
if (!result.objMatch && (!result.candidates || result.candidates.length === 0) && parsed.shape !== "ask") {
|
|
5952
6064
|
const objText = String(parsed.object || "").trim();
|
|
5953
6065
|
const fallback = parsed.entityType && PLURAL_FORMS[parsed.entityType] ? nounFor(parsed.entityType, 1) : "module";
|
|
@@ -6364,6 +6476,21 @@ ${result.branches.map((b, i) => `${i + 1}) ${b.candidate.label}: ${b.rendered.co
|
|
|
6364
6476
|
}
|
|
6365
6477
|
}
|
|
6366
6478
|
}
|
|
6479
|
+
if (parsed === null && rendered.miss && !rendered.ambiguous) {
|
|
6480
|
+
const forM = normalizeQuery(String(query || "")).match(WHATIS_FOR_FALLBACK_RE);
|
|
6481
|
+
const forTerm = forM?.[1]?.trim();
|
|
6482
|
+
if (forTerm) {
|
|
6483
|
+
const forParsed = parseQuery(`what is a ${forTerm}`, { nlp });
|
|
6484
|
+
if (forParsed?.shape === "meta") {
|
|
6485
|
+
const forResult = traverse(graph, forParsed, { contextId, prev });
|
|
6486
|
+
const forRendered = render(forParsed, forResult);
|
|
6487
|
+
if (!forRendered.miss && !forRendered.ambiguous) {
|
|
6488
|
+
result = forResult;
|
|
6489
|
+
rendered = forRendered;
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
}
|
|
6493
|
+
}
|
|
6367
6494
|
let content = relaxed && !rendered.miss && relaxed.to !== relaxed.from ? `read as "${relaxed.to}" \u2014 ${rendered.content}` : rendered.content;
|
|
6368
6495
|
if (!relaxed && !rendered.miss && !rendered.ambiguous && directFull.alternates.length) {
|
|
6369
6496
|
const answered = directFull.alternates.map((a) => {
|
|
@@ -6401,11 +6528,11 @@ ${lines.join("\n")}`;
|
|
|
6401
6528
|
// edit-distance, announced in the content as "assuming you meant …");
|
|
6402
6529
|
// null for every literal-identifier tier.
|
|
6403
6530
|
matchedVia: result.matchedVia || null,
|
|
6404
|
-
...rendered.ambiguous ? { candidates: rendered.candidates } : {}
|
|
6531
|
+
...rendered.ambiguous ? { candidates: rendered.candidates, candidateParses: rendered.candidateParses } : {}
|
|
6405
6532
|
}
|
|
6406
6533
|
};
|
|
6407
6534
|
}
|
|
6408
|
-
var askEdgesOfKindCache, SYMBOL_GRAIN_SIBLING, FINE_ENTITY_TYPES, FINE_CLASS_SIBLING, KIND_UNIONS, kindsFor, OVERFLOW_CAP, PLURAL_FORMS, REVERSE_MISS_VERB, LEADING_RELATION_VERB_RE, FROZEN_META_AMBIGUOUS_TERMS, MAX_COMPOSE_DEPTH, NEST_SENTINEL, PRED_LEAD_SKIP, FRAME_WORDS, COPULA_WORDS, entityNoun, isGerundVerb, FWD_NEG_FRAME, PLURAL_ANAPHORA_OBJECT, TEMPORAL_AUX, TEMPORAL_TAIL, TEMPORAL_TRAIL_FILLER, TEMPORAL_DET, COMMIT_FILTER_OPS, ANAPHORA_NAME_TOKEN_RE, AGG_TAIL_FILLER, LIST_SKIP, LIST_TRIGGERS_SORTED, LISTABLE_KINDS, SCOPE_PREPOSITIONS, FIND_LINKERS, RECENT_COMMIT_LEAD, qualCache, META_FALLBACK_CLASSES, inheritsApplicableCache, FIND_TIER, DEGREE_KINDS, COMMIT_FILTER_DATE_RE, compositeList, LEADING_ARTICLE_RE, TRAILING_GRAIN_WORD_RE, TRANSITIVE_MAX_DEPTH, CONTENT_VOCAB, STRUCTURAL_WORDS, CASCADE_NOISE_SET, NOISE_OR_SCAFFOLD, TRIGGER_FUZZY_WORDS, CASCADE_FUZZY_TARGETS, LAST_COMMIT_PHRASE_RE, BARE_WHEN_COMMIT_RE, DYNAMIC_LIST_TRIGGER_RE, DYNAMIC_COUNT_TRIGGER_RE, DYNAMIC_TAIL_OK_RE, BARE_META_WHATIS_RE;
|
|
6535
|
+
var askEdgesOfKindCache, SYMBOL_GRAIN_SIBLING, FINE_ENTITY_TYPES, FINE_CLASS_SIBLING, KIND_UNIONS, kindsFor, OVERFLOW_CAP, PLURAL_FORMS, REVERSE_MISS_VERB, LEADING_RELATION_VERB_RE, FROZEN_META_AMBIGUOUS_TERMS, MAX_COMPOSE_DEPTH, NEST_SENTINEL, PRED_LEAD_SKIP, FRAME_WORDS, COPULA_WORDS, entityNoun, isGerundVerb, FWD_NEG_FRAME, PLURAL_ANAPHORA_OBJECT, TEMPORAL_AUX, TEMPORAL_TAIL, TEMPORAL_TRAIL_FILLER, TEMPORAL_DET, COMMIT_FILTER_OPS, ANAPHORA_NAME_TOKEN_RE, AGG_TAIL_FILLER, LIST_SKIP, LIST_TRIGGERS_SORTED, LISTABLE_KINDS, SCOPE_PREPOSITIONS, FIND_LINKERS, RECENT_COMMIT_LEAD, qualCache, META_FALLBACK_CLASSES, inheritsApplicableCache, FIND_TIER, DEGREE_KINDS, COMMIT_FILTER_DATE_RE, compositeList, LEADING_ARTICLE_RE, TRAILING_GRAIN_WORD_RE, ENTRY_POINT_QUERY_RE, ENTRY_POINT_BASENAMES, TEST_FIXTURE_PATH_SEGMENTS, moduleStemOf, isTestFixturePath, TRANSITIVE_MAX_DEPTH, CONTENT_VOCAB, STRUCTURAL_WORDS, CASCADE_NOISE_SET, NOISE_OR_SCAFFOLD, TRIGGER_FUZZY_WORDS, CASCADE_FUZZY_TARGETS, LAST_COMMIT_PHRASE_RE, BARE_WHEN_COMMIT_RE, DYNAMIC_LIST_TRIGGER_RE, DYNAMIC_COUNT_TRIGGER_RE, DYNAMIC_TAIL_OK_RE, BARE_META_WHATIS_RE, WHATIS_FOR_FALLBACK_RE;
|
|
6409
6536
|
var init_ask = __esm({
|
|
6410
6537
|
"src/ask.mjs"() {
|
|
6411
6538
|
init_codegraph();
|
|
@@ -6513,6 +6640,11 @@ ${lines.join("\n")}`;
|
|
|
6513
6640
|
compositeList = (matches) => listJoin(matches.slice(0, OVERFLOW_CAP).map((m) => ["Function", "Method"].includes(m.class) ? `${m.label}()` : m.label)) + (matches.length > OVERFLOW_CAP ? `, \u2026and ${matches.length - OVERFLOW_CAP} more` : "");
|
|
6514
6641
|
LEADING_ARTICLE_RE = /^(?:the|a|an)\s+/i;
|
|
6515
6642
|
TRAILING_GRAIN_WORD_RE = new RegExp(`\\s+(${Object.keys(ENTITY_TO_TYPE).join("|")})$`, "i");
|
|
6643
|
+
ENTRY_POINT_QUERY_RE = /^(?:the\s+)?(?:main\s+|primary\s+)?entry[\s-]?points?(?:\s+(?:of|to|for)\s+(?:this|the)\s+(?:codebase|code|repo|repository|project|app))?$/i;
|
|
6644
|
+
ENTRY_POINT_BASENAMES = /* @__PURE__ */ new Set(["index", "main", "app", "server", "cli", "__main__"]);
|
|
6645
|
+
TEST_FIXTURE_PATH_SEGMENTS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "fixture", "fixtures", "spec", "specs", "testdata"]);
|
|
6646
|
+
moduleStemOf = (label) => String(label).toLowerCase().split("/").pop().replace(/\.[a-z0-9]+$/, "");
|
|
6647
|
+
isTestFixturePath = (label) => String(label).toLowerCase().split("/").slice(0, -1).some((seg) => TEST_FIXTURE_PATH_SEGMENTS.has(seg));
|
|
6516
6648
|
TRANSITIVE_MAX_DEPTH = 8;
|
|
6517
6649
|
CONTENT_VOCAB = /* @__PURE__ */ new Set([
|
|
6518
6650
|
...wordsOf(Object.keys(VERB_TO_KIND)),
|
|
@@ -6560,6 +6692,7 @@ ${lines.join("\n")}`;
|
|
|
6560
6692
|
DYNAMIC_COUNT_TRIGGER_RE = /^(?:how\s+many|number\s+of|count(?:\s+the)?)\s+([a-z][a-z'-]*)\s*(.*)$/i;
|
|
6561
6693
|
DYNAMIC_TAIL_OK_RE = /^(?:are there(?:\s+in\s+total)?|is there|do you know(?:\s+about)?|do you have|exist(?:s)?|are known|in (?:the |a )?(?:graph|memory)|you know(?:\s+about)?)?[?.!\s]*$/i;
|
|
6562
6694
|
BARE_META_WHATIS_RE = /^what\s+(?:is|are)\s+(?:an?\s+)?(.+?)[?.!\s]*$/i;
|
|
6695
|
+
WHATIS_FOR_FALLBACK_RE = /^what\s+is\s+(?:the\s+)?(?!(?:an?|it|this|that|these|those)\s)(.+?)\s+(?:used\s+)?for[?.!\s]*$/i;
|
|
6563
6696
|
}
|
|
6564
6697
|
});
|
|
6565
6698
|
|
|
@@ -7226,15 +7359,20 @@ ${lines.join("\n")}`;
|
|
|
7226
7359
|
};
|
|
7227
7360
|
}
|
|
7228
7361
|
function winkInstance() {
|
|
7362
|
+
if (instance !== void 0) return instance;
|
|
7229
7363
|
const loaded = loadWinkModel();
|
|
7230
|
-
if (!loaded)
|
|
7364
|
+
if (!loaded) {
|
|
7365
|
+
instance = null;
|
|
7366
|
+
return null;
|
|
7367
|
+
}
|
|
7231
7368
|
try {
|
|
7232
|
-
|
|
7369
|
+
instance = loaded.winkNLP(loaded.model);
|
|
7233
7370
|
} catch {
|
|
7234
|
-
|
|
7371
|
+
instance = null;
|
|
7235
7372
|
}
|
|
7373
|
+
return instance;
|
|
7236
7374
|
}
|
|
7237
|
-
var import_meta6, injected, cached;
|
|
7375
|
+
var import_meta6, injected, cached, instance;
|
|
7238
7376
|
var init_wink_model = __esm({
|
|
7239
7377
|
"src/wink-model.mjs"() {
|
|
7240
7378
|
init_node_module();
|
|
@@ -7242,6 +7380,13 @@ ${lines.join("\n")}`;
|
|
|
7242
7380
|
}
|
|
7243
7381
|
});
|
|
7244
7382
|
|
|
7383
|
+
// src/sentences.mjs
|
|
7384
|
+
var init_sentences = __esm({
|
|
7385
|
+
"src/sentences.mjs"() {
|
|
7386
|
+
init_wink_model();
|
|
7387
|
+
}
|
|
7388
|
+
});
|
|
7389
|
+
|
|
7245
7390
|
// src/prose-nlp.mjs
|
|
7246
7391
|
var prose_nlp_exports = {};
|
|
7247
7392
|
__export(prose_nlp_exports, {
|
|
@@ -7727,6 +7872,7 @@ ${lines.join("\n")}`;
|
|
|
7727
7872
|
const trustByTriple = /* @__PURE__ */ new Map();
|
|
7728
7873
|
for (const r of rows) trustByTriple.set(`${r.subject}${SEP}${r.predicate}${SEP}${r.object}`, r.trust);
|
|
7729
7874
|
const premiseTrust = (s, p, o) => trustByTriple.get(`${s}${SEP}${p}${SEP}${o}`);
|
|
7875
|
+
const hasTriple = (s, p, o) => trustByTriple.has(`${s}${SEP}${p}${SEP}${o}`);
|
|
7730
7876
|
const numericOnly = (arr) => arr.filter((t) => typeof t === "number");
|
|
7731
7877
|
const scmDerived = deriveSubClassClosure(subClassEdges, { depth, budget, focus: normalizedFocus });
|
|
7732
7878
|
const enlargedSubClassEdges = subClassEdges.concat(scmDerived.map((d) => [d.subject, d.object]));
|
|
@@ -7745,11 +7891,12 @@ ${lines.join("\n")}`;
|
|
|
7745
7891
|
predicate: SUBCLASS_PREDICATE,
|
|
7746
7892
|
object: d.object,
|
|
7747
7893
|
provenance: ENTAILED_PROVENANCE,
|
|
7748
|
-
// Persisted justification
|
|
7749
|
-
//
|
|
7750
|
-
//
|
|
7751
|
-
//
|
|
7752
|
-
//
|
|
7894
|
+
// Persisted justification: the premise fact ids this conclusion rode
|
|
7895
|
+
// (a⊑b, b⊑c) — content-addressed ids work even when a premise is
|
|
7896
|
+
// itself an entailment this same pass just derived. Read back by
|
|
7897
|
+
// retractSubClassOf (below) to find every entailment a retracted
|
|
7898
|
+
// premise could have supported. All five rules persist one, each
|
|
7899
|
+
// citing its own premise shape.
|
|
7753
7900
|
justification: [
|
|
7754
7901
|
factIdForTriple(d.subject, SUBCLASS_PREDICATE, d.via),
|
|
7755
7902
|
factIdForTriple(d.via, SUBCLASS_PREDICATE, d.object)
|
|
@@ -7759,13 +7906,22 @@ ${lines.join("\n")}`;
|
|
|
7759
7906
|
subject: d.subject,
|
|
7760
7907
|
predicate: TYPE_PREDICATE,
|
|
7761
7908
|
object: d.object,
|
|
7762
|
-
provenance: ENTAILED_TYPE_PROVENANCE
|
|
7909
|
+
provenance: ENTAILED_TYPE_PROVENANCE,
|
|
7910
|
+
// The ⊑ premise is cited as the DIRECT via⊑object edge even when the
|
|
7911
|
+
// taught chain is multi-hop: scm-sco materializes that edge (this same
|
|
7912
|
+
// pass or an earlier one), and retraction re-VERIFIES every candidate
|
|
7913
|
+
// anyway, so a citation left dangling by budget truncation is inert.
|
|
7914
|
+
justification: [
|
|
7915
|
+
factIdForTriple(d.subject, TYPE_PREDICATE, d.via),
|
|
7916
|
+
factIdForTriple(d.via, SUBCLASS_PREDICATE, d.object)
|
|
7917
|
+
]
|
|
7763
7918
|
})),
|
|
7764
7919
|
...dwDerived.map((d) => {
|
|
7765
|
-
const
|
|
7920
|
+
const dwStoredForward = hasTriple(d.viaClass, DISJOINT_PREDICATE, d.object);
|
|
7921
|
+
const [dwS, dwO] = dwStoredForward ? [d.viaClass, d.object] : [d.object, d.viaClass];
|
|
7766
7922
|
const premiseTrusts = numericOnly([
|
|
7767
7923
|
premiseTrust(d.subject, TYPE_PREDICATE, d.viaType),
|
|
7768
|
-
|
|
7924
|
+
premiseTrust(dwS, DISJOINT_PREDICATE, dwO),
|
|
7769
7925
|
// the ⊑-lift premise only exists when this IS a lift (viaClass !==
|
|
7770
7926
|
// viaType) — a direct hit has no extra subClassOf premise to price in.
|
|
7771
7927
|
...d.viaClass !== d.viaType ? [premiseTrust(d.viaType, SUBCLASS_PREDICATE, d.viaClass)] : []
|
|
@@ -7775,6 +7931,11 @@ ${lines.join("\n")}`;
|
|
|
7775
7931
|
predicate: DISJOINT_PREDICATE,
|
|
7776
7932
|
object: d.object,
|
|
7777
7933
|
provenance: ENTAILED_DISJOINT_PROVENANCE,
|
|
7934
|
+
justification: [
|
|
7935
|
+
factIdForTriple(d.subject, TYPE_PREDICATE, d.viaType),
|
|
7936
|
+
factIdForTriple(dwS, DISJOINT_PREDICATE, dwO),
|
|
7937
|
+
...d.viaClass !== d.viaType ? [factIdForTriple(d.viaType, SUBCLASS_PREDICATE, d.viaClass)] : []
|
|
7938
|
+
],
|
|
7778
7939
|
...premiseTrusts.length ? { premiseTrusts, ruleConfidence: CAX_DW_RULE_CONFIDENCE } : {}
|
|
7779
7940
|
};
|
|
7780
7941
|
}),
|
|
@@ -7793,6 +7954,13 @@ ${lines.join("\n")}`;
|
|
|
7793
7954
|
predicate: TYPE_PREDICATE,
|
|
7794
7955
|
object: d.object,
|
|
7795
7956
|
provenance: ENTAILED_SVF1_PROVENANCE,
|
|
7957
|
+
justification: [
|
|
7958
|
+
factIdForTriple(d.subject, d.viaProperty, d.viaValue),
|
|
7959
|
+
factIdForTriple(d.viaValue, TYPE_PREDICATE, d.viaType),
|
|
7960
|
+
factIdForTriple(d.object, ON_PROPERTY_PREDICATE, d.viaPropertyKey),
|
|
7961
|
+
factIdForTriple(d.object, SOME_VALUES_FROM_PREDICATE, d.viaTarget),
|
|
7962
|
+
...d.viaType !== d.viaTarget ? [factIdForTriple(d.viaType, SUBCLASS_PREDICATE, d.viaTarget)] : []
|
|
7963
|
+
],
|
|
7796
7964
|
// same sub-1 discount as cax-dw, same reason (see CAX_DW_RULE_CONFIDENCE).
|
|
7797
7965
|
...premiseTrusts.length ? { premiseTrusts, ruleConfidence: CLS_SVF1_RULE_CONFIDENCE } : {}
|
|
7798
7966
|
};
|
|
@@ -7812,6 +7980,13 @@ ${lines.join("\n")}`;
|
|
|
7812
7980
|
predicate: SUBCLASS_PREDICATE,
|
|
7813
7981
|
object: d.object,
|
|
7814
7982
|
provenance: ENTAILED_SCM_SVF_PROVENANCE,
|
|
7983
|
+
justification: [
|
|
7984
|
+
...r1 ? [factIdForTriple(d.subject, ON_PROPERTY_PREDICATE, r1.property)] : [],
|
|
7985
|
+
factIdForTriple(d.subject, SOME_VALUES_FROM_PREDICATE, d.viaY1),
|
|
7986
|
+
...r2 ? [factIdForTriple(d.object, ON_PROPERTY_PREDICATE, r2.property)] : [],
|
|
7987
|
+
factIdForTriple(d.object, SOME_VALUES_FROM_PREDICATE, d.viaY2),
|
|
7988
|
+
factIdForTriple(d.viaY1, SUBCLASS_PREDICATE, d.viaY2)
|
|
7989
|
+
],
|
|
7815
7990
|
// same sub-1 discount as cax-dw/cls-svf1, same reason (see CAX_DW_RULE_CONFIDENCE).
|
|
7816
7991
|
...premiseTrusts.length ? { premiseTrusts, ruleConfidence: SCM_SVF_RULE_CONFIDENCE } : {}
|
|
7817
7992
|
};
|
|
@@ -7846,6 +8021,71 @@ ${lines.join("\n")}`;
|
|
|
7846
8021
|
const tags = String(provenance || "").split(" | ").filter(Boolean);
|
|
7847
8022
|
return tags.length > 0 && tags.every((t) => t.startsWith("entailed:"));
|
|
7848
8023
|
}
|
|
8024
|
+
function buildSurvivorDerivabilityCheck(rows) {
|
|
8025
|
+
const subClassEdges = [];
|
|
8026
|
+
const typesOf = /* @__PURE__ */ new Map();
|
|
8027
|
+
const disjointOf = /* @__PURE__ */ new Map();
|
|
8028
|
+
const onPropertyOf = /* @__PURE__ */ new Map();
|
|
8029
|
+
const someValuesFromOf = /* @__PURE__ */ new Map();
|
|
8030
|
+
const propertyEdgesOf = /* @__PURE__ */ new Map();
|
|
8031
|
+
for (const r of rows) {
|
|
8032
|
+
const pLower = String(r.predicate || "").trim().toLowerCase();
|
|
8033
|
+
if (isSubClassOf(r.predicate)) subClassEdges.push([r.subject, r.object]);
|
|
8034
|
+
else if (isType(r.predicate)) {
|
|
8035
|
+
if (!typesOf.has(r.subject)) typesOf.set(r.subject, /* @__PURE__ */ new Set());
|
|
8036
|
+
typesOf.get(r.subject).add(r.object);
|
|
8037
|
+
} else if (isDisjoint(r.predicate)) {
|
|
8038
|
+
if (!disjointOf.has(r.subject)) disjointOf.set(r.subject, /* @__PURE__ */ new Set());
|
|
8039
|
+
disjointOf.get(r.subject).add(r.object);
|
|
8040
|
+
if (!disjointOf.has(r.object)) disjointOf.set(r.object, /* @__PURE__ */ new Set());
|
|
8041
|
+
disjointOf.get(r.object).add(r.subject);
|
|
8042
|
+
} else if (isOnProperty(r.predicate)) onPropertyOf.set(r.subject, r.object);
|
|
8043
|
+
else if (isSomeValuesFrom(r.predicate)) someValuesFromOf.set(r.subject, r.object);
|
|
8044
|
+
else if (!RESERVED_PREDICATES.has(pLower)) {
|
|
8045
|
+
if (!propertyEdgesOf.has(r.subject)) propertyEdgesOf.set(r.subject, []);
|
|
8046
|
+
propertyEdgesOf.get(r.subject).push([normFactTerm(r.predicate), r.object]);
|
|
8047
|
+
}
|
|
8048
|
+
}
|
|
8049
|
+
const ancestorsOf2 = buildAncestorCloser(subClassEdges);
|
|
8050
|
+
const reaches = (a, b) => a !== b && ancestorsOf2(a).has(b);
|
|
8051
|
+
const restrictionOf = (node) => {
|
|
8052
|
+
const property = onPropertyOf.get(node);
|
|
8053
|
+
const target = someValuesFromOf.get(node);
|
|
8054
|
+
return property && target ? { property: normFactTerm(property), target } : null;
|
|
8055
|
+
};
|
|
8056
|
+
return (row) => {
|
|
8057
|
+
if (isSubClassOf(row.predicate)) {
|
|
8058
|
+
if (reaches(row.subject, row.object)) return true;
|
|
8059
|
+
const r1 = restrictionOf(row.subject);
|
|
8060
|
+
const r2 = restrictionOf(row.object);
|
|
8061
|
+
return Boolean(r1 && r2 && r1.property === r2.property && reaches(r1.target, r2.target));
|
|
8062
|
+
}
|
|
8063
|
+
if (isType(row.predicate)) {
|
|
8064
|
+
for (const c of typesOf.get(row.subject) || []) {
|
|
8065
|
+
if (reaches(c, row.object)) return true;
|
|
8066
|
+
}
|
|
8067
|
+
const rec = restrictionOf(row.object);
|
|
8068
|
+
if (rec) {
|
|
8069
|
+
for (const [pKey, y] of propertyEdgesOf.get(row.subject) || []) {
|
|
8070
|
+
if (pKey !== rec.property) continue;
|
|
8071
|
+
for (const c of typesOf.get(y) || []) {
|
|
8072
|
+
if (c === rec.target || reaches(c, rec.target)) return true;
|
|
8073
|
+
}
|
|
8074
|
+
}
|
|
8075
|
+
}
|
|
8076
|
+
return false;
|
|
8077
|
+
}
|
|
8078
|
+
if (isDisjoint(row.predicate)) {
|
|
8079
|
+
for (const c of typesOf.get(row.subject) || []) {
|
|
8080
|
+
for (const d of [c, ...ancestorsOf2(c)]) {
|
|
8081
|
+
if (disjointOf.get(d)?.has(row.object)) return true;
|
|
8082
|
+
}
|
|
8083
|
+
}
|
|
8084
|
+
return false;
|
|
8085
|
+
}
|
|
8086
|
+
return true;
|
|
8087
|
+
};
|
|
8088
|
+
}
|
|
7849
8089
|
async function retractSubClassOf(repoDir, subject, object, { budget = 50, depth = 32 } = {}) {
|
|
7850
8090
|
const s = normFactTerm(subject);
|
|
7851
8091
|
const o = normFactTerm(object);
|
|
@@ -7854,19 +8094,18 @@ ${lines.join("\n")}`;
|
|
|
7854
8094
|
const rows = readFactRows(memory);
|
|
7855
8095
|
const byId = new Map(rows.map((r) => [r.id, r]));
|
|
7856
8096
|
if (!byId.has(targetId)) return { retracted: [], count: 0, budget, depth, truncated: false, found: false };
|
|
7857
|
-
const
|
|
7858
|
-
const edgeOf = new Map(scRows.map((r) => [r.id, [r.subject, r.object]]));
|
|
7859
|
-
const entailedScRows = scRows.filter((r) => r.justification.length && isPurelyEntailed(r.provenance));
|
|
8097
|
+
const entailedRows = rows.filter((r) => r.justification.length && isPurelyEntailed(r.provenance));
|
|
7860
8098
|
const removed = /* @__PURE__ */ new Set([targetId]);
|
|
7861
8099
|
const order = [targetId];
|
|
7862
8100
|
let truncated = false;
|
|
7863
8101
|
let round2 = 0;
|
|
7864
8102
|
for (; round2 < depth; round2 += 1) {
|
|
7865
|
-
const candidates =
|
|
8103
|
+
const candidates = entailedRows.filter((r) => !removed.has(r.id) && r.justification.some((j) => removed.has(j))).sort((a, b) => a.subject.localeCompare(b.subject) || a.predicate.localeCompare(b.predicate) || a.object.localeCompare(b.object));
|
|
7866
8104
|
if (!candidates.length) break;
|
|
7867
8105
|
const candidateIds = new Set(candidates.map((c) => c.id));
|
|
7868
|
-
const
|
|
7869
|
-
|
|
8106
|
+
const stillDerivable = buildSurvivorDerivabilityCheck(
|
|
8107
|
+
rows.filter((r) => !removed.has(r.id) && !candidateIds.has(r.id))
|
|
8108
|
+
);
|
|
7870
8109
|
let progressed = false;
|
|
7871
8110
|
let hitBudget = false;
|
|
7872
8111
|
for (const c of candidates) {
|
|
@@ -7874,7 +8113,7 @@ ${lines.join("\n")}`;
|
|
|
7874
8113
|
hitBudget = true;
|
|
7875
8114
|
break;
|
|
7876
8115
|
}
|
|
7877
|
-
if (
|
|
8116
|
+
if (stillDerivable(c)) continue;
|
|
7878
8117
|
removed.add(c.id);
|
|
7879
8118
|
order.push(c.id);
|
|
7880
8119
|
progressed = true;
|
|
@@ -7886,7 +8125,7 @@ ${lines.join("\n")}`;
|
|
|
7886
8125
|
if (!progressed) break;
|
|
7887
8126
|
}
|
|
7888
8127
|
if (!truncated && round2 >= depth) {
|
|
7889
|
-
truncated =
|
|
8128
|
+
truncated = entailedRows.some((r) => !removed.has(r.id) && r.justification.some((j) => removed.has(j)));
|
|
7890
8129
|
}
|
|
7891
8130
|
const { removed: actuallyRemoved } = await removeFacts(repoDir, order);
|
|
7892
8131
|
return { retracted: actuallyRemoved, count: actuallyRemoved.length, budget, depth, truncated, found: true };
|
|
@@ -7971,6 +8210,30 @@ ${lines.join("\n")}`;
|
|
|
7971
8210
|
});
|
|
7972
8211
|
|
|
7973
8212
|
// src/chat.mjs
|
|
8213
|
+
function deduceGoalFromParsed(parsed) {
|
|
8214
|
+
if (!parsed) return null;
|
|
8215
|
+
const { node, shape, kind } = parsed;
|
|
8216
|
+
if (node === "find") return `locate a specific named entity ("${parsed.term}")`;
|
|
8217
|
+
if (node === "count") return `get a count of ${goalNoun(parsed.entityType)}`;
|
|
8218
|
+
if (node === "list") return `list/enumerate ${goalNoun(parsed.entityType)} matching a condition`;
|
|
8219
|
+
if (node === "superlative") return `rank/compare ${goalNoun(parsed.entityType)} by ${parsed.metricNoun || parsed.metric || "a metric"}`;
|
|
8220
|
+
if (node === "anaphora") return "follow up on the previous answer's result set (discourse anaphora)";
|
|
8221
|
+
if (node === "membership") return `understand "${parsed.term || "an entity"}"'s membership/relationship`;
|
|
8222
|
+
if (node === "clause") return deduceGoalFromParsed(parsed.clause);
|
|
8223
|
+
if (node === "miss") return null;
|
|
8224
|
+
if (node === "boolean" || node === "qualifier" || node === "reverseSet" || node === "forwardSet" || node === "allOfClass" || node === "temporal") {
|
|
8225
|
+
const k = kind || parsed.inner?.kind;
|
|
8226
|
+
return k && GOAL_BY_KIND[k] ? GOAL_BY_KIND[k] : `filter/traverse ${goalNoun(parsed.entityType)} by a relationship`;
|
|
8227
|
+
}
|
|
8228
|
+
if (shape === "meta") return `understand a vocabulary/definition term ("${parsed.object}")`;
|
|
8229
|
+
if (shape === "where") return `locate where something is defined ("${parsed.object}")`;
|
|
8230
|
+
if (shape === "when") return "understand when something last changed (history)";
|
|
8231
|
+
if (shape === "whoLast") return "find who most recently touched something (history)";
|
|
8232
|
+
if (shape === "mentions") return `find where something is mentioned in prose ("${parsed.object}")`;
|
|
8233
|
+
if (shape === "ask") return kind && GOAL_BY_KIND[kind] || "check a specific subject/object relationship";
|
|
8234
|
+
if ((shape === "reverse" || shape === "forward") && kind) return GOAL_BY_KIND[kind] || `understand a "${kind}" relationship`;
|
|
8235
|
+
return "understand a graph relationship";
|
|
8236
|
+
}
|
|
7974
8237
|
function collapsedIndex(set) {
|
|
7975
8238
|
const idx = /* @__PURE__ */ new Map();
|
|
7976
8239
|
for (const phrase of set) if (!idx.has(collapseRuns(phrase))) idx.set(collapseRuns(phrase), phrase);
|
|
@@ -8117,6 +8380,10 @@ ${lines.join("\n")}`;
|
|
|
8117
8380
|
}
|
|
8118
8381
|
return null;
|
|
8119
8382
|
}
|
|
8383
|
+
function matchGenitiveWhoAsk(q) {
|
|
8384
|
+
const g = String(q).match(GENITIVE_WHO_ASK_RE);
|
|
8385
|
+
return g ? [g[0], g[2], g[1]] : null;
|
|
8386
|
+
}
|
|
8120
8387
|
function matchWhyIsa(q) {
|
|
8121
8388
|
const stripped = String(q || "").replace(WHY_ISA_LEAD_RE, "");
|
|
8122
8389
|
if (stripped !== q) {
|
|
@@ -8127,6 +8394,14 @@ ${lines.join("\n")}`;
|
|
|
8127
8394
|
if (ehyk) return `is ${ehyk[1].trim()} a ${ehyk[2].trim()}`.match(ISA_ASK_RE);
|
|
8128
8395
|
return null;
|
|
8129
8396
|
}
|
|
8397
|
+
function comparativeOfSuperlative(superlative) {
|
|
8398
|
+
const s = String(superlative || "").toLowerCase().trim().replace(/\s+/g, " ");
|
|
8399
|
+
if (s === "best") return "better";
|
|
8400
|
+
if (s === "worst") return "worse";
|
|
8401
|
+
const graded = s.match(/^(most|least)\s+([a-z][\w-]*)$/);
|
|
8402
|
+
if (graded) return `${graded[1] === "most" ? "more" : "less"} ${graded[2]}`;
|
|
8403
|
+
return /[a-z]est$/.test(s) && s.length > 4 ? `${s.slice(0, -3)}er` : null;
|
|
8404
|
+
}
|
|
8130
8405
|
function uniqueFacts(rows) {
|
|
8131
8406
|
const seen = /* @__PURE__ */ new Set();
|
|
8132
8407
|
const out = [];
|
|
@@ -8139,6 +8414,26 @@ ${lines.join("\n")}`;
|
|
|
8139
8414
|
return out;
|
|
8140
8415
|
}
|
|
8141
8416
|
async function factAnswer(memoryDir, query, envelope, miss2, biasByBundle = {}, cache = null) {
|
|
8417
|
+
return withDeducedGoal(await factAnswerReaders(memoryDir, query, envelope, miss2, biasByBundle, cache), envelope, query);
|
|
8418
|
+
}
|
|
8419
|
+
function withDeducedGoal(res, envelope, query) {
|
|
8420
|
+
if (!res || res.goal !== void 0) return res;
|
|
8421
|
+
const q = String(query || "").trim();
|
|
8422
|
+
let goal = deduceGoalFromParsed(envelope?.parsed);
|
|
8423
|
+
if (!goal && res.generalVerbQuery) goal = TAUGHT_FACT_LOOKUP_GOAL;
|
|
8424
|
+
if (!goal) {
|
|
8425
|
+
const yesNo = q.match(RELATION_FACT_YESNO_RE);
|
|
8426
|
+
const whoAsk = yesNo ? null : q.match(RELATION_WHO_ASK_RE) || matchGenitiveWhoAsk(q);
|
|
8427
|
+
const role = yesNo ? yesNo[2] : whoAsk ? whoAsk[1] : null;
|
|
8428
|
+
if (role && !ISA_IDIOM_ROLE_WORDS.has(role.toLowerCase())) goal = TAUGHT_FACT_LOOKUP_GOAL;
|
|
8429
|
+
}
|
|
8430
|
+
if (!goal) {
|
|
8431
|
+
const whatIs = q.match(BARE_WHATIS_RE);
|
|
8432
|
+
if (whatIs) goal = deduceGoalFromParsed({ shape: "meta", object: whatIs[1] });
|
|
8433
|
+
}
|
|
8434
|
+
return goal ? { ...res, goal } : res;
|
|
8435
|
+
}
|
|
8436
|
+
async function factAnswerReaders(memoryDir, query, envelope, miss2, biasByBundle = {}, cache = null) {
|
|
8142
8437
|
let normFactTerm2;
|
|
8143
8438
|
try {
|
|
8144
8439
|
({ normFactTerm: normFactTerm2 } = await Promise.resolve().then(() => (init_core(), core_exports)));
|
|
@@ -8174,11 +8469,82 @@ ${lines.join("\n")}`;
|
|
|
8174
8469
|
\u2026and ${rest.length} more \u2014 say 'more' to see them.` : "";
|
|
8175
8470
|
return { text: shown.join("\n") + extra, replace: true, ...rest.length ? { pending: { items: rest, noun: "facts" } } : {} };
|
|
8176
8471
|
}
|
|
8472
|
+
const whichSup = q.match(WHICH_KIND_SUPERLATIVE_RE);
|
|
8473
|
+
const whatSup = whichSup ? null : q.match(WHAT_IS_SUPERLATIVE_KIND_RE);
|
|
8474
|
+
const supKindRaw = whichSup ? whichSup[1] : whatSup?.[2];
|
|
8475
|
+
const supWord = whichSup ? whichSup[2] : whatSup?.[1];
|
|
8476
|
+
const supCompBase = supKindRaw && supWord ? comparativeOfSuperlative(supWord) : null;
|
|
8477
|
+
if (supCompBase) {
|
|
8478
|
+
const supPredicate = `mgx:${supCompBase.replace(/\s+/g, "-")}-than`;
|
|
8479
|
+
const rows = await factRows(memoryDir, cache);
|
|
8480
|
+
const kindVariants = factTermVariants(normFactTerm2, supKindRaw);
|
|
8481
|
+
const kindSingular = [...kindVariants].sort((a, b) => a.length - b.length)[0];
|
|
8482
|
+
const memberOfKind = (node) => kindVariants.has(node) || node.startsWith(`${kindSingular}-`) || node.startsWith(`${kindSingular} `) || rows.some((g) => ISA_PREDICATES.has(g.predicate) && g.subject === node && kindVariants.has(g.object));
|
|
8483
|
+
const pairs = uniqueFacts(rows.filter((f) => f.predicate === supPredicate && isOperatorTaught(f))).filter((f) => f.subject !== f.object && memberOfKind(f.subject) && memberOfKind(f.object));
|
|
8484
|
+
if (pairs.length) {
|
|
8485
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
8486
|
+
const inDeg = /* @__PURE__ */ new Map();
|
|
8487
|
+
for (const f of pairs) {
|
|
8488
|
+
nodes.add(f.subject);
|
|
8489
|
+
nodes.add(f.object);
|
|
8490
|
+
inDeg.set(f.object, (inDeg.get(f.object) || 0) + 1);
|
|
8491
|
+
if (!inDeg.has(f.subject)) inDeg.set(f.subject, inDeg.get(f.subject) || 0);
|
|
8492
|
+
}
|
|
8493
|
+
const remaining = new Map(inDeg);
|
|
8494
|
+
const order = [];
|
|
8495
|
+
let declined = null;
|
|
8496
|
+
while (remaining.size) {
|
|
8497
|
+
const sources = [...remaining.keys()].filter((n) => remaining.get(n) === 0);
|
|
8498
|
+
if (sources.length !== 1) {
|
|
8499
|
+
declined = sources.length === 0 ? {
|
|
8500
|
+
text: `I can't order the ${kindSingular}s \u2014 the "${supCompBase} than" facts I have loop back on themselves, so no ${supWord} exists. /memory to inspect them.`,
|
|
8501
|
+
replace: true,
|
|
8502
|
+
miss: true
|
|
8503
|
+
} : {
|
|
8504
|
+
text: `I can't pick the ${supWord} ${kindSingular} from what I know \u2014 nothing compares ${sources[0]} and ${sources[1]}. Teach me, e.g. "${sources[0]} is ${supCompBase} than ${sources[1]}".`,
|
|
8505
|
+
replace: true,
|
|
8506
|
+
miss: true
|
|
8507
|
+
};
|
|
8508
|
+
break;
|
|
8509
|
+
}
|
|
8510
|
+
const head = sources[0];
|
|
8511
|
+
order.push(head);
|
|
8512
|
+
remaining.delete(head);
|
|
8513
|
+
for (const f of pairs) {
|
|
8514
|
+
if (f.subject === head && remaining.has(f.object)) remaining.set(f.object, remaining.get(f.object) - 1);
|
|
8515
|
+
}
|
|
8516
|
+
}
|
|
8517
|
+
if (declined) return declined;
|
|
8518
|
+
const steps = order.slice(0, -1).map((n, i) => pairs.find((f) => f.subject === n && f.object === order[i + 1]));
|
|
8519
|
+
if (steps.every(Boolean)) {
|
|
8520
|
+
const cite = steps.map((g) => `${factPhrase(g)}${g.provenance ? ` (source: ${g.provenance})` : ""}`).join("; ");
|
|
8521
|
+
return { text: `${order[0]} \u2014 ${cite}; so ${order[0]} is the ${supWord} ${kindSingular}`, replace: true };
|
|
8522
|
+
}
|
|
8523
|
+
}
|
|
8524
|
+
}
|
|
8525
|
+
const whereQ = miss2 ? q.match(WHERE_IS_FACT_RE) : null;
|
|
8526
|
+
if (whereQ) {
|
|
8527
|
+
const variants = factTermVariants(normFactTerm2, whereQ[1]);
|
|
8528
|
+
const hits = (await factRows(memoryDir, cache)).filter((f) => LOCATIVE_FACT_PREDICATE_RE.test(f.predicate) && variants.has(f.subject));
|
|
8529
|
+
if (hits.length) {
|
|
8530
|
+
const ranked = rankByBiasThenTrust(uniqueFacts(hits), biasByBundle);
|
|
8531
|
+
const lines = ranked.map(renderFactLine);
|
|
8532
|
+
const shown = lines.slice(0, FACT_ANSWER_CAP);
|
|
8533
|
+
const rest = lines.slice(FACT_ANSWER_CAP);
|
|
8534
|
+
const extra = rest.length ? `
|
|
8535
|
+
\u2026and ${rest.length} more \u2014 say 'more' to see them.` : "";
|
|
8536
|
+
return { text: shown.join("\n") + extra, replace: true, ...rest.length ? { pending: { items: rest, noun: "facts" } } : {} };
|
|
8537
|
+
}
|
|
8538
|
+
}
|
|
8177
8539
|
let metaTerm = envelope?.parsed?.shape === "meta" ? envelope.parsed.object : null;
|
|
8178
8540
|
if (!metaTerm && miss2 && !envelope?.parsed && !WHAT_INHERITS_RE.test(q)) {
|
|
8179
8541
|
const m = q.match(BARE_WHATIS_RE) || q.match(/^what\s+(?:does|do)\s+(.+?)\s+means?[?.!\s]*$/i);
|
|
8180
8542
|
if (m) metaTerm = stripTrailingScopeFiller(m[1]);
|
|
8181
8543
|
}
|
|
8544
|
+
if (!metaTerm && envelope?.ambiguous && Array.isArray(envelope.candidateParses)) {
|
|
8545
|
+
const metaCand = envelope.candidateParses.find((c) => c?.shape === "meta" && c.object);
|
|
8546
|
+
if (metaCand) metaTerm = stripTrailingScopeFiller(String(metaCand.object));
|
|
8547
|
+
}
|
|
8182
8548
|
if (metaTerm) {
|
|
8183
8549
|
const { subject, predicate } = splitMetaPredicate(metaTerm);
|
|
8184
8550
|
const variants = factTermVariants(normFactTerm2, subject);
|
|
@@ -8268,7 +8634,7 @@ ${lines.join("\n")}`;
|
|
|
8268
8634
|
if (knownCan.length) {
|
|
8269
8635
|
const shown = knownCan.slice(0, 3).map(renderFactLine).join("; ");
|
|
8270
8636
|
return {
|
|
8271
|
-
text: `I can't confirm that \u2014 nothing I remember says ${can[1]} can ${can[2]}. I do know: ${shown}. If it's true, teach me: "a ${
|
|
8637
|
+
text: `I can't confirm that \u2014 nothing I remember says ${can[1]} can ${can[2]}. I do know: ${shown}. If it's true, teach me: "a ${knownCan[0].subject} can ${can[2]}".`,
|
|
8272
8638
|
replace: true,
|
|
8273
8639
|
miss: true
|
|
8274
8640
|
};
|
|
@@ -8285,6 +8651,34 @@ ${lines.join("\n")}`;
|
|
|
8285
8651
|
if (hit2) return { text: `yes \u2014 ${renderFactLine(hit2)}`, replace: true };
|
|
8286
8652
|
return null;
|
|
8287
8653
|
}
|
|
8654
|
+
const doAsk = q.match(DO_VERB_ASK_RE);
|
|
8655
|
+
if (doAsk) {
|
|
8656
|
+
const facts = await memoryFacts(memoryDir);
|
|
8657
|
+
const universal = !!doAsk[1];
|
|
8658
|
+
const subj = factTermVariants(normFactTerm2, doAsk[2]);
|
|
8659
|
+
const obj = factTermVariants(normFactTerm2, doAsk[3]);
|
|
8660
|
+
const hit2 = facts.find(
|
|
8661
|
+
(f) => f.predicate === "mgx:capableOf" && subj.has(f.subject) && obj.has(f.object)
|
|
8662
|
+
);
|
|
8663
|
+
if (hit2 && universal) {
|
|
8664
|
+
return {
|
|
8665
|
+
text: `I can't speak for all ${doAsk[2]} \u2014 what I remember is generic, not universal. I do know: ${renderFactLine(hit2)}.`,
|
|
8666
|
+
replace: true
|
|
8667
|
+
};
|
|
8668
|
+
}
|
|
8669
|
+
if (hit2) return { text: `yes \u2014 ${renderFactLine(hit2)}`, replace: true };
|
|
8670
|
+
if (miss2) {
|
|
8671
|
+
const knownCan = facts.filter((f) => f.predicate === "mgx:capableOf" && subj.has(f.subject));
|
|
8672
|
+
if (knownCan.length) {
|
|
8673
|
+
const shown = knownCan.slice(0, 3).map(renderFactLine).join("; ");
|
|
8674
|
+
return {
|
|
8675
|
+
text: `I can't confirm that \u2014 nothing I remember says ${doAsk[2]} can ${doAsk[3]}. I do know: ${shown}. If it's true, teach me: "a ${knownCan[0].subject} can ${doAsk[3]}".`,
|
|
8676
|
+
replace: true,
|
|
8677
|
+
miss: true
|
|
8678
|
+
};
|
|
8679
|
+
}
|
|
8680
|
+
}
|
|
8681
|
+
}
|
|
8288
8682
|
const canDo = q.match(WHAT_CAN_DO_RE);
|
|
8289
8683
|
if (canDo) {
|
|
8290
8684
|
const variants = factTermVariants(normFactTerm2, canDo[1]);
|
|
@@ -8298,6 +8692,59 @@ ${lines.join("\n")}`;
|
|
|
8298
8692
|
\u2026and ${rest.length} more \u2014 say 'more' to see them.` : "";
|
|
8299
8693
|
return { text: shown.join("\n") + extra, replace: true, ...rest.length ? { pending: { items: rest, noun: "facts" } } : {} };
|
|
8300
8694
|
}
|
|
8695
|
+
const whichCan = q.match(WHICH_KIND_CAN_RE);
|
|
8696
|
+
if (whichCan) {
|
|
8697
|
+
const kindVariants = factTermVariants(normFactTerm2, whichCan[1]);
|
|
8698
|
+
const verbVariants = factTermVariants(normFactTerm2, whichCan[2]);
|
|
8699
|
+
const facts = await factRows(memoryDir, cache);
|
|
8700
|
+
const capable = uniqueFacts(facts.filter((f) => f.predicate === "mgx:capableOf" && verbVariants.has(f.object)));
|
|
8701
|
+
if (capable.length) {
|
|
8702
|
+
const { findIsaChain: findIsaChain2, SUBCLASS_PREDICATE: SC_PRED, TYPE_PREDICATE: TYPE_PRED } = await Promise.resolve().then(() => (init_syllogise(), syllogise_exports));
|
|
8703
|
+
const subClassRows = facts.filter((f) => f.predicate === SC_PRED);
|
|
8704
|
+
const typeRows = facts.filter((f) => f.predicate === TYPE_PRED);
|
|
8705
|
+
const subClassEdges = subClassRows.map((f) => [f.subject, f.object]);
|
|
8706
|
+
const typeEdges = typeRows.map((f) => [f.subject, f.object]);
|
|
8707
|
+
const rowForStep = (step) => (step.predicate === SC_PRED ? subClassRows : typeRows).find((g) => g.subject === step.subject && g.object === step.object);
|
|
8708
|
+
const chainBySubject = /* @__PURE__ */ new Map();
|
|
8709
|
+
const inKind = capable.filter((f) => {
|
|
8710
|
+
if (kindVariants.has(f.subject)) return true;
|
|
8711
|
+
if (!chainBySubject.has(f.subject)) {
|
|
8712
|
+
chainBySubject.set(f.subject, findIsaChain2(f.subject, kindVariants, typeEdges, subClassEdges, { maxHops: 3 }));
|
|
8713
|
+
}
|
|
8714
|
+
return !!chainBySubject.get(f.subject);
|
|
8715
|
+
});
|
|
8716
|
+
const ranked = rankByBiasThenTrust(inKind.length ? inKind : capable, biasByBundle);
|
|
8717
|
+
const lines = ranked.map((f) => {
|
|
8718
|
+
const chain = inKind.length ? chainBySubject.get(f.subject) : null;
|
|
8719
|
+
if (!chain || chain.length < 2) return renderFactLine(f);
|
|
8720
|
+
const steps = chain.map(rowForStep);
|
|
8721
|
+
if (!steps.every(Boolean)) return renderFactLine(f);
|
|
8722
|
+
const cite = steps.map((g) => `${factPhrase(g)}${g.provenance ? ` (source: ${g.provenance})` : ""}`).join("; ");
|
|
8723
|
+
return `${renderFactLine(f)} \u2014 via: ${cite}`;
|
|
8724
|
+
});
|
|
8725
|
+
const shown = lines.slice(0, FACT_ANSWER_CAP);
|
|
8726
|
+
const rest = lines.slice(FACT_ANSWER_CAP);
|
|
8727
|
+
const extra = rest.length ? `
|
|
8728
|
+
\u2026and ${rest.length} more \u2014 say 'more' to see them.` : "";
|
|
8729
|
+
const preamble = inKind.length ? "" : `nothing I remember ties these to "${whichCan[1]}", but:
|
|
8730
|
+
`;
|
|
8731
|
+
return { text: preamble + shown.join("\n") + extra, replace: true, ...rest.length ? { pending: { items: rest, noun: "facts" } } : {} };
|
|
8732
|
+
}
|
|
8733
|
+
}
|
|
8734
|
+
const canVerb = q.match(WHAT_CAN_VERB_RE);
|
|
8735
|
+
if (canVerb && canVerb[1].trim().split(/\s+/).at(-1)?.toLowerCase() !== "do") {
|
|
8736
|
+
const verbVariants = factTermVariants(normFactTerm2, canVerb[1]);
|
|
8737
|
+
const hits = (await factRows(memoryDir, cache)).filter((f) => f.predicate === "mgx:capableOf" && verbVariants.has(f.object));
|
|
8738
|
+
if (hits.length) {
|
|
8739
|
+
const ranked = rankByBiasThenTrust(uniqueFacts(hits), biasByBundle);
|
|
8740
|
+
const lines = ranked.map(renderFactLine);
|
|
8741
|
+
const shown = lines.slice(0, FACT_ANSWER_CAP);
|
|
8742
|
+
const rest = lines.slice(FACT_ANSWER_CAP);
|
|
8743
|
+
const extra = rest.length ? `
|
|
8744
|
+
\u2026and ${rest.length} more \u2014 say 'more' to see them.` : "";
|
|
8745
|
+
return { text: shown.join("\n") + extra, replace: true, ...rest.length ? { pending: { items: rest, noun: "facts" } } : {} };
|
|
8746
|
+
}
|
|
8747
|
+
}
|
|
8301
8748
|
const hasQ = q.match(WHAT_HAS_RE);
|
|
8302
8749
|
if (hasQ && !HAS_TEMPORAL_TAIL.has(hasQ[1].trim().split(/\s+/)[0]?.toLowerCase())) {
|
|
8303
8750
|
const variants = factTermVariants(normFactTerm2, hasQ[1]);
|
|
@@ -8413,6 +8860,9 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
8413
8860
|
return out;
|
|
8414
8861
|
}
|
|
8415
8862
|
async function factReadBack(memoryDir, query, envelope, miss2, graph = null, focusLabel = null, biasByBundle = {}, cache = null) {
|
|
8863
|
+
return withDeducedGoal(await factReadBackReaders(memoryDir, query, envelope, miss2, graph, focusLabel, biasByBundle, cache), envelope, query);
|
|
8864
|
+
}
|
|
8865
|
+
async function factReadBackReaders(memoryDir, query, envelope, miss2, graph = null, focusLabel = null, biasByBundle = {}, cache = null) {
|
|
8416
8866
|
if (!miss2) return null;
|
|
8417
8867
|
let normFactTerm2;
|
|
8418
8868
|
try {
|
|
@@ -8505,7 +8955,7 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
8505
8955
|
};
|
|
8506
8956
|
}
|
|
8507
8957
|
}
|
|
8508
|
-
const whoAsk = qHedge.match(RELATION_WHO_ASK_RE);
|
|
8958
|
+
const whoAsk = qHedge.match(RELATION_WHO_ASK_RE) || matchGenitiveWhoAsk(qHedge);
|
|
8509
8959
|
if (whoAsk) {
|
|
8510
8960
|
const relationName = whoAsk[1].trim().toLowerCase();
|
|
8511
8961
|
const rawObject = whoAsk[2].trim();
|
|
@@ -9050,7 +9500,7 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9050
9500
|
if (!hits.length) return null;
|
|
9051
9501
|
return renderMany(hits);
|
|
9052
9502
|
}
|
|
9053
|
-
var CONTEXT_WORDS, isPronoun, GOAL_BY_KIND, COMMANDS, COMMAND_WORDS, CLASS_LABELS, AMBIGUOUS_HAVE_VERBS, RESTRICTOR_VERB_RE, GREET, THANKS, BYE, OK_ACK, collapseRuns, GREET_COLLAPSED, THANKS_COLLAPSED, BYE_COLLAPSED, ACK_LEAD_RE, CONVERSATIONAL_PHRASES, COMPARATIVE_SRC, COMPARATIVE_TEACH_RE, COMPARATIVE_ASK_RE, PREP_SRC, OWNED_BY_PREDICATE, HAS_PROPERTY_PREDICATE, SUBCLASS_PREDICATE2,
|
|
9503
|
+
var CONTEXT_WORDS, isPronoun, GOAL_BY_KIND, goalNoun, TAUGHT_FACT_LOOKUP_GOAL, COMMANDS, COMMAND_WORDS, CLASS_LABELS, AMBIGUOUS_HAVE_VERBS, RESTRICTOR_VERB_RE, GREET, THANKS, BYE, OK_ACK, collapseRuns, GREET_COLLAPSED, THANKS_COLLAPSED, BYE_COLLAPSED, ACK_LEAD_RE, CONVERSATIONAL_PHRASES, COMPARATIVE_SRC, COMPARATIVE_TEACH_RE, COMPARATIVE_ASK_RE, PREP_SRC, OWNED_BY_PREDICATE, HAS_PROPERTY_PREDICATE, SUBCLASS_PREDICATE2, TAUGHT_SOURCE_TYPES, isOperatorTaught, ACTION_SIGNATURE_TEACH_RE, ACTION_SIGNATURE_PASSIVE_RE, ACTION_PRECOND_NOTHING_RE, ACTION_PRECOND_COMPARATIVE_RE, ACTION_EFFECT_TEACH_RE, ACTION_CONSTRAINT_TEACH_RE, GOAL_TEACH_RE, GOAL_TEACH_INFINITIVE_RE, TEACH_ADVERB_SKIP_SRC, GENERAL_VERB_TEACH_RE, GENERAL_VERB_EXCLUDE_RE, GENERAL_VERB_ANYWHERE_EXCLUDE_RE, GENERAL_VERB_NOT_A_VERB_RE, GENERAL_VERB_YESNO_RE, GENERAL_VERB_OPEN_RE, GENERAL_VERB_QUERY_EXCLUDE_RE, GENERAL_VERB_PREP_RE, TRAILING_ADVERB_RE, MODULE_ORIENT_RE, MODULE_ORIENT_SVO_RE, AUTHOR_NAME_SRC, AUTHOR_WHO_IS_RE, AUTHOR_TOUCHED_RE, OPINION_ADJ_SRC, OPINION_NUDGE_RE, PERSONAL_ASSISTANT_NUDGE_RE, PREDICATE_WORDS, FACT_PREDICATE_PHRASES, factPhrase, TRAILING_PREDICATE_MARKERS, GENERIC_ENTITY_WORDS, SYNONYM_DENYLIST, RELATION_FACT_YESNO_RE, RELATION_WHO_ASK_RE, GENITIVE_WHO_ASK_RE, RECURSIVE_LIST_ASK_RE, ISA_ASK_RE, ISA_PREDICATES, WHY_ISA_LEAD_RE, EXPLAIN_HOW_YOU_KNOW_RE, ISA_IDIOM_ROLE_WORDS, CONFIRM_TAG_RE, KNOW_ABOUT_RE, FACT_ANSWER_CAP, CAN_ASK_RE, DOES_HAVE_ASK_RE, WHAT_CAN_DO_RE, WHAT_HAS_RE, WHAT_USED_FOR_RE, WHERE_IS_FACT_RE, LOCATIVE_FACT_PREDICATE_RE, DO_VERB_ASK_RE, WHAT_CAN_VERB_RE, WHICH_KIND_CAN_RE, SUPERLATIVE_WORD_SRC, WHICH_KIND_SUPERLATIVE_RE, WHAT_IS_SUPERLATIVE_KIND_RE, REVERSE_PREDICATE_EXCLUDE, REVERSE_PREDICATE_MARKERS, FORWARD_YESNO_EXCLUDE, FORWARD_YESNO_MARKERS, WHAT_INHERITS_RE, HAS_TEMPORAL_TAIL, TOLD_ABOUT_RE, KIND_OF_RE, CARD_AT_LEAST_ASK_RE, CARD_EXISTENCE_ASK_RE, CARDINALITY_ROW_PREDICATES, WHO_OWNS_RE, OWNS_YESNO_RE, OWNS_PASSIVE_YESNO_RE, HAS_METHOD_YESNO_RE, HAS_METHOD_OPEN_RE, IS_ADJECTIVE_YESNO_RE, IS_ADJECTIVE_PRONOUN_RE, IS_ADJECTIVE_YESNO_PRONOUN_SUBJECT_RE, unknownAdjectiveOffer, WHOLE_RECALL_RE, INHERITS_GROUP_RE, INHERITS_MAX_HOPS, PRONOUN_IN_QUERY_RE, BARE_WHATIS_RE, DESCRIBE_GRAIN_WORD_RE, GOAL_BY_COMMAND, BASE_QUALIFIER_SRC, USES_AS_BASE_WH_ASK_RE, USES_AS_BASE_WHAT_FRONT_RE, USES_AS_BASE_YESNO_RE, USES_AS_BASE_TEACH_RE, SEED_MARKER_REL;
|
|
9054
9504
|
var init_chat = __esm({
|
|
9055
9505
|
"src/chat.mjs"() {
|
|
9056
9506
|
init_node_path();
|
|
@@ -9063,6 +9513,7 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9063
9513
|
init_config();
|
|
9064
9514
|
init_cli_args();
|
|
9065
9515
|
init_codegraph();
|
|
9516
|
+
init_ask();
|
|
9066
9517
|
init_sessions();
|
|
9067
9518
|
init_uuid();
|
|
9068
9519
|
init_telemetry();
|
|
@@ -9070,7 +9521,9 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9070
9521
|
init_templates();
|
|
9071
9522
|
init_extensions();
|
|
9072
9523
|
init_bias();
|
|
9524
|
+
init_core();
|
|
9073
9525
|
init_finish();
|
|
9526
|
+
init_sentences();
|
|
9074
9527
|
init_ask_vocab();
|
|
9075
9528
|
init_normalize();
|
|
9076
9529
|
init_fuzzy();
|
|
@@ -9091,6 +9544,8 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9091
9544
|
cochange: "understand change-coupling between modules",
|
|
9092
9545
|
reexports: "understand a module's public exports/API surface"
|
|
9093
9546
|
};
|
|
9547
|
+
goalNoun = (entityType) => entityType ? `${String(entityType).toLowerCase()}(s)` : "entities";
|
|
9548
|
+
TAUGHT_FACT_LOOKUP_GOAL = "look up a taught fact about a subject/verb/object";
|
|
9094
9549
|
COMMANDS = {
|
|
9095
9550
|
find: { tool: "tmct_search", arg: "query", help: "lexical search across the graph" },
|
|
9096
9551
|
search: { tool: "tmct_search", arg: "query", help: "alias of /find" },
|
|
@@ -9263,11 +9718,14 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9263
9718
|
OWNED_BY_PREDICATE = "mgx:ownedBy";
|
|
9264
9719
|
HAS_PROPERTY_PREDICATE = "mgx:hasProperty";
|
|
9265
9720
|
SUBCLASS_PREDICATE2 = "rdfs:subClassOf";
|
|
9266
|
-
HAS_A_PREDICATE = "mgx:hasA";
|
|
9267
9721
|
TAUGHT_SOURCE_TYPES = /* @__PURE__ */ new Set(["operator", "teach", "entailed"]);
|
|
9268
9722
|
isOperatorTaught = (f) => !!f.sourceTypes?.some((t) => TAUGHT_SOURCE_TYPES.has(t));
|
|
9269
9723
|
ACTION_SIGNATURE_TEACH_RE = new RegExp(
|
|
9270
|
-
`^you\\s+can\\s+([a-z]+)\\s+an?\\s+([a-z][\\w-]*)\\s+(${PREP_SRC})\\s+an?\\s+([a-z][\\w-]*)[.!?]*$`,
|
|
9724
|
+
`^you\\s+(?:can|may)\\s+([a-z]+)\\s+an?\\s+([a-z][\\w-]*)\\s+(${PREP_SRC})\\s+an?\\s+([a-z][\\w-]*)[.!?]*$`,
|
|
9725
|
+
"i"
|
|
9726
|
+
);
|
|
9727
|
+
ACTION_SIGNATURE_PASSIVE_RE = new RegExp(
|
|
9728
|
+
`^an?\\s+([a-z][\\w-]*)\\s+(?:can|may)\\s+be\\s+([a-z]+)\\s+(${PREP_SRC})\\s+an?\\s+([a-z][\\w-]*)[.!?]*$`,
|
|
9271
9729
|
"i"
|
|
9272
9730
|
);
|
|
9273
9731
|
ACTION_PRECOND_NOTHING_RE = new RegExp(
|
|
@@ -9279,7 +9737,19 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9279
9737
|
"i"
|
|
9280
9738
|
);
|
|
9281
9739
|
ACTION_EFFECT_TEACH_RE = new RegExp(
|
|
9282
|
-
`^([a-z]+ing)\\s+an?\\s+([a-z][\\w-]*)\\s+(${PREP_SRC})\\s+an?\\s+([a-z][\\w-]*)\\s+makes\\s+the\\s+([a-z][\\w-]*)\\s+([a-z]+)\\s+(${PREP_SRC})\\s+the\\s+([a-z][\\w-]*)[.!?]*$`,
|
|
9740
|
+
`^([a-z]+ing)\\s+an?\\s+([a-z][\\w-]*)\\s+(${PREP_SRC})\\s+an?\\s+([a-z][\\w-]*)\\s+makes\\s+(?:it|the\\s+([a-z][\\w-]*))\\s+([a-z]+)\\s+(${PREP_SRC})\\s+the\\s+([a-z][\\w-]*)[.!?]*$`,
|
|
9741
|
+
"i"
|
|
9742
|
+
);
|
|
9743
|
+
ACTION_CONSTRAINT_TEACH_RE = new RegExp(
|
|
9744
|
+
`^to\\s+([a-z]+)\\s+an?\\s+([a-z][\\w-]*)\\s+(${PREP_SRC})\\s+an?\\s+([a-z][\\w-]*)\\s*,?\\s*the\\s+([a-z][\\w-]*)\\s+may\\s+not\\s+be\\s+with\\s+the\\s+([a-z][\\w-]*)\\s+without\\s+the\\s+([a-z][\\w-]*)[.!?]*$`,
|
|
9745
|
+
"i"
|
|
9746
|
+
);
|
|
9747
|
+
GOAL_TEACH_RE = new RegExp(
|
|
9748
|
+
`^the\\s+goal\\s+is\\s+that\\s+(?:(every|each|all)\\s+)?([\\w-]+)\\s+([a-z]+s)\\s+(${PREP_SRC})\\s+([\\w-]+)[.!?]*$`,
|
|
9749
|
+
"i"
|
|
9750
|
+
);
|
|
9751
|
+
GOAL_TEACH_INFINITIVE_RE = new RegExp(
|
|
9752
|
+
`^(?:the\\s+goal\\s+is\\s+for|i\\s+want)\\s+(?:(every|each|all)\\s+)?([\\w-]+)\\s+to\\s+([a-z]+)\\s+(${PREP_SRC})\\s+([\\w-]+)[.!?]*$`,
|
|
9283
9753
|
"i"
|
|
9284
9754
|
);
|
|
9285
9755
|
TEACH_ADVERB_SKIP_SRC = "(?:(?:usually|often|sometimes|rarely|never|always|typically|generally|occasionally|frequently|normally|regularly|commonly|mostly|currently|still|also|really|actually)\\s+)?";
|
|
@@ -9407,6 +9877,7 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9407
9877
|
].map(([a, b]) => [a, b].sort().join("|")));
|
|
9408
9878
|
RELATION_FACT_YESNO_RE = /^(?:is|are|was|were)\s+([\w'-]+(?:\s+[A-Z][\w'-]*)?)\s+(?:the|an?)\s+([a-z][\w-]*)\s+of\s+([\w'-]+(?:\s+[A-Z][\w'-]*)?)[?.!\s]*$/i;
|
|
9409
9879
|
RELATION_WHO_ASK_RE = /^(?:who|what)\s+(?:is|are)\s+(?:the|an?)\s+([a-z][\w-]*)\s+of\s+([\w'-]+(?:\s+[A-Z][\w'-]*)?)[?.!\s]*$/i;
|
|
9880
|
+
GENITIVE_WHO_ASK_RE = /^(?:who|what)\s+(?:is|are|was|were)\s+([\w-]+(?:\s+[A-Z][\w-]*)?)'s\s+([a-z][\w-]*)[?.!\s]*$/i;
|
|
9410
9881
|
RECURSIVE_LIST_ASK_RE = /^list\s+(?:the\s+|all\s+)?([a-z][\w-]*)\s+of\s+([\w'-]+(?:\s+[A-Z][\w'-]*)?)[?.!\s]*$/i;
|
|
9411
9882
|
ISA_ASK_RE = /^(?:is|are)\s+(?:an?\s+)?(.+?)\s+(?:a\s+kind\s+of|a\s+type\s+of|an?)\s+(.+?)[?.!\s]*$/i;
|
|
9412
9883
|
ISA_PREDICATES = /* @__PURE__ */ new Set(["rdfs:subClassOf", "rdf:type"]);
|
|
@@ -9421,6 +9892,14 @@ ${shown.join("\n")}${extra}`, replace: true, ...rest.length ? { pending: { items
|
|
|
9421
9892
|
WHAT_CAN_DO_RE = /^what\s+can\s+(?:an?\s+)?(.+?)\s+do[?.!\s]*$/i;
|
|
9422
9893
|
WHAT_HAS_RE = /^what\s+has\s+(?:an?\s+)?(.+?)[?.!\s]*$/i;
|
|
9423
9894
|
WHAT_USED_FOR_RE = /^what\s+(?:(?:can\s+be|is)\s+used\s+for|is\s+for)\s+(.+?)[?.!\s]*$/i;
|
|
9895
|
+
WHERE_IS_FACT_RE = /^where(?:'s|\s+is|\s+are)\s+(.+?)(?:\s+now)?\s*[?.!]*$/i;
|
|
9896
|
+
LOCATIVE_FACT_PREDICATE_RE = /^mgx:[a-z]+-(?:on|in|at|inside|under|below|above|near|beside|behind|by)$/;
|
|
9897
|
+
DO_VERB_ASK_RE = /^(?:do|does)\s+(all\s+|every\s+)?(?:an?\s+|the\s+)?([\w'-]+(?:\s+[\w'-]+)*?)\s+([a-z-]+)[?.!\s]*$/i;
|
|
9898
|
+
WHAT_CAN_VERB_RE = /^what\s+can\s+(?!be\s)(.+?)[?.!\s]*$/i;
|
|
9899
|
+
WHICH_KIND_CAN_RE = /^(?:which|what)\s+([\w'-]+(?:\s+[\w'-]+)*?)\s+can\s+(.+?)[?.!\s]*$/i;
|
|
9900
|
+
SUPERLATIVE_WORD_SRC = "(?:most|least)\\s+[a-z][\\w-]*|[a-z][\\w-]*est|best|worst";
|
|
9901
|
+
WHICH_KIND_SUPERLATIVE_RE = new RegExp(`^which\\s+([\\w'-]+)\\s+(?:is|are)\\s+(?:the\\s+)?(${SUPERLATIVE_WORD_SRC})[?.!\\s]*$`, "i");
|
|
9902
|
+
WHAT_IS_SUPERLATIVE_KIND_RE = new RegExp(`^what(?:'s|s|\\s+is)\\s+the\\s+(${SUPERLATIVE_WORD_SRC})\\s+([\\w'-]+)[?.!\\s]*$`, "i");
|
|
9424
9903
|
REVERSE_PREDICATE_EXCLUDE = /* @__PURE__ */ new Set([
|
|
9425
9904
|
"rdfs:subClassOf",
|
|
9426
9905
|
"rdf:type",
|