feat(gateway): add Seedream 5.0 Pro
This commit is contained in:
parent
03abc0eab7
commit
9c300de72c
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@ -1673,6 +1674,119 @@ func TestVolcesClientImageEditPreservesExplicitSequentialDisabledAndClampsMaxIma
|
||||
}
|
||||
}
|
||||
|
||||
func TestVolcesClientSeedreamProGenerationUsesRealModelAndSingleOutput(t *testing.T) {
|
||||
var captured map[string]any
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&captured); err != nil {
|
||||
t.Fatalf("decode request: %v", err)
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": "img-seedream-pro",
|
||||
"data": []any{map[string]any{"url": "https://example.com/out.png"}},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
_, err := (VolcesClient{HTTPClient: server.Client()}).Run(context.Background(), Request{
|
||||
Kind: "images.generations",
|
||||
ModelType: "image_generate",
|
||||
Model: "Seedream-5.0-Pro",
|
||||
Body: map[string]any{
|
||||
"model": "Seedream-5.0-Pro",
|
||||
"prompt": "draw a mountain",
|
||||
"resolution": "2K",
|
||||
"n": 4,
|
||||
"sequential_image_generation": "auto",
|
||||
"sequential_image_generation_options": map[string]any{"max_images": 4},
|
||||
},
|
||||
Candidate: store.RuntimeModelCandidate{
|
||||
BaseURL: server.URL,
|
||||
ModelName: "Seedream-5.0-Pro",
|
||||
ModelAlias: "Seedream-5.0-Pro",
|
||||
ProviderModelName: "doubao-seedream-5-0-pro-260628",
|
||||
Credentials: map[string]any{"apiKey": "volces-key"},
|
||||
Capabilities: map[string]any{
|
||||
"image_generate": map[string]any{
|
||||
"output_multiple_images": false,
|
||||
"output_max_images_count": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("run Seedream Pro generation: %v", err)
|
||||
}
|
||||
if captured["model"] != "doubao-seedream-5-0-pro-260628" || captured["size"] != "2K" {
|
||||
t.Fatalf("Seedream Pro should use the real model and resolution size, got %+v", captured)
|
||||
}
|
||||
if captured["n"] != float64(1) {
|
||||
t.Fatalf("Seedream Pro should force single-image output, got %+v", captured)
|
||||
}
|
||||
if _, ok := captured["sequential_image_generation"]; ok {
|
||||
t.Fatalf("Seedream Pro request must not include sequential image generation, got %+v", captured)
|
||||
}
|
||||
if _, ok := captured["sequential_image_generation_options"]; ok {
|
||||
t.Fatalf("Seedream Pro request must not include sequential image options, got %+v", captured)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVolcesClientSeedreamProEditForwardsTenReferencesAndCustomSize(t *testing.T) {
|
||||
var captured map[string]any
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&captured); err != nil {
|
||||
t.Fatalf("decode request: %v", err)
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"id": "img-seedream-pro-edit",
|
||||
"data": []any{map[string]any{"url": "https://example.com/out.png"}},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
images := make([]any, 10)
|
||||
for index := range images {
|
||||
images[index] = fmt.Sprintf("https://example.com/reference-%d.png", index+1)
|
||||
}
|
||||
_, err := (VolcesClient{HTTPClient: server.Client()}).Run(context.Background(), Request{
|
||||
Kind: "images.edits",
|
||||
ModelType: "image_edit",
|
||||
Model: "Seedream-5.0-Pro",
|
||||
Body: map[string]any{
|
||||
"model": "Seedream-5.0-Pro",
|
||||
"prompt": "combine the references",
|
||||
"image": images,
|
||||
"width": 1600,
|
||||
"height": 900,
|
||||
},
|
||||
Candidate: store.RuntimeModelCandidate{
|
||||
BaseURL: server.URL,
|
||||
ModelName: "Seedream-5.0-Pro",
|
||||
ModelAlias: "Seedream-5.0-Pro",
|
||||
ProviderModelName: "doubao-seedream-5-0-pro-260628",
|
||||
Credentials: map[string]any{"apiKey": "volces-key"},
|
||||
Capabilities: map[string]any{
|
||||
"image_edit": map[string]any{
|
||||
"input_multiple_images": true,
|
||||
"input_max_images_count": 10,
|
||||
"output_multiple_images": false,
|
||||
"output_max_images_count": 1,
|
||||
"input_max_file_size_bytes": 30 * 1024 * 1024,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("run Seedream Pro edit: %v", err)
|
||||
}
|
||||
gotImages, _ := captured["image"].([]any)
|
||||
if captured["model"] != "doubao-seedream-5-0-pro-260628" || captured["size"] != "1600x900" || len(gotImages) != 10 {
|
||||
t.Fatalf("Seedream Pro edit should preserve ten references and custom size, got %+v", captured)
|
||||
}
|
||||
if _, ok := captured["sequential_image_generation"]; ok {
|
||||
t.Fatalf("Seedream Pro edit must not include sequential image generation, got %+v", captured)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVolcesClientVideoSubmitsAndPollsTask(t *testing.T) {
|
||||
var submitPath string
|
||||
var pollPath string
|
||||
|
||||
@ -781,14 +781,22 @@ func supportsMultipleOutputs(request Request, capabilityName string) bool {
|
||||
}
|
||||
|
||||
func normalizeVolcesSequentialImageGeneration(body map[string]any, request Request) {
|
||||
if !supportsMultipleOutputs(request, request.ModelType) {
|
||||
delete(body, "sequential_image_generation")
|
||||
delete(body, "sequential_image_generation_options")
|
||||
if numericValue(body["n"], 1) > 1 {
|
||||
body["n"] = 1
|
||||
}
|
||||
if numericValue(body["batch_size"], 1) > 1 {
|
||||
body["batch_size"] = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
options, hasOptions := volcesSequentialImageGenerationOptions(body)
|
||||
normalizeVolcesSequentialMaxImages(options, request)
|
||||
if _, explicit := body["sequential_image_generation"]; explicit {
|
||||
return
|
||||
}
|
||||
if !supportsMultipleOutputs(request, request.ModelType) {
|
||||
return
|
||||
}
|
||||
count := requestedVolcesSequentialImageCount(body, options)
|
||||
if count <= 1 {
|
||||
return
|
||||
|
||||
@ -125,6 +125,7 @@ func TestCoreLocalFlow(t *testing.T) {
|
||||
t.Fatalf("connect test pool: %v", err)
|
||||
}
|
||||
defer testPool.Close()
|
||||
assertSeedreamProCatalogMigration(t, ctx, testPool)
|
||||
if _, err := testPool.Exec(ctx, `UPDATE gateway_users SET roles = '["admin"]'::jsonb WHERE username = $1`, username); err != nil {
|
||||
t.Fatalf("promote smoke user: %v", err)
|
||||
}
|
||||
@ -1794,6 +1795,42 @@ CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
}
|
||||
}
|
||||
|
||||
func assertSeedreamProCatalogMigration(t *testing.T, ctx context.Context, pool *pgxpool.Pool) {
|
||||
t.Helper()
|
||||
var valid bool
|
||||
if err := pool.QueryRow(ctx, `
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM base_model_catalog model
|
||||
WHERE model.provider_key = 'volces'
|
||||
AND model.canonical_model_key = 'volces:doubao-seedream-5-0-pro-260628'
|
||||
AND model.provider_model_name = 'doubao-seedream-5-0-pro-260628'
|
||||
AND model.display_name = 'Seedream-5.0-Pro'
|
||||
AND model.display_name !~ '[[:space:]]'
|
||||
AND model.model_type = '["image_edit","image_generate"]'::jsonb
|
||||
AND model.capabilities->'image_edit'->>'input_multiple_images' = 'true'
|
||||
AND model.capabilities->'image_edit'->>'input_max_images_count' = '10'
|
||||
AND model.capabilities->'image_edit'->>'input_max_file_size_bytes' = '31457280'
|
||||
AND model.capabilities->'image_edit'->'output_resolutions' = '["1K","2K"]'::jsonb
|
||||
AND model.capabilities->'image_edit'->'output_size_range' = '[921600,4624220]'::jsonb
|
||||
AND model.capabilities->'image_edit'->'aspect_ratio_range' = '[0.0625,16]'::jsonb
|
||||
AND model.capabilities->'image_edit'->>'output_multiple_images' = 'false'
|
||||
AND model.capabilities->'image_edit'->>'output_max_images_count' = '1'
|
||||
AND model.capabilities->'image_generate'->>'allow_custom_width_height_size' = 'true'
|
||||
AND model.capabilities->'image_generate'->>'output_multiple_images' = 'false'
|
||||
AND model.capabilities->>'stream' = 'false'
|
||||
AND model.capabilities->>'supportWebSearch' = 'false'
|
||||
AND model.default_rate_limit_policy->'rules'->0->>'limit' = '500'
|
||||
AND model.default_snapshot->>'modelAlias' = 'Seedream-5.0-Pro'
|
||||
AND model.default_snapshot->>'displayName' = 'Seedream 5.0 Pro'
|
||||
)`).Scan(&valid); err != nil {
|
||||
t.Fatalf("query Seedream 5.0 Pro catalog migration: %v", err)
|
||||
}
|
||||
if !valid {
|
||||
t.Fatal("Seedream 5.0 Pro catalog migration does not match the expected alias, upstream model, capabilities, or rate limit")
|
||||
}
|
||||
}
|
||||
|
||||
func doJSON(t *testing.T, baseURL string, method string, path string, token string, payload any, expectedStatus int, out any) {
|
||||
t.Helper()
|
||||
doJSONWithHeaders(t, baseURL, method, path, token, payload, nil, expectedStatus, out)
|
||||
|
||||
@ -238,7 +238,7 @@ func buildModelCatalog(
|
||||
current = &catalogGroup{
|
||||
key: key,
|
||||
alias: firstNonEmpty(model.ModelAlias, model.DisplayName, model.ModelName),
|
||||
displayName: firstNonEmpty(model.ModelAlias, model.DisplayName, model.ModelName),
|
||||
displayName: firstNonEmpty(model.DisplayName, model.ModelAlias, model.ModelName),
|
||||
modelName: model.ModelName,
|
||||
modelType: cloneStringSlice(model.ModelType),
|
||||
capabilities: cloneObject(model.Capabilities),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
|
||||
@ -114,6 +115,36 @@ func TestBuildModelCatalogAggregatesSources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildModelCatalogKeepsDisplayNameSeparateFromCallAlias(t *testing.T) {
|
||||
models := []store.PlatformModel{
|
||||
{
|
||||
ID: "seedream-pro",
|
||||
PlatformID: "platform-volces",
|
||||
ModelName: "Seedream-5.0-Pro",
|
||||
ProviderModelName: "doubao-seedream-5-0-pro-260628",
|
||||
ModelAlias: "Seedream-5.0-Pro",
|
||||
ModelType: store.StringList{"image_edit", "image_generate"},
|
||||
DisplayName: "Seedream 5.0 Pro",
|
||||
Enabled: true,
|
||||
},
|
||||
}
|
||||
platforms := []store.Platform{
|
||||
{ID: "platform-volces", Provider: "volces", Name: "火山引擎", Status: "enabled"},
|
||||
}
|
||||
|
||||
response := buildModelCatalog(models, platforms, nil, nil, nil, nil, nil)
|
||||
if len(response.Items) != 1 {
|
||||
t.Fatalf("expected one Seedream Pro catalog item, got %+v", response.Items)
|
||||
}
|
||||
item := response.Items[0]
|
||||
if item.Alias != "Seedream-5.0-Pro" || item.DisplayName != "Seedream 5.0 Pro" || item.ModelName != "Seedream-5.0-Pro" {
|
||||
t.Fatalf("catalog should separate the call alias from the display name, got %+v", item)
|
||||
}
|
||||
if strings.Contains(item.Alias, " ") {
|
||||
t.Fatalf("Seedream Pro call alias must not contain spaces, got %q", item.Alias)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildModelCatalogUsesBaseModelProviderForProviderFilters(t *testing.T) {
|
||||
models := []store.PlatformModel{
|
||||
{
|
||||
|
||||
@ -722,10 +722,13 @@ func (imageCountProcessor) ShouldProcess(params map[string]any, modelType string
|
||||
|
||||
func (imageCountProcessor) Process(params map[string]any, modelType string, context *paramProcessContext) bool {
|
||||
capability := capabilityForType(context.modelCapability, modelType)
|
||||
if capability == nil || !boolFromAny(capability["output_multiple_images"]) {
|
||||
if capability == nil {
|
||||
return true
|
||||
}
|
||||
maxCount := int(math.Round(floatFromAny(capability["output_max_images_count"])))
|
||||
if !boolFromAny(capability["output_multiple_images"]) {
|
||||
maxCount = 1
|
||||
}
|
||||
if maxCount <= 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -662,6 +662,31 @@ func TestParamProcessorImageResolutionAndOutputCount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamProcessorForcesSingleImageWhenMultipleOutputsAreDisabled(t *testing.T) {
|
||||
body := map[string]any{
|
||||
"model": "Seedream-5.0-Pro",
|
||||
"prompt": "draw",
|
||||
"n": 4,
|
||||
}
|
||||
candidate := store.RuntimeModelCandidate{
|
||||
ModelType: "image_generate",
|
||||
Capabilities: map[string]any{
|
||||
"image_generate": map[string]any{
|
||||
"output_multiple_images": false,
|
||||
"output_max_images_count": 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := preprocessRequestWithLog("images.generations", body, candidate)
|
||||
if result.Body["n"] != 1 {
|
||||
t.Fatalf("single-output image model should force n=1, got %+v", result.Body)
|
||||
}
|
||||
if len(result.Log.Changes) == 0 || result.Log.Changes[len(result.Log.Changes)-1].CapabilityPath != "capabilities.image_generate.output_max_images_count" {
|
||||
t.Fatalf("single-output adjustment should be logged against output_max_images_count, got %+v", result.Log.Changes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamProcessorImageSizeConstraintsNormalizeExplicitDimensions(t *testing.T) {
|
||||
body := map[string]any{
|
||||
"model": "doubao-5.0图像编辑",
|
||||
|
||||
237
apps/api/migrations/0060_volces_seedream50_pro.sql
Normal file
237
apps/api/migrations/0060_volces_seedream50_pro.sql
Normal file
@ -0,0 +1,237 @@
|
||||
WITH seedream50_pro AS (
|
||||
SELECT
|
||||
'volces:doubao-seedream-5-0-pro-260628' AS canonical_model_key,
|
||||
'doubao-seedream-5-0-pro-260628' AS provider_model_name,
|
||||
'Seedream-5.0-Pro' AS model_alias,
|
||||
'Seedream 5.0 Pro' AS display_name,
|
||||
'["image_edit","image_generate"]'::jsonb AS model_type,
|
||||
'{
|
||||
"image_edit": {
|
||||
"input_multiple_images": true,
|
||||
"input_max_images_count": 10,
|
||||
"input_max_file_size_bytes": 31457280,
|
||||
"output_resolutions": ["1K", "2K"],
|
||||
"size_param_format": "resolution",
|
||||
"allow_custom_width_height_size": true,
|
||||
"output_max_size": 4624220,
|
||||
"output_size_range": [921600, 4624220],
|
||||
"aspect_ratio_range": [0.0625, 16],
|
||||
"output_multiple_images": false,
|
||||
"output_max_images_count": 1
|
||||
},
|
||||
"image_generate": {
|
||||
"output_resolutions": ["1K", "2K"],
|
||||
"size_param_format": "resolution",
|
||||
"allow_custom_width_height_size": true,
|
||||
"output_max_size": 4624220,
|
||||
"output_size_range": [921600, 4624220],
|
||||
"aspect_ratio_range": [0.0625, 16],
|
||||
"output_multiple_images": false,
|
||||
"output_max_images_count": 1
|
||||
},
|
||||
"stream": false,
|
||||
"supportWebSearch": false,
|
||||
"originalTypes": ["image_edit", "image_generate"]
|
||||
}'::jsonb AS capabilities,
|
||||
'{
|
||||
"image": {
|
||||
"basePrice": 10,
|
||||
"baseWeight": 1,
|
||||
"dynamicWeight": {"1K": 1, "2K": 1.5, "3K": 1.75, "4K": 2, "8K": 4}
|
||||
},
|
||||
"currency": "resource"
|
||||
}'::jsonb AS base_billing_config,
|
||||
'{"rules":[{"metric":"rpm","limit":500,"windowSeconds":60}]}'::jsonb AS rate_limit_policy,
|
||||
'{
|
||||
"source": "server-main.integration-platform",
|
||||
"sourceProviderCode": "volces",
|
||||
"sourceProviderName": "火山引擎(豆包)",
|
||||
"sourceSpecType": "volces",
|
||||
"originalTypes": ["image_edit", "image_generate"],
|
||||
"alias": "Seedream-5.0-Pro",
|
||||
"displayName": "Seedream 5.0 Pro",
|
||||
"description": "高精度图片生成与多参考图编辑,支持 1K、2K 和自定义尺寸",
|
||||
"iconPath": "https://ecmb.bdimg.com/tam-ogel/1801637412_-164881388_88_88.jpg",
|
||||
"billingType": "external-api",
|
||||
"billingMode": "",
|
||||
"referenceModel": "",
|
||||
"modelWeight": null,
|
||||
"selectable": true,
|
||||
"rawModel": {
|
||||
"name": "doubao-seedream-5-0-pro-260628",
|
||||
"types": ["image_edit", "image_generate"],
|
||||
"alias": "Seedream-5.0-Pro",
|
||||
"display_name": "Seedream 5.0 Pro",
|
||||
"description": "高精度图片生成与多参考图编辑,支持 1K、2K 和自定义尺寸",
|
||||
"icon_path": "https://ecmb.bdimg.com/tam-ogel/1801637412_-164881388_88_88.jpg",
|
||||
"model_limits": {"max_request_per_minute": 500}
|
||||
}
|
||||
}'::jsonb AS metadata
|
||||
)
|
||||
INSERT INTO base_model_catalog (
|
||||
provider_id,
|
||||
provider_key,
|
||||
canonical_model_key,
|
||||
provider_model_name,
|
||||
model_type,
|
||||
display_name,
|
||||
capabilities,
|
||||
base_billing_config,
|
||||
default_rate_limit_policy,
|
||||
metadata,
|
||||
catalog_type,
|
||||
default_snapshot,
|
||||
status
|
||||
)
|
||||
SELECT
|
||||
(SELECT id FROM model_catalog_providers WHERE provider_key = 'volces' OR provider_code = 'volces' LIMIT 1),
|
||||
'volces',
|
||||
model.canonical_model_key,
|
||||
model.provider_model_name,
|
||||
model.model_type,
|
||||
model.model_alias,
|
||||
model.capabilities,
|
||||
model.base_billing_config,
|
||||
model.rate_limit_policy,
|
||||
jsonb_set(model.metadata, '{rawModel,capabilities}', model.capabilities, true),
|
||||
'system',
|
||||
jsonb_build_object(
|
||||
'providerKey', 'volces',
|
||||
'canonicalModelKey', model.canonical_model_key,
|
||||
'providerModelName', model.provider_model_name,
|
||||
'modelType', model.model_type,
|
||||
'modelAlias', model.model_alias,
|
||||
'displayName', model.display_name,
|
||||
'capabilities', model.capabilities,
|
||||
'baseBillingConfig', model.base_billing_config,
|
||||
'defaultRateLimitPolicy', model.rate_limit_policy,
|
||||
'metadata', jsonb_set(model.metadata, '{rawModel,capabilities}', model.capabilities, true),
|
||||
'status', 'active'
|
||||
),
|
||||
'active'
|
||||
FROM seedream50_pro model
|
||||
ON CONFLICT (canonical_model_key) DO UPDATE
|
||||
SET provider_id = EXCLUDED.provider_id,
|
||||
provider_key = EXCLUDED.provider_key,
|
||||
provider_model_name = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.provider_model_name ELSE base_model_catalog.provider_model_name END,
|
||||
model_type = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.model_type ELSE base_model_catalog.model_type END,
|
||||
display_name = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.display_name ELSE base_model_catalog.display_name END,
|
||||
capabilities = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.capabilities ELSE base_model_catalog.capabilities END,
|
||||
base_billing_config = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.base_billing_config ELSE base_model_catalog.base_billing_config END,
|
||||
default_rate_limit_policy = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.default_rate_limit_policy ELSE base_model_catalog.default_rate_limit_policy END,
|
||||
metadata = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.metadata ELSE base_model_catalog.metadata END,
|
||||
catalog_type = CASE WHEN base_model_catalog.customized_at IS NULL THEN 'system' ELSE base_model_catalog.catalog_type END,
|
||||
default_snapshot = CASE WHEN base_model_catalog.customized_at IS NULL THEN EXCLUDED.default_snapshot ELSE base_model_catalog.default_snapshot END,
|
||||
status = CASE WHEN base_model_catalog.customized_at IS NULL THEN 'active' ELSE base_model_catalog.status END,
|
||||
updated_at = now();
|
||||
|
||||
WITH seedream50_pro AS (
|
||||
SELECT
|
||||
base_model.id AS base_model_id,
|
||||
base_model.provider_model_name,
|
||||
'Seedream-5.0-Pro' AS model_alias,
|
||||
'Seedream 5.0 Pro' AS display_name,
|
||||
base_model.model_type,
|
||||
base_model.capabilities,
|
||||
base_model.base_billing_config,
|
||||
base_model.default_rate_limit_policy
|
||||
FROM base_model_catalog base_model
|
||||
WHERE base_model.canonical_model_key = 'volces:doubao-seedream-5-0-pro-260628'
|
||||
)
|
||||
UPDATE platform_models model
|
||||
SET base_model_id = seedream.base_model_id,
|
||||
model_name = CASE
|
||||
WHEN model.model_name = seedream.model_alias THEN seedream.model_alias
|
||||
WHEN NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM platform_models peer
|
||||
WHERE peer.platform_id = model.platform_id
|
||||
AND peer.id <> model.id
|
||||
AND peer.model_name = seedream.model_alias
|
||||
) THEN seedream.model_alias
|
||||
ELSE model.model_name
|
||||
END,
|
||||
provider_model_name = seedream.provider_model_name,
|
||||
model_alias = seedream.model_alias,
|
||||
model_type = seedream.model_type,
|
||||
display_name = seedream.display_name,
|
||||
capabilities = seedream.capabilities,
|
||||
pricing_mode = 'inherit_discount',
|
||||
billing_config = seedream.base_billing_config,
|
||||
retry_policy = '{"enabled":true,"maxAttempts":1}'::jsonb,
|
||||
rate_limit_policy = seedream.default_rate_limit_policy,
|
||||
enabled = NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM platform_models peer
|
||||
WHERE peer.platform_id = model.platform_id
|
||||
AND peer.id <> model.id
|
||||
AND peer.model_name = seedream.model_alias
|
||||
),
|
||||
updated_at = now()
|
||||
FROM integration_platforms platform
|
||||
JOIN seedream50_pro seedream ON TRUE
|
||||
WHERE model.platform_id = platform.id
|
||||
AND platform.provider = 'volces'
|
||||
AND platform.deleted_at IS NULL
|
||||
AND (
|
||||
model.model_name IN ('Seedream-5.0-Pro', 'doubao-seedream-5-0-pro-260628')
|
||||
OR model.provider_model_name = 'doubao-seedream-5-0-pro-260628'
|
||||
OR model.model_alias = 'Seedream-5.0-Pro'
|
||||
);
|
||||
|
||||
INSERT INTO platform_models (
|
||||
platform_id,
|
||||
base_model_id,
|
||||
model_name,
|
||||
provider_model_name,
|
||||
model_alias,
|
||||
model_type,
|
||||
display_name,
|
||||
capabilities,
|
||||
pricing_mode,
|
||||
billing_config,
|
||||
retry_policy,
|
||||
rate_limit_policy,
|
||||
enabled
|
||||
)
|
||||
SELECT
|
||||
platform.id,
|
||||
base_model.id,
|
||||
'Seedream-5.0-Pro',
|
||||
base_model.provider_model_name,
|
||||
'Seedream-5.0-Pro',
|
||||
base_model.model_type,
|
||||
'Seedream 5.0 Pro',
|
||||
base_model.capabilities,
|
||||
'inherit_discount',
|
||||
base_model.base_billing_config,
|
||||
'{"enabled":true,"maxAttempts":1}'::jsonb,
|
||||
base_model.default_rate_limit_policy,
|
||||
true
|
||||
FROM integration_platforms platform
|
||||
JOIN base_model_catalog base_model ON base_model.canonical_model_key = 'volces:doubao-seedream-5-0-pro-260628'
|
||||
WHERE platform.provider = 'volces'
|
||||
AND platform.deleted_at IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM platform_models existing
|
||||
WHERE existing.platform_id = platform.id
|
||||
AND (
|
||||
existing.model_name IN ('Seedream-5.0-Pro', 'doubao-seedream-5-0-pro-260628')
|
||||
OR existing.provider_model_name = 'doubao-seedream-5-0-pro-260628'
|
||||
OR existing.model_alias = 'Seedream-5.0-Pro'
|
||||
)
|
||||
)
|
||||
ON CONFLICT (platform_id, model_name) DO UPDATE
|
||||
SET base_model_id = EXCLUDED.base_model_id,
|
||||
provider_model_name = EXCLUDED.provider_model_name,
|
||||
model_alias = EXCLUDED.model_alias,
|
||||
display_name = EXCLUDED.display_name,
|
||||
model_type = EXCLUDED.model_type,
|
||||
capabilities = EXCLUDED.capabilities,
|
||||
pricing_mode = EXCLUDED.pricing_mode,
|
||||
billing_config = EXCLUDED.billing_config,
|
||||
retry_policy = EXCLUDED.retry_policy,
|
||||
rate_limit_policy = EXCLUDED.rate_limit_policy,
|
||||
enabled = EXCLUDED.enabled,
|
||||
updated_at = now();
|
||||
Loading…
Reference in New Issue
Block a user