Yandex Smart Home: bump v1.4.5 → v2.1.2#3834
Yandex Smart Home: bump v1.4.5 → v2.1.2#3834trudenboy wants to merge 54 commits intomusic-assistant:devfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR bumps the yandex_smarthome plugin to v1.5.0 and adds support for exposing configured MA library playlists as Yandex mode(input_source) values, enabling Alice voice commands to start playlist playback via player_queues.play_media.
Changes:
- Add “Exposed Playlists” configuration and plumb
playlist_uristhrough cloud/direct handlers and state notifier. - Extend device mapping to publish combined native sources + playlist-backed
mode(input_source)slots (capped at 10) and route mode actions to eitherplayers.select_sourceorplayer_queues.play_media. - Add a small
playlists.pyseam plus tests covering the new mode registration and action routing.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
music_assistant/providers/yandex_smarthome/__init__.py |
Adds config UI entry for selecting playlists and loads options from MA library. |
music_assistant/providers/yandex_smarthome/constants.py |
Introduces CONF_EXPOSED_PLAYLISTS and MAX_INPUT_SOURCES (10). |
music_assistant/providers/yandex_smarthome/device.py |
Implements combined input_source slots and executes playlist-backed mode actions via queue playback. |
music_assistant/providers/yandex_smarthome/direct.py |
Passes configured playlist URIs through the direct HTTP handlers. |
music_assistant/providers/yandex_smarthome/handlers.py |
Threads playlist_uris through device list/query/action handling. |
music_assistant/providers/yandex_smarthome/notifier.py |
Includes playlist-aware input_source capability/state reporting in callbacks. |
music_assistant/providers/yandex_smarthome/playlists.py |
New helper module for config options + starting playlist playback. |
music_assistant/providers/yandex_smarthome/plugin.py |
Parses/sanitizes playlist URI config and wires it into handlers/notifier. |
tests/providers/yandex_smarthome/test_device.py |
Adds coverage for combined modes and playlist/native action routing. |
tests/providers/yandex_smarthome/test_handlers.py |
Adds coverage that playlist URIs trigger mode(input_source) capability registration. |
🔒 Dependency Security Report📦 Modified Dependencies
|
| Name | Skip Reason |
|---|---|
| torch | Dependency not found on PyPI and could not be audited: torch (2.11.0+cpu) |
| torchaudio | Dependency not found on PyPI and could not be audited: torchaudio (2.11.0+cpu) |
| ✅ No known vulnerabilities found |
Automated Security Checks
- ✅ Vulnerability Scan: Passed - No known vulnerabilities
- ✅ Trusted Sources: All packages have verified source repositories
- ✅ Typosquatting Check: No suspicious package names detected
- ✅ License Compatibility: All licenses are OSI-approved and compatible
- ✅ Supply Chain Risk: Passed - packages appear mature and maintained
Manual Review
Maintainer approval required:
- I have reviewed the changes above and approve these dependency updates
To approve: Comment /approve-dependencies or manually add the dependencies-reviewed label.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 30 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
music_assistant/providers/yandex_smarthome/device.py:149
- [PROBLEM]
_mode_to_sourceis now unused after switching input_source actions to_resolve_combined_slot, leaving dead code that can drift from the active mapping logic; remove it (and its docstring) or reintroduce a caller if it’s still needed.
def _mode_to_source(mode_value: str, source_list: list[PlayerSource]) -> str | None:
"""Resolve a Yandex mode value to an MA source id."""
try:
idx = YANDEX_MODE_VALUES.index(mode_value)
except ValueError:
return None
if idx >= len(source_list):
return None
return source_list[idx].id
Copilot review on upstream PR music-assistant/server#3834 flagged this helper as defined but never used — the live code path uses resolve_base_url from _smarthome_auto_create.py instead. Drop the dead helper to shrink maintenance surface. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Bumps the
yandex_smarthomeplugin provider from v1.4.5 → v2.1.2. The work since the upstream baseline is best understood in three buckets — but the upstream sync intentionally lands as a single net diff (no intermediate-version commits), so the description below focuses on the shipping state, not the journey.Source repo: trudenboy/ma-provider-yandex-smarthome · tag v2.1.2
Net change: +1,873 / −4,468 LOC across 29 files. The big negative number is the voice extraction (next bullet).
What changed since v1.4.5
Voice skill extracted to a separate provider
The Yandex Dialogs custom skill (free-form Russian voice control via a webhook custom skill — «Алиса, попроси Music Assistant включи джаз на кухне») lived in
provider/dialogs*.pyfrom v1.6.0 through v1.9.1, accumulating ~3,100 LOC and 137 tests of NLU + state management. In v2.0.0 it was extracted into a dedicated provider —ma-provider-yandex-alice— and removed from this repo entirely. Smart Home users were never required to enable voice; users who DID enable voice install the new provider and re-paste theirskill_id/ OAuth token. Migration block in smarthome 2.0.0 CHANGELOG.The
dialogs*.pyfiles in this PR appear as deletions for that reason.Yandex Dialogs Developer API client extracted to a PyPI library
The
auto_skill.py(~1,630 LOC reverse-engineered from DevTools traces, drives the dev-console programmatic skill creation) and its state machine were extracted into a generic, framework-agnostic Python library:ya-dialogs-api(Sigstore-signed PyPI release). Both this provider andma-provider-yandex-aliceconsume it viamanifest.json:requirements.requirements_all.txtaddsya-dialogs-api==2.0.0accordingly.provider/auto_skill.py/auto_skill_state.py/_compat.py/auto_skill_logo.pngappear as deletions for that reason.Auto-create flow re-wired against the new lib API
Restored in v2.1.0 against
ya-dialogs-api 2.0.0. The pipeline (Device Flow OAuth → CSRF/cookie session → POST/apps→ upload logo → patch draft → register OAuth app → publish) is intact; only the call site changed. Two new files:provider/_smarthome_auto_create.py(~135 LOC) — URL derivations forcloud_plus+directmodes (backend_uri, OAuth endpoints, client_id, client_secret). Equivalent of thederive_*helpers that previously lived insideauto_skill.py.provider/ma_authenticator.py(~365 LOC, ~140 of which are the Device-Code activation HTML page template) — adapter wrappingya-passport-auth.PassportClient.login_device_code+ hosting an MA-flavored activation page onmass.webserver. Conforms to theAuthenticatorCMProtocol thatya-dialogs-api.auto_create_skillexpects (no-arg async-context-manager factory yielding an authorizedaiohttp.ClientSession).The state machine (
SkillCreationArtifacts) checkpoints partial progress; transient failures resume from the last completed step on the next click. State-aware action button: Create… / Retry / Continue / Re-create. Cachedx_token(CONF_AUTH_X_TOKEN) skips the Device Code prompt on subsequent runs within the token's TTL.MA library playlists as Yandex
mode(input_source)slots (v1.5.0 carry-over)Multi-select up to 10 playlists from MA library; ordinal triggers via
one..ten.provider/playlists.pybuilds the option list;_init_input_source_capabilityindevice.pymaps native sources first, then exposed playlists.Direct-mode hardening (v1.7.x carry-over)
Base URLpointing at the local address (so HA Ingress / local UI keep working) while exposing a public HTTPS URL only to Yandex via a reverse proxy.structuredExamplesshape, required top-level fields, backend URI without/v1.0).cmd_power(True)for power-on beforeplay_media;UNKNOWN_USERcallback errors no longer flood logs;CancelledErrorpropagated; webhook secret no longer logged in plain text; track URI format corrected to{instance_id}://track/{id}.Provider modes (no changes vs upstream baseline)
cloud— public Yaha Cloud skill (zero setup, but linked to one MA / HA install per Yandex account).cloud_plus— private skill via the yaha-cloud relay.direct— Yandex calls the MA webserver directly (requires public HTTPS).The auto-create action is available in
cloud_plus+directmodes.Files in this PR
__init__.py,cloud.py,device.py,direct.py,handlers.py,manifest.json,notifier.py,playlists.py,plugin.py,constants.py_smarthome_auto_create.py,ma_authenticator.pyauto_skill.py,auto_skill_state.py,auto_skill_ui.py,_compat.py,auto_skill_logo.pngya-dialogs-apiPyPI lib)test_cloud.py,test_device.py,test_direct.py,test_handlers.pytest_ma_authenticator.py,test_smarthome_auto_create.pytest_auto_skill.py,test_auto_skill_state.py,test_auto_skill_ui.py,test_config_actions.pyya-dialogs-apifor the lib portion)Runtime dependencies
requirements_all.txt:ya-passport-auth==1.3.0— Yandex Passport Device Flow / QR / cookie auth (used byma_authenticator.py).ya-dialogs-api==2.0.0— generic Yandex Dialogs Developer API client. Used by__init__.py:_run_auto_create_action.Verification
pytest tests/providers/yandex_smarthome/— clean on the source repo (224 tests in source repo's own suite; subset syncs upstream).ruff check— clean.# ruff: noqa: RUF001/002/003directives in Cyrillic-heavy modules survive the upstream sync (file-level placement).mypy --strict— no new errors.Companion / related
ma-provider-yandex-alice(v1.0.0) — separate plugin, install if you want voice.ya-dialogs-api— generic Yandex Dialogs Developer API client, framework-agnostic.🤖 Generated with Claude Code