Commit 1fb196c
authored
🤖 fix: respect compaction model preference on context exceeded (#1677)
Fixes the context-exceeded "Compact & retry" suggestion to respect the
user's configured **Compaction Model** (Settings → Models → Compaction
Model) instead of always picking the largest-context configured model.
Behavior:
- First context_exceeded: suggest the configured compaction model when
it's usable.
- Compaction recovery (retrying a failed compaction request): fall back
to a higher-context model suggestion.
Tests:
- Updated UI integration coverage to assert the preferred compaction
model is suggested.
Local validation:
- `make fmt-check`, `make lint`, `make typecheck`
- `make static-check` fails locally due to Docker daemon unavailable
(zizmor).
---
<details>
<summary>đź“‹ Implementation Plan</summary>
# Fix: context-exceeded compaction ignores configured compaction model
## What’s happening
- The “Context window exceeded” banner is rendered by `RetryBarrier`.
- For that banner, Mux computes a **best-effort compaction suggestion**
via `getHigherContextCompactionSuggestion()`.
- That function scans `KNOWN_MODELS` and picks the **configured model
with the largest `max_input_tokens`**.
- If xAI is configured (or Grok is enabled via Mux Gateway), **Grok
wins** because it has the biggest context window.
- This path **does not consult** the Settings value stored under
`preferredCompactionModel` (used by `/compact`).
## Goal
When a stream fails with `context_exceeded`, the “Compact & retry” flow
should:
1) Prefer the user’s configured **Compaction Model** (Settings → Models
→ Compaction Model).
2) Fall back to the current “pick a higher-context model” behavior only
when needed (e.g., the preferred model isn’t usable, or compaction fails
and we’re in a recovery retry).
---
## Approach A (recommended): Prefer settings compaction model, fallback
to higher-context on failure
**Net LoC (product code): ~50–90**
### 1) Plumb the preferred compaction model into `RetryBarrier`
- File: `src/browser/components/Messages/ChatBarrier/RetryBarrier.tsx`
- Read `PREFERRED_COMPACTION_MODEL_KEY` using
`usePersistedState<string>(..., "", { listener: true })`.
- Change `compactionSuggestion` selection to be context-aware:
- **If we are retrying a failed compaction request**
(`triggerUserMessage.compactionRequest` exists):
- Keep current behavior: call `getHigherContextCompactionSuggestion({
currentModel: compactionTargetModel, providersConfig })`.
- **Otherwise (first time we hit context_exceeded)**:
- If `preferredCompactionModel` is set and “usable”, build a suggestion
for it and use it.
- Else, fall back to `getHigherContextCompactionSuggestion()`.
### 2) Add a small helper to “materialize” a `CompactionSuggestion` for
an explicit model
- File: `src/browser/utils/compaction/suggestion.ts`
- Add something like:
- `getExplicitCompactionSuggestion({ modelId, providersConfig }):
CompactionSuggestion | null`
- Responsibilities:
- Validate modelId is non-empty.
- Determine whether the model is usable:
- Provider has creds in `providersConfig`, OR
- `toGatewayModel(modelId)` returns a `mux-gateway:` model (gateway
enabled for that model).
- Populate `displayName` + `maxInputTokens` via `getModelStats()`.
- Use a known alias (`KNOWN_MODELS`) for `modelArg` when possible;
otherwise use the raw `modelId`.
### 3) Fix the banner copy so it’s accurate
- File: `src/browser/components/Messages/ChatBarrier/RetryBarrier.tsx`
- Today it always says “to unblock you with a higher-context model”.
- Update copy to reflect the chosen source:
- If using the user’s configured compaction model: “We’ll compact with
your configured compaction model …”
- If using fallback higher-context suggestion: keep current wording.
### 4) Keep failure behavior safe
- Ensure that if the preferred compaction model *can’t* compact (e.g.,
still hits `context_exceeded`), the existing “compaction recovery flow”
continues to work:
- Because the previous compaction request becomes
`triggerUserMessage.compactionRequest`, the next banner should naturally
suggest a larger-context model.
### 5) Update / add tests
- Update/add UI integration tests to cover both cases:
1) **Preferred model set** → banner suggests that model (not Grok).
2) **Preferred model empty** + xAI configured → banner suggests Grok
(existing behavior).
- Likely file:
- `tests/ui/contextExceededCompactionSuggestion.integration.test.ts`
---
## Approach B (optional): Add a settings toggle for “Context exceeded
recovery model”
**Net LoC (product code): ~120–200**
- Add a dedicated setting:
- “When context is exceeded: [Use my compaction model] / [Use
highest-context model]”
- Default to “Use my compaction model” to match user expectation, but
keep an explicit escape hatch.
<details>
<summary>Why this is heavier</summary>
It requires new storage keys, Settings UI, and more UX
copy/documentation. Approach A achieves the same behavior without adding
another preference knob.
</details>
---
## Validation checklist
- Repro: hit `context_exceeded` in a workspace that has xAI configured.
- With `preferredCompactionModel` set to a non-xAI model:
- Banner suggests the preferred model.
- Clicking “Compact & retry” runs compaction using that model.
- If compaction fails again with `context_exceeded`:
- Banner switches to a higher-context suggestion (e.g., Grok) for
recovery.
- Run:
- `make typecheck`
- Updated UI integration test(s)
</details>
---
_Generated with `mux` • Model: `openai:gpt-5.2` • Thinking: `high` •
Cost: $3.85_
---------
Signed-off-by: Thomas Kosiewski <tk@coder.com>1 parent c7dc49a commit 1fb196c
File tree
4 files changed
+245
-48
lines changed- src/browser
- components/Messages/ChatBarrier
- utils/compaction
- tests/ui
4 files changed
+245
-48
lines changedSome generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments