Changeset 0.10.4 (#60)

This commit is contained in:
2026-02-24 22:01:20 +00:00
parent ba2cd42428
commit e5ee78c498
18 changed files with 152 additions and 31 deletions

View File

@@ -204,7 +204,12 @@ async function adminRoleProviderChanged(role, slot) {
modelSelect.innerHTML = '<option value="">— select model —</option>';
if (!provId || !window._adminModelList) return;
const models = window._adminModelList.filter(m => m.provider_config_id === provId);
// Filter by provider AND model type matching the role
const typeForRole = role === 'embedding' ? 'embedding' : 'chat';
const models = window._adminModelList.filter(m =>
m.provider_config_id === provId &&
(m.model_type || 'chat') === typeForRole
);
models.forEach(m => {
const opt = document.createElement('option');
opt.value = m.model_id;
@@ -226,7 +231,8 @@ async function adminSaveRole(role) {
fallback: getBinding('fallback')
});
if (status) { status.textContent = '✓ Saved'; status.style.color = 'var(--success)'; }
setTimeout(() => { if (status) status.textContent = ''; }, 3000);
// Reload to reflect saved state in dropdowns
setTimeout(() => UI.loadAdminRoles(), 500);
} catch (e) {
if (status) { status.textContent = '✗ ' + e.message; status.style.color = 'var(--error)'; }
}

View File

@@ -75,6 +75,7 @@ async function fetchModels() {
name: m.display_name || baseModelId,
provider: m.provider_name || m.provider || '',
configId: m.config_id || m.provider_config_id || null,
model_type: m.model_type || 'chat',
capabilities: resolveCapabilities(m.capabilities, baseModelId),
isPreset,
presetId: m.preset_id || m.persona_id || null,

View File

@@ -220,9 +220,13 @@ async function userRoleProviderChanged(role) {
modelSel.innerHTML = '<option value="">— select model —</option>';
if (!providerId) return;
// Load models for the selected provider (App.models uses configId, not provider_config_id)
// Filter by provider AND model type matching the role
const typeForRole = role === 'embedding' ? 'embedding' : 'chat';
const allModels = App.models || [];
const provModels = allModels.filter(m => m.configId === providerId);
const provModels = allModels.filter(m =>
m.configId === providerId &&
(m.model_type || 'chat') === typeForRole
);
provModels.forEach(m => {
modelSel.innerHTML += `<option value="${m.baseModelId}">${esc(m.name || m.baseModelId)}</option>`;
});

View File

@@ -145,6 +145,8 @@ Object.assign(UI, {
const roleNames = ['utility', 'embedding'];
el.innerHTML = roleNames.map(role => {
const cfg = roles[role] || { primary: null, fallback: null };
const typeForRole = role === 'embedding' ? 'embedding' : 'chat';
const typeFilter = m => (m.model_type || 'chat') === typeForRole;
return `
<div class="settings-section" style="margin-bottom:16px">
<h3 style="font-size:14px;margin:0 0 8px;text-transform:capitalize">${role}</h3>
@@ -156,7 +158,7 @@ Object.assign(UI, {
</select>
<select id="role-${role}-primary-model" style="min-width:200px">
<option value="">— select model —</option>
${cfg.primary ? modelList.filter(m => m.provider_config_id === cfg.primary.provider_config_id).map(m => `<option value="${m.model_id}" ${m.model_id === cfg.primary.model_id ? 'selected' : ''}>${esc(m.display_name || m.model_id)}</option>`).join('') : ''}
${cfg.primary ? modelList.filter(m => m.provider_config_id === cfg.primary.provider_config_id && typeFilter(m)).map(m => `<option value="${m.model_id}" ${m.model_id === cfg.primary.model_id ? 'selected' : ''}>${esc(m.display_name || m.model_id)}</option>`).join('') : ''}
</select>
</div>
<div class="form-row" style="gap:8px;align-items:center;margin-top:6px">
@@ -167,7 +169,7 @@ Object.assign(UI, {
</select>
<select id="role-${role}-fallback-model" style="min-width:200px">
<option value="">— select model —</option>
${cfg.fallback ? modelList.filter(m => m.provider_config_id === cfg.fallback.provider_config_id).map(m => `<option value="${m.model_id}" ${m.model_id === cfg.fallback.model_id ? 'selected' : ''}>${esc(m.display_name || m.model_id)}</option>`).join('') : ''}
${cfg.fallback ? modelList.filter(m => m.provider_config_id === cfg.fallback.provider_config_id && typeFilter(m)).map(m => `<option value="${m.model_id}" ${m.model_id === cfg.fallback.model_id ? 'selected' : ''}>${esc(m.display_name || m.model_id)}</option>`).join('') : ''}
</select>
</div>
<div class="form-row" style="gap:8px;margin-top:8px">

View File

@@ -391,6 +391,8 @@ Object.assign(UI, {
const roleNames = ['utility', 'embedding'];
el.innerHTML = roleNames.map(role => {
const cfg = userRoles[role] || { primary: null };
const typeForRole = role === 'embedding' ? 'embedding' : 'chat';
const typeFilter = m => (m.model_type || 'chat') === typeForRole;
return `
<div class="settings-section" style="margin-bottom:12px">
<h4 style="font-size:13px;margin:0 0 6px;text-transform:capitalize">${role}
@@ -404,7 +406,7 @@ Object.assign(UI, {
</select>
<select id="userRole-${role}-model" style="min-width:200px;font-size:12px">
<option value="">— select model —</option>
${cfg.primary ? personalModels.filter(m => m.configId === cfg.primary.provider_config_id).map(m => `<option value="${m.baseModelId}" ${m.baseModelId === cfg.primary.model_id ? 'selected' : ''}>${esc(m.name || m.baseModelId)}</option>`).join('') : ''}
${cfg.primary ? personalModels.filter(m => m.configId === cfg.primary.provider_config_id && typeFilter(m)).map(m => `<option value="${m.baseModelId}" ${m.baseModelId === cfg.primary.model_id ? 'selected' : ''}>${esc(m.name || m.baseModelId)}</option>`).join('') : ''}
</select>
<button class="btn-small" onclick="saveUserRole('${role}')" style="font-size:11px">Save</button>
${cfg.primary ? `<button class="btn-small btn-danger" onclick="clearUserRole('${role}')" style="font-size:11px" title="Remove override, use org default">Clear</button>` : ''}