Checkpoint Odysseus local update

This commit is contained in:
pewdiepie-archdaemon
2026-07-07 00:50:07 +00:00
parent 5f6e6a2c4a
commit 017903de61
66 changed files with 22349 additions and 982 deletions
+18 -9
View File
@@ -17,6 +17,7 @@ let API_BASE = '';
let _cachedItems = []; // cached /api/models items for model-switch dropdown
let _lastFetchTime = 0;
let _fetchInflight = null;
let _fetchSeq = 0;
const _FETCH_CACHE_TTL = 30000; // 30s client-side cache for /api/models
const COLLAPSE_KEY = 'odysseus-models-collapsed';
const FAVORITES_KEY = 'odysseus-model-favorites';
@@ -165,18 +166,21 @@ function _buildModelRow(mid, url, displayName, endpointId, offline, modelType) {
export async function refreshModels(force = false) {
const box = document.getElementById('models');
if (!box) return;
// Skip network fetch if cache is fresh and not forced — still re-render UI
const now = Date.now();
const needsFetch = force || _cachedItems.length === 0 || (now - _lastFetchTime) >= _FETCH_CACHE_TTL;
box.innerHTML = '';
if (box) box.innerHTML = '';
if (needsFetch) {
const _loadingSpinner = spinnerModule.create('', 'right', 'wave');
box.appendChild(_loadingSpinner.createElement());
_loadingSpinner.start();
let _loadingSpinner = null;
if (box) {
_loadingSpinner = spinnerModule.create('', 'right', 'wave');
box.appendChild(_loadingSpinner.createElement());
_loadingSpinner.start();
}
try {
if (force) _fetchInflight = null;
if (!_fetchInflight) {
// Pass ?refresh=true on forced refreshes so the BACKEND's 30s
// per-user cache also gets bypassed. Without this, `force=true`
@@ -184,25 +188,30 @@ export async function refreshModels(force = false) {
// back — newly-served endpoints don't appear until the cache
// ages out. (Bug repro: serve a model, picker is empty for ~30s
// even though the endpoint is in the DB and online.)
const _seq = ++_fetchSeq;
const _url = `${API_BASE}/api/models` + (force ? '?refresh=true' : '?background=false');
_fetchInflight = fetch(_url, { credentials: 'same-origin' })
.then(async (res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
const data = await res.json();
return { data, seq: _seq };
})
.finally(() => { _fetchInflight = null; });
}
const data = await _fetchInflight;
const { data, seq } = await _fetchInflight;
if (seq < _fetchSeq) return;
_lastFetchTime = Date.now();
_cachedItems = data.items || [];
} catch (e) {
console.error(e);
box.textContent = '(scan failed)';
if (box) box.textContent = '(scan failed)';
return;
} finally {
box.innerHTML = '';
try { _loadingSpinner && _loadingSpinner.stop && _loadingSpinner.stop(); } catch (_) {}
if (box) box.innerHTML = '';
}
}
if (!box) return;
try {
const collapseState = _loadCollapsed();