feat: add recommendation domain foundations
This commit is contained in:
parent
fad7884c42
commit
5c3ba8d6ec
10 changed files with 446 additions and 0 deletions
28
backend/app/domain/profile.py
Normal file
28
backend/app/domain/profile.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
"""Compress Spotify taste signals for prompts and known-track filtering."""
|
||||
|
||||
from app.domain.models import CompressedTasteProfile, TasteProfile, Track
|
||||
|
||||
|
||||
def compress_taste_profile(profile: TasteProfile) -> CompressedTasteProfile:
|
||||
"""Build compact prompt text and the complete known track identifier set."""
|
||||
sections = (
|
||||
_line("Short-term top artists", profile.short_term_artists),
|
||||
_line("Long-term top artists", profile.long_term_artists),
|
||||
_line("Short-term top tracks", _track_labels(profile.short_term_tracks)),
|
||||
_line("Long-term top tracks", _track_labels(profile.long_term_tracks)),
|
||||
_line("Saved-track sample", _track_labels(profile.saved_tracks)),
|
||||
)
|
||||
known_tracks = (*profile.short_term_tracks, *profile.long_term_tracks, *profile.saved_tracks)
|
||||
return CompressedTasteProfile(
|
||||
text="\n".join(sections),
|
||||
known_track_ids=frozenset(track.id for track in known_tracks),
|
||||
)
|
||||
|
||||
|
||||
def _track_labels(tracks: tuple[Track, ...]) -> tuple[str, ...]:
|
||||
return tuple(f"{track.title} by {', '.join(track.artists)}" for track in tracks)
|
||||
|
||||
|
||||
def _line(label: str, values: tuple[str, ...]) -> str:
|
||||
rendered_values = "; ".join(values) if values else "none"
|
||||
return f"{label}: {rendered_values}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue