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") // Convert role "system" to "developer" in input array to comply with Codex API requirements. rawJSON = convertSystemRoleToDeveloper(rawJSON) 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 }