Bug Description
Installing Hermes Agent on a Raspberry Pi 3B — either via scripts/install.sh or via hermes update on an existing install — hangs indefinitely. The process sits in pip install -e .[all] for hours trying to build ctranslate2 and onnxruntime from source. These are transitive dependencies of faster-whisper, which is pulled in via the voice optional-extras group, referenced unconditionally from [all].
On 1GB-RAM devices the source build either OOMs, fills the 128MB /tmp tmpfs, or never finishes in any reasonable timeframe. Because hermes update --gateway runs pip install as a child of the running gateway, the Telegram /update command never returns and the bot becomes unresponsive until the stuck pip process is killed manually. The stale .update_pending.json state file then causes every subsequent gateway restart to replay the unfinished update output to Telegram until the state files are cleaned up by hand.
This is functionally equivalent to the Termux case already documented in the termux optional-extras group, whose comment explicitly calls out faster-whisper -> ctranslate2 as the reason that group avoids [voice]. The Raspberry Pi 3B / 2 / Zero class of 32-bit ARM Linux hosts suffer the same issue but have no automatic handling.
Steps to Reproduce
- Provision a Raspberry Pi 3 Model B Rev 1.2 with Raspbian Bookworm 12 (32-bit,
armv7l), 1GB RAM, Python 3.11.2.
- Install hermes-agent via
scripts/install.sh (which detects armv7l and installs Node.js, so the platform is nominally supported).
- Run
hermes update from the CLI, OR send /update to an already-running Telegram gateway.
- Observe: the process reaches
→ Updating Python dependencies... and hangs.
ps auxf shows pip install -e .[all] --quiet consuming ~85% CPU in the R state for hours; df -h /tmp climbs toward 100%.
Expected Behavior
pip install -e .[all] should complete successfully on 32-bit ARM Linux hosts, installing every extras group that has prebuilt wheels. voice-related functionality (local STT via faster-whisper) should be skipped automatically on those hosts — mirroring the existing termux extras' rationale — and remain available as a manual opt-in via pip install -e '.[voice]' for users who really need it.
Actual Behavior
pip install -e .[all] never finishes. It spends hours attempting to build ctranslate2 and onnxruntime from source because no armv6l / armv7l wheels are published on PyPI for either package. A user hitting this via the Telegram /update command sees a silent gateway hang, and .update_pending.json keeps replaying the stale output on every restart.
Affected Component
Messaging Platform (if gateway-related)
(Root cause is install-layer, not Telegram-specific — any user running hermes update or pip install -e .[all] on armv7l will hit it.)
Operating System
Raspbian GNU/Linux 12 (bookworm), 32-bit; kernel 6.12.47+rpt-rpi-v7
Python Version
3.11.2
Hermes Version
Hermes Agent v0.8.0 (2026.4.8)
Relevant Logs / Traceback
$ /data/apps/hermes/venv/bin/python3 -m pip install -e .[all] --quiet
# (hangs here indefinitely — no output)
$ ps auxf | grep -E "hermes|pip install"
aras 21455 ... python3 -m hermes_cli.main gateway
aras 1369 ... bash -c "... /usr/local/bin/hermes update --gateway ..."
aras 1370 ... \_ python3 -m hermes_cli.main update --gateway
aras 1403 ... \_ python3 -m pip install -e .[all] --quiet (76% CPU, R state)
$ df -h /tmp
tmpfs 128M 110M 19M 86% /tmp
$ uname -m
armv7l
$ cat /proc/device-tree/model
Raspberry Pi 3 Model B Rev 1.2
Root Cause Analysis
The issue is in pyproject.toml. The [all] meta-extra aggregates hermes-agent[voice] unconditionally (line 106 on current main):
all = [
...
"hermes-agent[voice]",
...
]
voice defines faster-whisper >= 1.0.0, which transitively depends on ctranslate2 and onnxruntime. Neither package publishes 32-bit ARM wheels to PyPI (only aarch64, x86_64, arm64, etc.), so pip falls back to building them from source, which on a 1GB-RAM Pi 3B either OOMs or runs indefinitely with /tmp filling up.
The voice extras definition already flags the risk in a comment:
voice = [
# Local STT pulls in wheel-only transitive deps (ctranslate2, onnxruntime),
# so keep it out of the base install for source-build packagers like Homebrew.
"faster-whisper>=1.0.0,<2",
...
]
…and the termux extras documents the same problem as its reason for existing:
termux = [
# Tested Android / Termux path: keeps the core CLI feature-rich while
# avoiding extras that currently depend on non-Android wheels (notably
# faster-whisper -> ctranslate2 via the voice extra).
...
]
But there is no automatic handling for 32-bit ARM Linux hosts like the Raspberry Pi 3B class — they hit the same failure without any guardrail.
Proposed Fix
Gate the voice entry in [all] with a platform_machine environment marker, mirroring the existing [matrix]; sys_platform == 'linux' pattern merged in #7461:
all = [
...
"hermes-agent[voice] ; platform_machine != 'armv6l' and platform_machine != 'armv7l'",
...
]
This keeps the default pip install -e .[all] path working on x86_64, arm64, aarch64, and every other architecture exactly as before, but transparently skips voice (and therefore faster-whisper -> ctranslate2 -> onnxruntime) on 32-bit ARM. Users who genuinely need local STT on an ARM32 host can still install it explicitly:
pip install -e '.[voice]'
I have a PR ready implementing this fix plus a regression test in tests/test_packaging_metadata.py.
Are you willing to submit a PR?
Bug Description
Installing Hermes Agent on a Raspberry Pi 3B — either via
scripts/install.shor viahermes updateon an existing install — hangs indefinitely. The process sits inpip install -e .[all]for hours trying to buildctranslate2andonnxruntimefrom source. These are transitive dependencies offaster-whisper, which is pulled in via thevoiceoptional-extras group, referenced unconditionally from[all].On 1GB-RAM devices the source build either OOMs, fills the 128MB
/tmptmpfs, or never finishes in any reasonable timeframe. Becausehermes update --gatewayrunspip installas a child of the running gateway, the Telegram/updatecommand never returns and the bot becomes unresponsive until the stuck pip process is killed manually. The stale.update_pending.jsonstate file then causes every subsequent gateway restart to replay the unfinished update output to Telegram until the state files are cleaned up by hand.This is functionally equivalent to the Termux case already documented in the
termuxoptional-extras group, whose comment explicitly calls outfaster-whisper -> ctranslate2as the reason that group avoids[voice]. The Raspberry Pi 3B / 2 / Zero class of 32-bit ARM Linux hosts suffer the same issue but have no automatic handling.Steps to Reproduce
armv7l), 1GB RAM, Python 3.11.2.scripts/install.sh(which detectsarmv7land installs Node.js, so the platform is nominally supported).hermes updatefrom the CLI, OR send/updateto an already-running Telegram gateway.→ Updating Python dependencies...and hangs.ps auxfshowspip install -e .[all] --quietconsuming ~85% CPU in theRstate for hours;df -h /tmpclimbs toward 100%.Expected Behavior
pip install -e .[all]should complete successfully on 32-bit ARM Linux hosts, installing every extras group that has prebuilt wheels.voice-related functionality (local STT via faster-whisper) should be skipped automatically on those hosts — mirroring the existingtermuxextras' rationale — and remain available as a manual opt-in viapip install -e '.[voice]'for users who really need it.Actual Behavior
pip install -e .[all]never finishes. It spends hours attempting to buildctranslate2andonnxruntimefrom source because noarmv6l/armv7lwheels are published on PyPI for either package. A user hitting this via the Telegram/updatecommand sees a silent gateway hang, and.update_pending.jsonkeeps replaying the stale output on every restart.Affected Component
Messaging Platform (if gateway-related)
(Root cause is install-layer, not Telegram-specific — any user running
hermes updateorpip install -e .[all]onarmv7lwill hit it.)Operating System
Raspbian GNU/Linux 12 (bookworm), 32-bit; kernel
6.12.47+rpt-rpi-v7Python Version
3.11.2
Hermes Version
Hermes Agent v0.8.0 (2026.4.8)
Relevant Logs / Traceback
Root Cause Analysis
The issue is in
pyproject.toml. The[all]meta-extra aggregateshermes-agent[voice]unconditionally (line 106 on currentmain):voicedefinesfaster-whisper >= 1.0.0, which transitively depends onctranslate2andonnxruntime. Neither package publishes 32-bit ARM wheels to PyPI (onlyaarch64,x86_64,arm64, etc.), so pip falls back to building them from source, which on a 1GB-RAM Pi 3B either OOMs or runs indefinitely with/tmpfilling up.The
voiceextras definition already flags the risk in a comment:…and the
termuxextras documents the same problem as its reason for existing:But there is no automatic handling for 32-bit ARM Linux hosts like the Raspberry Pi 3B class — they hit the same failure without any guardrail.
Proposed Fix
Gate the
voiceentry in[all]with aplatform_machineenvironment marker, mirroring the existing[matrix]; sys_platform == 'linux'pattern merged in #7461:This keeps the default
pip install -e .[all]path working onx86_64,arm64,aarch64, and every other architecture exactly as before, but transparently skipsvoice(and thereforefaster-whisper -> ctranslate2 -> onnxruntime) on 32-bit ARM. Users who genuinely need local STT on an ARM32 host can still install it explicitly:pip install -e '.[voice]'I have a PR ready implementing this fix plus a regression test in
tests/test_packaging_metadata.py.Are you willing to submit a PR?