hermes-agent/website/docs
Ben Barclay 7d19033d2e
fix(wake): run openWakeWord on tflite on macOS ARM64
openWakeWord's ONNX backend returns near-zero scores on Apple Silicon
(dscripka/openWakeWord#336), so "Hey Hermes" never crossed the 0.5
threshold: the listener armed, the microphone worked, and nothing fired.

Bisecting the pipeline puts the fault in exactly one stage — feeding the
same audio through both backends, the melspectrogram front-end is
bit-identical (maxdiff 0.00000) and the wake classifier agrees on
identical features, while the shared embedding model diverges by 45.44.
Cross-feeding confirms it: tflite features scored through the *onnx*
classifier give 0.9948 vs 0.000009 for onnx features. A telling
secondary symptom is that scores fall as input gets louder (0.5x ->
0.00031, 8x -> 0.000066), which is garbage inference rather than a weak
detection.

Selecting tflite in config alone does not fix it. openWakeWord hardcodes
`import tflite_runtime.interpreter` but declares tflite-runtime for
`platform_system == "Linux"` only; on macOS the equivalent wheel is
ai-edge-litert, so that import always fails and model.py silently
downgrades back to onnx. The result is a detector that reports itself
listening and can never fire.

- default the backend per platform (tflite on macOS ARM64, onnx
  elsewhere) instead of hardcoding onnx, and pick the matching bundled
  model artifact
- bridge tflite_runtime -> ai_edge_litert through sys.modules, in-process,
  with no writes to site-packages
- refuse the silent onnx downgrade on macOS ARM64 and report the missing
  runtime through check_wake_word_requirements() so the GUI surfaces an
  actionable hint rather than arming a dead ear
- lazy-install ai-edge-litert via its own feature key, because lazy-dep
  specs cannot carry PEP 508 markers (_spec_is_safe rejects ";")

An explicit `inference_framework` in config still wins, so anyone pinning
a backend keeps it.

Verified on macOS 26.5.2 / M-series: "hey hermes" scores 0.0005 on onnx
and 0.9423 on tflite from the same clip, with cross-phrase controls at
0.0003. Live over-the-air through the real microphone fires 4/4
utterances (peak 0.9532).
2026-07-28 07:59:34 -07:00
..
developer-guide fix subagent lifecycle ownership invariants 2026-07-26 23:27:30 -07:00
getting-started Reapply "Merge pull request #30179 from NousResearch/feat/iron-proxy" 2026-07-24 09:49:00 -07:00
guides docs(portal): describe per-model routing accurately — not everything goes through OpenRouter 2026-07-26 18:02:13 -07:00
integrations docs(portal): describe per-model routing accurately — not everything goes through OpenRouter 2026-07-26 18:02:13 -07:00
reference docs(wake-word): sidebar entry, env-var reference row, voice-mode cross-link 2026-07-28 07:59:34 -07:00
user-guide fix(wake): run openWakeWord on tflite on macOS ARM64 2026-07-28 07:59:34 -07:00
index.mdx feat(docs): clarify platform support 2026-06-26 11:37:56 -07:00
user-stories.mdx docs(website): add User Stories and Use Cases collage page (#18282) 2026-04-30 23:56:59 -07:00