acp-kernel 0.0.8 → 0.0.10
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/compress.d.ts.map +1 -1
- package/dist/hide-consumed.d.ts.map +1 -1
- package/dist/index.js +95 -122
- package/dist/index.js.map +1 -1
- package/dist/nudge-text.d.ts.map +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/compress.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAcpB,OAAO,EAGL,KAAK,YAAY,EAElB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AAED,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAcpB,OAAO,EAGL,KAAK,YAAY,EAElB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAEhB,MAAM,EAEN,WAAW,EAGX,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACvE,YAAY,IAAI,YAAY,EAAE,CAAC;IAC/B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IACnE,MAAM,CACJ,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;IACJ,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnC;AAED,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CAoN7D;AAgpBD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hide-consumed.d.ts","sourceRoot":"","sources":["../src/hide-consumed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"hide-consumed.d.ts","sourceRoot":"","sources":["../src/hide-consumed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQhE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAClB;AAGD,wBAAgB,yBAAyB,CACrC,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,WAAW,EAAE,GACxB,kBAAkB,CAwDpB"}
|
package/dist/index.js
CHANGED
|
@@ -81,7 +81,8 @@ function createInitialState() {
|
|
|
81
81
|
lastPerMessageNudgeTokens: 0,
|
|
82
82
|
lastNudgeShownTokens: 0,
|
|
83
83
|
baselineTokens: 0,
|
|
84
|
-
anchors: {}
|
|
84
|
+
anchors: {},
|
|
85
|
+
lastShownByTier: {}
|
|
85
86
|
},
|
|
86
87
|
stats: { tokensCompressed: 0, compressionCount: 0 },
|
|
87
88
|
nextBlockId: 1,
|
|
@@ -504,7 +505,7 @@ function truncateLargeToolOutputs(messages, tokenCount, config, countTokens, opt
|
|
|
504
505
|
}
|
|
505
506
|
|
|
506
507
|
// src/hide-consumed.ts
|
|
507
|
-
var KEEP_LAST_ORPHANED =
|
|
508
|
+
var KEEP_LAST_ORPHANED = 0;
|
|
508
509
|
function hideConsumedCompressCalls(state, messages) {
|
|
509
510
|
const activeCallIds = /* @__PURE__ */ new Set();
|
|
510
511
|
const allBlockCallIds = /* @__PURE__ */ new Set();
|
|
@@ -1048,6 +1049,7 @@ function createCore(ports = {}) {
|
|
|
1048
1049
|
if (blocksCreated > 0) {
|
|
1049
1050
|
state.nudge.lastPerMessageNudgeTokens = 0;
|
|
1050
1051
|
state.nudge.lastNudgeShownTokens = 0;
|
|
1052
|
+
state.nudge.lastShownByTier = {};
|
|
1051
1053
|
}
|
|
1052
1054
|
return { state, result: { blocksCreated, tokensCompressed, errors } };
|
|
1053
1055
|
}
|
|
@@ -1183,7 +1185,8 @@ var nudgeNode = {
|
|
|
1183
1185
|
config: ctx.config,
|
|
1184
1186
|
state: io.state,
|
|
1185
1187
|
messages: io.messages,
|
|
1186
|
-
recommendation: io.effects.recommendation
|
|
1188
|
+
recommendation: io.effects.recommendation,
|
|
1189
|
+
countTokens: ctx.countTokens
|
|
1187
1190
|
});
|
|
1188
1191
|
const baseline = io.state.nudge.lastPerMessageNudgeTokens;
|
|
1189
1192
|
const nudgeGrowthTokens = resolveAdaptiveGrowth(
|
|
@@ -1200,6 +1203,9 @@ var nudgeNode = {
|
|
|
1200
1203
|
}
|
|
1201
1204
|
if (nudge.shouldInject) {
|
|
1202
1205
|
stamped.lastNudgeShownTokens = ctx.tokenCount;
|
|
1206
|
+
if (nudge.tier !== null) {
|
|
1207
|
+
stamped.lastShownByTier = { ...stamped.lastShownByTier, [nudge.tier]: ctx.tokenCount };
|
|
1208
|
+
}
|
|
1203
1209
|
}
|
|
1204
1210
|
return {
|
|
1205
1211
|
...io,
|
|
@@ -1427,8 +1433,19 @@ function resolveAdaptiveGrowth(modelContextLimit, nudge) {
|
|
|
1427
1433
|
)
|
|
1428
1434
|
);
|
|
1429
1435
|
}
|
|
1436
|
+
function pendingByTier(state, recommendation, countTokens) {
|
|
1437
|
+
const out = {};
|
|
1438
|
+
const compressible = recommendation?.contextRanges.compressible ?? [];
|
|
1439
|
+
out[1] = { pending: compressible.reduce((s, r) => s + r.tokens, 0), targetBlocks: [] };
|
|
1440
|
+
const active = activeBlocks(state);
|
|
1441
|
+
const t1 = active.filter((b) => b.tier === 1);
|
|
1442
|
+
const t2 = active.filter((b) => b.tier === 2);
|
|
1443
|
+
out[2] = { pending: t1.reduce((s, b) => s + countTokens(b.summary), 0), targetBlocks: t1 };
|
|
1444
|
+
out[3] = { pending: t2.reduce((s, b) => s + countTokens(b.summary), 0), targetBlocks: t2 };
|
|
1445
|
+
return out;
|
|
1446
|
+
}
|
|
1430
1447
|
function decideNudge(input) {
|
|
1431
|
-
const { config, state, tokenCount, recommendation } = input;
|
|
1448
|
+
const { config, state, tokenCount, recommendation, countTokens } = input;
|
|
1432
1449
|
const limit = config.modelContextLimit;
|
|
1433
1450
|
const usage = limit > 0 ? tokenCount / limit : 0;
|
|
1434
1451
|
const nudgeGrowthTokens = resolveAdaptiveGrowth(limit, config.nudge);
|
|
@@ -1443,40 +1460,45 @@ function decideNudge(input) {
|
|
|
1443
1460
|
config.nudge.minGrowthRatio * nudgeGrowthTokens
|
|
1444
1461
|
);
|
|
1445
1462
|
const growthSinceReference = tokenCount - growthReference;
|
|
1446
|
-
const
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
tierTargetBlocks = activeT1;
|
|
1463
|
+
const rec = recommendation;
|
|
1464
|
+
const tiers = pendingByTier(state, rec, countTokens);
|
|
1465
|
+
let injectedTier = null;
|
|
1466
|
+
let injectedReason = "";
|
|
1467
|
+
const growthReady = growthSinceReference >= growthFloor;
|
|
1468
|
+
if (!emergencyOverride && growthReady) {
|
|
1469
|
+
for (const tier of [1, 2, 3]) {
|
|
1470
|
+
if (!config.tiers.enabled && tier > 1) break;
|
|
1471
|
+
const info = tiers[tier];
|
|
1472
|
+
if (!info || info.pending < nudgeGrowthTokens) continue;
|
|
1473
|
+
const lastShown = state.nudge.lastShownByTier[tier] ?? 0;
|
|
1474
|
+
const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
|
|
1475
|
+
if (!cadenceMet) continue;
|
|
1476
|
+
injectedTier = tier;
|
|
1477
|
+
injectedReason = tier === 1 ? `T1 compressible ${info.pending} >= ${nudgeGrowthTokens}, growth ${growthSinceReference}, usage ${Math.round(usage * 100)}%` : `T${tier} distill ready: ${info.targetBlocks.length} tier-${tier - 1} blocks (${info.pending} tokens) >= ${nudgeGrowthTokens}, usage ${Math.round(usage * 100)}%`;
|
|
1478
|
+
break;
|
|
1463
1479
|
}
|
|
1464
1480
|
}
|
|
1465
|
-
const
|
|
1466
|
-
const nothingToCompress = rec ? rec.contextRanges.compressible.length === 0 : false;
|
|
1467
|
-
const shouldInject = shouldContextNudge;
|
|
1481
|
+
const shouldInject = emergencyOverride || injectedTier !== null;
|
|
1468
1482
|
let reason;
|
|
1469
|
-
if (
|
|
1470
|
-
const tierHint = tier !== null ? `, tier-${tier} ready (distill when growth reaches threshold)` : "";
|
|
1471
|
-
reason = `growth ${growthSinceReference} < threshold ${effectiveThreshold}${hasPendingNudge ? " (halved)" : ""} (floor ${growthFloor})${tierHint}`;
|
|
1472
|
-
} else if (emergencyOverride) {
|
|
1483
|
+
if (emergencyOverride) {
|
|
1473
1484
|
reason = `EMERGENCY: usage ${Math.round(usage * 100)}% >= ${Math.round(config.nudge.emergencyThresholdPct * 100)}%`;
|
|
1474
|
-
} else if (
|
|
1475
|
-
reason =
|
|
1476
|
-
} else if (nothingToCompress) {
|
|
1477
|
-
reason = `growth ${growthSinceReference} >= ${effectiveThreshold} but no specific ranges worth compressing`;
|
|
1485
|
+
} else if (injectedTier !== null) {
|
|
1486
|
+
reason = injectedReason;
|
|
1478
1487
|
} else {
|
|
1479
|
-
|
|
1488
|
+
const tiersList = [1, 2, 3];
|
|
1489
|
+
const eligible = tiersList.filter((t) => config.tiers.enabled || t === 1);
|
|
1490
|
+
const ready = eligible.filter((t) => (tiers[t]?.pending ?? 0) >= nudgeGrowthTokens).map((t) => `T${t} ${tiers[t].pending}`);
|
|
1491
|
+
const readyHint = ready.length > 0 ? `, ready: ${ready.join(", ")}` : "";
|
|
1492
|
+
const blocked = eligible.filter((t) => (tiers[t]?.pending ?? 0) >= nudgeGrowthTokens && (state.nudge.lastShownByTier[t] ?? 0) > 0 && tokenCount - (state.nudge.lastShownByTier[t] ?? 0) < growthFloor).map((t) => `T${t} (cadence)`);
|
|
1493
|
+
const blockedHint = blocked.length > 0 ? `, blocked: ${blocked.join(", ")}` : "";
|
|
1494
|
+
const maxPending = Math.max(0, ...Object.values(tiers).map((t) => t.pending));
|
|
1495
|
+
const pendingShort = maxPending < nudgeGrowthTokens;
|
|
1496
|
+
const growthShort = growthSinceReference < growthFloor;
|
|
1497
|
+
const parts = [];
|
|
1498
|
+
if (pendingShort) parts.push(`max compressible ${maxPending} < threshold ${nudgeGrowthTokens}`);
|
|
1499
|
+
if (growthShort) parts.push(`growth ${growthSinceReference} < floor ${growthFloor}`);
|
|
1500
|
+
if (parts.length === 0) parts.push(`max compressible ${maxPending}, growth ${growthSinceReference}`);
|
|
1501
|
+
reason = `${parts.join("; ")}${readyHint}${blockedHint}`;
|
|
1480
1502
|
}
|
|
1481
1503
|
const ctxBreakdown = computeContextBreakdown(input.messages, tokenCount, growthSinceReference);
|
|
1482
1504
|
return {
|
|
@@ -1484,9 +1506,9 @@ function decideNudge(input) {
|
|
|
1484
1506
|
reason,
|
|
1485
1507
|
compressibleRanges: rec?.recommendedRanges ?? [],
|
|
1486
1508
|
protectedRanges: rec?.contextRanges.protected ?? [],
|
|
1487
|
-
tierTargetBlocks,
|
|
1509
|
+
tierTargetBlocks: injectedTier ? tiers[injectedTier].targetBlocks : [],
|
|
1488
1510
|
contextUsage: usage,
|
|
1489
|
-
tier,
|
|
1511
|
+
tier: injectedTier,
|
|
1490
1512
|
breakdown: {
|
|
1491
1513
|
usage,
|
|
1492
1514
|
growth: growthSinceReference,
|
|
@@ -1495,7 +1517,10 @@ function decideNudge(input) {
|
|
|
1495
1517
|
nudgeGrowthTokens,
|
|
1496
1518
|
growthFloor,
|
|
1497
1519
|
hasPendingNudge: hasPendingNudge ? 1 : 0,
|
|
1498
|
-
emergencyOverride: emergencyOverride ? 1 : 0
|
|
1520
|
+
emergencyOverride: emergencyOverride ? 1 : 0,
|
|
1521
|
+
pendingT1: tiers[1].pending,
|
|
1522
|
+
pendingT2: tiers[2].pending,
|
|
1523
|
+
pendingT3: tiers[3].pending
|
|
1499
1524
|
},
|
|
1500
1525
|
contextBreakdown: ctxBreakdown
|
|
1501
1526
|
};
|
|
@@ -1691,76 +1716,6 @@ function formatBreakdown(bd) {
|
|
|
1691
1716
|
+${formatK(bd.growth)} since last nudge` : "";
|
|
1692
1717
|
return `Context breakdown: ${parts.join(" | ")}${growth}`;
|
|
1693
1718
|
}
|
|
1694
|
-
function refToNum(ref) {
|
|
1695
|
-
if (!ref) return 0;
|
|
1696
|
-
const m = ref.match(/^m0*(\d+)$/);
|
|
1697
|
-
return m && m[1] ? parseInt(m[1], 10) : 0;
|
|
1698
|
-
}
|
|
1699
|
-
function mergeRanges(compressible, protected_) {
|
|
1700
|
-
const entries = [];
|
|
1701
|
-
for (const r of compressible) {
|
|
1702
|
-
const sNum = refToNum(r.startRef);
|
|
1703
|
-
const eNum = refToNum(r.endRef);
|
|
1704
|
-
entries.push({
|
|
1705
|
-
startRef: r.startRef,
|
|
1706
|
-
endRef: r.endRef,
|
|
1707
|
-
startNum: sNum,
|
|
1708
|
-
endNum: eNum,
|
|
1709
|
-
count: r.count,
|
|
1710
|
-
tokens: r.tokens,
|
|
1711
|
-
compressibleTokens: r.tokens,
|
|
1712
|
-
compressibleCount: r.count,
|
|
1713
|
-
protectedTokens: 0,
|
|
1714
|
-
protectedCount: 0,
|
|
1715
|
-
protectedTools: [],
|
|
1716
|
-
toolPct: r.toolPct,
|
|
1717
|
-
textPct: r.textPct,
|
|
1718
|
-
dangerous: r.dangerous ?? false
|
|
1719
|
-
});
|
|
1720
|
-
}
|
|
1721
|
-
for (const r of protected_) {
|
|
1722
|
-
const sNum = refToNum(r.startRef);
|
|
1723
|
-
const eNum = refToNum(r.endRef);
|
|
1724
|
-
entries.push({
|
|
1725
|
-
startRef: r.startRef,
|
|
1726
|
-
endRef: r.endRef,
|
|
1727
|
-
startNum: sNum,
|
|
1728
|
-
endNum: eNum,
|
|
1729
|
-
count: r.count,
|
|
1730
|
-
tokens: r.tokens,
|
|
1731
|
-
compressibleTokens: 0,
|
|
1732
|
-
compressibleCount: 0,
|
|
1733
|
-
protectedTokens: r.tokens,
|
|
1734
|
-
protectedCount: r.count,
|
|
1735
|
-
protectedTools: [...r.tools],
|
|
1736
|
-
toolPct: 0,
|
|
1737
|
-
textPct: 0,
|
|
1738
|
-
dangerous: false
|
|
1739
|
-
});
|
|
1740
|
-
}
|
|
1741
|
-
entries.sort((a, b) => a.startNum - b.startNum);
|
|
1742
|
-
const merged = [];
|
|
1743
|
-
for (const e of entries) {
|
|
1744
|
-
const last = merged[merged.length - 1];
|
|
1745
|
-
if (last && last.endNum + 1 >= e.startNum) {
|
|
1746
|
-
last.endRef = e.endRef;
|
|
1747
|
-
last.endNum = Math.max(last.endNum, e.endNum);
|
|
1748
|
-
last.count += e.count;
|
|
1749
|
-
last.tokens += e.tokens;
|
|
1750
|
-
last.compressibleTokens += e.compressibleTokens;
|
|
1751
|
-
last.compressibleCount += e.compressibleCount;
|
|
1752
|
-
last.protectedTokens += e.protectedTokens;
|
|
1753
|
-
last.protectedCount += e.protectedCount;
|
|
1754
|
-
if (e.dangerous) last.dangerous = true;
|
|
1755
|
-
for (const t of e.protectedTools) {
|
|
1756
|
-
if (!last.protectedTools.includes(t)) last.protectedTools.push(t);
|
|
1757
|
-
}
|
|
1758
|
-
} else {
|
|
1759
|
-
merged.push({ ...e });
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
return merged;
|
|
1763
|
-
}
|
|
1764
1719
|
function formatTierTargetBlocks(blocks) {
|
|
1765
1720
|
if (blocks.length === 0) {
|
|
1766
1721
|
return "Target blocks: (none \u2014 no tier blocks found)";
|
|
@@ -1773,27 +1728,25 @@ function formatTierTargetBlocks(blocks) {
|
|
|
1773
1728
|
return `Target ${blocks[0].tier === 1 ? "tier-1" : "tier-2"} blocks to distill (${blocks.length}):
|
|
1774
1729
|
${lines.join("\n")}`;
|
|
1775
1730
|
}
|
|
1776
|
-
function formatRanges(compressible
|
|
1777
|
-
|
|
1778
|
-
if (merged.length === 0) {
|
|
1731
|
+
function formatRanges(compressible) {
|
|
1732
|
+
if (compressible.length === 0) {
|
|
1779
1733
|
return "[No specific ranges detected \u2014 compress any consumed content.]";
|
|
1780
1734
|
}
|
|
1781
|
-
const
|
|
1782
|
-
const
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
}
|
|
1735
|
+
const refNum2 = (ref) => {
|
|
1736
|
+
const m = ref.match(/\d+/);
|
|
1737
|
+
return m ? parseInt(m[0], 10) : 0;
|
|
1738
|
+
};
|
|
1739
|
+
const sorted = [...compressible].sort((a, b) => refNum2(a.startRef) - refNum2(b.startRef));
|
|
1740
|
+
const lines = sorted.map((e) => {
|
|
1741
|
+
const suffix = e.dangerous ? " \u26A0\uFE0F NOT recommended unless you are certain." : "";
|
|
1789
1742
|
return ` ${e.startRef}\u2013${e.endRef} ${e.count} msgs ${formatK(e.tokens)} [tool ${e.toolPct}% | text ${e.textPct}%]${suffix}`;
|
|
1790
1743
|
});
|
|
1791
|
-
return `Compressible ranges (oldest first):
|
|
1744
|
+
return `Compressible ranges (${compressible.length}, oldest first):
|
|
1792
1745
|
${lines.join("\n")}`;
|
|
1793
1746
|
}
|
|
1794
1747
|
function renderNudgeText(decision) {
|
|
1795
1748
|
const breakdownStr = formatBreakdown(decision.contextBreakdown);
|
|
1796
|
-
const rangesStr = formatRanges(decision.compressibleRanges
|
|
1749
|
+
const rangesStr = formatRanges(decision.compressibleRanges);
|
|
1797
1750
|
if (decision.tier !== null && decision.tier >= 2) {
|
|
1798
1751
|
const isT2 = decision.tier === 2;
|
|
1799
1752
|
const targets = decision.tierTargetBlocks ?? [];
|
|
@@ -2150,11 +2103,31 @@ function renderUncompressedRanges(visible) {
|
|
|
2150
2103
|
lines.push("");
|
|
2151
2104
|
if (visible.length === 0) {
|
|
2152
2105
|
lines.push(" (no uncompressed messages)");
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2106
|
+
return lines.join("\n");
|
|
2107
|
+
}
|
|
2108
|
+
const refNum2 = (ref) => {
|
|
2109
|
+
const m = ref.match(/\d+/);
|
|
2110
|
+
return m ? parseInt(m[0], 10) : 0;
|
|
2111
|
+
};
|
|
2112
|
+
const merged = [];
|
|
2113
|
+
for (const m of visible) {
|
|
2114
|
+
const num = refNum2(m.ref);
|
|
2115
|
+
const last = merged[merged.length - 1];
|
|
2116
|
+
if (last && num === last.startNum + last.count) {
|
|
2117
|
+
last.endRef = m.ref;
|
|
2118
|
+
last.count += 1;
|
|
2119
|
+
last.tokens += m.tokens;
|
|
2120
|
+
} else {
|
|
2121
|
+
merged.push({ startRef: m.ref, endRef: m.ref, startNum: num, count: 1, tokens: m.tokens, tool: m.tool });
|
|
2156
2122
|
}
|
|
2157
2123
|
}
|
|
2124
|
+
for (const r of merged.slice(0, 30)) {
|
|
2125
|
+
const range = r.count === 1 ? r.startRef : `${r.startRef}\u2013${r.endRef}`;
|
|
2126
|
+
lines.push(` ${range} (${r.count} msgs, ${formatTokens2(r.tokens)}${r.count > 1 ? ` (${Math.round(r.tokens / r.count)}/msg)` : ""}) ${r.tool}`);
|
|
2127
|
+
}
|
|
2128
|
+
if (merged.length > 30) {
|
|
2129
|
+
lines.push(` ... and ${merged.length - 30} more ranges`);
|
|
2130
|
+
}
|
|
2158
2131
|
return lines.join("\n");
|
|
2159
2132
|
}
|
|
2160
2133
|
function renderMessageDrilldown(visible, toolFilter, sort, limit) {
|