* Phase 2 Plan 02-04: GET /engines/{id}/health + gpu_compat + HF mask
ENGINE-06 backend half. Adds the data + spawn-on-demand endpoint the new
Engine Compatibility Matrix UI will consume:
* `gpu_compat: tuple[str, ...]` class attribute on `TTSBackend`, overridden
per backend with reasonable defaults (cuda+mps+cpu for OmniVoice/VoxCPM2;
cpu-only for KittenTTS; mps+cpu for MLX-Audio; etc.). `list_backends()`
serializes it as a list.
* `_HF_TOKEN_MASK_RE` (`hf_[A-Za-z0-9]{30,}`) scrubs the `reason` and
`last_error` fields before they leave the registry — Phase 1's
HFTokenRedactor logging filter does not run on FastAPI response bodies,
so this closes T-02-12.
* `GET /engines/{engine_id}/health` — loopback-gated route that resolves
the backend across tts/asr/llm registries, then either calls
`SubprocessBackend.health_check()` (spawn-and-ping) for subprocess
engines or falls back to `is_available()` for in-process engines.
Returns `{ id, ok, message, latency_ms }`. Engine instances are cached
per-class so repeated checks don't leak atexit hooks or spawn extra
sidecars. The masked-redactor is reapplied on the way out.
Test coverage (tests/backend/api/test_engines_route_shape.py, 11 tests):
* Response shape includes the new fields for every TTS entry
* IndexTTS2 isolation_mode == "subprocess", OmniVoice == "in-process"
* Health route round-trips with mocked SubprocessBackend success
* Health route falls back to is_available for in-process backends
* Unknown engine id → 404
* Non-loopback origin → 403
* Engine instance cache reuses the singleton across calls
* HF tokens leaked into is_available() / health_check() are masked
in both the /engines and /engines/{id}/health response bodies
Existing tts_backend_registry shape test updated to include `gpu_compat`.
Full suite: 402 passed, 0 failures (up from 391+ baseline).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Phase 2 Plan 02-04: EngineCompatibilityMatrix UI + Settings wiring
ENGINE-06 frontend half. Mounts a new component on Settings → Engines
that surfaces, end-to-end, the data shape Plan 02-01 + Plan 02-03 added
to the backend registry:
* `frontend/src/components/EngineCompatibilityMatrix.jsx` (270 lines) —
semantic <table> with role=row/cell so RTL queries work; one row per
registered backend. Columns:
- Engine name + install hint + Last error line
- Install state badge (Available / Unavailable + inline reason)
- GPU compat chips (CUDA / MPS / ROCm / CPU with colored variants)
- Isolation mode badge (subprocess for IndexTTS, in-process for the
rest — makes the Phase 2 architectural shift legible to users)
- "Test engine" button → `/engines/{id}/health` round-trip; renders
latency in ms inline next to the button; disabled while inflight;
5 s cooldown to prevent click-storms.
Mount does NOT auto-test any engine — per the plan's Open Question #2,
spawning sidecars is gated on user action.
* `frontend/src/components/EngineCompatibilityMatrix.css` — minimal
styling that reuses chrome tokens; chip colors per GPU target.
* `frontend/src/api/engines.ts` — `getEngineHealth(id)` client function
wraps the new backend route through the shared apiJson helper.
* `frontend/src/api/types.ts` — extends EngineBackend with optional
`isolation_mode`, `last_error`, `install_hint`, `gpu_compat` so the
TypeScript surface tracks the backend wire shape, and adds
EngineHealthResponse.
* `frontend/src/pages/Settings.jsx` — replaces the hand-rolled Engines
table inside EnginesTab with `<EngineCompatibilityMatrix family="tts"
onSelect={...} />`. selectEngine still wires up the picker; the
matrix's onSelect prop renders the Use button per row when provided.
Removes the now-unused FAMILY_META local map.
Test coverage (`frontend/src/test/EngineCompatibilityMatrix.test.jsx`,
8 tests via vitest):
* Renders one row per backend with documented columns
* isolation_mode badge: subprocess for IndexTTS2, in-process for
OmniVoice / KittenTTS
* GPU compat chips: omnivoice → cuda/mps/cpu; kittentts → cpu only
* Unavailable rows render the failure reason inline
* last_error line renders below status when populated; masked HF
token sentinel survives verbatim
* Test engine click fires getEngineHealth(id) and renders latency_ms
* Test button disabled while inflight; second click is a no-op
* Failure path (ok=false) renders a failure marker
Frontend suite: 65 passed (8 new). Lint: 0 new errors. typecheck:ci: clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Phase 2 Plan 02-04: SUMMARY
Recap of Engine Compatibility Matrix delivery — backend route +
gpu_compat metadata + HF-token redaction, frontend EngineCompatibility-
Matrix component, full test counts, deviations, gpu_compat confidence
matrix, frontend test-runner command notes for Phase 6 CI.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 lines
0 B
Python
0 lines
0 B
Python
The file is empty.