Revert "Show active models for Default LLM"
This reverts commit 7c59ac9e577694b60ba062f0a6eaab8a2fb5df3c.
Alessandro committed
May 2, 2026 at 14:12 UTC
aea1718f9f27a541145a03d87cbc0b9f2d095019
5 files changed
+28
-148
plugins/_model_config/api/model_override.py
+4
-37
@@ -4,23 +4,6 @@ from agent import AgentContext
4
from plugins._model_config.helpers import model_config
5
6
7
-def _public_model_config(config: dict) -> dict | None:
8
- if not isinstance(config, dict):
9
- return None
10
- provider = str(config.get("provider", "") or "").strip()
11
- name = str(config.get("name", "") or "").strip()
12
- if not provider and not name:
13
- return None
14
- return {"provider": provider, "name": name}
15
-
16
-
17
-def _active_models(ctx: AgentContext) -> dict:
18
- return {
19
- "main": _public_model_config(model_config.get_chat_model_config(ctx.agent0)),
20
- "utility": _public_model_config(model_config.get_utility_model_config(ctx.agent0)),
21
- }
22
-
23
-
7
class ModelOverride(ApiHandler):
8
async def process(self, input: dict, request: Request) -> dict | Response:
9
context_id = input.get("context_id", "")
@@ -36,11 +19,7 @@ class ModelOverride(ApiHandler):
19
if action == "get":
20
override = ctx.get_data("chat_model_override")
21
allowed = model_config.is_chat_override_allowed(ctx.agent0)
39
- return {
40
- "override": override,
41
- "allowed": allowed,
42
- "active_models": _active_models(ctx),
43
- }
22
+ return {"override": override, "allowed": allowed}
23
24
elif action == "set":
25
if not model_config.is_chat_override_allowed(ctx.agent0):
@@ -50,11 +29,7 @@ class ModelOverride(ApiHandler):
29
return Response(status=400, response="Missing or invalid override config")
30
ctx.set_data("chat_model_override", override_config)
31
save_tmp_chat(ctx)
53
- return {
54
- "ok": True,
55
- "override": override_config,
56
- "active_models": _active_models(ctx),
57
- }
32
+ return {"ok": True, "override": override_config}
33
34
elif action == "set_preset":
35
if not model_config.is_chat_override_allowed(ctx.agent0):
@@ -70,19 +45,11 @@ class ModelOverride(ApiHandler):
45
override_value = {"preset_name": preset_name}
46
ctx.set_data("chat_model_override", override_value)
47
save_tmp_chat(ctx)
73
- return {
74
- "ok": True,
75
- "preset_name": preset_name,
76
- "active_models": _active_models(ctx),
77
- }
48
+ return {"ok": True, "preset_name": preset_name}
49
50
elif action == "clear":
51
ctx.set_data("chat_model_override", None)
52
save_tmp_chat(ctx)
82
- return {
83
- "ok": True,
84
- "override": None,
85
- "active_models": _active_models(ctx),
86
- }
53
+ return {"ok": True, "override": None}
54
55
return Response(status=400, response=f"Unknown action: {action}")
plugins/_model_config/extensions/webui/chat-input-progress-start/model-switcher.html
+7
-11
@@ -11,10 +11,7 @@
11
$store.modelConfig.refreshSwitcher($store.chats?.selected || ''),
12
$store.modelConfig.loadAgentProfiles(),
13
]);
14
- const refreshActiveModels = () => $store.modelConfig.refreshSwitcher($store.chats?.selected || '');
14
$watch('$store.chats.selected', v => $store.modelConfig.refreshSwitcher(v || ''));
16
- $watch('$store.chats.selectedContext?.project?.name || \'\'' , refreshActiveModels);
17
- $watch('$store.chats.selectedContext?.agent_profile || \'\'' , refreshActiveModels);
15
">
16
<template x-if="($store.modelConfig.switcherAllowed && !$store.modelConfig.switcherLoading) || $store.chats?.selectedContext?.agent_profile">
17
<div class="model-switcher-container">
@@ -30,18 +27,18 @@
27
x-text="showDropdown ? 'expand_less' : 'expand_more'"></span>
28
</button>
29
33
- <!-- Inline active model pills -->
34
- <template x-if="$store.modelConfig.hasActiveModelNames()">
30
+ <!-- Inline active model pills (shown when a preset is active) -->
31
+ <template x-if="$store.modelConfig.switcherOverride">
32
<div class="model-switcher-active-pills">
36
- <template x-if="$store.modelConfig.getActiveModels().main?.name">
33
+ <template x-if="$store.modelConfig.getActiveModels().main">
34
<div class="model-pill">
38
- <span class="model-pill-role">Main:</span>
35
+ <span class="model-pill-role">Main</span>
36
<span class="model-pill-name" x-text="$store.modelConfig.getActiveModels().main.name"></span>
37
</div>
38
</template>
42
- <template x-if="$store.modelConfig.getActiveModels().utility?.name">
39
+ <template x-if="$store.modelConfig.getActiveModels().utility">
40
<div class="model-pill">
44
- <span class="model-pill-role">Utility:</span>
41
+ <span class="model-pill-role">Util</span>
42
<span class="model-pill-name" x-text="$store.modelConfig.getActiveModels().utility.name"></span>
43
</div>
44
</template>
@@ -259,7 +256,6 @@
256
font-size: 0.68rem;
257
white-space: nowrap;
258
min-width: 0;
262
- max-width: 240px;
259
overflow: hidden;
260
}
261
.model-pill-role {
@@ -400,7 +396,7 @@
396
}
397
398
/* Responsive: hide pills on narrow screens */
403
- @media (max-width: 760px) {
399
+ @media (max-width: 600px) {
400
.model-switcher-active-pills {
401
display: none;
402
}
plugins/_model_config/webui/model-config-store.js
-10
@@ -200,7 +200,6 @@ export const store = createStore("modelConfig", {
200
/**
201
* Install save and reset hooks on the plugin settings context.
202
* - Save: persists dirty API keys before the normal config save.
203
- * - Save: refreshes active chat model names after the config is persisted.
203
* - Reset: reloads global presets when settings are reset to defaults.
204
*/
205
installSettingsHooks(context, config) {
@@ -216,9 +215,6 @@ export const store = createStore("modelConfig", {
215
return;
216
}
217
await originalSave();
219
- if (!context.error) {
220
- await this.refreshActiveChatModels();
221
- }
218
};
219
220
const originalReset = context.resetToDefault.bind(context);
@@ -233,12 +229,6 @@ export const store = createStore("modelConfig", {
229
context.__modelConfigHooksInstalled = true;
230
},
231
236
- async refreshActiveChatModels() {
237
- const contextId = window.Alpine?.store("chats")?.selected || "";
238
- if (!contextId) return;
239
- await this.refreshSwitcher(contextId);
240
- },
241
-
232
// Model search
233
getProviders(key) {
234
return key === 'embedding_model' ? this.embeddingProviders : this.chatProviders;
plugins/_model_config/webui/switcher-mixin.js
+17
-56
@@ -9,7 +9,6 @@ export const switcherState = {
9
switcherAllowed: false,
10
switcherOverride: null,
11
switcherPresets: [],
12
- switcherActiveModels: { main: null, utility: null },
12
switcherLoading: true,
13
agentProfiles: [],
14
agentProfilesLoading: true,
@@ -18,33 +17,6 @@ export const switcherState = {
17
};
18
19
export const switcherMethods = {
21
- normalizeActiveModel(model) {
22
- if (!model || typeof model !== "object") return null;
23
- const provider = String(model.provider || "").trim();
24
- const name = String(model.name || "").trim();
25
- if (!provider && !name) return null;
26
- return { provider, name };
27
- },
28
-
29
- normalizeActiveModels(models = {}) {
30
- return {
31
- main: this.normalizeActiveModel(models.main),
32
- utility: this.normalizeActiveModel(models.utility),
33
- };
34
- },
35
-
36
- hasModelNames(models) {
37
- return !!(models?.main?.name || models?.utility?.name);
38
- },
39
-
40
- modelsFromPreset(preset) {
41
- if (!preset) return { main: null, utility: null };
42
- return this.normalizeActiveModels({
43
- main: preset.chat,
44
- utility: preset.utility,
45
- });
46
- },
47
-
20
async loadAgentProfiles(force = false) {
21
if (!force && this.agentProfiles.length > 0 && this.agentProfileSettings) return this.agentProfiles;
22
this.agentProfilesLoading = true;
@@ -72,7 +44,7 @@ export const switcherMethods = {
44
},
45
46
async loadSwitcherState(contextId) {
75
- const result = { allowed: false, presets: [], override: null, activeModels: { main: null, utility: null } };
47
+ const result = { allowed: false, presets: [], override: null };
48
try {
49
await this.loadGlobalPresets();
50
result.presets = this.globalPresets.filter(p => p.name);
@@ -85,7 +57,6 @@ export const switcherMethods = {
57
const overData = await overRes.json();
58
result.allowed = !!overData.allowed;
59
result.override = overData.override || null;
88
- result.activeModels = this.normalizeActiveModels(overData.active_models || {});
60
}
61
} catch (e) {
62
console.error("Model switcher load failed:", e);
@@ -100,10 +71,10 @@ export const switcherMethods = {
71
headers: { "Content-Type": "application/json" },
72
body: JSON.stringify({ action: "set_preset", context_id: contextId, preset_name: presetName }),
73
});
103
- return await res.json();
74
+ return !!(await res.json()).ok;
75
} catch (e) {
76
console.error("Failed to set preset override:", e);
106
- return { ok: false };
77
+ return false;
78
}
79
},
80
@@ -114,10 +85,10 @@ export const switcherMethods = {
85
headers: { "Content-Type": "application/json" },
86
body: JSON.stringify({ action: "clear", context_id: contextId }),
87
});
117
- return await res.json();
88
+ return !!(await res.json()).ok;
89
} catch (e) {
90
console.error("Failed to clear override:", e);
120
- return { ok: false };
91
+ return false;
92
}
93
},
94
@@ -223,7 +194,6 @@ export const switcherMethods = {
194
this.switcherAllowed = state.allowed;
195
this.switcherPresets = state.presets;
196
this.switcherOverride = state.override;
226
- this.switcherActiveModels = state.activeModels;
197
} catch (e) {
198
console.error('Model switcher refresh failed:', e);
199
} finally {
@@ -232,24 +202,15 @@ export const switcherMethods = {
202
},
203
204
async selectPresetSwitch(contextId, presetName) {
235
- const data = await this.setPresetOverride(contextId, presetName);
236
- if (data?.ok) {
237
- this.switcherOverride = { preset_name: data.preset_name || presetName };
238
- const activeModels = this.normalizeActiveModels(data.active_models || {});
239
- this.switcherActiveModels = this.hasModelNames(activeModels)
240
- ? activeModels
241
- : this.modelsFromPreset(this.switcherPresets.find(p => p.name === presetName));
242
- }
243
- return !!data?.ok;
205
+ const ok = await this.setPresetOverride(contextId, presetName);
206
+ if (ok) this.switcherOverride = { preset_name: presetName };
207
+ return ok;
208
},
209
210
async clearOverrideSwitch(contextId) {
247
- const data = await this.clearOverride(contextId);
248
- if (data?.ok) {
249
- this.switcherOverride = null;
250
- this.switcherActiveModels = this.normalizeActiveModels(data.active_models || {});
251
- }
252
- return !!data?.ok;
211
+ const ok = await this.clearOverride(contextId);
212
+ if (ok) this.switcherOverride = null;
213
+ return ok;
214
},
215
216
getSwitcherLabel() {
@@ -265,11 +226,11 @@ export const switcherMethods = {
226
},
227
228
getActiveModels() {
268
- if (this.hasModelNames(this.switcherActiveModels)) return this.switcherActiveModels;
269
- return this.modelsFromPreset(this.getActivePreset());
270
- },
271
-
272
- hasActiveModelNames() {
273
- return this.hasModelNames(this.getActiveModels());
229
+ const preset = this.getActivePreset();
230
+ if (!preset) return { main: null, utility: null };
231
+ return {
232
+ main: preset.chat?.name ? { provider: preset.chat.provider, name: preset.chat.name } : null,
233
+ utility: preset.utility?.name ? { provider: preset.utility.provider, name: preset.utility.name } : null,
234
+ };
235
},
236
};
tests/test_model_config_switcher.py
deleted
-34
@@ -1,34 +0,0 @@
1
-from pathlib import Path
2
-
3
-
4
-PROJECT_ROOT = Path(__file__).resolve().parents[1]
5
-
6
-
7
-def test_model_switcher_surfaces_default_active_models():
8
- switcher = (
9
- PROJECT_ROOT / "plugins" / "_model_config" / "webui" / "switcher-mixin.js"
10
- ).read_text(encoding="utf-8")
11
- store = (
12
- PROJECT_ROOT / "plugins" / "_model_config" / "webui" / "model-config-store.js"
13
- ).read_text(encoding="utf-8")
14
- template = (
15
- PROJECT_ROOT
16
- / "plugins"
17
- / "_model_config"
18
- / "extensions"
19
- / "webui"
20
- / "chat-input-progress-start"
21
- / "model-switcher.html"
22
- ).read_text(encoding="utf-8")
23
- api = (
24
- PROJECT_ROOT / "plugins" / "_model_config" / "api" / "model_override.py"
25
- ).read_text(encoding="utf-8")
26
-
27
- assert '"active_models": _active_models(ctx)' in api
28
- assert "switcherActiveModels" in switcher
29
- assert "hasActiveModelNames()" in template
30
- assert "Main:" in template
31
- assert "Utility:" in template
32
- assert "@media (max-width: 760px)" in template
33
- assert "await this.refreshActiveChatModels();" in store
34
- assert 'window.Alpine?.store("chats")?.selected' in store