acp-kernel 0.0.59 → 0.0.60-pr.238.84

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/README.md CHANGED
@@ -111,7 +111,7 @@ The nudge system tells the model *when* to compress. It implements:
111
111
 
112
112
  - **Threshold gate**: fires when context usage ≥ `nudge.minContextLimitPct`.
113
113
  - **Growth-gating**: a repeat nudge requires positive growth since the baseline (prevents re-firing every turn). `"strong"` force relaxes this.
114
- - **Tier-distillation triggers**: when active tier-1 blocks pile up past `tiers.tier2Trigger`, emit a tier-2 distillation nudge; tier-3 analogously.
114
+ - **Tier-distillation triggers**: when active tier-1 blocks pile up past `tiers.tier2Trigger`, emit a tier-2 distillation nudge; tier-3 analogously. Count-triggered distillation is gated to the nudge usage band (`nudge.minContextLimitPct`): below it, block counts alone don't justify burning a turn (#237).
115
115
  - **Compressible-range computation**: reports the actual compressible ranges (excluding covered + preserved-recent messages) so the model knows what to target.
116
116
  - **Baseline reset on compress**: `applyCompression` clears the growth baseline on success, preventing the feedback-loop bug where the nudge re-fires post-compress.
117
117
 
@@ -1 +1 @@
1
- {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAehF,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;AA2DD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CAyU7D;AAo8BD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkC,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAehF,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;AA2DD,wBAAgB,UAAU,CAAC,KAAK,GAAE,KAAU,GAAG,eAAe,CAyU7D;AAu9BD,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;AAYhE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAClB;AA8BD,wBAAgB,yBAAyB,CACrC,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,WAAW,EAAE,GACxB,kBAAkB,CAmFpB"}
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;AAYhE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAClB;AA8FD,wBAAgB,yBAAyB,CACrC,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,WAAW,EAAE,GACxB,kBAAkB,CAwFpB"}
package/dist/index.js CHANGED
@@ -1,3 +1,13 @@
1
+ import {
2
+ activeBlocks,
3
+ advanceSurvival,
4
+ allocateBlockId,
5
+ allocateRunId,
6
+ blockById,
7
+ coveredMessageIds,
8
+ createInitialState,
9
+ highestActiveTier
10
+ } from "./chunk-UX4LINT7.js";
1
11
  import {
2
12
  COMPRESS_PHILOSOPHY,
3
13
  HOW_TO_COMPRESS_RULES,
@@ -13,16 +23,6 @@ import {
13
23
  resolvePrompts,
14
24
  viableRanges
15
25
  } from "./chunk-JGNVAFFE.js";
16
- import {
17
- activeBlocks,
18
- advanceSurvival,
19
- allocateBlockId,
20
- allocateRunId,
21
- blockById,
22
- coveredMessageIds,
23
- createInitialState,
24
- highestActiveTier
25
- } from "./chunk-UX4LINT7.js";
26
26
 
27
27
  // src/refs.ts
28
28
  var REF_WIDTH = 5;
@@ -666,25 +666,71 @@ var KEEP_LAST_ORPHANED = 2;
666
666
  function rangeKey(startRef, endRef) {
667
667
  return `${startRef}::${endRef}`;
668
668
  }
669
- function rewriteCompressText(text, liveKeys) {
669
+ function parseCallText(text) {
670
+ const raw = text ?? "";
671
+ const start = raw.indexOf("{");
672
+ if (start < 0) return null;
670
673
  let parsed;
671
674
  try {
672
- parsed = JSON.parse(text ?? "");
675
+ parsed = JSON.parse(raw.slice(start));
673
676
  } catch {
674
677
  return null;
675
678
  }
676
679
  if (!parsed || typeof parsed !== "object") return null;
677
680
  const obj = parsed;
678
- const content = obj.content;
679
- if (!Array.isArray(content) || content.length === 0) return null;
681
+ let content = null;
682
+ let contentWasString = false;
683
+ if (Array.isArray(obj.content)) {
684
+ content = obj.content;
685
+ } else if (typeof obj.content === "string") {
686
+ contentWasString = true;
687
+ try {
688
+ const inner = JSON.parse(obj.content);
689
+ if (Array.isArray(inner)) content = inner;
690
+ } catch {
691
+ content = null;
692
+ }
693
+ }
694
+ if (!content || content.length === 0) return null;
695
+ return { prefix: raw.slice(0, start), obj, content, contentWasString };
696
+ }
697
+ function rewriteCompressText(text, liveKeys) {
698
+ const parsed = parseCallText(text);
699
+ if (!parsed) return null;
700
+ const { prefix, obj, content, contentWasString } = parsed;
680
701
  const kept = content.filter((entry) => {
681
702
  if (!entry || typeof entry !== "object") return false;
682
- const s = typeof entry.startId === "string" ? entry.startId : typeof entry.messageId === "string" ? entry.messageId : "";
683
- const e = typeof entry.endId === "string" ? entry.endId : typeof entry.messageId === "string" ? entry.messageId : "";
684
- return liveKeys.has(rangeKey(s, e));
703
+ const e = entry;
704
+ const s = typeof e.startId === "string" ? e.startId : typeof e.messageId === "string" ? e.messageId : "";
705
+ const end = typeof e.endId === "string" ? e.endId : typeof e.messageId === "string" ? e.messageId : "";
706
+ return liveKeys.has(rangeKey(s, end));
685
707
  });
686
- if (kept.length === content.length || kept.length === 0) return null;
687
- return JSON.stringify({ ...obj, content: kept });
708
+ if (kept.length === 0) return null;
709
+ return prefix + serializeCompacted(obj, kept, contentWasString).text;
710
+ }
711
+ var SUMMARY_STUB_CHARS = 200;
712
+ function compactEntry(entry) {
713
+ if (!entry || typeof entry !== "object") return entry;
714
+ const e = entry;
715
+ if (typeof e.summary !== "string" || e.summary.length <= SUMMARY_STUB_CHARS) return entry;
716
+ return { ...e, summary: `${e.summary.slice(0, SUMMARY_STUB_CHARS - 1)}\u2026` };
717
+ }
718
+ function serializeCompacted(obj, content, contentWasString) {
719
+ let changed = false;
720
+ const compacted = content.map((entry) => {
721
+ const out = compactEntry(entry);
722
+ if (out !== entry) changed = true;
723
+ return out;
724
+ });
725
+ const outContent = contentWasString ? JSON.stringify(compacted) : compacted;
726
+ return { text: JSON.stringify({ ...obj, content: outContent }), changed };
727
+ }
728
+ function compactCompressText(text) {
729
+ const parsed = parseCallText(text);
730
+ if (!parsed) return null;
731
+ const { prefix, obj, content, contentWasString } = parsed;
732
+ const { text: out, changed } = serializeCompacted(obj, content, contentWasString);
733
+ return changed ? prefix + out : null;
688
734
  }
689
735
  function hideConsumedCompressCalls(state, messages) {
690
736
  const allBlockCallIds = /* @__PURE__ */ new Set();
@@ -743,6 +789,11 @@ function hideConsumedCompressCalls(state, messages) {
743
789
  continue;
744
790
  }
745
791
  }
792
+ const compacted = compactCompressText(message.text);
793
+ if (compacted !== null) {
794
+ result.push({ ...message, text: compacted });
795
+ continue;
796
+ }
746
797
  }
747
798
  result.push(message);
748
799
  }
@@ -2593,6 +2644,9 @@ function decideNudge(input) {
2593
2644
  const growthReady = firstSightMassReady || growthSinceReference >= growthFloor;
2594
2645
  const t2Count = tiers[2]?.targetBlocks.length ?? 0;
2595
2646
  const t3Count = tiers[3]?.targetBlocks.length ?? 0;
2647
+ const tierCountUsageFloor = config.nudge.minContextLimitPct;
2648
+ const t2CountReady = t2Count >= config.tiers.tier2Trigger && usage >= tierCountUsageFloor;
2649
+ const t3CountReady = t3Count >= config.tiers.tier3Trigger && usage >= tierCountUsageFloor;
2596
2650
  if (pressure) {
2597
2651
  const candidates = [1];
2598
2652
  if (config.tiers.enabled) {
@@ -2615,19 +2669,19 @@ function decideNudge(input) {
2615
2669
  if (t1Eff >= nudgeGrowthTokens) {
2616
2670
  injectedTier = 1;
2617
2671
  injectedReason = `T1 effective ${t1Eff} >= ${nudgeGrowthTokens}, growth ${growthSinceReference}, usage ${Math.round(usage * 100)}%`;
2618
- } else if (config.tiers.enabled && (t2Count >= config.tiers.tier2Trigger || t2Pen >= tier2Threshold && t2Pen > t1Eff)) {
2672
+ } else if (config.tiers.enabled && (t2CountReady || t2Pen >= tier2Threshold && t2Pen > t1Eff)) {
2619
2673
  const lastShown = state.nudge.lastShownByTier[2] ?? 0;
2620
2674
  const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
2621
2675
  if (cadenceMet) {
2622
2676
  injectedTier = 2;
2623
- injectedReason = t2Count >= config.tiers.tier2Trigger ? `T2 distill ready: ${t2Count} tier-1 blocks >= tier2Trigger ${config.tiers.tier2Trigger} (${t2Pen} tokens), usage ${Math.round(usage * 100)}%` : `T2 distill ready: ${tiers[2].targetBlocks.length} tier-1 blocks (${t2Pen} tokens) >= ${tier2Threshold} (1.5x) and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
2677
+ injectedReason = t2CountReady ? `T2 distill ready: ${t2Count} tier-1 blocks >= tier2Trigger ${config.tiers.tier2Trigger} (${t2Pen} tokens), usage ${Math.round(usage * 100)}%` : `T2 distill ready: ${tiers[2].targetBlocks.length} tier-1 blocks (${t2Pen} tokens) >= ${tier2Threshold} (1.5x) and > T1 effective ${t1Eff}, usage ${Math.round(usage * 100)}%`;
2624
2678
  }
2625
- } else if (config.tiers.enabled && (t3Count >= config.tiers.tier3Trigger || t3Pen >= tier2Threshold && t3Pen > t2Pen && t3Pen > t1Eff)) {
2679
+ } else if (config.tiers.enabled && (t3CountReady || t3Pen >= tier2Threshold && t3Pen > t2Pen && t3Pen > t1Eff)) {
2626
2680
  const lastShown = state.nudge.lastShownByTier[3] ?? 0;
2627
2681
  const cadenceMet = lastShown === 0 || tokenCount - lastShown >= growthFloor;
2628
2682
  if (cadenceMet) {
2629
2683
  injectedTier = 3;
2630
- injectedReason = t3Count >= config.tiers.tier3Trigger ? `T3 condense ready: ${t3Count} tier-2 blocks >= tier3Trigger ${config.tiers.tier3Trigger} (${t3Pen} tokens), usage ${Math.round(usage * 100)}%` : `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)}%`;
2684
+ injectedReason = t3CountReady ? `T3 condense ready: ${t3Count} tier-2 blocks >= tier3Trigger ${config.tiers.tier3Trigger} (${t3Pen} tokens), usage ${Math.round(usage * 100)}%` : `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)}%`;
2631
2685
  }
2632
2686
  }
2633
2687
  }
@@ -2644,9 +2698,14 @@ function decideNudge(input) {
2644
2698
  } else {
2645
2699
  const tiersList = [1, 2, 3];
2646
2700
  const eligible = tiersList.filter((t) => config.tiers.enabled || t === 1);
2647
- const countReady = (t) => t === 2 ? t2Count >= config.tiers.tier2Trigger : t === 3 ? t3Count >= config.tiers.tier3Trigger : false;
2701
+ const countReadyUngated = (t) => t === 2 ? t2Count >= config.tiers.tier2Trigger : t === 3 ? t3Count >= config.tiers.tier3Trigger : false;
2702
+ const countReady = (t) => countReadyUngated(t) && usage >= tierCountUsageFloor;
2648
2703
  const ready = eligible.filter((t) => (tiers[t]?.pending ?? 0) >= nudgeGrowthTokens).map((t) => `T${t} ${tiers[t].pending}`);
2649
- const readyCount = eligible.filter((t) => (tiers[t]?.pending ?? 0) < nudgeGrowthTokens && countReady(t)).map((t) => `T${t} ${t === 2 ? t2Count : t3Count} blocks (count)`);
2704
+ const readyCount = eligible.filter(
2705
+ (t) => (tiers[t]?.pending ?? 0) < nudgeGrowthTokens && countReadyUngated(t)
2706
+ ).map(
2707
+ (t) => `T${t} ${t === 2 ? t2Count : t3Count} blocks (count${usage >= tierCountUsageFloor ? "" : ", usage-gated"})`
2708
+ );
2650
2709
  const readyAll = [...ready, ...readyCount];
2651
2710
  const readyHint = readyAll.length > 0 ? `, ready: ${readyAll.join(", ")}` : "";
2652
2711
  const blocked = eligible.filter(