npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@voxflow/openclaw-tts

v0.1.4

Published

VoxFlow TTS speech provider for OpenClaw — 94+ Chinese voices, multilingual, voice cloning

Downloads

482

Readme

@voxflow/openclaw-tts

npm version

VoxFlow TTS speech provider for OpenClaw — bring 94+ Chinese voices and multilingual auto-detection to every channel your bot lives in, with zero API key setup.


What It Does

@voxflow/openclaw-tts registers VoxFlow as a speech provider inside OpenClaw. When a reply is ready, OpenClaw calls the plugin's synthesize() method, which sends the text to api.voxflow.studio, receives an MP3 buffer, and hands it back to OpenClaw. OpenClaw then re-encodes the audio per channel: SILK for WeChat voice messages, Opus for Telegram/Discord, and so on. Authentication uses the same JWT token shared with the VoxFlow CLI — login once via device code and all tools share the session.


Quick Start

Step 1 — Install the plugin

openclaw plugins install @voxflow/openclaw-tts
openclaw gateway restart

Step 2 — Set VoxFlow as your TTS provider in openclaw.json

{
  "messages": {
    "tts": {
      "auto": "inbound",
      "provider": "voxflow"
    }
  }
}

Step 3 — Authenticate

Send /voxflow login in any chat channel, or run in a terminal:

npx voxflow login

A browser window opens. Sign in with email OTP or Google. Done — the token is cached at ~/.config/voxflow/token.json and shared with the CLI.


Full openclaw.json Example

{
  // TTS behaviour
  "messages": {
    "tts": {
      // When to auto-synthesize replies (see TTS Modes table below)
      "auto": "inbound",
      // Use VoxFlow as the speech provider
      "provider": "voxflow"
    }
  },

  // Plugin-level config for the VoxFlow provider
  "plugins": {
    "entries": {
      "openclaw-tts": {
        "config": {
          // Voice ID from the VoxFlow voice library
          "voice": "v-female-R2s4N9qJ",
          // Playback speed multiplier (0.5 – 2.0, default 1.0)
          "speed": 1.0,
          // API endpoint (change only if self-hosting)
          "apiBase": "https://api.voxflow.studio",
          // Request timeout in milliseconds (default 15000)
          "timeoutMs": 15000
        }
      }
    }
  }
}

TTS Modes

Set messages.tts.auto to one of:

| Value | Behaviour | |-------|-----------| | off | TTS never runs automatically (default). Use /voxflow command or LLM directive to trigger manually. | | always | Every bot reply is synthesized to voice, regardless of how the user messaged. | | inbound | Voice reply only when the incoming user message was itself a voice message. | | tagged | The LLM decides per-reply by inserting a [[tts:…]] directive in its output. |

You can also force TTS on a single reply using an LLM directive in your system prompt or message:

[[tts:provider=voxflow voiceId=v-female-R2s4N9qJ speed=1.2]]

Voice Selection

Set plugins.entries["openclaw-tts"].config.voice to any voice ID from the VoxFlow library.

Browse all voices at voxflow.studio/app — filter by language, gender, and style.

Example Voices

| Voice ID | Description | |----------|-------------| | v-female-R2s4N9qJ | Default — warm Mandarin female, neutral style | | v-male-Zh4kP1mX | Deep Mandarin male, broadcast style | | v-female-En9wQ3jY | English female, clear and natural | | v-female-Ja5rT8nK | Japanese female, polite style |

Multilingual auto-detection is on by default: VoxFlow detects zh/en/ja per segment and switches pronunciation accordingly — no extra config needed.


Commands

Send these slash commands in any OpenClaw channel:

/voxflow

Synthesizes the previous bot reply as voice and sends it to the channel.

User:  /voxflow
Bot:   🔊 [voice message — 3s]

/voxflow login

Starts the device-code authentication flow (see Authentication section).

User:  /voxflow login
Bot:   Open this URL to log in:
       https://voxflow.studio/cli-auth?state=abc123&callback_port=0
       (expires in 10 minutes)

/voxflow status

Shows authentication status and remaining quota.

User:  /voxflow status
Bot:   ✅ Authenticated as [email protected]
       Quota remaining: 8,400 / 10,000 (free tier)
       Voice: v-female-R2s4N9qJ  Speed: 1.0x

Advanced Config

All options under plugins.entries["openclaw-tts"].config:

| Option | Type | Default | Description | |--------|------|---------|-------------| | voice | string | v-female-R2s4N9qJ | Voice ID. Browse at voxflow.studio/app. | | speed | number | 1.0 | Playback speed multiplier. Range: 0.5 – 2.0. | | apiBase | string | https://api.voxflow.studio | API base URL. Override only if self-hosting. | | timeoutMs | number | 15000 | HTTP request timeout in milliseconds. |


