Skip to content

Add Claude 1M context window switching#4

Merged
dibstern merged 7 commits into
mainfrom
ds/claude-subscription-1m-context
May 11, 2026
Merged

Add Claude 1M context window switching#4
dibstern merged 7 commits into
mainfrom
ds/claude-subscription-1m-context

Conversation

@dibstern
Copy link
Copy Markdown
Owner

Summary

  • Capture Claude subscription type and expose Sonnet context window options through model discovery.
  • Add session-level context window switching from WebSocket handler through session overrides and prompt dispatch.
  • Apply Claude SDK [1m] model IDs for Sonnet when selected, plus frontend selector, debug display, E2E, unit, and visual coverage.

Test Plan

  • pnpm check
  • pnpm lint
  • pnpm test:unit
  • pnpm build:frontend && pnpm exec playwright test --config test/e2e/playwright-variant.config.ts
  • pnpm storybook:build
  • pnpm exec playwright test --config test/visual/playwright.config.ts --grep "Model/ContextWindowSelector"
  • pnpm test:all

Note

  • .github/pull_request_template.md is not present in this checkout or on main; this body follows the repo's summary/test-plan shape from the implemented diff.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 contextWindowOptions for Claude Sonnet models and capture Claude account subscriptionType to pick defaults.
  • Add session-level context-window overrides and route switch_context_window messages 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 via query.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.availableContextWindowOptions is populated via a context_window_info message, but client init currently never sends context_window_info (only variant_info). As a result the context-window badge/dropdown won’t appear on initial connect, even though model_list now includes contextWindowOptions. Consider emitting an initial context_window_info here (similar to the existing variant_info block) 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

  • handleGetModels now includes contextWindowOptions in the model_list payload, but it still doesn’t send any context_window_info message to establish the current selection + options (unlike variant_info). Since the frontend store populates availableContextWindowOptions from context_window_info, the context-window selector won’t become visible after get_models unless something else triggers that message. Suggest sending a context_window_info alongside variant_info using 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.

Comment thread src/lib/frontend/components/model/ContextWindowSelector.svelte
Comment thread src/lib/shared-types.ts Outdated
@dibstern
Copy link
Copy Markdown
Owner Author

Also addressed the two suppressed Copilot notes in 91d5f72: client init now sends context_window_info after model_list, and handleGetModels sends the same state using the active model plus the current context-window override/default. Covered by the new unit tests in client-init.test.ts and effect-handlers.test.ts.

@dibstern dibstern merged commit 9e9bc42 into main May 11, 2026
1 check passed
@dibstern dibstern deleted the ds/claude-subscription-1m-context branch May 11, 2026 11:07
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.

2 participants