mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-03 06:52:13 +08:00
fix(openai): convert string input to array for Codex OAuth responses endpoint
The ChatGPT backend-api codex/responses endpoint requires `input` to be an array, but the OpenAI Responses API spec allows it to be a plain string. When a client sends a string input, sub2api now converts it to the expected message array format. Empty/whitespace-only strings become an empty array to avoid triggering a 400 "Input must be a list" error.
This commit is contained in:
@@ -146,6 +146,22 @@ func applyCodexOAuthTransform(reqBody map[string]any, isCodexCLI bool, isCompact
|
||||
input = filterCodexInput(input, needsToolContinuation)
|
||||
reqBody["input"] = input
|
||||
result.Modified = true
|
||||
} else if inputStr, ok := reqBody["input"].(string); ok {
|
||||
// ChatGPT codex endpoint requires input to be a list, not a string.
|
||||
// Convert string input to the expected message array format.
|
||||
trimmed := strings.TrimSpace(inputStr)
|
||||
if trimmed != "" {
|
||||
reqBody["input"] = []any{
|
||||
map[string]any{
|
||||
"type": "message",
|
||||
"role": "user",
|
||||
"content": inputStr,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
reqBody["input"] = []any{}
|
||||
}
|
||||
result.Modified = true
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -249,6 +249,50 @@ func TestApplyCodexOAuthTransform_NonCodexCLI_PreservesExistingInstructions(t *t
|
||||
require.Equal(t, "old instructions", instructions)
|
||||
}
|
||||
|
||||
func TestApplyCodexOAuthTransform_StringInputConvertedToArray(t *testing.T) {
|
||||
reqBody := map[string]any{"model": "gpt-5.4", "input": "Hello, world!"}
|
||||
result := applyCodexOAuthTransform(reqBody, false, false)
|
||||
require.True(t, result.Modified)
|
||||
input, ok := reqBody["input"].([]any)
|
||||
require.True(t, ok)
|
||||
require.Len(t, input, 1)
|
||||
msg, ok := input[0].(map[string]any)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "message", msg["type"])
|
||||
require.Equal(t, "user", msg["role"])
|
||||
require.Equal(t, "Hello, world!", msg["content"])
|
||||
}
|
||||
|
||||
func TestApplyCodexOAuthTransform_EmptyStringInputBecomesEmptyArray(t *testing.T) {
|
||||
reqBody := map[string]any{"model": "gpt-5.4", "input": ""}
|
||||
result := applyCodexOAuthTransform(reqBody, false, false)
|
||||
require.True(t, result.Modified)
|
||||
input, ok := reqBody["input"].([]any)
|
||||
require.True(t, ok)
|
||||
require.Len(t, input, 0)
|
||||
}
|
||||
|
||||
func TestApplyCodexOAuthTransform_WhitespaceStringInputBecomesEmptyArray(t *testing.T) {
|
||||
reqBody := map[string]any{"model": "gpt-5.4", "input": " "}
|
||||
result := applyCodexOAuthTransform(reqBody, false, false)
|
||||
require.True(t, result.Modified)
|
||||
input, ok := reqBody["input"].([]any)
|
||||
require.True(t, ok)
|
||||
require.Len(t, input, 0)
|
||||
}
|
||||
|
||||
func TestApplyCodexOAuthTransform_StringInputWithToolsField(t *testing.T) {
|
||||
reqBody := map[string]any{
|
||||
"model": "gpt-5.4",
|
||||
"input": "Run the tests",
|
||||
"tools": []any{map[string]any{"type": "function", "name": "bash"}},
|
||||
}
|
||||
applyCodexOAuthTransform(reqBody, false, false)
|
||||
input, ok := reqBody["input"].([]any)
|
||||
require.True(t, ok)
|
||||
require.Len(t, input, 1)
|
||||
}
|
||||
|
||||
func TestIsInstructionsEmpty(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user