Voice
Supervoicemode
OpenClaw channel plugin for Super Voice Mode
Install
npm install
npm
Configuration Example
{
"channels": {
"supervoicemode": {
"bindAddress": "127.0.0.1:18790",
"accounts": { "default": {} }
}
}
}
README
# @superlabs/openclaw-supervoicemode
OpenClaw channel plugin for [Super Voice Mode](https://voicemode.io) β a native Mac voice dictation and assistant app.
This plugin lets Super Voice Mode use a locally-running OpenClaw gateway as its assistant backend. SVM opens a WebSocket to this plugin and ships voice turns; the plugin dispatches them and streams replies back over the same socket.
## Status
Working end-to-end: WebSocket protocol, auth, turn dispatch, gateway lifecycle hooks (Running / Connected / Last inbound visible in the OpenClaw web UI). The dispatch path is currently a **shortcut** that POSTs to the gateway's `/v1/chat/completions` rather than going through `runtime.channel.turn.run` β so the wire works, but skills, memory, scheduling, and proactive heartbeat delivery don't reach SVM yet. See `STATUS.md` for the full roadmap.
## Wire protocol
The plugin opens a WebSocket server on `127.0.0.1:18790` (configurable via `SUPERVOICEMODE_BIND_ADDRESS`). Clients authenticate with a shared token, then send `supervoicemode.turn` frames and receive `supervoicemode.reply` frames.
```
Client β {"type":"auth","token":"<token>"}
Server β {"type":"auth.ok"} // or {"type":"auth.error","message":"..."}
Client β {"type":"supervoicemode.turn",
"turnId":"<uuid>",
"transcript":"<user speech>",
"userId":"<stable per-install id>",
"systemPrompt":"<composed prompt>"}
Server β {"type":"supervoicemode.reply",
"turnId":"<uuid>","text":"<reply>","final":true}
```
Errors come back as `{"type":"supervoicemode.error","code":"...","message":"...","turnId":"..."}`. Bad-handshake closes use code 4400; auth-failure closes use 4401.
## Gateway configuration
Two env vars on the gateway container:
- `SUPERVOICEMODE_AUTH_TOKEN` β the shared token clients must present
- `SUPERVOICEMODE_BIND_ADDRESS` β `host:port` to listen on (default `127.0.0.1:18790`)
Plus a `channels.supervoicemode` block in `~/.openclaw/openclaw.json`:
```json
{
"channels": {
"supervoicemode": {
"bindAddress": "127.0.0.1:18790",
"accounts": { "default": {} }
}
}
}
```
The `accounts.default` entry is what makes the gateway's lifecycle harness call `startAccount` and bind the channel as live.
## Local development
```bash
npm install
npm run build
# Sideload into a running OpenClaw container
docker cp . openclaw-openclaw-gateway-1:/tmp/svm-plugin
docker exec openclaw-openclaw-gateway-1 \
node /app/dist/index.js plugins install /tmp/svm-plugin --force
docker restart openclaw-openclaw-gateway-1
```
Smoke test from the host (after the gateway logs `WS server listening on ws://0.0.0.0:18790`):
```bash
TOKEN=$(grep ^SUPERVOICEMODE_AUTH_TOKEN ~/Projects/openclaw/.env | cut -d= -f2)
node -e "
const ws = new WebSocket('ws://127.0.0.1:18790');
ws.addEventListener('open', () => ws.send(JSON.stringify({type:'auth', token:'$TOKEN'})));
ws.addEventListener('message', (e) => {
console.log('β', e.data);
const m = JSON.parse(e.data);
if (m.type === 'auth.ok') {
ws.send(JSON.stringify({type:'supervoicemode.turn', turnId:'t1', transcript:'pong', userId:'test'}));
}
if (m.type === 'supervoicemode.reply') ws.close();
});
ws.addEventListener('close', () => process.exit(0));
"
```
Expected: `auth.ok`, then a `supervoicemode.reply` with the gateway's response.
## Repo layout
```
src/
βββ index.ts # plugin entry; gateway.startAccount/stopAccount
βββ ws-server.ts # WebSocket listener, auth + frame parsing
βββ dispatch-shortcut.ts # POST /v1/chat/completions (Phase 4c-B)
βββ setup-adapter.ts # listAccountIds / resolveAccount / resolveAccountId
```
`STATUS.md` tracks open debts and the next-session roadmap. The longer plan lives in the [voicemode repo](https://github.com/mhkey/voicemode) under `docs/drafts/openclaw-supervoicemode-plugin-plan.md`.
## License
MIT
voice
Comments
Sign in to leave a comment