Restore standard MiniMax resolutions and client mapping

This commit is contained in:
2026-06-08 09:29:45 +08:00
parent ca5e71c8e8
commit 97f29ed156
8 changed files with 587 additions and 4 deletions
+139
View File
@@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/hex"
"net/http"
"net/url"
"strings"
"time"
)
@@ -157,9 +158,147 @@ func minimaxSpec() providerTaskSpec {
StatusPaths: []string{"status"},
SuccessStatuses: []string{"success"},
FailureStatuses: []string{"failed", "expired"},
DefaultSubmitBody: func(request Request, body map[string]any) map[string]any {
return minimaxVideoPayload(request, body)
},
ResolveSuccess: minimaxResolveVideoFile,
}
}
func minimaxVideoPayload(request Request, body map[string]any) map[string]any {
model := upstreamModelName(request.Candidate)
body["model"] = model
if strings.TrimSpace(stringFromAny(body["prompt"])) == "" {
body["prompt"] = mediaPromptText(body)
}
firstFrame, lastFrame := minimaxFrameImages(body)
if firstFrame != "" && strings.TrimSpace(stringFromAny(body["first_frame_image"])) == "" {
body["first_frame_image"] = firstFrame
}
if lastFrame != "" && strings.TrimSpace(stringFromAny(body["last_frame_image"])) == "" {
body["last_frame_image"] = lastFrame
}
if resolution := minimaxVideoResolution(model, stringFromAny(body["resolution"])); resolution != "" {
body["resolution"] = resolution
}
for _, key := range []string{
"content", "input", "_paramWarnings",
"first_frame", "firstFrame", "last_frame", "lastFrame",
"image", "images", "image_url", "imageUrl", "image_urls", "imageUrls",
"reference_image", "referenceImage", "duration_seconds", "durationSeconds",
} {
delete(body, key)
}
return body
}
func minimaxFrameImages(body map[string]any) (string, string) {
firstFrame := firstNonEmptyStringValue(body, "first_frame_image", "firstFrameImage", "first_frame", "firstFrame")
lastFrame := firstNonEmptyStringValue(body, "last_frame_image", "lastFrameImage", "last_frame", "lastFrame")
imageURLs := firstNonEmptyStringListFromAny(body["image"], body["images"], body["image_url"], body["imageUrl"], body["image_urls"], body["imageUrls"])
if firstFrame == "" && len(imageURLs) > 0 {
firstFrame = imageURLs[0]
}
for _, item := range contentItems(body["content"]) {
if strings.TrimSpace(stringFromAny(item["type"])) != "image_url" {
continue
}
url := minimaxNestedURL(item, "image_url")
if url == "" {
continue
}
switch strings.TrimSpace(stringFromAny(item["role"])) {
case "first_frame":
if firstFrame == "" {
firstFrame = url
}
case "last_frame":
if lastFrame == "" {
lastFrame = url
}
default:
if firstFrame == "" {
firstFrame = url
}
}
}
return firstFrame, lastFrame
}
func minimaxNestedURL(item map[string]any, key string) string {
if url := strings.TrimSpace(stringFromAny(item[key])); url != "" {
return url
}
nested := mapFromAny(item[key])
return strings.TrimSpace(stringFromAny(nested["url"]))
}
func minimaxVideoResolution(model string, resolution string) string {
resolution = strings.TrimSpace(resolution)
if resolution == "" {
return ""
}
normalized := strings.ToLower(strings.ReplaceAll(resolution, " ", ""))
isHailuo23 := strings.Contains(strings.ToLower(model), "hailuo-2.3")
if isHailuo23 {
switch normalized {
case "720", "720p", "768", "768p":
return "768P"
case "1080", "1080p":
return "1080P"
}
}
switch normalized {
case "512", "512p":
return "512P"
case "720", "720p":
return "720P"
case "768", "768p":
return "768P"
case "1080", "1080p":
return "1080P"
default:
if strings.HasSuffix(normalized, "p") {
return strings.TrimSuffix(normalized, "p") + "P"
}
return resolution
}
}
func minimaxResolveVideoFile(ctx context.Context, client *http.Client, request Request, result map[string]any) (map[string]any, string, error) {
if len(providerTaskData(request, result)) > 0 {
return result, "", nil
}
fileID := strings.TrimSpace(stringFromPathValue(valueAtPath(result, "file_id")))
if fileID == "" {
return result, "", nil
}
fetched, requestID, err := providerGetJSON(ctx, client, providerURL(request.Candidate.BaseURL, "/files/retrieve?file_id="+url.QueryEscape(fileID)), request.Candidate.Credentials, "bearer")
if err != nil {
return nil, requestID, err
}
if isProviderTaskFailure(minimaxSpec(), fetched) {
return nil, requestID, providerTaskFailure(minimaxSpec(), fetched, firstNonEmptyString(requestID, requestIDFromResult(fetched)), time.Now())
}
downloadURL := firstNonEmptyString(
valueAtPath(fetched, "file.download_url"),
valueAtPath(fetched, "file.downloadUrl"),
valueAtPath(fetched, "download_url"),
valueAtPath(fetched, "downloadUrl"),
valueAtPath(fetched, "url"),
)
if downloadURL == "" {
return nil, requestID, &ClientError{Code: "invalid_response", Message: "minimax video download url is missing", RequestID: requestID, Retryable: false}
}
out := cloneMapAny(result)
out["video_url"] = downloadURL
if file, ok := fetched["file"].(map[string]any); ok {
out["file"] = cloneMapAny(file)
}
out["file_retrieve"] = cloneMapAny(fetched)
return out, firstNonEmptyString(requestID, requestIDFromResult(fetched)), nil
}
func (c MinimaxClient) runSpeech(ctx context.Context, request Request) (Response, error) {
startedAt := time.Now()
payload := minimaxSpeechPayload(request)