From ca42a45802b29d77a17437fd70f6c8641a96034f Mon Sep 17 00:00:00 2001 From: ius Date: Sat, 14 Mar 2026 13:47:01 +0800 Subject: [PATCH] fix: stop rewriting native responses input ids --- .../service/openai_codex_transform.go | 19 ++----- .../service/openai_codex_transform_test.go | 55 ++++++++++++++++++- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/backend/internal/service/openai_codex_transform.go b/backend/internal/service/openai_codex_transform.go index 8fffce1b..29f2b672 100644 --- a/backend/internal/service/openai_codex_transform.go +++ b/backend/internal/service/openai_codex_transform.go @@ -339,8 +339,9 @@ func filterCodexInput(input []any, preserveReferences bool) []any { } typ, _ := m["type"].(string) - // 修复 OpenAI 上游的最新校验:"Expected an ID that begins with 'fc'" - fixIDPrefix := func(id string) string { + // 仅修正真正的 tool/function call 标识,避免误改普通 message/reasoning id; + // 若 item_reference 指向 legacy call_* 标识,则仅修正该引用本身。 + fixCallIDPrefix := func(id string) string { if id == "" || strings.HasPrefix(id, "fc") { return id } @@ -358,8 +359,8 @@ func filterCodexInput(input []any, preserveReferences bool) []any { for key, value := range m { newItem[key] = value } - if id, ok := newItem["id"].(string); ok && id != "" { - newItem["id"] = fixIDPrefix(id) + if id, ok := newItem["id"].(string); ok && strings.HasPrefix(id, "call_") { + newItem["id"] = fixCallIDPrefix(id) } filtered = append(filtered, newItem) continue @@ -390,7 +391,7 @@ func filterCodexInput(input []any, preserveReferences bool) []any { } if callID != "" { - fixedCallID := fixIDPrefix(callID) + fixedCallID := fixCallIDPrefix(callID) if fixedCallID != callID { ensureCopy() newItem["call_id"] = fixedCallID @@ -404,14 +405,6 @@ func filterCodexInput(input []any, preserveReferences bool) []any { if !isCodexToolCallItemType(typ) { delete(newItem, "call_id") } - } else { - if id, ok := newItem["id"].(string); ok && id != "" { - fixedID := fixIDPrefix(id) - if fixedID != id { - ensureCopy() - newItem["id"] = fixedID - } - } } filtered = append(filtered, newItem) diff --git a/backend/internal/service/openai_codex_transform_test.go b/backend/internal/service/openai_codex_transform_test.go index df012d7c..ae6f8555 100644 --- a/backend/internal/service/openai_codex_transform_test.go +++ b/backend/internal/service/openai_codex_transform_test.go @@ -33,12 +33,63 @@ func TestApplyCodexOAuthTransform_ToolContinuationPreservesInput(t *testing.T) { first, ok := input[0].(map[string]any) require.True(t, ok) require.Equal(t, "item_reference", first["type"]) - require.Equal(t, "fc_ref1", first["id"]) + require.Equal(t, "ref1", first["id"]) // 校验 input[1] 为 map,确保后续字段断言安全。 second, ok := input[1].(map[string]any) require.True(t, ok) - require.Equal(t, "fc_o1", second["id"]) + require.Equal(t, "o1", second["id"]) + require.Equal(t, "fc1", second["call_id"]) +} + +func TestApplyCodexOAuthTransform_ToolContinuationPreservesNativeMessageAndReasoningIDs(t *testing.T) { + reqBody := map[string]any{ + "model": "gpt-5.2", + "input": []any{ + map[string]any{"type": "message", "id": "msg_0", "role": "user", "content": "hi"}, + map[string]any{"type": "item_reference", "id": "rs_123"}, + }, + "tool_choice": "auto", + } + + applyCodexOAuthTransform(reqBody, false, false) + + input, ok := reqBody["input"].([]any) + require.True(t, ok) + require.Len(t, input, 2) + + first, ok := input[0].(map[string]any) + require.True(t, ok) + require.Equal(t, "msg_0", first["id"]) + + second, ok := input[1].(map[string]any) + require.True(t, ok) + require.Equal(t, "rs_123", second["id"]) +} + +func TestApplyCodexOAuthTransform_ToolContinuationNormalizesToolReferenceIDsOnly(t *testing.T) { + reqBody := map[string]any{ + "model": "gpt-5.2", + "input": []any{ + map[string]any{"type": "item_reference", "id": "call_1"}, + map[string]any{"type": "function_call_output", "call_id": "call_1", "output": "ok"}, + }, + "tool_choice": "auto", + } + + applyCodexOAuthTransform(reqBody, false, false) + + input, ok := reqBody["input"].([]any) + require.True(t, ok) + require.Len(t, input, 2) + + first, ok := input[0].(map[string]any) + require.True(t, ok) + require.Equal(t, "fc1", first["id"]) + + second, ok := input[1].(map[string]any) + require.True(t, ok) + require.Equal(t, "fc1", second["call_id"]) } func TestApplyCodexOAuthTransform_ExplicitStoreFalsePreserved(t *testing.T) {