Skip to content

Add Yandex Alice voice assistant plugin provider (v1.3.1)#3843

Draft
trudenboy wants to merge 12 commits intomusic-assistant:devfrom
trudenboy:upstream/yandex_alice
Draft

Add Yandex Alice voice assistant plugin provider (v1.3.1)#3843
trudenboy wants to merge 12 commits intomusic-assistant:devfrom
trudenboy:upstream/yandex_alice

Conversation

@trudenboy
Copy link
Copy Markdown
Contributor

@trudenboy trudenboy commented May 6, 2026

Yandex Alice voice-skill provider

Source repo: trudenboy/ma-provider-yandex-alice

Exposes Music Assistant playback to Yandex Alice as a Yandex Dialogs custom skill. The user activates the skill by saying "Алиса, попроси ..."; Yandex transcribes the rest of the phrase and POSTs it to a webhook on the MA webserver, where the request is dispatched against eleven custom grammars declared on Yandex's side, with a Russian regex-based NLU as the long-tail fallback.

Voice command surface

Playback (play artist / genre / playlist, what's playing, pause / resume / stop, next / previous, volume, mute), queue control (shuffle, repeat, seek, jump-to-start, add-to-queue), multi-room (transfer / continue / start playback on a named player, list / forget players), voice-first ordinal disambiguation when a player name is ambiguous. Russian NLU handles morphologically inflected forms, fuzzy player-name matching, and Yandex Station's session-state quirks. Built-in YANDEX.REJECT / YANDEX.HELP are wired into disambiguation/slot-elicit flows for clean cancel-and-help UX.

Architecture

music_assistant/providers/yandex_alice/ — three layers, ~3,200 LOC:

  • Webhook + NLUdialogs.py, dialogs_nlu.py, dialogs_control.py, dialogs_player.py, dialogs_grammar.py, tts_dictionary.py. TTL-keyed in-process state cache, platform-intent dispatch (request.nlu.intents first, regex parsers as fallback), eleven custom Yandex grammars, YANDEX.NUMBER entity for relative-volume phrasings, dangerous_context graceful refusal with log redaction, screen-aware suggestion buttons, foreign-band TTS transliteration (~40 phrases), opt-in voice-continuation toggle, post-auth try / except so dispatch errors land as a Russian fallback instead of HTTP 500.
  • Setup form + skill lifecyclesetup_view.py, __init__.py, auth_page.py, auto_create.py, auto_update.py, publication_status.py, webhook_probe.py, url_helpers.py, dialog_skill_meta.py. Three-section form (Authorization / Skill / Settings), blocking Device Flow with custom user_code page, full skill lifecycle (create / adopt / recreate / edit / delete), live publication-status banner, public-HTTPS validation (rejects private/loopback/link-local hosts), declarative custom-intent sync via set_intents.
  • Plugin glueplugin.py, auth_session.py, constants.py, manifest.json. Webhook route registration, diagnostics counters, env-overridable channel, bundled provider icon + skill catalog logo.

tests/providers/yandex_alice/466 unit tests, no live Yandex calls.

Runtime dependencies

requirements_all.txt adds:

  • ya-dialogs-api ==2.1.0 — Yandex Dialogs developer-console API client. 2.1.0 adds programmatic management of custom intent grammars (IntentDraft + set_intents / list_intents / update_intent / delete_intent / create_intent) wrapping the private /apps/{id}/intents/* endpoints; endpoints and payload shape derived from a Playwright probe of the live dev console (full network capture in the library's RESEARCH.md § 7).
  • ya-passport-auth ==1.3.0 — Yandex Passport Device Flow / cookie auth.

Both are shared with the yandex_smarthome provider and Sigstore-signed on PyPI.

What's new since the original v1.2.0 PR

Source release Adds / fixes
v1.2.1 Align with upstream MA pre-commit lint rules (ruff).
v1.2.2 build_backend_uri and webhook_probe._validate_inputs now route URLs through is_public_https_url and reject private / loopback / link-local hosts up front (Copilot review threads #1, #2).
v1.2.3 Device-code popup URL built via mass.webserver.base_url so the popup works under the Home Assistant ingress prefix.
v1.3.0 Maximum platform integration (Phases 0–2 of docs/NLU_RESEARCH.md). Read the rest of the request envelope (meta.interfaces.screen, request.markup.dangerous_context, request.nlu.entities[YANDEX.NUMBER] for volume_relative, request.original_utterance for misclassification logs). Eleven custom intent grammars declared on the skill via ya-dialogs-api 2.1.0 and dispatched via request.nlu.intents; built-in YANDEX.REJECT / YANDEX.HELP wired into pending-prompt flows. Screen-aware suggestion buttons, ~40 foreign-band TTS transliterations, opt-in voice-continuation toggle, root CLAUDE.md aligned with upstream conventions, six existing Google-style docstrings converted to Sphinx-style (per @chrisuthe review), and try / except around post-auth dispatch so an inner raise surfaces as a Russian fallback instead of HTTP 500 → Alice silence.
v1.3.1 Inline # codespell:ignore sting for the artist Стинг in tts_dictionary.py (codespell on this PR's CI flagged it as a typo of string).

Resolved review threads on this PR

  • @chrisuthe — webhook handler error handling: post-auth dispatch wrapped in try / except (v1.3.0).
  • @chrisuthe — Sphinx-style docstrings: six existing Google-style sections converted (v1.3.0).
  • Copilot — build_backend_uri rejecting private hosts (v1.2.2).
  • Copilot — webhook_probe._validate_inputs rejecting private hosts (v1.2.2).
  • Copilot — dangerous_context log leak: command / original_utterance redacted to <redacted: dangerous_context> when the flag is set (v1.3.0 follow-up, in source PR #18).
  • Copilot — volume_relative zero-magnitude clamp: 0 preserved end-to-end instead of silently promoted to +1 (v1.3.0 follow-up).
  • Copilot — CONF_DIALOG_VOICE_CONTINUATION doc-comment accuracy (v1.3.0 follow-up).

Verification

pytest tests/providers/yandex_alice/ (466 passed) · ruff check + format · mypy · codespell — all green on the source-repo CI (latest run). Source PR #18 merged 2026-05-07.

Related

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🔒 Dependency Security Report

📦 Modified Dependencies

music_assistant/providers/yandex_alice/manifest.json

Added:

The following dependencies were added or modified:

diff --git a/requirements_all.txt b/requirements_all.txt
index 65aec400..9887c971 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -88,6 +88,7 @@ uv>=0.8.0
 websocket-client==1.9.0
 wiim==0.1.4
 xmltodict==1.0.4
+ya-dialogs-api==2.1.0
 ya-passport-auth==1.3.0
 yandex-music==3.0.0
 ytmusicapi==1.11.5

New/modified packages to review:

  • ya-dialogs-api==2.1.0

🔍 Vulnerability Scan Results

No known vulnerabilities found

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.

@trudenboy trudenboy changed the title feat(yandex_alice): add yandex_alice provider v1.0.0 add Yandex Alice voice assistant plugin provider v1.0.0 May 6, 2026
@trudenboy trudenboy changed the title add Yandex Alice voice assistant plugin provider v1.0.0 Add Yandex Alice voice assistant plugin provider (v1.1.0) May 6, 2026
@trudenboy trudenboy changed the title Add Yandex Alice voice assistant plugin provider (v1.1.0) Add Yandex Alice voice assistant plugin provider (v1.2.0) May 7, 2026
@trudenboy trudenboy marked this pull request as ready for review May 7, 2026 14:59
Copilot AI review requested due to automatic review settings May 7, 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

Adds a new Yandex Alice plugin provider that exposes Music Assistant playback control via a Yandex Dialogs custom-skill webhook, including a full config/setup experience (Passport Device Flow sign-in, auto-create/update skill lifecycle, webhook reachability probe) and a comprehensive unit test suite.

Changes:

  • Introduces music_assistant/providers/yandex_alice/ implementing the webhook handler, Russian NLU, playback/control dispatch, and skill lifecycle helpers (create/update/publication status).
  • Adds config-flow UI builders for a 3-section setup (Authorization / Skill / Settings) and supporting helpers (URL detection/validation, skill logo loader, webhook probe).
  • Adds an extensive test suite under tests/providers/yandex_alice/ and updates requirements_all.txt for ya-dialogs-api.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
requirements_all.txt Adds ya-dialogs-api to the full dependency set.
music_assistant/providers/yandex_alice/manifest.json Declares the new plugin provider and its runtime requirements.
music_assistant/providers/yandex_alice/__init__.py Config-entry builder + action dispatcher for sign-in/create/update/delete/probe flows.
music_assistant/providers/yandex_alice/plugin.py PluginProvider glue: loads config, registers/unregisters webhook routes, exposes diagnostics.
music_assistant/providers/yandex_alice/dialogs.py Webhook HTTP handler: request auth (secret + skill_id), state handling, NLU dispatch, disambiguation, responses.
music_assistant/providers/yandex_alice/dialogs_nlu.py Russian NLU for “play …” commands + fuzzy player resolution utilities.
music_assistant/providers/yandex_alice/dialogs_control.py Russian NLU for transport/volume/queue control + executor dispatch into MA APIs.
music_assistant/providers/yandex_alice/dialogs_player.py Media resolver + power-on/play wrapper for executing parsed play intents.
music_assistant/providers/yandex_alice/auto_create.py Auto-create skill pipeline wrapper (duplicate pre-check + create/update/deploy orchestration).
music_assistant/providers/yandex_alice/auto_update.py Cached-token-only skill update wrapper (rename/drift sync/edit updates).
music_assistant/providers/yandex_alice/auth_session.py Cached Passport-cookie session/authenticator helpers for ya-dialogs-api integration.
music_assistant/providers/yandex_alice/auth_page.py Device Flow auth UI: dynamic web routes + popup flow + polling until confirmed.
music_assistant/providers/yandex_alice/url_helpers.py Public HTTPS URL validation + best-effort base URL detection helpers.
music_assistant/providers/yandex_alice/webhook_probe.py Outgoing POST probe to validate webhook reachability/status classification.
music_assistant/providers/yandex_alice/dialog_skill_meta.py Pure helpers for skill metadata + URL assembly + validation.
music_assistant/providers/yandex_alice/publication_status.py Snapshot-based publication status fetch + classification for config UI banners.
music_assistant/providers/yandex_alice/setup_view.py Config form composition (Authorization/Skill/Settings), edit-mode UX, advanced fields, status banners.
music_assistant/providers/yandex_alice/skill_logo.py Loads bundled logo bytes with fallback to library default.
music_assistant/providers/yandex_alice/icon.svg Provider icon asset.
music_assistant/providers/yandex_alice/skill_logo.png Bundled skill logo asset.
tests/providers/yandex_alice/__init__.py Test package marker.
tests/providers/yandex_alice/test_auth_session.py Unit tests for cached Passport session/authenticator behavior.
tests/providers/yandex_alice/test_auto_create.py Unit tests for auto-create pipeline wrapper + duplicate/adopt/recreate paths.
tests/providers/yandex_alice/test_auto_update.py Unit tests for auto-update wrapper + auth failure handling.
tests/providers/yandex_alice/test_dialog_skill_meta.py Tests for pure skill metadata helpers.
tests/providers/yandex_alice/test_dialog_skill_meta_v12.py Tests for v1.2.0 skill-name validation rules.
tests/providers/yandex_alice/test_dialogs_control.py Tests for control NLU parsing + executor dispatch.
tests/providers/yandex_alice/test_dialogs_nlu.py Tests for play-command NLU parsing + player resolution.
tests/providers/yandex_alice/test_dialogs_player.py Tests for query resolver + play orchestration.
tests/providers/yandex_alice/test_dialogs.py Tests covering webhook handler behavior/state/disambiguation flows.
tests/providers/yandex_alice/test_init_actions.py Integration-style tests for config action dispatch/rehydration semantics.
tests/providers/yandex_alice/test_url_helpers.py Tests for public-HTTPS detection/validation helpers.
tests/providers/yandex_alice/test_webhook_probe.py Tests for webhook probe input validation + status/exception mapping.

Comment thread music_assistant/providers/yandex_alice/dialog_skill_meta.py
Comment thread music_assistant/providers/yandex_alice/webhook_probe.py
@chrisuthe
Copy link
Copy Markdown
Member

@trudenboy One thing I'd suggest as a starting point here is to have an AI find and let you replace all the google style docstrings. The claude.md tries to get it across:

Use Sphinx-style docstrings with :param: syntax. For simple functions, a single-line docstring is fine.
Don't explain inner workings of the code in the docstrings (you can use inline comments for that if/when needed). The docstring should provide clarity to the caller of the function/method, not explain how it works technically/internally.

def my_function(param1: str, param2: int, param3: bool = False) -> str:
    """
    Brief one-line description of the function.

    :param param1: Description of what param1 is used for.
    :param param2: Description of what param2 is used for.
    :param param3: Description of what param3 is used for.
    """

Do not use Google-style (Args:) or bullet-style (- param:) docstrings.

But it's easy to bypass if AI is helpfully generating docstrings for you.

Comment thread music_assistant/providers/yandex_alice/dialogs.py Outdated
@trudenboy trudenboy requested a review from Copilot May 7, 2026 20:52
trudenboy added a commit to trudenboy/ma-provider-yandex-alice that referenced this pull request May 7, 2026
Upstream music-assistant/server uses its own pyproject.toml codespell
config and doesn't pick up our ignore-words-list addition. The inline
directive works regardless of repo-level config — the entry is the
artist Стинг, not a typo of 'string'.

Failing upstream CI run: music-assistant/server#3843 lint job
(25521399342).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 33 out of 36 changed files in this pull request and generated 2 comments.

Comment on lines +80 to +81
"No cached authentication — run 'Create skill' first "
"to sign in via Yandex Passport."
failed = dataclasses.replace(
artifacts,
state=SkillCreationState.FAILED,
last_error=("Cached auth has expired. Run 'Create skill' to re-authenticate."),
@trudenboy trudenboy changed the title Add Yandex Alice voice assistant plugin provider (v1.2.0) Add Yandex Alice voice assistant plugin provider (v1.3.1) May 7, 2026
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.

3 participants