diff --git a/backend/internal/service/openai_images.go b/backend/internal/service/openai_images.go index bc6b6b807f..c661aade36 100644 --- a/backend/internal/service/openai_images.go +++ b/backend/internal/service/openai_images.go @@ -34,12 +34,13 @@ const ( openAIImagesGenerationsURL = "https://api.openai.com/v1/images/generations" openAIImagesEditsURL = "https://api.openai.com/v1/images/edits" - openAIChatGPTStartURL = "https://chatgpt.com/" - openAIChatGPTFilesURL = "https://chatgpt.com/backend-api/files" - openAIImageBackendUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" - openAIImageMaxDownloadBytes = 20 << 20 // 20MB per image download - openAIImageMaxUploadPartSize = 20 << 20 // 20MB per multipart upload part - openAIImagesResponsesMainModel = "gpt-5.4-mini" + openAIChatGPTStartURL = "https://chatgpt.com/" + openAIChatGPTFilesURL = "https://chatgpt.com/backend-api/files" + openAIImageBackendUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" + openAIImageMaxDownloadBytes = 20 << 20 // 20MB per image download + openAIImageMaxUploadPartSize = 20 << 20 // 20MB per multipart upload part + openAIImagesResponsesMainModel = "gpt-5.4-mini" + openAIImagesVerbatimPromptInstructions = "When invoking the image_generation tool, use the user's image prompt verbatim. Do not rewrite, expand, summarize, embellish, translate, normalize punctuation, or add or remove visual details or constraints. Preserve the original language, wording, capitalization, quotes, and punctuation exactly." ) type OpenAIImagesCapability string diff --git a/backend/internal/service/openai_images_responses.go b/backend/internal/service/openai_images_responses.go index 9e72aaecc4..9374a6f7c7 100644 --- a/backend/internal/service/openai_images_responses.go +++ b/backend/internal/service/openai_images_responses.go @@ -356,6 +356,7 @@ func buildOpenAIImagesResponsesRequest(parsed *OpenAIImagesRequest, toolModel st req := []byte(`{"instructions":"","stream":true,"reasoning":{"effort":"medium","summary":"auto"},"parallel_tool_calls":true,"include":["reasoning.encrypted_content"],"model":"","store":false,"tool_choice":{"type":"image_generation"}}`) req, _ = sjson.SetBytes(req, "model", openAIImagesResponsesMainModel) + req, _ = sjson.SetBytes(req, "instructions", openAIImagesVerbatimPromptInstructions) input := []byte(`[{"type":"message","role":"user","content":[{"type":"input_text","text":""}]}]`) input, _ = sjson.SetBytes(input, "0.content.0.text", prompt) diff --git a/backend/internal/service/openai_images_test.go b/backend/internal/service/openai_images_test.go index 6761c55131..f06c213f46 100644 --- a/backend/internal/service/openai_images_test.go +++ b/backend/internal/service/openai_images_test.go @@ -2011,6 +2011,21 @@ func TestBuildOpenAIImagesResponsesRequest_StripsInputFidelity(t *testing.T) { require.Equal(t, "edit", gjson.GetBytes(body, "tools.0.action").String()) } +func TestBuildOpenAIImagesResponsesRequest_RequiresVerbatimUserPrompt(t *testing.T) { + prompt := "画一个蓝色马克杯,杯身只写“SkelOT”,保持大小写;白色背景,不要增加其他文字。" + parsed := &OpenAIImagesRequest{ + Endpoint: openAIImagesGenerationsEndpoint, + Model: "gpt-image-2", + Prompt: prompt, + N: 1, + } + + body, err := buildOpenAIImagesResponsesRequest(parsed, "gpt-image-2") + require.NoError(t, err) + require.Equal(t, openAIImagesVerbatimPromptInstructions, gjson.GetBytes(body, "instructions").String()) + require.Equal(t, prompt, gjson.GetBytes(body, "input.0.content.0.text").String()) +} + func TestCollectOpenAIImagesFromResponsesBody_FallsBackToOutputItemDone(t *testing.T) { body := []byte( "data: {\"type\":\"response.created\",\"response\":{\"created_at\":1710000004}}\n\n" +