fix(voice): resolve API keys from ~/.hermes/.env in TTS + STT tools (#17140)#17434
Merged
Conversation
) TTS provider tools (elevenlabs, xai, minimax, mistral, gemini) called os.getenv("X_API_KEY") directly, which bypassed Hermes's dotenv bridge in hermes_cli.config. Users who keep their TTS keys only in ~/.hermes/.env saw "X_API_KEY not set" errors even though the rest of the stack (agent/credential_pool, hermes_cli/auth) already resolves keys through get_env_value() — same class of bug as #15914 fixed for those modules. Switch every TTS env-var lookup (API keys, base URLs, and check_tts_requirements gates) to get_env_value, which checks os.environ first and then ~/.hermes/.env. Behaviour for users with keys exported in the shell is unchanged; users with dotenv-only keys now succeed. The two diagnostics prints in __main__ are migrated for consistency. Regression test (tests/tools/test_tts_dotenv_fallback.py): - per-provider: each backend reads the dotenv key when only ~/.hermes/.env carries it (5 providers). - end-to-end: with hermes_cli.config.load_env returning the key and os.environ empty, _generate_minimax_tts and check_tts_requirements both succeed; reverting tools/tts_tool.py back to os.getenv makes all 7 tests fail with "MINIMAX_API_KEY not set" / similar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wrap the new top-level `from hermes_cli.config import get_env_value` in try/except ImportError and fall back to a thin os.getenv shim, so importing tools.tts_tool keeps working in environments where hermes_cli.config is unavailable. This matches the existing tolerance in `_load_tts_config()` (tools/tts_tool.py) and the same import-fallback pattern in tools/tool_backend_helpers.py::fal_key_is_configured. Also update the TestDotenvFallbackPerProvider docstring to accurately describe the mocking strategy: per-provider tests patch `tools.tts_tool.get_env_value` directly, while the regression-guard tests cover the lower-level `hermes_cli.config.load_env` integration. Addresses Copilot review on #17163. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
) Widen #17163 to the sibling file tools/transcription_tools.py, which had the same class of bug. STT provider call sites and the _get_provider selection gate called os.getenv(...) directly and missed keys that only lived in ~/.hermes/.env. Same pattern as tts_tool.py: one guarded top-level import of get_env_value (falls back to os.getenv on ImportError), then every API-key and paired-base-URL lookup swapped over. Call sites migrated: - _transcribe_groq — GROQ_API_KEY - _transcribe_mistral — MISTRAL_API_KEY - _transcribe_xai — XAI_API_KEY, XAI_STT_BASE_URL - _get_provider — GROQ/MISTRAL/XAI_API_KEY in explicit + auto branches Module-level defaults (DEFAULT_STT_MODEL, GROQ_BASE_URL, etc.) stay on os.getenv — they're import-time constants, not runtime config, and the dotenv fallback would add no value there. New regression tests in tests/tools/test_transcription_dotenv_fallback.py (8 cases) mirror briandevans' TTS tests: per-provider dotenv-key forwarding, selection-gate dotenv visibility, and an end-to-end probe that patches hermes_cli.config.load_env to simulate ~/.hermes/.env carrying the key while os.environ does not.
5 tasks
3 tasks
This was referenced May 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Users with TTS/STT API keys only in
~/.hermes/.envcan now use every voice backend. Salvages #17163 (@briandevans, TTS variant) and widens the same fix to the sibling filetools/transcription_tools.py(STT variant — identical bug class, untouched by the original PR).Same class of bug as #15914 / #15920 (auth.py +
agent/credential_poolvariants) —os.getenv()misses keys that only live in~/.hermes/.env.hermes_cli.config.get_env_value()is the canonical resolver (env first, dotenv fallback).Changes
tools/tts_tool.py(@briandevans, cherry-picked as-is from fix(tts): resolve API keys from ~/.hermes/.env via get_env_value (#17140) #17163): 13 call sites across ElevenLabs, xAI, MiniMax, Mistral, Gemini — all API-key / paired-base-URL lookups and thecheck_tts_requirements()gate.tools/transcription_tools.py(new in this PR): 9 call sites across_transcribe_groq,_transcribe_mistral,_transcribe_xai, and the_get_providerselection gate. Module-level constants (DEFAULT_STT_MODEL, GROQ_BASE_URL, etc.) intentionally stay onos.getenv— they're import-time defaults, not runtime-resolved config.tests/tools/test_tts_dotenv_fallback.py(@briandevans): 7 tests.tests/tools/test_transcription_dotenv_fallback.py(new): 8 tests mirroring the TTS pattern — per-provider key forwarding, selection-gate dotenv visibility, and an end-to-end probe patchinghermes_cli.config.load_envto simulate~/.hermes/.env-only keys.Both files use the same guarded import pattern as
tools/tool_backend_helpers.py::fal_key_is_configured:Validation
tests/tools/test_tts_dotenv_fallback.pytests/tools/test_transcription_dotenv_fallback.pytools/transcription_tools.pyre-triggers all 8 new failuresAuthorship
fix(tts): resolve API keys from ~/.hermes/.env via get_env_value (#17140)andfix(tts): tolerate missing hermes_cli.config in tts_tool import(Copilot review follow-up).Related