mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-03-29 23:12:46 +00:00
Merge pull request #993 from xvhuan/fix/codex-responses-id-prefix-hotfix-20260314
fix: 止血 Codex/Responses 原生 input id 被误改成 fc_*
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user