opencode-acp 1.14.22-pr.326.47 → 1.14.22-pr.327.45

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
@@ -123,8 +123,8 @@ stateDiagram-v2
123
123
  - **T1** fires when raw context exceeds the configured limit. The model sees
124
124
  compressible ranges and writes a detailed summary preserving file paths,
125
125
  signatures, decisions, and rationale.
126
- - **T2** fires when T1 summary tokens reach `nudgeGrowthTokens` (default 5% of
127
- context window). The model distills old T1 blocks — keeping decisions and
126
+ - **T2** fires when T1 summary tokens reach `nudgeGrowthTokens` (fixed default
127
+ 50000). The model distills old T1 blocks — keeping decisions and
128
128
  outcomes, dropping verbose process details.
129
129
  - **T3** fires when T2 summary tokens reach the same threshold. The model
130
130
  condenses to bare facts (shipped releases, key bugs, architecture decisions).
package/README.zh-CN.md CHANGED
@@ -100,7 +100,7 @@ stateDiagram-v2
100
100
  **触发机制:**
101
101
 
102
102
  - **T1** 在原始上下文超过配置限制时触发。模型看到可压缩范围,编写详细摘要,保留文件路径、函数签名、决策和理由。
103
- - **T2** 在 T1 摘要 token 达到 `nudgeGrowthTokens`(默认上下文窗口的 5%)时触发。模型蒸馏旧的 T1 块 — 保留决策和结果,丢弃冗长的过程细节。
103
+ - **T2** 在 T1 摘要 token 达到 `nudgeGrowthTokens`(固定默认 50000)时触发。模型蒸馏旧的 T1 块 — 保留决策和结果,丢弃冗长的过程细节。
104
104
  - **T3** 在 T2 摘要 token 达到同样阈值时触发。模型浓缩为纯事实(已发布的版本、关键 bug、架构决策)。
105
105
 
106
106
  每层有**独立的节奏计数器** — T2 触发不阻塞 T3。T1 通过 `!shouldInject` 守卫获得优先级:如果 T1 触发了,T2/T3 等到下一轮。这确保原始上下文压缩优先发生(影响最大)。
package/dist/index.js CHANGED
@@ -6953,13 +6953,7 @@ function computeShouldNudge2(params) {
6953
6953
  }
6954
6954
  return policy.computeShouldNudge(params);
6955
6955
  }
