Skip to content

fix(plugins): start configured speech providers#76540

Merged
amknight merged 2 commits into
mainfrom
ak/issue-76481-microsoft-speech
May 3, 2026
Merged

fix(plugins): start configured speech providers#76540
amknight merged 2 commits into
mainfrom
ak/issue-76481-microsoft-speech

Conversation

@amknight

@amknight amknight commented May 3, 2026

Copy link
Copy Markdown
Member

Summary

  • Problem: Gateway startup did not activate configured speech-provider plugins like Microsoft, so TTS providers appeared loaded in plugin metadata but were absent from the startup plugin set.
  • Why it matters: Users upgrading to 2026.5.2 could select messages.tts.provider=microsoft and still get no Telegram voice replies because the Microsoft speech plugin never started with the Gateway.
  • What changed: Gateway startup planning now detects configured TTS providers and includes the owning bundled speech-provider plugin, including the legacy edge alias for Microsoft.
  • What did NOT change (scope boundary): Provider synthesis, Telegram delivery, plugin install flows, and model-provider startup behavior are unchanged.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: Startup plugin planning handled configured channels, startup sidecars, memory, harnesses, and generic activation paths, but did not treat configured messages.tts speech-provider ownership as a startup activation signal.
  • Missing detection / guardrail: There was no startup-planner regression test for messages.tts.provider selecting a plugin-owned speech provider.
  • Contributing context (if known): Speech providers are manifest-declared plugin contracts and can still resolve lazily for local capability calls, which masked the Gateway startup omission.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/plugins/channel-plugin-ids.test.ts
  • Scenario the test should lock in: messages.tts.provider: "microsoft", legacy "edge", and provider blocks such as messages.tts.providers["tts-local-cli"] include the owning speech plugin in Gateway startup unless explicitly disabled.
  • Why this is the smallest reliable guardrail: The bug was in the startup plugin planner, before provider synthesis or channel delivery runs.
  • Existing test that already covers this (if any): None.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

Configured TTS speech providers such as Microsoft and Local CLI are now activated during Gateway startup, so voice replies work after selecting those providers.

Diagram (if applicable)

Before:
messages.tts.provider=microsoft -> startup plan omits microsoft -> Gateway has no Microsoft speech provider

After:
messages.tts.provider=microsoft -> startup plan includes microsoft -> Gateway can synthesize TTS replies

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS local source checkout
  • Runtime/container: Node 25 local dev runtime; npm-installed OpenClaw 2026.5.2 for reproduction
  • Model/provider: Microsoft speech provider
  • Integration/channel (if any): TTS / Telegram-reported path
  • Relevant config (redacted): messages.tts.provider=microsoft, plugins.entries.microsoft.enabled=true

Steps

  1. Install/run OpenClaw 2026.5.2 with messages.tts.provider=microsoft.
  2. Start Gateway and inspect startup plugin log / startup planner output.
  3. Apply fix and rerun the startup planner/tests.

Expected

  • Microsoft appears in the Gateway startup plugin set when selected as the speech provider.

Actual

  • Before this fix, Microsoft was omitted from Gateway startup even though plugin metadata showed it as loaded/enabled.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Before fix, local planner repro omitted Microsoft:

startup [acpx, bonjour, browser, device-pair, file-transfer, memory-core, phone-control, talk-voice]

After fix, local planner repro includes Microsoft:

["microsoft"]

Validation run:

OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test src/plugins/channel-plugin-ids.test.ts
pnpm check:changed
pnpm test:changed

Human Verification (required)

  • Verified scenarios: startup planner includes Microsoft for messages.tts.provider=microsoft, includes Local CLI for provider-block config, maps legacy edge to Microsoft, and respects disabled provider/plugin config.
  • Edge cases checked: disabled provider blocks and explicit plugins.entries.microsoft.enabled=false do not force activation.
  • What you did not verify: A live Telegram voice message delivery with a real Telegram bot token.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: More configured speech providers may start with the Gateway when they were previously loaded lazily.
    • Mitigation: Activation is limited to manifest-declared speech-provider owners and still honors explicit plugin/provider disablement and deny lists.

@openclaw-barnacle openclaw-barnacle Bot added size: M maintainer Maintainer-authored PR labels May 3, 2026
@clawsweeper

clawsweeper Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge.

Summary
The PR adds startup planning for manifest-owned speech provider plugins selected by TTS config, plus regression tests and a changelog entry.

Reproducibility: yes. at source level: current main's startup planner never inspects messages.tts speech-provider contracts, matching the reported v2026.5.2 Microsoft startup omission. I did not run tests because this review was constrained to read-only inspection.

Next step before merge
A narrow automated repair can adjust the persona disablement edge and add one focused regression test without a product decision.

Security
Cleared: No concrete security or supply-chain concern found; the diff touches startup planning, tests, and changelog only, with no dependency, workflow, script, permission, or secret-handling changes.

Review findings

  • [P3] Preserve disabled root provider blocks for personas — src/plugins/gateway-startup-speech-providers.ts:111-113
Review details

Best possible solution:

Align startup speech-provider discovery with effective TTS provider/config merge semantics, then land the narrow startup planner, regression-test, and changelog change for #76481.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level: current main's startup planner never inspects messages.tts speech-provider contracts, matching the reported v2026.5.2 Microsoft startup omission. I did not run tests because this review was constrained to read-only inspection.

Is this the best way to solve the issue?

No, not quite. The PR is in the right layer, but active-persona provider startup should preserve root provider-block disablement unless the persona binding explicitly re-enables that provider.

