Skip to content

feat(context): compact after large responses - #84

Merged
omarluq merged 6 commits into
mainfrom
feat/post-response-auto-compaction
Jun 6, 2026
Merged

feat(context): compact after large responses#84
omarluq merged 6 commits into
mainfrom
feat/post-response-auto-compaction

Conversation

@omarluq

@omarluq omarluq commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Automatically compact sessions after successful assistant turns when estimated context usage reaches the proactive threshold. Emits non-fatal context compaction events and skips duplicate post-response compaction when a request already compacted before sending.

Validation:

  • mise exec -- task ci

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1dd884f8-b723-4610-b065-580cfc986302

📥 Commits

Reviewing files that changed from the base of the PR and between def3fdd and e0683a0.

📒 Files selected for processing (2)
  • internal/assistant/context_auto_compaction_internal_extra_test.go
  • internal/assistant/export_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/assistant/export_test.go
  • internal/assistant/context_auto_compaction_internal_extra_test.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added automatic context compaction after assistant responses to optimize context window usage when thresholds are reached.
  • Tests

    • Added comprehensive test coverage for post-response auto-compaction behavior and edge cases.
  • Chores

    • Updated CI workflow to use Codecov PyPI uploader version 11.2.8.

Walkthrough

Adds post-response auto-compaction: after an assistant response the runtime evaluates context usage against a threshold, emits start/completion/failure events, and runs CompactSessionFrom when needed. Refactors compaction message formatting, exposes test helpers, updates runtime gating to avoid redundant compaction, and adds integration/unit tests.

Changes

Post-Response Context Auto-Compaction

Layer / File(s) Summary
Post-response policy & threshold evaluation
internal/assistant/context_auto_compaction.go
Adds autoCompactAfterResponse, shouldTryPostResponseAutoCompaction, contextBudgetFromUsage, and shouldAutoCompactAfterResponse to decide whether post-response compaction runs.
Post-response emitters & message refactor
internal/assistant/context_auto_compaction.go
Adds emitPostResponseAutoCompactionError and postResponseAutoCompactionStartMessage, and refactors autoCompactionMessage through compactionMessage(prefix, budget, entry).
Runtime integration & redundancy prevention
internal/assistant/runtime.go
Runtime.Prompt records compactedBeforeRequest := bundle.ParentEntryID != nil and only triggers autoCompactAfterResponse when pre-request compaction did not occur.
Test harness, integration and unit tests
internal/assistant/context_auto_compaction_test.go, internal/assistant/context_post_response_auto_compaction_test.go, internal/assistant/context_auto_compaction_internal_extra_test.go
Refactors test harness into autoCompactionRuntimeHarness, adds a near-threshold integration test asserting emitted events and created compaction entries, table-driven threshold tests, extensive error-path tests, and multiple test helpers and stub completion clients.
Test export helpers
internal/assistant/export_test.go
Adds ShouldAutoCompactAfterResponseForTest, Runtime.AutoCompactAfterResponseForTest, Runtime.EmitPostResponseAutoCompactionErrorForTest, and AutoCompactionMessageForTest to allow assertions from tests.
CI uploader config
.github/workflows/ci.yml
Updates Codecov upload inputs to use_pypi: true and version: 11.2.8.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Runtime
  participant SessionRepository
  participant Compactor
  Client->>Runtime: send continuation prompt / finish response
  Runtime->>SessionRepository: GetContextUsage(sessionID)
  SessionRepository-->>Runtime: return token usage
  Runtime->>Runtime: derive contextBudgetFromUsage
  Runtime->>Runtime: shouldAutoCompactAfterResponse(decision)
  alt threshold_exceeded
    Runtime->>Client: emit post-response compaction start event
    Runtime->>Compactor: CompactSessionFrom(parentEntryID)
    Compactor-->>SessionRepository: write compaction branch and leaf
    Runtime->>Client: emit post-response compaction completion event
  else compaction_not_needed
    Runtime->>Client: no compaction performed
  end
  opt compaction_error
    Runtime->>Client: emit post-response compaction failure event
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • omarluq/librecode#83: Introduces the preflight auto-compaction path and sets bundle.ParentEntryID after CompactSessionFrom, which this PR coordinates with to avoid redundant compaction.
  • omarluq/librecode#23: Modifies Runtime.Prompt lifecycle handling; changes may overlap with the prompt gating adjustments here.
  • omarluq/librecode#63: Refactors prompt orchestration and could intersect with the conditional post-response compaction invocation.