6956
- function resolveAdaptiveNudgeGrowth2(modelContextLimit) {
6957
- const policy = getDefaultTriggerPolicy();
6958
- if (!policy) {
6959
- return 6e3;
6960
- }
6961
- return policy.resolveAdaptiveNudgeGrowth(modelContextLimit);
6962
- }
6956
+ var DEFAULT_NUDGE_GROWTH_TOKENS = 5e4;
6963
6957
  function addAnchor(anchorMessageIds, anchorMessageId, anchorMessageIndex, messages, interval) {
6964
6958
  if (anchorMessageIndex < 0) {
6965
6959
  return false;
@@ -7192,9 +7186,7 @@ function refNum(ref) {
7192
7186
  function buildCompressibleRanges(messages, state, protectedTools = [], protectedFilePatterns = [], protectedZoneRefs) {
7193
7187
  const msgInfo = [];
7194
7188
  const protectedMsgInfo = [];
7195
- const lastUserRefIdx = [];
7196
- for (let mi = 0; mi < messages.length; mi++) {
7197
- const msg = messages[mi];
7189
+ for (const msg of messages) {
7198
7190
  if (isSyntheticMessage(msg)) continue;
7199
7191
  const ref = state.messageIds.byRawId.get(msg.info.id);
7200
7192
  if (!ref) continue;
@@ -7229,27 +7221,15 @@ function buildCompressibleRanges(messages, state, protectedTools = [], protected
7229
7221
  }
7230
7222
  let tokens = 0;
7231
7223
  let isTool = false;
7232
- let hasMeaningfulPart = false;
7233
7224
  for (const part of msg.parts || []) {
7234
7225
  if (part.type === "text" && typeof part.text === "string") {
7235
7226
  tokens += Math.round(part.text.length / 4);
7236
- if (part.text.trim().length > 0) hasMeaningfulPart = true;
7237
7227
  } else if (part.type !== "text" && part.type !== "reasoning") {
7238
7228
  tokens += Math.round(JSON.stringify(part).length / 4);
7239
7229
  isTool = true;
7240
- hasMeaningfulPart = true;
7241
7230
  }
7242
7231
  }
7243
- if (msg.info.role === "user" && !isIgnoredUserMessage(msg)) {
7244
- lastUserRefIdx.length = 0;
7245
- lastUserRefIdx.push(msgInfo.length);
7246
- }
7247
- msgInfo.push({ ref, refNum: rn, tokens, effectiveTokens: 0, meaningful: hasMeaningfulPart, isTool, isUser: msg.info.role === "user" });
7248
- }
7249
- const lastUserIdx = lastUserRefIdx.length > 0 ? lastUserRefIdx[0] : -1;
7250
- for (let i = 0; i < msgInfo.length; i++) {
7251
- const info = msgInfo[i];
7252
- info.effectiveTokens = i !== lastUserIdx && info.meaningful ? info.tokens : 0;
7232
+ msgInfo.push({ ref, refNum: rn, tokens, isTool, isUser: msg.info.role === "user" });
7253
7233
  }
7254
7234
  const groups = [];
7255
7235
  let cur = null;
@@ -7275,7 +7255,6 @@ function buildCompressibleRanges(messages, state, protectedTools = [], protected
7275
7255
  endRef: info.ref,
7276
7256
  count: 1,
7277
7257
  tokens: info.tokens,
7278
- effectiveTokens: info.effectiveTokens,
7279
7258
  toolPct: info.isTool ? 100 : 0,
7280
7259
  textPct: info.isTool ? 0 : 100
7281
7260
  };
@@ -7283,7 +7262,6 @@ function buildCompressibleRanges(messages, state, protectedTools = [], protected
7283
7262
  cur.endRef = info.ref;
7284
7263
  cur.count++;
7285
7264
  cur.tokens += info.tokens;
7286
- cur.effectiveTokens += info.effectiveTokens;
7287
7265
  if (info.isTool) {
7288
7266
  cur.toolPct = Math.round((cur.toolPct * (cur.count - 1) + 100) / cur.count);
7289
7267
  } else {
@@ -7326,11 +7304,6 @@ function buildCompressibleRanges(messages, state, protectedTools = [], protected
7326
7304
  protected: protectedGroups
7327
7305
  };
7328
7306
  }
7329
- var EFFECTIVE_MIN_COMPRESSIBLE_TOKENS = 1250;
7330
- function resolveEffectiveFloor(config) {
7331
- const minChars = config.compress?.minCompressRange ?? 5e3;
7332
- return minChars > 0 ? Math.floor(minChars / 4) : 0;
7333
- }
7334
7307
  function filterRecommendedRanges(compressible, _protectedRanges, options) {
7335
7308
  const { logger } = options;
7336
7309
  const log = logger?.debug.bind(logger);
@@ -7338,22 +7311,12 @@ function filterRecommendedRanges(compressible, _protectedRanges, options) {
7338
7311
  log?.("filterRecommendedRanges: no compressible ranges, returning empty");
7339
7312
  return [];
7340
7313
  }
7341
- const floor = options.minEffectiveTokens ?? EFFECTIVE_MIN_COMPRESSIBLE_TOKENS;
7342
- const kept = compressible.filter((r) => {
7343
- const effective = r.effectiveTokens ?? r.tokens;
7344
- return effective > 0 && effective >= floor;
7345
- });
7346
- const result = kept.map(
7347
- (r, i) => i === kept.length - 1 ? { ...r, dangerous: true } : r
7314
+ const result = compressible.map(
7315
+ (r, i) => i === compressible.length - 1 ? { ...r, dangerous: true } : r
7348
7316
  );
7349
- log?.("filterRecommendedRanges: effective-token floor applied", {
7317
+ log?.("filterRecommendedRanges: passthrough (last segment marked dangerous)", {
7350
7318
  inputRanges: compressible.length,
7351
- outputRanges: result.length,
7352
- floor,
7353
- dropped: compressible.filter((r) => {
7354
- const effective = r.effectiveTokens ?? r.tokens;
7355
- return effective <= 0 || effective < floor;
7356
- }).map((r) => `${r.startRef}\u2013${r.endRef} (${r.effectiveTokens ?? r.tokens} eff tokens)`)
7319
+ outputRanges: result.length
7357
7320
  });
7358
7321
  return result;
7359
7322
  }
@@ -7362,10 +7325,8 @@ function formatCompressibleRanges(ranges, protectedRanges) {
7362
7325
  if (!protectedRanges || protectedRanges.length === 0) {
7363
7326
  if (ranges.length === 0) return "";
7364
7327
  const lines2 = ranges.map((r) => {
7365
- const eff = r.effectiveTokens ?? r.tokens;
7366
- const size = eff < r.tokens ? `${fmt(eff)} effective of ${fmt(r.tokens)}` : fmt(r.tokens);
7367
7328
  const suffix = r.dangerous ? " \u26A0\uFE0F NOT recommended unless you are certain. If you MUST compress this, pass `dangerous: true`." : "";
7368
- return ` ${r.startRef}\u2013${r.endRef} ${r.count} msgs ${size} [tool ${r.toolPct}% | text ${r.textPct}%]${suffix}`;
7329
+ return ` ${r.startRef}\u2013${r.endRef} ${r.count} msgs ${fmt(r.tokens)} [tool ${r.toolPct}% | text ${r.textPct}%]${suffix}`;
7369
7330
  });
7370
7331
  return `Compressible ranges (oldest first):
7371
7332
  ${lines2.join("\n")}`;
@@ -7381,7 +7342,7 @@ ${lines2.join("\n")}`;
7381
7342
  tokens: r.tokens,
7382
7343
  toolPct: r.toolPct,
7383
7344
  textPct: r.textPct,
7384
- compressibleTokens: r.effectiveTokens ?? r.tokens,
7345
+ compressibleTokens: r.tokens,
7385
7346
  compressibleCount: r.count,
7386
7347
  protectedTokens: 0,
7387
7348
  protectedCount: 0,
@@ -7621,7 +7582,7 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
7621
7582
  }
7622
7583
  }
7623
7584
  const suffixMessage = createSuffixMessage(messages);
7624
- const nudgeGrowthTokens = config.compress?.nudgeGrowthTokens ?? resolveAdaptiveNudgeGrowth2(modelContextLimit);
7585
+ const nudgeGrowthTokens = config.compress?.nudgeGrowthTokens ?? DEFAULT_NUDGE_GROWTH_TOKENS;
7625
7586
  const growthFloor = Math.max(
7626
7587
  config.compress?.minNudgeGrowthFloor ?? 5e3,
7627
7588
  (config.compress?.minNudgeGrowthRatio ?? 0.45) * nudgeGrowthTokens
@@ -7670,18 +7631,14 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
7670
7631
  const recommendedRanges = filterRecommendedRanges(
7671
7632
  unprotectedCompressible,
7672
7633
  contextRanges.protected,
7673
- { logger, minEffectiveTokens: resolveEffectiveFloor(config) }
7634
+ { logger }
7674
7635
  );
7675
7636
  const hasRecommendations = recommendedRanges.length > 0;
7676
7637
  const allProtected = contextRanges.compressible.length === 0 && contextRanges.protected.length > 0;
7677
7638
  const allInProtectedZone = protectedRefs.size > 0 && unprotectedCompressible.length === 0;
7678
- const allBelowMin = contextRanges.compressible.length > 0 && recommendedRanges.length === 0;
7679
- const nothingToCompress = allProtected || allInProtectedZone || allBelowMin;
7680
- const emergencyNoTargets = emergencyOverride && nothingToCompress;
7681
- const noticeCadenceMet = state.nudges.lastNudgeShownTokens === void 0 || growthSinceBaseline !== void 0 && growthSinceBaseline >= growthFloor;
7682
- const shouldInjectNudge = nudgeAllowed && !nothingToCompress;
7683
- const shouldInjectNotice = emergencyNoTargets && noticeCadenceMet;
7684
- let shouldInject = shouldInjectNudge || shouldInjectNotice;
7639
+ const nothingToCompress = allProtected || allInProtectedZone;
7640
+ const shouldInjectNudge = nudgeAllowed && (!nothingToCompress || emergencyOverride);
7641
+ let shouldInject = shouldInjectNudge;
7685
7642
  if (shouldInjectNudge) {
7686
7643
  applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit, suffixMessage);
7687
7644
  }
@@ -7815,19 +7772,8 @@ ${formatCompressibleRanges(recommendedRanges, contextRanges.protected)}`;
7815
7772
  Use \`acp_status({scope:"uncompressed"})\` to re-fetch compressible ranges after compressing, or \`acp_status\` for compressed block details.`;
7816
7773
  appendToLastTextPart(suffixMessage, breakdown);
7817
7774
  }
7818
- if (effectiveTipsVariant === "maxLimit" && !emergencyNoTargets) {
7775
+ if (effectiveTipsVariant === "maxLimit") {
7819
7776
  tipsText = "\n\n\u26A0\uFE0F Context limit reached \u2014 compress now. Prioritize consumed tool outputs.\n\n" + HOW_TO_COMPRESS_RULES + '\n\n{ "topic": "...", "content": [{ "startId": "<ID>", "endId": "<ID>", "summary": "..." }] }\n\nOnly use IDs from visible messages above. Compress older work first.';
7820
- } else if (shouldInjectNotice) {
7821
- const emergencyPct = currentTokens !== void 0 && modelContextLimit !== void 0 && modelContextLimit > 0 ? Math.round(currentTokens / modelContextLimit * 100) : void 0;
7822
- tipsText = `
7823
-
7824
- \u{1F6A8} Context is critically full${emergencyPct !== void 0 ? ` (${emergencyPct}% of limit)` : ""} and there is nothing left that can be safely compressed.
7825
- Do NOT retry compress on the same ranges \u2014 they will keep failing.
7826
- You cannot execute user commands yourself. Act now via your reply/message tool:
7827
- - Inform the user that context is full and compression is exhausted
7828
- - Recommend they run /acp export (archives compression summaries to a file), then /compact or start a new session
7829
- - Alternatively, ask them to relax protected-tool / preserve-recent settings so compression becomes possible
7830
- Then stop retrying and await the user's response.`;
7831
7777
  }
7832
7778
  state.nudges.lastNudgeShownTokens = currentTokens;
7833
7779
  {
@@ -9080,7 +9026,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
9080
9026
  import { join as join3 } from "path";
9081
9027
  import { existsSync as existsSync3 } from "fs";
9082
9028
  import { homedir as homedir3 } from "os";
9083
- var LOG_VERSION = true ? "1.14.22-pr.326.47" : "dev";
9029
+ var LOG_VERSION = true ? "1.14.22-pr.327.45" : "dev";
9084
9030
  var Logger = class {
9085
9031
  logDir;
9086
9032
  enabled;