AverVOX
Local speech for OpenClaw — no cloud speech API. AverVOX speech provider (OSS or Pro via the avrvx CLI).
Install
openclaw plugins install clawhub:@avervox/openclaw-pluginAverVOX ↔ OpenClaw
Local speech for OpenClaw — no cloud speech API.
Use AverVOX (OSS or Pro) as a local speech provider for OpenClaw. Distributed on npm and ClawHub. MIT licensed, source-visible — see the Security model for exactly what the plugin runs, writes, and connects to.
Speech runs on the same machine as the agent: replies are never sent to a speech vendor, there is no per-character bill, and it all keeps working with the network down. With the warm bridge running, OpenClaw hears the first audio of a reply in about 0.36 s — see Latency for the test conditions.
Fastest path
Recent AverVOX builds write the config below and verify it for you:
avrvx --install-integration openclaw
It synthesizes real audio afterwards and exits non-zero if anything is wrong,
and it never modifies an existing ~/.openclaw/openclaw.json — if you already
have one, it writes the snippet alongside for you to merge.
Quick path: Local CLI TTS (no custom plugin)
If you only need reply TTS, OpenClaw’s built-in tts-local-cli provider can call AverVOX directly:
// ~/.openclaw/openclaw.json
{
tts: {
auto: "always",
provider: "tts-local-cli",
providers: {
"tts-local-cli": {
command: "avrvx",
args: ["--synthesize", "--text", "{{Text}}", "--output", "{{OutputPath}}"],
outputFormat: "wav",
timeoutMs: 180000,
},
},
},
}
See openclaw.config.snippet.json5.
This package: @avervox/openclaw-plugin
Registers speech provider id avervox via api.registerSpeechProvider, which
is the preferred vendor shape for ClawHub and richer tooling.
Unlike the config snippet above, the plugin pipes reply text to avrvx over
stdin (so it never appears in the process list), writes its temporary WAV files
into an owner-only directory, and runs avrvx in its own process group so a
timeout also kills Piper or Whisper.
Install
openclaw plugins install @avervox/openclaw-plugin
A bare spec resolves against ClawHub first and falls back to npm, which is
where this package is published; npm:@avervox/openclaw-plugin forces that
source. plugins install enables the plugin as well, so there is no separate
openclaw plugins enable step.
To pin a version instead of tracking the latest release:
openclaw plugins install @avervox/openclaw-plugin@0.2.2
To verify what you installed:
# The registry artifact: ClawHub stores the exact npm-pack bytes and checks
# them against npm's shasum. Compare npm's published checksum yourself with:
npm view @avervox/openclaw-plugin@0.2.2 dist.shasum
# The wiring, end to end: synthesizes real audio through the provider and
# exits non-zero if anything along the path is broken.
avrvx --install-integration openclaw
Then select avervox as the speech provider in ~/.openclaw/openclaw.json:
{ tts: { auto: "always", provider: "avervox" } }
Optional plugin settings: avrvxPath (an explicit binary path, if avrvx is
not on PATH), timeoutMs (default 180000), and voice/speed defaults for
hosts that do not offer a picker.
Security model
OpenClaw native plugins run in-process and are not sandboxed, so you should
know exactly what a plugin does before installing it. This one is MIT licensed
and the tarball ships src/ alongside dist/, so what you install is
readable. Specifically:
- Commands it executes. Only
avrvx— resolved from theavrvxPathsetting if you set one, otherwise fromPATH. Reply text is piped to it over stdin, never passed as a command-line argument, so your conversations do not appear in the process list. - Files it creates. Temporary WAV files under
$TMPDIR/avervox-openclaw/, a directory created with mode0700(owner-only, unlike shared/tmp). Each file is deleted as soon as it has been read. - Network access. None. No telemetry, no update checks, no remote calls.
The only socket the plugin touches is the local Unix socket of the optional
avrvx --daemonwarm bridge ($XDG_RUNTIME_DIR/avervox/bridge.sock), and settingAVERVOX_BRIDGE=0disables even that. - Process control.
avrvxruns in its own process group, so a timeout kills the Piper or Whisper children too, not just the wrapper. - Pinning and verification. Install with an explicit
@versionand check the artifact and the wiring as shown under Install. - How releases are built.
prepackruns the TypeScript build, tests run against a stubavrvx(npm test), and the tarball fromnpm packis published byte-for-byte to npm and ClawHub — ClawHub verifies its copy against npm's shasum. See RELEASING.md.
Streaming
The provider implements streamSynthesize alongside synthesize, so a host
that can play audio chunks starts on the first sentence instead of waiting for
the last (see Latency). It resolves to a ReadableStream of
headerless little-endian PCM16, with the sample rate in outputFormat:
const { audioStream, outputFormat, release } = await provider.streamSynthesize({ text });
const reader = audioStream.getReader(); // outputFormat: "pcm_22050"
for (;;) {
const { value, done } = await reader.read();
if (done) break;
player.write(value);
}
await release?.();
It streams over the warm bridge when
avrvx --daemon is running and falls back to avrvx --synthesize --output -
when it is not. Hosts that only call synthesize are unaffected and keep
getting a complete WAV.
Develop locally
git clone https://github.com/avrvx/AverVOX-Integrations.git
cd AverVOX-Integrations/openclaw
npm install
npm run typecheck
npm test # builds, then runs node:test against a stub avrvx
npm run build # emits dist/, which package.json and openclaw.extensions point at
# Point OpenClaw at this checkout:
# openclaw plugins install .
# or add to plugins.load.paths in openclaw.json
The tests spawn a Python stub in place of avrvx, so no speech models are
needed to run them.
Publish to ClawHub
ClawHub is a registry of its own, so an npm publish does not appear there. Its CLI ships separately from OpenClaw:
npm install -g clawhub
clawhub login
npm pack --pack-destination /tmp
clawhub package publish /tmp/avervox-openclaw-plugin-0.2.2.tgz
Publishing the tarball rather than the directory uploads the exact npm-pack
bytes, so ClawHub serves the same artifact npm does and can verify it against
npm's own shasum. openclaw.compat.pluginApi and openclaw.build.openclawVersion
are required of a code plugin and are already set in package.json.
AverVOX → OpenClaw (Converse)
Add an AverVOX LLM profile whose API base is your OpenClaw OpenAI-compatible endpoint. No special session header unless your OpenClaw setup documents one.
OSS vs Pro
One plugin id (avervox). Edition and engines come from avrvx --capabilities.
Latency
Measured through the plugin's own synthesize and streamSynthesize on a 2017
laptop with Piper en_US-lessac-high. "First audio" is the wait before playback
can start on a three-sentence reply; "whole reply" is the wait for a finished WAV.
| Spawn per call | Warm daemon | |
|---|---|---|
First audio (streamSynthesize) | 2.6 s | 0.36 s |
Whole reply (synthesize) | 3.2 s | 0.91 s |
Two independent wins. avrvx --daemon removes the Python start and model load
from every call; see systemd/
for a user unit. Streaming then starts playback on the first sentence instead
of the last. Neither is required — without both, the first column applies and
everything still works.
Tested against
| Version | |
|---|---|
| OpenClaw | 2026.6.33 (npm) and 2026.7.2 (source, commit 34ee065b) |
| AverVOX | OSS and Pro, 0.5.0 and newer |
| Node | 20 and 22 |
The published npm build trails the source tree, so the packed tarball is
typechecked against SpeechProviderPlugin from both — the one users install
and the one that is coming. synthesize and streamSynthesize were then run
against a real avrvx from the installed package.
Speech output only: OpenClaw's transcription hook is
registerRealtimeTranscriptionProvider, a duplex streaming interface, and
avrvx --transcribe takes a finished file. There is no seam for it today, so
the plugin does not pretend to offer one.
