From 589ad8d4624ea01e02610f4eee64815f336b7eac Mon Sep 17 00:00:00 2001 From: Futureppo Date: Mon, 13 Jul 2026 14:09:30 +0800 Subject: [PATCH 1/2] Fix responses assistant history content --- internal/openai/responses_compat.go | 24 ++++++++++++++++++++++++ internal/openai/responses_compat_test.go | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/internal/openai/responses_compat.go b/internal/openai/responses_compat.go index cd65fec..b4a7618 100644 --- a/internal/openai/responses_compat.go +++ b/internal/openai/responses_compat.go @@ -202,6 +202,30 @@ func sanitizeInputItem(item map[string]any) map[string]any { out := clone(item) delete(out, "internal_chat_message_metadata_passthrough") delete(out, "phase") + if String(out, "type", "") == "message" { + out["content"] = sanitizeMessageContent(out["content"]) + } + return out +} + +func sanitizeMessageContent(content any) any { + parts, ok := content.([]any) + if !ok { + return content + } + out := make([]any, 0, len(parts)) + for _, raw := range parts { + part, ok := raw.(map[string]any) + if !ok { + out = append(out, raw) + continue + } + clean := clone(part) + if String(clean, "type", "") == "output_text" { + clean["type"] = "input_text" + } + out = append(out, clean) + } return out } diff --git a/internal/openai/responses_compat_test.go b/internal/openai/responses_compat_test.go index 87c4003..65b0f48 100644 --- a/internal/openai/responses_compat_test.go +++ b/internal/openai/responses_compat_test.go @@ -126,6 +126,29 @@ func TestPrepareCompatibleResponsesDropsUnknownInput(t *testing.T) { } } +func TestPrepareCompatibleResponsesRewritesAssistantOutputTextHistory(t *testing.T) { + wire, _, err := PrepareCompatibleResponses(map[string]any{ + "model": "grok-4.5", + "input": []any{ + map[string]any{ + "type": "message", "role": "assistant", "id": "msg_1", "status": "completed", + "content": []any{map[string]any{"type": "output_text", "text": "first response"}}, + }, + map[string]any{"type": "message", "role": "user", "content": []any{map[string]any{"type": "input_text", "text": "continue"}}}, + }, + }) + if err != nil { + t.Fatal(err) + } + input := wire["input"].([]any) + message := input[0].(map[string]any) + content := message["content"].([]any) + part := content[0].(map[string]any) + if part["type"] != "input_text" || part["text"] != "first response" { + t.Fatalf("assistant history content = %#v", content) + } +} + func TestPrepareCompatibleResponsesNormalizesCodexHostedTools(t *testing.T) { wire, _, err := PrepareCompatibleResponses(map[string]any{ "model": "grok-4.5", "input": "hello", From 72c61b1cb1b6fa7d5d7afb64c86a06e44b080d59 Mon Sep 17 00:00:00 2001 From: Futureppo Date: Mon, 13 Jul 2026 14:16:03 +0800 Subject: [PATCH 2/2] Fix responses assistant history content --- internal/openai/responses_compat.go | 4 ++-- internal/openai/responses_compat_test.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/internal/openai/responses_compat.go b/internal/openai/responses_compat.go index b4a7618..8037be7 100644 --- a/internal/openai/responses_compat.go +++ b/internal/openai/responses_compat.go @@ -202,8 +202,8 @@ func sanitizeInputItem(item map[string]any) map[string]any { out := clone(item) delete(out, "internal_chat_message_metadata_passthrough") delete(out, "phase") - if String(out, "type", "") == "message" { - out["content"] = sanitizeMessageContent(out["content"]) + if content, exists := out["content"]; exists && String(out, "type", "") == "message" { + out["content"] = sanitizeMessageContent(content) } return out } diff --git a/internal/openai/responses_compat_test.go b/internal/openai/responses_compat_test.go index 65b0f48..14f8b3c 100644 --- a/internal/openai/responses_compat_test.go +++ b/internal/openai/responses_compat_test.go @@ -149,6 +149,23 @@ func TestPrepareCompatibleResponsesRewritesAssistantOutputTextHistory(t *testing } } +func TestPrepareCompatibleResponsesDoesNotAddMissingMessageContent(t *testing.T) { + wire, _, err := PrepareCompatibleResponses(map[string]any{ + "model": "grok-4.5", + "input": []any{ + map[string]any{"type": "message", "role": "assistant", "tool_calls": []any{map[string]any{"id": "call_1", "type": "function"}}}, + }, + }) + if err != nil { + t.Fatal(err) + } + input := wire["input"].([]any) + message := input[0].(map[string]any) + if _, exists := message["content"]; exists { + t.Fatalf("missing content was added: %#v", message) + } +} + func TestPrepareCompatibleResponsesNormalizesCodexHostedTools(t *testing.T) { wire, _, err := PrepareCompatibleResponses(map[string]any{ "model": "grok-4.5", "input": "hello",