Skip to content

Smart playlist plugin#3630

Open
dmoo500 wants to merge 34 commits intomusic-assistant:devfrom
dmoo500:feature/smart-playlist-plugin
Open

Smart playlist plugin#3630
dmoo500 wants to merge 34 commits intomusic-assistant:devfrom
dmoo500:feature/smart-playlist-plugin

Conversation

@dmoo500
Copy link
Copy Markdown
Contributor

@dmoo500 dmoo500 commented Apr 10, 2026

Smart Playlist Plugin

A new plugin provider that enables smart (rule-based) playlists in Music Assistant.

Features

  • Filter rules: Genre, Artist, Album, Favorites only, Min. popularity, Year range
  • Seed-based dynamic mode: pick a track → get similar tracks via provider SIMILAR_TRACKS (e.g. Apple Music, Spotify)
  • AND / OR logic for combining filters
  • Fixed and dynamic playlist modes (dynamic refreshes on every play)
  • Human-readable rule summary stored as playlist description [Smart Playlist] ...
  • REST API: create, update_rules, get_rules, list, generate, count_tracks, preview_tracks

Seed track behaviour

When a seed track URI is set:

  • artist_ids / album_ids are ignored (incompatible with similar-track lookup)
  • Genre (AND mode), Favorites, Min. popularity and Year range are applied as post-filters on the returned similar tracks
  • Year and genre filters are best-effort: tracks without those metadata fields are kept rather than excluded

Moos, Daniel added 4 commits April 9, 2026 23:30
- Fix parse_uri unpacking order (provider/item_id were swapped)
- Fix _evaluate_and returning all library tracks for seed-only rules
- Apply genre filter (AND mode) to similar tracks (best-effort)
- Apply year filter to similar tracks (keep tracks with missing year metadata)
- Add seed_track_name field for human-readable playlist description
- Fix human_readable(): seed_track was incorrectly nested inside album_ids block
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 10, 2026

🔒 Dependency Security Report

✅ No dependency changes detected in this PR.

@dmoo500 dmoo500 marked this pull request as ready for review April 16, 2026 16:35
Copilot AI review requested due to automatic review settings April 16, 2026 16:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “Smart Playlist” provider that lets Music Assistant expose rule-based library playlists (including seed/similar-track mode) and includes a dedicated test suite for rules/validation/evaluation.

Changes:

  • Introduces SmartPlaylistProvider (music provider) with persisted rule storage, playlist generation, and custom API endpoints for CRUD + preview/count/generate.
  • Adds SmartPlaylistRules + validation + JSON read/write helpers.
  • Adds provider assets (manifest + icon) and a new pytest module covering core rule behavior.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
music_assistant/providers/smart_playlist/__init__.py Implements the provider, rule evaluation, persistence, and API commands.
music_assistant/providers/smart_playlist/helpers.py Defines the rules dataclass, validation, and JSON I/O helpers.
music_assistant/providers/smart_playlist/manifest.json Registers the provider and its metadata/docs link.
music_assistant/providers/smart_playlist/icon.svg Adds provider icon used for playlist imagery.
tests/providers/test_smart_playlist.py Adds unit tests for rules serialization/validation and evaluation behavior.

Comment thread music_assistant/providers/smart_playlist/manifest.json Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py
@dmoo500
Copy link
Copy Markdown
Contributor Author

dmoo500 commented Apr 19, 2026

The Dependency Security Check CI failure is not caused by this PR.

audible==0.10.0 (Audible provider) is incompatible with Python 3.14 and this issue is already present on dev since commit c72c193e ("Bump Python to 3.14"). This PR simply inherits the failure.

There is currently no open PR to fix this. A separate PR targeting dev is needed — either by updating audible to a Python 3.14-compatible version or by finding an alternative.

Comment thread music_assistant/providers/smart_playlist/helpers.py Outdated
Comment thread music_assistant/providers/smart_playlist/helpers.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
…nload cleanup, OR-logic bug fix, fetch_limit cap
Copilot AI review requested due to automatic review settings April 20, 2026 08:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 7 comments.

Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/__init__.py
Comment thread music_assistant/providers/smart_playlist/__init__.py
Comment thread music_assistant/providers/smart_playlist/__init__.py Outdated
Comment thread music_assistant/providers/smart_playlist/helpers.py
Comment thread music_assistant/providers/smart_playlist/manifest.json Outdated
Comment thread tests/providers/test_smart_playlist.py
…eview limit clamp, fetch cap, year range validation
Copilot AI review requested due to automatic review settings April 20, 2026 14:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Comment thread music_assistant/providers/smart_playlist/__init__.py
Comment thread tests/providers/test_smart_playlist.py
Moos, Daniel and others added 18 commits April 20, 2026 17:15
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Detailed how-to-use guidance lives in _demo_plugin_provider's commented
stubs; the base class methods only need a one-line summary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Originally added for a soft-validation warning at provider load that
was scoped out of the plan. No callers remained.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…fallback

The dispatch helper returns the full ProviderInstanceType union; an
isinstance check on (MetadataProvider, PluginProvider) lets mypy verify
the get_similar_tracks/get_similar_artists call without suppressions
and is also runtime-defensive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The dispatch helper's priority filter already guarantees the runtime
type, so the isinstance branch was redundant. cast inside the try makes
the invariant explicit without an extra runtime check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the style of _demo_music_provider: real method signatures with
docstrings + inline guidance, returning empty results. Easier for plugin
authors to copy/paste than commented-out blocks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… items

Plugins surfacing playlists via browse/recommendations need their items
fetchable via the standard MediaControllerBase.get_provider_item path.
Previously the controller hard-cast every provider to MusicProvider and
called provider.get_item, which doesn't exist on PluginProvider.

- Add PluginProvider.get_item dispatcher (PLAYLIST -> get_playlist for now).
- Widen the cast in MediaControllerBase.get_provider_item to
  MusicProvider | PluginProvider.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dmoo500 dmoo500 marked this pull request as draft April 30, 2026 13:09
@dmoo500 dmoo500 marked this pull request as ready for review May 1, 2026 10:32
Copilot AI review requested due to automatic review settings May 1, 2026 10:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comment thread music_assistant/providers/smart_playlist/__init__.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants