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

@@ -292,3 +292,31 @@ class AudioCaptureManager:
except Exception as e:
logger.error(f"Error enumerating devices for engine '{engine_type}': {e}")
return result
@staticmethod
def enumerate_devices_by_engine() -> Dict[str, List[dict]]:
"""List available audio devices grouped by engine type.
Unlike enumerate_devices(), does NOT deduplicate across engines.
Each engine's devices are returned with their engine-specific indices.
"""
result: Dict[str, List[dict]] = {}
for engine_type, engine_class in AudioEngineRegistry.get_all_engines().items():
try:
if not engine_class.is_available():
continue
devices = []
for dev in engine_class.enumerate_devices():
devices.append({
"index": dev.index,
"name": dev.name,
"is_input": dev.is_input,
"is_loopback": dev.is_loopback,
"channels": dev.channels,
"default_samplerate": dev.default_samplerate,
"engine_type": engine_type,
})
result[engine_type] = devices
except Exception as e:
logger.error(f"Error enumerating devices for engine '{engine_type}': {e}")
return result