squeezr-ai 1.17.12 → 1.18.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/dist/codexMitm.js +29 -27
- package/dist/compressor.d.ts +4 -0
- package/dist/compressor.js +42 -24
- package/dist/dashboard.d.ts +1 -1
- package/dist/dashboard.js +1218 -1217
- package/dist/gain.js +50 -22
- package/dist/limits.js +11 -4
- package/dist/server.js +29 -8
- package/dist/stats.d.ts +12 -0
- package/dist/stats.js +38 -4
- package/dist/systemPrompt.d.ts +5 -1
- package/dist/systemPrompt.js +5 -5
- package/package.json +66 -66
package/dist/codexMitm.js
CHANGED
|
@@ -16,33 +16,35 @@ export const BUNDLE_PATH = join(CA_DIR, 'bundle.crt');
|
|
|
16
16
|
export const MITM_PORT = config.mitmPort;
|
|
17
17
|
// ── CA generation ─────────────────────────────────────────────────────────────
|
|
18
18
|
function ensureCA() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
19
|
+
const certsExist = fs.existsSync(CA_KEY_PATH) && fs.existsSync(CA_CERT_PATH);
|
|
20
|
+
if (!certsExist) {
|
|
21
|
+
fs.mkdirSync(CA_DIR, { recursive: true, mode: 0o700 });
|
|
22
|
+
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
23
|
+
const cert = forge.pki.createCertificate();
|
|
24
|
+
cert.publicKey = keys.publicKey;
|
|
25
|
+
cert.serialNumber = '01';
|
|
26
|
+
cert.validity.notBefore = new Date();
|
|
27
|
+
cert.validity.notAfter = new Date();
|
|
28
|
+
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10);
|
|
29
|
+
const attrs = [{ name: 'commonName', value: 'Squeezr-MITM-CA' }];
|
|
30
|
+
cert.setSubject(attrs);
|
|
31
|
+
cert.setIssuer(attrs);
|
|
32
|
+
cert.setExtensions([
|
|
33
|
+
{ name: 'basicConstraints', cA: true },
|
|
34
|
+
{ name: 'keyUsage', keyCertSign: true, cRLSign: true },
|
|
35
|
+
]);
|
|
36
|
+
cert.sign(keys.privateKey, forge.md.sha256.create());
|
|
37
|
+
fs.writeFileSync(CA_KEY_PATH, forge.pki.privateKeyToPem(keys.privateKey), { mode: 0o600 });
|
|
38
|
+
fs.writeFileSync(CA_CERT_PATH, forge.pki.certificateToPem(cert), { mode: 0o644 });
|
|
39
|
+
console.log(`[squeezr/mitm] CA generated → ${CA_CERT_PATH}`);
|
|
40
|
+
}
|
|
41
|
+
// Always regenerate bundle.crt from the CA cert only.
|
|
42
|
+
// Avoid concatenating system CA bundles — they can contain certs that
|
|
43
|
+
// BoringSSL/Node.js rejects (e.g. on WSL), causing NODE_EXTRA_CA_CERTS to fail.
|
|
44
|
+
// Node.js already trusts its own built-in root CAs, so only the squeezr CA
|
|
45
|
+
// cert is needed here.
|
|
46
|
+
const caCertPem = fs.readFileSync(CA_CERT_PATH, 'utf-8');
|
|
47
|
+
fs.writeFileSync(BUNDLE_PATH, caCertPem, { mode: 0o644 });
|
|
46
48
|
}
|
|
47
49
|
// ── Per-host cert (cached) ────────────────────────────────────────────────────
|
|
48
50
|
const certCache = new Map();
|
package/dist/compressor.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export interface Savings {
|
|
|
11
11
|
}>;
|
|
12
12
|
dryRun: boolean;
|
|
13
13
|
sessionCacheHits: number;
|
|
14
|
+
detSavedChars?: number;
|
|
15
|
+
dedupSavedChars?: number;
|
|
16
|
+
aiSavedChars?: number;
|
|
17
|
+
overheadChars?: number;
|
|
14
18
|
}
|
|
15
19
|
export declare function getCache(config: Config): CompressionCache;
|
|
16
20
|
interface AnthropicMessage {
|
package/dist/compressor.js
CHANGED
|
@@ -92,9 +92,11 @@ function buildAndCache(original, result) {
|
|
|
92
92
|
const ratio = Math.round((1 - result.length / Math.max(original.length, 1)) * 100);
|
|
93
93
|
const id = storeOriginal(original);
|
|
94
94
|
const fullString = `[squeezr:${id} -${ratio}%] ${result}`;
|
|
95
|
-
const
|
|
95
|
+
const overheadChars = fullString.length - result.length; // tag overhead
|
|
96
|
+
// Real savings: original minus what's actually sent (fullString, including tag)
|
|
97
|
+
const savedChars = original.length - fullString.length;
|
|
96
98
|
setBlock(hashText(original), { fullString, savedChars, originalChars: original.length });
|
|
97
|
-
return { fullString, savedChars };
|
|
99
|
+
return { fullString, savedChars, overheadChars };
|
|
98
100
|
}
|
|
99
101
|
function extractAnthropicToolResults(messages, toolIdMap) {
|
|
100
102
|
const results = [];
|
|
@@ -152,10 +154,10 @@ export async function compressAnthropicMessages(messages, apiKey, config, system
|
|
|
152
154
|
// keep the most recent occurrence at full fidelity and replace earlier ones
|
|
153
155
|
// with a short reference (saves tokens, model still has access via expand).
|
|
154
156
|
const dedupedSet = new Set(); // "index:subIndex" keys — skip in later steps
|
|
157
|
+
let readDedupSaved = 0;
|
|
155
158
|
{
|
|
156
159
|
const readHashToId = new Map(); // hash → expand id of most recent
|
|
157
160
|
const seenMostRecent = new Set();
|
|
158
|
-
let readDedupSaved = 0;
|
|
159
161
|
let readDedupCount = 0;
|
|
160
162
|
// Scan newest → oldest: first encounter of each hash = most recent
|
|
161
163
|
for (let i = allResults.length - 1; i >= 0; i--) {
|
|
@@ -203,11 +205,11 @@ export async function compressAnthropicMessages(messages, apiKey, config, system
|
|
|
203
205
|
const candidates = allResults.slice(0, Math.max(0, allResults.length - effectiveKeepRecent(config)));
|
|
204
206
|
const toProcess = candidates.filter(c => c.text.length >= threshold && !dedupedSet.has(`${c.index}:${c.subIndex}`));
|
|
205
207
|
if (toProcess.length === 0)
|
|
206
|
-
return [msgs, emptySavings()];
|
|
208
|
+
return [msgs, emptySavings(false, detSaved, readDedupSaved)];
|
|
207
209
|
if (config.dryRun) {
|
|
208
210
|
const potential = toProcess.reduce((sum, c) => sum + c.text.length, 0);
|
|
209
211
|
console.log(`[squeezr dry-run] Would AI-compress ${toProcess.length} block(s) | potential -${potential.toLocaleString()} chars | pressure=${Math.round(pressure * 100)}%`);
|
|
210
|
-
return [msgs, emptySavings(true)];
|
|
212
|
+
return [msgs, emptySavings(true, detSaved, readDedupSaved)];
|
|
211
213
|
}
|
|
212
214
|
// Differential: split session cache hits from uncached
|
|
213
215
|
const sessionHits = [];
|
|
@@ -229,19 +231,24 @@ export async function compressAnthropicMessages(messages, apiKey, config, system
|
|
|
229
231
|
: [];
|
|
230
232
|
let totalOriginal = 0;
|
|
231
233
|
let totalCompressed = 0;
|
|
234
|
+
let totalOverhead = 0;
|
|
235
|
+
let totalAiSaved = 0;
|
|
232
236
|
const byTool = [];
|
|
233
237
|
for (const { index, subIndex, tool, block } of sessionHits) {
|
|
234
238
|
;
|
|
235
239
|
msgs[index].content[subIndex].content = block.fullString;
|
|
236
240
|
totalOriginal += block.originalChars;
|
|
237
241
|
totalCompressed += block.originalChars - block.savedChars;
|
|
242
|
+
totalAiSaved += block.savedChars;
|
|
238
243
|
byTool.push({ tool, savedChars: block.savedChars, originalChars: block.originalChars });
|
|
239
244
|
}
|
|
240
245
|
for (const { index, subIndex, original, result, tool } of freshlyCompressed) {
|
|
241
|
-
const { fullString, savedChars } = buildAndCache(original, result);
|
|
246
|
+
const { fullString, savedChars, overheadChars } = buildAndCache(original, result);
|
|
242
247
|
msgs[index].content[subIndex].content = fullString;
|
|
243
248
|
totalOriginal += original.length;
|
|
244
249
|
totalCompressed += original.length - savedChars;
|
|
250
|
+
totalOverhead += overheadChars;
|
|
251
|
+
totalAiSaved += savedChars;
|
|
245
252
|
byTool.push({ tool, savedChars, originalChars: original.length });
|
|
246
253
|
}
|
|
247
254
|
if (pressure >= 0.5)
|
|
@@ -255,6 +262,10 @@ export async function compressAnthropicMessages(messages, apiKey, config, system
|
|
|
255
262
|
byTool,
|
|
256
263
|
dryRun: false,
|
|
257
264
|
sessionCacheHits: sessionHits.length,
|
|
265
|
+
detSavedChars: detSaved,
|
|
266
|
+
dedupSavedChars: readDedupSaved,
|
|
267
|
+
aiSavedChars: totalAiSaved,
|
|
268
|
+
overheadChars: totalOverhead,
|
|
258
269
|
}];
|
|
259
270
|
}
|
|
260
271
|
function extractOpenAIToolResults(messages) {
|
|
@@ -293,10 +304,11 @@ export async function compressOpenAIMessages(messages, apiKey, config, isLocal =
|
|
|
293
304
|
const msgs = structuredClone(messages);
|
|
294
305
|
// Step 0: Cross-turn Read dedup
|
|
295
306
|
const dedupedIndices = new Set();
|
|
307
|
+
let readDedupSaved = 0;
|
|
296
308
|
{
|
|
297
309
|
const readHashToId = new Map();
|
|
298
310
|
const seenMostRecent = new Set();
|
|
299
|
-
let
|
|
311
|
+
let readDedupCount = 0;
|
|
300
312
|
for (let i = allResults.length - 1; i >= 0; i--) {
|
|
301
313
|
const { index, text, tool } = allResults[i];
|
|
302
314
|
if (tool.toLowerCase() !== 'read')
|
|
@@ -337,11 +349,11 @@ export async function compressOpenAIMessages(messages, apiKey, config, isLocal =
|
|
|
337
349
|
const candidates = allResults.slice(0, Math.max(0, allResults.length - effectiveKeepRecent(config)));
|
|
338
350
|
const toProcess = candidates.filter(c => c.text.length >= threshold && !dedupedIndices.has(c.index));
|
|
339
351
|
if (toProcess.length === 0)
|
|
340
|
-
return [msgs, emptySavings()];
|
|
352
|
+
return [msgs, emptySavings(false, detSaved, readDedupSaved)];
|
|
341
353
|
if (config.dryRun) {
|
|
342
354
|
const tag = isLocal ? 'ollama' : 'codex';
|
|
343
355
|
console.log(`[squeezr dry-run/${tag}] Would AI-compress ${toProcess.length} block(s) | potential -${toProcess.reduce((s, c) => s + c.text.length, 0).toLocaleString()} chars`);
|
|
344
|
-
return [msgs, emptySavings(true)];
|
|
356
|
+
return [msgs, emptySavings(true, detSaved, readDedupSaved)];
|
|
345
357
|
}
|
|
346
358
|
const sessionHits = [];
|
|
347
359
|
const toCompress = [];
|
|
@@ -354,7 +366,6 @@ export async function compressOpenAIMessages(messages, apiKey, config, isLocal =
|
|
|
354
366
|
sessionHits.push({ index: c.index, tool: c.tool, block: cached });
|
|
355
367
|
}
|
|
356
368
|
else if (aiEnabled() && c.index > newStartIdx && !config.aiSkipTools.has(c.tool.toLowerCase())) {
|
|
357
|
-
// Only AI-compress new tool results (after last assistant turn) — prevents burst on first activation.
|
|
358
369
|
toCompress.push(c);
|
|
359
370
|
}
|
|
360
371
|
}
|
|
@@ -364,19 +375,22 @@ export async function compressOpenAIMessages(messages, apiKey, config, isLocal =
|
|
|
364
375
|
const freshlyCompressed = toCompress.length > 0
|
|
365
376
|
? await runCompression(toCompress, compressFn, config)
|
|
366
377
|
: [];
|
|
367
|
-
let totalOriginal = 0, totalCompressed = 0;
|
|
378
|
+
let totalOriginal = 0, totalCompressed = 0, totalOverhead = 0, totalAiSaved = 0;
|
|
368
379
|
const byTool = [];
|
|
369
380
|
for (const { index, tool, block } of sessionHits) {
|
|
370
381
|
msgs[index].content = block.fullString;
|
|
371
382
|
totalOriginal += block.originalChars;
|
|
372
383
|
totalCompressed += block.originalChars - block.savedChars;
|
|
384
|
+
totalAiSaved += block.savedChars;
|
|
373
385
|
byTool.push({ tool, savedChars: block.savedChars, originalChars: block.originalChars });
|
|
374
386
|
}
|
|
375
387
|
for (const { index, original, result, tool } of freshlyCompressed) {
|
|
376
|
-
const { fullString, savedChars } = buildAndCache(original, result);
|
|
388
|
+
const { fullString, savedChars, overheadChars } = buildAndCache(original, result);
|
|
377
389
|
msgs[index].content = fullString;
|
|
378
390
|
totalOriginal += original.length;
|
|
379
391
|
totalCompressed += original.length - savedChars;
|
|
392
|
+
totalOverhead += overheadChars;
|
|
393
|
+
totalAiSaved += savedChars;
|
|
380
394
|
byTool.push({ tool, savedChars, originalChars: original.length });
|
|
381
395
|
}
|
|
382
396
|
if (pressure >= 0.5) {
|
|
@@ -385,7 +399,7 @@ export async function compressOpenAIMessages(messages, apiKey, config, isLocal =
|
|
|
385
399
|
}
|
|
386
400
|
if (sessionHits.length > 0)
|
|
387
401
|
console.log(`[squeezr] Session cache: ${sessionHits.length} block(s) reused`);
|
|
388
|
-
return [msgs, { compressed: freshlyCompressed.length, savedChars: totalOriginal - totalCompressed, originalChars: totalOriginal, byTool, dryRun: false, sessionCacheHits: sessionHits.length }];
|
|
402
|
+
return [msgs, { compressed: freshlyCompressed.length, savedChars: totalOriginal - totalCompressed, originalChars: totalOriginal, byTool, dryRun: false, sessionCacheHits: sessionHits.length, detSavedChars: detSaved, dedupSavedChars: readDedupSaved, aiSavedChars: totalAiSaved, overheadChars: totalOverhead }];
|
|
389
403
|
}
|
|
390
404
|
export async function compressGeminiContents(contents, apiKey, config) {
|
|
391
405
|
if (config.disabled)
|
|
@@ -415,10 +429,11 @@ export async function compressGeminiContents(contents, apiKey, config) {
|
|
|
415
429
|
const cts = structuredClone(contents);
|
|
416
430
|
// Step 0: Cross-turn Read dedup
|
|
417
431
|
const geminiDedupedSet = new Set();
|
|
432
|
+
let geminiReadDedupSaved = 0;
|
|
418
433
|
{
|
|
419
434
|
const readHashToId = new Map();
|
|
420
435
|
const seenMostRecent = new Set();
|
|
421
|
-
let
|
|
436
|
+
let readDedupCount = 0;
|
|
422
437
|
for (let i = allResults.length - 1; i >= 0; i--) {
|
|
423
438
|
const { index, subIndex, text, tool } = allResults[i];
|
|
424
439
|
if (tool.toLowerCase() !== 'read')
|
|
@@ -432,11 +447,11 @@ export async function compressGeminiContents(contents, apiKey, config) {
|
|
|
432
447
|
cts[index].parts[subIndex].functionResponse.response = { output: `[same file content as a later read — squeezr_expand(${readHashToId.get(hash)}) to retrieve]` };
|
|
433
448
|
geminiDedupedSet.add(`${index}:${subIndex}`);
|
|
434
449
|
readDedupCount++;
|
|
435
|
-
|
|
450
|
+
geminiReadDedupSaved += text.length;
|
|
436
451
|
}
|
|
437
452
|
}
|
|
438
|
-
if (
|
|
439
|
-
console.log(`[squeezr/read-dedup/gemini] ${readDedupCount} duplicate file read(s) collapsed: -${
|
|
453
|
+
if (geminiReadDedupSaved > 0) {
|
|
454
|
+
console.log(`[squeezr/read-dedup/gemini] ${readDedupCount} duplicate file read(s) collapsed: -${geminiReadDedupSaved.toLocaleString()} chars`);
|
|
440
455
|
hitPattern('readDedup', readDedupCount);
|
|
441
456
|
}
|
|
442
457
|
}
|
|
@@ -457,10 +472,10 @@ export async function compressGeminiContents(contents, apiKey, config) {
|
|
|
457
472
|
const candidates = allResults.slice(0, Math.max(0, allResults.length - effectiveKeepRecent(config)))
|
|
458
473
|
.filter(c => c.text.length >= threshold && !geminiDedupedSet.has(`${c.index}:${c.subIndex}`));
|
|
459
474
|
if (candidates.length === 0)
|
|
460
|
-
return [cts, emptySavings()];
|
|
475
|
+
return [cts, emptySavings(false, detSaved, geminiReadDedupSaved)];
|
|
461
476
|
if (config.dryRun) {
|
|
462
477
|
console.log(`[squeezr dry-run/gemini] Would AI-compress ${candidates.length} block(s) | potential -${candidates.reduce((s, c) => s + c.text.length, 0).toLocaleString()} chars`);
|
|
463
|
-
return [cts, emptySavings(true)];
|
|
478
|
+
return [cts, emptySavings(true, detSaved, geminiReadDedupSaved)];
|
|
464
479
|
}
|
|
465
480
|
const sessionHits = [];
|
|
466
481
|
const toCompress = [];
|
|
@@ -474,25 +489,28 @@ export async function compressGeminiContents(contents, apiKey, config) {
|
|
|
474
489
|
const freshlyCompressed = toCompress.length > 0
|
|
475
490
|
? await runCompression(toCompress, t => compressWithGeminiFlash(t, apiKey), config)
|
|
476
491
|
: [];
|
|
477
|
-
let totalOriginal = 0, totalCompressed = 0;
|
|
492
|
+
let totalOriginal = 0, totalCompressed = 0, totalOverhead = 0, totalAiSaved = 0;
|
|
478
493
|
const byTool = [];
|
|
479
494
|
for (const { index, subIndex, tool, block } of sessionHits) {
|
|
480
495
|
cts[index].parts[subIndex].functionResponse.response = { output: block.fullString };
|
|
481
496
|
totalOriginal += block.originalChars;
|
|
482
497
|
totalCompressed += block.originalChars - block.savedChars;
|
|
498
|
+
totalAiSaved += block.savedChars;
|
|
483
499
|
byTool.push({ tool, savedChars: block.savedChars, originalChars: block.originalChars });
|
|
484
500
|
}
|
|
485
501
|
for (const { index, subIndex, original, result, tool } of freshlyCompressed) {
|
|
486
|
-
const { fullString, savedChars } = buildAndCache(original, result);
|
|
502
|
+
const { fullString, savedChars, overheadChars } = buildAndCache(original, result);
|
|
487
503
|
cts[index].parts[subIndex].functionResponse.response = { output: fullString };
|
|
488
504
|
totalOriginal += original.length;
|
|
489
505
|
totalCompressed += original.length - savedChars;
|
|
506
|
+
totalOverhead += overheadChars;
|
|
507
|
+
totalAiSaved += savedChars;
|
|
490
508
|
byTool.push({ tool, savedChars, originalChars: original.length });
|
|
491
509
|
}
|
|
492
510
|
if (sessionHits.length > 0)
|
|
493
511
|
console.log(`[squeezr/gemini] Session cache: ${sessionHits.length} block(s) reused`);
|
|
494
|
-
return [cts, { compressed: freshlyCompressed.length, savedChars: totalOriginal - totalCompressed, originalChars: totalOriginal, byTool, dryRun: false, sessionCacheHits: sessionHits.length }];
|
|
512
|
+
return [cts, { compressed: freshlyCompressed.length, savedChars: totalOriginal - totalCompressed, originalChars: totalOriginal, byTool, dryRun: false, sessionCacheHits: sessionHits.length, detSavedChars: detSaved, dedupSavedChars: geminiReadDedupSaved, aiSavedChars: totalAiSaved, overheadChars: totalOverhead }];
|
|
495
513
|
}
|
|
496
|
-
function emptySavings(dryRun = false) {
|
|
497
|
-
return { compressed: 0, savedChars: 0, originalChars: 0, byTool: [], dryRun, sessionCacheHits: 0 };
|
|
514
|
+
function emptySavings(dryRun = false, detSavedChars = 0, dedupSavedChars = 0) {
|
|
515
|
+
return { compressed: 0, savedChars: 0, originalChars: 0, byTool: [], dryRun, sessionCacheHits: 0, detSavedChars, dedupSavedChars, aiSavedChars: 0, overheadChars: 0 };
|
|
498
516
|
}
|