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 +2 -2
- package/README.zh-CN.md +1 -1
- package/dist/index.js +16 -70
- package/dist/index.js.map +1 -1
- package/dist/lib/messages/inject/inject.d.ts.map +1 -1
- package/dist/lib/messages/inject/utils.d.ts +6 -46
- package/dist/lib/messages/inject/utils.d.ts.map +1 -1
- package/package.json +1 -1
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
|
|
127
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
7342
|
-
|
|
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:
|
|
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 ${
|
|
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.
|
|
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 ??
|
|
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
|
|
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
|
|
7679
|
-
const
|
|
7680
|
-
|
|
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"
|
|
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.
|
|
9029
|
+
var LOG_VERSION = true ? "1.14.22-pr.327.45" : "dev";
|
|
9084
9030
|
var Logger = class {
|
|
9085
9031
|
logDir;
|
|
9086
9032
|
enabled;
|