diff --git a/src/sessions/model-overrides.test.ts b/src/sessions/model-overrides.test.ts index 4029788f8940..faa7e503aa84 100644 --- a/src/sessions/model-overrides.test.ts +++ b/src/sessions/model-overrides.test.ts @@ -180,6 +180,39 @@ describe("applyModelOverrideToSessionEntry", () => { expect((entry.updatedAt ?? 0) > before).toBe(true); }); + it("sets liveModelSwitchPending when switching to default with runtime-only fields", () => { + const entry: SessionEntry = { + sessionId: "sess-96269", + updatedAt: Date.now() - 5_000, + modelProvider: "anthropic", + model: "claude-sonnet-4-6", + contextTokens: 200_000, + contextBudgetStatus: contextBudgetStatus({ + updatedAt: Date.now() - 5_000, + provider: "anthropic", + model: "claude-sonnet-4-6", + contextTokenBudget: 200_000, + }), + }; + + const result = applyModelOverrideToSessionEntry({ + entry, + selection: { + provider: "openai", + model: "gpt-5.4", + isDefault: true, + }, + markLiveSwitchPending: true, + }); + + expect(result.updated).toBe(true); + expect(entry.modelProvider).toBeUndefined(); + expect(entry.model).toBeUndefined(); + expect(entry.contextTokens).toBeUndefined(); + expect(entry.contextBudgetStatus).toBeUndefined(); + expect(entry.liveModelSwitchPending).toBe(true); + }); + it("marks non-default overrides with the provided source", () => { const entry: SessionEntry = { sessionId: "sess-5a", diff --git a/src/sessions/model-overrides.ts b/src/sessions/model-overrides.ts index 1da6b657232a..24f427d26e8d 100644 --- a/src/sessions/model-overrides.ts +++ b/src/sessions/model-overrides.ts @@ -93,6 +93,14 @@ export function applyModelOverrideToSessionEntry(params: { } } + // When switching back to the default model without override fields to delete + // (e.g. model comes from steering/fallback runtime fields), the isDefault + // branch at line 42 won't set selectionUpdated. Mark it here so that + // liveModelSwitchPending can still be set below when runtime is misaligned. + if (selection.isDefault && runtimePresent && !runtimeAligned) { + selectionUpdated = true; + } + // contextTokens are derived from the active session model. When the selected // model changes (or runtime model is already stale), the cached window can // pin the session to an older/smaller limit until another run refreshes it.