Skip to content

fix(compaction): recover agent config after session compaction#2378

Open
code-yeongyu wants to merge 8 commits intodevfrom
fix/issue-2232
Open

fix(compaction): recover agent config after session compaction#2378
code-yeongyu wants to merge 8 commits intodevfrom
fix/issue-2232

Conversation

@code-yeongyu
Copy link
Owner

@code-yeongyu code-yeongyu commented Mar 7, 2026

Summary

  • checkpoint session agent, model, and tool state before compaction and re-inject it when compaction leaves the latest prompt context incomplete
  • detect repeated assistant no-text tails after compaction and trigger defensive recovery before sessions degrade further
  • make background-agent parent-session resolution merge partial metadata and fall back to compaction checkpoints during post-compaction lookups

Testing

  • bun test src/hooks/compaction-context-injector/index.test.ts src/features/background-agent/compaction-aware-message-resolver.test.ts src/index.test.ts src/hooks/preemptive-compaction.test.ts src/hooks/compaction-todo-preserver/index.test.ts
  • bun test src/features/background-agent/manager.test.ts src/features/background-agent/manager.polling.test.ts
  • bun run typecheck
  • bun test
  • bun run build

Summary by cubic

Restores session agent/model/tools after compaction by checkpointing and merging recent context, preventing degraded “no-text” assistant tails and lost background-agent configuration. Addresses issue-2232.

  • Bug Fixes

    • Checkpoint agent config (agent, model, tools) before compaction and re-inject it when post-compaction context is incomplete or after repeated assistant messages with no text.
    • Merge partial prompt context from recent SDK messages and on-disk messages, ignoring the "compaction" agent; fall back to the checkpoint if needed.
    • Background agent now resolves parent-session prompt context with the new resolver to avoid losing agent/model/tools across compaction.
    • Clear checkpoints on session deletion and throttle recovery to avoid churn.
  • Refactors

    • Compaction context injector now exposes capture/inject/event; plugin wiring updated to capture before compaction and route events to the hook.

Written for commit 719a35e. Summary will update on new commits.

code-yeongyu and others added 8 commits March 8, 2026 02:23
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 11 files

Confidence score: 2/5

  • There is a concrete compatibility risk in src/hooks/compaction-context-injector/index.test.ts: using { id } instead of sessionID for session.promptAsync can break URL path substitution, which is likely to cause OpenCode calls to fail rather than just a test mismatch.
  • src/features/background-agent/compaction-aware-message-resolver.ts has two high-impact issues: synchronous read/parse of all message files can block the event loop on long sessions, and reading info.model?.variant (instead of root info.variant) can silently skip variant-specific behavior.
  • Given the high severity and high confidence on multiple issues, this is likely a regression-prone merge until compatibility and performance handling are corrected.
  • Pay close attention to src/features/background-agent/compaction-aware-message-resolver.ts, src/hooks/compaction-context-injector/index.test.ts - SDK field/path mismatches and synchronous file processing may break behavior and responsiveness.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/features/background-agent/compaction-aware-message-resolver.ts">

<violation number="1" location="src/features/background-agent/compaction-aware-message-resolver.ts:53">
P1: Custom agent: **Opencode Compatibility**

The `variant` property in the OpenCode SDK is located at the root of the message object (`info.variant`), not within `model`. Reading `info.model?.variant` will silently fail to recover the agent variant from OpenCode message responses. Update the `SessionMessage` type and this mapping logic to extract `variant` directly from `info`.</violation>

<violation number="2" location="src/features/background-agent/compaction-aware-message-resolver.ts:136">
P1: Synchronously reading and parsing all message files before merging blocks the event loop and degrades performance for long sessions.</violation>
</file>

<file name="src/hooks/compaction-context-injector/index.test.ts">

<violation number="1" location="src/hooks/compaction-context-injector/index.test.ts:150">
P2: Custom agent: **Opencode Compatibility**

The OpenCode SDK defines the `tools` property on messages as `Record<string, boolean>`. The string value `"allow"` is invalid and should be a boolean (e.g., `true`).</violation>

