Filter audio devices by engine type and update tutorial steps

- Add enumerate_devices_by_engine() returning per-engine device lists
  without cross-engine dedup so frontend can filter correctly
- API /audio-devices now includes by_engine dict alongside flat list
- Frontend caches per-engine data, filters device dropdown by selected
  template's engine_type, refreshes on template change
- Reorder getting-started tutorial: add API docs and accent color steps
- Fix tutorial trigger button focus outline persisting on step 2
- Use accent color variable for tutorial pulse ring animation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 21:43:37 +03:00
parent efb05eba77
commit 49c985e5c5
8 changed files with 97 additions and 18 deletions

View File

@@ -10,9 +10,19 @@ router = APIRouter()
@router.get("/api/v1/audio-devices", tags=["Audio"])
async def list_audio_devices(_auth: AuthRequired):
"""List available audio input/output devices for audio-reactive sources."""
"""List available audio input/output devices for audio-reactive sources.
Returns a deduped flat list (backward compat) plus a ``by_engine`` dict
with per-engine device lists (no cross-engine dedup) so the frontend can
filter by the selected audio template's engine type.
"""
try:
devices = AudioCaptureManager.enumerate_devices()
return {"devices": devices, "count": len(devices)}
by_engine = AudioCaptureManager.enumerate_devices_by_engine()
return {
"devices": devices,
"count": len(devices),
"by_engine": by_engine,
}
except Exception as e:
return {"devices": [], "count": 0, "error": str(e)}
return {"devices": [], "count": 0, "by_engine": {}, "error": str(e)}