Skip to content

fix(tts): support configurable ElevenLabs URLs - #66311

Closed
moeadham wants to merge 1 commit into
NousResearch:mainfrom
moeadham:fix/elevenlabs-tts-url
Closed

moeadham wants to merge 1 commit into
NousResearch:mainfrom
moeadham:fix/elevenlabs-tts-url

Conversation

@moeadham

Copy link
Copy Markdown
Contributor

Certain elevenlabs environments require non-default URLs. This is already supported on STT, but for some reason was omitted on TTS.

This minimal change reads an optional base_url and wss_url from the tts.elevenlabs config block, mirroring how the OpenAI TTS provider reads tts.openai.base_url. When unset, the ElevenLabs client is constructed exactly as before (no behavior change). When set, it is passed through environment=ElevenLabsEnvironment(...), since the ElevenLabs SDK does not accept a base_url kwarg directly.

Applied to both construction sites: the sync _generate_elevenlabs handler and the streaming stream_tts_to_speaker path.

What does this PR do?

Fixes an omission where elevenlabs base_url is only supported on STT but not TTS.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • tts_tool.py - add lazy import for ElevenLabsEnvironment from current dependency
  • tts_tool.py - check if base_url and wss_url are configured, and set them in the client

How to Test

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform:

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

@moeadham
moeadham force-pushed the fix/elevenlabs-tts-url branch from 4a8673d to 6f02a13 Compare July 17, 2026 12:59
@alt-glitch alt-glitch added type/feature New feature or request tool/tts Text-to-speech and transcription P3 Low — cosmetic, nice to have labels Jul 17, 2026
@moeadham
moeadham force-pushed the fix/elevenlabs-tts-url branch from 6f02a13 to ff717ab Compare July 17, 2026 13:16

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Looks Good

  • Clean implementation of configurable ElevenLabs API and websocket URLs
  • New _import_elevenlabs_environment() helper avoids circular imports and keeps lazy-loading pattern
  • Graceful fallback to default client when base_url/wss_url are not both provided
  • Same pattern applied consistently to both sync (_generate_elevenlabs) and streaming (stream_tts_to_speaker) paths
  • Comprehensive regression tests with mocked environment verify correct URL passing
  • No security concerns — custom URL support is a standard feature for enterprise proxy/infrastructure setups

Reviewed by Hermes Agent

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Clean, well-scoped change with good test coverage. No security concerns.


Reviewed by Hermes Agent

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for addressing a real parity gap: current main constructs the ElevenLabs client without URL configuration in both the sync path (tools/tts_tool.py:1003-1005) and streaming path (tools/tts_tool.py:2797-2799), while STT already resolves stt.elevenlabs.base_url (tools/transcription_tools.py:1579-1585).

Problems

  • The new if base_url and wss_url branches (tools/tts_tool.py:1008, :2808) ignore a configured base_url unless wss_url is also set. This does not provide base-URL-only support.
  • pyproject.toml:172 pins elevenlabs==1.59.0; that SDK accepts ElevenLabs(base_url=...) directly. Use an explicit environment only for a separately configured WebSocket URL.
  • gh pr diff 66311 --name-only shows no test changes, despite altering both construction paths.

Suggested changes

  • Handle base_url independently in both paths, with wss_url as the opt-in case for ElevenLabsEnvironment.
  • Add regression coverage for sync and streaming construction, including base-only configuration.
  • Document the new user-facing config keys in the TTS configuration references.

Automated hermes-sweeper review.