Poem

🐇 I nibble old tokens at end of each chat,
Then measure the window where memory sat.
If near to the brim, I bundle and sweep,
Branches get tidy, the context stays neat.
Hop-hop — compact trails for the next prompt’s leap.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature: automatically compacting sessions after large responses, which is the primary change across all modified files.
Description check ✅ Passed The description directly relates to the changeset, explaining the auto-compaction behavior after assistant responses and validation approach.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/post-response-auto-compaction

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/assistant/context_auto_compaction_test.go (1)

92-92: Add a brief rationale for OutputReserveTokens = 1 in this test.

File: internal/assistant/context_auto_compaction_test.go
Lines: 92-92

Snippet showing the final state of code at these lines

runtimeConfig.Context.OutputReserveTokens = 1

OutputReserveTokens was changed from 01 in the same test harness (commit message: “stabilize post-response compaction”). Since this shifts the available context budget by 1 token, add a short comment explaining why reserving 1 token is required here (so future adjustments don’t treat it as an accidental tweak).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/assistant/context_auto_compaction_test.go` at line 92, Add a short
inline comment explaining why runtimeConfig.Context.OutputReserveTokens is set
to 1 in the test: mention it reserves one token for the model's post-response
output/compaction bookkeeping to avoid off-by-one failures in the post-response
compaction assertions (this stabilizes the test after changing from 0→1), and
place the comment immediately above the OutputReserveTokens assignment so future
readers know it is intentional.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/assistant/context_auto_compaction_test.go`:
- Line 92: Add a short inline comment explaining why
runtimeConfig.Context.OutputReserveTokens is set to 1 in the test: mention it
reserves one token for the model's post-response output/compaction bookkeeping
to avoid off-by-one failures in the post-response compaction assertions (this
stabilizes the test after changing from 0→1), and place the comment immediately
above the OutputReserveTokens assignment so future readers know it is
intentional.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5fe6dd04-477e-4d12-9dfc-ab2671113f94

📥 Commits

Reviewing files that changed from the base of the PR and between dc8b1c6 and 6573415.

📒 Files selected for processing (2)
  • internal/assistant/context_auto_compaction_test.go
  • internal/assistant/context_post_response_auto_compaction_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/assistant/context_post_response_auto_compaction_test.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026
@codecov

codecov Bot commented Jun 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.52542% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.61%. Comparing base (c30031b) to head (e0683a0).

Files with missing lines Patch % Lines
internal/assistant/context_auto_compaction.go 90.19% 3 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #84      +/-   ##
==========================================
+ Coverage   68.44%   68.61%   +0.17%     
==========================================
  Files         212      212              
  Lines       18638    18696      +58     
