opencode-acp 1.14.8-dev.3 → 1.14.8-dev.5
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 +36 -0
- package/README.zh-CN.md +36 -0
- package/dist/index.js +30 -92
- 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 +10 -7
- package/dist/lib/messages/inject/utils.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -492,6 +492,42 @@ 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.5 — Dev Prerelease (1 PR since v1.14.8-dev.4)
|
|
496
|
+
|
|
497
|
+
Dev prerelease covering PR #257. Published to `dev` npm tag for early testing.
|
|
498
|
+
|
|
499
|
+
**PRs included**:
|
|
500
|
+
- **#257** — Bump `context-compress-algorithms` from 1.2.1 to 1.3.0. cc-alg 1.3.0 ships holistic TIER2/TIER3 compression prompts — summarize by theme instead of per-block. The old per-block format (Source header + 3-5 bullets + 50-150 tokens per block) caused length overflow when compressing 70+ T1 blocks (~30K chars exceeding `maxSummaryLengthHard`). No source code changes needed (prompts consumed from dependency).
|
|
501
|
+
|
|
502
|
+
**Install**: `opencode plugin opencode-acp@dev --global`
|
|
503
|
+
|
|
504
|
+
### v1.14.8-dev.4 — Dev Prerelease (1 PR since v1.14.8-dev.3)
|
|
505
|
+
|
|
506
|
+
Dev prerelease covering PR #252. Published to `dev` npm tag for early testing.
|
|
507
|
+
|
|
508
|
+
**PRs included**:
|
|
509
|
+
- **#252** — Two fixes: (1) **Issue #251**: `filterRecommendedRanges` suppressed ALL recommendations when compressible content was below 5% of modelContextLimit (50K at 1M context). Rewrote to always show all ranges with `dangerous: true` on the last segment. Simplified `RangeFilterOptions`. (2) **Nudge loop fix**: `lastNudgeShownTokens` was reset to `undefined` on `nothingToCompress`, causing `growthReference` to fall back to stale session-start baseline → nudges firing every turn. Removed the reset. Also fixed growth display to use `lastNudgeShownTokens ?? lastPerMessageNudgeTokens` matching the actual decision logic. Oracle + Explore review: both APPROVE.
|
|
510
|
+
|
|
511
|
+
**Install**: `opencode plugin opencode-acp@dev --global`
|
|
512
|
+
|
|
513
|
+
### v1.14.8 — Stable Release (10 PRs since v1.14.7)
|
|
514
|
+
|
|
515
|
+
Stable release promoted from dev prereleases v1.14.8-dev.1 through v1.14.8-dev.3. Includes all fixes tested in the dev channel.
|
|
516
|
+
|
|
517
|
+
**Highlights**:
|
|
518
|
+
|
|
519
|
+
- **System token visibility** (#241): `acp_status` and nudge breakdown now show system prompt token proportion (5-15% of context). Consolidated 4 duplicate estimation algorithms into 1 shared `estimateSystemPromptTokens()` using the real Anthropic tokenizer.
|
|
520
|
+
- **HOW_TO_COMPRESS_RULES re-added to nudge** (#245): v1.14.7 over-removed the compression rules from all nudge locations. In long sessions (8,000+ messages), the rules in the system prompt degrade due to "lost in the middle" effect — re-added to nudge for high-attention guidance when compression triggers.
|
|
521
|
+
- **Tool pair integrity** (#248): Compression ranges that split tool_use/tool_result pairs caused API rejections. New `adjustBoundariesForToolPairs` auto-extends boundaries by callID matching.
|
|
522
|
+
- **Pluggable message filters** (#239, #242): `keepLastOnly` dedup mechanism + 4 OMO builtin filters for cleaning up third-party (e.g. OMO) injected messages that accumulate duplicates.
|
|
523
|
+
- **Orphan message splicing** (#240): When `hideConsumedCompressCalls` leaves only structural parts (step-finish, reasoning), the message is now spliced out instead of surviving as a 500-2000 token orphan.
|
|
524
|
+
- **E2E hardening** (#238): Observation recording, T2 cadence regression scenario, consumed-call hiding scenario, auxiliary call filtering. 12 E2E scenarios (was 8).
|
|
525
|
+
- **acp_status consumed compress hiding** (#244): Hides consumed compress calls from the PROTECTED list.
|
|
526
|
+
|
|
527
|
+
**All PRs included**: #238 (E2E hardening), #232 (remove dead turnProtection/DCP migration), #234 (re-add /acp stats), #239 (pluggable message filter), #240 (orphan splice), #241 (system tokens), #242 (keepLastOnly + OMO filters), #244 (acp_status consumed compress), #245 (HOW_TO_COMPRESS_RULES re-add), #248 (tool pair integrity).
|
|
528
|
+
|
|
529
|
+
**Install**: `opencode plugin opencode-acp@stable --global`
|
|
530
|
+
|
|
495
531
|
### v1.14.8-dev.3 — Dev Prerelease (1 PR since v1.14.8-dev.2)
|
|
496
532
|
|
|
497
533
|
Dev prerelease covering PR #248. Published to `dev` npm tag for early testing.
|
package/README.zh-CN.md
CHANGED
|
@@ -446,6 +446,24 @@ ACP 是 DCP 的直接替代品。迁移步骤:
|
|
|
446
446
|
|
|
447
447
|
## 更新日志
|
|
448
448
|
|
|
449
|
+
### v1.14.8-dev.5 — Dev 预发布(v1.14.8-dev.4 以来 1 个 PR)
|
|
450
|
+
|
|
451
|
+
Dev 预发布,涵盖 PR #257。发布到 `dev` npm tag 供早期测试。
|
|
452
|
+
|
|
453
|
+
**包含的 PR**:
|
|
454
|
+
- **#257** — 升级 `context-compress-algorithms` 从 1.2.1 到 1.3.0。cc-alg 1.3.0 提供整体式 TIER2/TIER3 压缩提示——按主题综合而非逐块处理。旧的逐块格式(Source 头 + 每块 3-5 条 + 每块 50-150 tokens)在压缩 70+ 个 T1 块时导致长度溢出(~30K 字符超过 `maxSummaryLengthHard`)。无需源码修改(提示从依赖中获取)。
|
|
455
|
+
|
|
456
|
+
**安装**: `opencode plugin opencode-acp@dev --global`
|
|
457
|
+
|
|
458
|
+
### v1.14.8-dev.4 — Dev 预发布(v1.14.8-dev.3 以来 1 个 PR)
|
|
459
|
+
|
|
460
|
+
Dev 预发布,涵盖 PR #252。发布到 `dev` npm tag 供早期测试。
|
|
461
|
+
|
|
462
|
+
**包含的 PR**:
|
|
463
|
+
- **#252** — 两个修复:(1) **Issue #251**:`filterRecommendedRanges` 在可压缩内容低于 modelContextLimit 的 5%(1M 上下文为 50K)时抑制所有推荐。重写为始终显示所有范围,最后一段标记 `dangerous: true`。简化 `RangeFilterOptions`。(2) **Nudge 循环修复**:`nothingToCompress` 时 `lastNudgeShownTokens` 被重置为 `undefined`,导致 `growthReference` 回退到 session 开始时的 stale baseline → 每轮都触发 nudge。移除该重置。同时修复增长显示使用 `lastNudgeShownTokens ?? lastPerMessageNudgeTokens`,与实际决策逻辑一致。Oracle + Explore Review:均通过。
|
|
464
|
+
|
|
465
|
+
**安装**:`opencode plugin opencode-acp@dev --global`
|
|
466
|
+
|
|
449
467
|
### v1.14.8-dev.3 — Dev 预发布(v1.14.8-dev.2 以来 1 个 PR)
|
|
450
468
|
|
|
451
469
|
Dev 预发布,涵盖 PR #248。发布到 `dev` npm tag 供早期测试。
|
|
@@ -480,6 +498,24 @@ Dev 预发布,涵盖 PR #238–#242。发布到 `dev` npm tag 供早期测试
|
|
|
480
498
|
|
|
481
499
|
**安装**:`opencode plugin opencode-acp@dev --global`
|
|
482
500
|
|
|
501
|
+
### v1.14.8 — 正式版(v1.14.7 以来 10 个 PR)
|
|
502
|
+
|
|
503
|
+
正式版,从 dev 预发布 v1.14.8-dev.1 至 v1.14.8-dev.3 提升而来。包含所有在 dev 通道测试过的修复。
|
|
504
|
+
|
|
505
|
+
**亮点**:
|
|
506
|
+
|
|
507
|
+
- **系统 token 可见性**(#241):`acp_status` 和 nudge breakdown 现在显示系统 prompt token 占比(上下文的 5-15%)。将 4 处重复的估算算法整合为 1 个共享 `estimateSystemPromptTokens()`,使用真正的 Anthropic 分词器。
|
|
508
|
+
- **HOW_TO_COMPRESS_RULES 重新加入 nudge**(#245):v1.14.7 过度删除了所有 nudge 位置的压缩规则。在长 session(8000+ 消息)中,system prompt 中的规则因"lost in the middle"效应衰减——重新加入 nudge 以在压缩触发时提供高注意力区指导。
|
|
509
|
+
- **工具配对完整性**(#248):压缩范围拆分 tool_use/tool_result 配对会导致 API 拒绝。新增 `adjustBoundariesForToolPairs` 按 callID 匹配自动扩展边界。
|
|
510
|
+
- **可插拔消息过滤器**(#239, #242):`keepLastOnly` 去重机制 + 4 个 OMO 内置过滤器,用于清理第三方注入消息的重复累积。
|
|
511
|
+
- **孤儿消息清理**(#240):`hideConsumedCompressCalls` 仅剩结构化部分时(step-finish、reasoning),消息现在被 splice 掉,不再作为 500-2000 token 孤儿存活。
|
|
512
|
+
- **E2E 强化**(#238):观察记录、T2 节奏回归场景、consumed-call 隐藏场景、辅助调用过滤。E2E 场景 8→12 个。
|
|
513
|
+
- **acp_status 隐藏已消耗 compress**(#244):从 PROTECTED 列表中隐藏已消耗的 compress 调用。
|
|
514
|
+
|
|
515
|
+
**包含的所有 PR**:#238(E2E 强化)、#232(移除死代码 turnProtection/DCP 迁移)、#234(重新添加 /acp stats)、#239(可插拔消息过滤器)、#240(孤儿消息清理)、#241(系统 token)、#242(keepLastOnly + OMO 过滤器)、#244(acp_status 已消耗 compress)、#245(HOW_TO_COMPRESS_RULES 重新加入)、#248(工具配对完整性)。
|
|
516
|
+
|
|
517
|
+
**安装**:`opencode plugin opencode-acp@stable --global`
|
|
518
|
+
|
|
483
519
|
### v1.14.7 — 去重 HOW_TO_COMPRESS_RULES(PR #228)
|
|
484
520
|
|
|
485
521
|
**问题**:`HOW_TO_COMPRESS_RULES`(~1.2K tokens)每次 nudge 注入重复 3-4 次——系统提示词 1 次、nudge 模板 1-2 次、breakdown 块 1 次。非 maxLimit 场景下 suffix 消息单独就包含 2-3 份规则。每次 nudge 浪费 2.4-3.6K tokens。v1.14.6 让 debug 模式持久化 nudge 文本到聊天界面后,重复变得可见。
|
package/dist/index.js
CHANGED
|
@@ -5500,7 +5500,7 @@ function evaluatePreCommitQuality(rawMessages, messageIds, messageTokenById, sum
|
|
|
5500
5500
|
}
|
|
5501
5501
|
}
|
|
5502
5502
|
|
|
5503
|
-
// node_modules/context-compress-algorithms/dist/chunk-
|
|
5503
|
+
// node_modules/context-compress-algorithms/dist/chunk-YCHW53QG.js
|
|
5504
5504
|
var COMPRESS_PHILOSOPHY = `Compression Philosophy:
|
|
5505
5505
|
- All compression serves the primary task, but be frugal.
|
|
5506
5506
|
- Context capacity is precious. Save context by compressing consumed outputs, not by avoiding tools.
|
|
@@ -5547,7 +5547,7 @@ PRIORITY \u2014 when the summary must be compact, preserve in this order:
|
|
|
5547
5547
|
Write dense, scannable bullets \u2014 not narrative prose. If the range spans distinct concerns (request \u2192 findings \u2192 decision), group bullets under short thematic headers so a reader can scan to the part they need. Every line must earn its place. Do not mimic the style of existing summaries in context; follow these rules.`;
|
|
5548
5548
|
var TIER2_DISTILL_RULES = `TIER 2 COMPRESSION \u2014 DISTILLATION
|
|
5549
5549
|
|
|
5550
|
-
You are compressing historical summaries (not raw conversation). These summaries have already captured the details. Your job is to DISTILL them:
|
|
5550
|
+
You are compressing historical summaries (not raw conversation). These summaries have already captured the details. Your job is to DISTILL them: write a holistic summary of what matters for future work, discarding the process.
|
|
5551
5551
|
|
|
5552
5552
|
KEEP \u2014 these are the only things that survive distillation:
|
|
5553
5553
|
- Decisions and their rationale ("chose X over Y because Z" \u2014 the "because" is load-bearing).
|
|
@@ -5555,9 +5555,9 @@ KEEP \u2014 these are the only things that survive distillation:
|
|
|
5555
5555
|
- Key lessons: what failed and why ("tried X, failed because Y"). These prevent repeating mistakes.
|
|
5556
5556
|
- Critical constraints discovered ("must support Node 22", "AGENTS.md forbids as any").
|
|
5557
5557
|
- Design decisions with architectural impact ("chose compress-as-anchor over synthetic messages because prefix cache").
|
|
5558
|
-
- Whether content is OBSOLETE or SUPERSEDED \u2014 mark with one line: "[SUPERSEDED by PR #NNN]" or "[OBSOLETE: deleted in vX.Y.Z]".
|
|
5559
|
-
- Function/class/type names and module paths that are the SUBJECT of the work \u2014 e.g., "fixed filterCompressedRanges in prune.ts"
|
|
5560
|
-
- Exploration findings: if a block was exploratory with no decision, keep the CONCLUSION in one line
|
|
5558
|
+
- Whether content is OBSOLETE or SUPERSEDED \u2014 mark with one line: "[SUPERSEDED by PR #NNN]" or "[OBSOLETE: deleted in vX.Y.Z]".
|
|
5559
|
+
- Function/class/type names and module paths that are the SUBJECT of the work \u2014 e.g., "fixed filterCompressedRanges in prune.ts". Not exact line numbers or full signatures \u2014 just enough to LOCATE the code.
|
|
5560
|
+
- Exploration findings: if a block was exploratory with no decision, keep the CONCLUSION in one line.
|
|
5561
5561
|
|
|
5562
5562
|
DROP \u2014 these were useful during the work but are no longer needed:
|
|
5563
5563
|
- Exact line numbers, diffs, verbose function signatures, full code listings.
|
|
@@ -5566,20 +5566,17 @@ DROP \u2014 these were useful during the work but are no longer needed:
|
|
|
5566
5566
|
- Verbose logs, command output, intermediate debugging steps.
|
|
5567
5567
|
|
|
5568
5568
|
FORMAT:
|
|
5569
|
-
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
-
|
|
5573
|
-
- Dense, scannable \u2014 no narrative prose.
|
|
5574
|
-
-
|
|
5575
|
-
- Cross-block synthesis: if multiple source blocks cover the same topic (same PR, same feature, same bug), MERGE them into a single group of bullets. Do not repeat the same fact from different blocks \u2014 keep it once under the most relevant source header.
|
|
5576
|
-
|
|
5577
|
-
SIZE TARGET: 50-150 tokens per source block (excluding the header). If you can't fit it in 150 tokens, you're keeping too much process. If a block has nothing worth keeping (pure noise), output just the header followed by "[no actionable content]".`;
|
|
5569
|
+
- Write a HOLISTIC summary grouped by THEME, not by source block.
|
|
5570
|
+
- NO per-block headers. NO "Source: bN" lines. This is a review of what happened, not a catalog of blocks.
|
|
5571
|
+
- Group related work together: all releases in one section, all bug fixes in another, all architecture decisions in a third.
|
|
5572
|
+
- Start with the most important outcomes (shipped releases, merged PRs, critical bugs).
|
|
5573
|
+
- Dense, scannable bullets \u2014 no narrative prose.
|
|
5574
|
+
- Most blocks will collapse into 1-2 bullets within a theme group. Many will have nothing worth keeping \u2014 omit them entirely.`;
|
|
5578
5575
|
var TIER3_CONDENSE_RULES = `TIER 3 COMPRESSION \u2014 ULTRA-CONDENSATION
|
|
5579
5576
|
|
|
5580
5577
|
You are compressing distilled summaries (Tier 2) into ultra-condensed facts (Tier 3). The distilled summaries already contain only decisions and outcomes. Your job is to reduce them to bare factual references.
|
|
5581
5578
|
|
|
5582
|
-
PRIORITY \u2014
|
|
5579
|
+
PRIORITY \u2014 keep in this order:
|
|
5583
5580
|
1. Shipped outcomes (versions released, PRs merged) \u2014 these are permanent record.
|
|
5584
5581
|
2. Open work (PRs/issues still pending) \u2014 these may need follow-up.
|
|
5585
5582
|
3. Key decisions with architectural impact ("chose X over Y because Z").
|
|
@@ -5587,12 +5584,11 @@ PRIORITY \u2014 when a source block has more facts than the size target allows,
|
|
|
5587
5584
|
Drop everything else. Tier 3 is a lookup index, not a knowledge base.
|
|
5588
5585
|
|
|
5589
5586
|
FORMAT:
|
|
5590
|
-
-
|
|
5591
|
-
|
|
5592
|
-
-
|
|
5587
|
+
- Write a HOLISTIC list of bare facts, grouped by theme \u2014 not by source block.
|
|
5588
|
+
- NO per-block headers. NO "Source: bN" lines.
|
|
5589
|
+
- Each fact is a single line: "[PR/Issue/Version] \u2014 [outcome in \u22648 words]"
|
|
5590
|
+
- Merge related facts aggressively. If multiple blocks concern the same release/feature/bug, output ONE line covering all of them.
|
|
5593
5591
|
- No explanations, no rationale, no process \u2014 just the fact.
|
|
5594
|
-
- Format: "[PR/Issue/Version] \u2014 [outcome in \u22648 words]"
|
|
5595
|
-
- Merge related facts from different source blocks if they concern the same topic.
|
|
5596
5592
|
|
|
5597
5593
|
EXAMPLES:
|
|
5598
5594
|
- "v1.13.0 shipped \u2014 quality gate + GC fix (7 PRs)"
|
|
@@ -5605,9 +5601,7 @@ DROP:
|
|
|
5605
5601
|
- Multi-sentence context. If a fact needs >1 sentence, it's too detailed for Tier 3.
|
|
5606
5602
|
- Lessons learned ("tried X, failed because Y") \u2014 drop UNLESS the failure is likely to recur and the block is <30 days old.
|
|
5607
5603
|
- Design rationale details \u2014 keep the decision, drop the "because" unless it's a critical constraint.
|
|
5608
|
-
- Anything marked [OBSOLETE] or [SUPERSEDED] \u2014 drop entirely, note "[N blocks obsolete]"
|
|
5609
|
-
|
|
5610
|
-
SIZE TARGET: 30-60 tokens per source block (including header). For a batch of N source blocks, total output \u2248 N \xD7 40 tokens. If a source block has only one trivial fact, output just the header + one line.`;
|
|
5604
|
+
- Anything marked [OBSOLETE] or [SUPERSEDED] \u2014 drop entirely, note "[N blocks obsolete]" at the end.`;
|
|
5611
5605
|
|
|
5612
5606
|
// lib/compress/quality-gate/rejection.ts
|
|
5613
5607
|
function formatMetric(result, name) {
|
|
@@ -7168,62 +7162,19 @@ function buildCompressibleRanges(messages, state, protectedTools = [], protected
|
|
|
7168
7162
|
};
|
|
7169
7163
|
}
|
|
7170
7164
|
function filterRecommendedRanges(compressible, _protectedRanges, options) {
|
|
7171
|
-
const {
|
|
7165
|
+
const { logger } = options;
|
|
7172
7166
|
const log = logger?.debug.bind(logger);
|
|
7173
|
-
if (!modelContextLimit || modelContextLimit <= 0) {
|
|
7174
|
-
log?.("filterRecommendedRanges: modelContextLimit unknown, passthrough", {
|
|
7175
|
-
inputCount: compressible.length
|
|
7176
|
-
});
|
|
7177
|
-
if (compressible.length === 0) return [];
|
|
7178
|
-
const passthrough = [...compressible];
|
|
7179
|
-
passthrough[passthrough.length - 1] = {
|
|
7180
|
-
...passthrough[passthrough.length - 1],
|
|
7181
|
-
dangerous: true
|
|
7182
|
-
};
|
|
7183
|
-
return passthrough;
|
|
7184
|
-
}
|
|
7185
7167
|
if (compressible.length === 0) {
|
|
7186
7168
|
log?.("filterRecommendedRanges: no compressible ranges, returning empty");
|
|
7187
7169
|
return [];
|
|
7188
7170
|
}
|
|
7189
|
-
const
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
const lastSegmentIncluded = lastRange.tokens >= lastSegmentFloor;
|
|
7194
|
-
let effectiveCompressible = 0;
|
|
7195
|
-
const result = [];
|
|
7196
|
-
for (let i = 0; i < compressible.length; i++) {
|
|
7197
|
-
const r = compressible[i];
|
|
7198
|
-
if (i === lastIndex) {
|
|
7199
|
-
const excess = Math.max(0, r.tokens - lastSegmentFloor);
|
|
7200
|
-
effectiveCompressible += excess;
|
|
7201
|
-
if (lastSegmentIncluded) {
|
|
7202
|
-
result.push({ ...r, dangerous: true });
|
|
7203
|
-
}
|
|
7204
|
-
} else {
|
|
7205
|
-
effectiveCompressible += r.tokens;
|
|
7206
|
-
result.push(r);
|
|
7207
|
-
}
|
|
7208
|
-
}
|
|
7209
|
-
const suppressed = effectiveCompressible < growthThreshold;
|
|
7210
|
-
log?.("filterRecommendedRanges: decision", {
|
|
7171
|
+
const result = compressible.map(
|
|
7172
|
+
(r, i) => i === compressible.length - 1 ? { ...r, dangerous: true } : r
|
|
7173
|
+
);
|
|
7174
|
+
log?.("filterRecommendedRanges: passthrough (last segment marked dangerous)", {
|
|
7211
7175
|
inputRanges: compressible.length,
|
|
7212
|
-
|
|
7213
|
-
growthThreshold,
|
|
7214
|
-
lastSegmentFloor,
|
|
7215
|
-
lastSegment: {
|
|
7216
|
-
ref: `${lastRange.startRef}\u2013${lastRange.endRef}`,
|
|
7217
|
-
tokens: lastRange.tokens,
|
|
7218
|
-
included: lastSegmentIncluded
|
|
7219
|
-
},
|
|
7220
|
-
effectiveCompressible,
|
|
7221
|
-
suppressed,
|
|
7222
|
-
outputRanges: suppressed ? 0 : result.length
|
|
7176
|
+
outputRanges: result.length
|
|
7223
7177
|
});
|
|
7224
|
-
if (suppressed) {
|
|
7225
|
-
return [];
|
|
7226
|
-
}
|
|
7227
7178
|
return result;
|
|
7228
7179
|
}
|
|
7229
7180
|
function formatCompressibleRanges(ranges, protectedRanges) {
|
|
@@ -7537,37 +7488,24 @@ var injectCompressNudges = (state, config, logger, messages, prompts, compressio
|
|
|
7537
7488
|
const recommendedRanges = filterRecommendedRanges(
|
|
7538
7489
|
unprotectedCompressible,
|
|
7539
7490
|
contextRanges.protected,
|
|
7540
|
-
{
|
|
7491
|
+
{ logger }
|
|
7541
7492
|
);
|
|
7542
7493
|
const hasRecommendations = recommendedRanges.length > 0;
|
|
7543
|
-
if (config.debug && contextRanges.compressible.length > 0
|
|
7544
|
-
const growthThreshold = modelContextLimit * 0.05;
|
|
7545
|
-
const lastSegmentFloor = growthThreshold * 2;
|
|
7494
|
+
if (config.debug && contextRanges.compressible.length > 0) {
|
|
7546
7495
|
const compressible = contextRanges.compressible;
|
|
7547
|
-
const lastRange = compressible[compressible.length - 1];
|
|
7548
|
-
const lastIncluded = lastRange.tokens >= lastSegmentFloor;
|
|
7549
|
-
const nonLastTokens = compressible.slice(0, -1).reduce((s, r) => s + r.tokens, 0);
|
|
7550
|
-
const effective = nonLastTokens + Math.max(0, lastRange.tokens - lastSegmentFloor);
|
|
7551
|
-
const suppressed = effective < growthThreshold;
|
|
7552
7496
|
const fmt = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : String(n);
|
|
7553
7497
|
const lines = [
|
|
7554
|
-
`[ACP Debug] Recommendation filter
|
|
7498
|
+
`[ACP Debug] Recommendation filter:`,
|
|
7555
7499
|
` Input: ${compressible.length} range(s), ${fmt(compressible.reduce((s, r) => s + r.tokens, 0))} tokens`,
|
|
7556
|
-
`
|
|
7557
|
-
` Last segment: ${lastRange.startRef}\u2013${lastRange.endRef} ${fmt(lastRange.tokens)} tokens \u2192 ${lastIncluded ? "included (dangerous)" : "excluded (< floor)"}`,
|
|
7558
|
-
` Effective compressible: ${fmt(effective)} \u2192 ${suppressed ? "SUPPRESSED (< growth threshold)" : `${recommendedRanges.length} range(s) recommended`}`
|
|
7500
|
+
` Output: ${recommendedRanges.length} range(s) (last segment marked dangerous)`
|
|
7559
7501
|
];
|
|
7560
7502
|
logger.debug(lines.join("\n"));
|
|
7561
7503
|
}
|
|
7562
|
-
const filterSuppressed = contextRanges.compressible.length > 0 && !hasRecommendations;
|
|
7563
7504
|
const allProtected = contextRanges.compressible.length === 0 && contextRanges.protected.length > 0;
|
|
7564
7505
|
const allInProtectedZone = protectedRefs.size > 0 && unprotectedCompressible.length === 0;
|
|
7565
|
-
const nothingToCompress =
|
|
7506
|
+
const nothingToCompress = allProtected || allInProtectedZone;
|
|
7566
7507
|
const shouldInjectNudge = nudgeAllowed && (!nothingToCompress || emergencyOverride);
|
|
7567
7508
|
let shouldInject = shouldInjectNudge;
|
|
7568
|
-
if (nudgeAllowed && nothingToCompress && !emergencyOverride) {
|
|
7569
|
-
state.nudges.lastNudgeShownTokens = void 0;
|
|
7570
|
-
}
|
|
7571
7509
|
if (shouldInjectNudge) {
|
|
7572
7510
|
applyAnchoredNudges(state, config, messages, prompts, compressionPriorities, currentTokens, modelContextLimit, suffixMessage);
|
|
7573
7511
|
}
|
|
@@ -7662,7 +7600,7 @@ ${rules}`;
|
|
|
7662
7600
|
if (suffixMessage && composition.total > 0) {
|
|
7663
7601
|
const fmt = (n) => n >= 1e3 ? `${(n / 1e3).toFixed(1)}K` : String(n);
|
|
7664
7602
|
const pct2 = (n) => n > 0 ? Math.max(1, Math.round(n / composition.total * 100)) : 0;
|
|
7665
|
-
const growth = currentTokens !== void 0 && state.nudges.lastPerMessageNudgeTokens !== void 0 ? currentTokens - state.nudges.lastPerMessageNudgeTokens : 0;
|
|
7603
|
+
const growth = currentTokens !== void 0 && (state.nudges.lastNudgeShownTokens ?? state.nudges.lastPerMessageNudgeTokens) !== void 0 ? currentTokens - (state.nudges.lastNudgeShownTokens ?? state.nudges.lastPerMessageNudgeTokens) : 0;
|
|
7666
7604
|
const growthStr = growth > 0 ? ` (+${fmt(growth)} since last nudge)` : "";
|
|
7667
7605
|
const plainTextTokens = composition.textTokens;
|
|
7668
7606
|
const efficiencyNote = effectiveTipsVariant !== "maxLimit" ? `
|
|
@@ -8892,7 +8830,7 @@ import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
|
8892
8830
|
import { join as join3 } from "path";
|
|
8893
8831
|
import { existsSync as existsSync3 } from "fs";
|
|
8894
8832
|
import { homedir as homedir3 } from "os";
|
|
8895
|
-
var LOG_VERSION = true ? "1.14.8-dev.
|
|
8833
|
+
var LOG_VERSION = true ? "1.14.8-dev.5" : "dev";
|
|
8896
8834
|
var Logger = class {
|
|
8897
8835
|
logDir;
|
|
8898
8836
|
enabled;
|