Comment thread tools/tts_tool.py
@@ -1001,7 +1008,11 @@ def _generate_elevenlabs(text: str, output_path: str, tts_config: Dict[str, Any]
output_format = "mp3_44100_128"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

base_url alone is ignored here, so the advertised tts.elevenlabs.base_url configuration still routes to the default endpoint unless users also supply wss_url. The pinned ElevenLabs 1.59.0 client accepts base_url directly; handle that case independently, reserving ElevenLabsEnvironment for an explicitly distinct WSS URL.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 18, 2026
teknium1 pushed a commit that referenced this pull request Jul 28, 2026
Salvaged from PR #66311 (@moeadham), rebased onto the current streaming
registry. tts.elevenlabs.base_url (+ optional wss_url, derived from
base_url when omitted) routes both the sync ElevenLabs path and the
chunked ElevenLabsStreamer through an ElevenLabsEnvironment, matching
the STT side's ELEVENLABS_STT_BASE_URL/config override pattern.
teknium1 added a commit that referenced this pull request Jul 28, 2026
…g tests

Class-level sweep following the ElevenLabs salvage (#66311): every cloud
TTS provider section now honors tts.<provider>.base_url. xAI, MiniMax,
Gemini, OpenAI and DeepInfra already did; Mistral (SDK server_url) was
the remaining gap. Adds per-provider config tests locking in the
ElevenLabs environment plumbing and the Mistral server_url passthrough.
@teknium1

Copy link
Copy Markdown
Collaborator

Merged into main via consolidated salvage PR #73512 (merge f3cc2bc022). Your configurable ElevenLabs URLs (tts.elevenlabs.base_url + derived wss_url via ElevenLabsEnvironment) were cherry-picked as 851f75b with your authorship.

Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage.

@teknium1 teknium1 closed this Jul 29, 2026
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
Salvaged from PR NousResearch#66311 (@moeadham), rebased onto the current streaming
registry. tts.elevenlabs.base_url (+ optional wss_url, derived from
base_url when omitted) routes both the sync ElevenLabs path and the
chunked ElevenLabsStreamer through an ElevenLabsEnvironment, matching
the STT side's ELEVENLABS_STT_BASE_URL/config override pattern.
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…g tests

Class-level sweep following the ElevenLabs salvage (NousResearch#66311): every cloud
TTS provider section now honors tts.<provider>.base_url. xAI, MiniMax,
Gemini, OpenAI and DeepInfra already did; Mistral (SDK server_url) was
the remaining gap. Adds per-provider config tests locking in the
ElevenLabs environment plumbing and the Mistral server_url passthrough.
prmartinow pushed a commit to prmartinow/hermes-agent that referenced this pull request Aug 26, 2026
Salvaged from PR NousResearch#66311 (@moeadham), rebased onto the current streaming
registry. tts.elevenlabs.base_url (+ optional wss_url, derived from
base_url when omitted) routes both the sync ElevenLabs path and the
chunked ElevenLabsStreamer through an ElevenLabsEnvironment, matching
the STT side's ELEVENLABS_STT_BASE_URL/config override pattern.
prmartinow pushed a commit to prmartinow/hermes-agent that referenced this pull request Aug 26, 2026
…g tests

Class-level sweep following the ElevenLabs salvage (NousResearch#66311): every cloud
TTS provider section now honors tts.<provider>.base_url. xAI, MiniMax,
Gemini, OpenAI and DeepInfra already did; Mistral (SDK server_url) was
the remaining gap. Adds per-provider config tests locking in the
ElevenLabs environment plumbing and the Mistral server_url passthrough.
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
Salvaged from PR NousResearch#66311 (@moeadham), rebased onto the current streaming
registry. tts.elevenlabs.base_url (+ optional wss_url, derived from
base_url when omitted) routes both the sync ElevenLabs path and the
chunked ElevenLabsStreamer through an ElevenLabsEnvironment, matching
the STT side's ELEVENLABS_STT_BASE_URL/config override pattern.
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…g tests

Class-level sweep following the ElevenLabs salvage (NousResearch#66311): every cloud
TTS provider section now honors tts.<provider>.base_url. xAI, MiniMax,
Gemini, OpenAI and DeepInfra already did; Mistral (SDK server_url) was
the remaining gap. Adds per-provider config tests locking in the
ElevenLabs environment plumbing and the Mistral server_url passthrough.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data tool/tts Text-to-speech and transcription type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants