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")