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
@@ -228,6 +228,75 @@ func TestProviderTaskClientsSubmitAndPoll(t *testing.T) {
}
}
func TestMinimaxClientNormalizesHailuo23PayloadAndRetrievesFile(t *testing.T) {
var submitted map[string]any
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer test-key" {
t.Fatalf("unexpected auth header: %q", r.Header.Get("Authorization"))
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("x-request-id", "req-minimax")
switch {
case r.Method == http.MethodPost && r.URL.Path == "/video_generation":
if err := json.NewDecoder(r.Body).Decode(&submitted); err != nil {
t.Fatalf("decode minimax submit request: %v", err)
}
_, _ = w.Write([]byte(`{"task_id":"mm-task","base_resp":{"status_code":0,"status_msg":"success"}}`))
case r.Method == http.MethodGet && r.URL.Path == "/query/video_generation" && r.URL.Query().Get("task_id") == "mm-task":
_, _ = w.Write([]byte(`{"task_id":"mm-task","status":"Success","file_id":"file-1","base_resp":{"status_code":0,"status_msg":"success"}}`))
case r.Method == http.MethodGet && r.URL.Path == "/files/retrieve" && r.URL.Query().Get("file_id") == "file-1":
_, _ = w.Write([]byte(`{"file":{"download_url":"https://cdn.example/minimax-file.mp4"},"base_resp":{"status_code":0,"status_msg":"success"}}`))
default:
t.Fatalf("unexpected request: %s %s", r.Method, r.URL.String())
}
}))
defer server.Close()
response, err := (MinimaxClient{HTTPClient: server.Client()}).Run(context.Background(), Request{
Kind: "videos.generations",
ModelType: "image_to_video",
Model: "海螺2.3",
Body: map[string]any{
"resolution": "720p",
"duration": 6,
"content": []any{
map[string]any{"type": "text", "text": "camera moves in"},
map[string]any{"type": "image_url", "role": "first_frame", "image_url": map[string]any{"url": "https://example.com/first.png"}},
},
},
Candidate: store.RuntimeModelCandidate{
Provider: "minimax",
SpecType: "minimax",
BaseURL: server.URL,
Credentials: map[string]any{"apiKey": "test-key"},
PlatformConfig: map[string]any{"pollIntervalMs": 1, "pollTimeoutMs": 1000},
ModelName: "海螺2.3",
ProviderModelName: "MiniMax-Hailuo-2.3",
ModelType: "image_to_video",
},
})
if err != nil {
t.Fatalf("run minimax client: %v", err)
}
if submitted["model"] != "MiniMax-Hailuo-2.3" || submitted["prompt"] != "camera moves in" || submitted["first_frame_image"] != "https://example.com/first.png" {
t.Fatalf("unexpected minimax submit payload: %+v", submitted)
}
if submitted["resolution"] != "768P" {
t.Fatalf("hailuo 2.3 720p should be submitted as 768P, got %+v", submitted)
}
if _, ok := submitted["content"]; ok {
t.Fatalf("minimax native request should not include generic content: %+v", submitted)
}
data, _ := response.Result["data"].([]any)
if len(data) != 1 {
t.Fatalf("unexpected minimax response data: %+v", response.Result)
}
first, _ := data[0].(map[string]any)
if first["url"] != "https://cdn.example/minimax-file.mp4" {
t.Fatalf("unexpected minimax video url: %+v", response.Result)
}
}
func TestSunoClientSubmitsAndPollsAudioGeneration(t *testing.T) {
var submitted map[string]any
var submittedRemoteTaskID string
@@ -303,6 +372,39 @@ func TestSunoClientSubmitsAndPollsAudioGeneration(t *testing.T) {
}
func TestProviderTaskClientFailureAndRetryableErrors(t *testing.T) {
t.Run("submit business failure", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("x-request-id", "req-minimax-invalid")
if r.Method != http.MethodPost || r.URL.Path != "/video_generation" {
t.Fatalf("unexpected request: %s %s", r.Method, r.URL.String())
}
_, _ = w.Write([]byte(`{"base_resp":{"status_code":1008,"status_msg":"invalid resolution"}}`))
}))
defer server.Close()
_, err := (MinimaxClient{HTTPClient: server.Client()}).Run(context.Background(), Request{
Kind: "videos.generations",
ModelType: "video_generate",
Model: "海螺2.3",
Body: map[string]any{"model": "海螺2.3", "prompt": "hello"},
Candidate: store.RuntimeModelCandidate{
Provider: "minimax",
SpecType: "minimax",
BaseURL: server.URL,
Credentials: map[string]any{"apiKey": "test-key"},
PlatformConfig: map[string]any{"pollIntervalMs": 1, "pollTimeoutMs": 1000},
ModelName: "海螺2.3",
ProviderModelName: "MiniMax-Hailuo-2.3",
ModelType: "video_generate",
},
})
var clientErr *ClientError
if !errors.As(err, &clientErr) || clientErr.Code != "1008" || clientErr.Message != "invalid resolution" || clientErr.RequestID != "req-minimax-invalid" {
t.Fatalf("expected minimax business failure, got %#v", err)
}
})
t.Run("poll failure", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")