@tyvm/knowhow 0.0.18 → 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 +1 -1
- package/src/plugins/downloader/plugin.ts +5 -2
- package/src/plugins/url.ts +8 -2
- package/src/processors/TokenCompressor.ts +50 -48
- package/ts_build/src/plugins/downloader/plugin.js +5 -2
- package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
- package/ts_build/src/plugins/url.js +6 -2
- package/ts_build/src/plugins/url.js.map +1 -1
- package/ts_build/src/processors/TokenCompressor.d.ts +5 -4
- package/ts_build/src/processors/TokenCompressor.js +35 -32
- package/ts_build/src/processors/TokenCompressor.js.map +1 -1
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ export class DownloaderPlugin extends PluginBase {
|
|
|
8
8
|
static readonly meta: PluginMeta = {
|
|
9
9
|
key: "downloader",
|
|
10
10
|
name: "Downloader Plugin",
|
|
11
|
-
requires: []
|
|
11
|
+
requires: [],
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
constructor() {
|
|
@@ -20,7 +20,7 @@ export class DownloaderPlugin extends PluginBase {
|
|
|
20
20
|
extractUrls(userInput: string): string[] {
|
|
21
21
|
const urlRegex = /https:\/\/[^\s]+/gim;
|
|
22
22
|
const matches = userInput.match(urlRegex) || [];
|
|
23
|
-
return matches;
|
|
23
|
+
return Array.from(new Set(matches));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async call(userInput: string): Promise<string> {
|
|
@@ -28,6 +28,9 @@ export class DownloaderPlugin extends PluginBase {
|
|
|
28
28
|
if (urls.length === 0) {
|
|
29
29
|
return "DOWNLOADER PLUGIN: No URLs found in the input";
|
|
30
30
|
}
|
|
31
|
+
if (urls.length > 10) {
|
|
32
|
+
return "DOWNLOADER PLUGIN: Too many URLs found in the input. Skipping likely unintentional bulk download.";
|
|
33
|
+
}
|
|
31
34
|
let transcript = "";
|
|
32
35
|
for (const url of urls) {
|
|
33
36
|
if (this.skipExt.includes(url.split(".").pop() || "")) {
|
package/src/plugins/url.ts
CHANGED
|
@@ -9,7 +9,7 @@ export class UrlPlugin extends PluginBase implements Plugin {
|
|
|
9
9
|
static readonly meta: PluginMeta = {
|
|
10
10
|
key: "url",
|
|
11
11
|
name: "URL Plugin",
|
|
12
|
-
requires: []
|
|
12
|
+
requires: [],
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
@@ -24,7 +24,9 @@ export class UrlPlugin extends PluginBase implements Plugin {
|
|
|
24
24
|
|
|
25
25
|
extractUrls(userPrompt: string): string[] {
|
|
26
26
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
27
|
-
|
|
27
|
+
const urls = userPrompt.match(urlRegex) || [];
|
|
28
|
+
|
|
29
|
+
return Array.from(new Set(urls));
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
async fetchAndParseUrl(url: string): Promise<MinimalEmbedding | null> {
|
|
@@ -50,6 +52,10 @@ export class UrlPlugin extends PluginBase implements Plugin {
|
|
|
50
52
|
return "URL PLUGIN: No URLs detected.";
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
if (urls.length > 10) {
|
|
56
|
+
return "URL PLUGIN: Too many URLs detected. Skipping like unintentional bulk browse.";
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
const results = await Promise.all(urls.map(this.fetchAndParseUrl));
|
|
54
60
|
const validResults = results.filter(
|
|
55
61
|
(r): r is MinimalEmbedding => r !== null
|
|
@@ -8,12 +8,15 @@ interface TokenCompressorStorage {
|
|
|
8
8
|
|
|
9
9
|
export class TokenCompressor {
|
|
10
10
|
private storage: TokenCompressorStorage = {};
|
|
11
|
-
private maxTokens: number = 20000;
|
|
12
|
-
private compressionRatio: number = 0.1;
|
|
13
11
|
private keyPrefix: string = "compressed_";
|
|
14
|
-
private jsonPropertyThreshold: number = 20000;
|
|
15
12
|
private toolName: string = expandTokensDefinition.function.name;
|
|
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,6 +27,18 @@ export class TokenCompressor {
|
|
|
24
27
|
return Math.ceil(text.length / 4);
|
|
25
28
|
}
|
|
26
29
|
|
|
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
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
/**
|
|
28
43
|
* Attempts to parse content as JSON and returns parsed object if successful
|
|
29
44
|
*/
|
|
@@ -39,6 +54,10 @@ export class TokenCompressor {
|
|
|
39
54
|
* Compresses a string into chunks from the end, creating a chain of references
|
|
40
55
|
*/
|
|
41
56
|
public compressStringInChunks(content: string, path: string = ""): string {
|
|
57
|
+
if (path === "" && this.estimateTokens(content) <= this.maxTokens) {
|
|
58
|
+
return content;
|
|
59
|
+
}
|
|
60
|
+
|
|
42
61
|
if (content.length <= this.characterLimit) {
|
|
43
62
|
return content;
|
|
44
63
|
}
|
|
@@ -73,7 +92,7 @@ export class TokenCompressor {
|
|
|
73
92
|
chunkContent += `\n\n[NEXT_CHUNK_KEY: ${nextKey}]`;
|
|
74
93
|
}
|
|
75
94
|
|
|
76
|
-
this.
|
|
95
|
+
this.storeString(key, chunkContent);
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
// Return reference to the first chunk
|
|
@@ -95,7 +114,11 @@ export class TokenCompressor {
|
|
|
95
114
|
public compressContent(content: string, path: string = ""): string {
|
|
96
115
|
const tokens = this.estimateTokens(content);
|
|
97
116
|
|
|
98
|
-
if (tokens <= this.maxTokens) {
|
|
117
|
+
if (path === "" && tokens <= this.maxTokens) {
|
|
118
|
+
return content;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (tokens <= this.compressionThreshold) {
|
|
99
122
|
return content;
|
|
100
123
|
}
|
|
101
124
|
|
|
@@ -122,6 +145,13 @@ export class TokenCompressor {
|
|
|
122
145
|
* Implements an efficient backward-iterating chunking strategy for large arrays.
|
|
123
146
|
*/
|
|
124
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
|
+
|
|
125
155
|
if (Array.isArray(obj)) {
|
|
126
156
|
// Step 1: Recursively compress all items first (depth-first).
|
|
127
157
|
const processedItems = obj.map((item, index) =>
|
|
@@ -129,11 +159,7 @@ export class TokenCompressor {
|
|
|
129
159
|
);
|
|
130
160
|
|
|
131
161
|
// Step 2: Early exit if the whole array is already small enough.
|
|
132
|
-
//
|
|
133
|
-
const initialTokens = this.estimateTokens(JSON.stringify(processedItems));
|
|
134
|
-
if (initialTokens <= this.jsonPropertyThreshold * 1.3) {
|
|
135
|
-
return processedItems;
|
|
136
|
-
}
|
|
162
|
+
// maxTokens allows us to fetch objects from the store without recompressing
|
|
137
163
|
|
|
138
164
|
// Step 3: Iterate backwards, building chunks from the end.
|
|
139
165
|
const finalArray: any[] = [];
|
|
@@ -146,9 +172,9 @@ export class TokenCompressor {
|
|
|
146
172
|
const chunkString = JSON.stringify(currentChunk);
|
|
147
173
|
const chunkTokens = this.estimateTokens(chunkString);
|
|
148
174
|
|
|
149
|
-
if (chunkTokens > this.
|
|
175
|
+
if (chunkTokens > this.compressionThreshold) {
|
|
150
176
|
const key = this.generateKey();
|
|
151
|
-
this.
|
|
177
|
+
this.storeString(key, chunkString);
|
|
152
178
|
|
|
153
179
|
const stub = `[COMPRESSED_JSON_ARRAY_CHUNK - ${chunkTokens} tokens, ${
|
|
154
180
|
currentChunk.length
|
|
@@ -182,9 +208,9 @@ export class TokenCompressor {
|
|
|
182
208
|
// After processing children, check if the entire object should be compressed
|
|
183
209
|
const objectAsString = JSON.stringify(result);
|
|
184
210
|
const tokens = this.estimateTokens(objectAsString);
|
|
185
|
-
if (tokens > this.
|
|
211
|
+
if (tokens > this.compressionThreshold) {
|
|
186
212
|
const key = this.generateKey();
|
|
187
|
-
this.
|
|
213
|
+
this.storeString(key, objectAsString);
|
|
188
214
|
|
|
189
215
|
return `[COMPRESSED_JSON_OBJECT - ${tokens} tokens]\nKey: ${key}\nPath: ${path}\nKeys: ${Object.keys(
|
|
190
216
|
result
|
|
@@ -215,7 +241,7 @@ export class TokenCompressor {
|
|
|
215
241
|
const tokens = this.estimateTokens(obj);
|
|
216
242
|
if (tokens > this.characterLimit * 4) {
|
|
217
243
|
const key = this.generateKey();
|
|
218
|
-
this.
|
|
244
|
+
this.storeString(key, obj);
|
|
219
245
|
|
|
220
246
|
return `[COMPRESSED_JSON_PROPERTY - ${tokens} tokens]\nKey: ${key}\nPath: ${path}\nPreview: ${obj.substring(
|
|
221
247
|
0,
|
|
@@ -236,36 +262,7 @@ export class TokenCompressor {
|
|
|
236
262
|
.substr(2, 9)}`;
|
|
237
263
|
}
|
|
238
264
|
|
|
239
|
-
public compressToolCall(message: Message): void {
|
|
240
|
-
if (message.tool_calls) {
|
|
241
|
-
for (const toolCall of message.tool_calls) {
|
|
242
|
-
if (toolCall.function.arguments) {
|
|
243
|
-
const args = toolCall.function.arguments;
|
|
244
|
-
const tokens = this.estimateTokens(args);
|
|
245
|
-
|
|
246
|
-
if (tokens > this.maxTokens) {
|
|
247
|
-
const key = this.generateKey();
|
|
248
|
-
this.storage[key] = args;
|
|
249
|
-
|
|
250
|
-
const compressed = `[COMPRESSED TOOL ARGS - ${tokens} tokens]\nKey: ${key}\nPreview: ${args.substring(
|
|
251
|
-
0,
|
|
252
|
-
200
|
|
253
|
-
)}...\n[Use ${
|
|
254
|
-
this.toolName
|
|
255
|
-
} tool with key "${key}" to retrieve full arguments]`;
|
|
256
|
-
|
|
257
|
-
toolCall.function.arguments = compressed;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
265
|
public async compressMessage(message: Message) {
|
|
265
|
-
// The previous check for 'isDecompressionToolResponse' is no longer necessary.
|
|
266
|
-
// The new chunking strategy returns manageable chunks that won't meet the
|
|
267
|
-
// compression threshold, naturally preventing cycles.
|
|
268
|
-
|
|
269
266
|
// Compress content if it's a string
|
|
270
267
|
if (typeof message.content === "string") {
|
|
271
268
|
message.content = this.compressContent(message.content);
|
|
@@ -278,9 +275,6 @@ export class TokenCompressor {
|
|
|
278
275
|
}
|
|
279
276
|
}
|
|
280
277
|
}
|
|
281
|
-
|
|
282
|
-
// Compress tool calls
|
|
283
|
-
this.compressToolCall(message);
|
|
284
278
|
}
|
|
285
279
|
|
|
286
280
|
createProcessor(
|
|
@@ -305,6 +299,14 @@ export class TokenCompressor {
|
|
|
305
299
|
return this.storage[key] || null;
|
|
306
300
|
}
|
|
307
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
|
+
|
|
308
310
|
clearStorage(): void {
|
|
309
311
|
this.storage = {};
|
|
310
312
|
}
|
|
@@ -12,7 +12,7 @@ class DownloaderPlugin extends PluginBase_1.PluginBase {
|
|
|
12
12
|
static meta = {
|
|
13
13
|
key: "downloader",
|
|
14
14
|
name: "Downloader Plugin",
|
|
15
|
-
requires: []
|
|
15
|
+
requires: [],
|
|
16
16
|
};
|
|
17
17
|
constructor() {
|
|
18
18
|
super(DownloaderPlugin.meta);
|
|
@@ -21,13 +21,16 @@ class DownloaderPlugin extends PluginBase_1.PluginBase {
|
|
|
21
21
|
extractUrls(userInput) {
|
|
22
22
|
const urlRegex = /https:\/\/[^\s]+/gim;
|
|
23
23
|
const matches = userInput.match(urlRegex) || [];
|
|
24
|
-
return matches;
|
|
24
|
+
return Array.from(new Set(matches));
|
|
25
25
|
}
|
|
26
26
|
async call(userInput) {
|
|
27
27
|
const urls = this.extractUrls(userInput);
|
|
28
28
|
if (urls.length === 0) {
|
|
29
29
|
return "DOWNLOADER PLUGIN: No URLs found in the input";
|
|
30
30
|
}
|
|
31
|
+
if (urls.length > 10) {
|
|
32
|
+
return "DOWNLOADER PLUGIN: Too many URLs found in the input. Skipping likely unintentional bulk download.";
|
|
33
|
+
}
|
|
31
34
|
let transcript = "";
|
|
32
35
|
for (const url of urls) {
|
|
33
36
|
if (this.skipExt.includes(url.split(".").pop() || "")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../src/plugins/downloader/plugin.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,8CAAuD;AAEvD,iDAA+D;AAC/D,6CAA0C;AAE1C,MAAa,gBAAiB,SAAQ,uBAAU;IAC9C,MAAM,CAAU,IAAI,GAAe;QACjC,GAAG,EAAE,YAAY;QACjB,IAAI,EAAE,mBAAmB;QACzB,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF;QACE,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAExC,WAAW,CAAC,SAAiB;QAC3B,MAAM,QAAQ,GAAG,qBAAqB,CAAC;QACvC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../src/plugins/downloader/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ class UrlPlugin extends PluginBase_1.PluginBase {
|
|
|
10
10
|
static meta = {
|
|
11
11
|
key: "url",
|
|
12
12
|
name: "URL Plugin",
|
|
13
|
-
requires: []
|
|
13
|
+
requires: [],
|
|
14
14
|
};
|
|
15
15
|
constructor() {
|
|
16
16
|
super(UrlPlugin.meta);
|
|
@@ -22,7 +22,8 @@ class UrlPlugin extends PluginBase_1.PluginBase {
|
|
|
22
22
|
}
|
|
23
23
|
extractUrls(userPrompt) {
|
|
24
24
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
25
|
-
|
|
25
|
+
const urls = userPrompt.match(urlRegex) || [];
|
|
26
|
+
return Array.from(new Set(urls));
|
|
26
27
|
}
|
|
27
28
|
async fetchAndParseUrl(url) {
|
|
28
29
|
try {
|
|
@@ -44,6 +45,9 @@ class UrlPlugin extends PluginBase_1.PluginBase {
|
|
|
44
45
|
if (urls.length === 0) {
|
|
45
46
|
return "URL PLUGIN: No URLs detected.";
|
|
46
47
|
}
|
|
48
|
+
if (urls.length > 10) {
|
|
49
|
+
return "URL PLUGIN: Too many URLs detected. Skipping like unintentional bulk browse.";
|
|
50
|
+
}
|
|
47
51
|
const results = await Promise.all(urls.map(this.fetchAndParseUrl));
|
|
48
52
|
const validResults = results.filter((r) => r !== null);
|
|
49
53
|
if (validResults.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/plugins/url.ts"],"names":[],"mappings":";;;;;;AAAA,6CAAsD;AAKtD,8EAAsD;AAEtD,MAAa,SAAU,SAAQ,uBAAU;IACvC,MAAM,CAAU,IAAI,GAAe;QACjC,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF;QACE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAkB;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACtE,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACrE,CAAC;IAED,WAAW,CAAC,UAAkB;QAC5B,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACxC,
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/plugins/url.ts"],"names":[],"mappings":";;;;;;AAAA,6CAAsD;AAKtD,8EAAsD;AAEtD,MAAa,SAAU,SAAQ,uBAAU;IACvC,MAAM,CAAU,IAAI,GAAe;QACjC,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF;QACE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAkB;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACtE,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACrE,CAAC;IAED,WAAW,CAAC,UAAkB;QAC5B,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACxC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAE9C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,GAAW;QAChC,IAAI;YACF,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC;YAEpC,OAAO,CAAC,GAAG,CAAC,oCAAoC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;YAE9D,OAAO;gBACL,EAAE,EAAE,GAAG,GAAG,MAAM;gBAChB,IAAI;gBACJ,QAAQ,EAAE,EAAE,GAAG,EAAE;aAClB,CAAC;SACH;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;SACb;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;YACrB,OAAO,+BAA+B,CAAC;SACxC;QAED,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE;YACpB,OAAO,8EAA8E,CAAC;SACvF;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACnE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CACjC,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC,KAAK,IAAI,CACzC,CAAC;QAEF,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;YAC7B,OAAO,gDAAgD,CAAC;SACzD;QAED,MAAM,gBAAgB,GAAG,YAAY;aAClC,GAAG,CACF,CAAC,MAAM,EAAE,EAAE,CACT,QAAQ,MAAM,CAAC,QAAQ,CAAC,GAAG,iBAAiB,MAAM,CAAC,IAAI,CAAC,SAAS,CAC/D,CAAC,EACD,GAAG,CACJ,KAAK,CACT;aACA,IAAI,CAAC,aAAa,CAAC,CAAC;QAEvB,OAAO,sEAAsE,gBAAgB,EAAE,CAAC;IAClG,CAAC;;AAvEH,8BAwEC"}
|
|
@@ -3,23 +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
|
-
private jsonPropertyThreshold;
|
|
10
7
|
private toolName;
|
|
8
|
+
private compressionThreshold;
|
|
11
9
|
private characterLimit;
|
|
10
|
+
private maxTokens;
|
|
12
11
|
constructor(toolsService?: ToolsService);
|
|
13
12
|
private estimateTokens;
|
|
13
|
+
setCompressionThreshold(threshold: number): void;
|
|
14
|
+
private setMaxTokens;
|
|
14
15
|
private tryParseJson;
|
|
15
16
|
compressStringInChunks(content: string, path?: string): string;
|
|
16
17
|
compressContent(content: string, path?: string): string;
|
|
17
18
|
compressJsonProperties(obj: any, path?: string): any;
|
|
18
19
|
private generateKey;
|
|
19
|
-
compressToolCall(message: Message): void;
|
|
20
20
|
compressMessage(message: Message): Promise<void>;
|
|
21
21
|
createProcessor(filterFn?: (msg: Message) => boolean): MessageProcessorFunction;
|
|
22
22
|
retrieveString(key: string): string | null;
|
|
23
|
+
storeString(key: string, value: string): void;
|
|
23
24
|
clearStorage(): void;
|
|
24
25
|
getStorageKeys(): string[];
|
|
25
26
|
getStorageSize(): number;
|
|
@@ -3,18 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.expandTokensDefinition = exports.TokenCompressor = void 0;
|
|
4
4
|
class TokenCompressor {
|
|
5
5
|
storage = {};
|
|
6
|
-
maxTokens = 20000;
|
|
7
|
-
compressionRatio = 0.1;
|
|
8
6
|
keyPrefix = "compressed_";
|
|
9
|
-
jsonPropertyThreshold = 20000;
|
|
10
7
|
toolName = exports.expandTokensDefinition.function.name;
|
|
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
|
+
}
|
|
21
|
+
setMaxTokens(maxTokens) {
|
|
22
|
+
if (maxTokens > this.maxTokens) {
|
|
23
|
+
this.maxTokens = maxTokens;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
18
26
|
tryParseJson(content) {
|
|
19
27
|
try {
|
|
20
28
|
return JSON.parse(content);
|
|
@@ -24,6 +32,9 @@ class TokenCompressor {
|
|
|
24
32
|
}
|
|
25
33
|
}
|
|
26
34
|
compressStringInChunks(content, path = "") {
|
|
35
|
+
if (path === "" && this.estimateTokens(content) <= this.maxTokens) {
|
|
36
|
+
return content;
|
|
37
|
+
}
|
|
27
38
|
if (content.length <= this.characterLimit) {
|
|
28
39
|
return content;
|
|
29
40
|
}
|
|
@@ -47,7 +58,7 @@ class TokenCompressor {
|
|
|
47
58
|
const nextKey = chunkKeys[i + 1];
|
|
48
59
|
chunkContent += `\n\n[NEXT_CHUNK_KEY: ${nextKey}]`;
|
|
49
60
|
}
|
|
50
|
-
this.
|
|
61
|
+
this.storeString(key, chunkContent);
|
|
51
62
|
}
|
|
52
63
|
const firstKey = chunkKeys[0];
|
|
53
64
|
const totalTokens = this.estimateTokens(content);
|
|
@@ -56,7 +67,10 @@ class TokenCompressor {
|
|
|
56
67
|
}
|
|
57
68
|
compressContent(content, path = "") {
|
|
58
69
|
const tokens = this.estimateTokens(content);
|
|
59
|
-
if (tokens <= this.maxTokens) {
|
|
70
|
+
if (path === "" && tokens <= this.maxTokens) {
|
|
71
|
+
return content;
|
|
72
|
+
}
|
|
73
|
+
if (tokens <= this.compressionThreshold) {
|
|
60
74
|
return content;
|
|
61
75
|
}
|
|
62
76
|
const jsonObj = this.tryParseJson(content);
|
|
@@ -71,12 +85,12 @@ class TokenCompressor {
|
|
|
71
85
|
return this.compressStringInChunks(content, path);
|
|
72
86
|
}
|
|
73
87
|
compressJsonProperties(obj, path = "") {
|
|
88
|
+
if (path === "" &&
|
|
89
|
+
this.estimateTokens(JSON.stringify(obj)) <= this.maxTokens) {
|
|
90
|
+
return obj;
|
|
91
|
+
}
|
|
74
92
|
if (Array.isArray(obj)) {
|
|
75
93
|
const processedItems = obj.map((item, index) => this.compressJsonProperties(item, `${path}[${index}]`));
|
|
76
|
-
const initialTokens = this.estimateTokens(JSON.stringify(processedItems));
|
|
77
|
-
if (initialTokens <= this.jsonPropertyThreshold * 1.3) {
|
|
78
|
-
return processedItems;
|
|
79
|
-
}
|
|
80
94
|
const finalArray = [];
|
|
81
95
|
let currentChunk = [];
|
|
82
96
|
for (let i = processedItems.length - 1; i >= 0; i--) {
|
|
@@ -84,9 +98,9 @@ class TokenCompressor {
|
|
|
84
98
|
currentChunk.unshift(item);
|
|
85
99
|
const chunkString = JSON.stringify(currentChunk);
|
|
86
100
|
const chunkTokens = this.estimateTokens(chunkString);
|
|
87
|
-
if (chunkTokens > this.
|
|
101
|
+
if (chunkTokens > this.compressionThreshold) {
|
|
88
102
|
const key = this.generateKey();
|
|
89
|
-
this.
|
|
103
|
+
this.storeString(key, chunkString);
|
|
90
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]`;
|
|
91
105
|
finalArray.unshift(stub);
|
|
92
106
|
currentChunk = [];
|
|
@@ -105,9 +119,9 @@ class TokenCompressor {
|
|
|
105
119
|
}
|
|
106
120
|
const objectAsString = JSON.stringify(result);
|
|
107
121
|
const tokens = this.estimateTokens(objectAsString);
|
|
108
|
-
if (tokens > this.
|
|
122
|
+
if (tokens > this.compressionThreshold) {
|
|
109
123
|
const key = this.generateKey();
|
|
110
|
-
this.
|
|
124
|
+
this.storeString(key, objectAsString);
|
|
111
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]`;
|
|
112
126
|
}
|
|
113
127
|
return result;
|
|
@@ -126,7 +140,7 @@ class TokenCompressor {
|
|
|
126
140
|
const tokens = this.estimateTokens(obj);
|
|
127
141
|
if (tokens > this.characterLimit * 4) {
|
|
128
142
|
const key = this.generateKey();
|
|
129
|
-
this.
|
|
143
|
+
this.storeString(key, obj);
|
|
130
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]`;
|
|
131
145
|
}
|
|
132
146
|
return obj;
|
|
@@ -138,22 +152,6 @@ class TokenCompressor {
|
|
|
138
152
|
.toString(36)
|
|
139
153
|
.substr(2, 9)}`;
|
|
140
154
|
}
|
|
141
|
-
compressToolCall(message) {
|
|
142
|
-
if (message.tool_calls) {
|
|
143
|
-
for (const toolCall of message.tool_calls) {
|
|
144
|
-
if (toolCall.function.arguments) {
|
|
145
|
-
const args = toolCall.function.arguments;
|
|
146
|
-
const tokens = this.estimateTokens(args);
|
|
147
|
-
if (tokens > this.maxTokens) {
|
|
148
|
-
const key = this.generateKey();
|
|
149
|
-
this.storage[key] = args;
|
|
150
|
-
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]`;
|
|
151
|
-
toolCall.function.arguments = compressed;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
155
|
async compressMessage(message) {
|
|
158
156
|
if (typeof message.content === "string") {
|
|
159
157
|
message.content = this.compressContent(message.content);
|
|
@@ -165,7 +163,6 @@ class TokenCompressor {
|
|
|
165
163
|
}
|
|
166
164
|
}
|
|
167
165
|
}
|
|
168
|
-
this.compressToolCall(message);
|
|
169
166
|
}
|
|
170
167
|
createProcessor(filterFn) {
|
|
171
168
|
return async (originalMessages, modifiedMessages) => {
|
|
@@ -180,6 +177,12 @@ class TokenCompressor {
|
|
|
180
177
|
retrieveString(key) {
|
|
181
178
|
return this.storage[key] || null;
|
|
182
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
|
+
}
|
|
183
186
|
clearStorage() {
|
|
184
187
|
this.storage = {};
|
|
185
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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"}
|