Add named taste profiles for per-person recommendations
Named profiles allow each household member to get personalized recommendations without polluting each other's taste. Includes profile CRUD API, speaker→profile auto-attribution, recent listen history endpoint, and profile param on all existing endpoints. All endpoints backward compatible (no profile param = "default"). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
42
README.md
42
README.md
@@ -49,10 +49,17 @@ docker exec haunt-fm alembic upgrade head
|
||||
| GET | `/api/status` | Full pipeline status JSON |
|
||||
| GET | `/` | HTML status dashboard |
|
||||
| POST | `/api/history/webhook` | Log a listen event (from HA automation) |
|
||||
| GET | `/api/history/recent?limit=20&profile=name` | Recent listen events (optional profile filter) |
|
||||
| POST | `/api/admin/discover` | Expand listening history via Last.fm |
|
||||
| POST | `/api/admin/build-taste-profile` | Rebuild taste profile from embeddings |
|
||||
| GET | `/api/recommendations?limit=50&vibe=chill+ambient` | Get ranked recommendations (optional vibe) |
|
||||
| POST | `/api/playlists/generate` | Generate and optionally play a playlist |
|
||||
| GET | `/api/profiles` | List all named profiles with stats |
|
||||
| POST | `/api/profiles` | Create a named profile |
|
||||
| GET | `/api/profiles/{name}` | Get profile details + stats |
|
||||
| DELETE | `/api/profiles/{name}` | Delete profile (reassigns events to default) |
|
||||
| PUT | `/api/profiles/{name}/speakers` | Set speaker→profile mappings |
|
||||
| GET | `/api/profiles/{name}/speakers` | List speaker mappings |
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -89,6 +96,7 @@ curl -X POST http://192.168.86.51:8321/api/playlists/generate \
|
||||
- `auto_play` — `true` to immediately play on the speaker
|
||||
- `vibe` — text description of the desired mood/vibe (e.g. "chill lo-fi beats", "upbeat party music"). Uses CLAP text embeddings to match tracks in the same vector space as audio.
|
||||
- `alpha` — blend factor between taste profile and vibe (default 0.5). `1.0` = pure taste profile, `0.0` = pure vibe match, `0.5` = equal blend. Ignored when no vibe is provided.
|
||||
- `profile` — named taste profile to use (default: "default"). Each profile has its own listening history and taste embedding.
|
||||
|
||||
### Speaker entities
|
||||
|
||||
@@ -110,6 +118,40 @@ The `speaker_entity` **must** be a Music Assistant entity (the `_2` suffix ones)
|
||||
| downstairs | `media_player.downstairs_2` |
|
||||
| upstairs | `media_player.upstairs_2` |
|
||||
|
||||
### Named profiles
|
||||
|
||||
Named profiles let each household member get personalized recommendations without polluting each other's taste.
|
||||
|
||||
```bash
|
||||
# Create a profile
|
||||
curl -X POST http://192.168.86.51:8321/api/profiles \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"antialias","display_name":"Me"}'
|
||||
|
||||
# Map speakers to auto-attribute listens
|
||||
curl -X PUT http://192.168.86.51:8321/api/profiles/antialias/speakers \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"speakers":["Study speaker","Master bathroom speaker"]}'
|
||||
|
||||
# Log a listen event with explicit profile
|
||||
curl -X POST http://192.168.86.51:8321/api/history/webhook \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"title":"Song","artist":"Artist","profile":"antialias"}'
|
||||
|
||||
# Get recommendations for a profile
|
||||
curl "http://192.168.86.51:8321/api/recommendations?limit=20&profile=antialias"
|
||||
|
||||
# Generate playlist for a profile
|
||||
curl -X POST http://192.168.86.51:8321/api/playlists/generate \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"total_tracks":20,"profile":"antialias","speaker_entity":"media_player.study_speaker_2","auto_play":true}'
|
||||
|
||||
# Build taste profile manually
|
||||
curl -X POST "http://192.168.86.51:8321/api/admin/build-taste-profile?profile=antialias"
|
||||
```
|
||||
|
||||
All endpoints are backward compatible — omitting `profile` uses the "default" profile. Events with no profile assignment (including all existing events) belong to "default".
|
||||
|
||||
### Other operations
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user