@tyvm/knowhow 0.0.19 → 0.0.20
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/package.json
CHANGED
|
@@ -8,12 +8,15 @@ interface TokenCompressorStorage {
|
|
|
8
8
|
|
|
9
9
|
export class TokenCompressor {
|
|
10
10
|
private storage: TokenCompressorStorage = {};
|
|
11
|
-
private maxTokens: number = 4000;
|
|
12
|
-
private compressionRatio: number = 0.1;
|
|
13
11
|
private keyPrefix: string = "compressed_";
|
|
14
12
|
private toolName: string = expandTokensDefinition.function.name;
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
|
|
14
|
+
// Threshold for compression - if content exceeds this size, we compress it
|
|
15
|
+
private compressionThreshold: number = 4000;
|
|
16
|
+
private characterLimit: number = this.compressionThreshold * 4;
|
|
17
|
+
|
|
18
|
+
// Largest size retrievable without re-compressing
|
|
19
|
+
private maxTokens: number = this.compressionThreshold * 2;
|
|
17
20
|
|
|
18
21
|
constructor(toolsService?: ToolsService) {
|
|
19
22
|
this.registerTool(toolsService);
|
|
@@ -24,10 +27,16 @@ export class TokenCompressor {
|
|
|
24
27
|
return Math.ceil(text.length / 4);
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
public
|
|
28
|
-
this.
|
|
29
|
-
this.characterLimit =
|
|
30
|
-
|
|
30
|
+
public setCompressionThreshold(threshold: number): void {
|
|
31
|
+
this.compressionThreshold = threshold;
|
|
32
|
+
this.characterLimit = threshold * 4; // Update character limit based on new threshold
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Internally adjust to ensure we can always retrieve data
|
|
36
|
+
private setMaxTokens(maxTokens: number): void {
|
|
37
|
+
if (maxTokens > this.maxTokens) {
|
|
38
|
+
this.maxTokens = maxTokens;
|
|
39
|
+
}
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
/**
|
|
@@ -45,6 +54,10 @@ export class TokenCompressor {
|
|
|
45
54
|
* Compresses a string into chunks from the end, creating a chain of references
|
|
46
55
|
*/
|
|
47
56
|
public compressStringInChunks(content: string, path: string = ""): string {
|
|
57
|
+
if (path === "" && this.estimateTokens(content) <= this.maxTokens) {
|
|
58
|
+
return content;
|
|
59
|
+
}
|
|
60
|
+
|
|
48
61
|
if (content.length <= this.characterLimit) {
|
|
49
62
|
return content;
|
|
50
63
|
}
|
|
@@ -79,7 +92,7 @@ export class TokenCompressor {
|
|
|
79
92
|
chunkContent += `\n\n[NEXT_CHUNK_KEY: ${nextKey}]`;
|
|
80
93
|
}
|
|
81
94
|
|
|
82
|
-
this.
|
|
95
|
+
this.storeString(key, chunkContent);
|
|
83
96
|
}
|
|
84
97
|
|
|
85
98
|
// Return reference to the first chunk
|
|
@@ -101,7 +114,11 @@ export class TokenCompressor {
|
|
|
101
114
|
public compressContent(content: string, path: string = ""): string {
|
|
102
115
|
const tokens = this.estimateTokens(content);
|
|
103
116
|
|
|
104
|
-
if (tokens <= this.maxTokens) {
|
|
117
|
+
if (path === "" && tokens <= this.maxTokens) {
|
|
118
|
+
return content;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (tokens <= this.compressionThreshold) {
|
|
105
122
|
return content;
|
|
106
123
|
}
|
|
107
124
|
|
|
@@ -128,6 +145,13 @@ export class TokenCompressor {
|
|
|
128
145
|
* Implements an efficient backward-iterating chunking strategy for large arrays.
|
|
129
146
|
*/
|
|
130
147
|
public compressJsonProperties(obj: any, path: string = ""): any {
|
|
148
|
+
if (
|
|
149
|
+
path === "" &&
|
|
150
|
+
this.estimateTokens(JSON.stringify(obj)) <= this.maxTokens
|
|
151
|
+
) {
|
|
152
|
+
return obj;
|
|
153
|
+
}
|
|
154
|
+
|
|
131
155
|
if (Array.isArray(obj)) {
|
|
132
156
|
// Step 1: Recursively compress all items first (depth-first).
|
|
133
157
|
const processedItems = obj.map((item, index) =>
|
|
@@ -135,11 +159,7 @@ export class TokenCompressor {
|
|
|
135
159
|
);
|
|
136
160
|
|
|
137
161
|
// Step 2: Early exit if the whole array is already small enough.
|
|
138
|
-
//
|
|
139
|
-
const initialTokens = this.estimateTokens(JSON.stringify(processedItems));
|
|
140
|
-
if (initialTokens <= this.jsonPropertyThreshold * 1.3) {
|
|
141
|
-
return processedItems;
|
|
142
|
-
}
|
|
162
|
+
// maxTokens allows us to fetch objects from the store without recompressing
|
|
143
163
|
|
|
144
164
|
// Step 3: Iterate backwards, building chunks from the end.
|
|
145
165
|
const finalArray: any[] = [];
|
|
@@ -152,9 +172,9 @@ export class TokenCompressor {
|
|
|
152
172
|
const chunkString = JSON.stringify(currentChunk);
|
|
153
173
|
const chunkTokens = this.estimateTokens(chunkString);
|
|
154
174
|
|
|
155
|
-
if (chunkTokens > this.
|
|
175
|
+
if (chunkTokens > this.compressionThreshold) {
|
|
156
176
|
const key = this.generateKey();
|
|
157
|
-
this.
|
|
177
|
+
this.storeString(key, chunkString);
|
|
158
178
|
|
|
159
179
|
const stub = `[COMPRESSED_JSON_ARRAY_CHUNK - ${chunkTokens} tokens, ${
|
|
160
180
|
currentChunk.length
|
|
@@ -188,9 +208,9 @@ export class TokenCompressor {
|
|
|
188
208
|
// After processing children, check if the entire object should be compressed
|
|
189
209
|
const objectAsString = JSON.stringify(result);
|
|
190
210
|
const tokens = this.estimateTokens(objectAsString);
|
|
191
|
-
if (tokens > this.
|
|
211
|
+
if (tokens > this.compressionThreshold) {
|
|
192
212
|
const key = this.generateKey();
|
|
193
|
-
this.
|
|
213
|
+
this.storeString(key, objectAsString);
|
|
194
214
|
|
|
195
215
|
return `[COMPRESSED_JSON_OBJECT - ${tokens} tokens]\nKey: ${key}\nPath: ${path}\nKeys: ${Object.keys(
|
|
196
216
|
result
|
|
@@ -221,7 +241,7 @@ export class TokenCompressor {
|
|
|
221
241
|
const tokens = this.estimateTokens(obj);
|
|
222
242
|
if (tokens > this.characterLimit * 4) {
|
|
223
243
|
const key = this.generateKey();
|
|
224
|
-
this.
|
|
244
|
+
this.storeString(key, obj);
|
|
225
245
|
|
|
226
246
|
return `[COMPRESSED_JSON_PROPERTY - ${tokens} tokens]\nKey: ${key}\nPath: ${path}\nPreview: ${obj.substring(
|
|
227
247
|
0,
|
|
@@ -242,36 +262,7 @@ export class TokenCompressor {
|
|
|
242
262
|
.substr(2, 9)}`;
|
|
243
263
|
}
|
|
244
264
|
|
|
245
|
-
public compressToolCall(message: Message): void {
|
|
246
|
-
if (message.tool_calls) {
|
|
247
|
-
for (const toolCall of message.tool_calls) {
|
|
248
|
-
if (toolCall.function.arguments) {
|
|
249
|
-
const args = toolCall.function.arguments;
|
|
250
|
-
const tokens = this.estimateTokens(args);
|
|
251
|
-
|
|
252
|
-
if (tokens > this.maxTokens) {
|
|
253
|
-
const key = this.generateKey();
|
|
254
|
-
this.storage[key] = args;
|
|
255
|
-
|
|
256
|
-
const compressed = `[COMPRESSED TOOL ARGS - ${tokens} tokens]\nKey: ${key}\nPreview: ${args.substring(
|
|
257
|
-
0,
|
|
258
|
-
200
|
|
259
|
-
)}...\n[Use ${
|
|
260
|
-
this.toolName
|
|
261
|
-
} tool with key "${key}" to retrieve full arguments]`;
|
|
262
|
-
|
|
263
|
-
toolCall.function.arguments = compressed;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
265
|
public async compressMessage(message: Message) {
|
|
271
|
-
// The previous check for 'isDecompressionToolResponse' is no longer necessary.
|
|
272
|
-
// The new chunking strategy returns manageable chunks that won't meet the
|
|
273
|
-
// compression threshold, naturally preventing cycles.
|
|
274
|
-
|
|
275
266
|
// Compress content if it's a string
|
|
276
267
|
if (typeof message.content === "string") {
|
|
277
268
|
message.content = this.compressContent(message.content);
|
|
@@ -284,9 +275,6 @@ export class TokenCompressor {
|
|
|
284
275
|
}
|
|
285
276
|
}
|
|
286
277
|
}
|
|
287
|
-
|
|
288
|
-
// Compress tool calls
|
|
289
|
-
this.compressToolCall(message);
|
|
290
278
|
}
|
|
291
279
|
|
|
292
280
|
createProcessor(
|
|
@@ -311,6 +299,14 @@ export class TokenCompressor {
|
|
|
311
299
|
return this.storage[key] || null;
|
|
312
300
|
}
|
|
313
301
|
|
|
302
|
+
storeString(key: string, value: string): void {
|
|
303
|
+
if (this.estimateTokens(value) > this.maxTokens) {
|
|
304
|
+
// adjust max tokens so we can always retrieve this without re-compressing
|
|
305
|
+
this.setMaxTokens(this.estimateTokens(value) + 1);
|
|
306
|
+
}
|
|
307
|
+
this.storage[key] = value;
|
|
308
|
+
}
|
|
309
|
+
|
|
314
310
|
clearStorage(): void {
|
|
315
311
|
this.storage = {};
|
|
316
312
|
}
|
|
@@ -3,24 +3,24 @@ import { MessageProcessorFunction } from "../services/MessageProcessor";
|
|
|
3
3
|
import { ToolsService } from "../services";
|
|
4
4
|
export declare class TokenCompressor {
|
|
5
5
|
private storage;
|
|
6
|
-
private maxTokens;
|
|
7
|
-
private compressionRatio;
|
|
8
6
|
private keyPrefix;
|
|
9
7
|
private toolName;
|
|
8
|
+
private compressionThreshold;
|
|
10
9
|
private characterLimit;
|
|
11
|
-
private
|
|
10
|
+
private maxTokens;
|
|
12
11
|
constructor(toolsService?: ToolsService);
|
|
13
12
|
private estimateTokens;
|
|
14
|
-
|
|
13
|
+
setCompressionThreshold(threshold: number): void;
|
|
14
|
+
private setMaxTokens;
|
|
15
15
|
private tryParseJson;
|
|
16
16
|
compressStringInChunks(content: string, path?: string): string;
|
|
17
17
|
compressContent(content: string, path?: string): string;
|
|
18
18
|
compressJsonProperties(obj: any, path?: string): any;
|
|
19
19
|
private generateKey;
|
|
20
|
-
compressToolCall(message: Message): void;
|
|
21
20
|
compressMessage(message: Message): Promise<void>;
|
|
22
21
|
createProcessor(filterFn?: (msg: Message) => boolean): MessageProcessorFunction;
|
|
23
22
|
retrieveString(key: string): string | null;
|
|
23
|
+
storeString(key: string, value: string): void;
|
|
24
24
|
clearStorage(): void;
|
|
25
25
|
getStorageKeys(): string[];
|
|
26
26
|
getStorageSize(): number;
|
|
@@ -3,22 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.expandTokensDefinition = exports.TokenCompressor = void 0;
|
|
4
4
|
class TokenCompressor {
|
|
5
5
|
storage = {};
|
|
6
|
-
maxTokens = 4000;
|
|
7
|
-
compressionRatio = 0.1;
|
|
8
6
|
keyPrefix = "compressed_";
|
|
9
7
|
toolName = exports.expandTokensDefinition.function.name;
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
compressionThreshold = 4000;
|
|
9
|
+
characterLimit = this.compressionThreshold * 4;
|
|
10
|
+
maxTokens = this.compressionThreshold * 2;
|
|
12
11
|
constructor(toolsService) {
|
|
13
12
|
this.registerTool(toolsService);
|
|
14
13
|
}
|
|
15
14
|
estimateTokens(text) {
|
|
16
15
|
return Math.ceil(text.length / 4);
|
|
17
16
|
}
|
|
17
|
+
setCompressionThreshold(threshold) {
|
|
18
|
+
this.compressionThreshold = threshold;
|
|
19
|
+
this.characterLimit = threshold * 4;
|
|
20
|
+
}
|
|
18
21
|
setMaxTokens(maxTokens) {
|
|
19
|
-
this.maxTokens
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
if (maxTokens > this.maxTokens) {
|
|
23
|
+
this.maxTokens = maxTokens;
|
|
24
|
+
}
|
|
22
25
|
}
|
|
23
26
|
tryParseJson(content) {
|
|
24
27
|
try {
|
|
@@ -29,6 +32,9 @@ class TokenCompressor {
|
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
compressStringInChunks(content, path = "") {
|
|
35
|
+
if (path === "" && this.estimateTokens(content) <= this.maxTokens) {
|
|
36
|
+
return content;
|
|
37
|
+
}
|
|
32
38
|
if (content.length <= this.characterLimit) {
|
|
33
39
|
return content;
|
|
34
40
|
}
|
|
@@ -52,7 +58,7 @@ class TokenCompressor {
|
|
|
52
58
|
const nextKey = chunkKeys[i + 1];
|
|
53
59
|
chunkContent += `\n\n[NEXT_CHUNK_KEY: ${nextKey}]`;
|
|
54
60
|
}
|
|
55
|
-
this.
|
|
61
|
+
this.storeString(key, chunkContent);
|
|
56
62
|
}
|
|
57
63
|
const firstKey = chunkKeys[0];
|
|
58
64
|
const totalTokens = this.estimateTokens(content);
|
|
@@ -61,7 +67,10 @@ class TokenCompressor {
|
|
|
61
67
|
}
|
|
62
68
|
compressContent(content, path = "") {
|
|
63
69
|
const tokens = this.estimateTokens(content);
|
|
64
|
-
if (tokens <= this.maxTokens) {
|
|
70
|
+
if (path === "" && tokens <= this.maxTokens) {
|
|
71
|
+
return content;
|
|
72
|
+
}
|
|
73
|
+
if (tokens <= this.compressionThreshold) {
|
|
65
74
|
return content;
|
|
66
75
|
}
|
|
67
76
|
const jsonObj = this.tryParseJson(content);
|
|
@@ -76,12 +85,12 @@ class TokenCompressor {
|
|
|
76
85
|
return this.compressStringInChunks(content, path);
|
|
77
86
|
}
|
|
78
87
|
compressJsonProperties(obj, path = "") {
|
|
88
|
+
if (path === "" &&
|
|
89
|
+
this.estimateTokens(JSON.stringify(obj)) <= this.maxTokens) {
|
|
90
|
+
return obj;
|
|
91
|
+
}
|
|
79
92
|
if (Array.isArray(obj)) {
|
|
80
93
|
const processedItems = obj.map((item, index) => this.compressJsonProperties(item, `${path}[${index}]`));
|
|
81
|
-
const initialTokens = this.estimateTokens(JSON.stringify(processedItems));
|
|
82
|
-
if (initialTokens <= this.jsonPropertyThreshold * 1.3) {
|
|
83
|
-
return processedItems;
|
|
84
|
-
}
|
|
85
94
|
const finalArray = [];
|
|
86
95
|
let currentChunk = [];
|
|
87
96
|
for (let i = processedItems.length - 1; i >= 0; i--) {
|
|
@@ -89,9 +98,9 @@ class TokenCompressor {
|
|
|
89
98
|
currentChunk.unshift(item);
|
|
90
99
|
const chunkString = JSON.stringify(currentChunk);
|
|
91
100
|
const chunkTokens = this.estimateTokens(chunkString);
|
|
92
|
-
if (chunkTokens > this.
|
|
101
|
+
if (chunkTokens > this.compressionThreshold) {
|
|
93
102
|
const key = this.generateKey();
|
|
94
|
-
this.
|
|
103
|
+
this.storeString(key, chunkString);
|
|
95
104
|
const stub = `[COMPRESSED_JSON_ARRAY_CHUNK - ${chunkTokens} tokens, ${currentChunk.length} items]\nKey: ${key}\nPath: ${path}[${i}...${i + currentChunk.length - 1}]\nPreview: ${chunkString.substring(0, 100)}...\n[Use ${this.toolName} tool with key "${key}" to retrieve this chunk]`;
|
|
96
105
|
finalArray.unshift(stub);
|
|
97
106
|
currentChunk = [];
|
|
@@ -110,9 +119,9 @@ class TokenCompressor {
|
|
|
110
119
|
}
|
|
111
120
|
const objectAsString = JSON.stringify(result);
|
|
112
121
|
const tokens = this.estimateTokens(objectAsString);
|
|
113
|
-
if (tokens > this.
|
|
122
|
+
if (tokens > this.compressionThreshold) {
|
|
114
123
|
const key = this.generateKey();
|
|
115
|
-
this.
|
|
124
|
+
this.storeString(key, objectAsString);
|
|
116
125
|
return `[COMPRESSED_JSON_OBJECT - ${tokens} tokens]\nKey: ${key}\nPath: ${path}\nKeys: ${Object.keys(result).join(", ")}\nPreview: ${objectAsString.substring(0, 200)}...\n[Use ${this.toolName} tool with key "${key}" to retrieve full content]`;
|
|
117
126
|
}
|
|
118
127
|
return result;
|
|
@@ -131,7 +140,7 @@ class TokenCompressor {
|
|
|
131
140
|
const tokens = this.estimateTokens(obj);
|
|
132
141
|
if (tokens > this.characterLimit * 4) {
|
|
133
142
|
const key = this.generateKey();
|
|
134
|
-
this.
|
|
143
|
+
this.storeString(key, obj);
|
|
135
144
|
return `[COMPRESSED_JSON_PROPERTY - ${tokens} tokens]\nKey: ${key}\nPath: ${path}\nPreview: ${obj.substring(0, 200)}...\n[Use ${this.toolName} tool with key "${key}" to retrieve full content]`;
|
|
136
145
|
}
|
|
137
146
|
return obj;
|
|
@@ -143,22 +152,6 @@ class TokenCompressor {
|
|
|
143
152
|
.toString(36)
|
|
144
153
|
.substr(2, 9)}`;
|
|
145
154
|
}
|
|
146
|
-
compressToolCall(message) {
|
|
147
|
-
if (message.tool_calls) {
|
|
148
|
-
for (const toolCall of message.tool_calls) {
|
|
149
|
-
if (toolCall.function.arguments) {
|
|
150
|
-
const args = toolCall.function.arguments;
|
|
151
|
-
const tokens = this.estimateTokens(args);
|
|
152
|
-
if (tokens > this.maxTokens) {
|
|
153
|
-
const key = this.generateKey();
|
|
154
|
-
this.storage[key] = args;
|
|
155
|
-
const compressed = `[COMPRESSED TOOL ARGS - ${tokens} tokens]\nKey: ${key}\nPreview: ${args.substring(0, 200)}...\n[Use ${this.toolName} tool with key "${key}" to retrieve full arguments]`;
|
|
156
|
-
toolCall.function.arguments = compressed;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
155
|
async compressMessage(message) {
|
|
163
156
|
if (typeof message.content === "string") {
|
|
164
157
|
message.content = this.compressContent(message.content);
|
|
@@ -170,7 +163,6 @@ class TokenCompressor {
|
|
|
170
163
|
}
|
|
171
164
|
}
|
|
172
165
|
}
|
|
173
|
-
this.compressToolCall(message);
|
|
174
166
|
}
|
|
175
167
|
createProcessor(filterFn) {
|
|
176
168
|
return async (originalMessages, modifiedMessages) => {
|
|
@@ -185,6 +177,12 @@ class TokenCompressor {
|
|
|
185
177
|
retrieveString(key) {
|
|
186
178
|
return this.storage[key] || null;
|
|
187
179
|
}
|
|
180
|
+
storeString(key, value) {
|
|
181
|
+
if (this.estimateTokens(value) > this.maxTokens) {
|
|
182
|
+
this.setMaxTokens(this.estimateTokens(value) + 1);
|
|
183
|
+
}
|
|
184
|
+
this.storage[key] = value;
|
|
185
|
+
}
|
|
188
186
|
clearStorage() {
|
|
189
187
|
this.storage = {};
|
|
190
188
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenCompressor.js","sourceRoot":"","sources":["../../../src/processors/TokenCompressor.ts"],"names":[],"mappings":";;;AAQA,MAAa,eAAe;IAClB,OAAO,GAA2B,EAAE,CAAC;IACrC,SAAS,GAAW,
|
|
1
|
+
{"version":3,"file":"TokenCompressor.js","sourceRoot":"","sources":["../../../src/processors/TokenCompressor.ts"],"names":[],"mappings":"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"}
|