StageWhisper Hermes Platform Adapter
Hermes platform adapter that exposes the StageWhisper desktop app as a first-class messaging surface for your Hermes Agent. Live-call transcripts arrive on a :reasoning chat thread, in-call chat arrives on a :chat thread, and the agent's reply is delivered back to the client over an SSE reply stream it holds open, or POSTed to a callback URL if the client's request asked for one.
Install
Install into the Hermes gateway's own venv, the same one that runs hermes_cli.main gateway run. Not pipx: a pipx install is isolated, so the gateway cannot import the adapter.
uv pip install --python <hermes-venv>/bin/python hermes-platform-stagewhisper
<hermes-venv>/bin/stagewhisper-hermes-install
Hermes creates its venv with uv, so that venv has no pip binary and no pip module. Use uv pip install --python as shown, not <hermes-venv>/bin/pip.
The installer drops a minimal shim into ~/.hermes/plugins/stagewhisper/:
PLUGIN.yamladapter.py(6-line shim that re-exports the in-package adapter)
Re-running the uv pip install upgrades the adapter without re-running the installer. stagewhisper-hermes-install --uninstall removes the shim.
Configure
Required environment variables (set in ~/.hermes/.env or via hermes config):
| Variable | Purpose |
|---|---|
STAGEWHISPER_RELAY_TOKEN |
Bearer token shared with the desktop app (32+ chars). |
STAGEWHISPER_LISTEN_PORT |
Loopback TCP port the adapter binds (1024-65535). |
Optional:
| Variable | Default | Purpose |
|---|---|---|
STAGEWHISPER_LISTEN_HOST |
127.0.0.1 |
Must be loopback. |
STAGEWHISPER_ALLOW_INGRESS_HOSTS |
unset | Comma-separated Host names accepted in addition to localhost. Set this to your tailnet name when reaching the adapter through tailscale serve. |
STAGEWHISPER_ALLOW_CALLBACK_URLS |
unset | Comma-separated exact origins (scheme + host + port) the adapter may POST replies to. Loopback is trusted implicitly only while STAGEWHISPER_ALLOW_INGRESS_HOSTS is unset; once remote ingress is enabled, every callback origin (loopback included) must be listed here. |
STAGEWHISPER_ALLOWED_USERS |
unset | Comma-separated session_id allowlist. |
STAGEWHISPER_ALLOW_ALL_USERS |
unset | 1 to bypass allowlist. |
STAGEWHISPER_MAX_CONCURRENT |
4 |
Max in-flight tasks. |
STAGEWHISPER_DEDUP_CACHE_SIZE |
2048 |
Idempotency LRU size. |
After setting the env vars, restart Hermes. hermes status will list StageWhisper (plugin) - connected.
Wire protocol
The client posts to http://127.0.0.1:<port>/v1/incoming with bearer auth. Three event reasons:
transcript_chunk(onlyis_final: trueroutes through the agent) -> chat threadsw:<session>:reasoningchat_message-> chat threadsw:<session>:chatsystem_prelude-> stashed and prepended to the next inbound message for that session as[Context: ...], then cleared
By default the adapter writes replies to GET /v1/events?session_id=<session>. The client opens the stream with the same bearer token before dispatch and shares it across pending tasks in that session. The stream closes after the last task settles. On connect, every currently retained terminal answer for that session is replayed, oldest first; that is the whole recovery story. Typing and tool activity are live-only and never consume the retained backlog.
If the inbound event instead carries a callback block ({"url": ..., "token": ...}), the adapter POSTs the reply to <callback.url>/tasks/<task_id> with that token as bearer auth, and retries on transient failures. callback.url must be a loopback URL, or an origin listed in STAGEWHISPER_ALLOW_CALLBACK_URLS. StageWhisper's own desktop and mobile apps never send a callback block; they always read from the stream.
Local development
uv run --with pytest --with pytest-asyncio python -m pytest -v
Metadata
Release files for hermes-platform-stagewhisper 0.43.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hermes_platform_stagewhisper-0.43.0.tar.gz | 36.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hermes_platform_stagewhisper-0.43.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.0 kB
Release files / hermes_platform_stagewhisper-0.43.0.tar.gz
| Download URL | hermes_platform_stagewhisper-0.43.0.tar.gz |
|---|---|
| Size | 36.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5c630bab36d4d04c14f437e14de172400161f7990e5a0027fe2e76ed4573ea20
|
|
BLAKE2b-256 checksum How to use checksums |
349f66b9624da12bf1b94d9ac557aeaf5a9b885aa18ebc5b4cfb418ab05c7425
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.11
|
Release files / hermes_platform_stagewhisper-0.43.0-py3-none-any.whl
| Download URL | hermes_platform_stagewhisper-0.43.0-py3-none-any.whl |
|---|---|
| Size | 45.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
72aa970aa1cf54165c8ac631274ed0d8c2826b3806880fa2af4aac15bf97ca99
|
|
BLAKE2b-256 checksum How to use checksums |
4ee8789b4638ac60819e674a8bfed2fe133f9644628b4ad745b1740295aad092
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.11
|