audioclaw-skills-voice-reply
by @kikidouloveme79
Use when AudioClaw Skills, Feishu, or Lark needs to send AudioClaw voice replies with runtime-switchable voice_id, emotion preset, or speaking style, includi...
clawhub install audioclaw-skills-voice-reply📖 About This Skill
name: audioclaw-skills-voice-reply description: Use when AudioClaw Skills, Feishu, or Lark needs to send AudioClaw voice replies with runtime-switchable voice_id, emotion preset, or speaking style, including per-message speaker overrides, voice-family emotion routing, cache reuse, and safe fallback when a requested voice is unavailable.
AudioClaw Skills Voice Reply
When to use
Use this skill when AudioClaw already has the final reply text and now needs a voice version that can change on demand.
Common triggers:
calm, warm, cheerful, serious, or promo.voice_id or voice_family in a single request without editing code.voice_id such as vc-... and wants the runtime to use it directly without falling back first.Do not use this skill for ASR intake or long-form digest generation.
Workflow
1. Start from the final user-facing text. Do not pass hidden reasoning or raw markdown tables.
2. Build an AudioClaw voice request with:
- text
- optional scene
- optional voice_id
- optional voice_family
- optional emotion
- optional speed, pitch, volume
3. Run scripts/openclaw_voice_switchboard.py.
- For AudioClaw on Feishu or Lark, prefer scripts/picoclaw_voice_reply.py.
4. Let the script resolve the request in this order:
- exact voice_id
- voice_family plus matching emotion variant
- scene plus emotion preset
- validated fallback voice
- Important: if the exact voice_id is a clone-style id such as vc-..., this skill now tries that id directly first, even if it is not part of the built-in official voice catalog.
5. If preference_key is present, the script can remember:
- reply_mode
- default voice_id
- default emotion
- default scene
6. If the result should be sent through AudioClaw media upload, pass:
- --out inside the AudioClaw workspace
- --openclaw-workspace-root pointing at the workspace root
- --delivery-profile feishu_voice when the downstream channel prefers .ogg/.opus
- optional --chmod 644 if you want to be explicit, though this skill now defaults to 0644
- if --openclaw-workspace-root is set and --out is omitted, this skill now writes to workspace/state/audio/ automatically
7. Use the returned JSON manifest in AudioClaw to:
- prefer scripts/picoclaw_voice_reply.py for AudioClaw on Feishu
- let the wrapper send the Feishu audio message directly
- do not send the local path or the MEDIA:... line through the message tool
- only use send_file when you intentionally opt out of direct Feishu sending
- log trace_id
- persist the resolved voice choice for the next turn if desired
8. If the requested voice is not available to the current key, let the fallback stand unless the user explicitly requires strict failure.
9. If you want AudioClaw to remember a clone voice, either:
- set it as the user's default voice with --set-default-voice-id vc-...
- or register it explicitly with --register-clone-voice-id vc-...
Voice discovery
When AudioClaw needs to find a usable voice or confirm a voice_id, use this order:
1. Check the local catalog first:
- run python3 scripts/openclaw_voice_switchboard.py --list-voices
- use this for fast lookup of built-in voices, known emotion variants, and clone voices already registered locally
2. If the user asks for the official public voice list, package availability, or a voice not found locally, check the official voice page:
- https://senseaudio.cn/docs/voice_api
- page title: API 音色服务说明
3. Prefer the official page when AudioClaw needs to confirm:
- whether a voice_id is a free, VIP, or SVIP voice
- whether a named speaker has multiple emotion variants
- whether the request likely needs selected-voice purchase or custom voice authorization
4. After finding a likely voice_id, still let the runtime validate access at synthesis time, because account permissions can differ by key.
Practical rule:
--list-voices is the first-stop runtime catalog.https://senseaudio.cn/docs/voice_api is the canonical fallback reference for official voice names, voice_id, and package tier notes.AudioClaw rule
When this skill is used inside AudioClaw for Feishu or Lark voice replies:
1. Run scripts/picoclaw_voice_reply.py.
2. Let the wrapper upload the generated .ogg/.opus file to Feishu and send it as msg_type=audio.
3. Do not call the send_file tool for that audio unless you explicitly passed --skip-direct-send.
4. Do not call the message tool with the local path or the MEDIA:... reference. AudioClaw will send them as plain text.
5. After the audio is sent, prefer no extra text confirmation.
6. If the host runtime still requires one final assistant message to finish the turn, send one short natural Chinese line such as 我已经用语音回复你了。 instead of leaving the turn empty.
7. Use media_reference only as debug metadata or future AudioClaw compatibility data.
This rule matters because this AudioClaw environment does not render MEDIA:... as media, and the generic send_file tool sends Feishu voice notes as plain files instead of audio messages. The reliable path here is direct Feishu upload plus msg_type=audio.
Runtime model
The official public TTS API exposes:
voice_setting.voice_idvoice_setting.speedvoice_setting.volvoice_setting.pitchaudio_setting.formataudio_setting.sample_ratestream=false
- SSE with stream=trueImportant constraint:
emotion request field.voice_id when one exists, or by keeping the voice and shaping speed / pitch / vol.Authorization: Bearer API_KEY. The generated Public Key is not required by this skill.voice_id looks like a clone id such as vc-..., this skill now auto-routes TTS to SenseAudio-TTS-1.5 and records audio.model_used in the manifest.API key lookup
This skill now treats SENSEAUDIO_API_KEY as the default API key source again.
Runtime rules:
SENSEAUDIO_API_KEY as an AudioClaw login token such as v2.public..., the shared bootstrap will replace it with the real sk-... value from ~/.audioclaw/workspace/state/senseaudio_credentials.json before TTS starts.--api-key-env still works, but the default runtime path is SENSEAUDIO_API_KEY.If you need the exact same speaker timbre across many emotions, use a purchased multi-variant voice family or an authorized custom voice. Otherwise this skill will approximate the requested emotion with the best available voice and tuning.
Request contract
Minimal JSON request:
{
"text": "我们已经收到你的需求,今天下午会把结果发给你。",
"scene": "assistant",
"emotion": "calm"
}
Full request:
{
"text": "新品今晚八点开售,现在下单还有首发赠品。",
"scene": "sales",
"voice_id": "male_0027_b",
"voice_family": "male_0027",
"emotion": "promo",
"speed": 1.08,
"pitch": 1,
"volume": 1.05,
"audio_format": "mp3",
"sample_rate": 32000,
"preference_key": "feishu:ou_xxx",
"reply_mode": "voice",
"allow_fallback": true,
"strict_voice": false,
"cache_dir": "/tmp/openclaw-voice-cache"
}
Clone voice example:
{
"text": "这是你的克隆音色回复测试。",
"voice_id": "vc-yxdCFUKyNLPexxJ66jaXWk",
"emotion": "calm",
"allow_fallback": false,
"strict_voice": true
}
Supported emotion presets:
neutralcalmwarmcheerfulseriouspromosadangryanalyticalSupported scene hints:
assistantcustomer_supportbriefingsalesmarketingnarrationeducationgamingwarningAudioClaw integration pattern
Recommended handoff:
1. AudioClaw generates final reply text.
2. AudioClaw decides whether this turn should speak and what mood it wants.
3. AudioClaw calls scripts/openclaw_voice_switchboard.py with a request JSON.
4. The script returns a manifest with:
- requested voice
- resolved voice
- emotion strategy
- effective speed / pitch / volume
- delivery profile and file mode
- local audio path
- AudioClaw-friendly media reference when the output is under a workspace root
- trace_id
5. AudioClaw uploads the resulting file to Feishu or any downstream channel, or lets the AudioClaw wrapper do that directly for Feishu.
Operational rules:
trace_id.0644 so the AudioClaw sender can read them reliably.--openclaw-workspace-root is set and --out stays inside that root, expose delivery.openclaw_media_reference.--delivery-profile feishu_voice is enabled, synthesize with AudioClaw first and then transcode to ogg/opus with system ffmpeg or imageio-ffmpeg.ffmpeg. Install ffmpeg or run python3 -m pip install imageio-ffmpeg on the target machine.workspace/state/audio/, which this skill will now use automatically when --openclaw-workspace-root is given without --out.scripts/picoclaw_voice_reply.py now uses the local Feishu app credentials from ~/.audioclaw/config.json, uploads the audio through the official /open-apis/im/v1/files endpoint, and sends it as msg_type=audio.chat_id from the latest agent_main_feishu_direct_*.jsonl session log unless you pass --chat-id explicitly.Commands
List voices:
python3 scripts/openclaw_voice_switchboard.py --list-voices
Check the official voice catalog page:
https://senseaudio.cn/docs/voice_api
List emotion presets:
python3 scripts/openclaw_voice_switchboard.py --list-emotions
Enable permanent voice reply for one user:
python3 scripts/openclaw_voice_switchboard.py \
--preference-key "feishu:ou_xxx" \
--set-reply-mode voice \
--set-default-voice-id male_0004_a \
--set-default-emotion calm \
--set-default-scene assistant
Enable permanent cloned-voice reply for one user:
python3 scripts/openclaw_voice_switchboard.py \
--preference-key "feishu:ou_xxx" \
--set-reply-mode voice \
--set-default-voice-id vc-yxdCFUKyNLPexxJ66jaXWk \
--set-default-emotion calm \
--set-default-scene assistant
Register a prepared clone voice so the runtime can list and reuse it:
python3 scripts/openclaw_voice_switchboard.py \
--register-clone-voice-id vc-yxdCFUKyNLPexxJ66jaXWk \
--register-clone-name "我的克隆音色"
Show registered clone voices:
python3 scripts/openclaw_voice_switchboard.py --show-clone-voices
Show current voice preference:
python3 scripts/openclaw_voice_switchboard.py \
--preference-key "feishu:ou_xxx" \
--show-preference
Generate one AudioClaw turn from a JSON request:
python3 scripts/openclaw_voice_switchboard.py \
--request-file /path/to/request.json \
--out /tmp/openclaw_reply.mp3
Direct CLI example:
python3 scripts/openclaw_voice_switchboard.py \
--text "我们已经处理好了,稍后把结果发给你。" \
--scene assistant \
--emotion warm \
--preference-key "feishu:ou_xxx" \
--delivery-profile feishu_voice \
--openclaw-workspace-root ~/.audioclaw/workspace \
--out ~/.audioclaw/workspace/audioclaw_warm.ogg
AudioClaw Feishu one-step example:
python3 scripts/picoclaw_voice_reply.py \
--text "这是一次可以直接发给飞书的语音回复。" \
--scene assistant \
--emotion calm \
--workspace-root ~/.audioclaw/workspace
Only generate, do not send:
python3 scripts/picoclaw_voice_reply.py \
--text "这是一次只生成不直发的测试语音。" \
--scene assistant \
--emotion calm \
--workspace-root ~/.audioclaw/workspace \
--skip-direct-send
Resources
scripts/senseaudio_tts_client.pyhttps://api.senseaudio.cn/v1/t2a_v2
- Handles SSE chunks and writes audio bytes
references/openclaw_voice_switchboard.mdhttps://senseaudio.cn/docs/voice_api
scripts/openclaw_voice_switchboard.pyscripts/picoclaw_voice_reply.pyaudio message
scripts/feishu_audio_sender.py.ogg/.opus
- Uses ~/.audioclaw/config.json app credentials by default, infers the active chat, uploads the file, and sends msg_type=audio
references/openclaw_voice_switchboard.md