Merge pull request #993 from xvhuan/fix/codex-responses-id-prefix-hotfix-20260314

fix: 止血 Codex/Responses 原生 input id 被误改成 fc_*
This commit is contained in:
Wesley Liddick
2026-03-14 13:54:26 +08:00
committed by GitHub
2 changed files with 59 additions and 15 deletions

View File

@@ -339,8 +339,9 @@ func filterCodexInput(input []any, preserveReferences bool) []any {
} }
typ, _ := m["type"].(string) typ, _ := m["type"].(string)
// 修复 OpenAI 上游的最新校验:"Expected an ID that begins with 'fc'" // 仅修正真正的 tool/function call 标识,避免误改普通 message/reasoning id
fixIDPrefix := func(id string) string { // 若 item_reference 指向 legacy call_* 标识,则仅修正该引用本身。
fixCallIDPrefix := func(id string) string {
if id == "" || strings.HasPrefix(id, "fc") { if id == "" || strings.HasPrefix(id, "fc") {
return id return id
} }
@@ -358,8 +359,8 @@ func filterCodexInput(input []any, preserveReferences bool) []any {
for key, value := range m { for key, value := range m {
newItem[key] = value newItem[key] = value
} }
if id, ok := newItem["id"].(string); ok && id != "" { if id, ok := newItem["id"].(string); ok && strings.HasPrefix(id, "call_") {
newItem["id"] = fixIDPrefix(id) newItem["id"] = fixCallIDPrefix(id)
} }
filtered = append(filtered, newItem) filtered = append(filtered, newItem)
continue continue
@@ -390,7 +391,7 @@ func filterCodexInput(input []any, preserveReferences bool) []any {
} }
if callID != "" { if callID != "" {
fixedCallID := fixIDPrefix(callID) fixedCallID := fixCallIDPrefix(callID)
if fixedCallID != callID { if fixedCallID != callID {
ensureCopy() ensureCopy()
newItem["call_id"] = fixedCallID newItem["call_id"] = fixedCallID
@@ -404,14 +405,6 @@ func filterCodexInput(input []any, preserveReferences bool) []any {
if !isCodexToolCallItemType(typ) { if !isCodexToolCallItemType(typ) {
delete(newItem, "call_id") 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) filtered = append(filtered, newItem)

View File

@@ -33,12 +33,63 @@ func TestApplyCodexOAuthTransform_ToolContinuationPreservesInput(t *testing.T) {
first, ok := input[0].(map[string]any) first, ok := input[0].(map[string]any)
require.True(t, ok) require.True(t, ok)
require.Equal(t, "item_reference", first["type"]) require.Equal(t, "item_reference", first["type"])
require.Equal(t, "fc_ref1", first["id"]) require.Equal(t, "ref1", first["id"])
// 校验 input[1] 为 map确保后续字段断言安全。 // 校验 input[1] 为 map确保后续字段断言安全。
second, ok := input[1].(map[string]any) second, ok := input[1].(map[string]any)
require.True(t, ok) 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) { func TestApplyCodexOAuthTransform_ExplicitStoreFalsePreserved(t *testing.T) {