fix(minimax): normalize tts pitch for api · openclaw/openclaw@978a50a
steipete
·
2026-04-25
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -91,6 +91,7 @@ Docs: https://docs.openclaw.ai
|
91 | 91 | - Plugins/OpenCode: strip unsupported disabled Responses reasoning payloads for OpenCode image understanding. Fixes #70252. |
92 | 92 | - Plugins/OpenCode/OpenCode Go: register image understanding metadata so the image tool is available for OpenCode catalog models with vision support. Fixes #70482 and #61789. |
93 | 93 | - Providers/ElevenLabs: omit the MP3-only `Accept` header for PCM telephony synthesis, so Voice Call requests for `pcm_22050` no longer receive MP3 audio. Fixes #67340. Thanks @marcchabot. |
| 94 | +- Providers/MiniMax TTS: truncate fractional pitch overrides before sending T2A requests, matching MiniMax's integer pitch contract while preserving fractional speed and volume. Fixes #62144. |
94 | 95 | - Providers/MiniMax TTS: transcode voice-note targets to Opus so Feishu/Telegram receive native voice messages instead of MP3 file attachments. Fixes #63540, #64134, and #70445. |
95 | 96 | - Providers/Microsoft TTS: keep allowlisted bundled speech providers discoverable even when another speech plugin has already registered, so Edge/Microsoft TTS is available alongside OpenAI. Fixes #62117 and #66850. |
96 | 97 | - Providers/Microsoft TTS: honor legacy `messages.tts.providers.edge` voice settings after normalizing Edge TTS to the Microsoft provider. Fixes #64153. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -255,12 +255,17 @@ The bundled `minimax` plugin registers MiniMax T2A v2 as a speech provider for
|
255 | 255 | - Voice-note targets such as Feishu and Telegram are transcoded from MiniMax |
256 | 256 | MP3 to 48kHz Opus with `ffmpeg`, because the Feishu/Lark file API only |
257 | 257 | accepts `file_type: "opus"` for native audio messages. |
| 258 | +- MiniMax T2A accepts fractional `speed` and `vol`, but `pitch` is sent as an |
| 259 | + integer; OpenClaw truncates fractional `pitch` values before the API request. |
258 | 260 | |
259 | 261 | | Setting | Env var | Default | Description | |
260 | 262 | | ---------------------------------------- | ---------------------- | ----------------------------- | -------------------------------- | |
261 | 263 | | `messages.tts.providers.minimax.baseUrl` | `MINIMAX_API_HOST` | `https://api.minimax.io` | MiniMax T2A API host. | |
262 | 264 | | `messages.tts.providers.minimax.model` | `MINIMAX_TTS_MODEL` | `speech-2.8-hd` | TTS model id. | |
263 | 265 | | `messages.tts.providers.minimax.voiceId` | `MINIMAX_TTS_VOICE_ID` | `English_expressive_narrator` | Voice id used for speech output. | |
| 266 | +| `messages.tts.providers.minimax.speed` | | `1.0` | Playback speed, `0.5..2.0`. | |
| 267 | +| `messages.tts.providers.minimax.vol` | | `1.0` | Volume, `(0, 10]`. | |
| 268 | +| `messages.tts.providers.minimax.pitch` | | `0` | Integer pitch shift, `-12..12`. | |
264 | 269 | |
265 | 270 | ### Music generation |
266 | 271 | |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -374,7 +374,7 @@ Then run:
|
374 | 374 | - `providers.minimax.voiceId`: voice identifier (default `English_expressive_narrator`, env: `MINIMAX_TTS_VOICE_ID`). |
375 | 375 | - `providers.minimax.speed`: playback speed `0.5..2.0` (default 1.0). |
376 | 376 | - `providers.minimax.vol`: volume `(0, 10]` (default 1.0; must be greater than 0). |
377 | | -- `providers.minimax.pitch`: pitch shift `-12..12` (default 0). |
| 377 | +- `providers.minimax.pitch`: integer pitch shift `-12..12` (default 0). Fractional values are truncated before calling MiniMax T2A because the API rejects non-integer pitch values. |
378 | 378 | - `providers.google.model`: Gemini TTS model (default `gemini-3.1-flash-tts-preview`). |
379 | 379 | - `providers.google.voiceName`: Gemini prebuilt voice name (default `Kore`; `voice` is also accepted). |
380 | 380 | - `providers.google.baseUrl`: override the Gemini API base URL. Only `https://generativelanguage.googleapis.com` is accepted. |
@@ -432,7 +432,7 @@ Available directive keys (when enabled):
|
432 | 432 | - `model` (OpenAI TTS model, ElevenLabs model id, or MiniMax model) or `google_model` (Google TTS model) |
433 | 433 | - `stability`, `similarityBoost`, `style`, `speed`, `useSpeakerBoost` |
434 | 434 | - `vol` / `volume` (MiniMax volume, 0-10) |
435 | | -- `pitch` (MiniMax pitch, -12 to 12) |
| 435 | +- `pitch` (MiniMax integer pitch, -12 to 12; fractional values are truncated before the MiniMax request) |
436 | 436 | - `applyTextNormalization` (`auto|on|off`) |
437 | 437 | - `languageCode` (ISO 639-1) |
438 | 438 | - `seed` |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -309,7 +309,13 @@ describe("buildMinimaxSpeechProvider", () => {
|
309 | 309 | text: "Test", |
310 | 310 | cfg: {} as never, |
311 | 311 | providerConfig: { apiKey: "sk-test" }, |
312 | | -providerOverrides: { model: "speech-01-240228", voiceId: "custom_voice", speed: 1.5 }, |
| 312 | +providerOverrides: { |
| 313 | +model: "speech-01-240228", |
| 314 | +voiceId: "custom_voice", |
| 315 | +speed: 1.5, |
| 316 | +vol: 1.5, |
| 317 | +pitch: 0.5, |
| 318 | +}, |
313 | 319 | target: "audio-file", |
314 | 320 | timeoutMs: 30000, |
315 | 321 | }); |
@@ -318,6 +324,8 @@ describe("buildMinimaxSpeechProvider", () => {
|
318 | 324 | expect(body.model).toBe("speech-01-240228"); |
319 | 325 | expect(body.voice_setting.voice_id).toBe("custom_voice"); |
320 | 326 | expect(body.voice_setting.speed).toBe(1.5); |
| 327 | +expect(body.voice_setting.vol).toBe(1.5); |
| 328 | +expect(body.voice_setting.pitch).toBe(0); |
321 | 329 | }); |
322 | 330 | |
323 | 331 | it("throws when API key is missing", async () => { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -24,6 +24,10 @@ export function normalizeMinimaxTtsBaseUrl(baseUrl?: string): string {
|
24 | 24 | return trimmed.replace(/\/+$/, ""); |
25 | 25 | } |
26 | 26 | |
| 27 | +function normalizeMinimaxTtsPitch(pitch: number): number { |
| 28 | +return Math.trunc(pitch); |
| 29 | +} |
| 30 | + |
27 | 31 | export async function minimaxTTS(params: { |
28 | 32 | text: string; |
29 | 33 | apiKey: string; |
@@ -70,7 +74,7 @@ export async function minimaxTTS(params: {
|
70 | 74 | voice_id: voiceId, |
71 | 75 | speed, |
72 | 76 | vol, |
73 | | - pitch, |
| 77 | +pitch: normalizeMinimaxTtsPitch(pitch), |
74 | 78 | }, |
75 | 79 | audio_setting: { |
76 | 80 | format, |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。