diff --git a/nanobot/bus/outbound_events.py b/nanobot/bus/outbound_events.py index ba1e864de..24e36daea 100644 --- a/nanobot/bus/outbound_events.py +++ b/nanobot/bus/outbound_events.py @@ -100,7 +100,6 @@ class TurnModelUpdatedEvent(OutboundEvent): model: str model_preset: str | None = None context_window_tokens: int | None = None - is_fallback: bool = False def outbound_message_for_event( diff --git a/nanobot/channels/websocket/runtime.py b/nanobot/channels/websocket/runtime.py index 638d6dc48..606a33d9d 100644 --- a/nanobot/channels/websocket/runtime.py +++ b/nanobot/channels/websocket/runtime.py @@ -1685,7 +1685,6 @@ class WebSocketChannel(BaseChannel): model_name=event.model, model_preset=event.model_preset, context_window_tokens=event.context_window_tokens, - is_fallback=event.is_fallback, ) return if isinstance(event, UserInputEvent): @@ -2103,7 +2102,6 @@ class WebSocketChannel(BaseChannel): model_name: Any, model_preset: Any = None, context_window_tokens: Any = None, - is_fallback: Any = False, ) -> None: """Notify one chat's subscribers which model is handling its current request.""" conns = list(self._subs.get(chat_id, ())) @@ -2117,7 +2115,6 @@ class WebSocketChannel(BaseChannel): "event": "turn_model_updated", "chat_id": chat_id, "model_name": model_name.strip(), - "is_fallback": is_fallback is True, } if isinstance(model_preset, str) and model_preset.strip(): body["model_preset"] = model_preset.strip() diff --git a/nanobot/channels/websocket/tests/test_websocket_channel.py b/nanobot/channels/websocket/tests/test_websocket_channel.py index b05c0c905..c1519afe6 100644 --- a/nanobot/channels/websocket/tests/test_websocket_channel.py +++ b/nanobot/channels/websocket/tests/test_websocket_channel.py @@ -2061,7 +2061,6 @@ async def test_send_scopes_turn_model_updates_to_the_subscribed_chat() -> None: model="deepseek/deepseek-chat", model_preset="Deep Research", context_window_tokens=128_000, - is_fallback=True, ), ) ) @@ -2073,7 +2072,6 @@ async def test_send_scopes_turn_model_updates_to_the_subscribed_chat() -> None: "model_name": "deepseek/deepseek-chat", "model_preset": "Deep Research", "context_window_tokens": 128_000, - "is_fallback": True, } chat_two.send.assert_not_awaited() diff --git a/nanobot/session/webui_turns.py b/nanobot/session/webui_turns.py index ee6d31f88..e7d9af6a3 100644 --- a/nanobot/session/webui_turns.py +++ b/nanobot/session/webui_turns.py @@ -495,7 +495,6 @@ def build_webui_fallback_model_observer(bus: MessageBus) -> FallbackModelObserve if context.runtime is not None else None ), - is_fallback=True, ), metadata=context.metadata, ) diff --git a/tests/utils/test_webui_turn_helpers.py b/tests/utils/test_webui_turn_helpers.py index bd4b86538..955d85060 100644 --- a/tests/utils/test_webui_turn_helpers.py +++ b/tests/utils/test_webui_turn_helpers.py @@ -179,7 +179,6 @@ async def test_fallback_model_is_scoped_to_its_websocket_chat() -> None: assert isinstance(outbound.event, TurnModelUpdatedEvent) assert outbound.event.model == "deepseek/deepseek-chat" assert outbound.event.model_preset == "Deep Research" - assert outbound.event.is_fallback is True @pytest.mark.asyncio @@ -219,7 +218,6 @@ async def test_admitted_runtime_publishes_chat_scoped_model_and_preset(tmp_path) assert isinstance(outbound.event, TurnModelUpdatedEvent) assert outbound.event.model == "openai-codex/gpt-5.6" assert outbound.event.model_preset == "Codex" - assert outbound.event.is_fallback is False @pytest.mark.asyncio diff --git a/webui/src/components/thread/ThreadShell.tsx b/webui/src/components/thread/ThreadShell.tsx index 75a27162e..98ecbe3d6 100644 --- a/webui/src/components/thread/ThreadShell.tsx +++ b/webui/src/components/thread/ThreadShell.tsx @@ -400,7 +400,7 @@ function toModelBadgeInfo( ); return { label, - model: toModelBadgeLabel(model), + model: model?.trim() || null, provider, providerLabel: provider ? providerDisplayLabel(settings?.providers ?? [], provider) : null, needsSetup, @@ -959,9 +959,12 @@ export function ThreadShell({ setFallbackModelName(null); return client.onChat(chatId, (event) => { if (event.event !== "turn_model_updated") return; - setFallbackModelName(event.is_fallback ? event.model_name : null); + const activeModel = event.model_name.trim(); + setFallbackModelName( + modelBadge.model && activeModel !== modelBadge.model ? activeModel : null, + ); }); - }, [chatId, client]); + }, [chatId, client, modelBadge.model]); useEffect(() => { if (!historyKey || !chatId || loading) return; @@ -1451,7 +1454,7 @@ export function ThreadShell({ : t("thread.composer.placeholderThread") } modelLabel={modelBadgeLabel} - modelDetail={modelBadge.model} + modelDetail={toModelBadgeLabel(modelBadge.model)} modelPreset={activeModelPreset} modelPresets={modelPresetOptions} onModelPresetChange={handleModelPresetChange} @@ -1498,7 +1501,7 @@ export function ThreadShell({ : t("thread.composer.placeholderHero") } modelLabel={modelBadgeLabel} - modelDetail={modelBadge.model} + modelDetail={toModelBadgeLabel(modelBadge.model)} modelPreset={activeModelPreset} modelPresets={modelPresetOptions} onModelPresetChange={handleModelPresetChange} diff --git a/webui/src/lib/types.ts b/webui/src/lib/types.ts index 9f5c2cf6a..0ca9ce4af 100644 --- a/webui/src/lib/types.ts +++ b/webui/src/lib/types.ts @@ -1313,7 +1313,6 @@ export type InboundEvent = chat_id: string; model_name: string; model_preset?: string | null; - is_fallback?: boolean; } | ({ event: "turn_end"; diff --git a/webui/src/tests/nanobot-client.test.ts b/webui/src/tests/nanobot-client.test.ts index 4a641d5e5..0112d73fb 100644 --- a/webui/src/tests/nanobot-client.test.ts +++ b/webui/src/tests/nanobot-client.test.ts @@ -1724,7 +1724,6 @@ describe("NanobotClient", () => { chat_id: "chat-a", model_name: "deepseek/deepseek-chat", model_preset: "Deep Research", - is_fallback: true, }); expect(chatHandler).toHaveBeenCalledWith({ @@ -1732,7 +1731,6 @@ describe("NanobotClient", () => { chat_id: "chat-a", model_name: "deepseek/deepseek-chat", model_preset: "Deep Research", - is_fallback: true, }); }); diff --git a/webui/src/tests/thread-shell.test.tsx b/webui/src/tests/thread-shell.test.tsx index 2492c93ee..5f5610683 100644 --- a/webui/src/tests/thread-shell.test.tsx +++ b/webui/src/tests/thread-shell.test.tsx @@ -720,7 +720,6 @@ describe("ThreadShell", () => { event: "turn_model_updated", chat_id: "fallback-model", model_name: "openai-codex/gpt-5.5", - is_fallback: false, }); }); @@ -731,7 +730,6 @@ describe("ThreadShell", () => { event: "turn_model_updated", chat_id: "fallback-model", model_name: "deepseek/deepseek-chat", - is_fallback: true, }); });