diff --git a/ccw/src/templates/dashboard-js/i18n.js b/ccw/src/templates/dashboard-js/i18n.js index fa1fa1eb..b77bbaea 100644 --- a/ccw/src/templates/dashboard-js/i18n.js +++ b/ccw/src/templates/dashboard-js/i18n.js @@ -291,6 +291,7 @@ const i18n = { 'codexlens.useAllKeys': 'Use All Keys', 'codexlens.selectKeys': 'Select Keys', 'codexlens.configureRotation': 'Configure Rotation', + 'codexlens.configureInApiSettings': 'Configure in API Settings', 'codexlens.rotationSaved': 'Rotation config saved successfully', 'codexlens.endpointsSynced': 'endpoints synced to CodexLens', 'codexlens.syncFailed': 'Sync failed', @@ -1997,6 +1998,7 @@ const i18n = { 'codexlens.useAllKeys': '使用所有密钥', 'codexlens.selectKeys': '选择密钥', 'codexlens.configureRotation': '配置轮训', + 'codexlens.configureInApiSettings': '在 API 设置中配置', 'codexlens.rotationSaved': '轮训配置保存成功', 'codexlens.endpointsSynced': '个端点已同步到 CodexLens', 'codexlens.syncFailed': '同步失败', diff --git a/ccw/src/templates/dashboard-js/views/codexlens-manager.js b/ccw/src/templates/dashboard-js/views/codexlens-manager.js index 34a36ba9..bf9167e3 100644 --- a/ccw/src/templates/dashboard-js/views/codexlens-manager.js +++ b/ccw/src/templates/dashboard-js/views/codexlens-manager.js @@ -2058,7 +2058,7 @@ function buildCodexLensManagerPage(config) { '' + '

' + t('codexlens.concurrencyHint') + '

' + '' + - // Multi-Provider Rotation (only for LiteLLM backend) + // Multi-Provider Rotation (only for LiteLLM backend) - Simplified, config in API Settings '' + '' + @@ -2656,15 +2658,21 @@ async function cleanAllIndexesFromPage() { */ async function loadRotationStatus() { try { - var response = await fetch('/api/litellm-api/codexlens/rotation'); + // Load from unified embedding-pool API (handles both new and legacy config) + var response = await fetch('/api/litellm-api/embedding-pool'); if (!response.ok) { - console.warn('[CodexLens] Failed to load rotation config:', response.status); + console.warn('[CodexLens] Failed to load embedding pool config:', response.status); return; } var data = await response.json(); - window.rotationConfig = data.rotationConfig; - window.availableRotationProviders = data.availableProviders; - updateRotationStatusDisplay(data.rotationConfig); + window.embeddingPoolConfig = data.poolConfig; + window.embeddingPoolAvailableModels = data.availableModels || []; + + // Also get endpoint count + var endpointsResponse = await fetch('/api/litellm-api/codexlens/rotation/endpoints'); + var endpointsData = endpointsResponse.ok ? await endpointsResponse.json() : { count: 0 }; + + updateRotationStatusDisplay(data.poolConfig, endpointsData.count); } catch (err) { console.error('[CodexLens] Error loading rotation status:', err); } @@ -2672,29 +2680,47 @@ async function loadRotationStatus() { /** * Update the rotation status display in the page + * @param {Object} poolConfig - The embedding pool configuration + * @param {number} endpointCount - Number of active endpoints */ -function updateRotationStatusDisplay(rotationConfig) { +function updateRotationStatusDisplay(poolConfig, endpointCount) { var badge = document.getElementById('rotationStatusBadge'); + var detailsEl = document.getElementById('rotationDetails'); + var modelNameEl = document.getElementById('rotationModelName'); var countEl = document.getElementById('rotationEndpointCount'); if (!badge) return; - if (rotationConfig && rotationConfig.enabled) { + if (poolConfig && poolConfig.enabled) { badge.textContent = t('common.enabled'); badge.className = 'text-xs px-2 py-0.5 rounded-full bg-success/10 text-success'; - // Show endpoint count - if (countEl && rotationConfig.providers) { - var totalEndpoints = 0; - rotationConfig.providers.forEach(function(p) { - if (p.enabled) totalEndpoints += (p.useAllKeys ? 4 : 1); // Estimate - }); - countEl.textContent = '~' + totalEndpoints + ' ' + t('codexlens.totalEndpoints').toLowerCase(); + // Show details + if (detailsEl) { + detailsEl.classList.remove('hidden'); + if (modelNameEl) modelNameEl.textContent = poolConfig.targetModel || ''; + if (countEl) countEl.textContent = (endpointCount || 0) + ' ' + t('codexlens.totalEndpoints').toLowerCase(); } } else { badge.textContent = t('common.disabled'); badge.className = 'text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground'; - if (countEl) countEl.textContent = ''; + if (detailsEl) detailsEl.classList.add('hidden'); + } +} + +/** + * Navigate to API Settings Embedding Pool tab + */ +function navigateToApiSettingsEmbeddingPool() { + // Navigate to API Settings page with embedding-pool tab + if (typeof switchView === 'function') { + switchView('api-settings'); + // Give time for page to render, then switch to embedding-pool tab + setTimeout(function() { + if (typeof switchSidebarTab === 'function') { + switchSidebarTab('embedding-pool'); + } + }, 100); } }