mirror of
https://github.com/router-for-me/CLIProxyAPIPlus.git
synced 2026-03-09 15:25:17 +00:00
fix(translator): remove broken type uppercasing in OpenAI Responses-to-Gemini translator
The `ConvertOpenAIResponsesRequestToGemini` function had code that attempted to uppercase JSON Schema type values (e.g. "string" -> "STRING") for Gemini compatibility. This broke nullable types because when `type` is a JSON array like `["string", "null"]`: 1. `gjson.Result.String()` returns the raw JSON text `["string","null"]` 2. `strings.ToUpper()` produces `["STRING","NULL"]` 3. `sjson.Set()` stores it as a JSON **string** `"[\"STRING\",\"NULL\"]"` instead of a JSON array 4. The downstream `CleanJSONSchemaForGemini()` / `flattenTypeArrays()` cannot detect it (since `IsArray()` returns false on a string) 5. Gemini/Antigravity API rejects it with: `400 Invalid value at '...type' (Type), "["STRING","NULL"]"` This was confirmed and tested with Droid Factory (Antigravity) Gemini models where Claude Code sends tool schemas with nullable parameters. The fix removes the uppercasing logic entirely and passes the raw schema through to `parametersJsonSchema`. This is safe because: - Antigravity executor already runs `CleanJSONSchemaForGemini()` which properly handles type arrays, nullable fields, and all schema cleanup - Gemini/Vertex executors use `parametersJsonSchema` which accepts raw JSON Schema directly (no uppercasing needed) - The uppercasing code also only iterated top-level properties, missing nested schemas entirely Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -330,22 +330,7 @@ func ConvertOpenAIResponsesRequestToGemini(modelName string, inputRawJSON []byte
|
||||
funcDecl, _ = sjson.Set(funcDecl, "description", desc.String())
|
||||
}
|
||||
if params := tool.Get("parameters"); params.Exists() {
|
||||
// Convert parameter types from OpenAI format to Gemini format
|
||||
cleaned := params.Raw
|
||||
// Convert type values to uppercase for Gemini
|
||||
paramsResult := gjson.Parse(cleaned)
|
||||
if properties := paramsResult.Get("properties"); properties.Exists() {
|
||||
properties.ForEach(func(key, value gjson.Result) bool {
|
||||
if propType := value.Get("type"); propType.Exists() {
|
||||
upperType := strings.ToUpper(propType.String())
|
||||
cleaned, _ = sjson.Set(cleaned, "properties."+key.String()+".type", upperType)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
// Set the overall type to OBJECT
|
||||
cleaned, _ = sjson.Set(cleaned, "type", "OBJECT")
|
||||
funcDecl, _ = sjson.SetRaw(funcDecl, "parametersJsonSchema", cleaned)
|
||||
funcDecl, _ = sjson.SetRaw(funcDecl, "parametersJsonSchema", params.Raw)
|
||||
}
|
||||
|
||||
geminiTools, _ = sjson.SetRaw(geminiTools, "0.functionDeclarations.-1", funcDecl)
|
||||
|
||||
Reference in New Issue
Block a user