mirror of
https://gh-proxy.org/https://github.com/klinsmaya/CLIProxyAPI.git
synced 2026-11-08 01:16:47 +08:00
feat(translator): normalize service_tier in Codex requests and add tests
- Added `normalizeCodexServiceTier` to standardize `service_tier` values (`fast` to `priority`, omit unsupported tiers). - Updated `ConvertClaudeRequestToCodex` to apply normalization logic. - Introduced `TestConvertClaudeRequestToCodex_ServiceTier` to validate behavior across various `service_tier` inputs. Closes: #3276 #3294
This commit is contained in:
@@ -327,6 +327,9 @@ func ConvertClaudeRequestToCodex(modelName string, inputRawJSON []byte, _ bool)
|
||||
}
|
||||
template, _ = sjson.SetBytes(template, "reasoning.effort", reasoningEffort)
|
||||
template, _ = sjson.SetBytes(template, "reasoning.summary", "auto")
|
||||
if serviceTier := normalizeCodexServiceTier(rootResult.Get("service_tier")); serviceTier != "" {
|
||||
template, _ = sjson.SetBytes(template, "service_tier", serviceTier)
|
||||
}
|
||||
template, _ = sjson.SetBytes(template, "stream", true)
|
||||
template, _ = sjson.SetBytes(template, "store", false)
|
||||
template, _ = sjson.SetBytes(template, "include", []string{"reasoning.encrypted_content"})
|
||||
@@ -334,6 +337,19 @@ func ConvertClaudeRequestToCodex(modelName string, inputRawJSON []byte, _ bool)
|
||||
return template
|
||||
}
|
||||
|
||||
func normalizeCodexServiceTier(result gjson.Result) string {
|
||||
if !result.Exists() || result.Type != gjson.String {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch strings.ToLower(strings.TrimSpace(result.String())) {
|
||||
case "fast", "priority":
|
||||
return "priority"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// shortenCodexCallIDIfNeeded keeps Claude tool IDs within the OpenAI Responses
|
||||
// API call_id limit while preserving a stable, low-collision mapping.
|
||||
func shortenCodexCallIDIfNeeded(id string) string {
|
||||
|
||||
@@ -148,6 +148,58 @@ func TestConvertClaudeRequestToCodex_ParallelToolCalls(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertClaudeRequestToCodex_ServiceTier(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
serviceTierJSON string
|
||||
want string
|
||||
wantExists bool
|
||||
}{
|
||||
{
|
||||
name: "Priority passes through",
|
||||
serviceTierJSON: `"priority"`,
|
||||
want: "priority",
|
||||
wantExists: true,
|
||||
},
|
||||
{
|
||||
name: "Fast normalizes to priority",
|
||||
serviceTierJSON: `"fast"`,
|
||||
want: "priority",
|
||||
wantExists: true,
|
||||
},
|
||||
{
|
||||
name: "Unsupported tier is omitted",
|
||||
serviceTierJSON: `"default"`,
|
||||
},
|
||||
{
|
||||
name: "Non-string tier is omitted",
|
||||
serviceTierJSON: `true`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
inputJSON := `{
|
||||
"model": "gpt-5.4",
|
||||
"service_tier": ` + tt.serviceTierJSON + `,
|
||||
"messages": [{"role": "user", "content": "Reply with OK"}]
|
||||
}`
|
||||
|
||||
result := ConvertClaudeRequestToCodex("gpt-5.4", []byte(inputJSON), false)
|
||||
serviceTierResult := gjson.GetBytes(result, "service_tier")
|
||||
if serviceTierResult.Exists() != tt.wantExists {
|
||||
t.Fatalf("service_tier exists = %v, want %v. Output: %s", serviceTierResult.Exists(), tt.wantExists, string(result))
|
||||
}
|
||||
if !tt.wantExists {
|
||||
return
|
||||
}
|
||||
if got := serviceTierResult.String(); got != tt.want {
|
||||
t.Fatalf("service_tier = %q, want %q. Output: %s", got, tt.want, string(result))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertClaudeRequestToCodex_ShortenLongToolUseIDs(t *testing.T) {
|
||||
longID := "toolu_" + strings.Repeat("a", 62)
|
||||
if len(longID) <= 64 {
|
||||
|
||||
Reference in New Issue
Block a user