diff --git a/ccw/src/templates/dashboard-js/views/api-settings.js b/ccw/src/templates/dashboard-js/views/api-settings.js index 7e9c6f21..bd103d48 100644 --- a/ccw/src/templates/dashboard-js/views/api-settings.js +++ b/ccw/src/templates/dashboard-js/views/api-settings.js @@ -189,6 +189,13 @@ async function toggleProviderExclusion(providerId) { // Re-render the discovered providers section renderDiscoveredProviders(); + + // Update sidebar summary + const sidebarContainer = document.querySelector('.api-settings-sidebar .embedding-pool-sidebar-summary'); + if (sidebarContainer && sidebarContainer.parentElement) { + sidebarContainer.parentElement.innerHTML = renderEmbeddingPoolSidebar(); + if (window.lucide) lucide.createIcons(); + } } // ========== Provider Management ========== @@ -991,9 +998,7 @@ async function renderApiSettings() { ' ' + t('apiSettings.addEndpoint') + ''; } else if (activeSidebarTab === 'embedding-pool') { - sidebarContentHtml = '
' + - '

' + t('apiSettings.embeddingPoolDesc') + '

' + - '
'; + sidebarContentHtml = renderEmbeddingPoolSidebar(); } else if (activeSidebarTab === 'cache') { sidebarContentHtml = '
' + '

' + t('apiSettings.cacheTabHint') + '

' + @@ -2533,6 +2538,72 @@ function generateKeyId() { // ========== Embedding Pool Management ========== +/** + * Render embedding pool sidebar summary + */ +function renderEmbeddingPoolSidebar() { + if (!embeddingPoolConfig) { + return '
' + + '
' + + '

' + t('apiSettings.embeddingPoolDesc') + '

' + + '
' + + '
'; + } + + const enabled = embeddingPoolConfig.enabled || false; + const targetModel = embeddingPoolConfig.targetModel || ''; + const strategy = embeddingPoolConfig.strategy || 'round_robin'; + const excludedIds = embeddingPoolConfig.excludedProviderIds || []; + + // Count total providers/keys + let totalProviders = embeddingPoolDiscoveredProviders.length; + let totalKeys = 0; + let activeProviders = 0; + + embeddingPoolDiscoveredProviders.forEach(function(p) { + totalKeys += p.apiKeys?.length || 1; + if (excludedIds.indexOf(p.providerId) === -1) { + activeProviders++; + } + }); + + const strategyLabels = { + 'round_robin': t('codexlens.strategyRoundRobin') || 'Round Robin', + 'latency_aware': t('codexlens.strategyLatency') || 'Latency-Aware', + 'weighted_random': t('codexlens.strategyWeighted') || 'Weighted Random' + }; + + return '
' + + '
' + + '

' + + t('apiSettings.embeddingPool') + + '

' + + '
' + + '
' + + '' + + '' + (enabled ? (t('common.enabled') || 'Enabled') : (t('common.disabled') || 'Disabled')) + '' + + '
' + + (enabled && targetModel ? + '
' + + '' + t('apiSettings.targetModel') + '' + + '' + targetModel + '' + + '
' : '') + + (enabled ? + '
' + + '' + t('apiSettings.strategy') + '' + + '' + (strategyLabels[strategy] || strategy) + '' + + '
' : '') + + (enabled && totalProviders > 0 ? + '
' + + '' + t('apiSettings.discoveredProviders') + '' + + '' + activeProviders + ' / ' + totalProviders + ' providers (' + totalKeys + ' keys)' + + '
' : '') + + '
' + + '
' + + '
'; +} + + /** * Render embedding pool main panel */ @@ -2567,10 +2638,13 @@ async function renderEmbeddingPoolMainPanel() { '

' + t('apiSettings.embeddingPoolDesc') + '

' + '
' + - // Enable/Disable Toggle - '
' + - '
' + - '

' + t('apiSettings.poolEnabled') + '

' + + // Enable/Disable Toggle Card + '
' + + '
' + + '
' + + '' + + '

' + t('apiSettings.poolEnabled') + '

' + + '
' + '
' + '
' + - // Configuration Form + // Configuration Form Card '
' + - '
' + - '' + - '' + + '

' + t('apiSettings.configuration') || 'Configuration' + '

' + + + // Model and Strategy in Grid + '
' + + '
' + + '' + + '' + + '
' + + '
' + + '' + + '' + + '
' + '
' + - '
' + - '' + - '' + - '
' + - - '
' + - '' + - '' + - '
' + - - '
' + - '' + - '' + + // Cooldown and Concurrent in Grid + '
' + + '
' + + '' + + '' + + '
' + + '
' + + '' + + '' + + '
' + '
' + // Discovered Providers Section - '
' + + '
' + '
' + '' + '
' + - '
' + - '
' + - '' + - '
' + - '
'; + '
'; }); providersHtml += '
'; diff --git a/ccw/src/templates/dashboard-js/views/codexlens-manager.js b/ccw/src/templates/dashboard-js/views/codexlens-manager.js index bf9167e3..c63c70f1 100644 --- a/ccw/src/templates/dashboard-js/views/codexlens-manager.js +++ b/ccw/src/templates/dashboard-js/views/codexlens-manager.js @@ -1947,16 +1947,9 @@ async function renderCodexLensManager() { // Wait for LiteLLM config before loading semantic deps (it may need provider info) await litellmPromise; - // Load semantic deps status (skip if we already have it from dashboard-init) - if (!dashboardData?.semantic) { - loadSemanticDepsStatus(); - } else { - // Use cached semantic status from dashboard-init - var semanticContainer = document.getElementById('semanticDepsStatus'); - if (semanticContainer && dashboardData.semantic) { - updateSemanticDepsUI(semanticContainer, dashboardData.semantic); - } - } + // Always load semantic deps status - it needs GPU detection and device list + // which are not included in the aggregated endpoint + loadSemanticDepsStatus(); loadModelList(); @@ -1970,20 +1963,6 @@ async function renderCodexLensManager() { } } -/** - * Update semantic deps UI from cached data - */ -function updateSemanticDepsUI(container, semanticData) { - if (!container) return; - - if (semanticData.available) { - container.innerHTML = '
' + (semanticData.backend || 'Ready') + '
'; - } else { - container.innerHTML = '
' + t('codexlens.notInstalled') + '
'; - } - if (window.lucide) lucide.createIcons(); -} - /** * Build CodexLens Manager page content */