acp-kernel 0.0.22 → 0.0.24
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/config.d.ts.map +1 -1
- package/dist/index.js +187 -50
- package/dist/index.js.map +1 -1
- package/dist/nudge-text.d.ts.map +1 -1
- package/dist/prune.d.ts.map +1 -1
- package/dist/reasoning-pairs.d.ts +33 -0
- package/dist/reasoning-pairs.d.ts.map +1 -0
- package/dist/recommend.d.ts +2 -1
- package/dist/recommend.d.ts.map +1 -1
- package/dist/types.d.ts +4 -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;AAapB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAapB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AASvD,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;IACnB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;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;AAsBD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CAwQ7D;AAixBD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CAqCR;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BvD"}
|
package/dist/index.js
CHANGED
|
@@ -142,9 +142,11 @@ function prune(messages, state, options = {}) {
|
|
|
142
142
|
const indexById = /* @__PURE__ */ new Map();
|
|
143
143
|
messages.forEach((message, index) => indexById.set(message.id, index));
|
|
144
144
|
const anchors = inject ? collectSummaryAnchors(state, indexById) : [];
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
return stripOrphanedReasoning(
|
|
146
|
+
stripOrphanedToolResults(
|
|
147
|
+
stripOrphanedToolCalls(
|
|
148
|
+
rebuildMessages(messages, covered, firstUserIndex, anchors)
|
|
149
|
+
)
|
|
148
150
|
)
|
|
149
151
|
);
|
|
150
152
|
}
|
|
@@ -221,6 +223,24 @@ function stripOrphanedToolCalls(messages) {
|
|
|
221
223
|
(m) => m.contentType !== "tool-call" || !m.toolCallId || m.toolName === "compress" || knownResultIds.has(m.toolCallId)
|
|
222
224
|
);
|
|
223
225
|
}
|
|
226
|
+
function stripOrphanedReasoning(messages) {
|
|
227
|
+
const drop = /* @__PURE__ */ new Set();
|
|
228
|
+
for (let i = 0; i < messages.length; i++) {
|
|
229
|
+
if (drop.has(i)) continue;
|
|
230
|
+
if (messages[i].contentType !== "reasoning") continue;
|
|
231
|
+
let j = i;
|
|
232
|
+
while (j + 1 < messages.length && messages[j + 1].contentType === "reasoning") {
|
|
233
|
+
j++;
|
|
234
|
+
}
|
|
235
|
+
const companion = messages[j + 1];
|
|
236
|
+
const hasCompanion = companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call");
|
|
237
|
+
if (!hasCompanion) {
|
|
238
|
+
for (let k = i; k <= j; k++) drop.add(k);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (drop.size === 0) return messages;
|
|
242
|
+
return messages.filter((_, i) => !drop.has(i));
|
|
243
|
+
}
|
|
224
244
|
|
|
225
245
|
// src/sync.ts
|
|
226
246
|
function syncBlocks(messages, state) {
|
|
@@ -310,7 +330,8 @@ function defaultConfig(modelContextLimit, overrides = {}) {
|
|
|
310
330
|
growthCap: 5e4,
|
|
311
331
|
minGrowthFloor: 2e4,
|
|
312
332
|
minGrowthRatio: 0.45,
|
|
313
|
-
emergencyThresholdPct: 0.95
|
|
333
|
+
emergencyThresholdPct: 0.95,
|
|
334
|
+
tier2GrowthMultiplier: 1.5
|
|
314
335
|
},
|
|
315
336
|
promotionThreshold: 5,
|
|
316
337
|
truncate: { threshold: 0.95 },
|
|
@@ -889,6 +910,40 @@ function adjustBoundariesForToolPairs(startIndex, endIndex, messages, maxScan =
|
|
|
889
910
|
return { startIndex: newStartIndex, endIndex: newEndIndex };
|
|
890
911
|
}
|
|
891
912
|
|
|
913
|
+
// src/reasoning-pairs.ts
|
|
914
|
+
function adjustBoundariesForReasoningPairs(startIndex, endIndex, messages) {
|
|
915
|
+
if (startIndex > endIndex) {
|
|
916
|
+
return { startIndex, endIndex };
|
|
917
|
+
}
|
|
918
|
+
let newStartIndex = startIndex;
|
|
919
|
+
let newEndIndex = endIndex;
|
|
920
|
+
for (let i = startIndex; i <= endIndex && i < messages.length; i++) {
|
|
921
|
+
const msg = messages[i];
|
|
922
|
+
if (!msg) continue;
|
|
923
|
+
if (msg.contentType === "reasoning") {
|
|
924
|
+
let j = i;
|
|
925
|
+
while (j + 1 < messages.length && messages[j + 1].contentType === "reasoning") {
|
|
926
|
+
j++;
|
|
927
|
+
}
|
|
928
|
+
const companion = messages[j + 1];
|
|
929
|
+
if (companion !== void 0 && companion.role === "assistant" && (companion.contentType === "text" || companion.contentType === "tool-call") && j + 1 > newEndIndex) {
|
|
930
|
+
newEndIndex = j + 1;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
if (msg.role === "assistant" && (msg.contentType === "text" || msg.contentType === "tool-call")) {
|
|
934
|
+
let k = i - 1;
|
|
935
|
+
while (k >= 0 && messages[k].contentType === "reasoning") {
|
|
936
|
+
k--;
|
|
937
|
+
}
|
|
938
|
+
const runStart = k + 1;
|
|
939
|
+
if (runStart < i && runStart >= 0 && messages[runStart].contentType === "reasoning" && runStart < newStartIndex) {
|
|
940
|
+
newStartIndex = runStart;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
return { startIndex: newStartIndex, endIndex: newEndIndex };
|
|
945
|
+
}
|
|
946
|
+
|
|
892
947
|
// src/recommend.ts
|
|
893
948
|
function refNum(ref) {
|
|
894
949
|
const n = parseInt(ref.slice(1), 10);
|
|
@@ -1036,6 +1091,44 @@ function buildCompressibleRanges(messages, state, config, protectedZoneRefs, cou
|
|
|
1036
1091
|
protected: protectedRanges
|
|
1037
1092
|
};
|
|
1038
1093
|
}
|
|
1094
|
+
function mergeBatch(batch) {
|
|
1095
|
+
const first = batch[0];
|
|
1096
|
+
const last = batch[batch.length - 1];
|
|
1097
|
+
const count = batch.reduce((s, r) => s + r.count, 0);
|
|
1098
|
+
const tokens = batch.reduce((s, r) => s + r.tokens, 0);
|
|
1099
|
+
const toolPct = Math.round(
|
|
1100
|
+
batch.reduce((s, r) => s + r.toolPct * r.count, 0) / count
|
|
1101
|
+
);
|
|
1102
|
+
const merged = {
|
|
1103
|
+
startRef: first.startRef,
|
|
1104
|
+
endRef: last.endRef,
|
|
1105
|
+
count,
|
|
1106
|
+
tokens,
|
|
1107
|
+
toolPct,
|
|
1108
|
+
textPct: 100 - toolPct
|
|
1109
|
+
};
|
|
1110
|
+
if (batch.some((r) => r.dangerous === true)) {
|
|
1111
|
+
merged.dangerous = true;
|
|
1112
|
+
}
|
|
1113
|
+
return merged;
|
|
1114
|
+
}
|
|
1115
|
+
function mergeRangesToThreshold(ranges, minChars) {
|
|
1116
|
+
if (minChars <= 0 || ranges.length === 0) return ranges;
|
|
1117
|
+
const result = [];
|
|
1118
|
+
let batch = [];
|
|
1119
|
+
for (const r of ranges) {
|
|
1120
|
+
batch.push(r);
|
|
1121
|
+
const batchTokens = batch.reduce((s, x) => s + x.tokens, 0);
|
|
1122
|
+
if (batchTokens * 4 >= minChars) {
|
|
1123
|
+
result.push(mergeBatch(batch));
|
|
1124
|
+
batch = [];
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
if (batch.length > 0) {
|
|
1128
|
+
result.push(mergeBatch(batch));
|
|
1129
|
+
}
|
|
1130
|
+
return result;
|
|
1131
|
+
}
|
|
1039
1132
|
|
|
1040
1133
|
// src/pipeline.ts
|
|
1041
1134
|
function makeIO(messages, state, effects = {}) {
|
|
@@ -1322,7 +1415,10 @@ var recommendNode = {
|
|
|
1322
1415
|
const nothingToCompress = contextRanges.compressible.length === 0;
|
|
1323
1416
|
const recommendation = {
|
|
1324
1417
|
contextRanges,
|
|
1325
|
-
recommendedRanges:
|
|
1418
|
+
recommendedRanges: mergeRangesToThreshold(
|
|
1419
|
+
contextRanges.compressible,
|
|
1420
|
+
ctx.config.compress.minCompressRange
|
|
1421
|
+
),
|
|
1326
1422
|
nothingToCompress
|
|
1327
1423
|
};
|
|
1328
1424
|
return { ...io, effects: { ...io.effects, recommendation } };
|
|
@@ -1348,6 +1444,7 @@ var nudgeNode = {
|
|
|
1348
1444
|
if (baseline > 0 && ctx.tokenCount < baseline - nudgeGrowthTokens) {
|
|
1349
1445
|
stamped.lastPerMessageNudgeTokens = ctx.tokenCount;
|
|
1350
1446
|
stamped.lastNudgeShownTokens = 0;
|
|
1447
|
+
stamped.lastShownByTier = {};
|
|
1351
1448
|
}
|
|
1352
1449
|
if (stamped.lastPerMessageNudgeTokens === 0) {
|
|
1353
1450
|
stamped.lastPerMessageNudgeTokens = ctx.tokenCount;
|
|
@@ -1392,7 +1489,7 @@ function applySingleRange(input) {
|
|
|
1392
1489
|
messages: input.messages,
|
|
1393
1490
|
state: input.state
|
|
1394
1491
|
});
|
|
1395
|
-
const rangeMessageIds =
|
|
1492
|
+
const rangeMessageIds = applyPairBoundaryAdjustments(
|
|
1396
1493
|
resolved,
|
|
1397
1494
|
input.messages
|
|
1398
1495
|
);
|
|
@@ -1506,20 +1603,33 @@ function applySingleRange(input) {
|
|
|
1506
1603
|
}
|
|
1507
1604
|
return { tokens: compressedTokens, warnings };
|
|
1508
1605
|
}
|
|
1509
|
-
function
|
|
1606
|
+
function applyPairBoundaryAdjustments(resolved, messages) {
|
|
1510
1607
|
if (resolved.boundaryKind === "block") {
|
|
1511
1608
|
return resolved.messageIds;
|
|
1512
1609
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1610
|
+
let startIndex = resolved.startIndex;
|
|
1611
|
+
let endIndex = resolved.endIndex;
|
|
1612
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
1613
|
+
const reasoningAdjusted = adjustBoundariesForReasoningPairs(
|
|
1614
|
+
startIndex,
|
|
1615
|
+
endIndex,
|
|
1616
|
+
messages
|
|
1617
|
+
);
|
|
1618
|
+
const toolAdjusted = adjustBoundariesForToolPairs(
|
|
1619
|
+
reasoningAdjusted.startIndex,
|
|
1620
|
+
reasoningAdjusted.endIndex,
|
|
1621
|
+
messages
|
|
1622
|
+
);
|
|
1623
|
+
const changed = toolAdjusted.startIndex !== startIndex || toolAdjusted.endIndex !== endIndex;
|
|
1624
|
+
startIndex = toolAdjusted.startIndex;
|
|
1625
|
+
endIndex = toolAdjusted.endIndex;
|
|
1626
|
+
if (!changed) break;
|
|
1627
|
+
}
|
|
1628
|
+
if (startIndex === resolved.startIndex && endIndex === resolved.endIndex) {
|
|
1519
1629
|
return resolved.messageIds;
|
|
1520
1630
|
}
|
|
1521
1631
|
const ids = [];
|
|
1522
|
-
for (let i =
|
|
1632
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
1523
1633
|
const msg = messages[i];
|
|
1524
1634
|
if (msg) ids.push(msg.id);
|
|
1525
1635
|
}
|
|
@@ -1603,10 +1713,11 @@ function resolveAdaptiveGrowth(modelContextLimit, nudge) {
|
|
|
1603
1713
|
)
|
|
1604
1714
|
);
|
|
1605
1715
|
}
|
|
1606
|
-
function pendingByTier(state, recommendation, countTokens) {
|
|
1716
|
+
function pendingByTier(state, recommendation, countTokens, minCompressRange) {
|
|
1607
1717
|
const out = {};
|
|
1608
|
-
const
|
|
1609
|
-
|
|
1718
|
+
const merged = recommendation?.recommendedRanges ?? [];
|
|
1719
|
+
const effective = minCompressRange > 0 ? merged.filter((r) => r.tokens * 4 >= minCompressRange) : merged;
|
|
1720
|
+
out[1] = { pending: effective.reduce((s, r) => s + r.tokens, 0), targetBlocks: [] };
|
|
1610
1721
|
const active = activeBlocks(state);
|
|
1611
1722
|
const t1 = active.filter((b) => b.tier === 1);
|
|
1612
1723
|
const t2 = active.filter((b) => b.tier === 2);
|
|
@@ -1621,6 +1732,7 @@ function decideNudge(input) {
|
|
|
1621
1732
|
const nudgeGrowthTokens = resolveAdaptiveGrowth(limit, config.nudge);
|
|
1622
1733
|
const overLimit = usage >= config.nudge.maxContextLimitPct;
|
|
1623
1734
|
const emergencyOverride = usage >= config.nudge.emergencyThresholdPct;
|
|
1735
|
+
const pressure = overLimit || emergencyOverride;
|
|
1624
1736
|
const baseline = state.nudge.lastPerMessageNudgeTokens;
|
|
1625
1737
|
const hadPendingNudge = state.nudge.lastNudgeShownTokens > 0;
|
|
1626
1738
|
const hasPendingNudge = hadPendingNudge;
|
|
@@ -1632,44 +1744,67 @@ function decideNudge(input) {
|
|
|
1632
1744
|
);
|
|
1633
1745
|
const growthSinceReference = tokenCount - growthReference;
|
|
1634
1746
|
const rec = recommendation;
|
|
1635
|
-
const tiers = pendingByTier(
|
|
1747
|
+
const tiers = pendingByTier(
|
|
1748
|
+
state,
|
|
1749
|
+
rec,
|
|
1750
|
+
countTokens,
|
|
1751
|
+
config.compress.minCompressRange
|
|
1752
|
+
);
|
|
1753
|
+
const tier2Threshold = Math.round(
|
|
1754
|
+
nudgeGrowthTokens * (config.nudge.tier2GrowthMultiplier ?? 1.5)
|
|
1755
|
+
);
|
|
1636
1756
|
let injectedTier = null;
|
|
1637
1757
|
let injectedReason = "";
|
|
1638
1758
|
const growthReady = growthSinceReference >= growthFloor;
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1759
|
+
const t1Eff = tiers[1]?.pending ?? 0;
|
|
1760
|
+
const t2Pen = tiers[2]?.pending ?? 0;
|
|
1761
|
+
const t3Pen = tiers[3]?.pending ?? 0;
|
|
1762
|
+
if (pressure) {
|
|
1763
|
+
const candidates = [1];
|
|
1764
|
+
if (config.tiers.enabled) {
|
|
1765
|
+
candidates.push(2, 3);
|
|
1766
|
+
}
|
|
1767
|
+
let best = null;
|
|
1768
|
+
let bestPending = 0;
|
|
1769
|
+
for (const t of candidates) {
|
|
1770
|
+
const p = tiers[t]?.pending ?? 0;
|
|
1771
|
+
if (p > bestPending) {
|
|
1772
|
+
bestPending = p;
|
|
1773
|
+
best = t;
|
|
1774
|
+
}
|
|
1650
1775
|
}
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1776
|
+
if (best !== null && bestPending > 0) {
|
|
1777
|
+
injectedTier = best;
|
|
1778
|
+
const label = emergencyOverride ? "EMERGENCY" : "OVER-LIMIT";
|
|
1779
|
+
injectedReason = best === 1 ? `${label} T1: max effective pending ${bestPending}, usage ${Math.round(usage * 100)}%` : `${label} T${best} distill: max pending ${bestPending} (T1 effective ${t1Eff}, T2 ${t2Pen}, T3 ${t3Pen}), usage ${Math.round(usage * 100)}%`;
|
|
1780
|
+
}
|
|
1781
|
+
} else if (growthReady) {
|
|
1782
|
+
if (t1Eff >= nudgeGrowthTokens) {
|
|
1783
|
+
injectedTier = 1;
|
|
1784
|
+
injectedReason = `T1 effective ${t1Eff} >= ${nudgeGrowthTokens}, growth ${growthSinceReference}, usage ${Math.round(usage * 100)}%`;
|
|
1785
|
+
} else if (config.tiers.enabled && t2Pen >= tier2Threshold && t2Pen > t1Eff) {
|
|
1786
|
+
const lastShown = state.nudge.lastShownByTier[2] ?? 0;
|
|
1787
|
+
const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
|
|
1788
|
+
if (cadenceMet) {
|
|
1789
|
+
injectedTier = 2;
|
|
1790
|
+
injectedReason = `T2 distill ready: ${tiers[2].targetBlocks.length} tier-1 blocks (${t2Pen} tokens) >= ${tier2Threshold} (1.5x) and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
|
|
1791
|
+
}
|
|
1792
|
+
} else if (config.tiers.enabled && t3Pen >= tier2Threshold && t3Pen > t2Pen && t3Pen > t1Eff) {
|
|
1793
|
+
const lastShown = state.nudge.lastShownByTier[3] ?? 0;
|
|
1794
|
+
const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
|
|
1795
|
+
if (cadenceMet) {
|
|
1796
|
+
injectedTier = 3;
|
|
1797
|
+
injectedReason = `T3 condense ready: ${tiers[3].targetBlocks.length} tier-2 blocks (${t3Pen} tokens) >= ${tier2Threshold} (1.5x) and > T2 ${t2Pen} and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
|
|
1798
|
+
}
|
|
1659
1799
|
}
|
|
1660
1800
|
}
|
|
1661
|
-
const shouldInject = injectedTier !== null
|
|
1801
|
+
const shouldInject = injectedTier !== null;
|
|
1662
1802
|
let reason;
|
|
1663
|
-
if (
|
|
1664
|
-
reason = injectedReason;
|
|
1665
|
-
} else if (emergencyOverride) {
|
|
1666
|
-
reason = `EMERGENCY: usage ${Math.round(usage * 100)}% >= ${Math.round(config.nudge.emergencyThresholdPct * 100)}% (no compressible content)`;
|
|
1667
|
-
} else if (overLimit && injectedTier !== null) {
|
|
1668
|
-
reason = injectedReason;
|
|
1669
|
-
} else if (overLimit) {
|
|
1670
|
-
reason = `OVER-LIMIT: usage ${Math.round(usage * 100)}% >= ${Math.round(config.nudge.maxContextLimitPct * 100)}% (no compressible content)`;
|
|
1671
|
-
} else if (injectedTier !== null) {
|
|
1803
|
+
if (injectedTier !== null) {
|
|
1672
1804
|
reason = injectedReason;
|
|
1805
|
+
} else if (pressure) {
|
|
1806
|
+
const label = emergencyOverride ? "EMERGENCY" : "OVER-LIMIT";
|
|
1807
|
+
reason = `${label}: usage ${Math.round(usage * 100)}% but no tier has effective compressible content (T1 effective ${t1Eff}, T2 ${t2Pen}, T3 ${t3Pen}) \u2014 nudge suppressed to avoid offering ranges below minCompressRange`;
|
|
1673
1808
|
} else {
|
|
1674
1809
|
const tiersList = [1, 2, 3];
|
|
1675
1810
|
const eligible = tiersList.filter((t) => config.tiers.enabled || t === 1);
|
|
@@ -2024,20 +2159,23 @@ ${lines.join("\n")}`;
|
|
|
2024
2159
|
function renderNudgeText(decision, prompts = defaultPrompts) {
|
|
2025
2160
|
const breakdownStr = formatBreakdown(decision.contextBreakdown);
|
|
2026
2161
|
const rangesStr = formatRanges(decision.compressibleRanges, decision.protectedRanges ?? []);
|
|
2162
|
+
const isEmergency = !!decision.breakdown?.emergencyOverride || !!decision.breakdown?.overLimit;
|
|
2027
2163
|
if (decision.tier !== null && decision.tier >= 2) {
|
|
2028
2164
|
const isT2 = decision.tier === 2;
|
|
2029
2165
|
const targets = decision.tierTargetBlocks ?? [];
|
|
2030
2166
|
const blockList = formatTierTargetBlocks(targets);
|
|
2031
2167
|
const startId = targets[0]?.blockId ?? "b1";
|
|
2032
2168
|
const endId = targets[targets.length - 1]?.blockId ?? "b5";
|
|
2169
|
+
const voice = isEmergency ? "emergency" : "gentle";
|
|
2170
|
+
const triggerLine = isEmergency ? `[EMERGENCY \u2014 TIER ${decision.tier} ${isT2 ? "DISTILLATION" : "CONDENSATION"}] Context limit reached \u2014 distill NOW into a denser summary to reclaim tokens.` : `[TIER ${decision.tier} ${isT2 ? "DISTILLATION" : "CONDENSATION"} TRIGGER]`;
|
|
2033
2171
|
return {
|
|
2034
|
-
voice
|
|
2172
|
+
voice,
|
|
2035
2173
|
text: [
|
|
2036
2174
|
efficiencyNote(prompts),
|
|
2037
2175
|
"",
|
|
2038
2176
|
breakdownStr,
|
|
2039
2177
|
"",
|
|
2040
|
-
|
|
2178
|
+
triggerLine,
|
|
2041
2179
|
isT2 ? `Your tier-1 compression summaries have accumulated. Distill them into a single denser tier-2 summary. Use block IDs as boundaries (startId and endId as bN). Any raw (uncompressed) messages sitting between the boundary blocks are absorbed into the tier-2 block as well \u2014 apply HOW TO COMPRESS to those raw messages and the TIER 2 distillation rules to the existing summaries, so the whole span is covered and nothing is lost.` : `Your tier-2 compression summaries have accumulated. Condense them further into a tier-3 ultra-condensed summary. Use block IDs as boundaries (startId and endId as bN). Any raw (uncompressed) messages sitting between the boundary blocks are absorbed into the tier-3 block as well \u2014 apply HOW TO COMPRESS to those raw messages and the TIER 3 condensation rules to the existing summaries, so the whole span is covered and nothing is lost.`,
|
|
2042
2180
|
blockList,
|
|
2043
2181
|
`Example: compress({ content: [{ startId: "${startId}", endId: "${endId}", summary: "..." }] })`,
|
|
@@ -2048,7 +2186,6 @@ function renderNudgeText(decision, prompts = defaultPrompts) {
|
|
|
2048
2186
|
].join("\n")
|
|
2049
2187
|
};
|
|
2050
2188
|
}
|
|
2051
|
-
const isEmergency = !!decision.breakdown?.emergencyOverride || !!decision.breakdown?.overLimit;
|
|
2052
2189
|
if (isEmergency) {
|
|
2053
2190
|
return {
|
|
2054
2191
|
voice: "emergency",
|