@blockrun/clawrouter 0.12.95 → 0.12.97
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/auth.d.ts +82 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +388 -0
- package/dist/auth.js.map +1 -0
- package/dist/balance.d.ts +97 -0
- package/dist/balance.d.ts.map +1 -0
- package/dist/balance.js +157 -0
- package/dist/balance.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +256 -54994
- package/dist/cli.js.map +1 -1
- package/dist/compression/codebook.d.ts +24 -0
- package/dist/compression/codebook.d.ts.map +1 -0
- package/dist/compression/codebook.js +119 -0
- package/dist/compression/codebook.js.map +1 -0
- package/dist/compression/index.d.ts +33 -0
- package/dist/compression/index.d.ts.map +1 -0
- package/dist/compression/index.js +246 -0
- package/dist/compression/index.js.map +1 -0
- package/dist/compression/layers/deduplication.d.ts +28 -0
- package/dist/compression/layers/deduplication.d.ts.map +1 -0
- package/dist/compression/layers/deduplication.js +101 -0
- package/dist/compression/layers/deduplication.js.map +1 -0
- package/dist/compression/layers/dictionary.d.ts +21 -0
- package/dist/compression/layers/dictionary.d.ts.map +1 -0
- package/dist/compression/layers/dictionary.js +73 -0
- package/dist/compression/layers/dictionary.js.map +1 -0
- package/dist/compression/layers/dynamic-codebook.d.ts +26 -0
- package/dist/compression/layers/dynamic-codebook.d.ts.map +1 -0
- package/dist/compression/layers/dynamic-codebook.js +149 -0
- package/dist/compression/layers/dynamic-codebook.js.map +1 -0
- package/dist/compression/layers/json-compact.d.ts +23 -0
- package/dist/compression/layers/json-compact.d.ts.map +1 -0
- package/dist/compression/layers/json-compact.js +79 -0
- package/dist/compression/layers/json-compact.js.map +1 -0
- package/dist/compression/layers/observation.d.ts +21 -0
- package/dist/compression/layers/observation.d.ts.map +1 -0
- package/dist/compression/layers/observation.js +130 -0
- package/dist/compression/layers/observation.js.map +1 -0
- package/dist/compression/layers/paths.d.ts +24 -0
- package/dist/compression/layers/paths.d.ts.map +1 -0
- package/dist/compression/layers/paths.js +110 -0
- package/dist/compression/layers/paths.js.map +1 -0
- package/dist/compression/layers/whitespace.d.ts +27 -0
- package/dist/compression/layers/whitespace.d.ts.map +1 -0
- package/dist/compression/layers/whitespace.js +60 -0
- package/dist/compression/layers/whitespace.js.map +1 -0
- package/dist/compression/types.d.ts +84 -0
- package/dist/compression/types.d.ts.map +1 -0
- package/dist/compression/types.js +27 -0
- package/dist/compression/types.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/dedup.d.ts +34 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/dedup.js +150 -0
- package/dist/dedup.js.map +1 -0
- package/dist/doctor.d.ts +8 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +375 -0
- package/dist/doctor.js.map +1 -0
- package/dist/error-classification.test.d.ts +2 -0
- package/dist/error-classification.test.d.ts.map +1 -0
- package/dist/error-classification.test.js +59 -0
- package/dist/error-classification.test.js.map +1 -0
- package/dist/errors.d.ts +54 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/exclude-models.d.ts +28 -0
- package/dist/exclude-models.d.ts.map +1 -0
- package/dist/exclude-models.integration.test.d.ts +2 -0
- package/dist/exclude-models.integration.test.d.ts.map +1 -0
- package/dist/exclude-models.integration.test.js +46 -0
- package/dist/exclude-models.integration.test.js.map +1 -0
- package/dist/exclude-models.js +70 -0
- package/dist/exclude-models.js.map +1 -0
- package/dist/exclude-models.test.d.ts +5 -0
- package/dist/exclude-models.test.d.ts.map +1 -0
- package/dist/exclude-models.test.js +95 -0
- package/dist/exclude-models.test.js.map +1 -0
- package/dist/fs-read.d.ts +11 -0
- package/dist/fs-read.d.ts.map +1 -0
- package/dist/fs-read.js +47 -0
- package/dist/fs-read.js.map +1 -0
- package/dist/index.d.ts +34 -1368
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1071 -56194
- package/dist/index.js.map +1 -1
- package/dist/journal.d.ts +67 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +184 -0
- package/dist/journal.js.map +1 -0
- package/dist/journal.test.d.ts +2 -0
- package/dist/journal.test.d.ts.map +1 -0
- package/dist/journal.test.js +201 -0
- package/dist/journal.test.js.map +1 -0
- package/dist/logger.d.ts +33 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +35 -0
- package/dist/logger.js.map +1 -0
- package/dist/models.d.ts +107 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +941 -0
- package/dist/models.js.map +1 -0
- package/dist/models.test.d.ts +2 -0
- package/dist/models.test.d.ts.map +1 -0
- package/dist/models.test.js +38 -0
- package/dist/models.test.js.map +1 -0
- package/dist/partners/index.d.ts +8 -0
- package/dist/partners/index.d.ts.map +1 -0
- package/dist/partners/index.js +6 -0
- package/dist/partners/index.js.map +1 -0
- package/dist/partners/registry.d.ts +51 -0
- package/dist/partners/registry.d.ts.map +1 -0
- package/dist/partners/registry.js +256 -0
- package/dist/partners/registry.js.map +1 -0
- package/dist/partners/tools.d.ts +24 -0
- package/dist/partners/tools.d.ts.map +1 -0
- package/dist/partners/tools.js +97 -0
- package/dist/partners/tools.js.map +1 -0
- package/dist/payment-preauth.d.ts +17 -0
- package/dist/payment-preauth.d.ts.map +1 -0
- package/dist/payment-preauth.js +102 -0
- package/dist/payment-preauth.js.map +1 -0
- package/dist/provider.d.ts +19 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +45 -0
- package/dist/provider.js.map +1 -0
- package/dist/proxy.d.ts +210 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.debrand.test.d.ts +2 -0
- package/dist/proxy.debrand.test.d.ts.map +1 -0
- package/dist/proxy.debrand.test.js +101 -0
- package/dist/proxy.debrand.test.js.map +1 -0
- package/dist/proxy.degraded-response.test.d.ts +2 -0
- package/dist/proxy.degraded-response.test.d.ts.map +1 -0
- package/dist/proxy.degraded-response.test.js +105 -0
- package/dist/proxy.degraded-response.test.js.map +1 -0
- package/dist/proxy.image-download.test.d.ts +2 -0
- package/dist/proxy.image-download.test.d.ts.map +1 -0
- package/dist/proxy.image-download.test.js +92 -0
- package/dist/proxy.image-download.test.js.map +1 -0
- package/dist/proxy.js +3810 -0
- package/dist/proxy.js.map +1 -0
- package/dist/proxy.models-endpoint.test.d.ts +2 -0
- package/dist/proxy.models-endpoint.test.d.ts.map +1 -0
- package/dist/proxy.models-endpoint.test.js +19 -0
- package/dist/proxy.models-endpoint.test.js.map +1 -0
- package/dist/proxy.multiturn-thinking.test.d.ts +2 -0
- package/dist/proxy.multiturn-thinking.test.d.ts.map +1 -0
- package/dist/proxy.multiturn-thinking.test.js +82 -0
- package/dist/proxy.multiturn-thinking.test.js.map +1 -0
- package/dist/proxy.payment-chain-reuse.test.d.ts +2 -0
- package/dist/proxy.payment-chain-reuse.test.d.ts.map +1 -0
- package/dist/proxy.payment-chain-reuse.test.js +30 -0
- package/dist/proxy.payment-chain-reuse.test.js.map +1 -0
- package/dist/proxy.solana-resilience.test.d.ts +12 -0
- package/dist/proxy.solana-resilience.test.d.ts.map +1 -0
- package/dist/proxy.solana-resilience.test.js +39 -0
- package/dist/proxy.solana-resilience.test.js.map +1 -0
- package/dist/report.d.ts +6 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +44 -0
- package/dist/report.js.map +1 -0
- package/dist/response-cache.advanced.test.d.ts +2 -0
- package/dist/response-cache.advanced.test.d.ts.map +1 -0
- package/dist/response-cache.advanced.test.js +566 -0
- package/dist/response-cache.advanced.test.js.map +1 -0
- package/dist/response-cache.d.ts +85 -0
- package/dist/response-cache.d.ts.map +1 -0
- package/dist/response-cache.edge-cases.test.d.ts +2 -0
- package/dist/response-cache.edge-cases.test.d.ts.map +1 -0
- package/dist/response-cache.edge-cases.test.js +488 -0
- package/dist/response-cache.edge-cases.test.js.map +1 -0
- package/dist/response-cache.extreme.test.d.ts +2 -0
- package/dist/response-cache.extreme.test.d.ts.map +1 -0
- package/dist/response-cache.extreme.test.js +561 -0
- package/dist/response-cache.extreme.test.js.map +1 -0
- package/dist/response-cache.js +240 -0
- package/dist/response-cache.js.map +1 -0
- package/dist/response-cache.test.d.ts +2 -0
- package/dist/response-cache.test.d.ts.map +1 -0
- package/dist/response-cache.test.js +242 -0
- package/dist/response-cache.test.js.map +1 -0
- package/dist/retry.d.ts +42 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +99 -0
- package/dist/retry.js.map +1 -0
- package/dist/router/config.d.ts +11 -0
- package/dist/router/config.d.ts.map +1 -0
- package/dist/router/config.js +1215 -0
- package/dist/router/config.js.map +1 -0
- package/dist/router/index.d.ts +18 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +19 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/llm-classifier.d.ts +29 -0
- package/dist/router/llm-classifier.d.ts.map +1 -0
- package/dist/router/llm-classifier.js +99 -0
- package/dist/router/llm-classifier.js.map +1 -0
- package/dist/router/rules.d.ts +12 -0
- package/dist/router/rules.d.ts.map +1 -0
- package/dist/router/rules.js +202 -0
- package/dist/router/rules.js.map +1 -0
- package/dist/router/selector.d.ts +58 -0
- package/dist/router/selector.d.ts.map +1 -0
- package/dist/router/selector.js +165 -0
- package/dist/router/selector.js.map +1 -0
- package/dist/router/selector.test.d.ts +2 -0
- package/dist/router/selector.test.d.ts.map +1 -0
- package/dist/router/selector.test.js +67 -0
- package/dist/router/selector.test.js.map +1 -0
- package/dist/router/strategy.d.ts +19 -0
- package/dist/router/strategy.d.ts.map +1 -0
- package/dist/router/strategy.js +138 -0
- package/dist/router/strategy.js.map +1 -0
- package/dist/router/strategy.test.d.ts +2 -0
- package/dist/router/strategy.test.d.ts.map +1 -0
- package/dist/router/strategy.test.js +131 -0
- package/dist/router/strategy.test.js.map +1 -0
- package/dist/router/types.d.ts +127 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +11 -0
- package/dist/router/types.js.map +1 -0
- package/dist/session.d.ts +124 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +256 -0
- package/dist/session.js.map +1 -0
- package/dist/session.test.d.ts +2 -0
- package/dist/session.test.d.ts.map +1 -0
- package/dist/session.test.js +163 -0
- package/dist/session.test.js.map +1 -0
- package/dist/solana-balance.d.ts +48 -0
- package/dist/solana-balance.d.ts.map +1 -0
- package/dist/solana-balance.js +142 -0
- package/dist/solana-balance.js.map +1 -0
- package/dist/spend-control.d.ts +112 -0
- package/dist/spend-control.d.ts.map +1 -0
- package/dist/spend-control.js +278 -0
- package/dist/spend-control.js.map +1 -0
- package/dist/spend-control.test.d.ts +5 -0
- package/dist/spend-control.test.d.ts.map +1 -0
- package/dist/spend-control.test.js +210 -0
- package/dist/spend-control.test.js.map +1 -0
- package/dist/stats.d.ts +64 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +295 -0
- package/dist/stats.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/update-hint.test.d.ts +9 -0
- package/dist/update-hint.test.d.ts.map +1 -0
- package/dist/update-hint.test.js +156 -0
- package/dist/update-hint.test.js.map +1 -0
- package/dist/updater.d.ts +10 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +55 -0
- package/dist/updater.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -0
- package/dist/wallet.d.ts +52 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +93 -0
- package/dist/wallet.js.map +1 -0
- package/dist/wallet.test.d.ts +6 -0
- package/dist/wallet.test.d.ts.map +1 -0
- package/dist/wallet.test.js +117 -0
- package/dist/wallet.test.js.map +1 -0
- package/dist/x402-sdk.test.d.ts +6 -0
- package/dist/x402-sdk.test.d.ts.map +1 -0
- package/dist/x402-sdk.test.js +161 -0
- package/dist/x402-sdk.test.js.map +1 -0
- package/package.json +1 -1
- package/scripts/e2e-multiturn.mjs +4 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dictionary Codebook
|
|
3
|
+
*
|
|
4
|
+
* Static dictionary of frequently repeated phrases observed in LLM prompts.
|
|
5
|
+
* Built from analysis of BlockRun production logs.
|
|
6
|
+
*
|
|
7
|
+
* Format: Short code ($XX) -> Long phrase
|
|
8
|
+
* The LLM receives a codebook header and decodes in-context.
|
|
9
|
+
*/
|
|
10
|
+
export declare const STATIC_CODEBOOK: Record<string, string>;
|
|
11
|
+
/**
|
|
12
|
+
* Get the inverse codebook for decompression.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getInverseCodebook(): Record<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* Generate the codebook header for inclusion in system message.
|
|
17
|
+
* LLMs can decode in-context using this header.
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateCodebookHeader(usedCodes: Set<string>, pathMap?: Record<string, string>): string;
|
|
20
|
+
/**
|
|
21
|
+
* Decompress a string using the codebook (for logging).
|
|
22
|
+
*/
|
|
23
|
+
export declare function decompressContent(content: string, codebook?: Record<string, string>): string;
|
|
24
|
+
//# sourceMappingURL=codebook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebook.d.ts","sourceRoot":"","sources":["../../src/compression/codebook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuElD,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAM3D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,MAAM,CAwBR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmB,GACjD,MAAM,CAMR"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dictionary Codebook
|
|
3
|
+
*
|
|
4
|
+
* Static dictionary of frequently repeated phrases observed in LLM prompts.
|
|
5
|
+
* Built from analysis of BlockRun production logs.
|
|
6
|
+
*
|
|
7
|
+
* Format: Short code ($XX) -> Long phrase
|
|
8
|
+
* The LLM receives a codebook header and decodes in-context.
|
|
9
|
+
*/
|
|
10
|
+
// Static codebook - common patterns from system prompts
|
|
11
|
+
// Ordered by expected frequency and impact
|
|
12
|
+
export const STATIC_CODEBOOK = {
|
|
13
|
+
// High-impact: OpenClaw/Agent system prompt patterns (very common)
|
|
14
|
+
$OC01: "unbrowse_", // Common prefix in tool names
|
|
15
|
+
$OC02: "<location>",
|
|
16
|
+
$OC03: "</location>",
|
|
17
|
+
$OC04: "<name>",
|
|
18
|
+
$OC05: "</name>",
|
|
19
|
+
$OC06: "<description>",
|
|
20
|
+
$OC07: "</description>",
|
|
21
|
+
$OC08: "(may need login)",
|
|
22
|
+
$OC09: "API skill for OpenClaw",
|
|
23
|
+
$OC10: "endpoints",
|
|
24
|
+
// Skill/tool markers
|
|
25
|
+
$SK01: "<available_skills>",
|
|
26
|
+
$SK02: "</available_skills>",
|
|
27
|
+
$SK03: "<skill>",
|
|
28
|
+
$SK04: "</skill>",
|
|
29
|
+
// Schema patterns (very common in tool definitions)
|
|
30
|
+
$T01: 'type: "function"',
|
|
31
|
+
$T02: '"type": "function"',
|
|
32
|
+
$T03: '"type": "string"',
|
|
33
|
+
$T04: '"type": "object"',
|
|
34
|
+
$T05: '"type": "array"',
|
|
35
|
+
$T06: '"type": "boolean"',
|
|
36
|
+
$T07: '"type": "number"',
|
|
37
|
+
// Common descriptions
|
|
38
|
+
$D01: "description:",
|
|
39
|
+
$D02: '"description":',
|
|
40
|
+
// Common instructions
|
|
41
|
+
$I01: "You are a personal assistant",
|
|
42
|
+
$I02: "Tool names are case-sensitive",
|
|
43
|
+
$I03: "Call tools exactly as listed",
|
|
44
|
+
$I04: "Use when",
|
|
45
|
+
$I05: "without asking",
|
|
46
|
+
// Safety phrases
|
|
47
|
+
$S01: "Do not manipulate or persuade",
|
|
48
|
+
$S02: "Prioritize safety and human oversight",
|
|
49
|
+
$S03: "unless explicitly requested",
|
|
50
|
+
// JSON patterns
|
|
51
|
+
$J01: '"required": ["',
|
|
52
|
+
$J02: '"properties": {',
|
|
53
|
+
$J03: '"additionalProperties": false',
|
|
54
|
+
// Heartbeat patterns
|
|
55
|
+
$H01: "HEARTBEAT_OK",
|
|
56
|
+
$H02: "Read HEARTBEAT.md if it exists",
|
|
57
|
+
// Role markers
|
|
58
|
+
$R01: '"role": "system"',
|
|
59
|
+
$R02: '"role": "user"',
|
|
60
|
+
$R03: '"role": "assistant"',
|
|
61
|
+
$R04: '"role": "tool"',
|
|
62
|
+
// Common endings/phrases
|
|
63
|
+
$E01: "would you like to",
|
|
64
|
+
$E02: "Let me know if you",
|
|
65
|
+
$E03: "internal APIs",
|
|
66
|
+
$E04: "session cookies",
|
|
67
|
+
// BlockRun model aliases (common in prompts)
|
|
68
|
+
$M01: "blockrun/",
|
|
69
|
+
$M02: "openai/",
|
|
70
|
+
$M03: "anthropic/",
|
|
71
|
+
$M04: "google/",
|
|
72
|
+
$M05: "xai/",
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Get the inverse codebook for decompression.
|
|
76
|
+
*/
|
|
77
|
+
export function getInverseCodebook() {
|
|
78
|
+
const inverse = {};
|
|
79
|
+
for (const [code, phrase] of Object.entries(STATIC_CODEBOOK)) {
|
|
80
|
+
inverse[phrase] = code;
|
|
81
|
+
}
|
|
82
|
+
return inverse;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate the codebook header for inclusion in system message.
|
|
86
|
+
* LLMs can decode in-context using this header.
|
|
87
|
+
*/
|
|
88
|
+
export function generateCodebookHeader(usedCodes, pathMap = {}) {
|
|
89
|
+
if (usedCodes.size === 0 && Object.keys(pathMap).length === 0) {
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
const parts = [];
|
|
93
|
+
// Add used dictionary codes
|
|
94
|
+
if (usedCodes.size > 0) {
|
|
95
|
+
const codeEntries = Array.from(usedCodes)
|
|
96
|
+
.map((code) => `${code}=${STATIC_CODEBOOK[code]}`)
|
|
97
|
+
.join(", ");
|
|
98
|
+
parts.push(`[Dict: ${codeEntries}]`);
|
|
99
|
+
}
|
|
100
|
+
// Add path map
|
|
101
|
+
if (Object.keys(pathMap).length > 0) {
|
|
102
|
+
const pathEntries = Object.entries(pathMap)
|
|
103
|
+
.map(([code, path]) => `${code}=${path}`)
|
|
104
|
+
.join(", ");
|
|
105
|
+
parts.push(`[Paths: ${pathEntries}]`);
|
|
106
|
+
}
|
|
107
|
+
return parts.join("\n");
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Decompress a string using the codebook (for logging).
|
|
111
|
+
*/
|
|
112
|
+
export function decompressContent(content, codebook = STATIC_CODEBOOK) {
|
|
113
|
+
let result = content;
|
|
114
|
+
for (const [code, phrase] of Object.entries(codebook)) {
|
|
115
|
+
result = result.split(code).join(phrase);
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=codebook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebook.js","sourceRoot":"","sources":["../../src/compression/codebook.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wDAAwD;AACxD,2CAA2C;AAC3C,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,mEAAmE;IACnE,KAAK,EAAE,WAAW,EAAE,8BAA8B;IAClD,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,aAAa;IACpB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,eAAe;IACtB,KAAK,EAAE,gBAAgB;IACvB,KAAK,EAAE,kBAAkB;IACzB,KAAK,EAAE,wBAAwB;IAC/B,KAAK,EAAE,WAAW;IAElB,qBAAqB;IACrB,KAAK,EAAE,oBAAoB;IAC3B,KAAK,EAAE,qBAAqB;IAC5B,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,UAAU;IAEjB,oDAAoD;IACpD,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,mBAAmB;IACzB,IAAI,EAAE,kBAAkB;IAExB,sBAAsB;IACtB,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,gBAAgB;IAEtB,sBAAsB;IACtB,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE,+BAA+B;IACrC,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,gBAAgB;IAEtB,iBAAiB;IACjB,IAAI,EAAE,+BAA+B;IACrC,IAAI,EAAE,uCAAuC;IAC7C,IAAI,EAAE,6BAA6B;IAEnC,gBAAgB;IAChB,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,+BAA+B;IAErC,qBAAqB;IACrB,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,gCAAgC;IAEtC,eAAe;IACf,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,qBAAqB;IAC3B,IAAI,EAAE,gBAAgB;IAEtB,yBAAyB;IACzB,IAAI,EAAE,mBAAmB;IACzB,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE,iBAAiB;IAEvB,6CAA6C;IAC7C,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,MAAM;CACb,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QAC7D,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACzB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,SAAsB,EACtB,UAAkC,EAAE;IAEpC,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,4BAA4B;IAC5B,IAAI,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;aACtC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;aACjD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,UAAU,WAAW,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,eAAe;IACf,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;aACxC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,WAAmC,eAAe;IAElD,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM-Safe Context Compression
|
|
3
|
+
*
|
|
4
|
+
* Reduces token usage by 15-40% while preserving semantic meaning.
|
|
5
|
+
* Implements 7 compression layers inspired by claw-compactor.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const result = await compressContext(messages);
|
|
9
|
+
* // result.messages -> compressed version to send to provider
|
|
10
|
+
* // result.originalMessages -> original for logging
|
|
11
|
+
*/
|
|
12
|
+
import { NormalizedMessage, CompressionConfig, CompressionResult } from "./types.js";
|
|
13
|
+
export * from "./types.js";
|
|
14
|
+
export { STATIC_CODEBOOK } from "./codebook.js";
|
|
15
|
+
/**
|
|
16
|
+
* Main compression function.
|
|
17
|
+
*
|
|
18
|
+
* Applies 5 layers in sequence:
|
|
19
|
+
* 1. Deduplication - Remove exact duplicate messages
|
|
20
|
+
* 2. Whitespace - Normalize excessive whitespace
|
|
21
|
+
* 3. Dictionary - Replace common phrases with codes
|
|
22
|
+
* 4. Paths - Shorten repeated file paths
|
|
23
|
+
* 5. JSON - Compact JSON in tool calls
|
|
24
|
+
*
|
|
25
|
+
* Then prepends a codebook header for the LLM to decode in-context.
|
|
26
|
+
*/
|
|
27
|
+
export declare function compressContext(messages: NormalizedMessage[], config?: Partial<CompressionConfig>): Promise<CompressionResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Quick check if compression would benefit these messages.
|
|
30
|
+
* Returns true if messages are large enough to warrant compression.
|
|
31
|
+
*/
|
|
32
|
+
export declare function shouldCompress(messages: NormalizedMessage[]): boolean;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compression/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAGlB,MAAM,YAAY,CAAC;AAUpB,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAqEhD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,MAAM,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACtC,OAAO,CAAC,iBAAiB,CAAC,CA+J5B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAIrE"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM-Safe Context Compression
|
|
3
|
+
*
|
|
4
|
+
* Reduces token usage by 15-40% while preserving semantic meaning.
|
|
5
|
+
* Implements 7 compression layers inspired by claw-compactor.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const result = await compressContext(messages);
|
|
9
|
+
* // result.messages -> compressed version to send to provider
|
|
10
|
+
* // result.originalMessages -> original for logging
|
|
11
|
+
*/
|
|
12
|
+
import { DEFAULT_COMPRESSION_CONFIG, } from "./types.js";
|
|
13
|
+
import { deduplicateMessages } from "./layers/deduplication.js";
|
|
14
|
+
import { normalizeMessagesWhitespace } from "./layers/whitespace.js";
|
|
15
|
+
import { encodeMessages } from "./layers/dictionary.js";
|
|
16
|
+
import { shortenPaths } from "./layers/paths.js";
|
|
17
|
+
import { compactMessagesJson } from "./layers/json-compact.js";
|
|
18
|
+
import { compressObservations } from "./layers/observation.js";
|
|
19
|
+
import { applyDynamicCodebook, generateDynamicCodebookHeader } from "./layers/dynamic-codebook.js";
|
|
20
|
+
import { generateCodebookHeader, STATIC_CODEBOOK } from "./codebook.js";
|
|
21
|
+
export * from "./types.js";
|
|
22
|
+
export { STATIC_CODEBOOK } from "./codebook.js";
|
|
23
|
+
/**
|
|
24
|
+
* Calculate total character count for messages.
|
|
25
|
+
*/
|
|
26
|
+
function calculateTotalChars(messages) {
|
|
27
|
+
return messages.reduce((total, msg) => {
|
|
28
|
+
let chars = 0;
|
|
29
|
+
if (typeof msg.content === "string") {
|
|
30
|
+
chars = msg.content.length;
|
|
31
|
+
}
|
|
32
|
+
else if (Array.isArray(msg.content)) {
|
|
33
|
+
// For multimodal content, stringify to get approximate size
|
|
34
|
+
chars = JSON.stringify(msg.content).length;
|
|
35
|
+
}
|
|
36
|
+
if (msg.tool_calls) {
|
|
37
|
+
chars += JSON.stringify(msg.tool_calls).length;
|
|
38
|
+
}
|
|
39
|
+
return total + chars;
|
|
40
|
+
}, 0);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Deep clone messages to preserve originals.
|
|
44
|
+
*/
|
|
45
|
+
function cloneMessages(messages) {
|
|
46
|
+
return JSON.parse(JSON.stringify(messages));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Prepend codebook header to the first USER message (not system).
|
|
50
|
+
*
|
|
51
|
+
* Why not system message?
|
|
52
|
+
* - Google Gemini uses systemInstruction which doesn't support codebook format
|
|
53
|
+
* - The codebook header in user message is still visible to all LLMs
|
|
54
|
+
* - This ensures compatibility across all providers
|
|
55
|
+
*/
|
|
56
|
+
function prependCodebookHeader(messages, usedCodes, pathMap) {
|
|
57
|
+
const header = generateCodebookHeader(usedCodes, pathMap);
|
|
58
|
+
if (!header)
|
|
59
|
+
return messages;
|
|
60
|
+
// Find first user message (not system - Google's systemInstruction doesn't support codebook)
|
|
61
|
+
const userIndex = messages.findIndex((m) => m.role === "user");
|
|
62
|
+
if (userIndex === -1) {
|
|
63
|
+
// No user message, add codebook as system (fallback)
|
|
64
|
+
return [{ role: "system", content: header }, ...messages];
|
|
65
|
+
}
|
|
66
|
+
// Prepend to first user message (only if content is a string)
|
|
67
|
+
return messages.map((msg, i) => {
|
|
68
|
+
if (i === userIndex) {
|
|
69
|
+
// Only prepend to string content - skip arrays (multimodal messages)
|
|
70
|
+
if (typeof msg.content === "string") {
|
|
71
|
+
return {
|
|
72
|
+
...msg,
|
|
73
|
+
content: `${header}\n\n${msg.content}`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// For non-string content, don't modify the message
|
|
77
|
+
// The codebook header would corrupt array content
|
|
78
|
+
}
|
|
79
|
+
return msg;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Main compression function.
|
|
84
|
+
*
|
|
85
|
+
* Applies 5 layers in sequence:
|
|
86
|
+
* 1. Deduplication - Remove exact duplicate messages
|
|
87
|
+
* 2. Whitespace - Normalize excessive whitespace
|
|
88
|
+
* 3. Dictionary - Replace common phrases with codes
|
|
89
|
+
* 4. Paths - Shorten repeated file paths
|
|
90
|
+
* 5. JSON - Compact JSON in tool calls
|
|
91
|
+
*
|
|
92
|
+
* Then prepends a codebook header for the LLM to decode in-context.
|
|
93
|
+
*/
|
|
94
|
+
export async function compressContext(messages, config = {}) {
|
|
95
|
+
const fullConfig = {
|
|
96
|
+
...DEFAULT_COMPRESSION_CONFIG,
|
|
97
|
+
...config,
|
|
98
|
+
layers: {
|
|
99
|
+
...DEFAULT_COMPRESSION_CONFIG.layers,
|
|
100
|
+
...config.layers,
|
|
101
|
+
},
|
|
102
|
+
dictionary: {
|
|
103
|
+
...DEFAULT_COMPRESSION_CONFIG.dictionary,
|
|
104
|
+
...config.dictionary,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
// If compression disabled, return as-is
|
|
108
|
+
if (!fullConfig.enabled) {
|
|
109
|
+
const originalChars = calculateTotalChars(messages);
|
|
110
|
+
return {
|
|
111
|
+
messages,
|
|
112
|
+
originalMessages: messages,
|
|
113
|
+
originalChars,
|
|
114
|
+
compressedChars: originalChars,
|
|
115
|
+
compressionRatio: 1,
|
|
116
|
+
stats: {
|
|
117
|
+
duplicatesRemoved: 0,
|
|
118
|
+
whitespaceSavedChars: 0,
|
|
119
|
+
dictionarySubstitutions: 0,
|
|
120
|
+
pathsShortened: 0,
|
|
121
|
+
jsonCompactedChars: 0,
|
|
122
|
+
observationsCompressed: 0,
|
|
123
|
+
observationCharsSaved: 0,
|
|
124
|
+
dynamicSubstitutions: 0,
|
|
125
|
+
dynamicCharsSaved: 0,
|
|
126
|
+
},
|
|
127
|
+
codebook: {},
|
|
128
|
+
pathMap: {},
|
|
129
|
+
dynamicCodes: {},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// Preserve originals for logging
|
|
133
|
+
const originalMessages = fullConfig.preserveRaw ? cloneMessages(messages) : messages;
|
|
134
|
+
const originalChars = calculateTotalChars(messages);
|
|
135
|
+
// Initialize stats
|
|
136
|
+
const stats = {
|
|
137
|
+
duplicatesRemoved: 0,
|
|
138
|
+
whitespaceSavedChars: 0,
|
|
139
|
+
dictionarySubstitutions: 0,
|
|
140
|
+
pathsShortened: 0,
|
|
141
|
+
jsonCompactedChars: 0,
|
|
142
|
+
observationsCompressed: 0,
|
|
143
|
+
observationCharsSaved: 0,
|
|
144
|
+
dynamicSubstitutions: 0,
|
|
145
|
+
dynamicCharsSaved: 0,
|
|
146
|
+
};
|
|
147
|
+
let result = cloneMessages(messages);
|
|
148
|
+
let usedCodes = new Set();
|
|
149
|
+
let pathMap = {};
|
|
150
|
+
let dynamicCodes = {};
|
|
151
|
+
// Layer 1: Deduplication
|
|
152
|
+
if (fullConfig.layers.deduplication) {
|
|
153
|
+
const dedupResult = deduplicateMessages(result);
|
|
154
|
+
result = dedupResult.messages;
|
|
155
|
+
stats.duplicatesRemoved = dedupResult.duplicatesRemoved;
|
|
156
|
+
}
|
|
157
|
+
// Layer 2: Whitespace normalization
|
|
158
|
+
if (fullConfig.layers.whitespace) {
|
|
159
|
+
const wsResult = normalizeMessagesWhitespace(result);
|
|
160
|
+
result = wsResult.messages;
|
|
161
|
+
stats.whitespaceSavedChars = wsResult.charsSaved;
|
|
162
|
+
}
|
|
163
|
+
// Layer 3: Dictionary encoding
|
|
164
|
+
if (fullConfig.layers.dictionary) {
|
|
165
|
+
const dictResult = encodeMessages(result);
|
|
166
|
+
result = dictResult.messages;
|
|
167
|
+
stats.dictionarySubstitutions = dictResult.substitutionCount;
|
|
168
|
+
usedCodes = dictResult.usedCodes;
|
|
169
|
+
}
|
|
170
|
+
// Layer 4: Path shortening
|
|
171
|
+
if (fullConfig.layers.paths) {
|
|
172
|
+
const pathResult = shortenPaths(result);
|
|
173
|
+
result = pathResult.messages;
|
|
174
|
+
pathMap = pathResult.pathMap;
|
|
175
|
+
stats.pathsShortened = Object.keys(pathMap).length;
|
|
176
|
+
}
|
|
177
|
+
// Layer 5: JSON compaction
|
|
178
|
+
if (fullConfig.layers.jsonCompact) {
|
|
179
|
+
const jsonResult = compactMessagesJson(result);
|
|
180
|
+
result = jsonResult.messages;
|
|
181
|
+
stats.jsonCompactedChars = jsonResult.charsSaved;
|
|
182
|
+
}
|
|
183
|
+
// Layer 6: Observation compression (BIG WIN - 97% on tool results)
|
|
184
|
+
if (fullConfig.layers.observation) {
|
|
185
|
+
const obsResult = compressObservations(result);
|
|
186
|
+
result = obsResult.messages;
|
|
187
|
+
stats.observationsCompressed = obsResult.observationsCompressed;
|
|
188
|
+
stats.observationCharsSaved = obsResult.charsSaved;
|
|
189
|
+
}
|
|
190
|
+
// Layer 7: Dynamic codebook (learns from actual content)
|
|
191
|
+
if (fullConfig.layers.dynamicCodebook) {
|
|
192
|
+
const dynResult = applyDynamicCodebook(result);
|
|
193
|
+
result = dynResult.messages;
|
|
194
|
+
stats.dynamicSubstitutions = dynResult.substitutions;
|
|
195
|
+
stats.dynamicCharsSaved = dynResult.charsSaved;
|
|
196
|
+
dynamicCodes = dynResult.dynamicCodes;
|
|
197
|
+
}
|
|
198
|
+
// Add codebook header if enabled and we have codes to include
|
|
199
|
+
if (fullConfig.dictionary.includeCodebookHeader &&
|
|
200
|
+
(usedCodes.size > 0 || Object.keys(pathMap).length > 0 || Object.keys(dynamicCodes).length > 0)) {
|
|
201
|
+
result = prependCodebookHeader(result, usedCodes, pathMap);
|
|
202
|
+
// Also add dynamic codebook header if we have dynamic codes
|
|
203
|
+
if (Object.keys(dynamicCodes).length > 0) {
|
|
204
|
+
const dynHeader = generateDynamicCodebookHeader(dynamicCodes);
|
|
205
|
+
if (dynHeader) {
|
|
206
|
+
const systemIndex = result.findIndex((m) => m.role === "system");
|
|
207
|
+
// Only prepend to string content - skip arrays (multimodal messages)
|
|
208
|
+
if (systemIndex >= 0 && typeof result[systemIndex].content === "string") {
|
|
209
|
+
result[systemIndex] = {
|
|
210
|
+
...result[systemIndex],
|
|
211
|
+
content: `${dynHeader}\n${result[systemIndex].content}`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Calculate final stats
|
|
218
|
+
const compressedChars = calculateTotalChars(result);
|
|
219
|
+
const compressionRatio = compressedChars / originalChars;
|
|
220
|
+
// Build used codebook for logging
|
|
221
|
+
const usedCodebook = {};
|
|
222
|
+
usedCodes.forEach((code) => {
|
|
223
|
+
usedCodebook[code] = STATIC_CODEBOOK[code];
|
|
224
|
+
});
|
|
225
|
+
return {
|
|
226
|
+
messages: result,
|
|
227
|
+
originalMessages,
|
|
228
|
+
originalChars,
|
|
229
|
+
compressedChars,
|
|
230
|
+
compressionRatio,
|
|
231
|
+
stats,
|
|
232
|
+
codebook: usedCodebook,
|
|
233
|
+
pathMap,
|
|
234
|
+
dynamicCodes,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Quick check if compression would benefit these messages.
|
|
239
|
+
* Returns true if messages are large enough to warrant compression.
|
|
240
|
+
*/
|
|
241
|
+
export function shouldCompress(messages) {
|
|
242
|
+
const chars = calculateTotalChars(messages);
|
|
243
|
+
// Only compress if > 5000 chars (roughly 1000 tokens)
|
|
244
|
+
return chars > 5000;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compression/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 1: Message Deduplication
|
|
3
|
+
*
|
|
4
|
+
* Removes exact duplicate messages from conversation history.
|
|
5
|
+
* Common in heartbeat patterns and repeated tool calls.
|
|
6
|
+
*
|
|
7
|
+
* Safe for LLM: Identical messages add no new information.
|
|
8
|
+
* Expected savings: 2-5%
|
|
9
|
+
*/
|
|
10
|
+
import { NormalizedMessage } from "../types.js";
|
|
11
|
+
export interface DeduplicationResult {
|
|
12
|
+
messages: NormalizedMessage[];
|
|
13
|
+
duplicatesRemoved: number;
|
|
14
|
+
originalCount: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Remove exact duplicate messages from the conversation.
|
|
18
|
+
*
|
|
19
|
+
* Strategy:
|
|
20
|
+
* - Keep first occurrence of each unique message
|
|
21
|
+
* - Preserve order for semantic coherence
|
|
22
|
+
* - Never dedupe system messages (they set context)
|
|
23
|
+
* - Allow duplicate user messages (user might repeat intentionally)
|
|
24
|
+
* - CRITICAL: Never dedupe assistant messages with tool_calls that are
|
|
25
|
+
* referenced by subsequent tool messages (breaks Anthropic tool_use/tool_result pairing)
|
|
26
|
+
*/
|
|
27
|
+
export declare function deduplicateMessages(messages: NormalizedMessage[]): DeduplicationResult;
|
|
28
|
+
//# sourceMappingURL=deduplication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplication.d.ts","sourceRoot":"","sources":["../../../src/compression/layers/deduplication.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB;AAiCD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,mBAAmB,CA+DtF"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 1: Message Deduplication
|
|
3
|
+
*
|
|
4
|
+
* Removes exact duplicate messages from conversation history.
|
|
5
|
+
* Common in heartbeat patterns and repeated tool calls.
|
|
6
|
+
*
|
|
7
|
+
* Safe for LLM: Identical messages add no new information.
|
|
8
|
+
* Expected savings: 2-5%
|
|
9
|
+
*/
|
|
10
|
+
import crypto from "crypto";
|
|
11
|
+
/**
|
|
12
|
+
* Generate a hash for a message based on its semantic content.
|
|
13
|
+
* Uses role + content + tool_call_id to identify duplicates.
|
|
14
|
+
*/
|
|
15
|
+
function hashMessage(message) {
|
|
16
|
+
// Handle content - stringify arrays (multimodal), use string directly, or empty string
|
|
17
|
+
let contentStr = "";
|
|
18
|
+
if (typeof message.content === "string") {
|
|
19
|
+
contentStr = message.content;
|
|
20
|
+
}
|
|
21
|
+
else if (Array.isArray(message.content)) {
|
|
22
|
+
contentStr = JSON.stringify(message.content);
|
|
23
|
+
}
|
|
24
|
+
const parts = [message.role, contentStr, message.tool_call_id || "", message.name || ""];
|
|
25
|
+
// Include tool_calls if present
|
|
26
|
+
if (message.tool_calls) {
|
|
27
|
+
parts.push(JSON.stringify(message.tool_calls.map((tc) => ({
|
|
28
|
+
name: tc.function.name,
|
|
29
|
+
args: tc.function.arguments,
|
|
30
|
+
}))));
|
|
31
|
+
}
|
|
32
|
+
const content = parts.join("|");
|
|
33
|
+
return crypto.createHash("md5").update(content).digest("hex");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Remove exact duplicate messages from the conversation.
|
|
37
|
+
*
|
|
38
|
+
* Strategy:
|
|
39
|
+
* - Keep first occurrence of each unique message
|
|
40
|
+
* - Preserve order for semantic coherence
|
|
41
|
+
* - Never dedupe system messages (they set context)
|
|
42
|
+
* - Allow duplicate user messages (user might repeat intentionally)
|
|
43
|
+
* - CRITICAL: Never dedupe assistant messages with tool_calls that are
|
|
44
|
+
* referenced by subsequent tool messages (breaks Anthropic tool_use/tool_result pairing)
|
|
45
|
+
*/
|
|
46
|
+
export function deduplicateMessages(messages) {
|
|
47
|
+
const seen = new Set();
|
|
48
|
+
const result = [];
|
|
49
|
+
let duplicatesRemoved = 0;
|
|
50
|
+
// First pass: collect all tool_call_ids that are referenced by tool messages
|
|
51
|
+
// These tool_calls MUST be preserved to maintain tool_use/tool_result pairing
|
|
52
|
+
const referencedToolCallIds = new Set();
|
|
53
|
+
for (const message of messages) {
|
|
54
|
+
if (message.role === "tool" && message.tool_call_id) {
|
|
55
|
+
referencedToolCallIds.add(message.tool_call_id);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const message of messages) {
|
|
59
|
+
// Always keep system messages (they set important context)
|
|
60
|
+
if (message.role === "system") {
|
|
61
|
+
result.push(message);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Always keep user messages (user might repeat intentionally)
|
|
65
|
+
if (message.role === "user") {
|
|
66
|
+
result.push(message);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// Always keep tool messages (they are results of tool calls)
|
|
70
|
+
// Removing them would break the tool_use/tool_result pairing
|
|
71
|
+
if (message.role === "tool") {
|
|
72
|
+
result.push(message);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// For assistant messages with tool_calls, check if any are referenced
|
|
76
|
+
// by subsequent tool messages - if so, we MUST keep this message
|
|
77
|
+
if (message.role === "assistant" && message.tool_calls) {
|
|
78
|
+
const hasReferencedToolCall = message.tool_calls.some((tc) => referencedToolCallIds.has(tc.id));
|
|
79
|
+
if (hasReferencedToolCall) {
|
|
80
|
+
// This assistant message has tool_calls that are referenced - keep it
|
|
81
|
+
result.push(message);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// For other assistant messages, check for duplicates
|
|
86
|
+
const hash = hashMessage(message);
|
|
87
|
+
if (!seen.has(hash)) {
|
|
88
|
+
seen.add(hash);
|
|
89
|
+
result.push(message);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
duplicatesRemoved++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
messages: result,
|
|
97
|
+
duplicatesRemoved,
|
|
98
|
+
originalCount: messages.length,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=deduplication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplication.js","sourceRoot":"","sources":["../../../src/compression/layers/deduplication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 3: Dictionary Encoding
|
|
3
|
+
*
|
|
4
|
+
* Replaces frequently repeated long phrases with short codes.
|
|
5
|
+
* Uses a static codebook of common patterns from production logs.
|
|
6
|
+
*
|
|
7
|
+
* Safe for LLM: Reversible substitution with codebook header.
|
|
8
|
+
* Expected savings: 4-8%
|
|
9
|
+
*/
|
|
10
|
+
import { NormalizedMessage } from "../types.js";
|
|
11
|
+
export interface DictionaryResult {
|
|
12
|
+
messages: NormalizedMessage[];
|
|
13
|
+
substitutionCount: number;
|
|
14
|
+
usedCodes: Set<string>;
|
|
15
|
+
charsSaved: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Apply dictionary encoding to all messages.
|
|
19
|
+
*/
|
|
20
|
+
export declare function encodeMessages(messages: NormalizedMessage[]): DictionaryResult;
|
|
21
|
+
//# sourceMappingURL=dictionary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dictionary.d.ts","sourceRoot":"","sources":["../../../src/compression/layers/dictionary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AA6CD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,gBAAgB,CA+B9E"}
|