<violation number="2" location="src/hooks/compaction-context-injector/index.test.ts:185">
P0: Custom agent: **Opencode Compatibility**

The OpenCode SDK expects the path parameter for `session.promptAsync` to be `sessionID`, not `id`. Passing `{ id }` breaks URL path substitution. Update both the test expectation and the underlying implementation.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.


//#then
expect(promptAsyncMock).toHaveBeenCalledWith({
path: { id: "ses_checkpoint" },
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 7, 2026

Choose a reason for hiding this comment

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

P0: Custom agent: Opencode Compatibility

The OpenCode SDK expects the path parameter for session.promptAsync to be sessionID, not id. Passing { id } breaks URL path substitution. Update both the test expectation and the underlying implementation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/compaction-context-injector/index.test.ts, line 185:

<comment>The OpenCode SDK expects the path parameter for `session.promptAsync` to be `sessionID`, not `id`. Passing `{ id }` breaks URL path substitution. Update both the test expectation and the underlying implementation.</comment>

<file context>
@@ -104,13 +125,152 @@ describe("createCompactionContextInjector", () => {
+
+      //#then
+      expect(promptAsyncMock).toHaveBeenCalledWith({
+        path: { id: "ses_checkpoint" },
+        body: {
+          noReply: true,
</file context>
Fix with Cubic

model: {
providerID,
modelID,
...(info.model?.variant ? { variant: info.model.variant } : {}),
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 7, 2026

Choose a reason for hiding this comment

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

P1: Custom agent: Opencode Compatibility

The variant property in the OpenCode SDK is located at the root of the message object (info.variant), not within model. Reading info.model?.variant will silently fail to recover the agent variant from OpenCode message responses. Update the SessionMessage type and this mapping logic to extract variant directly from info.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/background-agent/compaction-aware-message-resolver.ts, line 53:

<comment>The `variant` property in the OpenCode SDK is located at the root of the message object (`info.variant`), not within `model`. Reading `info.model?.variant` will silently fail to recover the agent variant from OpenCode message responses. Update the `SessionMessage` type and this mapping logic to extract `variant` directly from `info`.</comment>

<file context>
@@ -16,42 +31,121 @@ function hasFullAgentAndModel(message: StoredMessage): boolean {
+          model: {
+            providerID,
+            modelID,
+            ...(info.model?.variant ? { variant: info.model.variant } : {}),
+          },
+        }
</file context>
Fix with Cubic

continue
}
}
const messages: Array<StoredMessage | null> = []
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 7, 2026

Choose a reason for hiding this comment

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

P1: Synchronously reading and parsing all message files before merging blocks the event loop and degrades performance for long sessions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/background-agent/compaction-aware-message-resolver.ts, line 136:

<comment>Synchronously reading and parsing all message files before merging blocks the event loop and degrades performance for long sessions.</comment>

<file context>
@@ -16,42 +31,121 @@ function hasFullAgentAndModel(message: StoredMessage): boolean {
-        continue
-      }
-    }
+    const messages: Array<StoredMessage | null> = []
 
     for (const file of files) {
</file context>
Fix with Cubic

role: "user",
agent: "atlas",
model: { providerID: "openai", modelID: "gpt-5" },
tools: { bash: "allow" },
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 7, 2026

Choose a reason for hiding this comment

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

P2: Custom agent: Opencode Compatibility

The OpenCode SDK defines the tools property on messages as Record<string, boolean>. The string value "allow" is invalid and should be a boolean (e.g., true).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/compaction-context-injector/index.test.ts, line 150:

<comment>The OpenCode SDK defines the `tools` property on messages as `Record<string, boolean>`. The string value `"allow"` is invalid and should be a boolean (e.g., `true`).</comment>

<file context>
@@ -104,13 +125,152 @@ describe("createCompactionContextInjector", () => {
+                role: "user",
+                agent: "atlas",
+                model: { providerID: "openai", modelID: "gpt-5" },
+                tools: { bash: "allow" },
+              },
+            },
</file context>
Suggested change
tools: { bash: "allow" },
tools: { bash: true },
Fix with Cubic

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