"""Build a Pipeline from Settings. This is the single place that knows which concrete class each config name maps to, so adding a backend = one line here.""" from __future__ import annotations from .config import Settings from .pipeline import Pipeline def build(settings: Settings) -> Pipeline: return Pipeline( source=_source(settings), vision=_vision(settings), brain=_brain(settings), stt=_stt(settings), tts=_tts(settings), text_channel=_text(settings), ) def _source(s: Settings): if s.source == "mss": from .backends.capture_mss import MSSFrameSource return MSSFrameSource(interval=s.capture_interval) from .backends.mock import MockFrameSource return MockFrameSource(interval=s.capture_interval) def _vision(s: Settings): if s.vision == "claude": from .backends.claude import ClaudeVision return ClaudeVision(model=s.anthropic_model) from .backends.mock import MockVision return MockVision() def _brain(s: Settings): if s.brain == "claude": from .backends.claude import ClaudeBrain return ClaudeBrain(model=s.anthropic_model) from .backends.mock import MockBrain return MockBrain() def _stt(s: Settings): if s.stt in (None, "none"): return None from .backends.mock import MockSTT return MockSTT() def _tts(s: Settings): if s.tts in (None, "none"): return None from .backends.mock import MockTTS return MockTTS() def _text(s: Settings): if s.text in (None, "none"): return None raise NotImplementedError("discord text channel backend not implemented yet")