refactor(ui): delete the permanently no-op onModelChanged seam (#124009)

state.onModelChanged has been () => undefined since the original Control
UI refactor (65e12328aa) and was never overridden; three call sites
awaited a decoy. Effective-tools previews key their requests on the model
override, so the post-switch refresh only needs a re-render, and the
model-switch reconcile already awaits the canonical session-list refresh.
Tests that used the seam as a deferral hook now hold the list refresh
open instead — the barrier the production code actually awaits.
This commit is contained in:
Peter Steinberger
2026-08-14 21:58:42 -07:00
committed by GitHub
parent 124847928d
commit 7ac49e280e
5 changed files with 8 additions and 21 deletions
+2 -1
View File
@@ -381,8 +381,9 @@ export abstract class ChatPaneLifecycle extends ChatPaneSessionCreation {
pageState.confirmConversationReset = () => this.confirmConversationReset();
pageState.exportCurrentChat = () =>
exportChatMarkdown(pageState.chatMessages, pageState.assistantName);
// Effective-tools previews key their requests on the model override, so a
// post-switch refresh only needs a re-render.
pageState.refreshCurrentSessionTools = async () => {
await pageState.onModelChanged?.();
pageState.requestUpdate?.();
};
pageState.refreshCurrentChat = async () => {
-2
View File
@@ -43,7 +43,6 @@ type ChatModelSettingsHost = ChatSessionRefreshHost & {
chatModelCatalog: Parameters<typeof resolveChatModelOverrideValue>[0]["chatModelCatalog"];
chatModelSwitchPromises?: Record<string, Promise<boolean>>;
chatThinkingLevel: string | null;
onModelChanged?: () => unknown;
sessions: SessionCapability;
sessionsResult?: SessionsListResult | null;
requestUpdate?: () => void;
@@ -444,7 +443,6 @@ export async function switchChatModel(
...scopedAgentParamsForSession(host, targetSessionKey),
ownsModelOverride,
reconcile: async () => {
await host.onModelChanged?.();
await refreshCurrentChatSessionList(host);
},
},
-1
View File
@@ -120,7 +120,6 @@ export type ChatPageHost = ChatHost &
imageLightboxRequestVersion: number;
querySelector: (selectors: string) => Element | null;
renderLifecycle: RenderLifecycle;
onModelChanged: () => Promise<void> | void;
resetToolStream: () => void;
resetChatScroll: () => void;
resetChatInputHistoryNavigation: () => void;
-1
View File
@@ -268,7 +268,6 @@ export function createPageState(
} as unknown as ChatPageHost;
state.resetToolStream = () => resetToolStream(state as never);
state.onModelChanged = () => undefined;
state.resetChatInputHistoryNavigation = () => resetChatInputHistoryNavigation(state);
state.resetChatScroll = () => resetChatScroll(state);
state.scrollToBottom = (options) => {
+6 -16
View File
@@ -76,14 +76,6 @@ function registerChatAttachmentPayload(
return attachment;
}
async function refreshVisibleToolsEffectiveForCurrentSessionForTest(state: ChatHeaderTestState) {
const agentId = state.agentsSelectedId ?? "main";
const sessionKey = state.sessionKey;
await state.client?.request("tools.effective", { agentId, sessionKey });
const override = state.sessions.state.modelOverrides[sessionKey];
state.toolsEffectiveResultKey = `${agentId}:${sessionKey}:model=${override ?? "(default)"}`;
state.toolsEffectiveResult = { agentId, profile: "coding", groups: [] };
}
const buildChatItemsMock = vi.fn(
(props: {
messages: unknown[];
@@ -255,7 +247,6 @@ type ChatHeaderTestState = {
toolsEffectiveResult: unknown;
applySettings(patch: Partial<UiSettings>): void;
loadAssistantIdentity(): void;
onModelChanged(): void | Promise<void>;
resetChatInputHistoryNavigation(): void;
resetChatScroll(): void;
resetToolStream(): void;
@@ -501,8 +492,6 @@ function createChatHeaderState(
resetChatInputHistoryNavigation: vi.fn(),
resetToolStream: vi.fn(),
resetChatScroll: vi.fn(),
onModelChanged: (): Promise<void> =>
refreshVisibleToolsEffectiveForCurrentSessionForTest(state),
};
sessions.subscribe((next) => {
state.sessionsResult = next.result;
@@ -6357,7 +6346,12 @@ describe("chat model controls", () => {
return patchResult;
},
),
refresh: async () => {},
// The list refresh is the reconcile step switchChatModel awaits; holding
// it open models a slow reconciliation inside the settings lane.
refresh: async () => {
reconciliationStarted.resolve();
await releaseReconciliation.promise;
},
setModelOverride: vi.fn(),
patchRowLocal: vi.fn(),
};
@@ -6379,10 +6373,6 @@ describe("chat model controls", () => {
thinkingLevel: "high",
},
]),
onModelChanged: async () => {
reconciliationStarted.resolve();
await releaseReconciliation.promise;
},
} as unknown as Parameters<typeof switchChatModel>[0];
const modelSwitch = switchChatModel(host, "openai/gpt-5.6-sol");