Repository navigation
fix: 22 bug fixes for non-Anthropic provider compatibility and compression reliability - #523
ranxianglei wants to merge 2 commits into
Conversation
…ility Major fixes: - Bug 1: Persist messageIds across restarts (persistence.ts, state.ts) - Bug 2: resetOnCompaction preserves prune.messages (utils.ts) - Bug 3: syncCompressionBlocks ignores missing compressMessageId (sync.ts) - Bug 6: Fix silent summary drop when no user msg before anchor (prune.ts) - Bug 7: Assign mNNNN refs to synthetic summary messages (hooks.ts) - Bug 8: Fallback token estimation when API returns 0 (token-utils.ts) - Bug 9: Propagate save errors instead of swallowing (persistence.ts) - Bug 10: Persist block deactivations after sync (hooks.ts) - Bug 11: Recursive deactivatedByUser for decompress (decompress.ts) - Bug 12: Fix isMessageCompacted inconsistency at compaction boundary (utils.ts) - Bug 13: Fix duplicate activeBlockIds loading (utils.ts) - Bug 14: Guard against undefined modelID/providerID (reasoning-strip.ts) - Bug 17: Provider-aware token calculation heuristic (token-utils.ts) - Bug 18: Use raw context limit instead of inputBudget (hooks.ts) - Bug 19: Secondary anchor check against persisted byMessageId (sync.ts) - Bug 20: Cooldown period after compress to prevent repeated warnings (utils.ts) - Bug 21: Strengthen compress prompt against stale ID usage (compress-range.ts) All fixes marked with [FIX Bug N] or [PATCH Bug N] in source.
|
Thank you for your work, but I can't really review a PR that fixes 20 bugs in 1 go, this needs to be many much smaller PRs. There's a lot of good stuff here I think but its very hard for me to replicate bugs or check how your fixes work with a branch that has so many changes. Please consider breaking this down into much more easily digestible PRs, and make sure to verify all of the AI code is good, i'm seeing things like sdk v1 types used and your code/comments don't line up with descriptions in this PR. Also note that when you #n in github you're referencing this PR to previous PRs/issues. |
|
Do as you please, I won't disassemble it anymore. These bugs are ones I actually discovered and confirmed through long-term operation; failing to fix them would render the system inoperable. This plugin is excellent, but I simply don't have the energy to invest more in the community. I will maintain my own version. Finally, thank you very much for your plugin and the inspiration it provided. |
…cted syncCompressionBlocks deactivated any block whose compressMessageId no longer appeared in the current message list. OpenCode compacts old assistant messages including the compress tool-call message, so a perfectly healthy block lost its origin and was deactivated - compressed context silently uncompressed with no error anywhere. PR Tarquinen#523 Bug Tarquinen#3 / Issue Tarquinen#537. The persisted byMessageId index is the authoritative source of truth, so the presence check is gone rather than relaxed. This is independent of the resolvableBlockIds work on this branch: that set gates whether a bN can be looked up right now (anchor present and not an ignored user message), while `active` tracks block lifecycle. Removing the origin check widens which blocks are active; it does not change which of them resolve.
…oint filterCompressedRanges warned and dropped the range when it could not find a user message to anchor the summary to - original messages were removed with no summary in their place. It now falls back to a synthetic user message built from the anchor, which is also the path prune.ts:203/205 already uses for the normal case. PR Tarquinen#523 Bug Tarquinen#6.
DCP Plugin: Comprehensive Bug Fix — Persistence, Token Heuristics, and Compression Stability
This PR fixes 18 bugs across the Dynamic Context Pruning plugin that collectively rendered DCP unreliable in production. The issues span three failure domains: persistence (compression state lost across restarts and compaction), token measurement (inflated counts causing false warnings on non-Anthropic providers), and compression block lifecycle (blocks deactivating spuriously, summaries silently dropped, re-compression impossible). Together, these fixes make DCP's compression behavior stable across long sessions, restarts, and multi-provider setups.
Key themes:
Test Environment
🔴 CRITICAL Fixes
🟠 HIGH Fixes
🟡 MEDIUM Fixes
🟢 LOW Fixes
Design Decisions
1. Provider-Aware Token Heuristic (Bug #17)
Different providers report token counts with different semantics:
The heuristic: if `cacheRead > input && input > 0`, the provider uses split reporting where `cacheRead` is the better proxy. Otherwise `input` already contains the full context. This is deliberately simple and observable.
2. Anchor Persistence Strategy (Bugs #1, #19)
DCP now maintains its own persisted `byMessageId` index, decoupling block validity from opencode's message windowing:
3. Compaction Coexistence (Bug #2)
`resetOnCompaction()` now preserves `prune.messages` (compression blocks) while resetting transient state. After compaction, DCP reassigns refs and re-syncs blocks — but compression summaries survive.
Files Changed
Notes for Reviewers
Reproduction Recipes (for QA)
Bug #1: Start session → compress messages → restart opencode → attempt compress → `startId not available`
Bug #3: Start session → compress → continue 20+ turns → observe blocks deactivating
Bug #6: Compress messages near conversation start (first 5 messages) → observe messages vanish with no summary
Bug #17: Use non-Anthropic provider → observe CRITICAL WARNING at low context usage
Bug #18: Use model with large output budget (204K context, 131K output) → observe 45% threshold firing at ~17%
Bug #20: Compress at high context → observe model immediately re-compressing