mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-28 10:24:27 +08:00
80 lines
2.8 KiB
Go
80 lines
2.8 KiB
Go
package responses
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/sjson"
|
|
)
|
|
|
|
func ConvertOpenAIResponsesRequestToCodex(modelName string, inputRawJSON []byte, _ bool) []byte {
|
|
rawJSON := inputRawJSON
|
|
|
|
inputResult := gjson.GetBytes(rawJSON, "input")
|
|
if inputResult.Type == gjson.String {
|
|
input, _ := sjson.Set(`[{"type":"message","role":"user","content":[{"type":"input_text","text":""}]}]`, "0.content.0.text", inputResult.String())
|
|
rawJSON, _ = sjson.SetRawBytes(rawJSON, "input", []byte(input))
|
|
}
|
|
|
|
rawJSON, _ = sjson.SetBytes(rawJSON, "stream", true)
|
|
rawJSON, _ = sjson.SetBytes(rawJSON, "store", false)
|
|
rawJSON, _ = sjson.SetBytes(rawJSON, "parallel_tool_calls", true)
|
|
rawJSON, _ = sjson.SetBytes(rawJSON, "include", []string{"reasoning.encrypted_content"})
|
|
// Codex Responses rejects token limit fields, so strip them out before forwarding.
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "max_output_tokens")
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "max_completion_tokens")
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "temperature")
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "top_p")
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "service_tier")
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "truncation")
|
|
rawJSON = applyResponsesCompactionCompatibility(rawJSON)
|
|
|
|
// Delete the user field as it is not supported by the Codex upstream.
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "user")
|
|
|
|
// Convert role "system" to "developer" in input array to comply with Codex API requirements.
|
|
rawJSON = convertSystemRoleToDeveloper(rawJSON)
|
|
|
|
return rawJSON
|
|
}
|
|
|
|
// applyResponsesCompactionCompatibility handles OpenAI Responses context_management.compaction
|
|
// for Codex upstream compatibility.
|
|
//
|
|
// Codex /responses currently rejects context_management with:
|
|
// {"detail":"Unsupported parameter: context_management"}.
|
|
//
|
|
// Compatibility strategy:
|
|
// 1) Remove context_management before forwarding to Codex upstream.
|
|
func applyResponsesCompactionCompatibility(rawJSON []byte) []byte {
|
|
if !gjson.GetBytes(rawJSON, "context_management").Exists() {
|
|
return rawJSON
|
|
}
|
|
|
|
rawJSON, _ = sjson.DeleteBytes(rawJSON, "context_management")
|
|
return rawJSON
|
|
}
|
|
|
|
// convertSystemRoleToDeveloper traverses the input array and converts any message items
|
|
// with role "system" to role "developer". This is necessary because Codex API does not
|
|
// accept "system" role in the input array.
|
|
func convertSystemRoleToDeveloper(rawJSON []byte) []byte {
|
|
inputResult := gjson.GetBytes(rawJSON, "input")
|
|
if !inputResult.IsArray() {
|
|
return rawJSON
|
|
}
|
|
|
|
inputArray := inputResult.Array()
|
|
result := rawJSON
|
|
|
|
// Directly modify role values for items with "system" role
|
|
for i := 0; i < len(inputArray); i++ {
|
|
rolePath := fmt.Sprintf("input.%d.role", i)
|
|
if gjson.GetBytes(result, rolePath).String() == "system" {
|
|
result, _ = sjson.SetBytes(result, rolePath, "developer")
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|