diff --git a/static/panels.js b/static/panels.js index 1ad076c..cbbb072 100644 --- a/static/panels.js +++ b/static/panels.js @@ -668,17 +668,18 @@ async function switchToProfile(name) { // Refresh model dropdown (profile may have different provider/models) _skillsData = null; await populateModelDropdown(); - // Apply profile's default model if provided - if (data.default_model && $('modelSelect')) { - $('modelSelect').value = data.default_model; - if ($('modelSelect').value !== data.default_model) { - // Model not in list — add it - const opt = document.createElement('option'); - opt.value = data.default_model; - opt.textContent = data.default_model.split('/').pop(); - $('modelSelect').insertBefore(opt, $('modelSelect').firstChild); - $('modelSelect').value = data.default_model; + // Apply profile's default model using the smart resolver (handles id mismatches + // like 'claude-sonnet-4-6' vs 'anthropic/claude-sonnet-4.6' in the dropdown) + if (data.default_model) { + const sel = $('modelSelect'); + const resolved = _applyModelToDropdown(data.default_model, sel); + const modelToUse = resolved || data.default_model; + // Also update the current session's model so syncTopbar() doesn't fight us + if (S.session) { + S.session.model = modelToUse; } + // Store as pending so syncTopbar skips its model override on the next call + S._pendingProfileModel = modelToUse; } // Refresh workspace list (now profile-local) _workspaceList = null; diff --git a/static/ui.js b/static/ui.js index a4f8c07..0650985 100644 --- a/static/ui.js +++ b/static/ui.js @@ -7,6 +7,38 @@ const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'& // Dynamic model labels -- populated by populateModelDropdown(), fallback to static map let _dynamicModelLabels={}; +// ── Smart model resolver ──────────────────────────────────────────────────── +// Finds the best matching option value in a