功能增加
This commit is contained in:
1 parent
b340fc7ad7
commit
f1993eb388
69 files changed
+2243
-162
No files matched your search
@@ -85,10 +85,14 @@ func imageEngine(getenv postgres.Getenv) string {
|
||||
}
|
||||
|
||||
func videoEngine(getenv postgres.Getenv) string {
|
||||
if strings.EqualFold(strings.TrimSpace(getenv("VIDEO_GENERATE_ENGINE")), "seedance") {
|
||||
switch strings.ToLower(strings.TrimSpace(getenv("VIDEO_GENERATE_ENGINE"))) {
|
||||
case "seedance":
|
||||
return "seedance"
|
||||
case "minimax":
|
||||
return "minimax"
|
||||
default:
|
||||
return "bailian"
|
||||
}
|
||||
return "bailian"
|
||||
}
|
||||
|
||||
func imageProvider(getenv postgres.Getenv) string {
|
||||
@@ -105,10 +109,7 @@ func imageProvider(getenv postgres.Getenv) string {
|
||||
}
|
||||
|
||||
func videoProvider(getenv postgres.Getenv) string {
|
||||
if videoEngine(getenv) == "seedance" {
|
||||
return "seedance"
|
||||
}
|
||||
return "bailian"
|
||||
return videoEngine(getenv)
|
||||
}
|
||||
|
||||
func imageModel(getenv postgres.Getenv) string {
|
||||
@@ -125,10 +126,14 @@ func imageModel(getenv postgres.Getenv) string {
|
||||
}
|
||||
|
||||
func videoModel(getenv postgres.Getenv) string {
|
||||
if videoEngine(getenv) == "seedance" {
|
||||
switch videoEngine(getenv) {
|
||||
case "seedance":
|
||||
return firstNonEmpty(getenv("SEEDANCE_MODEL"), "doubao-seedance-2-0-260128")
|
||||
case "minimax":
|
||||
return providers.MinimaxH3Model
|
||||
default:
|
||||
return firstNonEmpty(getenv("BAILIAN_VIDEO_MODEL"), "wan2.7-i2v-2026-04-25")
|
||||
}
|
||||
return firstNonEmpty(getenv("BAILIAN_VIDEO_MODEL"), "wan2.7-i2v-2026-04-25")
|
||||
}
|
||||
|
||||
func bailianAPIKey(getenv postgres.Getenv) string {
|
||||
@@ -162,6 +167,7 @@ func buildProviderRegistryWithClient(getenv postgres.Getenv, client *http.Client
|
||||
"bailian": providers.NewBailian(providers.Config{BaseURL: bailianNativeBaseURL(getenv), APIKey: bailianAPIKey(getenv), Model: firstNonEmpty(getenv("BAILIAN_IMAGE_MODEL"), "wan2.7-image-pro"), MaxResponseBytes: maximum}, client),
|
||||
"seedance": providers.NewSeedance(providers.Config{BaseURL: firstNonEmpty(getenv("SEEDANCE_BASE_URL"), "https://ark.cn-beijing.volces.com/api/v3"), APIKey: getenv("SEEDANCE_API_KEY"), Model: firstNonEmpty(getenv("SEEDANCE_MODEL"), "doubao-seedance-2-0-260128"), MaxResponseBytes: maximum}, client),
|
||||
"seedream": providers.NewSeedream(providers.Config{BaseURL: firstNonEmpty(getenv("SEEDANCE_BASE_URL"), "https://ark.cn-beijing.volces.com/api/v3"), APIKey: getenv("SEEDANCE_API_KEY"), Model: providers.Seedream50ProModel, MaxResponseBytes: maximum}, client),
|
||||
"minimax": providers.NewMinimax(providers.Config{BaseURL: firstNonEmpty(getenv("MINIMAX_BASE_URL"), "https://api.minimax.cn"), APIKey: getenv("MINIMAX_API_KEY"), Model: providers.MinimaxH3Model, MaxResponseBytes: maximum}, client),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,6 +206,11 @@ func providerVideoTargets(getenv postgres.Getenv) map[string]jobs.ProviderTarget
|
||||
Provider: "bailian",
|
||||
Model: firstNonEmpty(getenv("BAILIAN_VIDEO_MODEL"), "wan2.7-i2v-2026-04-25"),
|
||||
},
|
||||
"minimax": {
|
||||
Provider: "minimax",
|
||||
Model: providers.MinimaxH3Model,
|
||||
Settings: map[string]any{"ratio": "16:9", "duration": float64(5), "resolution": "768P"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +260,9 @@ func providerUnavailableMessages(getenv postgres.Getenv) map[string]string {
|
||||
missing["seedance"] = "Seedance 服务商未配置,请先配置 SEEDANCE_API_KEY。"
|
||||
missing["seedream"] = "Seedream 服务商未配置,请先配置火山方舟 API Key(SEEDANCE_API_KEY)。"
|
||||
}
|
||||
if strings.TrimSpace(getenv("MINIMAX_API_KEY")) == "" {
|
||||
missing["minimax"] = "MiniMax 服务商未配置,请先配置 MINIMAX_API_KEY。"
|
||||
}
|
||||
return missing
|
||||
}
|
||||
|
||||
@@ -272,6 +286,9 @@ func capabilitySummary(getenv postgres.Getenv) func(context.Context) (any, error
|
||||
primaryVideo["label"] = "Seedance 视频生成"
|
||||
primaryVideo["limits"] = seedanceCapabilityLimits(videoModel(getenv))
|
||||
primaryVideo["models"] = seedanceModelOptions()
|
||||
} else if primaryVideoEngine == "minimax" {
|
||||
primaryVideo["label"] = "MiniMax H3 视频生成"
|
||||
primaryVideo["limits"] = minimaxVideoCapabilityLimits()
|
||||
} else {
|
||||
primaryVideo["label"] = "百炼图生视频"
|
||||
primaryVideo["limits"] = bailianVideoCapabilityLimits()
|
||||
@@ -280,6 +297,7 @@ func capabilitySummary(getenv postgres.Getenv) func(context.Context) (any, error
|
||||
map[string]any{"id": "image.generate", "label": imageCapabilityLabel(engine), "kind": "image", "engine": engine, "provider": provider, "reqKey": imageModel(getenv)},
|
||||
primaryVideo,
|
||||
map[string]any{"id": "video.generate.bailian", "label": "百炼图生视频", "kind": "video", "engine": "bailian", "provider": "bailian", "reqKey": firstNonEmpty(getenv("BAILIAN_VIDEO_MODEL"), "wan2.7-i2v-2026-04-25"), "limits": bailianVideoCapabilityLimits()},
|
||||
map[string]any{"id": "video.generate.minimax", "label": "MiniMax H3 视频生成", "kind": "video", "engine": "minimax", "provider": "minimax", "reqKey": providers.MinimaxH3Model, "limits": minimaxVideoCapabilityLimits()},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@@ -303,11 +321,20 @@ func bailianVideoCapabilityLimits() map[string]any {
|
||||
return map[string]any{"inputImages": map[string]int{"min": 1, "max": 2}, "durationSeconds": map[string]int{"min": 2, "max": 15}, "resolutions": []string{"720P", "1080P"}}
|
||||
}
|
||||
|
||||
func minimaxVideoCapabilityLimits() map[string]any {
|
||||
return map[string]any{
|
||||
"inputImages": map[string]int{"min": 0, "max": 1},
|
||||
"durationSeconds": map[string]int{"min": 4, "max": 15},
|
||||
"ratios": []string{"21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "adaptive"},
|
||||
"resolutions": []string{"768P", "2K"},
|
||||
}
|
||||
}
|
||||
|
||||
func runtimeHealthDetails(getenv postgres.Getenv) httpapi.HealthDetails {
|
||||
image := imageEngine(getenv)
|
||||
imageLabel := map[string]string{"jimeng": "即梦", "evolink": "EvoLink", "bailian": "阿里云百炼", "seedream": "Seedream 5.0 Pro"}[image]
|
||||
video := videoEngine(getenv)
|
||||
videoLabel := map[string]string{"seedance": "Seedance", "bailian": "阿里云百炼"}[video]
|
||||
videoLabel := map[string]string{"seedance": "Seedance", "bailian": "阿里云百炼", "minimax": "MiniMax H3"}[video]
|
||||
visualConfigured := strings.TrimSpace(getenv("VOLCENGINE_ACCESS_KEY_ID")) != "" && strings.TrimSpace(getenv("VOLCENGINE_SECRET_ACCESS_KEY")) != ""
|
||||
auth, _ := ParseAuthConfig(getenv)
|
||||
bailianKey := bailianAPIKey(getenv)
|
||||
@@ -318,15 +345,20 @@ func runtimeHealthDetails(getenv postgres.Getenv) httpapi.HealthDetails {
|
||||
authMode = "configured"
|
||||
}
|
||||
}
|
||||
videoCapability := map[string]any{"id": "video.generate", "label": "视频生成", "engine": video, "engineLabel": videoLabel, "reqKey": videoModel(getenv)}
|
||||
if video == "seedance" {
|
||||
videoCapability["models"] = seedanceModelOptions()
|
||||
}
|
||||
return httpapi.HealthDetails{
|
||||
VisualAPIMode: providerMode(visualConfigured, "volcengine"),
|
||||
EvolinkMode: providerMode(strings.TrimSpace(getenv("EVOLINK_API_KEY")) != "", "evolink"),
|
||||
SeedanceMode: providerMode(strings.TrimSpace(getenv("SEEDANCE_API_KEY")) != "", "seedance"),
|
||||
BailianMode: providerMode(bailianKey != "", "bailian"),
|
||||
MinimaxMode: providerMode(strings.TrimSpace(getenv("MINIMAX_API_KEY")) != "", "minimax"),
|
||||
AuthMode: authMode,
|
||||
Capabilities: []any{
|
||||
map[string]any{"id": "image.generate", "label": imageCapabilityLabel(image), "engine": image, "engineLabel": imageLabel, "reqKey": imageModel(getenv)},
|
||||
map[string]any{"id": "video.generate", "label": "视频生成", "engine": video, "engineLabel": videoLabel, "reqKey": videoModel(getenv), "models": seedanceModelOptions()},
|
||||
videoCapability,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -353,6 +385,7 @@ var runtimeSettingKeys = []string{
|
||||
"ALI_OSS_ACCESS_KEY_ID", "ALI_OSS_ACCESS_KEY_SECRET", "ALI_OSS_BUCKET", "ALI_OSS_ENDPOINT", "ALI_OSS_PUBLIC_BASE_URL",
|
||||
"BAILIAN_API_KEY", "BAILIAN_BASE_URL", "BAILIAN_IMAGE_MODEL", "BAILIAN_VIDEO_MODEL", "DATABASE_URL", "DASHSCOPE_API_KEY",
|
||||
"EVOLINK_API_KEY", "EVOLINK_BASE_URL", "EVOLINK_IMAGE_MODEL", "EVOLINK_IMAGE_QUALITY", "IMAGE_GENERATE_ENGINE",
|
||||
"MINIMAX_API_KEY", "MINIMAX_BASE_URL",
|
||||
"SEEDANCE_API_KEY", "SEEDANCE_MODEL", "VIDEO_GENERATE_ENGINE", "VOLCENGINE_ACCESS_KEY_ID", "VOLCENGINE_SECRET_ACCESS_KEY",
|
||||
"ZHINIAN_AUTH_REQUIRED", "ZHINIAN_AUTH_SESSION_SECRET", "ZHINIAN_BILLING_ACCOUNT_BANK", "ZHINIAN_BILLING_ACCOUNT_NAME",
|
||||
"ZHINIAN_BILLING_ACCOUNT_NUMBER", "ZHINIAN_BILLING_CONTACT", "ZHINIAN_BILLING_REQUIRED",
|
||||
|
||||
@@ -215,6 +215,32 @@ func TestRuntimeProviderJobBuilderRoutesSeedreamWithoutReplacingJimeng(t *testin
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuntimeProviderJobBuilderRoutesMinimaxH3FromDatabaseSettings(t *testing.T) {
|
||||
values := map[string]string{
|
||||
"MINIMAX_API_KEY": "minimax-secret",
|
||||
"MINIMAX_BASE_URL": "https://api.minimax.test",
|
||||
"VIDEO_GENERATE_ENGINE": "minimax",
|
||||
}
|
||||
getenv := func(name string) string { return values[name] }
|
||||
builder := configuredProviderJobBuilder(getenv, true)
|
||||
command, err := builder.Build(context.Background(), "owner", "", "video.generate", "", map[string]any{
|
||||
"engine": "minimax", "prompt": "animate", "settings": map[string]any{"duration": 5.0, "resolution": "768P", "ratio": "16:9"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if command.Job.Provider != "minimax" || command.Job.ReqKey != providers.MinimaxH3Model {
|
||||
t.Fatalf("job=%#v", command.Job)
|
||||
}
|
||||
if _, ok := buildProviderRegistryWithClient(getenv, http.DefaultClient, 2<<20)["minimax"].(*providers.Minimax); !ok {
|
||||
t.Fatalf("minimax adapter is not registered")
|
||||
}
|
||||
details := runtimeHealthDetails(getenv)
|
||||
if details.MinimaxMode != "minimax" {
|
||||
t.Fatalf("health=%#v", details)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRuntimeProviderResolverUsesLatestDatabaseCredential(t *testing.T) {
|
||||
var authorizations []string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
|
||||
@@ -279,7 +305,7 @@ func TestProviderUnavailableMessagesIdentifyOnlyMissingCredentials(t *testing.T)
|
||||
"BAILIAN_API_KEY": "bailian",
|
||||
}
|
||||
missing := providerUnavailableMessages(func(name string) string { return values[name] })
|
||||
if len(missing) != 1 || !strings.Contains(missing["seedance"], "SEEDANCE_API_KEY") {
|
||||
if len(missing) != 3 || !strings.Contains(missing["seedance"], "SEEDANCE_API_KEY") || !strings.Contains(missing["seedream"], "SEEDANCE_API_KEY") || !strings.Contains(missing["minimax"], "MINIMAX_API_KEY") {
|
||||
t.Fatalf("missing = %#v", missing)
|
||||
}
|
||||
}
|
||||
@@ -313,6 +339,17 @@ func TestProviderVideoTargetsUseDocumentedSeedanceDefaults(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderVideoTargetsIncludeMinimaxH3Defaults(t *testing.T) {
|
||||
target := providerVideoTargets(func(string) string { return "" })["minimax"]
|
||||
if target.Provider != "minimax" || target.Model != providers.MinimaxH3Model {
|
||||
t.Fatalf("target=%#v", target)
|
||||
}
|
||||
want := map[string]any{"ratio": "16:9", "duration": float64(5), "resolution": "768P"}
|
||||
if !reflect.DeepEqual(target.Settings, want) {
|
||||
t.Fatalf("settings=%#v want=%#v", target.Settings, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderVideoModelsKeepSeedance20And25Available(t *testing.T) {
|
||||
targets := providerVideoModels(func(string) string { return "" })
|
||||
for _, model := range []string{"doubao-seedance-2-0-260128", "doubao-seedance-2-5-260628"} {
|
||||
@@ -335,6 +372,7 @@ func TestCapabilitySummaryMatchesConfiguredDefaultVideoEngine(t *testing.T) {
|
||||
}{
|
||||
{name: "Bailian default", engine: "", wantEngine: "bailian", wantProvider: "bailian", wantModel: "wan2.7-i2v-2026-04-25"},
|
||||
{name: "Seedance configured", engine: "seedance", wantEngine: "seedance", wantProvider: "seedance", wantModel: "doubao-seedance-2-0-260128"},
|
||||
{name: "MiniMax configured", engine: "minimax", wantEngine: "minimax", wantProvider: "minimax", wantModel: providers.MinimaxH3Model},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
values := map[string]string{"VIDEO_GENERATE_ENGINE": test.engine}
|
||||
|
||||
Reference in new issue
Block a user