opencode-acp 1.14.8-dev.1 → 1.14.8-dev.2
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 +10 -0
- package/README.zh-CN.md +10 -0
- package/dist/index.js +63 -51
- package/dist/index.js.map +1 -1
- package/dist/lib/compress/hide-consumed.d.ts +0 -18
- package/dist/lib/compress/hide-consumed.d.ts.map +1 -1
- package/dist/lib/compress/status.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -492,6 +492,16 @@ For the complete list with root cause analysis, see the [bug tracker](https://gi
|
|
|
492
492
|
|
|
493
493
|
## Changelog
|
|
494
494
|
|
|
495
|
+
### v1.14.8-dev.2 — Dev Prerelease (2 PRs since v1.14.8-dev.1)
|
|
496
|
+
|
|
497
|
+
Dev prerelease covering PRs #244–#245. Published to `dev` npm tag for early testing.
|
|
498
|
+
|
|
499
|
+
**PRs included**:
|
|
500
|
+
- **#245** — Fix: re-add HOW_TO_COMPRESS_RULES to nudge injection for high-attention summary guidance. v1.14.7 over-removed the rules from all 4 nudge locations (breakdown + 3 templates), leaving them only in system prompt. In long sessions, system prompt rules degrade due to "lost in the middle" effect — model needs rules at high attention (end of context) when nudge fires.
|
|
501
|
+
- **#244** — Fix: acp_status hides consumed compress calls from PROTECTED list.
|
|
502
|
+
|
|
503
|
+
**Install**: `opencode plugin opencode-acp@dev --global`
|
|
504
|
+
|
|
495
505
|
### v1.14.8-dev.1 — Dev Prerelease (7 PRs since v1.14.7)
|
|
496
506
|
|
|
497
507
|
Dev prerelease covering PRs #238–#242. Published to `dev` npm tag for early testing.
|
package/README.zh-CN.md
CHANGED
|
@@ -446,6 +446,16 @@ ACP 是 DCP 的直接替代品。迁移步骤:
|
|
|
446
446
|
|
|
447
447
|
## 更新日志
|
|
448
448
|
|
|
449
|
+
### v1.14.8-dev.2 — Dev 预发布(v1.14.8-dev.1 以来 2 个 PR)
|
|
450
|
+
|
|
451
|
+
Dev 预发布,涵盖 PR #244–#245。发布到 `dev` npm tag 供早期测试。
|
|
452
|
+
|
|
453
|
+
**包含的 PR**:
|
|
454
|
+
- **#245** — 修复:重新将 HOW_TO_COMPRESS_RULES 加入 nudge 注入。v1.14.7 过度删除了所有 4 处 nudge 位置的规则(breakdown + 3 个模板),只保留在 system prompt。在长 session 中,system prompt 的规则因"lost in the middle"效应衰减——模型在 nudge 触发时需要规则在高注意力区(上下文末尾)。
|
|
455
|
+
- **#244** — 修复:acp_status 隐藏 PROTECTED 列表中已消耗的 compress 调用。
|
|
456
|
+
|
|
457
|
+
**安装**:`opencode plugin opencode-acp@dev --global`
|
|
458
|
+
|
|
449
459
|
### v1.14.8-dev.1 — Dev 预发布(v1.14.7 以来 7 个 PR)
|
|
450
460
|
|
|
451
461
|
Dev 预发布,涵盖 PR #238–#242。发布到 `dev` npm tag 供早期测试。
|
package/dist/index.js
CHANGED
|
@@ -7609,6 +7609,8 @@ Breakdown: ${sysPart}${fmt(composition.toolTokens)} tool (${pct2(composition.too
|
|
|
7609
7609
|
if (recommendedRanges.length > 0) {
|
|
7610
7610
|
breakdown += `
|
|
7611
7611
|
|
|
7612
|
+
${HOW_TO_COMPRESS_RULES}
|
|
7613
|
+
|
|
7612
7614
|
${formatCompressibleRanges(recommendedRanges, contextRanges.protected)}`;
|
|
7613
7615
|
breakdown += `
|
|
7614
7616
|
\u{1F4A1} Compress all ranges in one call (pass multiple content entries: \`content: [{...}, {...}]\`).`;
|
|
@@ -7618,7 +7620,7 @@ Use \`acp_status({scope:"uncompressed"})\` to re-fetch compressible ranges after
|
|
|
7618
7620
|
appendToLastTextPart(suffixMessage, breakdown);
|
|
7619
7621
|
}
|
|
7620
7622
|
if (effectiveTipsVariant === "maxLimit") {
|
|
7621
|
-
tipsText =
|
|
7623
|
+
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.';
|
|
7622
7624
|
}
|
|
7623
7625
|
state.nudges.lastNudgeShownTokens = currentTokens;
|
|
7624
7626
|
{
|
|
@@ -8258,6 +8260,64 @@ function createDecompressTool(factoryCtx) {
|
|
|
8258
8260
|
|
|
8259
8261
|
// lib/compress/status.ts
|
|
8260
8262
|
import { tool as tool4 } from "@opencode-ai/plugin";
|
|
8263
|
+
|
|
8264
|
+
// lib/compress/parts.ts
|
|
8265
|
+
var STRUCTURAL_PART_TYPES = /* @__PURE__ */ new Set(["step-start", "step-finish", "reasoning"]);
|
|
8266
|
+
function hasMeaningfulContent(parts) {
|
|
8267
|
+
return parts.some((p) => !STRUCTURAL_PART_TYPES.has(p.type));
|
|
8268
|
+
}
|
|
8269
|
+
|
|
8270
|
+
// lib/compress/hide-consumed.ts
|
|
8271
|
+
var KEEP_LAST_ORPHANED = 2;
|
|
8272
|
+
function hideConsumedCompressCalls(state, messages) {
|
|
8273
|
+
const activeCallIds = /* @__PURE__ */ new Set();
|
|
8274
|
+
const allBlockCallIds = /* @__PURE__ */ new Set();
|
|
8275
|
+
for (const block of state.prune.messages.blocksById.values()) {
|
|
8276
|
+
if (block.compressCallId) {
|
|
8277
|
+
allBlockCallIds.add(block.compressCallId);
|
|
8278
|
+
if (block.active && !block.deactivatedByUser && !block.deactivatedByUserDeep) {
|
|
8279
|
+
activeCallIds.add(block.compressCallId);
|
|
8280
|
+
}
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
const lastOrphanedCallIds = [];
|
|
8284
|
+
for (let i = messages.length - 1; i >= 0 && lastOrphanedCallIds.length < KEEP_LAST_ORPHANED; i--) {
|
|
8285
|
+
const parts = Array.isArray(messages[i]?.parts) ? messages[i].parts : [];
|
|
8286
|
+
for (let j = parts.length - 1; j >= 0 && lastOrphanedCallIds.length < KEEP_LAST_ORPHANED; j--) {
|
|
8287
|
+
const p = parts[j];
|
|
8288
|
+
if (p.type === "tool" && p.tool === "compress" && p.callID && !allBlockCallIds.has(p.callID)) {
|
|
8289
|
+
lastOrphanedCallIds.push(p.callID);
|
|
8290
|
+
}
|
|
8291
|
+
}
|
|
8292
|
+
}
|
|
8293
|
+
const keepCallIds = /* @__PURE__ */ new Set([...activeCallIds, ...lastOrphanedCallIds]);
|
|
8294
|
+
let hidden = 0;
|
|
8295
|
+
for (let i = 0; i < messages.length; i++) {
|
|
8296
|
+
const msg = messages[i];
|
|
8297
|
+
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
8298
|
+
let changed = false;
|
|
8299
|
+
const remaining = parts.filter((p) => {
|
|
8300
|
+
if (p.type === "tool" && p.tool === "compress") {
|
|
8301
|
+
if (p.callID && keepCallIds.has(p.callID)) return true;
|
|
8302
|
+
hidden++;
|
|
8303
|
+
changed = true;
|
|
8304
|
+
return false;
|
|
8305
|
+
}
|
|
8306
|
+
return true;
|
|
8307
|
+
});
|
|
8308
|
+
if (changed) {
|
|
8309
|
+
if (hasMeaningfulContent(remaining)) {
|
|
8310
|
+
messages[i] = { ...msg, parts: remaining };
|
|
8311
|
+
} else {
|
|
8312
|
+
messages.splice(i, 1);
|
|
8313
|
+
i--;
|
|
8314
|
+
}
|
|
8315
|
+
}
|
|
8316
|
+
}
|
|
8317
|
+
return hidden;
|
|
8318
|
+
}
|
|
8319
|
+
|
|
8320
|
+
// lib/compress/status.ts
|
|
8261
8321
|
var ACP_STATUS_TOOL_DESCRIPTION = `Show context status \u2014 overview includes compressible ranges by default.
|
|
8262
8322
|
|
|
8263
8323
|
No args: Overview with totals, compressed blocks, and compressible ranges.
|
|
@@ -8648,6 +8708,7 @@ function createAcpStatusTool(factoryCtx) {
|
|
|
8648
8708
|
if (scope === "uncompressed") return "(unable to fetch messages)";
|
|
8649
8709
|
rawMessages = [];
|
|
8650
8710
|
}
|
|
8711
|
+
hideConsumedCompressCalls(ctx.state, rawMessages);
|
|
8651
8712
|
return buildStatusReport(
|
|
8652
8713
|
{ state: ctx.state, config: ctx.config },
|
|
8653
8714
|
rawMessages,
|
|
@@ -8714,55 +8775,6 @@ Call with blockId to get the full summary: acp_context_recap({ blockId: N })`);
|
|
|
8714
8775
|
});
|
|
8715
8776
|
}
|
|
8716
8777
|
|
|
8717
|
-
// lib/compress/parts.ts
|
|
8718
|
-
var STRUCTURAL_PART_TYPES = /* @__PURE__ */ new Set(["step-start", "step-finish", "reasoning"]);
|
|
8719
|
-
function hasMeaningfulContent(parts) {
|
|
8720
|
-
return parts.some((p) => !STRUCTURAL_PART_TYPES.has(p.type));
|
|
8721
|
-
}
|
|
8722
|
-
|
|
8723
|
-
// lib/compress/hide-consumed.ts
|
|
8724
|
-
function hideConsumedCompressCalls(state, messages) {
|
|
8725
|
-
if (state.prune.messages.blocksById.size === 0) {
|
|
8726
|
-
return 0;
|
|
8727
|
-
}
|
|
8728
|
-
const consumedMessageIds = /* @__PURE__ */ new Set();
|
|
8729
|
-
for (const block of state.prune.messages.blocksById.values()) {
|
|
8730
|
-
if (block.active) continue;
|
|
8731
|
-
if (block.deactivatedByUser) continue;
|
|
8732
|
-
if (block.deactivatedByUserDeep) continue;
|
|
8733
|
-
if (block.deactivatedByBlockId === void 0) continue;
|
|
8734
|
-
if (!block.compressMessageId) continue;
|
|
8735
|
-
consumedMessageIds.add(block.compressMessageId);
|
|
8736
|
-
}
|
|
8737
|
-
if (consumedMessageIds.size === 0) {
|
|
8738
|
-
return 0;
|
|
8739
|
-
}
|
|
8740
|
-
let hidden = 0;
|
|
8741
|
-
for (let i = 0; i < messages.length; i++) {
|
|
8742
|
-
const msg = messages[i];
|
|
8743
|
-
if (!consumedMessageIds.has(msg.info.id)) continue;
|
|
8744
|
-
const parts = Array.isArray(msg.parts) ? msg.parts : [];
|
|
8745
|
-
let changed = false;
|
|
8746
|
-
const remaining = parts.filter((p) => {
|
|
8747
|
-
if (p.type === "tool" && p.tool === "compress") {
|
|
8748
|
-
hidden++;
|
|
8749
|
-
changed = true;
|
|
8750
|
-
return false;
|
|
8751
|
-
}
|
|
8752
|
-
return true;
|
|
8753
|
-
});
|
|
8754
|
-
if (changed) {
|
|
8755
|
-
if (hasMeaningfulContent(remaining)) {
|
|
8756
|
-
messages[i] = { ...msg, parts: remaining };
|
|
8757
|
-
} else {
|
|
8758
|
-
messages.splice(i, 1);
|
|
8759
|
-
i--;
|
|
8760
|
-
}
|
|
8761
|
-
}
|
|
8762
|
-
}
|
|
8763
|
-
return hidden;
|
|
8764
|
-
}
|
|
8765
|
-
|
|
8766
8778
|
// lib/compress/hide-failed.ts
|
|
8767
8779
|
function hideFailedCompressCalls(messages) {
|
|
8768
8780
|
let mostRecentFailedId;
|
|
@@ -8809,7 +8821,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
|
8809
8821
|
import { join as join3 } from "path";
|
|
8810
8822
|
import { existsSync as existsSync3 } from "fs";
|
|
8811
8823
|
import { homedir as homedir3 } from "os";
|
|
8812
|
-
var LOG_VERSION = true ? "1.14.8-dev.
|
|
8824
|
+
var LOG_VERSION = true ? "1.14.8-dev.2" : "dev";
|
|
8813
8825
|
var Logger = class {
|
|
8814
8826
|
logDir;
|
|
8815
8827
|
enabled;
|