Restore standard MiniMax resolutions and client mapping
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user