Agent pane: a chat that outgrew its context window offers Compact, not a Retry that fails again

Merged
TE
7d ago
+307-13

First of the sustained-chat error-recovery dead ends (claim: "inventorying and fixing the top five cmux NEXT sustained-chat error recovery dead ends, starting with findings and turn retry/continue UX").

The dead end

A long chat that reaches the model's context window fails with Claude's prompt is too long, OpenAI's context_length_exceeded / "maximum context length", or Codex's "exceeds the context window". In the pane:

  • failureKind matched none of these, so the card read "Claude Code ran into a problem and stopped."
  • Retry was the only way out, and it sends the same prompt into the same history, so it fails the same way.
  • acpmux never auto-resumes a refused request (turn_errors.rs, limits_sign_in_bad_requests_and_refusals_are_never_continued), and the composer's context card has a Compact slot that nothing wires (ContextRing onCompact has no caller).

The person had to know to type /compact themselves. Long chats hit this by definition.

Change

  • failureCopy.ts: a new context-full kind, from the text or from a typed errorCode that names the context (Codex's context_window_exceeded). It is checked before capacity; a per-minute "too many tokens" limit stays rate-limited. failureRecovery returns "compact" for it, and the copy reads: "This chat is too long for {harness}'s context window. Compact it, then retry."
  • TurnRows.tsx TurnFailure: a context-full card leads with Compact (filled), with Retry after it. One click sends one /compact: the button is disabled until the send settles.
  • turnActions.ts / App.tsx: compact sends /compact through chat.send, exactly as Continue sends its prompt, so it shows as the reader's prompt and queues behind one already sent. It has the same reach checks as Continue and Restart (restartOwner / restartReaches), so it never goes to a View Only chat, a read-only pane, or the next chat during a switch.
  • Compact is offered only where the agent lists compact in its available_commands_update (offersCompact). Elsewhere, Retry stays the way out.
  • One new string, turn.failure.contextFull, in all 21 pane locales (non-English needs_review). The button reuses context.compact.

Tests

webviews/test/turn-error-card.test.tsx, 4 new tests:

  • context-full classification from five real error texts and from the typed code. A per-minute token limit stays capacity.
  • The card's order: Compact (primary), then Retry. A double click sends once.
  • Without /compact, Retry stays primary.
  • offersCompact only for the agent's own command.

Red at 64e5e7e6b3b (test only, base sources): 3 fail (the fallback test passes on base, as it should). Green at 850946c5538: bun test test/turn-error-card.test.tsx test/failure-copy-team-account.test.ts, 25 pass, 0 fail.

Observed / Not run

  • Observed:
    • The red and green runs above.
    • vp lint exit 0, vp check --no-fmt --no-lint no type errors, vp fmt --check clean on the changed files, check:catalog-keys clean, prepush-gate.py no new violations.
    • scripts/web-lint.sh's only red is vp fmt --check on src/pages/settings/channelsCard.test.tsx and src/pages/settings/store.ts. This PR doesn't touch those; it is a base finding.
  • Not run:
    • A live agent hitting a real context overflow. This was checked against the error texts acpmux's own tests use and the published OpenAI and Codex wordings.
    • The gallery compare page: this lane host is not a fleet origin, so gallery-compare.sh can't reach the gallery host. The before/after comes from this PR's gallery advisory run (agent-pane.turn-error-card: context-full, context-full-no-compact; the base has no such state, so "before" is the unknown variant's generic card).

Risk

Low. The change is limited to the failed-turn card of one failure kind. Compact sends the harness's own slash command through the existing send path, and only where the harness offers it.

Changelog

Fixed: when a long agent chat runs out of context, its error says so and offers Compact instead of a Retry that fails again.

Agent session: agent session

šŸ¤– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.