@nxuss/lemma 1.38.0 → 1.39.0
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 +3 -4
- package/bin/brain-ingest.js +68 -31
- package/bin/init.js +25 -28
- package/dashboard/dist/assets/index-DNTQXLER.css +1 -0
- package/dashboard/dist/assets/index-DzL_Zu3m.js +452 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/cjs/cli/gitHooks.d.ts +9 -2
- package/dist/cjs/cli/gitHooks.d.ts.map +1 -1
- package/dist/cjs/cli/gitHooks.js +31 -4
- package/dist/cjs/cli/gitHooks.js.map +1 -1
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +21 -1
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/infra/analyzers/index.d.ts +0 -2
- package/dist/cjs/infra/analyzers/index.d.ts.map +1 -1
- package/dist/cjs/infra/analyzers/index.js +1 -6
- package/dist/cjs/infra/analyzers/index.js.map +1 -1
- package/dist/cjs/infra/cli.d.ts +4 -0
- package/dist/cjs/infra/cli.d.ts.map +1 -1
- package/dist/cjs/infra/cli.js +6 -199
- package/dist/cjs/infra/cli.js.map +1 -1
- package/dist/cjs/infra/index.d.ts +1 -3
- package/dist/cjs/infra/index.d.ts.map +1 -1
- package/dist/cjs/infra/index.js +1 -16
- package/dist/cjs/infra/index.js.map +1 -1
- package/dist/cjs/infra/mcp-tools.d.ts.map +1 -1
- package/dist/cjs/infra/mcp-tools.js +8 -453
- package/dist/cjs/infra/mcp-tools.js.map +1 -1
- package/dist/cjs/infra/types.d.ts +0 -101
- package/dist/cjs/infra/types.d.ts.map +1 -1
- package/dist/cjs/infra/types.js +2 -1
- package/dist/cjs/infra/types.js.map +1 -1
- package/dist/cjs/mcp/prompts.d.ts +1 -1
- package/dist/cjs/mcp/prompts.d.ts.map +1 -1
- package/dist/cjs/mcp/prompts.js +8 -23
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/tool-profiles.d.ts +8 -3
- package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/cjs/mcp/tool-profiles.js +25 -54
- package/dist/cjs/mcp/tool-profiles.js.map +1 -1
- package/dist/cjs/mcp/tools/memory.d.ts +8 -0
- package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/memory.js +154 -125
- package/dist/cjs/mcp/tools/memory.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +11 -6
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/mcp/workspaceShared.d.ts.map +1 -1
- package/dist/cjs/mcp/workspaceShared.js +8 -4
- package/dist/cjs/mcp/workspaceShared.js.map +1 -1
- package/dist/cjs/proxy/ProjectRegistry.d.ts +20 -0
- package/dist/cjs/proxy/ProjectRegistry.d.ts.map +1 -1
- package/dist/cjs/proxy/ProjectRegistry.js +46 -4
- package/dist/cjs/proxy/ProjectRegistry.js.map +1 -1
- package/dist/cjs/subconscious/HostRecall.d.ts +26 -2
- package/dist/cjs/subconscious/HostRecall.d.ts.map +1 -1
- package/dist/cjs/subconscious/HostRecall.js +101 -36
- package/dist/cjs/subconscious/HostRecall.js.map +1 -1
- package/dist/cjs/subconscious/NarrowEvidence.d.ts +47 -0
- package/dist/cjs/subconscious/NarrowEvidence.d.ts.map +1 -0
- package/dist/cjs/subconscious/NarrowEvidence.js +252 -0
- package/dist/cjs/subconscious/NarrowEvidence.js.map +1 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts +37 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.js +147 -15
- package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
- package/dist/cjs/subconscious/freshness/LocalFsResolver.d.ts.map +1 -1
- package/dist/cjs/subconscious/freshness/LocalFsResolver.js +17 -0
- package/dist/cjs/subconscious/freshness/LocalFsResolver.js.map +1 -1
- package/dist/cjs/subconscious/recallDigest.d.ts +8 -0
- package/dist/cjs/subconscious/recallDigest.d.ts.map +1 -1
- package/dist/cjs/subconscious/recallDigest.js +13 -1
- package/dist/cjs/subconscious/recallDigest.js.map +1 -1
- package/dist/cjs/utils/OtherLanguageSymbols.d.ts +31 -0
- package/dist/cjs/utils/OtherLanguageSymbols.d.ts.map +1 -0
- package/dist/cjs/utils/OtherLanguageSymbols.js +283 -0
- package/dist/cjs/utils/OtherLanguageSymbols.js.map +1 -0
- package/dist/cjs/utils/SavingsLedger.d.ts +27 -0
- package/dist/cjs/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/cjs/utils/SavingsLedger.js +51 -0
- package/dist/cjs/utils/SavingsLedger.js.map +1 -1
- package/dist/cjs/utils/StoreDraft.d.ts +12 -0
- package/dist/cjs/utils/StoreDraft.d.ts.map +1 -1
- package/dist/cjs/utils/StoreDraft.js +53 -1
- package/dist/cjs/utils/StoreDraft.js.map +1 -1
- package/dist/cjs/utils/SymbolSurgicalContext.d.ts +2 -0
- package/dist/cjs/utils/SymbolSurgicalContext.d.ts.map +1 -1
- package/dist/cjs/utils/SymbolSurgicalContext.js +1 -0
- package/dist/cjs/utils/SymbolSurgicalContext.js.map +1 -1
- package/dist/cjs/utils/reportSavings.d.ts +17 -4
- package/dist/cjs/utils/reportSavings.d.ts.map +1 -1
- package/dist/cjs/utils/reportSavings.js +67 -22
- package/dist/cjs/utils/reportSavings.js.map +1 -1
- package/dist/esm/cli/gitHooks.d.ts +9 -2
- package/dist/esm/cli/gitHooks.d.ts.map +1 -1
- package/dist/esm/cli/gitHooks.js +31 -4
- package/dist/esm/cli/gitHooks.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +21 -1
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/infra/analyzers/index.d.ts +0 -2
- package/dist/esm/infra/analyzers/index.d.ts.map +1 -1
- package/dist/esm/infra/analyzers/index.js +0 -2
- package/dist/esm/infra/analyzers/index.js.map +1 -1
- package/dist/esm/infra/cli.d.ts +4 -0
- package/dist/esm/infra/cli.d.ts.map +1 -1
- package/dist/esm/infra/cli.js +6 -199
- package/dist/esm/infra/cli.js.map +1 -1
- package/dist/esm/infra/index.d.ts +1 -3
- package/dist/esm/infra/index.d.ts.map +1 -1
- package/dist/esm/infra/index.js +1 -3
- package/dist/esm/infra/index.js.map +1 -1
- package/dist/esm/infra/mcp-tools.d.ts.map +1 -1
- package/dist/esm/infra/mcp-tools.js +9 -454
- package/dist/esm/infra/mcp-tools.js.map +1 -1
- package/dist/esm/infra/types.d.ts +0 -101
- package/dist/esm/infra/types.d.ts.map +1 -1
- package/dist/esm/infra/types.js +2 -1
- package/dist/esm/infra/types.js.map +1 -1
- package/dist/esm/mcp/prompts.d.ts +1 -1
- package/dist/esm/mcp/prompts.d.ts.map +1 -1
- package/dist/esm/mcp/prompts.js +8 -23
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/tool-profiles.d.ts +8 -3
- package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/esm/mcp/tool-profiles.js +25 -54
- package/dist/esm/mcp/tool-profiles.js.map +1 -1
- package/dist/esm/mcp/tools/memory.d.ts +8 -0
- package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
- package/dist/esm/mcp/tools/memory.js +156 -128
- package/dist/esm/mcp/tools/memory.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +12 -7
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/mcp/workspaceShared.d.ts.map +1 -1
- package/dist/esm/mcp/workspaceShared.js +9 -5
- package/dist/esm/mcp/workspaceShared.js.map +1 -1
- package/dist/esm/proxy/ProjectRegistry.d.ts +20 -0
- package/dist/esm/proxy/ProjectRegistry.d.ts.map +1 -1
- package/dist/esm/proxy/ProjectRegistry.js +45 -3
- package/dist/esm/proxy/ProjectRegistry.js.map +1 -1
- package/dist/esm/subconscious/HostRecall.d.ts +26 -2
- package/dist/esm/subconscious/HostRecall.d.ts.map +1 -1
- package/dist/esm/subconscious/HostRecall.js +99 -37
- package/dist/esm/subconscious/HostRecall.js.map +1 -1
- package/dist/esm/subconscious/NarrowEvidence.d.ts +47 -0
- package/dist/esm/subconscious/NarrowEvidence.d.ts.map +1 -0
- package/dist/esm/subconscious/NarrowEvidence.js +211 -0
- package/dist/esm/subconscious/NarrowEvidence.js.map +1 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts +37 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.js +146 -14
- package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
- package/dist/esm/subconscious/freshness/LocalFsResolver.d.ts.map +1 -1
- package/dist/esm/subconscious/freshness/LocalFsResolver.js +17 -0
- package/dist/esm/subconscious/freshness/LocalFsResolver.js.map +1 -1
- package/dist/esm/subconscious/recallDigest.d.ts +8 -0
- package/dist/esm/subconscious/recallDigest.d.ts.map +1 -1
- package/dist/esm/subconscious/recallDigest.js +12 -1
- package/dist/esm/subconscious/recallDigest.js.map +1 -1
- package/dist/esm/utils/OtherLanguageSymbols.d.ts +31 -0
- package/dist/esm/utils/OtherLanguageSymbols.d.ts.map +1 -0
- package/dist/esm/utils/OtherLanguageSymbols.js +275 -0
- package/dist/esm/utils/OtherLanguageSymbols.js.map +1 -0
- package/dist/esm/utils/SavingsLedger.d.ts +27 -0
- package/dist/esm/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/esm/utils/SavingsLedger.js +51 -0
- package/dist/esm/utils/SavingsLedger.js.map +1 -1
- package/dist/esm/utils/StoreDraft.d.ts +12 -0
- package/dist/esm/utils/StoreDraft.d.ts.map +1 -1
- package/dist/esm/utils/StoreDraft.js +52 -1
- package/dist/esm/utils/StoreDraft.js.map +1 -1
- package/dist/esm/utils/SymbolSurgicalContext.d.ts +2 -0
- package/dist/esm/utils/SymbolSurgicalContext.d.ts.map +1 -1
- package/dist/esm/utils/SymbolSurgicalContext.js +1 -1
- package/dist/esm/utils/SymbolSurgicalContext.js.map +1 -1
- package/dist/esm/utils/reportSavings.d.ts +17 -4
- package/dist/esm/utils/reportSavings.d.ts.map +1 -1
- package/dist/esm/utils/reportSavings.js +65 -22
- package/dist/esm/utils/reportSavings.js.map +1 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/index-CLXWgzTm.css +0 -1
- package/dashboard/dist/assets/index-CoMIMxyC.js +0 -451
- package/dist/cjs/infra/analyzers/DriftDetector.d.ts +0 -4
- package/dist/cjs/infra/analyzers/DriftDetector.d.ts.map +0 -1
- package/dist/cjs/infra/analyzers/DriftDetector.js +0 -88
- package/dist/cjs/infra/analyzers/DriftDetector.js.map +0 -1
- package/dist/cjs/infra/analyzers/InfraAnalyzer.d.ts +0 -3
- package/dist/cjs/infra/analyzers/InfraAnalyzer.d.ts.map +0 -1
- package/dist/cjs/infra/analyzers/InfraAnalyzer.js +0 -73
- package/dist/cjs/infra/analyzers/InfraAnalyzer.js.map +0 -1
- package/dist/cjs/infra/config.d.ts +0 -17
- package/dist/cjs/infra/config.d.ts.map +0 -1
- package/dist/cjs/infra/config.js +0 -111
- package/dist/cjs/infra/config.js.map +0 -1
- package/dist/cjs/infra/errorCause.d.ts +0 -36
- package/dist/cjs/infra/errorCause.d.ts.map +0 -1
- package/dist/cjs/infra/errorCause.js +0 -143
- package/dist/cjs/infra/errorCause.js.map +0 -1
- package/dist/cjs/infra/providers/InfraProvider.d.ts +0 -9
- package/dist/cjs/infra/providers/InfraProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/InfraProvider.js +0 -3
- package/dist/cjs/infra/providers/InfraProvider.js.map +0 -1
- package/dist/cjs/infra/providers/JenkinsProvider.d.ts +0 -16
- package/dist/cjs/infra/providers/JenkinsProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/JenkinsProvider.js +0 -193
- package/dist/cjs/infra/providers/JenkinsProvider.js.map +0 -1
- package/dist/cjs/infra/providers/OKDProvider.d.ts +0 -24
- package/dist/cjs/infra/providers/OKDProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/OKDProvider.js +0 -296
- package/dist/cjs/infra/providers/OKDProvider.js.map +0 -1
- package/dist/cjs/infra/providers/TerraformProvider.d.ts +0 -17
- package/dist/cjs/infra/providers/TerraformProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/TerraformProvider.js +0 -111
- package/dist/cjs/infra/providers/TerraformProvider.js.map +0 -1
- package/dist/cjs/infra/providers/index.d.ts +0 -9
- package/dist/cjs/infra/providers/index.d.ts.map +0 -1
- package/dist/cjs/infra/providers/index.js +0 -34
- package/dist/cjs/infra/providers/index.js.map +0 -1
- package/dist/cjs/infra/templates/jenkins/index.d.ts +0 -15
- package/dist/cjs/infra/templates/jenkins/index.d.ts.map +0 -1
- package/dist/cjs/infra/templates/jenkins/index.js +0 -128
- package/dist/cjs/infra/templates/jenkins/index.js.map +0 -1
- package/dist/cjs/infra/templates/okd/index.d.ts +0 -31
- package/dist/cjs/infra/templates/okd/index.d.ts.map +0 -1
- package/dist/cjs/infra/templates/okd/index.js +0 -149
- package/dist/cjs/infra/templates/okd/index.js.map +0 -1
- package/dist/esm/infra/analyzers/DriftDetector.d.ts +0 -4
- package/dist/esm/infra/analyzers/DriftDetector.d.ts.map +0 -1
- package/dist/esm/infra/analyzers/DriftDetector.js +0 -84
- package/dist/esm/infra/analyzers/DriftDetector.js.map +0 -1
- package/dist/esm/infra/analyzers/InfraAnalyzer.d.ts +0 -3
- package/dist/esm/infra/analyzers/InfraAnalyzer.d.ts.map +0 -1
- package/dist/esm/infra/analyzers/InfraAnalyzer.js +0 -70
- package/dist/esm/infra/analyzers/InfraAnalyzer.js.map +0 -1
- package/dist/esm/infra/config.d.ts +0 -17
- package/dist/esm/infra/config.d.ts.map +0 -1
- package/dist/esm/infra/config.js +0 -101
- package/dist/esm/infra/config.js.map +0 -1
- package/dist/esm/infra/errorCause.d.ts +0 -36
- package/dist/esm/infra/errorCause.d.ts.map +0 -1
- package/dist/esm/infra/errorCause.js +0 -138
- package/dist/esm/infra/errorCause.js.map +0 -1
- package/dist/esm/infra/providers/InfraProvider.d.ts +0 -9
- package/dist/esm/infra/providers/InfraProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/InfraProvider.js +0 -2
- package/dist/esm/infra/providers/InfraProvider.js.map +0 -1
- package/dist/esm/infra/providers/JenkinsProvider.d.ts +0 -16
- package/dist/esm/infra/providers/JenkinsProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/JenkinsProvider.js +0 -186
- package/dist/esm/infra/providers/JenkinsProvider.js.map +0 -1
- package/dist/esm/infra/providers/OKDProvider.d.ts +0 -24
- package/dist/esm/infra/providers/OKDProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/OKDProvider.js +0 -292
- package/dist/esm/infra/providers/OKDProvider.js.map +0 -1
- package/dist/esm/infra/providers/TerraformProvider.d.ts +0 -17
- package/dist/esm/infra/providers/TerraformProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/TerraformProvider.js +0 -107
- package/dist/esm/infra/providers/TerraformProvider.js.map +0 -1
- package/dist/esm/infra/providers/index.d.ts +0 -9
- package/dist/esm/infra/providers/index.d.ts.map +0 -1
- package/dist/esm/infra/providers/index.js +0 -27
- package/dist/esm/infra/providers/index.js.map +0 -1
- package/dist/esm/infra/templates/jenkins/index.d.ts +0 -15
- package/dist/esm/infra/templates/jenkins/index.d.ts.map +0 -1
- package/dist/esm/infra/templates/jenkins/index.js +0 -124
- package/dist/esm/infra/templates/jenkins/index.js.map +0 -1
- package/dist/esm/infra/templates/okd/index.d.ts +0 -31
- package/dist/esm/infra/templates/okd/index.d.ts.map +0 -1
- package/dist/esm/infra/templates/okd/index.js +0 -142
- package/dist/esm/infra/templates/okd/index.js.map +0 -1
|
@@ -631,6 +631,14 @@ export function tokenize(text) {
|
|
|
631
631
|
'cada', 'otra', 'otro', 'otras', 'otros', 'entre', 'sobre', 'sin', 'ya', 'tan', 'mas',
|
|
632
632
|
'lo', 'le', 'les', 'nos', 'os', 'ni', 'sino', 'porque', 'cuando', 'donde', 'quien',
|
|
633
633
|
'cual', 'cuales', 'sea', 'ha', 'han', 'hemos', 'habia', 'habían', 'esta', 'están',
|
|
634
|
+
// Conversational filler. Prompts are written to a person ("can you please help me…",
|
|
635
|
+
// "necesito que realmente…"), and these words outweighed the topic when measuring how much
|
|
636
|
+
// of a prompt a memory covers. They name no subject a memory could be about.
|
|
637
|
+
'please', 'help', 'know', 'want', 'like', 'just', 'really', 'actually', 'maybe', 'also', 'let',
|
|
638
|
+
'me', 'my', 'we', 'our', 'us', 'you', 'your', 'i', 'im', 'get', 'got', 'make', 'sure', 'thing', 'things',
|
|
639
|
+
'por', 'favor', 'necesito', 'quiero', 'puedes', 'podemos', 'podrias', 'haz', 'hacer', 'dime', 'ayuda',
|
|
640
|
+
'ayudame', 'realmente', 'actualmente', 'tambien', 'solo', 'algo', 'cosa', 'cosas', 'nos', 'tu', 'yo',
|
|
641
|
+
'me', 'mi', 'mis', 'te', 'ver', 'bien',
|
|
634
642
|
]);
|
|
635
643
|
const terms = normalized
|
|
636
644
|
.split(/\s+/)
|
|
@@ -652,7 +660,25 @@ export function tokenize(text) {
|
|
|
652
660
|
const synonymTags = terms
|
|
653
661
|
.map(t => SYNONYM_CLUSTERS.get(t))
|
|
654
662
|
.filter((c) => c !== undefined);
|
|
655
|
-
|
|
663
|
+
// 8. English/Spanish cognates share a root once their suffix is dropped: "description" and
|
|
664
|
+
// "descripcion", "configuration"/"configuracion", "velocity"/"velocidad", "automatic"/
|
|
665
|
+
// "automatico". Same additive rule as stems and synonyms.
|
|
666
|
+
const cognateTags = terms.map(cognate).filter((c) => c !== undefined);
|
|
667
|
+
return [...new Set([...terms, ...bigrams, ...stems, ...synonymTags, ...cognateTags])];
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Bump whenever tokenize() changes what it emits. Terms are computed once, at store time, and
|
|
671
|
+
* persisted, so a tokenizer improvement (stems, diacritics, synonym groups) used to reach new
|
|
672
|
+
* memories only — every memory already in the Brain kept the vocabulary it was stored with.
|
|
673
|
+
* rebuildIndex() re-tokenizes any entry indexed under another version.
|
|
674
|
+
*/
|
|
675
|
+
export const TOKENIZER_VERSION = 6;
|
|
676
|
+
/** (Re)computes an entry's index terms with the current tokenizer. */
|
|
677
|
+
function indexTerms(entry) {
|
|
678
|
+
const terms = tokenize(`${entry.query} ${entry.response || ''}`);
|
|
679
|
+
entry.terms = [...new Set(terms)];
|
|
680
|
+
entry.termFreq = termFrequencies(terms);
|
|
681
|
+
entry.tokv = TOKENIZER_VERSION;
|
|
656
682
|
}
|
|
657
683
|
// Groups of interchangeable dev-vocabulary terms (bilingual). Each member maps to a shared
|
|
658
684
|
// `syn_<canonical>` token so any two synonyms in the same group become a shared index bucket
|
|
@@ -662,14 +688,43 @@ export function tokenize(text) {
|
|
|
662
688
|
const SYNONYM_GROUPS = [
|
|
663
689
|
['jwt', 'token', 'session', 'auth', 'login', 'autenticacion', 'sesion', 'autenticar'],
|
|
664
690
|
['timeout', 'expiration', 'expiry', 'vencimiento', 'caducidad', 'expirar', 'vencer'],
|
|
665
|
-
['bug', 'error', 'fallo', 'falla', 'issue', 'defect', 'defecto'],
|
|
691
|
+
['bug', 'error', 'fallo', 'falla', 'issue', 'defect', 'defecto', 'fail', 'fails', 'failing', 'failed', 'fallar', 'fallaba'],
|
|
666
692
|
['fix', 'patch', 'solucion', 'solucionar', 'arreglar', 'corregir', 'hotfix'],
|
|
667
693
|
['delete', 'remove', 'eliminar', 'borrar', 'quitar'],
|
|
668
694
|
['config', 'configuration', 'configuracion', 'settings', 'ajustes'],
|
|
669
695
|
['deploy', 'deployment', 'despliegue', 'desplegar', 'release'],
|
|
670
|
-
['crash', 'exception', 'excepcion', 'throw'
|
|
696
|
+
['crash', 'exception', 'excepcion', 'throw'],
|
|
671
697
|
['slow', 'lento', 'lentitud', 'latency', 'latencia', 'performance', 'rendimiento'],
|
|
672
698
|
['test', 'tests', 'testing', 'prueba', 'pruebas', 'spec'],
|
|
699
|
+
// Everyday words a bilingual corpus splits across languages: a Spanish memory and an English
|
|
700
|
+
// question about the same thing otherwise share no term at all.
|
|
701
|
+
['change', 'changes', 'changed', 'cambio', 'cambios', 'cambiar', 'cambia', 'cambiado'],
|
|
702
|
+
['active', 'activo', 'activos', 'activa', 'activas', 'enabled', 'habilitado'],
|
|
703
|
+
['file', 'files', 'archivo', 'archivos', 'fichero'],
|
|
704
|
+
['search', 'searches', 'buscar', 'busqueda', 'busca', 'find'],
|
|
705
|
+
['memory', 'memories', 'memoria', 'memorias'],
|
|
706
|
+
['write', 'writes', 'escribir', 'escribe', 'escritura'],
|
|
707
|
+
['read', 'reads', 'leer', 'lee', 'lectura', 'lecturas'],
|
|
708
|
+
['build', 'compile', 'compilar', 'compila', 'compilacion'],
|
|
709
|
+
['publish', 'published', 'publicar', 'publicado', 'publicada', 'publicacion'],
|
|
710
|
+
['comment', 'comments', 'comentario', 'comentarios'],
|
|
711
|
+
['string', 'strings', 'cadena', 'cadenas'],
|
|
712
|
+
['server', 'servidor'],
|
|
713
|
+
['tool', 'tools', 'herramienta', 'herramientas'],
|
|
714
|
+
['project', 'projects', 'proyecto', 'proyectos'],
|
|
715
|
+
['broken', 'breaks', 'roto', 'rota', 'rompe', 'romper', 'rompia'],
|
|
716
|
+
['missing', 'falta', 'faltante', 'faltaba'],
|
|
717
|
+
['ignore', 'ignored', 'ignores', 'ignora', 'ignorar', 'ignorado', 'ignoraba'],
|
|
718
|
+
['update', 'updated', 'actualizar', 'actualiza', 'actualizacion'],
|
|
719
|
+
['stale', 'outdated', 'desactualizado', 'desactualizada', 'obsoleto', 'obsoleta'],
|
|
720
|
+
['restart', 'reconnect', 'reiniciar', 'reconectar'],
|
|
721
|
+
['wrong', 'incorrect', 'incorrecto', 'incorrecta', 'erroneo'],
|
|
722
|
+
// Money vocabulary: "¿por qué el saldo sale negativo?" shared only "negativo" with the memory
|
|
723
|
+
// that answers it ("why the ledger was negative") — and that with every "falso negativo".
|
|
724
|
+
['ledger', 'saldo', 'balance', 'bitacora'],
|
|
725
|
+
['negative', 'negativo', 'negativa', 'negativos', 'negativas'],
|
|
726
|
+
['cost', 'costs', 'costo', 'costos', 'gasto', 'gastos', 'spent', 'spend', 'charge', 'charged', 'cobro', 'cobrar', 'cobrado', 'cobraba'],
|
|
727
|
+
['savings', 'saving', 'saved', 'ahorro', 'ahorros', 'ahorrar', 'ahorra'],
|
|
673
728
|
];
|
|
674
729
|
const SYNONYM_CLUSTERS = new Map();
|
|
675
730
|
for (const group of SYNONYM_GROUPS) {
|
|
@@ -677,6 +732,24 @@ for (const group of SYNONYM_GROUPS) {
|
|
|
677
732
|
for (const member of group)
|
|
678
733
|
SYNONYM_CLUSTERS.set(member, canonical);
|
|
679
734
|
}
|
|
735
|
+
const COGNATE_RULES = [
|
|
736
|
+
[/(?:tions?|ciones|cion)$/, 'tion'],
|
|
737
|
+
[/(?:ities|ity|idades|idad)$/, 'ity'],
|
|
738
|
+
[/(?:ically|icamente)$/, 'ic'],
|
|
739
|
+
[/(?:ics?|icos?|icas?)$/, 'ic'],
|
|
740
|
+
];
|
|
741
|
+
/** `cog_<root><suffix>` for a word with an English/Spanish cognate suffix, else undefined. */
|
|
742
|
+
function cognate(term) {
|
|
743
|
+
if (term.length < 6 || term.includes('_'))
|
|
744
|
+
return undefined;
|
|
745
|
+
for (const [re, kind] of COGNATE_RULES) {
|
|
746
|
+
if (re.test(term)) {
|
|
747
|
+
const root = term.replace(re, '');
|
|
748
|
+
return root.length >= 3 ? `cog_${root}_${kind}` : undefined;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return undefined;
|
|
752
|
+
}
|
|
680
753
|
// Suffix-stripping rules, longest/most-specific match first. Additive expansion only —
|
|
681
754
|
// this is not a correctness-critical stemmer, so mild over-stemming (merging two distinct
|
|
682
755
|
// words into one stem) is an acceptable recall/precision trade: it can only ever add a
|
|
@@ -1289,7 +1362,9 @@ export class TheBrainV2 {
|
|
|
1289
1362
|
// index.json. It is a pure derivation of the entries, so reconstructing it is the
|
|
1290
1363
|
// only way it can never disagree with them — and a stale or half-written index.json
|
|
1291
1364
|
// used to be able to hide entries from search entirely while they sat on disk intact.
|
|
1292
|
-
|
|
1365
|
+
// Entries indexed by an older tokenizer were re-tokenized: write that back once.
|
|
1366
|
+
if (this.rebuildIndex() > 0)
|
|
1367
|
+
this.scheduleSave();
|
|
1293
1368
|
this.recalcAvgDocLength();
|
|
1294
1369
|
}
|
|
1295
1370
|
catch (err) {
|
|
@@ -1315,7 +1390,12 @@ export class TheBrainV2 {
|
|
|
1315
1390
|
// A merge can replace an id's entry with a peer's newer version whose query differs, so
|
|
1316
1391
|
// the memo is rebuilt alongside the index rather than trusted across one.
|
|
1317
1392
|
this.queryTermCache.clear();
|
|
1393
|
+
let retokenized = 0;
|
|
1318
1394
|
for (const entry of this.entries.values()) {
|
|
1395
|
+
if (entry.tokv !== TOKENIZER_VERSION) {
|
|
1396
|
+
indexTerms(entry);
|
|
1397
|
+
retokenized++;
|
|
1398
|
+
}
|
|
1319
1399
|
for (const term of entry.terms) {
|
|
1320
1400
|
let ids = this.invertedIndex.get(term);
|
|
1321
1401
|
if (!ids) {
|
|
@@ -1325,6 +1405,7 @@ export class TheBrainV2 {
|
|
|
1325
1405
|
ids.add(entry.id);
|
|
1326
1406
|
}
|
|
1327
1407
|
}
|
|
1408
|
+
return retokenized;
|
|
1328
1409
|
}
|
|
1329
1410
|
/**
|
|
1330
1411
|
* Pull in anything another process wrote since we last touched the corpus.
|
|
@@ -1623,6 +1704,7 @@ export class TheBrainV2 {
|
|
|
1623
1704
|
response: response.trim(),
|
|
1624
1705
|
terms: [...new Set(terms)],
|
|
1625
1706
|
termFreq,
|
|
1707
|
+
tokv: TOKENIZER_VERSION,
|
|
1626
1708
|
provider,
|
|
1627
1709
|
timestamp: options.timestamp || new Date().toISOString(),
|
|
1628
1710
|
hits: 0,
|
|
@@ -1734,17 +1816,15 @@ export class TheBrainV2 {
|
|
|
1734
1816
|
}
|
|
1735
1817
|
// 2b. Scope to the calling project. Entries with no projectId predate scoping and stay
|
|
1736
1818
|
// visible everywhere — dropping a user's existing memories to enforce a new field would
|
|
1737
|
-
// look exactly like the Brain losing data
|
|
1738
|
-
//
|
|
1739
|
-
|
|
1740
|
-
|
|
1819
|
+
// look exactly like the Brain losing data — but they are labelled 'unscoped' in the result.
|
|
1820
|
+
// Another project's memories are never returned unless the caller asks for allProjects:
|
|
1821
|
+
// this used to fall back to every project's candidates whenever the caller's own had none,
|
|
1822
|
+
// so a project with an empty Brain was answered from someone else's.
|
|
1823
|
+
if (options.projectId && !options.allProjects) {
|
|
1824
|
+
for (const id of [...candidateIds]) {
|
|
1741
1825
|
const owner = this.entries.get(id)?.projectId;
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
if (scoped.size > 0 || options.strictProject) {
|
|
1745
|
-
candidateIds.clear();
|
|
1746
|
-
for (const id of scoped)
|
|
1747
|
-
candidateIds.add(id);
|
|
1826
|
+
if (owner !== undefined && owner !== options.projectId)
|
|
1827
|
+
candidateIds.delete(id);
|
|
1748
1828
|
}
|
|
1749
1829
|
}
|
|
1750
1830
|
if (candidateIds.size === 0) {
|
|
@@ -1890,6 +1970,11 @@ export class TheBrainV2 {
|
|
|
1890
1970
|
...(r.entry.outcome ? { outcome: r.entry.outcome } : {}),
|
|
1891
1971
|
...(claims && claims.length > 0 ? { claims } : {}),
|
|
1892
1972
|
...(r.entry.domain ? { domain: r.entry.domain } : {}),
|
|
1973
|
+
...(r.entry.projectId === undefined
|
|
1974
|
+
? { scope: 'unscoped' }
|
|
1975
|
+
: options.projectId && r.entry.projectId !== options.projectId
|
|
1976
|
+
? { scope: 'other-project', ownerProject: r.entry.projectId }
|
|
1977
|
+
: {}),
|
|
1893
1978
|
...(cosmeticChanges && cosmeticChanges.length > 0 ? { cosmeticChanges } : {}),
|
|
1894
1979
|
};
|
|
1895
1980
|
});
|
|
@@ -1979,6 +2064,36 @@ export class TheBrainV2 {
|
|
|
1979
2064
|
}
|
|
1980
2065
|
return results;
|
|
1981
2066
|
}
|
|
2067
|
+
/**
|
|
2068
|
+
* Give memories stored before projects existed to the project their evidence lives in.
|
|
2069
|
+
*
|
|
2070
|
+
* An unscoped memory is visible to every project, so one project's notes surface in another's
|
|
2071
|
+
* searches. When all the code it tracks sits inside `root`, there is no doubt whose it is, and
|
|
2072
|
+
* it is stamped with `projectId`. A memory that tracks nothing, or tracks files outside `root`,
|
|
2073
|
+
* is left alone: nothing proves who it belongs to, and guessing would hide it from the project
|
|
2074
|
+
* that does own it. Returns how many were adopted.
|
|
2075
|
+
*/
|
|
2076
|
+
adoptUnscopedByEvidence(projectId, root) {
|
|
2077
|
+
const base = root.endsWith(path.sep) ? root : root + path.sep;
|
|
2078
|
+
let adopted = 0;
|
|
2079
|
+
for (const entry of this.entries.values()) {
|
|
2080
|
+
if (entry.projectId !== undefined)
|
|
2081
|
+
continue;
|
|
2082
|
+
const tracked = [
|
|
2083
|
+
...Object.keys(entry.fileHashes || {}),
|
|
2084
|
+
...Object.keys(entry.symbolHashes || {}).map((k) => k.substring(0, k.lastIndexOf('::'))),
|
|
2085
|
+
];
|
|
2086
|
+
if (tracked.length === 0)
|
|
2087
|
+
continue;
|
|
2088
|
+
if (!tracked.every((abs) => path.resolve(abs).startsWith(base)))
|
|
2089
|
+
continue;
|
|
2090
|
+
entry.projectId = projectId;
|
|
2091
|
+
adopted++;
|
|
2092
|
+
}
|
|
2093
|
+
if (adopted > 0)
|
|
2094
|
+
this.scheduleSave();
|
|
2095
|
+
return adopted;
|
|
2096
|
+
}
|
|
1982
2097
|
embeddingSidecar() {
|
|
1983
2098
|
if (!this.sidecar)
|
|
1984
2099
|
this.sidecar = new EmbeddingSidecar(EMBEDDINGS_FILE);
|
|
@@ -2092,6 +2207,21 @@ export class TheBrainV2 {
|
|
|
2092
2207
|
* whether a reuse happened. Unknown ids fail silently (a peer may have forgotten the
|
|
2093
2208
|
* entry since the search ranked it); savings attribution must never break a search.
|
|
2094
2209
|
*/
|
|
2210
|
+
/** Inverse document frequency of one index term over the whole corpus (BM25's formula). */
|
|
2211
|
+
termIdf(term) {
|
|
2212
|
+
this.syncIfChanged();
|
|
2213
|
+
const N = this.entries.size;
|
|
2214
|
+
const df = this.invertedIndex.get(term)?.size ?? 0;
|
|
2215
|
+
return Math.log((N - df + 0.5) / (df + 0.5) + 1);
|
|
2216
|
+
}
|
|
2217
|
+
/** One reuse of a memory the agent chose and read (see search_memory's shortlist). */
|
|
2218
|
+
recordReuse(id) {
|
|
2219
|
+
const entry = this.entries.get(id);
|
|
2220
|
+
if (!entry)
|
|
2221
|
+
return;
|
|
2222
|
+
entry.hits++;
|
|
2223
|
+
this.scheduleSave();
|
|
2224
|
+
}
|
|
2095
2225
|
creditSavings(id, tokens) {
|
|
2096
2226
|
if (!Number.isFinite(tokens) || tokens <= 0)
|
|
2097
2227
|
return;
|
|
@@ -2224,6 +2354,7 @@ export class TheBrainV2 {
|
|
|
2224
2354
|
const terms = tokenize(keeper.query + ' ' + keeper.response);
|
|
2225
2355
|
keeper.terms = [...new Set(terms)];
|
|
2226
2356
|
keeper.termFreq = termFrequencies(terms);
|
|
2357
|
+
keeper.tokv = TOKENIZER_VERSION;
|
|
2227
2358
|
keeper.charCount = keeper.query.length + keeper.response.length;
|
|
2228
2359
|
this.entries.set(keepId, keeper);
|
|
2229
2360
|
for (const term of keeper.terms) {
|
|
@@ -2667,6 +2798,7 @@ export class TheBrainV2 {
|
|
|
2667
2798
|
const terms = tokenize(entry.query + ' ' + entry.response);
|
|
2668
2799
|
entry.terms = [...new Set(terms)];
|
|
2669
2800
|
entry.termFreq = termFrequencies(terms);
|
|
2801
|
+
entry.tokv = TOKENIZER_VERSION;
|
|
2670
2802
|
entry.charCount = entry.query.length + entry.response.length;
|
|
2671
2803
|
// Claims supplied in this patch were just hashed by buildClaims; the helper re-anchors the
|
|
2672
2804
|
// ones carried over, so either way the entry's evidence describes the code as it is now.
|