@nxuss/lemma 1.2.4 → 1.3.1
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 +19 -5
- package/dist/cjs/infra/cli.d.ts.map +1 -1
- package/dist/cjs/infra/cli.js +10 -7
- package/dist/cjs/infra/cli.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 +39 -5
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +93 -1
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/utils/StateHashCache.d.ts +26 -0
- package/dist/cjs/utils/StateHashCache.d.ts.map +1 -0
- package/dist/cjs/utils/StateHashCache.js +107 -0
- package/dist/cjs/utils/StateHashCache.js.map +1 -0
- package/dist/cjs/utils/TokenReceipt.d.ts +24 -0
- package/dist/cjs/utils/TokenReceipt.d.ts.map +1 -0
- package/dist/cjs/utils/TokenReceipt.js +41 -0
- package/dist/cjs/utils/TokenReceipt.js.map +1 -0
- package/dist/esm/infra/cli.d.ts.map +1 -1
- package/dist/esm/infra/cli.js +10 -7
- package/dist/esm/infra/cli.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 +39 -5
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +93 -1
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/utils/StateHashCache.d.ts +26 -0
- package/dist/esm/utils/StateHashCache.d.ts.map +1 -0
- package/dist/esm/utils/StateHashCache.js +100 -0
- package/dist/esm/utils/StateHashCache.js.map +1 -0
- package/dist/esm/utils/TokenReceipt.d.ts +24 -0
- package/dist/esm/utils/TokenReceipt.d.ts.map +1 -0
- package/dist/esm/utils/TokenReceipt.js +36 -0
- package/dist/esm/utils/TokenReceipt.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StateHashCache — reasoning cache keyed to the exact content hash of the files
|
|
3
|
+
* a question depends on, instead of semantic similarity between questions.
|
|
4
|
+
*
|
|
5
|
+
* Unlike a fuzzy/vector cache, a hit here is only returned if every referenced
|
|
6
|
+
* file's current sha256 matches the hash recorded when the answer was stored.
|
|
7
|
+
* If any referenced file changed, it's a guaranteed MISS — no stale answers.
|
|
8
|
+
*/
|
|
9
|
+
export interface StateHashEntry {
|
|
10
|
+
id: string;
|
|
11
|
+
query: string;
|
|
12
|
+
answer: string;
|
|
13
|
+
fileHashes: Record<string, string>;
|
|
14
|
+
createdAt: number;
|
|
15
|
+
hits: number;
|
|
16
|
+
}
|
|
17
|
+
export interface StateHashLookupResult {
|
|
18
|
+
status: 'hit' | 'miss';
|
|
19
|
+
entry?: StateHashEntry;
|
|
20
|
+
reason?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Look up a cached answer. Only a hit if every referenced file's hash still matches. */
|
|
23
|
+
export declare function lookupStateHash(projectRoot: string, query: string, filePaths: string[]): StateHashLookupResult;
|
|
24
|
+
/** Store an answer along with the exact hash of every file it depends on. */
|
|
25
|
+
export declare function storeStateHash(projectRoot: string, query: string, answer: string, filePaths: string[]): StateHashEntry;
|
|
26
|
+
//# sourceMappingURL=StateHashCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateHashCache.d.ts","sourceRoot":"","sources":["../../../src/utils/StateHashCache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AA+CD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EAAE,GAClB,qBAAqB,CAwBvB;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EAAE,GAClB,cAAc,CAmBhB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* StateHashCache — reasoning cache keyed to the exact content hash of the files
|
|
4
|
+
* a question depends on, instead of semantic similarity between questions.
|
|
5
|
+
*
|
|
6
|
+
* Unlike a fuzzy/vector cache, a hit here is only returned if every referenced
|
|
7
|
+
* file's current sha256 matches the hash recorded when the answer was stored.
|
|
8
|
+
* If any referenced file changed, it's a guaranteed MISS — no stale answers.
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.lookupStateHash = lookupStateHash;
|
|
15
|
+
exports.storeStateHash = storeStateHash;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
19
|
+
const CACHE_FILE = '.lemma/state-hash-cache.json';
|
|
20
|
+
function getCachePath(projectRoot) {
|
|
21
|
+
return path_1.default.join(projectRoot, CACHE_FILE);
|
|
22
|
+
}
|
|
23
|
+
function loadCache(projectRoot) {
|
|
24
|
+
try {
|
|
25
|
+
const p = getCachePath(projectRoot);
|
|
26
|
+
if (fs_1.default.existsSync(p))
|
|
27
|
+
return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
|
|
28
|
+
}
|
|
29
|
+
catch { }
|
|
30
|
+
return { entries: [] };
|
|
31
|
+
}
|
|
32
|
+
function saveCache(projectRoot, data) {
|
|
33
|
+
try {
|
|
34
|
+
const dir = path_1.default.join(projectRoot, '.lemma');
|
|
35
|
+
if (!fs_1.default.existsSync(dir))
|
|
36
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
37
|
+
fs_1.default.writeFileSync(getCachePath(projectRoot), JSON.stringify(data, null, 2), 'utf8');
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
}
|
|
41
|
+
function sha256(content) {
|
|
42
|
+
return crypto_1.default.createHash('sha256').update(content).digest('hex');
|
|
43
|
+
}
|
|
44
|
+
function hashFiles(projectRoot, filePaths) {
|
|
45
|
+
const hashes = {};
|
|
46
|
+
for (const rel of filePaths) {
|
|
47
|
+
try {
|
|
48
|
+
const resolved = path_1.default.resolve(projectRoot, rel);
|
|
49
|
+
if (fs_1.default.existsSync(resolved)) {
|
|
50
|
+
hashes[rel] = sha256(fs_1.default.readFileSync(resolved, 'utf8'));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
hashes[rel] = 'MISSING';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
hashes[rel] = 'ERROR';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return hashes;
|
|
61
|
+
}
|
|
62
|
+
/** Look up a cached answer. Only a hit if every referenced file's hash still matches. */
|
|
63
|
+
function lookupStateHash(projectRoot, query, filePaths) {
|
|
64
|
+
const data = loadCache(projectRoot);
|
|
65
|
+
const currentHashes = hashFiles(projectRoot, filePaths);
|
|
66
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
67
|
+
const entry = data.entries.find((e) => e.query.trim().toLowerCase() === normalizedQuery);
|
|
68
|
+
if (!entry)
|
|
69
|
+
return { status: 'miss', reason: 'no entry for this exact query' };
|
|
70
|
+
for (const [file, hash] of Object.entries(entry.fileHashes)) {
|
|
71
|
+
if (currentHashes[file] !== hash) {
|
|
72
|
+
return { status: 'miss', reason: `file changed since caching: ${file}` };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Also fail if the caller now depends on a file that wasn't tracked before —
|
|
76
|
+
// conservative: only trust the cache if the tracked set covers what's asked now.
|
|
77
|
+
for (const f of filePaths) {
|
|
78
|
+
if (!(f in entry.fileHashes)) {
|
|
79
|
+
return { status: 'miss', reason: `new dependency not covered by cached entry: ${f}` };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
entry.hits += 1;
|
|
83
|
+
saveCache(projectRoot, data);
|
|
84
|
+
return { status: 'hit', entry };
|
|
85
|
+
}
|
|
86
|
+
/** Store an answer along with the exact hash of every file it depends on. */
|
|
87
|
+
function storeStateHash(projectRoot, query, answer, filePaths) {
|
|
88
|
+
const data = loadCache(projectRoot);
|
|
89
|
+
const fileHashes = hashFiles(projectRoot, filePaths);
|
|
90
|
+
const entry = {
|
|
91
|
+
id: crypto_1.default.randomBytes(6).toString('hex'),
|
|
92
|
+
query,
|
|
93
|
+
answer,
|
|
94
|
+
fileHashes,
|
|
95
|
+
createdAt: Date.now(),
|
|
96
|
+
hits: 0,
|
|
97
|
+
};
|
|
98
|
+
data.entries = data.entries.filter((e) => e.query.trim().toLowerCase() !== query.trim().toLowerCase());
|
|
99
|
+
data.entries.push(entry);
|
|
100
|
+
// Bound cache size so it doesn't grow unboundedly.
|
|
101
|
+
if (data.entries.length > 500) {
|
|
102
|
+
data.entries = data.entries.slice(data.entries.length - 500);
|
|
103
|
+
}
|
|
104
|
+
saveCache(projectRoot, data);
|
|
105
|
+
return entry;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=StateHashCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateHashCache.js","sourceRoot":"","sources":["../../../src/utils/StateHashCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenReceipt — an auditable, per-session ledger of how each answer was produced:
|
|
3
|
+
* exact cache hit, semantic cache hit, file read, or fresh reasoning.
|
|
4
|
+
*
|
|
5
|
+
* The point is trust, not just savings: the user (or the model itself) can always
|
|
6
|
+
* ask "where did that answer actually come from" and get a verifiable trail,
|
|
7
|
+
* instead of taking a "X% tokens saved" claim on faith.
|
|
8
|
+
*/
|
|
9
|
+
export type ReceiptEventType = 'exact_cache_hit' | 'semantic_cache_hit' | 'file_read' | 'reasoning' | 'tool_call';
|
|
10
|
+
export interface ReceiptEvent {
|
|
11
|
+
type: ReceiptEventType;
|
|
12
|
+
label: string;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
meta?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export declare function recordReceiptEvent(type: ReceiptEventType, label: string, meta?: Record<string, unknown>): void;
|
|
17
|
+
export interface ReceiptSummary {
|
|
18
|
+
totalEvents: number;
|
|
19
|
+
byType: Record<ReceiptEventType, number>;
|
|
20
|
+
recent: ReceiptEvent[];
|
|
21
|
+
}
|
|
22
|
+
export declare function getReceiptSummary(limit?: number): ReceiptSummary;
|
|
23
|
+
export declare function clearReceiptLedger(): void;
|
|
24
|
+
//# sourceMappingURL=TokenReceipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenReceipt.d.ts","sourceRoot":"","sources":["../../../src/utils/TokenReceipt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,gBAAgB,GACxB,iBAAiB,GACjB,oBAAoB,GACpB,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAK9G;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,SAAK,GAAG,cAAc,CAc5D;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TokenReceipt — an auditable, per-session ledger of how each answer was produced:
|
|
4
|
+
* exact cache hit, semantic cache hit, file read, or fresh reasoning.
|
|
5
|
+
*
|
|
6
|
+
* The point is trust, not just savings: the user (or the model itself) can always
|
|
7
|
+
* ask "where did that answer actually come from" and get a verifiable trail,
|
|
8
|
+
* instead of taking a "X% tokens saved" claim on faith.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.recordReceiptEvent = recordReceiptEvent;
|
|
12
|
+
exports.getReceiptSummary = getReceiptSummary;
|
|
13
|
+
exports.clearReceiptLedger = clearReceiptLedger;
|
|
14
|
+
const MAX_EVENTS = 2000;
|
|
15
|
+
const sessionLedger = [];
|
|
16
|
+
function recordReceiptEvent(type, label, meta) {
|
|
17
|
+
sessionLedger.push({ type, label, timestamp: Date.now(), meta });
|
|
18
|
+
if (sessionLedger.length > MAX_EVENTS) {
|
|
19
|
+
sessionLedger.splice(0, sessionLedger.length - MAX_EVENTS);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function getReceiptSummary(limit = 20) {
|
|
23
|
+
const byType = {
|
|
24
|
+
exact_cache_hit: 0,
|
|
25
|
+
semantic_cache_hit: 0,
|
|
26
|
+
file_read: 0,
|
|
27
|
+
reasoning: 0,
|
|
28
|
+
tool_call: 0,
|
|
29
|
+
};
|
|
30
|
+
for (const e of sessionLedger)
|
|
31
|
+
byType[e.type]++;
|
|
32
|
+
return {
|
|
33
|
+
totalEvents: sessionLedger.length,
|
|
34
|
+
byType,
|
|
35
|
+
recent: sessionLedger.slice(-limit),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function clearReceiptLedger() {
|
|
39
|
+
sessionLedger.length = 0;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=TokenReceipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenReceipt.js","sourceRoot":"","sources":["../../../src/utils/TokenReceipt.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAoBH,gDAKC;AAQD,8CAcC;AAED,gDAEC;AAjDD,MAAM,UAAU,GAAG,IAAI,CAAC;AAgBxB,MAAM,aAAa,GAAmB,EAAE,CAAC;AAEzC,SAAgB,kBAAkB,CAAC,IAAsB,EAAE,KAAa,EAAE,IAA8B;IACtG,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QACtC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAQD,SAAgB,iBAAiB,CAAC,KAAK,GAAG,EAAE;IAC1C,MAAM,MAAM,GAAqC;QAC/C,eAAe,EAAE,CAAC;QAClB,kBAAkB,EAAE,CAAC;QACrB,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;KACb,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,aAAa;QAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;IAChD,OAAO;QACL,WAAW,EAAE,aAAa,CAAC,MAAM;QACjC,MAAM;QACN,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB;IAChC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/infra/cli.ts"],"names":[],"mappings":"AAIA,wBAAgB,qBAAqB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/infra/cli.ts"],"names":[],"mappings":"AAIA,wBAAgB,qBAAqB,IAAI,IAAI,CAgN5C"}
|
package/dist/esm/infra/cli.js
CHANGED
|
@@ -73,7 +73,8 @@ export function registerInfraCommands() {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
|
-
infra.command('deploy
|
|
76
|
+
const deploy = infra.command('deploy').description('Deploy via Jenkins or OKD');
|
|
77
|
+
deploy.command('jenkins')
|
|
77
78
|
.description('Generate and trigger Jenkins pipeline')
|
|
78
79
|
.option('-n, --name <name>', 'Project name')
|
|
79
80
|
.option('-j, --job <job>', 'Jenkins job name to trigger')
|
|
@@ -93,7 +94,7 @@ export function registerInfraCommands() {
|
|
|
93
94
|
console.log(result.success ? `Build triggered: ${result.logs[0]}` : `Failed: ${result.logs[0]}`);
|
|
94
95
|
}
|
|
95
96
|
});
|
|
96
|
-
|
|
97
|
+
deploy.command('okd')
|
|
97
98
|
.description('Generate and apply OKD manifests')
|
|
98
99
|
.option('-n, --name <name>', 'Application name')
|
|
99
100
|
.option('-i, --image <image>', 'Container image')
|
|
@@ -161,14 +162,15 @@ export function registerInfraCommands() {
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
});
|
|
164
|
-
infra.command('terraform
|
|
165
|
+
const terraform = infra.command('terraform').description('Manage Terraform plans and state');
|
|
166
|
+
terraform.command('plan')
|
|
165
167
|
.description('Run terraform plan')
|
|
166
168
|
.action(async () => {
|
|
167
169
|
const p = getProvider('terraform');
|
|
168
170
|
const plan = await p.plan();
|
|
169
171
|
console.log(plan);
|
|
170
172
|
});
|
|
171
|
-
|
|
173
|
+
terraform.command('apply')
|
|
172
174
|
.description('Run terraform apply')
|
|
173
175
|
.option('--auto-approve', 'Skip confirmation')
|
|
174
176
|
.action(async (opts) => {
|
|
@@ -176,14 +178,14 @@ export function registerInfraCommands() {
|
|
|
176
178
|
const result = await p.apply(opts.autoApprove);
|
|
177
179
|
console.log(result);
|
|
178
180
|
});
|
|
179
|
-
|
|
181
|
+
terraform.command('state')
|
|
180
182
|
.description('List resources in Terraform state')
|
|
181
183
|
.action(async () => {
|
|
182
184
|
const p = getProvider('terraform');
|
|
183
185
|
const resources = await p.stateList();
|
|
184
186
|
resources.forEach((r) => console.log(` ${r}`));
|
|
185
187
|
});
|
|
186
|
-
|
|
188
|
+
terraform.command('drift')
|
|
187
189
|
.description('Detect configuration drift')
|
|
188
190
|
.action(async () => {
|
|
189
191
|
const p = getProvider('terraform');
|
|
@@ -196,7 +198,8 @@ export function registerInfraCommands() {
|
|
|
196
198
|
console.log(` [${d.severity}] ${d.resource}: ${d.actual}`);
|
|
197
199
|
}
|
|
198
200
|
});
|
|
199
|
-
infra.command('analyze
|
|
201
|
+
const analyze = infra.command('analyze').description('Analyze codebase for infrastructure insights');
|
|
202
|
+
analyze.command('monolith')
|
|
200
203
|
.description('Analyze codebase for microservice migration')
|
|
201
204
|
.action(async () => {
|
|
202
205
|
const { analyzeMonolith } = require('./analyzers');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/infra/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/infra/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
2
|
export declare const LEMMA_SYSTEM_PROMPT = "You are connected to Lemma \u2014 an intelligent local-first AI gateway.\nLemma gives you a set of tools you MUST use proactively and automatically. NEVER ask the user\nto call a tool manually. YOU invoke the tools. The user should experience zero friction.\n\n## MANDATORY AUTOMATIC BEHAVIORS\n\n### 1. Before reading ANY file \u2192 call get_ast_hologram first\nWhen you need to understand the structure of a codebase or navigate files, ALWAYS call\n`get_ast_hologram` first (with the relevant dirPath, e.g. \"src\"). Use the returned symbol\nmap to pinpoint exactly which files to read. NEVER blindly read every file one by one.\n\n### 2. Before answering ANY technical question \u2192 call query_hybrid_consensus first\nBEFORE making any reasoning or cloud LLM call, ALWAYS call `query_hybrid_consensus` with\nthe user's question. If similarity \u2265 80%, return the cached answer immediately \u2014 no cloud\ncall needed. Only proceed with your own reasoning if the Brain returns a MISS.\n\n### 3. When you start working on ANY file \u2192 call get_telepathic_hints automatically\nWhenever the user mentions a file or you are about to read/edit a file, IMMEDIATELY call\n`get_telepathic_hints` with that file's path. Surface the results to the user as relevant\ncontext BEFORE doing any work. Do not ask permission \u2014 just do it.\n\n### 4. Before applying ANY code patch \u2192 call validate_patch_sandbox first\nNEVER call `write_workspace_file` or `apply_workspace_patch` without FIRST calling\n`validate_patch_sandbox` with the proposed content. Only proceed with the write if the\nverdict is \"\u2705 SAFE TO APPLY\". If it fails, fix the issues and re-validate.\n\n### 5. After solving any technical problem \u2192 call store_memory automatically\nAfter resolving a bug, implementing a feature, or answering a significant technical question,\nALWAYS call `store_memory` to persist the solution. Use a descriptive query key so it can\nbe retrieved in future sessions across ALL projects.\n\n### 6. Workspace navigation \u2192 always use Lemma tools, NEVER guess file contents\n- Use `list_workspace_dir` to navigate structure\n- Use `read_workspace_file` (auto-compresses + scrubs secrets) instead of asking the user\n- Use `search_workspace` for text search across files\n- Use `run_workspace_command` for builds, tests, linters\n\n### 7. Privacy is automatic\n`read_workspace_file` and `search_workspace` automatically scrub API keys and PII.\nYou never need to manually sanitize file content.\n\n## LEMMA RESOURCES (auto-subscribe when available)\n- `lemma://runtime/context` \u2014 live crash logs. Read this FIRST when the user reports a bug.\n- `lemma://multiverse/timeline` \u2014 AST history. Use when the user says \"it was working before\".\n- `lemma://project/onboarding` \u2014 architecture map. Read at session start in new repos.\n- `lemma://stats/usage` \u2014 token savings report.\n\nRemember: the user hired YOU to be autonomous. Act like it.";
|
|
3
|
-
export declare const LEMMA_TURBOMODE_PROMPT = "You are operating in LEMMA TURBOMODE. Your goal: multiply the user's LLM membership 50x by spending 50x fewer tokens per task. Every token counts. Every cache hit is a membership extension.\n\n## MANDATORY TURBOMODE RULES \u2014 VIOLATE THESE AND YOU WASTE THE USER'S MONEY\n\n### 0. Before ANYTHING \u2192 check token_budget\nEvery 5 turns, call `token_budget` to check your consumption. If multiplier drops below 10x, optimize harder.\n\n### 1.
|
|
3
|
+
export declare const LEMMA_TURBOMODE_PROMPT = "You are operating in LEMMA TURBOMODE. Your goal: multiply the user's LLM membership 50x by spending 50x fewer tokens per task. Every token counts. Every cache hit is a membership extension.\n\n## MANDATORY TURBOMODE RULES \u2014 VIOLATE THESE AND YOU WASTE THE USER'S MONEY\n\n### 0. Before ANYTHING \u2192 check token_budget\nEvery 5 turns, call `token_budget` to check your consumption. If multiplier drops below 10x, optimize harder.\n\n### 1. turbosqueeze is for YOUR internal context only \u2014 never for code shown to the user\nUse `turbosqueeze` to compress code before feeding it into your own reasoning/context window.\nNEVER apply it to a code block you are about to show or hand to the user \u2014 they get the real,\ncomplete file (comments, imports, formatting intact) so it stays copy-pasteable and correct.\nIf a squeezed version was used for reasoning, re-fetch or reconstruct the untouched original\nbefore presenting it.\n\n### 2. smarter_cache (threshold 0.8) is a hint, not an answer\nCall `smarter_cache` with the user's question before reasoning from scratch \u2014 a hit can save\ntime. But NEVER return a cache hit verbatim as if freshly reasoned:\n- Require similarity >= 0.8 (raised from 0.75 \u2014 0.75 was matching questions that weren't\n actually the same question).\n- Always tell the user the answer came from cache (e.g. \"from a cached earlier answer:\").\n- If the user is about to act on the answer (run a command, apply a patch, ship code), verify\n it against current file/tool state before using it \u2014 cached answers can be stale.\n- On a MISS, or on any doubt, reason normally.\n\n### 3. Before every new turn \u2192 call compress_context\nAt the start of any extended interaction, call `compress_context` on the full message history. Keep only the last 3 turns intact. Summarize everything before that into 2 sentences. This keeps your context window lean.\n\n### 4. Before reading files \u2192 call get_ast_hologram\nNEVER read files blindly. Always call `get_ast_hologram` first to locate the exact symbols you need. Then read only those specific files. Each unnecessary file read wastes 1000+ tokens.\n\n### 4b. Before re-reading a file \u2192 call file_fingerprint\nBefore calling read_workspace_file, check if the file hash has changed since last read. If status is 'unchanged', skip the read entirely. Only read when hash differs.\n\n### 4c. Before deep file analysis \u2192 use import_tree_context + type_coverage_report\nInstead of reading full files to understand architecture, call import_tree_context (import graph) and type_coverage_report (type safety). Both are zero-token tools.\n\n### 4d. Before investigating code ownership \u2192 call git_blame_heat\nFor questions about who wrote code, why it's risky, or change history, call git_blame_heat instead of reasoning. Zero LLM cost.\n\n### 5. After every solution \u2192 call store_memory automatically\nEvery bug fix, feature, or answer MUST be stored via `store_memory`. This creates a permanent cache hit for future sessions. The first time costs tokens; every time after is FREE.\n\n### 6. Answer concisely \u2014 no fluff\n- No \"Sure, I can help you with that\" \u2014 just do it.\n- No explanation of what you did \u2014 unless asked.\n- No markdown formatting in internal responses.\n- No repeating the user's question back to them.\n\n### 7. Use batch_tool_calls aggressively\nAny set of independent operations (read 3 files, search 2 patterns, check cache for 2 questions) \u2014 use `batch_tool_calls` to run them in parallel. Single round-trip > multiple sequential calls.\n\n### 8. Before multi-file operations \u2192 use auto_context_bundle or bulk_file_digest\nInstead of reading files one by one, use `auto_context_bundle` (one file, everything included) or `bulk_file_digest` (multiple files, one call). Both save 75-80% round-trips.\n\n### 9. Before outputting long responses \u2192 check repeat_guard\nCall `repeat_guard` with your draft output to avoid repeating yourself. Saves 10-15% of output tokens.\n\n### 9b. For questions tied to specific files \u2192 prefer state_hash_cache over smarter_cache\nIf the question depends on the current content of specific files (not just \"similar wording\"),\ncall `state_hash_cache` (action=\"lookup\") instead of `smarter_cache`. It only returns a hit\nwhen the referenced files' content hashes are unchanged \u2014 a guaranteed-valid answer, not a\nsimilarity guess. After answering, call it again with action=\"store\" to cache it. Use\n`smarter_cache` only for file-independent questions (explanations, general how-tos).\n\n### 9c. Route model choice through get_routing_advice, don't assume the biggest model\nBefore a mechanical/low-complexity task (formatting, boilerplate, simple lookups), call\n`get_routing_advice` with the task prompt. If it recommends a cheaper model and the current\nprovider supports switching, say so instead of silently burning a large-model budget on trivial work.\n\n### 9d. Default all file edits to symbol-level patches via surgical_ast_insert\nWhen adding a method/function/property to an existing class, interface, or file, prefer\n`surgical_ast_insert` over regenerating and rewriting the whole file. Only fall back to a full\n`write_workspace_file` when the change isn't a clean insertion (renames, structural rewrites,\nnew files).\n\n### 9e. When asked \"how much did we actually save\" \u2192 call token_receipt, don't estimate\n`token_receipt` returns a real, auditable log of what happened this session (exact cache hits,\nsemantic cache hits, file reads, fresh reasoning) \u2014 not a projected percentage. Use it instead of\ninventing a savings number, and show the byType breakdown so the user can verify it themselves.\n\n### 10. When resuming work \u2192 load conversation_checkpoint\nAt session start or when user says \"continuemos\", call `conversation_checkpoint` with action \"load\" to restore context without re-explaining.\n\n### 11. When tests fail \u2192 use test_autofix_interceptor\nInstead of manually reading errors and reasoning, call `test_autofix_interceptor` to get failures + Brain-suggested fixes in one call.\n\n### 12. For common prompt patterns \u2192 use prompt_pattern_cache\nBefore generating repetitive prompts (\"explain this\", \"review this\", \"write tests\"), check `prompt_pattern_cache` action \"find\" for cached templates.\n\n## TURBOMODE SCORING\n- Cache HIT = perfect score (0 tokens spent)\n- Cache MISS + compress = good score (< 100 tokens spent on overhead)\n- Reasoning from scratch = bad score (only when absolutely necessary)\n- Reading full files without hologram = FAIL (wasteful)\n\nRemember: this user has a deadline. Every token you save is time and money. Make every token count.";
|
|
4
4
|
export declare function setupPromptsHandlers(server: Server): void;
|
|
5
5
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,eAAO,MAAM,mBAAmB,m6FA+C4B,CAAC;AAE7D,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,eAAO,MAAM,mBAAmB,m6FA+C4B,CAAC;AAE7D,eAAO,MAAM,sBAAsB,ymNA+FiE,CAAC;AAErG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiDzD"}
|
package/dist/esm/mcp/prompts.js
CHANGED
|
@@ -54,11 +54,22 @@ export const LEMMA_TURBOMODE_PROMPT = `You are operating in LEMMA TURBOMODE. You
|
|
|
54
54
|
### 0. Before ANYTHING → check token_budget
|
|
55
55
|
Every 5 turns, call \`token_budget\` to check your consumption. If multiplier drops below 10x, optimize harder.
|
|
56
56
|
|
|
57
|
-
### 1.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
### 1. turbosqueeze is for YOUR internal context only — never for code shown to the user
|
|
58
|
+
Use \`turbosqueeze\` to compress code before feeding it into your own reasoning/context window.
|
|
59
|
+
NEVER apply it to a code block you are about to show or hand to the user — they get the real,
|
|
60
|
+
complete file (comments, imports, formatting intact) so it stays copy-pasteable and correct.
|
|
61
|
+
If a squeezed version was used for reasoning, re-fetch or reconstruct the untouched original
|
|
62
|
+
before presenting it.
|
|
63
|
+
|
|
64
|
+
### 2. smarter_cache (threshold 0.8) is a hint, not an answer
|
|
65
|
+
Call \`smarter_cache\` with the user's question before reasoning from scratch — a hit can save
|
|
66
|
+
time. But NEVER return a cache hit verbatim as if freshly reasoned:
|
|
67
|
+
- Require similarity >= 0.8 (raised from 0.75 — 0.75 was matching questions that weren't
|
|
68
|
+
actually the same question).
|
|
69
|
+
- Always tell the user the answer came from cache (e.g. "from a cached earlier answer:").
|
|
70
|
+
- If the user is about to act on the answer (run a command, apply a patch, ship code), verify
|
|
71
|
+
it against current file/tool state before using it — cached answers can be stale.
|
|
72
|
+
- On a MISS, or on any doubt, reason normally.
|
|
62
73
|
|
|
63
74
|
### 3. Before every new turn → call compress_context
|
|
64
75
|
At the start of any extended interaction, call \`compress_context\` on the full message history. Keep only the last 3 turns intact. Summarize everything before that into 2 sentences. This keeps your context window lean.
|
|
@@ -93,6 +104,29 @@ Instead of reading files one by one, use \`auto_context_bundle\` (one file, ever
|
|
|
93
104
|
### 9. Before outputting long responses → check repeat_guard
|
|
94
105
|
Call \`repeat_guard\` with your draft output to avoid repeating yourself. Saves 10-15% of output tokens.
|
|
95
106
|
|
|
107
|
+
### 9b. For questions tied to specific files → prefer state_hash_cache over smarter_cache
|
|
108
|
+
If the question depends on the current content of specific files (not just "similar wording"),
|
|
109
|
+
call \`state_hash_cache\` (action="lookup") instead of \`smarter_cache\`. It only returns a hit
|
|
110
|
+
when the referenced files' content hashes are unchanged — a guaranteed-valid answer, not a
|
|
111
|
+
similarity guess. After answering, call it again with action="store" to cache it. Use
|
|
112
|
+
\`smarter_cache\` only for file-independent questions (explanations, general how-tos).
|
|
113
|
+
|
|
114
|
+
### 9c. Route model choice through get_routing_advice, don't assume the biggest model
|
|
115
|
+
Before a mechanical/low-complexity task (formatting, boilerplate, simple lookups), call
|
|
116
|
+
\`get_routing_advice\` with the task prompt. If it recommends a cheaper model and the current
|
|
117
|
+
provider supports switching, say so instead of silently burning a large-model budget on trivial work.
|
|
118
|
+
|
|
119
|
+
### 9d. Default all file edits to symbol-level patches via surgical_ast_insert
|
|
120
|
+
When adding a method/function/property to an existing class, interface, or file, prefer
|
|
121
|
+
\`surgical_ast_insert\` over regenerating and rewriting the whole file. Only fall back to a full
|
|
122
|
+
\`write_workspace_file\` when the change isn't a clean insertion (renames, structural rewrites,
|
|
123
|
+
new files).
|
|
124
|
+
|
|
125
|
+
### 9e. When asked "how much did we actually save" → call token_receipt, don't estimate
|
|
126
|
+
\`token_receipt\` returns a real, auditable log of what happened this session (exact cache hits,
|
|
127
|
+
semantic cache hits, file reads, fresh reasoning) — not a projected percentage. Use it instead of
|
|
128
|
+
inventing a savings number, and show the byType breakdown so the user can verify it themselves.
|
|
129
|
+
|
|
96
130
|
### 10. When resuming work → load conversation_checkpoint
|
|
97
131
|
At session start or when user says "continuemos", call \`conversation_checkpoint\` with action "load" to restore context without re-explaining.
|
|
98
132
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAEtG,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA+CyB,CAAC;AAE7D,MAAM,CAAC,MAAM,sBAAsB,GAAG
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/mcp/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAEtG,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA+CyB,CAAC;AAE7D,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oGA+F8D,CAAC;AAErG,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QAC5D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,iBAAiB;oBACvB,WAAW,EAAE,+JAA+J;oBAC5K,SAAS,EAAE,EAAE;iBACd;gBACD;oBACE,IAAI,EAAE,iBAAiB;oBACvB,WAAW,EAAE,wOAAwO;oBACrP,SAAS,EAAE,EAAE;iBACd;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9C,OAAO;gBACL,WAAW,EAAE,qCAAqC;gBAClD,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,mBAAmB;yBAC1B;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9C,OAAO;gBACL,WAAW,EAAE,8CAA8C;gBAC3D,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,sBAAsB;yBAC7B;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAwiCnE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAC1C,IAAI,CA2DN"}
|
package/dist/esm/mcp/tools.js
CHANGED
|
@@ -31,6 +31,8 @@ import { compressWormhole } from "../utils/WormholeCompressor";
|
|
|
31
31
|
import { generateExecutiveReport } from "../utils/ExecutiveReport";
|
|
32
32
|
import { surgicalASTInsert } from "../utils/SurgicalASTInsert";
|
|
33
33
|
import { getInfraToolDefinitions, getInfraToolHandlers, INFRA_TOOL_NAMES } from "../infra/mcp-tools";
|
|
34
|
+
import { lookupStateHash, storeStateHash } from "../utils/StateHashCache";
|
|
35
|
+
import { recordReceiptEvent, getReceiptSummary } from "../utils/TokenReceipt";
|
|
34
36
|
// ── Pro License Gate ──────────────────────────────────────────────────────────
|
|
35
37
|
const LICENSE_FILE = path.join(os.homedir(), '.lemma-cache', 'license.json');
|
|
36
38
|
let _proStatusCache = null;
|
|
@@ -50,7 +52,7 @@ function isProUser() {
|
|
|
50
52
|
}
|
|
51
53
|
const FREE_TOOLS = new Set([
|
|
52
54
|
// Cache & Memory — the hook that shows instant value
|
|
53
|
-
"smarter_cache", "search_memory", "store_memory",
|
|
55
|
+
"smarter_cache", "state_hash_cache", "token_receipt", "search_memory", "store_memory",
|
|
54
56
|
// Token optimization — shows what they're saving
|
|
55
57
|
"token_budget", "squeeze_prompt", "turbosqueeze",
|
|
56
58
|
// Utility — just enough to function
|
|
@@ -453,6 +455,31 @@ const toolDefinitions = [
|
|
|
453
455
|
required: ["query"],
|
|
454
456
|
},
|
|
455
457
|
},
|
|
458
|
+
{
|
|
459
|
+
name: "state_hash_cache",
|
|
460
|
+
description: "Cache de razonamiento con invalidación EXACTA (no probabilística): la respuesta queda atada al sha256 del contenido de los archivos de los que depende. Si esos archivos no cambiaron, el hit es matemáticamente válido, no una adivinanza por similitud. Usa action='lookup' antes de razonar sobre una pregunta que dependa de archivos específicos, y action='store' después de responder para cachearla.",
|
|
461
|
+
inputSchema: {
|
|
462
|
+
type: "object",
|
|
463
|
+
properties: {
|
|
464
|
+
action: { type: "string", enum: ["lookup", "store"], description: "lookup = buscar antes de razonar; store = guardar después de responder" },
|
|
465
|
+
query: { type: "string", description: "La pregunta o task, texto exacto" },
|
|
466
|
+
filePaths: { type: "array", items: { type: "string" }, description: "Archivos (relativos al workspace root) de los que depende la respuesta" },
|
|
467
|
+
answer: { type: "string", description: "Requerido solo para action='store': la respuesta a cachear" },
|
|
468
|
+
},
|
|
469
|
+
required: ["action", "query", "filePaths"],
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
name: "token_receipt",
|
|
474
|
+
description: "Recibo auditable de la sesión: de dónde vino cada respuesta (cache exacto, cache semántico, lectura de archivo, o razonamiento fresco). No es una estadística de 'ahorro' — es una bitácora verificable para que el usuario pueda comprobar que no se le está mintiendo con un cache hit inventado. Llamar con action='summary' para ver el reporte.",
|
|
475
|
+
inputSchema: {
|
|
476
|
+
type: "object",
|
|
477
|
+
properties: {
|
|
478
|
+
action: { type: "string", enum: ["summary"], default: "summary" },
|
|
479
|
+
limit: { type: "number", description: "Cuántos eventos recientes incluir en el detalle", default: 20 },
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
},
|
|
456
483
|
{
|
|
457
484
|
name: "token_budget",
|
|
458
485
|
description: "Muestra el dashboard de consumo: multiplicador actual de membresía, tokens ahorrados, tools usadas, y recomendaciones para optimizar más. Consultar periódicamente para auto-regular consumo.",
|
|
@@ -968,6 +995,8 @@ const toolHandlers = {
|
|
|
968
995
|
local_semantic_autofix: handleLocalSemanticAutofix,
|
|
969
996
|
compress_context: handleCompressContext,
|
|
970
997
|
smarter_cache: handleSmarterCache,
|
|
998
|
+
state_hash_cache: handleStateHashCache,
|
|
999
|
+
token_receipt: handleTokenReceipt,
|
|
971
1000
|
token_budget: handleTokenBudget,
|
|
972
1001
|
entropy_score: handleEntropyScore,
|
|
973
1002
|
coupling_radar: handleCouplingRadar,
|
|
@@ -2070,6 +2099,69 @@ async function handleSmarterCache(args) {
|
|
|
2070
2099
|
};
|
|
2071
2100
|
}
|
|
2072
2101
|
}
|
|
2102
|
+
// ── State Hash Cache (exact, non-probabilistic reasoning cache) ────
|
|
2103
|
+
async function handleStateHashCache(args) {
|
|
2104
|
+
const action = args?.action;
|
|
2105
|
+
const query = args?.query;
|
|
2106
|
+
const filePaths = Array.isArray(args?.filePaths) ? args.filePaths : [];
|
|
2107
|
+
if (!action || !query)
|
|
2108
|
+
throw new Error("action and query are required");
|
|
2109
|
+
const workspaceRoot = process.cwd();
|
|
2110
|
+
if (action === "lookup") {
|
|
2111
|
+
const result = lookupStateHash(workspaceRoot, query, filePaths);
|
|
2112
|
+
recordReceiptEvent(result.status === "hit" ? "exact_cache_hit" : "reasoning", query.substring(0, 100), { tool: "state_hash_cache", filePaths, reason: result.reason });
|
|
2113
|
+
if (result.status === "hit" && result.entry) {
|
|
2114
|
+
const tokensSaved = Math.floor(result.entry.answer.length / 4);
|
|
2115
|
+
try {
|
|
2116
|
+
reportSavings({ source: "cache", tokens: tokensSaved, toolName: "state_hash_cache", query: query.substring(0, 100) });
|
|
2117
|
+
}
|
|
2118
|
+
catch { }
|
|
2119
|
+
return {
|
|
2120
|
+
content: [{
|
|
2121
|
+
type: "text",
|
|
2122
|
+
text: JSON.stringify({
|
|
2123
|
+
status: "hit",
|
|
2124
|
+
answer: result.entry.answer,
|
|
2125
|
+
note: "Respuesta desde caché exacto (hash de archivos sin cambios) — no necesita re-razonar.",
|
|
2126
|
+
tokensSaved,
|
|
2127
|
+
}, null, 2),
|
|
2128
|
+
}],
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
return {
|
|
2132
|
+
content: [{
|
|
2133
|
+
type: "text",
|
|
2134
|
+
text: JSON.stringify({ status: "miss", reason: result.reason, hint: "Razona normalmente y luego llama action='store' con la respuesta." }, null, 2),
|
|
2135
|
+
}],
|
|
2136
|
+
};
|
|
2137
|
+
}
|
|
2138
|
+
if (action === "store") {
|
|
2139
|
+
const answer = args?.answer;
|
|
2140
|
+
if (!answer)
|
|
2141
|
+
throw new Error("answer is required for action='store'");
|
|
2142
|
+
const entry = storeStateHash(workspaceRoot, query, answer, filePaths);
|
|
2143
|
+
return {
|
|
2144
|
+
content: [{ type: "text", text: JSON.stringify({ status: "stored", id: entry.id, filesTracked: Object.keys(entry.fileHashes) }, null, 2) }],
|
|
2145
|
+
};
|
|
2146
|
+
}
|
|
2147
|
+
throw new Error(`Unknown action: ${action}. Use 'lookup' or 'store'.`);
|
|
2148
|
+
}
|
|
2149
|
+
// ── Token Receipt (auditable ledger, not a marketing stat) ─────────
|
|
2150
|
+
async function handleTokenReceipt(args) {
|
|
2151
|
+
const limit = typeof args?.limit === "number" ? args.limit : 20;
|
|
2152
|
+
const summary = getReceiptSummary(limit);
|
|
2153
|
+
return {
|
|
2154
|
+
content: [{
|
|
2155
|
+
type: "text",
|
|
2156
|
+
text: JSON.stringify({
|
|
2157
|
+
totalEvents: summary.totalEvents,
|
|
2158
|
+
byType: summary.byType,
|
|
2159
|
+
recentEvents: summary.recent,
|
|
2160
|
+
note: "Esto es una bitácora real de esta sesión, no una proyección de ahorro. Si byType.reasoning es alto, no hubo mucho cache — y está bien, es honesto.",
|
|
2161
|
+
}, null, 2),
|
|
2162
|
+
}],
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2073
2165
|
// ── Token Budget ─────────────────────────────────────────────────
|
|
2074
2166
|
async function handleTokenBudget(_args) {
|
|
2075
2167
|
const statsFile = path.join(os.homedir(), '.lemma-cache/stats.json');
|