discovery-by-llm/backend/app/ports/protocols.py

32 lines
977 B
Python

"""Port definitions — every adapter implements one of these protocols."""
from collections.abc import AsyncIterator
from typing import Protocol
from app.domain.models import Recommendation, TasteProfile, Track
class MusicCatalog(Protocol):
"""Resolve, verify, and personalise against a music catalog."""
async def search_track(self, title: str, artist: str) -> Track | None: ...
async def fetch_taste_profile(self) -> TasteProfile: ...
class Recommender(Protocol):
"""The two LLM calls: intent + candidates, then streamed rerank."""
async def propose_candidates(
self, query: str, profile_summary: str
) -> list[tuple[str, str]]: ...
def rerank(
self, query: str, profile_summary: str, grounded: list[Track]
) -> AsyncIterator[Recommendation]: ...
class PlaylistWriter(Protocol):
"""Persist a recommendation set as a playlist."""
async def create_playlist(self, name: str, tracks: list[Track]) -> str: ...