fix(desktop): ship the VC++ runtime the Windows voice wheels need

onnxruntime (wake word) and ctranslate2 (local speech-to-text) link against
msvcp140.dll and msvcp140_1.dll, which the managed CPython does not ship.
On Windows without the system VC++ Redistributable both imports failed with
"DLL load failed: The specified module could not be found", so "Hey Hermes"
and voice chat transcription never worked.

- Bundle the Microsoft-signed VC143 CRT set (14.44.35211, matching the
  managed CPython's vcruntime140) as a Windows extra resource with a SHA-256
  manifest.
- Before every local backend start, copy missing or mismatching CRT files
  beside the managed python.exe (the process image directory, searched first),
  verifying digests; never overwrite the interpreter's own vcruntime and never
  block boot. Existing installs heal on their next launch.
- Report an unloadable native voice wheel as a VC++ runtime problem in the
  wake-word requirements, local transcription and `hermes doctor`, instead of
  treating installed package metadata as proof the wheel loads.
- Bump AITURK IDE to 1.0.0-beta.12.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 5 committed 2026-09-15 19:46:39 +03:00
1 parent 9a1d831d4b
commit 233885d3a7
20 files changed
+684 -5

No files matched your search

+16 -1
View File
@@ -896,6 +896,12 @@ def _tts_ready() -> bool:
return False
def _native_runtime_error(module: str) -> Optional[str]:
from tools.windows_native_runtime import native_load_error
return native_load_error(module)
def check_wake_word_requirements(cfg: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""Report whether wake-word detection can run, with a remediation hint."""
cfg = cfg if cfg is not None else load_wake_word_config()
@@ -910,6 +916,10 @@ def check_wake_word_requirements(cfg: Optional[Dict[str, Any]] = None) -> Dict[s
feature = "wake.openwakeword"
deps_ok = lazy_deps.is_available(feature)
lazy_ok = lazy_deps._allow_lazy_installs()
# Installed metadata does not prove the native wheel loads: on Windows
# without the VC++ runtime onnxruntime is "installed" yet every import
# fails. Report that instead of a lazy install that cannot help.
native_error = _native_runtime_error("onnxruntime") if deps_ok and feature == "wake.openwakeword" else None
# The audio probe imports sounddevice + numpy — two of the very packages
# the lazy installer would fetch — so it can only be trusted once the
# feature's deps are installed. On a fresh install (deps missing, lazy
@@ -937,6 +947,10 @@ def check_wake_word_requirements(cfg: Optional[Dict[str, Any]] = None) -> Dict[s
if provider == "porcupine" and not (os.getenv("PORCUPINE_ACCESS_KEY") or "").strip():
key_ok = False
hint = "Set PORCUPINE_ACCESS_KEY (free key at https://console.picovoice.ai)."
elif native_error:
from tools.windows_native_runtime import voice_runtime_error_message
hint = voice_runtime_error_message(native_error)
elif not deps_ok and not lazy_ok:
hint = lazy_deps.feature_install_command(feature) or ""
elif not tflite_ok:
@@ -969,7 +983,7 @@ def check_wake_word_requirements(cfg: Optional[Dict[str, Any]] = None) -> Dict[s
)
return {
"available": key_ok and stt_ok and tts_ok and tflite_ok and mic_ok,
"available": key_ok and stt_ok and tts_ok and tflite_ok and mic_ok and native_error is None,
"provider": provider,
"deps_available": deps_ok,
"audio_available": audio_ok,
@@ -979,6 +993,7 @@ def check_wake_word_requirements(cfg: Optional[Dict[str, Any]] = None) -> Dict[s
"stt_available": stt_ok,
"tts_available": tts_ok,
"phrase": wake_phrase(cfg),
"native_runtime_error": native_error,
"hint": hint,
}