Repository navigation
fix(sdk): context-compact no longer repeats a compaction that changed nothing - #65
Merged
Merged
Conversation
Member
Author
Review round 1: changesReviewer: Claude agent (general-purpose subagent, Opus 5.5), independent of the author session. Commit reviewed:
Checked with no issue found: skipping compaction until an inference completes after the previous one (failure, |
matej21
force-pushed
the
fix/compaction-preamble-floor
branch
from
November 6, 2026 13:32
583cd4d to
52298c9
Compare
Member
Author
Response to review round 1The design was narrowed, and the PR now holds a single commit, 52298c9.
|
… nothing Two paths made an agent compact again without effect, each counted toward limits-guard's maxCompactions: - context_compacted replaces the history but leaves lastInferenceMetrics alone. When the turn after a compaction was paused or its inference failed, the next attempt compacted again on the prompt size measured before the first compaction, summarising the summary. The plugin now keeps a per-agent state slice and skips compaction until an inference has completed since the last one. - With every message inside keepRecentMessages there is nothing to compact, yet compactIfNeeded ran compact(), which returned an empty result the plugin emitted as context_compacted. compactIfNeeded now returns null in that case without calling compact(). A warning is logged when the first inference after a compaction is still over maxTokens. That means either large recent messages the next compaction will remove, or a system prompt, tools and immutable preamble too large on their own, in which case every following turn compacts. The existing test "after compaction, subsequent inference sees fewer messages" passed only on such an empty compaction; it now drives a real one and checks the request got shorter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
Review round 2: approveReviewer: same Claude agent as round 1 (general-purpose subagent, Opus 5.5). Commit reviewed: Verified:
|
matej21
force-pushed
the
fix/compaction-preamble-floor
branch
from
November 6, 2026 13:38
52298c9 to
f685f79
Compare
Member
Author
Response to review round 2All fixes are folded into the single commit f685f79.
Only minor items and nits, so no further round. |
matej21
marked this pull request as ready for review
November 6, 2026 13:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
contextCompactPlugindecides whether to compact from the provider's prompt size of the previous inference (lastInferenceMetrics.promptTokens). Two paths make an agent compact again without effect, andlimitsGuardPlugincounts each one towardmaxCompactions:context_compactedreplaces the history but leaveslastInferenceMetricsunchanged. If the turn after a compaction is paused, or its inference fails and is resumed, the next attempt sees the pre-compaction prompt size and compacts again. It summarises its own summary and counts another compaction.keepRecentMessages, there is nothing to compact. YetcompactIfNeededreturned an empty result and the plugin emittedcontext_compactedfor it. An agent whose system prompt and tools are already overmaxTokensdoes this on every early turn.We saw a related case in production: an agent whose immutable preamble alone was larger than
maxTokens, so every prompt stayed over the threshold, every turn compacted, and the agent was paused atmaxCompactions. History compaction cannot fix that, and the cause belongs with whoever builds the preamble. What it needs from the SDK is a clear signal.Change
contextCompaction, rebuilt from the event log) and skips compaction until an inference has completed since the last one.ContextCompactor.compactIfNeededreturnsnullwhen nothing was compacted, so nocontext_compactedis emitted for it.compact()itself is unchanged.maxTokens. It names the configured threshold and the measured prompt size, because every following turn will compact again. This is diagnostic only; the trigger is unchanged.An earlier version of this PR raised the threshold after an ineffective compaction. Review showed that this could push the prompt past the model's context window, which the plugin does not know, so it was dropped.
Tests
context-compact.integration.test.ts, newrepeated compactionblock. All three tests fail onmain:main).main).main).The existing test "after compaction, subsequent inference sees fewer messages" passed only because of an empty compaction. It now drives a real one and asserts that the request got shorter.
The warning is not asserted, because the test harness uses a silent logger.
bun test packages/sdk/src: 1872 pass, 0 fail.bun run ts:buildandbun run lintpass.Status
changeson the earlier design (threshold raise, now removed); round 2approveon 52298c9 (one minor and three nits, fixed in f685f79)🤖 Generated with Claude Code