from typing import Callable, Protocol, runtime_checkable from lyra_worker.types import Candidate, DownloadResult, MBTarget @runtime_checkable class SourceAdapter(Protocol): name: str tier: int def health(self) -> bool: """Is this source configured and reachable?""" ... def search(self, target: MBTarget) -> list[Candidate]: """Return zero or more candidates matching target. No downloading.""" ... def download( self, candidate: Candidate, dest: str, on_progress: Callable[[float], None] ) -> DownloadResult: """Fetch candidate into dest, reporting progress 0.0..1.0.""" ...