Skip to content

fix: preserve session state on session expiration, abort, and compaction (Fixes #1054) - #1055

Closed
Utkarsh-X wants to merge 8544 commits into
CodebuffAI:mainfrom
Utkarsh-X:fix/preserve-session-state-on-abort-compaction
Closed

fix: preserve session state on session expiration, abort, and compaction (Fixes #1054)#1055
Utkarsh-X wants to merge 8544 commits into
CodebuffAI:mainfrom
Utkarsh-X:fix/preserve-session-state-on-abort-compaction

Conversation

@Utkarsh-X

Copy link
Copy Markdown

Fixes #1054

Summary

Fixes an issue where sending a message (such as "continue") after a free session expires or after interrupting with Esc causes the assistant to lose all conversation memory and restart exploration from scratch.

Root Cause

  1. Missing in-memory state update on errors / session expiration (use-send-message.ts):
    When a free session ends or fails with a gate error, the catch (error) block in use-send-message.ts calls saveChatState to persist the snapshot to disk, but does not update previousRunStateRef.current in React memory. When the user sends a follow-up prompt in the same running session, sendMessage reads the un-synced previousRunStateRef.current, causing sdk/src/run.ts to instantiate a blank initialSessionState (messageHistory = []).

  2. Abort race condition (use-send-message.ts):
    When a user interrupts with Esc, the UI input lock was released before client.run() finished resolving without synchronously assigning previousRunStateRef.current = latestRunStateSnapshot.

  3. Compaction continuation guidance (compact-history.ts, context-pruner.ts):
    When deterministic compaction runs, the history is collapsed into a synthetic summary. Because the system prompt retains # Initial Git Changes, models seeing 0 assistant turns occasionally re-ran exploratory git diff and tree commands.

Changes

  • cli/src/hooks/use-send-message.ts:
    • Assign previousRunStateRef.current = latestRunStateSnapshot and setRunState(latestRunStateSnapshot) inside registerActiveRun upon abort.
    • Assign previousRunStateRef.current = latestRunStateSnapshot and setRunState(latestRunStateSnapshot) in the catch (error) block alongside saveChatState.
  • cli/src/hooks/helpers/send-message.ts:
    • Updated the abort listener comment to reflect synchronous state preservation.
  • packages/agent-runtime/src/compact-history.ts & agents/context-pruner.ts:
    • Clarified CONTINUATION_TEXT (in 100% parity) to instruct models that initial repository exploration is already recorded in <historical_memory>.

Verification

  • bun test sdk/src/__tests__/run-cancellation.test.ts (16 passed)
  • bun test cli/src/utils/__tests__/run-state-storage.test.ts (37 passed)
  • bun test packages/agent-runtime/src/__tests__/compact-history.test.ts (31 passed)
  • packages/agent-runtime/src/__tests__/context-pruner-parity.test.ts (13 passed)
  • agents/__tests__/context-pruner.test.ts (69 passed)
  • bun run build:sdk and bun run build:freebuff both compile with exit code 0.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:triaged Classified by the community triage bot pr:needs-work Right idea, not mergeable as written

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Session state is lost after free session expires or run is interrupted

3 participants