From 7c59ac9e577694b60ba062f0a6eaab8a2fb5df3c Mon Sep 17 00:00:00 2001 From: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:34:14 +0200 Subject: [PATCH] Show active models for Default LLM Expose sanitized active main and utility model metadata through the model override endpoint, then render those names in the chat model switcher even when no preset override is active. Keep the inline model names hidden on narrow screens and cover the behavior with a regression check. Refresh model names after settings save Refresh the active chat model switcher after _model_config settings are saved so changes to main and utility models appear immediately. Extend the model switcher regression check to cover the save-refresh hook. --- plugins/_model_config/api/model_override.py | 41 ++++++++++- .../model-switcher.html | 18 +++-- .../_model_config/webui/model-config-store.js | 10 +++ plugins/_model_config/webui/switcher-mixin.js | 73 ++++++++++++++----- tests/test_model_config_switcher.py | 34 +++++++++ 5 files changed, 148 insertions(+), 28 deletions(-) create mode 100644 tests/test_model_config_switcher.py diff --git a/plugins/_model_config/api/model_override.py b/plugins/_model_config/api/model_override.py index 038969edb..32e26b252 100644 --- a/plugins/_model_config/api/model_override.py +++ b/plugins/_model_config/api/model_override.py @@ -4,6 +4,23 @@ from agent import AgentContext from plugins._model_config.helpers import model_config +def _public_model_config(config: dict) -> dict | None: + if not isinstance(config, dict): + return None + provider = str(config.get("provider", "") or "").strip() + name = str(config.get("name", "") or "").strip() + if not provider and not name: + return None + return {"provider": provider, "name": name} + + +def _active_models(ctx: AgentContext) -> dict: + return { + "main": _public_model_config(model_config.get_chat_model_config(ctx.agent0)), + "utility": _public_model_config(model_config.get_utility_model_config(ctx.agent0)), + } + + class ModelOverride(ApiHandler): async def process(self, input: dict, request: Request) -> dict | Response: context_id = input.get("context_id", "") @@ -19,7 +36,11 @@ class ModelOverride(ApiHandler): if action == "get": override = ctx.get_data("chat_model_override") allowed = model_config.is_chat_override_allowed(ctx.agent0) - return {"override": override, "allowed": allowed} + return { + "override": override, + "allowed": allowed, + "active_models": _active_models(ctx), + } elif action == "set": if not model_config.is_chat_override_allowed(ctx.agent0): @@ -29,7 +50,11 @@ class ModelOverride(ApiHandler): return Response(status=400, response="Missing or invalid override config") ctx.set_data("chat_model_override", override_config) save_tmp_chat(ctx) - return {"ok": True, "override": override_config} + return { + "ok": True, + "override": override_config, + "active_models": _active_models(ctx), + } elif action == "set_preset": if not model_config.is_chat_override_allowed(ctx.agent0): @@ -45,11 +70,19 @@ class ModelOverride(ApiHandler): override_value = {"preset_name": preset_name} ctx.set_data("chat_model_override", override_value) save_tmp_chat(ctx) - return {"ok": True, "preset_name": preset_name} + return { + "ok": True, + "preset_name": preset_name, + "active_models": _active_models(ctx), + } elif action == "clear": ctx.set_data("chat_model_override", None) save_tmp_chat(ctx) - return {"ok": True, "override": None} + return { + "ok": True, + "override": None, + "active_models": _active_models(ctx), + } return Response(status=400, response=f"Unknown action: {action}") diff --git a/plugins/_model_config/extensions/webui/chat-input-progress-start/model-switcher.html b/plugins/_model_config/extensions/webui/chat-input-progress-start/model-switcher.html index 8d740171d..52953ab50 100644 --- a/plugins/_model_config/extensions/webui/chat-input-progress-start/model-switcher.html +++ b/plugins/_model_config/extensions/webui/chat-input-progress-start/model-switcher.html @@ -11,7 +11,10 @@ $store.modelConfig.refreshSwitcher($store.chats?.selected || ''), $store.modelConfig.loadAgentProfiles(), ]); + const refreshActiveModels = () => $store.modelConfig.refreshSwitcher($store.chats?.selected || ''); $watch('$store.chats.selected', v => $store.modelConfig.refreshSwitcher(v || '')); + $watch('$store.chats.selectedContext?.project?.name || \'\'' , refreshActiveModels); + $watch('$store.chats.selectedContext?.agent_profile || \'\'' , refreshActiveModels); ">