Authentication

The plugin reads the VoxFlow JWT from the following sources, in order:

  1. VOXFLOW_TOKEN environment variable
  2. VOXFLOW_JWT environment variable
  3. ~/.config/voxflow/token.json — written by voxflow login or /voxflow login

Device Code Flow (step by step)

  1. Send /voxflow login in any channel, or run npx voxflow login in a terminal.
  2. The plugin starts a temporary local HTTP server on a random port and opens (or prints) a URL like: https://voxflow.studio/cli-auth?state=<nonce>&callback_port=<port>
  3. Open the URL in a browser. Sign in with email OTP or Google OAuth.
  4. The browser redirects to localhost:<port>/callback?token=<JWT>.
  5. The plugin writes the token to ~/.config/voxflow/token.json.
  6. All subsequent requests use this cached token.

Token Expiry

Supabase JWTs expire after approximately 1 hour. When the token expires, the plugin will respond with an authentication error. Re-run /voxflow login to refresh.

CI / Headless Environments

Set the VOXFLOW_TOKEN or VOXFLOW_JWT environment variable to skip the browser flow entirely:

export VOXFLOW_TOKEN="eyJhbGciOiJFUzI1NiIs..."

Channel Support

VoxFlow outputs MP3. OpenClaw re-encodes per channel automatically:

| Channel | Encoding | Notes | |---------|----------|-------| | WeChat | SILK | Required by WeChat voice message protocol | | Telegram | Opus (OGG) | Standard Telegram voice note format | | Discord | Opus stream | Sent as audio attachment | | Slack | MP3 | Uploaded as file attachment | | WhatsApp | Opus (OGG) | Standard WhatsApp PTT format | | Feishu / Lark | MP3 | Uploaded as audio message | | DingTalk | MP3 | Uploaded as voice message |

No per-channel config is required — OpenClaw handles format conversion transparently.


Quota & Pricing

Each TTS synthesis call costs 100 quota regardless of text length (standard voices). Monthly quota resets every 30 days. Bonus quota from referrals never expires and is used after the monthly pool is exhausted.

| Tier | Monthly Quota | TTS Calls | Price | |------|--------------|-----------|-------| | Free | 10,000 | ~100 | $0 | | Plus | 100,000 | ~1,000 | $9/mo | | Pro | 250,000 | ~2,500 | $29/mo | | Max | 600,000 | ~6,000 | $59/mo |

Upgrade or check usage at voxflow.studio.


Troubleshooting

404 Not Found on /voxflow login

The plugin or bot is not connected to the internet, or apiBase is misconfigured. Verify connectivity to https://api.voxflow.studio/health.

401 Unauthorized / token expired

Your JWT has expired (Supabase tokens last ~1 hour). Re-authenticate:

npx voxflow login
# or in-chat:
/voxflow login

429 Too Many Requests

The TTS rate limiter is 20 requests/min. Reduce call frequency or upgrade your tier.

No token found on startup

The plugin cannot find a JWT. Either run /voxflow login, or set the VOXFLOW_TOKEN environment variable.

Voice ID not recognized

Check the voice ID against the library at voxflow.studio/app. Voice IDs are case-sensitive.

Audio not playing in WeChat

Ensure OpenClaw has WeChat voice message permissions. SILK encoding requires the bot account to have voice send rights in the target group.


Development / Contributing

Local Setup

# Clone the repo
git clone https://github.com/VoxFlowStudio/FlowStudio.git
cd FlowStudio/openclaw-plugin

# Install dependencies
npm install

# Build TypeScript
npm run build

# Link plugin locally (live reload, no copy)
openclaw plugins install -l .

Project Structure

openclaw-plugin/
├── index.ts                  → Plugin entry: definePluginEntry + registerSpeechProvider
├── src/
│   ├── speech-provider.ts    → buildVoxFlowSpeechProvider(): SpeechProviderPlugin
│   └── auth.ts               → getVoxFlowToken() — reads CLI cache or env var
├── tsconfig.json
└── package.json

Implemented Interface

The plugin implements OpenClaw's SpeechProviderPlugin interface:

| Method | Description | |--------|-------------| | id | "voxflow" — provider identifier used in openclaw.json | | label | Display name shown in OpenClaw UI | | isConfigured() | Returns true if a valid JWT is present | | synthesize(req) | Calls VoxFlow API, returns { audioBuffer, outputFormat, fileExtension, voiceCompatible } | | listVoices(req) | Fetches the full voice catalog from the VoxFlow API |

Running Tests

npm test

Contributing

  1. Fork the repo and create a branch: feat/my-change
  2. Make changes, run npm run build and npm test
  3. Open a PR against main — use Squash and Merge

Links