{"_id":"@avervox/openclaw-plugin","_rev":"3-1a32efd62e0dbd67fe5f171b2bdea976","name":"@avervox/openclaw-plugin","dist-tags":{"latest":"0.2.2"},"versions":{"0.2.0":{"name":"@avervox/openclaw-plugin","version":"0.2.0","keywords":["openclaw","clawhub","tts","stt","speech","avervox","offline","piper","kokoro"],"author":{"name":"Carl E. Hartung"},"license":"MIT","_id":"@avervox/openclaw-plugin@0.2.0","maintainers":[{"name":"avervox","email":"info@avervoxpro.com"}],"homepage":"https://github.com/avrvx/AverVOX-Integrations/tree/main/openclaw","bugs":{"url":"https://github.com/avrvx/AverVOX-Integrations/issues"},"dist":{"shasum":"6f16f9d80a6674933b306fb02626310a1e50a049","tarball":"https://registry.npmjs.org/@avervox/openclaw-plugin/-/openclaw-plugin-0.2.0.tgz","fileCount":8,"integrity":"sha512-ioPtksa+7wSaIC9HVJ99kHNMmCkie2GjwXKUu+vuVtRrRewE9l7hpQBmYBMekFO9P570bdqHj3v06wMYjjAfFg==","signatures":[{"sig":"MEUCIQCVH03O9QmStG7V8R2N0vYEKT/olFmwZH5eh0YPNU9Q6gIgGEaNb6dqmGR0VPycAAXMPq3dWego/Hu9vNUZvfV/LfI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56370},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"9b72c539fafb20f56fbb641e439690777adb0d6e","scripts":{"test":"npm run build && node --test test/*.test.mjs","build":"tsc -p tsconfig.json","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"avervox","email":"info@avervoxpro.com"},"openclaw":{"build":{"openclawVersion":"2026.7.2","pluginSdkVersion":"2026.7.2"},"compat":{"pluginApi":">=2026.7.2","minGatewayVersion":"2026.7.2"},"providers":["avervox"],"extensions":["./dist/index.js"]},"repository":{"url":"git+https://github.com/avrvx/AverVOX-Integrations.git","type":"git","directory":"openclaw"},"_npmVersion":"11.18.0","description":"AverVOX local speech provider for OpenClaw (OSS or Pro via avrvx CLI)","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/node":"^22.0.0"},"peerDependencies":{"openclaw":"*"},"_npmOperationalInternal":{"tmp":"tmp/openclaw-plugin_0.2.0_1785038579676_0.40130818769039345","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@avervox/openclaw-plugin","version":"0.2.1","keywords":["openclaw","clawhub","tts","stt","speech","avervox","offline","piper","kokoro"],"author":{"name":"Carl E. Hartung"},"license":"MIT","_id":"@avervox/openclaw-plugin@0.2.1","maintainers":[{"name":"avervox","email":"info@avervoxpro.com"}],"homepage":"https://github.com/avrvx/AverVOX-Integrations/tree/main/openclaw","bugs":{"url":"https://github.com/avrvx/AverVOX-Integrations/issues"},"dist":{"shasum":"f4749fd685cb8d09070028db020f5cd042fcd368","tarball":"https://registry.npmjs.org/@avervox/openclaw-plugin/-/openclaw-plugin-0.2.1.tgz","fileCount":8,"integrity":"sha512-+GaVhfjd9n0+tS7KR1Wc/5jIzCJ15+TlC+GhoBWWERf6z3MDOjxKhn7YKXxTBpUsnMKtB6cI/OtEs+hLJdAZXA==","signatures":[{"sig":"MEUCIQDdCFFnKSydkqzX1+yGKxdlobEiKUgZL8h6HZJPc+WCXwIgRJVY3qOX6UZzmvPONSe6SuFxl+S6YlOH7p3ujoFjRbs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56973},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"7d8be9687a9340b211b3e260ddf3932eeef54410","scripts":{"test":"npm run build && node --test test/*.test.mjs","build":"tsc -p tsconfig.json","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"avervox","email":"info@avervoxpro.com"},"openclaw":{"build":{"openclawVersion":"2026.7.2","pluginSdkVersion":"2026.7.2"},"compat":{"pluginApi":">=2026.7.2","minGatewayVersion":"2026.7.2"},"providers":["avervox"],"extensions":["./dist/index.js"]},"repository":{"url":"git+https://github.com/avrvx/AverVOX-Integrations.git","type":"git","directory":"openclaw"},"_npmVersion":"11.18.0","description":"AverVOX local speech provider for OpenClaw (OSS or Pro via avrvx CLI)","directories":{},"_nodeVersion":"22.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/node":"^22.0.0"},"peerDependencies":{"openclaw":"*"},"_npmOperationalInternal":{"tmp":"tmp/openclaw-plugin_0.2.1_1785039858275_0.31605292478657443","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@avervox/openclaw-plugin","version":"0.2.2","description":"Local speech for OpenClaw — no cloud speech API. AverVOX speech provider (OSS or Pro via the avrvx CLI).","keywords":["openclaw","clawhub","tts","stt","speech","avervox","offline","piper","kokoro"],"homepage":"https://github.com/avrvx/AverVOX-Integrations/tree/main/openclaw","bugs":{"url":"https://github.com/avrvx/AverVOX-Integrations/issues"},"repository":{"type":"git","url":"git+https://github.com/avrvx/AverVOX-Integrations.git","directory":"openclaw"},"author":{"name":"Carl E. Hartung"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"npm run build && node --test test/*.test.mjs","prepack":"npm run build"},"engines":{"node":">=20"},"openclaw":{"extensions":["./dist/index.js"],"providers":["avervox"],"compat":{"pluginApi":">=2026.7.2","minGatewayVersion":"2026.7.2"},"build":{"openclawVersion":"2026.7.2","pluginSdkVersion":"2026.7.2"}},"peerDependencies":{"openclaw":"*"},"devDependencies":{"typescript":"^5.8.0","@types/node":"^22.0.0"},"publishConfig":{"access":"public"},"license":"MIT","_id":"@avervox/openclaw-plugin@0.2.2","_integrity":"sha512-4p59pdD1MNhsamrQwpGOGYAqUAK7atYoqf3kjY9bPOqAgcr1zEvE8dnM09qI0R7pX+L7N92QzjpcP92edRJJ5Q==","_resolved":"/tmp/avervox-openclaw-plugin-0.2.2.tgz","_from":"file:/tmp/avervox-openclaw-plugin-0.2.2.tgz","_nodeVersion":"22.21.0","_npmVersion":"11.18.0","dist":{"integrity":"sha512-4p59pdD1MNhsamrQwpGOGYAqUAK7atYoqf3kjY9bPOqAgcr1zEvE8dnM09qI0R7pX+L7N92QzjpcP92edRJJ5Q==","shasum":"614909b74513c6c1c6305422ff755903a220f242","tarball":"https://registry.npmjs.org/@avervox/openclaw-plugin/-/openclaw-plugin-0.2.2.tgz","fileCount":9,"unpackedSize":64082,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAcr6ODGQiXpWOvfxUOpr28K/cIcuvU9Ht67B3ChXlkyAiEAqmzT8C3jzWflOn0+tqdMZ1R8jG9kJFWkmi6N5QzX+V8="}]},"_npmUser":{"name":"avervox","email":"info@avervoxpro.com"},"directories":{},"maintainers":[{"name":"avervox","email":"info@avervoxpro.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openclaw-plugin_0.2.2_1785079628456_0.184073390021668"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-26T04:02:59.417Z","modified":"2026-07-26T15:27:08.779Z","0.2.0":"2026-07-26T04:02:59.820Z","0.2.1":"2026-07-26T04:24:18.405Z","0.2.2":"2026-07-26T15:27:08.624Z"},"bugs":{"url":"https://github.com/avrvx/AverVOX-Integrations/issues"},"author":{"name":"Carl E. Hartung"},"license":"MIT","homepage":"https://github.com/avrvx/AverVOX-Integrations/tree/main/openclaw","keywords":["openclaw","clawhub","tts","stt","speech","avervox","offline","piper","kokoro"],"repository":{"type":"git","url":"git+https://github.com/avrvx/AverVOX-Integrations.git","directory":"openclaw"},"description":"Local speech for OpenClaw — no cloud speech API. AverVOX speech provider (OSS or Pro via the avrvx CLI).","maintainers":[{"name":"avervox","email":"info@avervoxpro.com"}],"readme":"# AverVOX ↔ OpenClaw\n\n**Local speech for OpenClaw — no cloud speech API.**\n\nUse AverVOX (OSS or Pro) as a local [speech provider](https://docs.openclaw.ai/plugins/sdk-provider-plugins)\nfor [OpenClaw](https://github.com/openclaw/openclaw). Distributed on npm and\n[ClawHub](https://github.com/openclaw/clawhub). MIT licensed, source-visible —\nsee the [Security model](#security-model) for exactly what the plugin runs,\nwrites, and connects to.\n\nSpeech runs on the same machine as the agent: replies are never sent to a\nspeech vendor, there is no per-character bill, and it all keeps working with\nthe network down. With the warm bridge running, OpenClaw hears the first audio\nof a reply in about 0.36 s — see [Latency](#latency) for the test conditions.\n\n## Fastest path\n\nRecent AverVOX builds write the config below and verify it for you:\n\n```bash\navrvx --install-integration openclaw\n```\n\nIt synthesizes real audio afterwards and exits non-zero if anything is wrong,\nand it never modifies an existing `~/.openclaw/openclaw.json` — if you already\nhave one, it writes the snippet alongside for you to merge.\n\n## Quick path: Local CLI TTS (no custom plugin)\n\nIf you only need reply TTS, OpenClaw’s built-in **tts-local-cli** provider can\ncall AverVOX directly:\n\n```json5\n// ~/.openclaw/openclaw.json\n{\n  tts: {\n    auto: \"always\",\n    provider: \"tts-local-cli\",\n    providers: {\n      \"tts-local-cli\": {\n        command: \"avrvx\",\n        args: [\"--synthesize\", \"--text\", \"{{Text}}\", \"--output\", \"{{OutputPath}}\"],\n        outputFormat: \"wav\",\n        timeoutMs: 180000,\n      },\n    },\n  },\n}\n```\n\nSee [`openclaw.config.snippet.json5`](https://github.com/avrvx/AverVOX-Integrations/blob/main/openclaw/openclaw.config.snippet.json5).\n\n## This package: `@avervox/openclaw-plugin`\n\nRegisters speech provider id `avervox` via `api.registerSpeechProvider`, which\nis the preferred vendor shape for ClawHub and richer tooling.\n\nUnlike the config snippet above, the plugin pipes reply text to `avrvx` over\nstdin (so it never appears in the process list), writes its temporary WAV files\ninto an owner-only directory, and runs `avrvx` in its own process group so a\ntimeout also kills Piper or Whisper.\n\n### Install\n\n```bash\nopenclaw plugins install @avervox/openclaw-plugin\n```\n\nA bare spec resolves against ClawHub first and falls back to npm, which is\nwhere this package is published; `npm:@avervox/openclaw-plugin` forces that\nsource. `plugins install` enables the plugin as well, so there is no separate\n`openclaw plugins enable` step.\n\nTo pin a version instead of tracking the latest release:\n\n```bash\nopenclaw plugins install @avervox/openclaw-plugin@0.2.2\n```\n\nTo verify what you installed:\n\n```bash\n# The registry artifact: ClawHub stores the exact npm-pack bytes and checks\n# them against npm's shasum. Compare npm's published checksum yourself with:\nnpm view @avervox/openclaw-plugin@0.2.2 dist.shasum\n\n# The wiring, end to end: synthesizes real audio through the provider and\n# exits non-zero if anything along the path is broken.\navrvx --install-integration openclaw\n```\n\nThen select `avervox` as the speech provider in `~/.openclaw/openclaw.json`:\n\n```json5\n{ tts: { auto: \"always\", provider: \"avervox\" } }\n```\n\nOptional plugin settings: `avrvxPath` (an explicit binary path, if `avrvx` is\nnot on `PATH`), `timeoutMs` (default 180000), and `voice`/`speed` defaults for\nhosts that do not offer a picker.\n\n### Security model\n\nOpenClaw native plugins run in-process and are not sandboxed, so you should\nknow exactly what a plugin does before installing it. This one is MIT licensed\nand the tarball ships `src/` alongside `dist/`, so what you install is\nreadable. Specifically:\n\n- **Commands it executes.** Only `avrvx` — resolved from the `avrvxPath`\n  setting if you set one, otherwise from `PATH`. Reply text is piped to it\n  over stdin, never passed as a command-line argument, so your conversations\n  do not appear in the process list.\n- **Files it creates.** Temporary WAV files under `$TMPDIR/avervox-openclaw/`,\n  a directory created with mode `0700` (owner-only, unlike shared `/tmp`).\n  Each file is deleted as soon as it has been read.\n- **Network access.** None. No telemetry, no update checks, no remote calls.\n  The only socket the plugin touches is the local Unix socket of the optional\n  `avrvx --daemon` warm bridge (`$XDG_RUNTIME_DIR/avervox/bridge.sock`), and\n  setting `AVERVOX_BRIDGE=0` disables even that.\n- **Process control.** `avrvx` runs in its own process group, so a timeout\n  kills the Piper or Whisper children too, not just the wrapper.\n- **Pinning and verification.** Install with an explicit `@version` and check\n  the artifact and the wiring as shown under [Install](#install).\n- **How releases are built.** `prepack` runs the TypeScript build, tests run\n  against a stub `avrvx` (`npm test`), and the tarball from `npm pack` is\n  published byte-for-byte to npm and ClawHub — ClawHub verifies its copy\n  against npm's shasum. See [RELEASING.md](../RELEASING.md).\n\n### Streaming\n\nThe provider implements `streamSynthesize` alongside `synthesize`, so a host\nthat can play audio chunks starts on the first sentence instead of waiting for\nthe last (see [Latency](#latency)). It resolves to a `ReadableStream` of\nheaderless little-endian PCM16, with the sample rate in `outputFormat`:\n\n```ts\nconst { audioStream, outputFormat, release } = await provider.streamSynthesize({ text });\nconst reader = audioStream.getReader();   // outputFormat: \"pcm_22050\"\nfor (;;) {\n  const { value, done } = await reader.read();\n  if (done) break;\n  player.write(value);\n}\nawait release?.();\n```\n\nIt streams over the [warm bridge](../README.md#streaming) when\n`avrvx --daemon` is running and falls back to `avrvx --synthesize --output -`\nwhen it is not. Hosts that only call `synthesize` are unaffected and keep\ngetting a complete WAV.\n\n### Develop locally\n\n```bash\ngit clone https://github.com/avrvx/AverVOX-Integrations.git\ncd AverVOX-Integrations/openclaw\nnpm install\nnpm run typecheck\nnpm test           # builds, then runs node:test against a stub avrvx\nnpm run build      # emits dist/, which package.json and openclaw.extensions point at\n# Point OpenClaw at this checkout:\n#   openclaw plugins install .\n# or add to plugins.load.paths in openclaw.json\n```\n\nThe tests spawn a Python stub in place of `avrvx`, so no speech models are\nneeded to run them.\n\n### Publish to ClawHub\n\nClawHub is a registry of its own, so an npm publish does not appear there. Its\nCLI ships separately from OpenClaw:\n\n```bash\nnpm install -g clawhub\nclawhub login\nnpm pack --pack-destination /tmp\nclawhub package publish /tmp/avervox-openclaw-plugin-0.2.2.tgz\n```\n\nPublishing the tarball rather than the directory uploads the exact npm-pack\nbytes, so ClawHub serves the same artifact npm does and can verify it against\nnpm's own shasum. `openclaw.compat.pluginApi` and `openclaw.build.openclawVersion`\nare required of a code plugin and are already set in `package.json`.\n\n## AverVOX → OpenClaw (Converse)\n\nAdd an AverVOX LLM profile whose API base is your OpenClaw OpenAI-compatible\nendpoint. No special session header unless your OpenClaw setup documents one.\n\n## OSS vs Pro\n\nOne plugin id (`avervox`). Edition and engines come from `avrvx --capabilities`.\n\n## Latency\n\nMeasured through the plugin's own `synthesize` and `streamSynthesize` on a 2017\nlaptop with Piper `en_US-lessac-high`. \"First audio\" is the wait before playback\ncan start on a three-sentence reply; \"whole reply\" is the wait for a finished WAV.\n\n| | Spawn per call | Warm daemon |\n|---|---|---|\n| First audio (`streamSynthesize`) | 2.6 s | 0.36 s |\n| Whole reply (`synthesize`) | 3.2 s | 0.91 s |\n\nTwo independent wins. `avrvx --daemon` removes the Python start and model load\nfrom every call; see [systemd/](https://github.com/avrvx/AverVOX-Integrations/tree/main/systemd)\nfor a user unit. Streaming then starts playback on the first sentence instead\nof the last. Neither is required — without both, the first column applies and\neverything still works.\n\n## Tested against\n\n| | Version |\n|---|---|\n| OpenClaw | 2026.6.33 (npm) and 2026.7.2 (source, commit `34ee065b`) |\n| AverVOX | OSS and Pro, 0.5.0 and newer |\n| Node | 20 and 22 |\n\nThe published npm build trails the source tree, so the packed tarball is\ntypechecked against `SpeechProviderPlugin` from *both* — the one users install\nand the one that is coming. `synthesize` and `streamSynthesize` were then run\nagainst a real `avrvx` from the installed package.\n\nSpeech output only: OpenClaw's transcription hook is\n`registerRealtimeTranscriptionProvider`, a duplex streaming interface, and\n`avrvx --transcribe` takes a finished file. There is no seam for it today, so\nthe plugin does not pretend to offer one.\n","readmeFilename":"README.md"}