fix(minimax/speech): place output_format at body root, not under audi… - #2
Merged
Merged
Conversation
…o_setting Upstream ExternalSpeechGenerationRequest schema (mule-router tasks/handlers/minimax/models/external.py:254) declares output_format at the top of the request body. The CLI's buildSpeechRequestBody was nesting it inside audio_setting, where upstream's AudioSetting model silently drops it during pydantic validation. As a result, every `--output-format url` invocation was effectively ignored and the upstream default (HEX) returned. Verified end-to-end against the mule-run review-app: - speech-2.8-turbo, no flag → audios[0] starts 49443304 (ID3 hex) ✅ - speech-2.8-turbo, output-format url → audios[0] starts https://... ✅ - speech-2.8-hd, output-format url → audios[0] starts https://... ✅ Move the field to the body root and add a regression test asserting audio_setting does not contain output_format. Update the existing cli/tests/run.test.ts case which had memorized the buggy placement. Strengthen the parameter description to explain url vs hex schemas and call out the upstream HEX default. Bump cli + core to 0.4.1. Reported by: github-mulerouter-skill harness session d20acc8b. Co-Authored-By: Claude <noreply@anthropic.com>
…nion schema The endpoint declaration has been wrong since the initial commit (82822db) and never touched. End-to-end validation by the github-mulerouter-skill harness (session d20acc8b) caught two independent breakages on the same upstream layer: 1. --function reference_generation -> 400 error_code 2001: "function expected 'image_reference','video_repainting','video_edit', 'video_extension','video_outpainting', got 'reference_generation'" 2. --ref-images-url ... -> 400: "Invalid parameters: 'images' expected to be provided, got None" Both are pydantic failures against VideoEditPayload (mule-router payloads/video.py:607). The public mule-router API for /vendors/alibaba/v1/wan2.1-vace-plus/generation validates the body against this discriminated union; only afterwards does the bailian-channel request_builder internally rename images -> ref_images_url (request_builder.py:408). CLI must conform to VideoEditPayload, not the downstream bailian schema. Why the existing test didn't catch this: tests/models.test.ts:147 only asserted the (wrong) declared enum contained the strings "outpainting" and "inpainting" -- which are literally present in the wrong 5-value enum by naming coincidence. The test was registry self-consistency only; it never validated against upstream and could not detect CLI/upstream drift. This is the class of bug that SOP Layer 4 (manual E2E) exists to catch. The new tests in this commit are still self-consistency only, so they can prevent regression from the correct state but cannot guarantee long-term alignment if upstream changes again -- Layer 4 E2E remains the authoritative gate. Changes: - function: replace enum with VideoEditPayload discriminator values (image_reference, video_repainting, video_edit, video_extension, video_outpainting). Was: outpainting, video_extend, reference_generation, interpolation, inpainting. - ref_images_url -> images: rename to match upstream. (Type was already array; only the name changed.) - obj_or_bg: string -> array of "obj"|"bg" (parallel to images, 'bg' at most once, required when images length > 1). - mask_frame_id: string -> integer (upstream Field(ge=1)). - negative_prompt: remove. Not in VideoEditBasePayload or any function subtype. - Add upstream enum constraints to size, mask_type, expand_mode. Note: expand_mode keeps the upstream typo "orginal" verbatim. - Per-field descriptions now call out which function each sub-param applies to, so `mulerouter params` is self-documenting. - Rewrite tests/models.test.ts vace block to assert against the new correct schema. E2E verified against review-app endpoint (api-r-main-6wkxvg.mule.run): - image_reference with --images: mule-router accepts body (task_id created); downstream bailian then returns code 3005 for unrelated reason (CLI body shape is no longer the blocker). - video_outpainting with --video-url + scales --no-wait: task created status=pending (body schema accepted). Pre-fix, both would have failed at mule-router pydantic with 400. Bump cli + core to 0.4.2. Co-Authored-By: Claude <noreply@anthropic.com>
…even for single image
Full end-to-end validation against api-r-main-6wkxvg.mule.run review-app
revealed: with --images of length 1 and --obj-or-bg omitted, the request
passes mule-router's pydantic (VideoEditValidators.validate_obj_or_bg
allows None when len(images)==1) but Alibaba Bailian rejects upstream
with code InvalidParameter:
"ref_images_url and obj_or_bg must be the same length"
(captured in mule-router primary pod task_executor.py:221 log, task
b2700315-cc50-4d03-ab1d-b970d101955b's external task a2f8a088-...)
After adding --obj-or-bg '["obj"]' to the same request, the task
completed successfully and returned a video URL (~3.5 min wall, $0.10
USD/s × 5s = 50 credits). CLI body shape is correct end-to-end; the
gap is a documentation issue only.
This is also a latent mule-router bug (its validator is more lenient
than Bailian's actual requirement), but rather than wait on upstream,
surface the requirement in the CLI param description so
`mulerouter params` is self-documenting.
Co-Authored-By: Claude <noreply@anthropic.com>
… + tests CI on PR openmule#2 failed at `bun run lint` (biome check) with: - packages/core/tests/models.test.ts:145 — `endpoint!.parameters` triggers lint/style/noNonNullAssertion - packages/core/tests/models.test.ts:291 — `Object.keys(audioSetting!)` same - packages/core/src/models/alibaba/wan2.1-vace-plus.ts:131 — long description line exceeds biome's formatter wrap threshold Fixes: - Replace `!` with explicit `if (!endpoint) return;` early-return after `expect(endpoint).toBeDefined()` so the type narrows naturally. - Replace `Object.keys(audioSetting!)` with `Object.keys(audioSetting ?? {})`; the assertion above ensures it's defined at runtime, this just keeps the type checker happy without a non-null assertion. - Apply biome's auto-format suggestion to wan2.1-vace-plus.ts (descriptions split onto their own lines). 172/172 tests still green. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…o_setting
Upstream ExternalSpeechGenerationRequest schema (mule-router tasks/handlers/minimax/models/external.py:254) declares output_format at the top of the request body. The CLI's buildSpeechRequestBody was nesting it inside audio_setting, where upstream's AudioSetting model silently drops it during pydantic validation. As a result, every
--output-format urlinvocation was effectively ignored and the upstream default (HEX) returned.Verified end-to-end against the mule-run review-app:
Move the field to the body root and add a regression test asserting audio_setting does not contain output_format. Update the existing cli/tests/run.test.ts case which had memorized the buggy placement. Strengthen the parameter description to explain url vs hex schemas and call out the upstream HEX default. Bump cli + core to 0.4.1.
Reported by: github-mulerouter-skill harness session d20acc8b.