fix(stt,tts): restore mistralai — 2.4.8 is clean, ban lifted (#34841)
* docs(code-execution): document HERMES_* env narrowing + passthrough workaround
The execute_code sandbox-child env scrub (108397726, #27303) deliberately
dropped the broad HERMES_ prefix passthrough, keeping only an operational
4-var allowlist (HERMES_HOME/PROFILE/CONFIG/ENV). A script that relied on a
non-secret HERMES_* var (HERMES_BASE_URL, HERMES_KANBAN_DB, HERMES_*_WEBHOOK,
or a plugin-defined one) now sees it unset in the child.
Document the behavior change and the two recovery routes (terminal.env_passthrough
in config.yaml, or required_environment_variables in skill frontmatter), plus
the debug log line that surfaces the drop for diagnosis.
* fix(stt,tts): restore mistralai — 2.4.8 is clean, ban lifted
PyPI quarantined mistralai on 2026-05-12 after the malicious 2.4.6
release (Mini Shai-Hulud worm). 2.4.6 has since been removed from the
registry and clean releases resumed (2.4.7 2026-05-25, 2.4.8 2026-05-28).
This rolls back the blanket runtime ban so Voxtral STT + TTS work again,
following the restoration checklist the repo left in pyproject.toml.
Verified against the real SDK: 2.4.8 keeps the import path the code uses
(from mistralai.client import Mistral) and the audio.transcriptions.complete
/ audio.speech.complete surfaces.
Changes:
- pyproject.toml: re-add mistral extra pinned to mistralai==2.4.8; left
OUT of [all] per the 2026-05-12 lazy-install policy (one quarantined
release must not break fresh installs). uv.lock regenerated.
- tools/lazy_deps.py: add stt.mistral / tts.mistral entries so the SDK
lazy-installs on first use (matches edge / elevenlabs).
- tools/transcription_tools.py: restore explicit-provider gate
(_HAS_MISTRAL + key) and auto-detect entry (local>groq>openai>mistral>xai);
_transcribe_mistral lazy-installs before import.
- tools/tts_tool.py: dispatcher routes back to _generate_mistral_tts;
_import_mistral_client lazy-installs the SDK.
- hermes_cli/tools_config.py, hermes_cli/web_server.py: un-hide Mistral
from the TTS provider picker and dashboard STT options.
- hermes_cli/security_advisories.py: KEEP the shai-hulud-2026-05 advisory
(module policy forbids removal) — it is scoped to 2.4.6 only, so it
still warns anyone with the poisoned build cached and never fires on
2.4.8. Summary note updated to reflect the un-quarantine.
- tests: revert the disabled-behavior assertions added by the ban commit
back to routing/positive expectations; add mistral to the
lazy-installable-extras-excluded-from-[all] contract.
Reported by @SkYNewZ (#34503).
Validation: 189 targeted STT/TTS/lazy_deps/metadata tests pass; E2E with
the real mistralai 2.4.8 SDK routes both STT and TTS to mistral.
This commit is contained in:
+24
-16
@@ -121,7 +121,20 @@ def _import_openai_client():
|
||||
return OpenAIClient
|
||||
|
||||
def _import_mistral_client():
|
||||
"""Lazy import Mistral client. Returns the class or raises ImportError."""
|
||||
"""Lazy import Mistral client. Returns the class or raises ImportError.
|
||||
|
||||
Calls :func:`tools.lazy_deps.ensure` first so the ``mistralai`` SDK gets
|
||||
installed on demand if the user picked Mistral as their STT/TTS provider
|
||||
but never ran the post-setup hook (e.g. enabled it by editing config.yaml
|
||||
directly). Mirrors the ElevenLabs lazy-import path.
|
||||
"""
|
||||
try:
|
||||
from tools.lazy_deps import ensure
|
||||
ensure("tts.mistral", prompt=False)
|
||||
except ImportError:
|
||||
pass
|
||||
except Exception as e: # FeatureUnavailable or any unexpected error
|
||||
raise ImportError(str(e))
|
||||
from mistralai.client import Mistral
|
||||
return Mistral
|
||||
|
||||
@@ -1974,21 +1987,16 @@ def text_to_speech_tool(
|
||||
_generate_xai_tts(text, file_str, tts_config)
|
||||
|
||||
elif provider == "mistral":
|
||||
# `mistralai` PyPI package was quarantined on 2026-05-12 after a
|
||||
# malicious 2.4.6 release. Surface a clear status message instead
|
||||
# of attempting an import that would either fail or pull a stale
|
||||
# cached package.
|
||||
return json.dumps({
|
||||
"success": False,
|
||||
"error": (
|
||||
"Mistral Voxtral TTS is temporarily disabled. The "
|
||||
"`mistralai` PyPI package was quarantined on 2026-05-12 "
|
||||
"after a malicious 2.4.6 release. Switch tts.provider in "
|
||||
"config.yaml to 'edge', 'elevenlabs', 'openai', 'minimax', "
|
||||
"'gemini', 'xai', 'neutts', or 'kittentts'. Mistral "
|
||||
"support will return once PyPI un-quarantines the package."
|
||||
),
|
||||
}, ensure_ascii=False)
|
||||
try:
|
||||
_import_mistral_client()
|
||||
except ImportError:
|
||||
return json.dumps({
|
||||
"success": False,
|
||||
"error": "Mistral provider selected but 'mistralai' package not installed. "
|
||||
"Run: pip install 'hermes-agent[mistral]'"
|
||||
}, ensure_ascii=False)
|
||||
logger.info("Generating speech with Mistral Voxtral TTS...")
|
||||
_generate_mistral_tts(text, file_str, tts_config)
|
||||
|
||||
elif provider == "gemini":
|
||||
logger.info("Generating speech with Google Gemini TTS...")
|
||||
|
||||
Reference in New Issue
Block a user