From fab326eca12963accac5bb884ac87fad7ee51c01 Mon Sep 17 00:00:00 2001 From: "CJACK." Date: Thu, 5 Mar 2026 18:20:42 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E6=B3=A8=E5=85=A5=20null=20=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E8=B0=83=E7=94=A8=E6=A0=BC=E5=BC=8F=E6=B7=B7=E4=B9=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/adapter/openai/message_normalize.go | 3 ++ .../adapter/openai/message_normalize_test.go | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/internal/adapter/openai/message_normalize.go b/internal/adapter/openai/message_normalize.go index 299f908..bbc5800 100644 --- a/internal/adapter/openai/message_normalize.go +++ b/internal/adapter/openai/message_normalize.go @@ -132,6 +132,9 @@ func formatToolResultForPrompt(msg map[string]any) string { } func normalizeOpenAIContentForPrompt(v any) string { + if v == nil { + return "" + } switch x := v.(type) { case string: return x diff --git a/internal/adapter/openai/message_normalize_test.go b/internal/adapter/openai/message_normalize_test.go index ba17a52..a4e1843 100644 --- a/internal/adapter/openai/message_normalize_test.go +++ b/internal/adapter/openai/message_normalize_test.go @@ -194,6 +194,36 @@ func TestNormalizeOpenAIMessagesForPrompt_PreservesConcatenatedToolArguments(t * } } +func TestNormalizeOpenAIMessagesForPrompt_AssistantNilContentDoesNotInjectNullLiteral(t *testing.T) { + raw := []any{ + map[string]any{ + "role": "assistant", + "content": nil, + "tool_calls": []any{ + map[string]any{ + "id": "call_screenshot", + "function": map[string]any{ + "name": "send_file_to_user", + "arguments": `{"file_path":"/tmp/a.png"}`, + }, + }, + }, + }, + } + + normalized := normalizeOpenAIMessagesForPrompt(raw, "") + if len(normalized) != 1 { + t.Fatalf("expected one normalized message, got %d", len(normalized)) + } + content, _ := normalized[0]["content"].(string) + if strings.Contains(content, "<|Assistant|>null") || strings.HasPrefix(strings.TrimSpace(content), "null") { + t.Fatalf("unexpected null literal injected into assistant tool history: %q", content) + } + if !strings.Contains(content, "function.name: send_file_to_user") { + t.Fatalf("expected tool history block preserved, got %q", content) + } +} + func TestNormalizeOpenAIMessagesForPrompt_DeveloperRoleMapsToSystem(t *testing.T) { raw := []any{ map[string]any{"role": "developer", "content": "必须先走工具调用"},