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:
rickylin047
2026-03-10 23:31:54 +08:00
parent 3cc407bc0e
commit 9f1f203b84
2 changed files with 60 additions and 0 deletions

View File

@@ -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