Full review comments:

  • [P3] Preserve disabled root provider blocks for personas — src/plugins/gateway-startup-speech-providers.ts:111-113
    addActivePersonaProvider treats any personas.<id>.providers.<provider> object as enabled and lets it override messages.tts.providers.<provider>.enabled=false. Runtime TTS merges the root provider config with the persona binding, so a persona binding without enabled: true keeps the root disabled flag and the provider remains not configured; startup should not add that plugin in this case.
    Confidence: 0.78

Overall correctness: patch is correct
Overall confidence: 0.82

Acceptance criteria:

  • OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test src/plugins/channel-plugin-ids.test.ts
  • pnpm check:changed

What I checked:

Likely related people:

  • vincentkoc: Blame on the central startup planner and startup tests points to the plugin metadata/startup refactor, and recent local history shows repeated plugin registry and launch-spec maintenance in src/plugins. (role: recent plugin/startup maintainer; confidence: medium; commits: c7bbb3f9af36, 4545a0ed61, 07e0342106; files: src/plugins/gateway-startup-plugin-ids.ts, src/plugins/channel-plugin-ids.test.ts, src/plugins)
  • steipete: Local history for the speech runtime and capability-provider boundary includes lazy TTS provider resolution, plugin-owned speech provider config, and capability provider resolution work. (role: TTS and plugin capability architecture maintainer; confidence: medium; commits: 85b3c1db30, d72115c9df, 2c6d099b01; files: extensions/speech-core/src/tts.ts, src/plugins/capability-provider-runtime.ts, src/tts)
  • stainlu: History shows prior work registering bundled TTS providers and routing overrides correctly across the speech provider surface touched by this regression. (role: adjacent TTS provider registration contributor; confidence: medium; commits: 6ea3cddf0d; files: extensions/speech-core, extensions/microsoft, extensions/tts-local-cli)

Remaining risk / open question:

  • The remaining disablement drift appears low-impact but can still start a speech plugin even when the root provider block is disabled for an active persona.
  • Validation was not executed in this read-only sweep; the PR body reports targeted and changed-gate runs.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 9772ce6ce975.

@amknight

amknight commented May 3, 2026

Copy link
Copy Markdown
Member Author

Re: the P3 persona disablement finding —

The concern is that addActivePersonaProvider lets a persona provider block without explicit enabled: true override a root providers.<id>.enabled = false. The merge semantics divergence is real, but the downstream impact described ("provider remains not configured") does not materialise: enabled on a SpeechProviderConfig is a startup-planner-only signal. The TTS runtime's isConfigured() checks for an API key, not enabled — so the merged { enabled: false, voice: "..." } config is still treated as configured at runtime.

The only practical effect of the current code in this edge case is starting an extra plugin that may go unused, which is strictly safer than the alternative (not starting a needed plugin — the original bug). The triggering config is also inherently contradictory: disable at root but configure in persona without re-enabling.

Happy to add the three-state activation check as a follow-up if real-world configs hit this, but for this PR the over-inclusive startup behaviour is intentional.

@amknight

amknight commented May 3, 2026

Copy link
Copy Markdown
Member Author

/clawsweeper automerge

@clawsweeper clawsweeper Bot added the clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge label May 3, 2026
@clawsweeper

clawsweeper Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper 🐠 automerge status

This pass ended as a no-op: no narrow repair surfaced, so ClawSweeper left the branch untouched.

Executor outcome: no planned fix actions.
Worker summary: Cluster is already resolved in hydrated live state: canonical this PR is closed and merged, and linked issue #76481 is already closed. No mutation is available or appropriate in this worker run because close and merge are blocked by job policy, post-merge close is disabled, and both hydrated refs are already closed.

Worker actions:

  • keep_closed on this PR: skipped - Already closed and merged in the preflight artifact; no repair, merge, or close action should be emitted.
  • keep_closed on #76481: skipped - Already closed after the merged canonical PR; no post-merge close action is allowed or needed.

No push, rebase, replacement PR, merge, or ClawSweeper re-review happened on this pass.

fish notes: model gpt-5.5, reasoning high.

Automerge progress:

  • 2026-05-03 11:06:40 UTC review queued [`46cd6989e773`](https://github.com/openclaw/openclaw/commit/46cd6989e7734f2ba151f4d3228862fd85b9e2ef) (queued)
  • 2026-05-03 11:07:49 UTC repair queued [`46cd6989e773`](https://github.com/openclaw/openclaw/commit/46cd6989e7734f2ba151f4d3228862fd85b9e2ef) (autonomous) Run: https://github.com/openclaw/clawsweeper/actions/runs/25277501882
  • 2026-05-03 12:04:00 UTC repair completed (no branch change) in 1s Run: https://github.com/openclaw/clawsweeper/actions/runs/25278615243 no planned fix actions

@amknight
amknight force-pushed the ak/issue-76481-microsoft-speech branch from 46cd698 to 623f45e Compare May 3, 2026 11:41
@amknight
amknight merged commit 8142e67 into main May 3, 2026
22 checks passed
@amknight
amknight deleted the ak/issue-76481-microsoft-speech branch May 3, 2026 11:41
lxe pushed a commit to lxe/openclaw that referenced this pull request May 6, 2026
* fix(plugins): start configured speech providers

* fix(plugins): mirror tts provider selection
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* fix(plugins): start configured speech providers

* fix(plugins): mirror tts provider selection
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* fix(plugins): start configured speech providers

* fix(plugins): mirror tts provider selection
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
* fix(plugins): start configured speech providers

* fix(plugins): mirror tts provider selection
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
* fix(plugins): start configured speech providers

* fix(plugins): mirror tts provider selection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: 5.2 microsoft speech plugin loads but never activates — TTS non-functional after upgrade

1 participant