Add Recommendations plugin provider#3890
Conversation
🔒 Dependency Security Report✅ No dependency changes detected in this PR. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new "Recommendations" plugin provider that surfaces additional library-based recommendation folders (e.g., Forgotten Tracks/Albums/Artists, Most Played, Never Played, plus opt-in duplicates of built-in rows) on the home screen, each individually toggleable with a configurable item count.
Changes:
- New plugin provider
recommendationswith manifest, icon, and implementation. - Per-folder enable/limit
ConfigEntrydefinitions and an asyncrecommendations()method that gathers folders concurrently. - Folders use
library_itemswith variousorder_bymodes (e.g.,last_played,play_count_desc,random_play_count).
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| music_assistant/providers/recommendations/manifest.json | Declares the new beta plugin provider metadata. |
| music_assistant/providers/recommendations/icon.svg | Adds the provider icon (bookshelf + plus). |
| music_assistant/providers/recommendations/init.py | Implements RecommendationsProvider, config entries, and folder builders. |
|
I am not sure if we want "the item count is configurable via a dropdown (10 / 20 / 30 / 50)." as that appears to be in response to a comment by one user and Marcel has been talking recently about the need to improve usability for new uers and increasing config options runs counter to that. Also if you are going to have all the duplicates of the builtin rows then I think you either need to remove them from builtin in this PR or in another one? |
| The following folders duplicate the built-in default recommendations and are | ||
| disabled by default. Enable them here and disable the built-in rows via the | ||
| frontend edit mode to use your custom limits instead. | ||
|
|
||
| - Recently Favorited Tracks | ||
| - Recently Favorited Albums | ||
| - Recently Added Tracks | ||
| - Random Artists | ||
| - Random Albums |
| def _get_media_controller(self, media: str) -> MediaControllerBase[Any]: | ||
| """Return the music controller for a supported media type.""" | ||
| if media == "tracks": | ||
| return self.mass.music.tracks | ||
| if media == "albums": | ||
| return self.mass.music.albums | ||
| if media == "artists": | ||
| return self.mass.music.artists | ||
| raise ValueError(f"Unsupported media type for recommendations provider: {media}") |
There was a problem hiding this comment.
I think you can just remove this and replace with
_CONTROLLERS = {
"tracks": lambda self: self.mass.music.tracks,
"albums": lambda self: self.mass.music.albums,
"artists": lambda self: self.mass.music.artists,
}
| def _get_bool(self, key: str) -> bool: | ||
| return cast("bool", self.config.get_value(key)) | ||
|
|
||
| def _get_limit(self, key: str) -> int: | ||
| return cast("int", self.config.get_value(key)) |
There was a problem hiding this comment.
Why have single line helpers which are only used in one place in the code? These should just be inlined.
| # Fetch DESC so never-played (NULL last_played) items sort last; | ||
| # avoids filtering out the entire batch in libraries with many | ||
| # never-played tracks. Reverse afterwards to restore ASC order. | ||
| raw = await controller.library_items( |
There was a problem hiding this comment.
This needs a proper fix. I think the right solution is to add a played_only parameter to library_items in the base controller, which would add last_played IS NOT NULL to the query when set. That keeps the provider code clean. Can you raise this as a separate PR to base.py which will be a prerequisite for this one?
|
Marking as draft just so we can keep track of those that need attention. |
Recommendations Plugin Provider
A new
PluginProviderthat surfaces library-based discovery folders as recommendations on the home screen. Each folder is individually toggleable and the item count is configurable via a dropdown (10 / 20 / 30 / 50).Motivation
The default recommendation folders in
_get_default_recommendations(Recently Favorited, Recently Added, Random Artists/Albums, …) are hardcoded inmusic.pyand cannot be configured or toggled individually by the user. This plugin adds library-based equivalents with full user control, and includes additional folders not available in the defaults (Forgotten Tracks/Albums/Artists, Most Played, Never/Rarely Played).Folders
Each folder has a companion config entry that lets the user choose how many items to show (10 / 20 / 30 / 50). The limit entry is automatically hidden when the folder is disabled (
depends_on).Translation keys follow the
recommendation.<key>pattern so they can be cleanly namespaced inen.json.Screenshots
Forgotten Tracks
Forgotten Albums
Forgotten Artists
Most Played Tracks
Never / Rarely Played