Skip to content

fix(coding-agent): reopen over-budget resumed sessions - #1430

Open
code-yeongyu wants to merge 3 commits into
mainfrom
fix/resume-admission-recovery
Open

fix(coding-agent): reopen over-budget resumed sessions#1430
code-yeongyu wants to merge 3 commits into
mainfrom
fix/resume-admission-recovery

Conversation

@code-yeongyu

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

Copy link
Copy Markdown
Owner

Incident

OmO Desktop thread a9a178a0-47c4-4b55-a94b-64b6c7e0f565 could not be reopened. Every thread.turn.start failed because the restored transcript was already 41,249 tokens over the Astra resume requirement, and the desktop exhausted its retries.

Root cause

createAgentSession called session.assertModelUsable(..., admission: "resume") before the compaction extension was wired. The budget guard correctly refused the next provider prompt, but the session itself became unopenable, so no compaction could run.

This is the third fix in the family: senpi #1425 made overflow recovery independent of compaction.enabled, and #1427 shipped the OpenAI input caps. This PR closes the remaining hole: a session that ALREADY exceeded the window can never be reopened.

Change

  1. Resume admission tries the newest valid cut-point suffixes and appends a deterministic no-LLM resume-admission compaction entry through SessionManager.appendCompaction. The JSONL transcript is preserved verbatim, and tool-call/tool-result pairs are not split.
  2. The admission summary and retained suffix are projected against the assembled prompt, tools, reserves, and safety margin. It preserves as much context as fits.
  3. If the minimal system/tools/reserves plus newest safe suffix cannot fit, the original ModelUsabilityBudgetError is rethrown unchanged.
  4. A successful slice emits one structured resume_admission_slice session-log line with dropped-entry count, tokens before/after, model, and shortfall.
  5. The first prompt after a sliced resume is routed through the existing required/pre-prompt compaction path before the user prompt can reach the provider.

Admission runs before extension wiring, so the summary is an equivalent minimal deterministic checkpoint rather than importing the extension runtime's deterministic-fallback implementation. The changelog records this boundary explicitly.

Verification

  • RED (remote box, before implementation): cd packages/coding-agent && bunx vitest --run test/suite/resume-admission-recovery.test.ts failed at the old resume admission guard with ModelUsabilityBudgetError and the missing accessor.
  • GREEN (remote box): cd packages/coding-agent && bunx vitest --run test/suite/resume-admission-recovery.test.ts — 1 file, 2 tests passed.
  • Adjacent suites (remote box): cd packages/coding-agent && bunx vitest --run test/suite/model-usability-budget.test.ts test/suite/model-shrink-speculative-warmstart.test.ts test/suite/model-usability-review.test.ts — 3 files, 17 tests passed.
  • Biome passed on all changed source/test files, locally and on the remote box.
  • TypeScript was attempted, but the repository baseline on the remote box cannot resolve workspace packages and reports existing errors across the package; local TypeScript also lacks the installed Node type definitions. No TypeScript result is claimed as green.
  • All Vitest runs were remote through /tmp/ulw-sidecar-20260907/box-test.sh; no tests were run locally.

The release window is live. Do not merge until the release window lifts.


Summary by cubic

Fixes restored sessions that exceed the model's token budget so they can be reopened instead of failing every thread.turn.start. Do not merge until the release window lifts.

Bug Fixes

  • Resume admission now slices the over-budget transcript at the newest valid cut-point and appends a deterministic no-LLM resume-admission compaction entry.
  • The JSONL transcript stays verbatim; only the in-memory context shrinks, and tool-call/tool-result pairs are not split.
  • The first prompt after a sliced resume runs the existing required-compaction path before reaching the provider.
  • If even the minimal context plus newest safe suffix cannot fit, the original ModelUsabilityBudgetError is rethrown unchanged.

Written for commit 962d631. Summary will update on new commits.

Review in 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