feat: Add aggregated endpoint for CodexLens dashboard initialization and improve loading performance

This commit is contained in:
catlog22
2025-12-25 17:22:42 +08:00
parent c5f379ba01
commit 777d5df573
2 changed files with 110 additions and 21 deletions

View File

@@ -129,6 +129,54 @@ async function loadCodexLensStatus() {
}
}
/**
* Load CodexLens dashboard data using aggregated endpoint (single API call)
* This is optimized for the CodexLens Manager page initialization
* @returns {Promise<object|null>} Dashboard init data or null on error
*/
async function loadCodexLensDashboardInit() {
try {
const response = await fetch('/api/codexlens/dashboard-init');
if (!response.ok) throw new Error('Failed to load CodexLens dashboard init');
const data = await response.json();
// Update status variables from aggregated response
codexLensStatus = data.status || { ready: false };
semanticStatus = data.semantic || { available: false };
// Expose to window for other modules
if (!window.cliToolsStatus) {
window.cliToolsStatus = {};
}
window.cliToolsStatus.codexlens = {
installed: data.installed || false,
version: data.status?.version || null,
installedModels: [],
config: data.config || {},
semantic: data.semantic || {}
};
// Store config globally for easy access
window.codexLensConfig = data.config || {};
window.codexLensStatusData = data.statusData || {};
// Update badges
updateCodexLensBadge();
console.log('[CLI Status] CodexLens dashboard init loaded:', {
installed: data.installed,
version: data.status?.version,
semanticAvailable: data.semantic?.available
});
return data;
} catch (err) {
console.error('Failed to load CodexLens dashboard init:', err);
// Fallback to individual calls
return await loadCodexLensStatus();
}
}
/**
* Legacy: Load semantic status individually
*/

View File

@@ -1904,37 +1904,64 @@ async function renderCodexLensManager() {
container.innerHTML = '<div class="flex items-center justify-center py-12"><div class="animate-spin w-6 h-6 border-2 border-primary border-t-transparent rounded-full"></div><span class="ml-3">' + t('common.loading') + '</span></div>';
try {
// Load CodexLens status first to populate window.cliToolsStatus.codexlens
if (typeof loadCodexLensStatus === 'function') {
await loadCodexLensStatus();
}
// Use aggregated endpoint for faster page load (single API call)
var dashboardData = null;
var config = { index_dir: '~/.codexlens/indexes', index_count: 0 };
// Load LiteLLM API config for embedding backend options
try {
console.log('[CodexLens] Loading LiteLLM config...');
var litellmResponse = await fetch('/api/litellm-api/config');
console.log('[CodexLens] LiteLLM response status:', litellmResponse.status);
if (litellmResponse.ok) {
window.litellmApiConfig = await litellmResponse.json();
console.log('[CodexLens] LiteLLM config loaded:', window.litellmApiConfig);
console.log('[CodexLens] Providers:', window.litellmApiConfig?.providers?.length || 0);
} else {
console.warn('[CodexLens] LiteLLM config response not ok:', litellmResponse.status);
if (typeof loadCodexLensDashboardInit === 'function') {
console.log('[CodexLens] Using aggregated dashboard-init endpoint...');
dashboardData = await loadCodexLensDashboardInit();
if (dashboardData && dashboardData.config) {
config = dashboardData.config;
console.log('[CodexLens] Dashboard init loaded, config:', config);
}
} catch (e) {
console.warn('[CodexLens] Could not load LiteLLM config:', e);
} else if (typeof loadCodexLensStatus === 'function') {
// Fallback to legacy individual calls
console.log('[CodexLens] Fallback to legacy loadCodexLensStatus...');
await loadCodexLensStatus();
var response = await fetch('/api/codexlens/config');
config = await response.json();
}
var response = await fetch('/api/codexlens/config');
var config = await response.json();
// Load LiteLLM API config for embedding backend options (parallel with page render)
var litellmPromise = (async () => {
try {
console.log('[CodexLens] Loading LiteLLM config...');
var litellmResponse = await fetch('/api/litellm-api/config');
if (litellmResponse.ok) {
window.litellmApiConfig = await litellmResponse.json();
console.log('[CodexLens] LiteLLM config loaded, providers:', window.litellmApiConfig?.providers?.length || 0);
}
} catch (e) {
console.warn('[CodexLens] Could not load LiteLLM config:', e);
}
})();
container.innerHTML = buildCodexLensManagerPage(config);
if (window.lucide) lucide.createIcons();
initCodexLensManagerPageEvents(config);
loadSemanticDepsStatus();
// Load additional data in parallel (non-blocking)
var isInstalled = window.cliToolsStatus?.codexlens?.installed || dashboardData?.installed;
// 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);
}
}
loadModelList();
// Load index stats for the Index Manager section
if (window.cliToolsStatus?.codexlens?.installed) {
if (isInstalled) {
loadIndexStatsForPage();
}
} catch (err) {
@@ -1943,6 +1970,20 @@ async function renderCodexLensManager() {
}
}
/**
* Update semantic deps UI from cached data
*/
function updateSemanticDepsUI(container, semanticData) {
if (!container) return;
if (semanticData.available) {
container.innerHTML = '<div class="flex items-center gap-2 text-success"><i data-lucide="check-circle" class="w-4 h-4"></i><span>' + (semanticData.backend || 'Ready') + '</span></div>';
} else {
container.innerHTML = '<div class="flex items-center gap-2 text-muted-foreground"><i data-lucide="circle-dashed" class="w-4 h-4"></i><span>' + t('codexlens.notInstalled') + '</span></div>';
}
if (window.lucide) lucide.createIcons();
}
/**
* Build CodexLens Manager page content
*/