Add Claude 1M context window switching#4
Conversation
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for switching Claude Sonnet’s context window (200K vs 1M) by plumbing a new switch_context_window WebSocket message through session overrides, prompt dispatch, and the Claude SDK adapter model ID selection.
Changes:
- Extend discovery/capabilities to expose
contextWindowOptionsfor Claude Sonnet models and capture Claude accountsubscriptionTypeto pick defaults. - Add session-level context-window overrides and route
switch_context_windowmessages through a new handler. - Introduce a frontend ContextWindowSelector badge/dropdown plus E2E/unit/storybook coverage; update Claude adapter to apply
[1m]model IDs and switch mid-session viaquery.setModel.
Reviewed changes
Copilot reviewed 40 out of 48 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/stores/discovery-store.test.ts | Adds unit tests for context-window discovery store state/handlers. |
| test/unit/session/session-overrides.test.ts | Tests new context-window fields and per-session override behavior. |
| test/unit/session/session-overrides-effect.test.ts | Tests Effect-based overrides state for context windows. |
| test/unit/server/ws-router.stateful.test.ts | Updates routed message type list to include switch_context_window. |
| test/unit/server/ws-router.pbt.test.ts | Updates PBT message-type generator and drift-guard counts. |
| test/unit/server/ws-message-schemas.test.ts | Extends schema coverage tests for switch_context_window. |
| test/unit/provider/claude/claude-capabilities-probe.test.ts | Adds tests for subscriptionType + contextWindowOptions defaults. |
| test/unit/provider/claude/claude-adapter-send-turn.test.ts | Verifies [1m] suffix behavior and mid-session model switching. |
| test/unit/handlers/effect-handlers.test.ts | Adds handler tests for model_list contextWindowOptions + switching behavior. |
| test/unit/handlers/dispatch-effect.test.ts | Updates handler override mocks for context-window fields. |
| test/unit/bridges/client-init.test.ts | Verifies model_list includes contextWindowOptions on connect. |
| test/helpers/mock-factories.ts | Extends override mocks with context-window fields/methods. |
| test/e2e/specs/context-window-selector.spec.ts | New E2E coverage for context-window badge/dropdown and WS messages. |
| test/e2e/playwright-variant.config.ts | Runs the new context-window E2E spec in the variant config. |
| test/e2e/fixtures/mockup-state.ts | Adds mock init fixtures for context-window selector scenarios. |
| src/lib/shared-types.ts | Adds shared ContextWindowOption, schemas, and relay message type. |
| src/lib/session/session-overrides.ts | Adds context-window fields + getters/setters to session overrides. |
| src/lib/server/ws-router.ts | Adds switch_context_window to incoming message routing types. |
| src/lib/relay/poller-pre-filter.ts | Treats context_window_info as metadata (non-content) events. |
| src/lib/provider/types.ts | Adds provider-level context-window options and send-turn input field. |
| src/lib/provider/claude/types.ts | Tracks currentApiModelId for mid-session model changes. |
| src/lib/provider/claude/claude-capabilities-probe.ts | Computes contextWindowOptions and defaults based on subscription. |
| src/lib/provider/claude/claude-adapter.ts | Applies [1m] model IDs for Sonnet + switches via setModel. |
| src/lib/handlers/prompt.ts | Passes contextWindow override through to engine send_turn. |
| src/lib/handlers/payloads.ts | Adds switch_context_window payload typing. |
| src/lib/handlers/payload-schemas.ts | Adds schema validation for switch_context_window payloads. |
| src/lib/handlers/model.ts | Includes contextWindowOptions in Claude model_list entries. |
| src/lib/handlers/index.ts | Registers the new switch_context_window handler. |
| src/lib/handlers/context-window.ts | New handler to validate/apply context-window overrides + echo state. |
| src/lib/frontend/types.ts | Re-exports ContextWindowOption to frontend type surface. |
| src/lib/frontend/stores/ws-dispatch.ts | Routes context_window_info messages into the discovery store. |
| src/lib/frontend/stores/discovery.svelte.ts | Adds context-window discovery state + handler/getter. |
| src/lib/frontend/components/model/ModelSelector.svelte | Renders ContextWindowSelector alongside variant badge with mutual exclusion. |
| src/lib/frontend/components/model/ModelSelector.stories.ts | Resets new discovery state fields in story setup. |
| src/lib/frontend/components/model/ContextWindowSelector.svelte | New UI badge/dropdown for context window selection. |
| src/lib/frontend/components/model/ContextWindowSelector.stories.ts | New storybook coverage for defaults/selection/open state. |
| src/lib/frontend/components/debug/DebugPanel.svelte | Shows context_window_info messages in debug panel. |
| src/lib/effect/ws-message-schemas.ts | Adds Incoming WS schema for switch_context_window. |
| src/lib/effect/session-overrides-state.ts | Adds Effect-based default/per-session context-window state. |
| src/lib/bridges/client-init.ts | Adds contextWindowOptions into Claude entries in initial model_list. |
Comments suppressed due to low confidence (2)
src/lib/bridges/client-init.ts:402
- The frontend’s ContextWindowSelector only renders when
discoveryState.availableContextWindowOptionsis populated via acontext_window_infomessage, but client init currently never sendscontext_window_info(onlyvariant_info). As a result the context-window badge/dropdown won’t appear on initial connect, even thoughmodel_listnow includescontextWindowOptions. Consider emitting an initialcontext_window_infohere (similar to the existingvariant_infoblock) using the active model + current override/default, so the UI has options immediately.
models: claudeCaps.models.map((m) => ({
id: m.id,
name: m.name,
provider: "claude",
...(m.limit ? { limit: m.limit } : {}),
...(m.variants && Object.keys(m.variants).length > 0
? { variants: Object.keys(m.variants) }
: {}),
...(m.contextWindowOptions && m.contextWindowOptions.length > 0
? { contextWindowOptions: m.contextWindowOptions }
: {}),
})),
});
wsHandler.sendTo(clientId, { type: "model_list", providers });
}
} catch {
// Claude adapter may not be available — skip silently
}
}
// Send variant info — current thinking level and available variants
// for the active model (per-session when available, global fallback)
const currentVariant = activeId
? overrides.getVariant(activeId)
: overrides.defaultVariant;
const activeModelId = activeId
? overrides.getModel(activeId)?.modelID
: overrides.defaultModel?.modelID;
let availableVariants: string[] = [];
if (activeModelId) {
for (const p of providers) {
const model = p.models.find(
(m: { id: string; variants?: string[] }) => m.id === activeModelId,
);
if (model?.variants) {
availableVariants = model.variants;
break;
}
}
}
wsHandler.sendTo(clientId, {
type: "variant_info",
variant: currentVariant,
variants: availableVariants,
});
src/lib/handlers/model.ts:110
handleGetModelsnow includescontextWindowOptionsin themodel_listpayload, but it still doesn’t send anycontext_window_infomessage to establish the current selection + options (unlikevariant_info). Since the frontend store populatesavailableContextWindowOptionsfromcontext_window_info, the context-window selector won’t become visible afterget_modelsunless something else triggers that message. Suggest sending acontext_window_infoalongsidevariant_infousing the active model and overrides/default context window.
models: engineResult.right.models.map((m) => ({
id: m.id,
name: m.name,
provider: "claude",
...(m.limit ? { limit: m.limit } : {}),
...(m.variants && Object.keys(m.variants).length > 0
? { variants: Object.keys(m.variants) }
: {}),
...(m.contextWindowOptions && m.contextWindowOptions.length > 0
? { contextWindowOptions: m.contextWindowOptions }
: {}),
})),
});
wsHandler.sendTo(clientId, { type: "model_list", providers });
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Also addressed the two suppressed Copilot notes in 91d5f72: client init now sends |
Summary
[1m]model IDs for Sonnet when selected, plus frontend selector, debug display, E2E, unit, and visual coverage.Test Plan
Note
.github/pull_request_template.mdis not present in this checkout or onmain; this body follows the repo's summary/test-plan shape from the implemented diff.