mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-03 06:52:13 +08:00
Merge pull request #956 from share-wey/main
chore: codex transform fixes and feature compatibility
This commit is contained in:
@@ -129,6 +129,41 @@ func applyCodexOAuthTransform(reqBody map[string]any, isCodexCLI bool, isCompact
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 兼容遗留的 functions 和 function_call,转换为 tools 和 tool_choice
|
||||||
|
if functionsRaw, ok := reqBody["functions"]; ok {
|
||||||
|
if functions, k := functionsRaw.([]any); k {
|
||||||
|
tools := make([]any, 0, len(functions))
|
||||||
|
for _, f := range functions {
|
||||||
|
tools = append(tools, map[string]any{
|
||||||
|
"type": "function",
|
||||||
|
"function": f,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
reqBody["tools"] = tools
|
||||||
|
}
|
||||||
|
delete(reqBody, "functions")
|
||||||
|
result.Modified = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if fcRaw, ok := reqBody["function_call"]; ok {
|
||||||
|
if fcStr, ok := fcRaw.(string); ok {
|
||||||
|
// e.g. "auto", "none"
|
||||||
|
reqBody["tool_choice"] = fcStr
|
||||||
|
} else if fcObj, ok := fcRaw.(map[string]any); ok {
|
||||||
|
// e.g. {"name": "my_func"}
|
||||||
|
if name, ok := fcObj["name"].(string); ok && strings.TrimSpace(name) != "" {
|
||||||
|
reqBody["tool_choice"] = map[string]any{
|
||||||
|
"type": "function",
|
||||||
|
"function": map[string]any{
|
||||||
|
"name": name,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(reqBody, "function_call")
|
||||||
|
result.Modified = true
|
||||||
|
}
|
||||||
|
|
||||||
if normalizeCodexTools(reqBody) {
|
if normalizeCodexTools(reqBody) {
|
||||||
result.Modified = true
|
result.Modified = true
|
||||||
}
|
}
|
||||||
@@ -303,6 +338,18 @@ func filterCodexInput(input []any, preserveReferences bool) []any {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
typ, _ := m["type"].(string)
|
typ, _ := m["type"].(string)
|
||||||
|
|
||||||
|
// 修复 OpenAI 上游的最新校验:"Expected an ID that begins with 'fc'"
|
||||||
|
fixIDPrefix := func(id string) string {
|
||||||
|
if id == "" || strings.HasPrefix(id, "fc") {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(id, "call_") {
|
||||||
|
return "fc" + strings.TrimPrefix(id, "call_")
|
||||||
|
}
|
||||||
|
return "fc_" + id
|
||||||
|
}
|
||||||
|
|
||||||
if typ == "item_reference" {
|
if typ == "item_reference" {
|
||||||
if !preserveReferences {
|
if !preserveReferences {
|
||||||
continue
|
continue
|
||||||
@@ -311,6 +358,9 @@ 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 != "" {
|
||||||
|
newItem["id"] = fixIDPrefix(id)
|
||||||
|
}
|
||||||
filtered = append(filtered, newItem)
|
filtered = append(filtered, newItem)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -330,10 +380,20 @@ func filterCodexInput(input []any, preserveReferences bool) []any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isCodexToolCallItemType(typ) {
|
if isCodexToolCallItemType(typ) {
|
||||||
if callID, ok := m["call_id"].(string); !ok || strings.TrimSpace(callID) == "" {
|
callID, ok := m["call_id"].(string)
|
||||||
|
if !ok || strings.TrimSpace(callID) == "" {
|
||||||
if id, ok := m["id"].(string); ok && strings.TrimSpace(id) != "" {
|
if id, ok := m["id"].(string); ok && strings.TrimSpace(id) != "" {
|
||||||
|
callID = id
|
||||||
ensureCopy()
|
ensureCopy()
|
||||||
newItem["call_id"] = id
|
newItem["call_id"] = callID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if callID != "" {
|
||||||
|
fixedCallID := fixIDPrefix(callID)
|
||||||
|
if fixedCallID != callID {
|
||||||
|
ensureCopy()
|
||||||
|
newItem["call_id"] = fixedCallID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,6 +404,14 @@ 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,12 @@ 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, "ref1", first["id"])
|
require.Equal(t, "fc_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, "o1", second["id"])
|
require.Equal(t, "fc_o1", second["id"])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyCodexOAuthTransform_ExplicitStoreFalsePreserved(t *testing.T) {
|
func TestApplyCodexOAuthTransform_ExplicitStoreFalsePreserved(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user