fix(minimax): stop advertising music duration control (#84765)

Summary:
- The PR removes MiniMax music duration support from provider capabilities and docs, stops prompt-injecting duration hints, updates the MiniMax provider test, and adds a changelog entry.
- Reproducibility: yes. by source inspection: current main advertises MiniMax duration support while the reque ... uage hint. I did not rerun a live pre-fix MiniMax request, but the code path and vendor contract are clear.

Automerge notes:
- PR branch already contained follow-up commit before automerge: docs(minimax): align music controls
- PR branch already contained follow-up commit before automerge: docs(music): remove minimax duration steering claim
- PR branch already contained follow-up commit before automerge: fix(minimax): stop advertising music duration control

Validation:
- ClawSweeper review passed for head 1c616da45c.
- Required merge gates passed before the squash merge.

Prepared head SHA: 1c616da45c
Review: https://github.com/openclaw/openclaw/pull/84765#issuecomment-4504176794

Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
This commit is contained in:
clawsweeper[bot]
2026-05-21 02:26:17 +00:00
committed by GitHub
parent c4f14a39a5
commit 86ebceeb2e
5 changed files with 16 additions and 24 deletions
+1
View File
@@ -18,6 +18,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Codex app-server: keep system-prompt reports working when bootstrap hooks provide workspace files with only a path and content, so hook-supplied SOUL/IDENTITY/TOOLS/USER context still reports injected characters correctly. (#84736) Thanks @JARVIS-Glasses.
- Providers/MiniMax music: stop advertising `durationSeconds` control and remove prompt-injected duration hints, so `music_generate` reports MiniMax duration as an unsupported override instead of suggesting MiniMax can enforce track length. Fixes #84508. Thanks @neeravmakwana.
- WhatsApp: update Baileys to `7.0.0-rc12`.
- Build: suppress per-locale `rolldown-plugin-dts:fake-js` CommonJS dts warnings emitted while bundling the intentionally-inlined `zod/v4/locales/*.d.cts` files, so `pnpm build` output stays readable after the 0.25.1 plugin bump. Thanks @romneyda.
- CLI/nodes: route lazy plugin-registration logs to stderr for JSON-mode `openclaw nodes` commands so stdout stays parseable. (#84684) Thanks @TurboTheTurtle.
+1 -1
View File
@@ -292,7 +292,7 @@ The bundled MiniMax plugin registers music generation through the shared
- Default music model: `minimax/music-2.6`
- OAuth music model: `minimax-portal/music-2.6`
- Also supports `minimax/music-2.5` and `minimax/music-2.0`
- Prompt controls: `lyrics`, `instrumental`, `durationSeconds`
- Prompt controls: `lyrics`, `instrumental`
- Output format: `mp3`
- Session-backed runs detach through the shared task/status flow, including `action: "status"`
+9 -9
View File
@@ -94,13 +94,13 @@ Generate an energetic chiptune loop about launching a rocket at sunrise.
## Supported providers
| Provider | Default model | Reference inputs | Supported controls | Auth |
| ---------- | ---------------------------- | ---------------- | --------------------------------------------------------- | -------------------------------------- |
| ComfyUI | `workflow` | Up to 1 image | Workflow-defined music or audio | `COMFY_API_KEY`, `COMFY_CLOUD_API_KEY` |
| fal | `fal-ai/minimax-music/v2.6` | None | `lyrics`, `instrumental`, `durationSeconds`, `format` | `FAL_KEY` or `FAL_API_KEY` |
| Google | `lyria-3-clip-preview` | Up to 10 images | `lyrics`, `instrumental`, `format` | `GEMINI_API_KEY`, `GOOGLE_API_KEY` |
| MiniMax | `music-2.6` | None | `lyrics`, `instrumental`, `durationSeconds`, `format=mp3` | `MINIMAX_API_KEY` or MiniMax OAuth |
| OpenRouter | `google/lyria-3-pro-preview` | Up to 1 image | `lyrics`, `instrumental`, `durationSeconds`, `format` | `OPENROUTER_API_KEY` |
| Provider | Default model | Reference inputs | Supported controls | Auth |
| ---------- | ---------------------------- | ---------------- | ----------------------------------------------------- | -------------------------------------- |
| ComfyUI | `workflow` | Up to 1 image | Workflow-defined music or audio | `COMFY_API_KEY`, `COMFY_CLOUD_API_KEY` |
| fal | `fal-ai/minimax-music/v2.6` | None | `lyrics`, `instrumental`, `durationSeconds`, `format` | `FAL_KEY` or `FAL_API_KEY` |
| Google | `lyria-3-clip-preview` | Up to 10 images | `lyrics`, `instrumental`, `format` | `GEMINI_API_KEY`, `GOOGLE_API_KEY` |
| MiniMax | `music-2.6` | None | `lyrics`, `instrumental`, `format=mp3` | `MINIMAX_API_KEY` or MiniMax OAuth |
| OpenRouter | `google/lyria-3-pro-preview` | Up to 1 image | `lyrics`, `instrumental`, `durationSeconds`, `format` | `OPENROUTER_API_KEY` |
### Capability matrix
@@ -274,8 +274,8 @@ explicit `model`, `primary`, and `fallbacks` entries.
</Accordion>
<Accordion title="MiniMax">
Uses the batch `music_generation` endpoint. Supports prompt, optional
lyrics, instrumental mode, duration steering, and mp3 output through
either `minimax` API-key auth or `minimax-portal` OAuth.
lyrics, instrumental mode, and mp3 output through either `minimax`
API-key auth or `minimax-portal` OAuth.
</Accordion>
<Accordion title="OpenRouter">
Uses OpenRouter chat completions audio output with streaming enabled. The
@@ -75,6 +75,9 @@ describe("minimax music generation provider", () => {
expect(request.url).toBe("https://api.minimax.io/v1/music_generation");
const body = request.body as Record<string, unknown>;
expect(body.model).toBe("music-2.6");
expect(body.prompt).toBe("upbeat dance-pop with female vocals");
expect(body.prompt).not.toContain("Target duration");
expect(body).not.toHaveProperty("duration");
expect(body.lyrics).toBe("our city wakes");
expect(body.output_format).toBe("url");
expect(body.audio_setting).toEqual({
@@ -89,6 +92,7 @@ describe("minimax music generation provider", () => {
expect(result.lyrics).toEqual(["our city wakes"]);
expect(result.metadata?.taskId).toBe("task-123");
expect(result.metadata?.audioUrl).toBe("https://example.com/out.mp3");
expect(result.metadata).not.toHaveProperty("requestedDurationSeconds");
});
it("downloads tracks when url output is returned in data.audio", async () => {
@@ -2,7 +2,6 @@ import { extensionForMime } from "openclaw/plugin-sdk/media-mime";
import type {
GeneratedMusicAsset,
MusicGenerationProvider,
MusicGenerationRequest,
} from "openclaw/plugin-sdk/music-generation";
import { isProviderApiKeyConfigured } from "openclaw/plugin-sdk/provider-auth";
import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime";
@@ -106,14 +105,6 @@ async function downloadTrackFromUrl(params: {
};
}
function buildPrompt(req: MusicGenerationRequest): string {
const parts = [req.prompt.trim()];
if (typeof req.durationSeconds === "number" && Number.isFinite(req.durationSeconds)) {
parts.push(`Target duration: about ${Math.max(1, Math.round(req.durationSeconds))} seconds.`);
}
return parts.join("\n\n");
}
function resolveMinimaxMusicModel(model: string | undefined): string {
const trimmed = normalizeOptionalString(model);
if (!trimmed) {
@@ -138,7 +129,6 @@ function buildMinimaxMusicProvider(providerId: string): MusicGenerationProvider
maxTracks: 1,
supportsLyrics: true,
supportsInstrumental: true,
supportsDuration: true,
supportsFormat: true,
supportedFormats: ["mp3"],
},
@@ -187,7 +177,7 @@ function buildMinimaxMusicProvider(providerId: string): MusicGenerationProvider
const lyrics = normalizeOptionalString(req.lyrics);
const body = {
model,
prompt: buildPrompt(req),
prompt: req.prompt.trim(),
...(req.instrumental === true ? { is_instrumental: true } : {}),
...(lyrics ? { lyrics } : req.instrumental === true ? {} : { lyrics_optimizer: true }),
output_format: "url",
@@ -251,9 +241,6 @@ function buildMinimaxMusicProvider(providerId: string): MusicGenerationProvider
...(audioUrl ? { audioUrl } : {}),
instrumental: req.instrumental === true,
...(lyrics ? { requestedLyrics: true } : {}),
...(typeof req.durationSeconds === "number"
? { requestedDurationSeconds: req.durationSeconds }
: {}),
},
};
} finally {