All engines are unified — every engine supports both batch and realtime interfaces. Runtimes that don't natively support realtime use a thin wrapper that splits audio on silence (or max chunk length) to simulate streaming. The web console must stop treating batch and realtime as separate worlds and present a single unified view.
This plan addresses 10 audit findings across 4 phases.
File: dalston/gateway/api/console.py
- Add
interfaces: list[str]field toBatchEnginePydantic model (always["batch", "realtime"]). - Add
interfaces: list[str]field toRealtimeWorkerPydantic model (always["batch", "realtime"]). - In
get_engines(), populateinterfacesfrom heartbeat data (data.get("interfaces")). - For catalog-only offline entries, default to
["batch", "realtime"].
File: dalston/gateway/api/console.py
- Change
RealtimeWorker.statusfromready | unhealthytoLiteral["ready", "busy", "draining", "offline", "unhealthy"]. - The session router already tracks richer status; stop discarding it.
File: web/src/api/types.ts
- Add
interfaces: string[]toBatchEngine. - Add
interfaces: string[]toWorkerStatus. - Widen
WorkerStatus.statusto'ready' | 'busy' | 'draining' | 'offline' | 'unhealthy'.
File: web/src/pages/Engines.tsx
Current: Two hard-separated sections — "Batch Pipeline" and "Real-time Workers".
New: One unified view. The stage accordion stays (engines grouped by stage), but each engine card shows both batch metrics (queue depth, processing) and realtime metrics (active sessions, capacity, utilization). No separate realtime section — every engine appears once under its stage.
Logic change:
- Match
batch_enginesandrealtime_enginesbyengine_idto build a single engine list with merged metrics. - Summary cards: "Engines: X/Y healthy", "Stages: N active" — no batch/realtime split.
Files: web/src/pages/Engines.tsx, web/src/pages/EngineDetail.tsx
- Remove the
stage === 'transcribe'guard from model badge rendering inEngines.tsx(~line 194) and from the models section inEngineDetail.tsx. - Query
useModelRegistry({ engine_id })for any engine, regardless of stage. - Backend already supports
GET /v1/models?engine_id=<any>— no change needed.
File: web/src/pages/EngineDetail.tsx
- Always render both batch metrics (queue depth, processing count) and realtime metrics (active sessions, capacity, utilization bar) on the same page.
- Merge data from
batch_enginesandrealtime_enginesbyengine_id. - Remove the separate
RealtimeWorkerDetail.tsxpage — redirect its route toEngineDetail.
File: web/src/pages/RealtimeWorkerDetail.tsx — Delete.
File: web/src/App.tsx
- Remove
/realtime/workers/:workerIdroute (or redirect to/engines/:engineId).
File: web/src/pages/Engines.tsx
- Replace the hardcoded
PIPELINE_STAGESarray. - Derive stages from actual engine data:
[...new Set(engines.map(e => e.stage))]. - Keep an ordered list as a sort-order hint, but show any stage that exists in the data even if not in the hint list.
File: web/src/components/ModelFiltersBar.tsx
- Replace the hardcoded
RUNTIMESarray with a dynamic list derived from distinctengine_idvalues in the model registry response. - Sort alphabetically.
Files:
web/src/components/ModelTable.tsx— column headerweb/src/components/ModelFiltersBar.tsx— filter label
Change "Runtime" to "Engine" everywhere in the Models page.
File: web/src/pages/EngineDetail.tsx
- Remove the engine-level "Capabilities" card that shows
supports_word_timestampsandsupports_native_streamingas engine-wide booleans. - Show capabilities per model in the Available Models grid — each model card already shows badges; add a summary: "3/5 models support word timestamps".
File: web/src/components/CapabilitiesCard.tsx
- Change from boolean checkmarks to counts: "Word Timestamps: 8 models" / "Streaming: 3 models".
- Compute client-side from the model registry.
File: web/src/pages/Dashboard.tsx
- Replace the separate batch/realtime summary cards with a unified
"Engine Utilization" card showing:
- Total engines, healthy count
- Combined utilization: batch queue depth + realtime active sessions
- Per-engine utilization breakdown (optional, if space allows)
File: web/src/pages/Dashboard.tsx
- On recent jobs and recent sessions, show which engine processed each item as a small badge/link.
| File | Changes |
|---|---|
dalston/gateway/api/console.py |
Add interfaces; widen status |
web/src/api/types.ts |
Add interfaces; widen WorkerStatus.status |
web/src/pages/Engines.tsx |
Merge batch+realtime; dynamic stages; models for all stages |
web/src/pages/EngineDetail.tsx |
Unified detail with both metrics; capabilities per-model |
web/src/pages/RealtimeWorkerDetail.tsx |
Delete |
web/src/App.tsx |
Remove/redirect realtime worker detail route |
web/src/components/CapabilitiesCard.tsx |
Model counts instead of booleans |
web/src/components/ModelFiltersBar.tsx |
Dynamic engines; rename "Runtime" → "Engine" |
web/src/components/ModelTable.tsx |
Rename "Runtime" → "Engine" column header |
web/src/pages/Dashboard.tsx |
Unified engine utilization; engine badges on activity |
- Phase 1 (Backend + types) — Must go first; frontend depends on
interfaces. - Phase 3A + 3B (Dynamic filters, terminology) — Quick wins, no dependencies.
- Phase 2B (Models for all stages) — Quick win, remove hardcoded guard.
- Phase 2A + 2D (Merge Engines page, dynamic stages) — Core restructure.
- Phase 2C (Unified detail page, delete RealtimeWorkerDetail) — Builds on 2A.
- Phase 3C + 3D (Capabilities per-model) — Independent, moderate effort.
- Phase 4 (Dashboard) — Independent, can be done anytime after Phase 1.