@nxuss/lemma 1.11.0 → 1.14.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 +98 -821
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +14 -0
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/infra/mcp-tools.d.ts +7 -0
- package/dist/cjs/infra/mcp-tools.d.ts.map +1 -1
- package/dist/cjs/infra/mcp-tools.js +22 -0
- package/dist/cjs/infra/mcp-tools.js.map +1 -1
- package/dist/cjs/mcp/index.js +35 -7
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/mcp/prompts.d.ts +1 -0
- package/dist/cjs/mcp/prompts.d.ts.map +1 -1
- package/dist/cjs/mcp/prompts.js +98 -0
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/resources.d.ts +2 -0
- package/dist/cjs/mcp/resources.d.ts.map +1 -1
- package/dist/cjs/mcp/resources.js +26 -0
- package/dist/cjs/mcp/resources.js.map +1 -1
- package/dist/cjs/mcp/tasks.d.ts +20 -0
- package/dist/cjs/mcp/tasks.d.ts.map +1 -0
- package/dist/cjs/mcp/tasks.js +71 -0
- package/dist/cjs/mcp/tasks.js.map +1 -0
- package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/cjs/mcp/tool-profiles.js +29 -50
- package/dist/cjs/mcp/tool-profiles.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +575 -93
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/proxy/Gatekeeper.d.ts +29 -0
- package/dist/cjs/proxy/Gatekeeper.d.ts.map +1 -1
- package/dist/cjs/proxy/Gatekeeper.js +122 -1
- package/dist/cjs/proxy/Gatekeeper.js.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.d.ts +50 -1
- package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.js +149 -8
- package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
- package/dist/cjs/utils/PatchMatcher.d.ts +1 -0
- package/dist/cjs/utils/PatchMatcher.d.ts.map +1 -1
- package/dist/cjs/utils/PatchMatcher.js +4 -4
- package/dist/cjs/utils/PatchMatcher.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +14 -0
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/infra/mcp-tools.d.ts +7 -0
- package/dist/esm/infra/mcp-tools.d.ts.map +1 -1
- package/dist/esm/infra/mcp-tools.js +22 -0
- package/dist/esm/infra/mcp-tools.js.map +1 -1
- package/dist/esm/mcp/index.js +37 -9
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/prompts.d.ts +1 -0
- package/dist/esm/mcp/prompts.d.ts.map +1 -1
- package/dist/esm/mcp/prompts.js +95 -1
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/resources.d.ts +2 -0
- package/dist/esm/mcp/resources.d.ts.map +1 -1
- package/dist/esm/mcp/resources.js +27 -2
- package/dist/esm/mcp/resources.js.map +1 -1
- package/dist/esm/mcp/tasks.d.ts +20 -0
- package/dist/esm/mcp/tasks.d.ts.map +1 -0
- package/dist/esm/mcp/tasks.js +66 -0
- package/dist/esm/mcp/tasks.js.map +1 -0
- package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/esm/mcp/tool-profiles.js +29 -50
- package/dist/esm/mcp/tool-profiles.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +577 -95
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/proxy/Gatekeeper.d.ts +29 -0
- package/dist/esm/proxy/Gatekeeper.d.ts.map +1 -1
- package/dist/esm/proxy/Gatekeeper.js +120 -0
- package/dist/esm/proxy/Gatekeeper.js.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.d.ts +50 -1
- package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.js +149 -8
- package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
- package/dist/esm/utils/PatchMatcher.d.ts +1 -0
- package/dist/esm/utils/PatchMatcher.d.ts.map +1 -1
- package/dist/esm/utils/PatchMatcher.js +4 -4
- package/dist/esm/utils/PatchMatcher.js.map +1 -1
- package/package.json +2 -2
|
@@ -17,6 +17,18 @@ export interface GatekeeperStatus {
|
|
|
17
17
|
isPro: boolean;
|
|
18
18
|
licenseKey: string | null;
|
|
19
19
|
}
|
|
20
|
+
export type InferenceMode = 'cloud' | 'hybrid' | 'airgapped';
|
|
21
|
+
export interface EgressDecision {
|
|
22
|
+
allowed: boolean;
|
|
23
|
+
mode: InferenceMode;
|
|
24
|
+
host: string;
|
|
25
|
+
reason: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class EgressBlockedError extends Error {
|
|
28
|
+
readonly decision: EgressDecision;
|
|
29
|
+
code: "EGRESS_BLOCKED";
|
|
30
|
+
constructor(decision: EgressDecision);
|
|
31
|
+
}
|
|
20
32
|
export interface CacheBackend {
|
|
21
33
|
set(key: string, input: string, data: any, ttl: number): Promise<void>;
|
|
22
34
|
findSimilar(input: string, threshold: number): Promise<{
|
|
@@ -32,7 +44,24 @@ export declare class Gatekeeper extends EventEmitter {
|
|
|
32
44
|
private memBackend;
|
|
33
45
|
private semBackend;
|
|
34
46
|
private semInitialized;
|
|
47
|
+
private inferenceMode;
|
|
48
|
+
private allowedEndpoints;
|
|
35
49
|
constructor(keyManager: KeyManager);
|
|
50
|
+
private loadInferencePolicy;
|
|
51
|
+
getInferenceStatus(): {
|
|
52
|
+
mode: InferenceMode;
|
|
53
|
+
allowedEndpoints: string[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Central egress decision. Called once per outbound provider request from
|
|
57
|
+
* lemma-proxy.ts — no call site talks to a provider without going through this.
|
|
58
|
+
*/
|
|
59
|
+
checkEgress(urlOrHost: string): EgressDecision;
|
|
60
|
+
/**
|
|
61
|
+
* Throws EgressBlockedError on denial, and emits 'egress-blocked' so callers
|
|
62
|
+
* (e.g. the audit/token_receipt log) can record the attempt for compliance.
|
|
63
|
+
*/
|
|
64
|
+
assertEgressAllowed(urlOrHost: string): void;
|
|
36
65
|
getBackend(): Promise<CacheBackend>;
|
|
37
66
|
getMode(): CacheMode;
|
|
38
67
|
getStatus(): GatekeeperStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Gatekeeper.d.ts","sourceRoot":"","sources":["../../../src/proxy/Gatekeeper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACjG,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,IAAI,CAAC;CACf;AAED,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,cAAc,CAAS;
|
|
1
|
+
{"version":3,"file":"Gatekeeper.d.ts","sourceRoot":"","sources":["../../../src/proxy/Gatekeeper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAmBD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;aAEf,QAAQ,EAAE,cAAc;IADpD,IAAI,EAAG,gBAAgB,CAAU;gBACL,QAAQ,EAAE,cAAc;CAOrD;AA0CD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACjG,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,IAAI,CAAC;CACf;AAED,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,gBAAgB,CAA0B;gBAEtC,UAAU,EAAE,UAAU;IAMlC,OAAO,CAAC,mBAAmB;IAsB3B,kBAAkB;;;;IAOlB;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;IAgC9C;;;OAGG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAStC,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC;IAazC,OAAO,IAAI,SAAS;IAIpB,SAAS,IAAI,gBAAgB;IAK7B,MAAM,IAAI,IAAI;IAKd,OAAO,CAAC,gBAAgB;YAKV,kBAAkB;CAejC"}
|
|
@@ -43,8 +43,60 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
43
43
|
};
|
|
44
44
|
})();
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.Gatekeeper = void 0;
|
|
46
|
+
exports.Gatekeeper = exports.EgressBlockedError = void 0;
|
|
47
47
|
const events_1 = require("events");
|
|
48
|
+
class EgressBlockedError extends Error {
|
|
49
|
+
constructor(decision) {
|
|
50
|
+
super(`[Gatekeeper] Blocked outbound request to "${decision.host}" ` +
|
|
51
|
+
`(LEMMA_INFERENCE_MODE=${decision.mode}): ${decision.reason}`);
|
|
52
|
+
this.decision = decision;
|
|
53
|
+
this.code = 'EGRESS_BLOCKED';
|
|
54
|
+
this.name = 'EgressBlockedError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.EgressBlockedError = EgressBlockedError;
|
|
58
|
+
// Public LLM provider hosts we recognize by default. Not exhaustive — enterprises
|
|
59
|
+
// extend this via LEMMA_ALLOWED_ENDPOINTS (allow) rather than us maintaining a
|
|
60
|
+
// perfect blocklist (deny-lists always miss something; this list only needs to
|
|
61
|
+
// cover the hosts Lemma itself dials directly, see lemma-proxy.ts callUpstream).
|
|
62
|
+
const KNOWN_PUBLIC_LLM_HOSTS = [
|
|
63
|
+
'api.openai.com',
|
|
64
|
+
'api.anthropic.com',
|
|
65
|
+
'generativelanguage.googleapis.com',
|
|
66
|
+
'api.mistral.ai',
|
|
67
|
+
'api.cohere.ai',
|
|
68
|
+
];
|
|
69
|
+
function parseAllowedEndpoints(raw) {
|
|
70
|
+
if (!raw)
|
|
71
|
+
return new Set();
|
|
72
|
+
return new Set(raw.split(',').map(h => h.trim().toLowerCase()).filter(Boolean));
|
|
73
|
+
}
|
|
74
|
+
function hostOf(urlOrHost) {
|
|
75
|
+
try {
|
|
76
|
+
return new URL(urlOrHost).hostname.toLowerCase();
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Already a bare hostname (e.g. from a config value, not a full URL)
|
|
80
|
+
return urlOrHost.toLowerCase().replace(/:\d+$/, '');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function isPrivateHost(host) {
|
|
84
|
+
if (host === 'localhost' || host === '127.0.0.1' || host === '::1')
|
|
85
|
+
return true;
|
|
86
|
+
if (host.endsWith('.local') || host.endsWith('.internal'))
|
|
87
|
+
return true;
|
|
88
|
+
const m = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
89
|
+
if (!m)
|
|
90
|
+
return false;
|
|
91
|
+
const [a, b] = [parseInt(m[1], 10), parseInt(m[2], 10)];
|
|
92
|
+
if (a === 10)
|
|
93
|
+
return true; // 10.0.0.0/8
|
|
94
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
95
|
+
return true; // 172.16.0.0/12
|
|
96
|
+
if (a === 192 && b === 168)
|
|
97
|
+
return true; // 192.168.0.0/16
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
48
100
|
class Gatekeeper extends events_1.EventEmitter {
|
|
49
101
|
constructor(keyManager) {
|
|
50
102
|
super();
|
|
@@ -52,7 +104,75 @@ class Gatekeeper extends events_1.EventEmitter {
|
|
|
52
104
|
this.memBackend = null;
|
|
53
105
|
this.semBackend = null;
|
|
54
106
|
this.semInitialized = false;
|
|
107
|
+
this.inferenceMode = 'cloud';
|
|
108
|
+
this.allowedEndpoints = new Set();
|
|
55
109
|
this.keyManager = keyManager;
|
|
110
|
+
this.loadInferencePolicy();
|
|
111
|
+
}
|
|
112
|
+
loadInferencePolicy() {
|
|
113
|
+
const envValue = process.env.LEMMA_INFERENCE_MODE;
|
|
114
|
+
const raw = (envValue || 'cloud').toLowerCase();
|
|
115
|
+
this.allowedEndpoints = parseAllowedEndpoints(process.env.LEMMA_ALLOWED_ENDPOINTS);
|
|
116
|
+
if (raw === 'cloud' || raw === 'hybrid' || raw === 'airgapped') {
|
|
117
|
+
this.inferenceMode = raw;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// LEMMA_INFERENCE_MODE was set to something we don't recognize (typo, stale
|
|
121
|
+
// value, etc). Unset defaults to "cloud" for backward compatibility, but a
|
|
122
|
+
// *garbled* value must not silently fall back to the unrestricted mode — that
|
|
123
|
+
// would let a typo quietly disable the one thing enterprises deploy this for.
|
|
124
|
+
// Fail closed to the strictest mode instead.
|
|
125
|
+
this.inferenceMode = 'airgapped';
|
|
126
|
+
console.error(`[Gatekeeper] Unknown LEMMA_INFERENCE_MODE="${envValue}". Failing closed to "airgapped" ` +
|
|
127
|
+
`(only private hosts + LEMMA_ALLOWED_ENDPOINTS) until this is fixed to one of: cloud, hybrid, airgapped.`);
|
|
128
|
+
}
|
|
129
|
+
getInferenceStatus() {
|
|
130
|
+
return {
|
|
131
|
+
mode: this.inferenceMode,
|
|
132
|
+
allowedEndpoints: Array.from(this.allowedEndpoints),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Central egress decision. Called once per outbound provider request from
|
|
137
|
+
* lemma-proxy.ts — no call site talks to a provider without going through this.
|
|
138
|
+
*/
|
|
139
|
+
checkEgress(urlOrHost) {
|
|
140
|
+
const host = hostOf(urlOrHost);
|
|
141
|
+
const mode = this.inferenceMode;
|
|
142
|
+
if (mode === 'cloud') {
|
|
143
|
+
return { allowed: true, mode, host, reason: 'LEMMA_INFERENCE_MODE=cloud (unrestricted)' };
|
|
144
|
+
}
|
|
145
|
+
if (this.allowedEndpoints.has(host)) {
|
|
146
|
+
return { allowed: true, mode, host, reason: 'host is in LEMMA_ALLOWED_ENDPOINTS' };
|
|
147
|
+
}
|
|
148
|
+
if (isPrivateHost(host)) {
|
|
149
|
+
return { allowed: true, mode, host, reason: 'private/local host' };
|
|
150
|
+
}
|
|
151
|
+
if (mode === 'hybrid' && !KNOWN_PUBLIC_LLM_HOSTS.includes(host)) {
|
|
152
|
+
// hybrid only blocks recognized public LLM providers; unknown hosts (e.g. a
|
|
153
|
+
// customer's own SaaS endpoint) pass through unless they opt into airgapped.
|
|
154
|
+
return { allowed: true, mode, host, reason: 'not a recognized public LLM provider host' };
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
allowed: false,
|
|
158
|
+
mode,
|
|
159
|
+
host,
|
|
160
|
+
reason: mode === 'airgapped'
|
|
161
|
+
? 'airgapped mode blocks all non-private hosts not in LEMMA_ALLOWED_ENDPOINTS'
|
|
162
|
+
: 'hybrid mode blocks known public LLM provider hosts not in LEMMA_ALLOWED_ENDPOINTS',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Throws EgressBlockedError on denial, and emits 'egress-blocked' so callers
|
|
167
|
+
* (e.g. the audit/token_receipt log) can record the attempt for compliance.
|
|
168
|
+
*/
|
|
169
|
+
assertEgressAllowed(urlOrHost) {
|
|
170
|
+
const decision = this.checkEgress(urlOrHost);
|
|
171
|
+
if (!decision.allowed) {
|
|
172
|
+
this.emit('egress-blocked', { ...decision, timestamp: Date.now() });
|
|
173
|
+
console.warn(`[Gatekeeper] BLOCKED egress to ${decision.host} (mode=${decision.mode}): ${decision.reason}`);
|
|
174
|
+
throw new EgressBlockedError(decision);
|
|
175
|
+
}
|
|
56
176
|
}
|
|
57
177
|
async getBackend() {
|
|
58
178
|
const mode = this.getMode();
|
|
@@ -75,6 +195,7 @@ class Gatekeeper extends events_1.EventEmitter {
|
|
|
75
195
|
}
|
|
76
196
|
reload() {
|
|
77
197
|
this.keyManager.reload();
|
|
198
|
+
this.loadInferencePolicy();
|
|
78
199
|
}
|
|
79
200
|
getMemoryBackend() {
|
|
80
201
|
if (!this.memBackend)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Gatekeeper.js","sourceRoot":"","sources":["../../../src/proxy/Gatekeeper.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Gatekeeper.js","sourceRoot":"","sources":["../../../src/proxy/Gatekeeper.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,12 @@ export interface BrainEntry {
|
|
|
38
38
|
* fix — the Brain can only ever suggest reuse, never warn "we already tried this."
|
|
39
39
|
*/
|
|
40
40
|
outcome?: 'confirmed' | 'failed';
|
|
41
|
+
/**
|
|
42
|
+
* Free-text domain tag (e.g. "auth", "billing") lifted from cognitive_map's current
|
|
43
|
+
* context at store time. Absent means untagged — those entries stay visible to every
|
|
44
|
+
* domain-scoped search rather than disappearing, same rationale as projectId above.
|
|
45
|
+
*/
|
|
46
|
+
domain?: string;
|
|
41
47
|
/**
|
|
42
48
|
* Absolute-path::symbolName -> sha256 of just that symbol's extracted source (via
|
|
43
49
|
* SymbolSurgicalContext), not the whole file. When a file has an entry here, freshness
|
|
@@ -55,6 +61,12 @@ export interface BrainEntry {
|
|
|
55
61
|
* still trustworthy instead of discarding (or blindly trusting) the whole thing.
|
|
56
62
|
*/
|
|
57
63
|
claims?: Claim[];
|
|
64
|
+
/**
|
|
65
|
+
* Count of explicit "this memory led me astray" signals via downvote(). Distinct from
|
|
66
|
+
* hits: hits means "this surfaced and looked relevant enough to reuse," demerits means
|
|
67
|
+
* "reuse turned out to be wrong." Absent/0 means never downvoted.
|
|
68
|
+
*/
|
|
69
|
+
demerits?: number;
|
|
58
70
|
}
|
|
59
71
|
export interface Claim {
|
|
60
72
|
id: string;
|
|
@@ -89,6 +101,7 @@ export interface BrainSearchResult {
|
|
|
89
101
|
staleFiles?: string[];
|
|
90
102
|
outcome?: 'confirmed' | 'failed';
|
|
91
103
|
claims?: ClaimFreshness[];
|
|
104
|
+
domain?: string;
|
|
92
105
|
}
|
|
93
106
|
export interface BrainSearchOptions {
|
|
94
107
|
/**
|
|
@@ -99,6 +112,8 @@ export interface BrainSearchOptions {
|
|
|
99
112
|
countStats?: boolean;
|
|
100
113
|
/** Prefer memories from this project. See the scoping note in search(). */
|
|
101
114
|
projectId?: string;
|
|
115
|
+
/** Prefer memories tagged with this domain. Same soft-fallback rule as projectId. */
|
|
116
|
+
domain?: string;
|
|
102
117
|
}
|
|
103
118
|
export interface BrainStats {
|
|
104
119
|
totalEntries: number;
|
|
@@ -156,11 +171,33 @@ export declare class TheBrainV2 {
|
|
|
156
171
|
* Store a query+response pair in the brain.
|
|
157
172
|
* Returns false if detected as duplicate (>= dupThreshold similarity).
|
|
158
173
|
*/
|
|
159
|
-
store(query: string, response: string, provider?: string, dupThreshold?: number, filePaths?: string[], projectId?: string, outcome?: 'confirmed' | 'failed', symbolRefs?: SymbolRef[], claimInputs?: ClaimInput[]): {
|
|
174
|
+
store(query: string, response: string, provider?: string, dupThreshold?: number, filePaths?: string[], projectId?: string, outcome?: 'confirmed' | 'failed', symbolRefs?: SymbolRef[], claimInputs?: ClaimInput[], domain?: string): {
|
|
160
175
|
stored: boolean;
|
|
161
176
|
reason: string;
|
|
162
177
|
duplicate?: BrainSearchResult;
|
|
178
|
+
conflicts?: Array<{
|
|
179
|
+
id: string;
|
|
180
|
+
query: string;
|
|
181
|
+
outcome: 'confirmed' | 'failed';
|
|
182
|
+
}>;
|
|
163
183
|
};
|
|
184
|
+
/**
|
|
185
|
+
* Hard cap on entry count. Past this, the inverted index keeps growing and old, unused
|
|
186
|
+
* entries dilute every future BM25 IDF calculation (more docs sharing a term → lower
|
|
187
|
+
* signal) without ever being asked for again. Evicting keeps ranking quality from
|
|
188
|
+
* degrading as the Brain accumulates months of memories.
|
|
189
|
+
*/
|
|
190
|
+
private static readonly MAX_ENTRIES;
|
|
191
|
+
/** How many entries to evict per pass once over MAX_ENTRIES — batched, not one-at-a-time. */
|
|
192
|
+
private static readonly EVICT_BATCH;
|
|
193
|
+
/**
|
|
194
|
+
* Evict the lowest-value entries once the Brain is over capacity. Value = hits (proven
|
|
195
|
+
* usefulness) with a mild recency tiebreak — never based on similarity to any one query,
|
|
196
|
+
* since an entry unrelated to today's search may still be exactly what tomorrow's needs.
|
|
197
|
+
* Failed-outcome entries are cheap to keep (they're short, deliberate warnings) so they're
|
|
198
|
+
* evicted last among equally-unused entries rather than first.
|
|
199
|
+
*/
|
|
200
|
+
private evictIfOverCapacity;
|
|
164
201
|
/**
|
|
165
202
|
* Search brain using BM25 + Jaccard re-ranking.
|
|
166
203
|
* Returns results with similarity scores normalized to 0-1.
|
|
@@ -180,6 +217,18 @@ export declare class TheBrainV2 {
|
|
|
180
217
|
similarity: number;
|
|
181
218
|
existing?: BrainSearchResult;
|
|
182
219
|
};
|
|
220
|
+
/**
|
|
221
|
+
* Record that a specific memory turned out NOT to help — the caller acted on it and it
|
|
222
|
+
* was wrong, misleading, or irrelevant despite ranking well. Unlike `outcome: 'failed'`
|
|
223
|
+
* (set at store time, about the underlying approach), this is set after the fact, about
|
|
224
|
+
* the memory's usefulness as a search result. Lowers future ranking and eviction priority
|
|
225
|
+
* without deleting the entry — a bad-fit-today memory may still be exactly right for a
|
|
226
|
+
* differently-phrased query tomorrow.
|
|
227
|
+
*/
|
|
228
|
+
downvote(id: string): {
|
|
229
|
+
ok: boolean;
|
|
230
|
+
message: string;
|
|
231
|
+
};
|
|
183
232
|
getStats(): BrainStats;
|
|
184
233
|
clear(): void;
|
|
185
234
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TheBrainV2.d.ts","sourceRoot":"","sources":["../../../src/subconscious/TheBrainV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAInB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IACjC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"TheBrainV2.d.ts","sourceRoot":"","sources":["../../../src/subconscious/TheBrainV2.ts"],"names":[],"mappings":"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"}
|
|
@@ -141,7 +141,37 @@ function tokenize(text) {
|
|
|
141
141
|
// the same index bucket. Purely additive: old entries that predate this still match on
|
|
142
142
|
// their original terms exactly as before, they just don't get the extra recall.
|
|
143
143
|
const stems = terms.map(stem).filter(s => s !== undefined);
|
|
144
|
-
|
|
144
|
+
// 7. Add a shared cluster tag for known dev-vocabulary synonyms (bilingual) so "jwt
|
|
145
|
+
// expiration" and "token timeout" land on a common term without needing embeddings.
|
|
146
|
+
// Purely additive, same rationale as stems — never replaces the surface form, so it
|
|
147
|
+
// can only add recall, never hide an existing exact match.
|
|
148
|
+
const synonymTags = terms
|
|
149
|
+
.map(t => SYNONYM_CLUSTERS.get(t))
|
|
150
|
+
.filter((c) => c !== undefined);
|
|
151
|
+
return [...new Set([...terms, ...bigrams, ...stems, ...synonymTags])];
|
|
152
|
+
}
|
|
153
|
+
// Groups of interchangeable dev-vocabulary terms (bilingual). Each member maps to a shared
|
|
154
|
+
// `syn_<canonical>` token so any two synonyms in the same group become a shared index bucket
|
|
155
|
+
// — a cheap substitute for embeddings when the gap is "different word, same concept" rather
|
|
156
|
+
// than true paraphrase. Keep groups small and unambiguous; a bad merge can only add a false
|
|
157
|
+
// candidate (never hide a real exact match), but it does dilute BM25 signal if overused.
|
|
158
|
+
const SYNONYM_GROUPS = [
|
|
159
|
+
['jwt', 'token', 'session', 'auth', 'login', 'autenticacion', 'sesion', 'autenticar'],
|
|
160
|
+
['timeout', 'expiration', 'expiry', 'vencimiento', 'caducidad', 'expirar', 'vencer'],
|
|
161
|
+
['bug', 'error', 'fallo', 'falla', 'issue', 'defect', 'defecto'],
|
|
162
|
+
['fix', 'patch', 'solucion', 'solucionar', 'arreglar', 'corregir', 'hotfix'],
|
|
163
|
+
['delete', 'remove', 'eliminar', 'borrar', 'quitar'],
|
|
164
|
+
['config', 'configuration', 'configuracion', 'settings', 'ajustes'],
|
|
165
|
+
['deploy', 'deployment', 'despliegue', 'desplegar', 'release'],
|
|
166
|
+
['crash', 'exception', 'excepcion', 'throw', 'falla'],
|
|
167
|
+
['slow', 'lento', 'lentitud', 'latency', 'latencia', 'performance', 'rendimiento'],
|
|
168
|
+
['test', 'tests', 'testing', 'prueba', 'pruebas', 'spec'],
|
|
169
|
+
];
|
|
170
|
+
const SYNONYM_CLUSTERS = new Map();
|
|
171
|
+
for (const group of SYNONYM_GROUPS) {
|
|
172
|
+
const canonical = `syn_${group[0]}`;
|
|
173
|
+
for (const member of group)
|
|
174
|
+
SYNONYM_CLUSTERS.set(member, canonical);
|
|
145
175
|
}
|
|
146
176
|
// Suffix-stripping rules, longest/most-specific match first. Additive expansion only —
|
|
147
177
|
// this is not a correctness-critical stemmer, so mild over-stemming (merging two distinct
|
|
@@ -483,7 +513,7 @@ class TheBrainV2 {
|
|
|
483
513
|
* Store a query+response pair in the brain.
|
|
484
514
|
* Returns false if detected as duplicate (>= dupThreshold similarity).
|
|
485
515
|
*/
|
|
486
|
-
store(query, response, provider = 'generic', dupThreshold = 0.92, filePaths, projectId = deriveProjectId(), outcome, symbolRefs, claimInputs) {
|
|
516
|
+
store(query, response, provider = 'generic', dupThreshold = 0.92, filePaths, projectId = deriveProjectId(), outcome, symbolRefs, claimInputs, domain) {
|
|
487
517
|
// Quick bloom check
|
|
488
518
|
const queryKey = query.trim().toLowerCase().substring(0, 200);
|
|
489
519
|
if (this.bloom.has(queryKey)) {
|
|
@@ -497,6 +527,28 @@ class TheBrainV2 {
|
|
|
497
527
|
};
|
|
498
528
|
}
|
|
499
529
|
}
|
|
530
|
+
// Conflict check: another entry about the exact same symbol, with the opposite
|
|
531
|
+
// outcome, is worth flagging before this one is even written — two memories about one
|
|
532
|
+
// function disagreeing on whether an approach works is a trap for whoever searches next.
|
|
533
|
+
// Not a block, just a warning: the newer entry may legitimately supersede the older one.
|
|
534
|
+
let conflicts;
|
|
535
|
+
if (symbolRefs && symbolRefs.length > 0) {
|
|
536
|
+
const newKeys = new Set(symbolRefs.map((r) => `${path_1.default.resolve(r.filePath)}::${r.symbolName}`));
|
|
537
|
+
const newOutcome = outcome === 'failed' ? 'failed' : 'confirmed';
|
|
538
|
+
const found = [];
|
|
539
|
+
for (const existingEntry of this.entries.values()) {
|
|
540
|
+
if (!existingEntry.symbolHashes)
|
|
541
|
+
continue;
|
|
542
|
+
const existingOutcome = existingEntry.outcome === 'failed' ? 'failed' : 'confirmed';
|
|
543
|
+
if (existingOutcome === newOutcome)
|
|
544
|
+
continue;
|
|
545
|
+
const sharesSymbol = Object.keys(existingEntry.symbolHashes).some((k) => newKeys.has(k));
|
|
546
|
+
if (sharesSymbol)
|
|
547
|
+
found.push({ id: existingEntry.id, query: existingEntry.query, outcome: existingOutcome });
|
|
548
|
+
}
|
|
549
|
+
if (found.length > 0)
|
|
550
|
+
conflicts = found;
|
|
551
|
+
}
|
|
500
552
|
const terms = tokenize(query + ' ' + response);
|
|
501
553
|
const termFreq = termFrequencies(terms);
|
|
502
554
|
const id = crypto_1.default
|
|
@@ -519,6 +571,7 @@ class TheBrainV2 {
|
|
|
519
571
|
outcome,
|
|
520
572
|
symbolHashes: symbolRefs && symbolRefs.length > 0 ? hashSymbolsForFreshness(symbolRefs) : undefined,
|
|
521
573
|
claims: claimInputs && claimInputs.length > 0 ? buildClaims(claimInputs) : undefined,
|
|
574
|
+
domain,
|
|
522
575
|
};
|
|
523
576
|
this.entries.set(id, entry);
|
|
524
577
|
// Update inverted index
|
|
@@ -531,8 +584,46 @@ class TheBrainV2 {
|
|
|
531
584
|
// Update bloom
|
|
532
585
|
this.bloom.add(queryKey);
|
|
533
586
|
this.recalcAvgDocLength();
|
|
587
|
+
this.evictIfOverCapacity();
|
|
534
588
|
this.scheduleSave();
|
|
535
|
-
return { stored: true, reason: 'Stored successfully' };
|
|
589
|
+
return { stored: true, reason: 'Stored successfully', conflicts };
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Evict the lowest-value entries once the Brain is over capacity. Value = hits (proven
|
|
593
|
+
* usefulness) with a mild recency tiebreak — never based on similarity to any one query,
|
|
594
|
+
* since an entry unrelated to today's search may still be exactly what tomorrow's needs.
|
|
595
|
+
* Failed-outcome entries are cheap to keep (they're short, deliberate warnings) so they're
|
|
596
|
+
* evicted last among equally-unused entries rather than first.
|
|
597
|
+
*/
|
|
598
|
+
evictIfOverCapacity() {
|
|
599
|
+
if (this.entries.size <= TheBrainV2.MAX_ENTRIES)
|
|
600
|
+
return;
|
|
601
|
+
const ranked = Array.from(this.entries.values()).sort((a, b) => {
|
|
602
|
+
// Net value = hits minus twice the demerits — a downvoted entry is worse than a
|
|
603
|
+
// merely-unused one, so it should be first out even if it has a few stale hits.
|
|
604
|
+
const aValue = a.hits - (a.demerits || 0) * 2;
|
|
605
|
+
const bValue = b.hits - (b.demerits || 0) * 2;
|
|
606
|
+
const aFailed = a.outcome === 'failed' ? 1 : 0;
|
|
607
|
+
const bFailed = b.outcome === 'failed' ? 1 : 0;
|
|
608
|
+
if (aValue !== bValue)
|
|
609
|
+
return aValue - bValue; // lower net value evicted first
|
|
610
|
+
if (aFailed !== bFailed)
|
|
611
|
+
return bFailed - aFailed; // confirmed evicted before failed, when tied on value
|
|
612
|
+
return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(); // older evicted first
|
|
613
|
+
});
|
|
614
|
+
const toEvict = ranked.slice(0, TheBrainV2.EVICT_BATCH);
|
|
615
|
+
for (const entry of toEvict) {
|
|
616
|
+
this.entries.delete(entry.id);
|
|
617
|
+
for (const term of entry.terms) {
|
|
618
|
+
const ids = this.invertedIndex.get(term);
|
|
619
|
+
if (!ids)
|
|
620
|
+
continue;
|
|
621
|
+
ids.delete(entry.id);
|
|
622
|
+
if (ids.size === 0)
|
|
623
|
+
this.invertedIndex.delete(term);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
this.recalcAvgDocLength();
|
|
536
627
|
}
|
|
537
628
|
// ─── Search ───────────────────────────────────────────────────────────────
|
|
538
629
|
/**
|
|
@@ -607,11 +698,33 @@ class TheBrainV2 {
|
|
|
607
698
|
}
|
|
608
699
|
// 4. Normalize BM25 to 0-1 range
|
|
609
700
|
const maxBm25 = Math.max(...scored.map(s => s.bm25), 1);
|
|
610
|
-
// 5. Combined score: 70% BM25 + 30% Jaccard
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
701
|
+
// 5. Combined score: 70% BM25 + 30% Jaccard, then adjust for signals BM25/Jaccard can't
|
|
702
|
+
// see on their own: a memory's own track record. Small and additive by design — none of
|
|
703
|
+
// these can turn an unrelated result into a top hit, they only reorder among already-
|
|
704
|
+
// relevant candidates.
|
|
705
|
+
const combined = scored.map(s => {
|
|
706
|
+
let similarity = (s.bm25 / maxBm25) * 0.7 + s.jaccard * 0.3;
|
|
707
|
+
// Popularity prior: entries other searches actually reused are more likely to be
|
|
708
|
+
// reused again. Log-scaled and capped at +0.08 so a handful of hits can't outrank a
|
|
709
|
+
// much better textual match.
|
|
710
|
+
similarity += Math.min(Math.log2(s.entry.hits + 1) * 0.02, 0.08);
|
|
711
|
+
// A documented dead end ranking above a working fix is actively harmful — it reads as
|
|
712
|
+
// a suggestion even with the "STALE"/"FAILED" label attached downstream. Demote, don't
|
|
713
|
+
// hide: the warning is still worth surfacing, just not first.
|
|
714
|
+
if (s.entry.outcome === 'failed')
|
|
715
|
+
similarity -= 0.15;
|
|
716
|
+
// Soft domain preference (see projectId scoping above for why this stays soft): an
|
|
717
|
+
// entry tagged with the requested domain is more likely relevant, but an untagged or
|
|
718
|
+
// cross-domain entry may still be the right answer.
|
|
719
|
+
if (options.domain && s.entry.domain === options.domain)
|
|
720
|
+
similarity += 0.05;
|
|
721
|
+
// Explicit negative feedback from downvote() — a caller saying "this was wrong" is a
|
|
722
|
+
// stronger, more deliberate signal than the absence of hits, so it outweighs the
|
|
723
|
+
// popularity prior above rather than just canceling it out.
|
|
724
|
+
if (s.entry.demerits)
|
|
725
|
+
similarity -= Math.min(s.entry.demerits * 0.06, 0.25);
|
|
726
|
+
return { entry: s.entry, similarity: Math.max(0, similarity) };
|
|
727
|
+
});
|
|
615
728
|
// 6. Sort and filter
|
|
616
729
|
combined.sort((a, b) => b.similarity - a.similarity);
|
|
617
730
|
const results = combined
|
|
@@ -631,6 +744,7 @@ class TheBrainV2 {
|
|
|
631
744
|
...(fresh ? {} : { staleFiles }),
|
|
632
745
|
...(r.entry.outcome ? { outcome: r.entry.outcome } : {}),
|
|
633
746
|
...(claims && claims.length > 0 ? { claims } : {}),
|
|
747
|
+
...(r.entry.domain ? { domain: r.entry.domain } : {}),
|
|
634
748
|
};
|
|
635
749
|
});
|
|
636
750
|
// 7. Update hit counters — only for searches a caller actually asked a question with.
|
|
@@ -684,6 +798,23 @@ class TheBrainV2 {
|
|
|
684
798
|
}
|
|
685
799
|
return { isDuplicate: false, similarity: sim };
|
|
686
800
|
}
|
|
801
|
+
// ─── Feedback ─────────────────────────────────────────────────────────────
|
|
802
|
+
/**
|
|
803
|
+
* Record that a specific memory turned out NOT to help — the caller acted on it and it
|
|
804
|
+
* was wrong, misleading, or irrelevant despite ranking well. Unlike `outcome: 'failed'`
|
|
805
|
+
* (set at store time, about the underlying approach), this is set after the fact, about
|
|
806
|
+
* the memory's usefulness as a search result. Lowers future ranking and eviction priority
|
|
807
|
+
* without deleting the entry — a bad-fit-today memory may still be exactly right for a
|
|
808
|
+
* differently-phrased query tomorrow.
|
|
809
|
+
*/
|
|
810
|
+
downvote(id) {
|
|
811
|
+
const entry = this.entries.get(id);
|
|
812
|
+
if (!entry)
|
|
813
|
+
return { ok: false, message: `No entry with id "${id}" in the Brain.` };
|
|
814
|
+
entry.demerits = (entry.demerits || 0) + 1;
|
|
815
|
+
this.scheduleSave();
|
|
816
|
+
return { ok: true, message: `Recorded negative feedback on entry "${id}" (demerits: ${entry.demerits}). It will rank lower and be evicted sooner.` };
|
|
817
|
+
}
|
|
687
818
|
// ─── Stats ────────────────────────────────────────────────────────────────
|
|
688
819
|
getStats() {
|
|
689
820
|
return {
|
|
@@ -714,6 +845,16 @@ class TheBrainV2 {
|
|
|
714
845
|
}
|
|
715
846
|
}
|
|
716
847
|
exports.TheBrainV2 = TheBrainV2;
|
|
848
|
+
// ─── Capacity / Pruning ─────────────────────────────────────────────────────
|
|
849
|
+
/**
|
|
850
|
+
* Hard cap on entry count. Past this, the inverted index keeps growing and old, unused
|
|
851
|
+
* entries dilute every future BM25 IDF calculation (more docs sharing a term → lower
|
|
852
|
+
* signal) without ever being asked for again. Evicting keeps ranking quality from
|
|
853
|
+
* degrading as the Brain accumulates months of memories.
|
|
854
|
+
*/
|
|
855
|
+
TheBrainV2.MAX_ENTRIES = 8000;
|
|
856
|
+
/** How many entries to evict per pass once over MAX_ENTRIES — batched, not one-at-a-time. */
|
|
857
|
+
TheBrainV2.EVICT_BATCH = 500;
|
|
717
858
|
// ─── Global singleton ────────────────────────────────────────────────────────
|
|
718
859
|
let _brain = null;
|
|
719
860
|
function getBrain() {
|