From 0f1765b226b3ca0d0fd8032a78561d25684a243a Mon Sep 17 00:00:00 2001 From: easyai Date: Wed, 22 Jul 2026 03:37:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(gemini):=20=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E5=9B=BE=E5=83=8F=E7=94=9F=E6=88=90=E9=85=8D=E7=BD=AE=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/internal/clients/clients_test.go | 19 +++++++++++++++++++ apps/api/internal/clients/gemini.go | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/apps/api/internal/clients/clients_test.go b/apps/api/internal/clients/clients_test.go index 700f6d9..7f528fb 100644 --- a/apps/api/internal/clients/clients_test.go +++ b/apps/api/internal/clients/clients_test.go @@ -1306,6 +1306,25 @@ func TestGeminiClientImageGenerateBuildsNativeImageBody(t *testing.T) { } } +func TestGeminiGenerationConfigInitializesMissingImageConfig(t *testing.T) { + config := geminiGenerationConfig(map[string]any{ + "aspect_ratio": "16:9", + "resolution": "4K", + }, true) + + imageConfig, ok := config["imageConfig"].(map[string]any) + if !ok { + t.Fatalf("imageConfig should be initialized, got %+v", config) + } + if imageConfig["aspectRatio"] != "16:9" || imageConfig["imageSize"] != "4K" { + t.Fatalf("unexpected imageConfig: %+v", imageConfig) + } + modalities, ok := config["responseModalities"].([]any) + if !ok || len(modalities) != 1 || modalities[0] != "IMAGE" { + t.Fatalf("image response modality should be initialized, got %+v", config) + } +} + func TestGeminiClientImageEditPreservesNativeContentsAndFileData(t *testing.T) { var captured map[string]any server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/apps/api/internal/clients/gemini.go b/apps/api/internal/clients/gemini.go index 8cfe74f..6dc86bc 100644 --- a/apps/api/internal/clients/gemini.go +++ b/apps/api/internal/clients/gemini.go @@ -195,14 +195,23 @@ func geminiApplyRequestOptions(body map[string]any, request Request, imageRespon func geminiGenerationConfig(body map[string]any, imageResponse bool) map[string]any { source := mapFromAny(firstPresent(body["generationConfig"], body["generation_config"])) out := cloneMapAny(source) + if out == nil { + out = map[string]any{} + } if aspectRatio := firstNonEmptyString(body["aspect_ratio"], body["aspectRatio"]); aspectRatio != "" { imageConfig := cloneMapAny(mapFromAny(firstPresent(out["imageConfig"], out["image_config"]))) + if imageConfig == nil { + imageConfig = map[string]any{} + } imageConfig["aspectRatio"] = aspectRatio out["imageConfig"] = imageConfig delete(out, "image_config") } if imageSize := firstNonEmptyString(body["resolution"], body["imageSize"], body["image_size"], body["size"]); imageSize != "" { imageConfig := cloneMapAny(mapFromAny(firstPresent(out["imageConfig"], out["image_config"]))) + if imageConfig == nil { + imageConfig = map[string]any{} + } imageConfig["imageSize"] = imageSize out["imageConfig"] = imageConfig delete(out, "image_config")