==========================================
+ Hits        12756    12829      +73     
+ Misses       4736     4725      -11     
+ Partials     1146     1142       -4     
Flag Coverage Δ
unittests 68.61% <91.52%> (+0.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
internal/assistant/export_test.go (1)

57-68: 💤 Low value

Consider adding a clarifying comment.

The hardcoded contextBudget values (InputTokens: 12, UsableInput: 10, etc.) appear arbitrary. A brief comment explaining they're chosen for formatting tests where exact values don't affect the output would improve clarity.

📝 Example comment
 // AutoCompactionMessageForTest exposes compaction notice formatting for external package tests.
+// The contextBudget values are arbitrary; message formatting tests don't depend on specific token counts.
 func AutoCompactionMessageForTest(entry *database.EntryEntity) string {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/assistant/export_test.go` around lines 57 - 68, Add a short
clarifying comment above AutoCompactionMessageForTest explaining that the
hardcoded contextBudget values (InputTokens: 12, UsableInput: 10, etc.) are
arbitrary and chosen solely to exercise compactionMessage formatting in tests
where exact numeric values don't affect the output; reference the function name
AutoCompactionMessageForTest, the contextBudget fields, and compactionMessage so
future readers understand these values are not semantic but for
formatting/testing purposes.
internal/assistant/context_auto_compaction_internal_extra_test.go (1)

96-105: ⚡ Quick win

Consider extracting event assertion to a helper.

The assert.Condition with inline loop is functional but verbose. For better readability, consider a helper like assertContainsCompactionErrorEvent(t, events).

♻️ Example helper refactor
func assertContainsCompactionErrorEvent(t *testing.T, events []assistant.StreamEvent) {
	t.Helper()
	for _, event := range events {
		if event.Kind == assistant.StreamEventContextCompaction &&
			strings.Contains(event.Text, "context auto-compaction after response failed:") {
			return
		}
	}
	t.Error("expected context compaction error event not found")
}

Then replace lines 96-105 with:

-	assert.Condition(t, func() bool {
-		for _, event := range events {
-			if event.Kind == assistant.StreamEventContextCompaction &&
-				strings.Contains(event.Text, "context auto-compaction after response failed:") {
-				return true
-			}
-		}
-
-		return false
-	})
+	assertContainsCompactionErrorEvent(t, events)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/assistant/context_auto_compaction_internal_extra_test.go` around
lines 96 - 105, Extract the inline assert.Condition loop into a helper to
improve readability: create a helper function named
assertContainsCompactionErrorEvent(t *testing.T, events []assistant.StreamEvent)
that calls t.Helper(), iterates over events, checks event.Kind ==
assistant.StreamEventContextCompaction and strings.Contains(event.Text, "context
auto-compaction after response failed:"), returns on match and calls
t.Error(...) if not found; then replace the assert.Condition(...) block with a
call to assertContainsCompactionErrorEvent(t, events).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/assistant/context_auto_compaction_internal_extra_test.go`:
- Around line 96-105: Extract the inline assert.Condition loop into a helper to
improve readability: create a helper function named
assertContainsCompactionErrorEvent(t *testing.T, events []assistant.StreamEvent)
that calls t.Helper(), iterates over events, checks event.Kind ==
assistant.StreamEventContextCompaction and strings.Contains(event.Text, "context
auto-compaction after response failed:"), returns on match and calls
t.Error(...) if not found; then replace the assert.Condition(...) block with a
call to assertContainsCompactionErrorEvent(t, events).

In `@internal/assistant/export_test.go`:
- Around line 57-68: Add a short clarifying comment above
AutoCompactionMessageForTest explaining that the hardcoded contextBudget values
(InputTokens: 12, UsableInput: 10, etc.) are arbitrary and chosen solely to
exercise compactionMessage formatting in tests where exact numeric values don't
affect the output; reference the function name AutoCompactionMessageForTest, the
contextBudget fields, and compactionMessage so future readers understand these
values are not semantic but for formatting/testing purposes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 230aa9e0-952c-43ba-8caa-3edfc05785f7

📥 Commits

Reviewing files that changed from the base of the PR and between def3fdd and 4485f7a.

📒 Files selected for processing (2)
  • internal/assistant/context_auto_compaction_internal_extra_test.go
  • internal/assistant/export_test.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026
@sonarqubecloud

sonarqubecloud Bot commented Jun 6, 2026

Copy link
Copy Markdown

@omarluq
omarluq merged commit 695581d into main Jun 6, 2026
15 checks passed
@omarluq
omarluq deleted the feat/post-response-auto-compaction branch June 6, 2026 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant