feat: add AI Jobs admin page, cache model lists, improve image-gen 502 UX
All checks were successful
Release / Test backend (push) Successful in 40s
Release / Check ui (push) Successful in 1m36s
Release / Docker / caddy (push) Successful in 45s
Release / Docker / backend (push) Successful in 4m27s
Release / Docker / runner (push) Successful in 3m32s
Release / Upload source maps (push) Successful in 44s
Release / Docker / ui (push) Successful in 2m46s
Release / Gitea Release (push) Successful in 58s

- Add /admin/ai-jobs page with live-polling jobs table, status badges, progress bars, and cancel action
- Add listAIJobs() helper in pocketbase.ts; AIJob type
- Add POST /api/admin/ai-jobs/[id]/cancel SvelteKit proxy
- Add ai-jobs link to admin sidebar nav (all 5 locales)
- Cache image-gen and text-gen model lists in Valkey (10 min TTL) via scraper.ts helpers
- Cache changelog Gitea API response (5 min TTL)
- Improve 502/504 error message on image-gen page with CF AI timeout hint
- Show CF AI timeout warning in advanced options when a Cloudflare/FLUX model is selected
This commit is contained in:
Admin
2026-04-05 20:07:54 +05:00
parent 6ca704ec9a
commit e3bb19892c
18 changed files with 536 additions and 33 deletions

View File

@@ -12,6 +12,7 @@
import { error } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import * as cache from '$lib/server/cache';
export const BACKEND_URL = env.BACKEND_API_URL ?? 'http://localhost:8080';
@@ -33,6 +34,50 @@ export async function backendFetch(path: string, init?: RequestInit): Promise<Re
}
}
// ─── Cached admin model lists ─────────────────────────────────────────────────
const MODELS_CACHE_TTL = 10 * 60; // 10 minutes — model lists rarely change
/**
* Fetch image-gen model list from the Go backend with a 10-minute cache.
* Returns an empty array on error (callers should surface a warning).
*/
export async function listImageModels<T>(): Promise<T[]> {
const key = 'backend:models:image-gen';
const cached = await cache.get<T[]>(key);
if (cached) return cached;
try {
const res = await backendFetch('/api/admin/image-gen/models');
if (!res.ok) return [];
const data = await res.json();
const models = (data.models ?? []) as T[];
await cache.set(key, models, MODELS_CACHE_TTL);
return models;
} catch {
return [];
}
}
/**
* Fetch text-gen model list from the Go backend with a 10-minute cache.
* Returns an empty array on error.
*/
export async function listTextModels<T>(): Promise<T[]> {
const key = 'backend:models:text-gen';
const cached = await cache.get<T[]>(key);
if (cached) return cached;
try {
const res = await backendFetch('/api/admin/text-gen/models');
if (!res.ok) return [];
const data = await res.json();
const models = (data.models ?? []) as T[];
await cache.set(key, models, MODELS_CACHE_TTL);
return models;
} catch {
return [];
}
}
// ─── Response types ───────────────────────────────────────────────────────────
/**