@wrongstack/core 0.256.0 → 0.257.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/defaults/index.d.ts +1 -1
- package/dist/defaults/index.js +128 -22
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.js +107 -20
- package/dist/execution/index.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +144 -38
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.js +9 -8
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/models/index.js +9 -8
- package/dist/models/index.js.map +1 -1
- package/dist/sdd/index.js +7 -2
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-BkYkJWQs.d.ts → secret-vault-gxtFZYBt.d.ts} +7 -0
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +23 -9
- package/dist/security/index.js.map +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +137 -36
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.js +9 -8
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/execution/index.js
CHANGED
|
@@ -6,16 +6,6 @@ import * as path2 from 'path';
|
|
|
6
6
|
import * as os from 'os';
|
|
7
7
|
import { EventEmitter } from 'events';
|
|
8
8
|
|
|
9
|
-
// src/utils/expect-defined.ts
|
|
10
|
-
function expectDefined(value, label) {
|
|
11
|
-
if (value === null || value === void 0) {
|
|
12
|
-
const err = new Error("Expected value to be defined");
|
|
13
|
-
err.name = "ExpectDefinedError";
|
|
14
|
-
throw err;
|
|
15
|
-
}
|
|
16
|
-
return value;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
9
|
// src/utils/token-estimate.ts
|
|
20
10
|
var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
|
|
21
11
|
var CALIBRATION_GLOBAL_KEY = "__global__";
|
|
@@ -35,12 +25,15 @@ function getCachedEstimate(key, compute) {
|
|
|
35
25
|
const existing = ESTIMATE_CACHE.get(key);
|
|
36
26
|
if (existing !== void 0) return existing;
|
|
37
27
|
if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
28
|
+
let evicted = 0;
|
|
29
|
+
const maxEvict = Math.floor(ESTIMATE_CACHE_MAX_SIZE / 4);
|
|
30
|
+
for (const k of ESTIMATE_CACHE.keys()) {
|
|
31
|
+
if (evicted >= maxEvict) break;
|
|
32
|
+
ESTIMATE_CACHE.delete(k);
|
|
33
|
+
evicted++;
|
|
41
34
|
}
|
|
42
35
|
}
|
|
43
|
-
const estimate = compute();
|
|
36
|
+
const estimate = compute(key);
|
|
44
37
|
ESTIMATE_CACHE.set(key, estimate);
|
|
45
38
|
return estimate;
|
|
46
39
|
}
|
|
@@ -49,13 +42,11 @@ function estimateToolInputTokens(input) {
|
|
|
49
42
|
if (input === null || typeof input !== "object") {
|
|
50
43
|
return RoughTokenEstimate(String(input));
|
|
51
44
|
}
|
|
52
|
-
|
|
53
|
-
return getCachedEstimate(key, () => RoughTokenEstimate(key));
|
|
45
|
+
return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));
|
|
54
46
|
}
|
|
55
47
|
function estimateToolResultTokens(content) {
|
|
56
48
|
if (typeof content === "string") return RoughTokenEstimate(content);
|
|
57
|
-
|
|
58
|
-
return getCachedEstimate(key, () => RoughTokenEstimate(key));
|
|
49
|
+
return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));
|
|
59
50
|
}
|
|
60
51
|
function estimateTextTokens(text) {
|
|
61
52
|
return RoughTokenEstimate(text);
|
|
@@ -162,6 +153,16 @@ function estimateRequestTokensCalibrated(messages, systemPrompt, tools, calibrat
|
|
|
162
153
|
return result;
|
|
163
154
|
}
|
|
164
155
|
|
|
156
|
+
// src/utils/expect-defined.ts
|
|
157
|
+
function expectDefined(value, label) {
|
|
158
|
+
if (value === null || value === void 0) {
|
|
159
|
+
const err = new Error("Expected value to be defined");
|
|
160
|
+
err.name = "ExpectDefinedError";
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
|
|
165
166
|
// src/utils/message-invariants.ts
|
|
166
167
|
function repairToolUseAdjacency(messages) {
|
|
167
168
|
const removedToolUses = [];
|
|
@@ -260,6 +261,25 @@ function isTextBlock(b) {
|
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
// src/execution/compaction-core.ts
|
|
264
|
+
function emitCompactionMetrics(event, metrics) {
|
|
265
|
+
console.log(
|
|
266
|
+
JSON.stringify({
|
|
267
|
+
level: "debug",
|
|
268
|
+
event,
|
|
269
|
+
messageCount: metrics.messageCount,
|
|
270
|
+
preserveStart: metrics.preserveStart,
|
|
271
|
+
fastPathIterations: metrics.fastPathIterations,
|
|
272
|
+
fastPathInnerIterations: metrics.fastPathInnerIterations,
|
|
273
|
+
// Ratios — anything > 2.0 indicates the inner loop is running more than expected
|
|
274
|
+
fastPathInnerPerOuter: metrics.fastPathIterations > 0 ? metrics.fastPathInnerIterations / metrics.fastPathIterations : 0,
|
|
275
|
+
fullPassIterations: metrics.fullPassIterations,
|
|
276
|
+
fullPassInnerIterations: metrics.fullPassInnerIterations,
|
|
277
|
+
fullPassInnerPerOuter: metrics.fullPassIterations > 0 ? metrics.fullPassInnerIterations / metrics.fullPassIterations : 0,
|
|
278
|
+
tokensSaved: metrics.tokensSaved,
|
|
279
|
+
changed: metrics.changed
|
|
280
|
+
})
|
|
281
|
+
);
|
|
282
|
+
}
|
|
263
283
|
var estimateMessages = estimateMessageTokens;
|
|
264
284
|
function hasTextContent(m) {
|
|
265
285
|
if (typeof m.content === "string") return m.content.trim().length > 0;
|
|
@@ -276,37 +296,78 @@ function findPreserveStart(messages, preserveK) {
|
|
|
276
296
|
preserveStart = i;
|
|
277
297
|
}
|
|
278
298
|
}
|
|
299
|
+
let forwardWalkIterations = 0;
|
|
300
|
+
let forwardWalkInnerIterations = 0;
|
|
279
301
|
for (let i = preserveStart; i < messages.length; i++) {
|
|
302
|
+
forwardWalkIterations++;
|
|
280
303
|
const m = messages[i];
|
|
281
304
|
if (!m || typeof m.content === "string" || !Array.isArray(m.content)) continue;
|
|
282
|
-
const hasToolUse3 = m.content.some((b) =>
|
|
305
|
+
const hasToolUse3 = m.content.some((b) => {
|
|
306
|
+
forwardWalkInnerIterations++;
|
|
307
|
+
return b.type === "tool_use";
|
|
308
|
+
});
|
|
283
309
|
if (hasToolUse3 && i + 1 < messages.length) {
|
|
284
310
|
const next = messages[i + 1];
|
|
285
|
-
if (next && next.role === "user" && typeof next.content !== "string" && Array.isArray(next.content) && next.content.some((b) =>
|
|
311
|
+
if (next && next.role === "user" && typeof next.content !== "string" && Array.isArray(next.content) && next.content.some((b) => {
|
|
312
|
+
forwardWalkInnerIterations++;
|
|
313
|
+
return b.type === "tool_result";
|
|
314
|
+
})) {
|
|
286
315
|
preserveStart = i + 1;
|
|
287
316
|
}
|
|
288
317
|
}
|
|
289
318
|
}
|
|
319
|
+
console.log(
|
|
320
|
+
JSON.stringify({
|
|
321
|
+
level: "debug",
|
|
322
|
+
event: "compaction.find_preserve_start.ended",
|
|
323
|
+
messageCount: messages.length,
|
|
324
|
+
preserveK,
|
|
325
|
+
preserveStart,
|
|
326
|
+
forwardWalkIterations,
|
|
327
|
+
forwardWalkInnerIterations,
|
|
328
|
+
forwardWalkInnerPerOuter: forwardWalkIterations > 0 ? forwardWalkInnerIterations / forwardWalkIterations : 0
|
|
329
|
+
})
|
|
330
|
+
);
|
|
290
331
|
return preserveStart;
|
|
291
332
|
}
|
|
292
333
|
function eliseOldToolResults(messages, opts) {
|
|
293
334
|
const preserveStart = findPreserveStart(messages, opts.preserveK);
|
|
294
335
|
let hasOversized = false;
|
|
336
|
+
let fastPathIterations = 0;
|
|
337
|
+
let fastPathInnerIterations = 0;
|
|
295
338
|
for (let i = 0; i < preserveStart && !hasOversized; i++) {
|
|
339
|
+
fastPathIterations++;
|
|
296
340
|
const msg = messages[i];
|
|
297
341
|
if (!msg || !Array.isArray(msg.content)) continue;
|
|
298
342
|
for (const b of msg.content) {
|
|
343
|
+
fastPathInnerIterations++;
|
|
299
344
|
if (b.type === "tool_result" && estimateToolResultTokens(b.content) >= opts.eliseThreshold) {
|
|
300
345
|
hasOversized = true;
|
|
301
346
|
break;
|
|
302
347
|
}
|
|
303
348
|
}
|
|
304
349
|
}
|
|
350
|
+
emitCompactionMetrics(
|
|
351
|
+
hasOversized ? "compaction.elision.fast_path.oversized_found" : "compaction.elision.fast_path.no_oversized",
|
|
352
|
+
{
|
|
353
|
+
messageCount: messages.length,
|
|
354
|
+
preserveStart,
|
|
355
|
+
fastPathIterations,
|
|
356
|
+
fastPathInnerIterations,
|
|
357
|
+
fullPassIterations: 0,
|
|
358
|
+
fullPassInnerIterations: 0,
|
|
359
|
+
tokensSaved: 0,
|
|
360
|
+
changed: false
|
|
361
|
+
}
|
|
362
|
+
);
|
|
305
363
|
if (!hasOversized) return { messages, saved: 0, changed: false };
|
|
306
364
|
let saved = 0;
|
|
307
365
|
let changed = false;
|
|
366
|
+
let fullPassIterations = 0;
|
|
367
|
+
let fullPassInnerIterations = 0;
|
|
308
368
|
const next = new Array(messages.length);
|
|
309
369
|
for (let i = 0; i < messages.length; i++) {
|
|
370
|
+
fullPassIterations++;
|
|
310
371
|
const msg = messages[i];
|
|
311
372
|
if (i >= preserveStart || !msg || !Array.isArray(msg.content)) {
|
|
312
373
|
next[i] = msg;
|
|
@@ -332,7 +393,33 @@ function eliseOldToolResults(messages, opts) {
|
|
|
332
393
|
next[i] = { ...msg, content: newContent };
|
|
333
394
|
changed = true;
|
|
334
395
|
}
|
|
396
|
+
fullPassInnerIterations += original.length;
|
|
397
|
+
if (process.env["NODE_ENV"] === "development" || process.env["WRONGSTACK_DEBUG"] === "1") {
|
|
398
|
+
const ratio = fullPassInnerIterations / fullPassIterations;
|
|
399
|
+
if (ratio > 10) {
|
|
400
|
+
console.error(
|
|
401
|
+
JSON.stringify({
|
|
402
|
+
level: "error",
|
|
403
|
+
event: "compaction.elision.regression",
|
|
404
|
+
message: `fullPassInnerPerOuter=${ratio.toFixed(2)} exceeds threshold 10 \u2014 possible O(n\xB7m) regression`,
|
|
405
|
+
messageCount: messages.length,
|
|
406
|
+
fullPassIterations,
|
|
407
|
+
fullPassInnerIterations
|
|
408
|
+
})
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
335
412
|
}
|
|
413
|
+
emitCompactionMetrics("compaction.elision.full_pass.ended", {
|
|
414
|
+
messageCount: messages.length,
|
|
415
|
+
preserveStart,
|
|
416
|
+
fastPathIterations,
|
|
417
|
+
fastPathInnerIterations,
|
|
418
|
+
fullPassIterations,
|
|
419
|
+
fullPassInnerIterations,
|
|
420
|
+
tokensSaved: saved,
|
|
421
|
+
changed
|
|
422
|
+
});
|
|
336
423
|
return { messages: changed ? next : messages, saved, changed };
|
|
337
424
|
}
|
|
338
425
|
function buildLosslessDigest(messages) {
|