0aaff91ebd
* feat(ui): add installed model lifecycle Models now owns catalog exploration and installed runtime controls under one canonical route. URL-owned state keeps lifecycle context recoverable through links and browser history. Assisted-by: Codex:gpt-5 Playwright * feat(ui): add installed backend lifecycle Backends split discovery from backend-binary management. The canonical page now keeps both lifecycle views under one URL-backed shell while it preserves target-node placement. Assisted-by: Codex:gpt-5 Playwright * fix(ui): repair lifecycle state updates Installed models lost distributed refreshes and kept a deleted selection. Backend searches also stopped tracking URL changes, while batch upgrades stopped after their first error. Preserve background refreshes and finish each requested batch action. Drive catalog results from URL-backed state without losing full metadata. Assisted-by: Codex:gpt-5 [Playwright] * feat(ui): make resource pages canonical Replace Host navigation with canonical Models and Backends lifecycle routes, preserve legacy management URLs, and surface shared host capacity on the Operate overview. Assisted-by: Codex:gpt-5 [Playwright] * feat(ui): complete canonical resource lifecycle Finish the responsive list-to-detail behavior, remove the retired Host implementation, and keep Explore focused on discovery while Installed owns destructive actions. Update regression coverage, localization, documentation, and development binding for the canonical resource pages. Assisted-by: Codex:gpt-5 [Playwright] * docs(ui): record the UI design context Record the approved users, brand character, and design principles so future interface work uses the same product direction. Index the context from the repository's agent instructions. Assisted-by: Codex:gpt-5 --------- Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
86 lines
3.4 KiB
JavaScript
86 lines
3.4 KiB
JavaScript
import { defineConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import istanbul from 'vite-plugin-istanbul'
|
|
|
|
const backendUrl = process.env.LOCALAI_URL || 'http://localhost:8080'
|
|
|
|
// COVERAGE=true produces an instrumented build whose modules report istanbul
|
|
// counters on window.__coverage__, harvested by the Playwright coverage
|
|
// fixture (e2e/coverage-fixtures.js). Off by default so normal/dev/prod builds
|
|
// carry no instrumentation overhead.
|
|
const coverage = process.env.COVERAGE === 'true'
|
|
// COVERAGE_V8=true produces a NON-instrumented build with source maps, so the
|
|
// Playwright coverage fixture can collect Chromium V8 coverage (near-zero
|
|
// runtime overhead, unlike istanbul's build-time counters) and map it back to
|
|
// source via v8-to-istanbul. Mutually exclusive with COVERAGE.
|
|
const coverageV8 = process.env.COVERAGE_V8 === 'true'
|
|
|
|
export default defineConfig({
|
|
plugins: [
|
|
react(),
|
|
...(coverage
|
|
? [
|
|
istanbul({
|
|
include: 'src/**/*',
|
|
extension: ['.js', '.jsx', '.ts', '.tsx'],
|
|
requireEnv: false,
|
|
// The e2e suite runs against `vite build` output, not the dev
|
|
// server, so instrumentation must be applied to the production
|
|
// build too (the plugin only instruments dev mode otherwise).
|
|
forceBuildInstrument: true,
|
|
}),
|
|
]
|
|
: []),
|
|
],
|
|
// Relative base so every generated URL (entry scripts in index.html, CSS
|
|
// `url()` font references, and lazily-imported route chunks) resolves against
|
|
// the file that references it rather than the origin root. When LocalAI is
|
|
// served under a reverse-proxy subpath (X-Forwarded-Prefix, e.g. `/llm/`),
|
|
// an absolute `/assets/...` bypasses the prefix and 404s — breaking fonts
|
|
// ("tofu" glyphs) and lazy-loaded chunks. index.html's now-relative refs
|
|
// resolve via the `<base href>` that serveIndex always injects (see
|
|
// core/http/app.go), so both proxied and root deployments load correctly.
|
|
base: './',
|
|
server: {
|
|
host: '0.0.0.0',
|
|
port: 3000,
|
|
proxy: {
|
|
'/api': backendUrl,
|
|
'/v1': backendUrl,
|
|
'/tts': backendUrl,
|
|
'/video': backendUrl,
|
|
'/backend': backendUrl,
|
|
'/models': backendUrl,
|
|
'/backends': backendUrl,
|
|
'/swagger': backendUrl,
|
|
'/static': backendUrl,
|
|
'/generated-audio': backendUrl,
|
|
'/generated-images': backendUrl,
|
|
'/generated-videos': backendUrl,
|
|
'/generated-3d': backendUrl,
|
|
'/3d': backendUrl,
|
|
'/version': backendUrl,
|
|
'/system': backendUrl,
|
|
},
|
|
},
|
|
build: {
|
|
outDir: 'dist',
|
|
assetsDir: 'assets',
|
|
// Source maps are needed only to map V8 coverage back to original sources.
|
|
sourcemap: coverageV8,
|
|
rollupOptions: {
|
|
output: {
|
|
// The coverage build inlines all dynamic imports into a single chunk.
|
|
// The app is route-code-split (router.jsx uses React.lazy), so a normal
|
|
// build emits ~50 lazy chunks. V8 coverage only sees chunks a test
|
|
// actually loaded, so untested pages would silently drop out of the
|
|
// denominator and inflate the percentage. Bundling everything into one
|
|
// chunk for the coverage build keeps the denominator complete and the
|
|
// measurement invariant to how production is split. Production builds
|
|
// (COVERAGE_V8 unset) keep code-splitting for fast first paint.
|
|
inlineDynamicImports: coverageV8,
|
|
},
|
|
},
|
|
},
|
|
})
|