Suppress debug logs for model routing and ignore empty tools arrays

- Comment out verbose routing logs in the API server to reduce noise.
- Remove the `tools` field from Qwen client requests when it is an empty array.
- Add guards in Claude, Codex, Gemini‑CLI, and Gemini translators to skip tool conversion when the `tools` array is empty, preventing unnecessary payload modifications.
This commit is contained in:
Luis Pater
2025-08-27 22:29:08 +08:00
parent 1c4183d943
commit 7a6adfa97e
6 changed files with 11 additions and 6 deletions

View File

@@ -140,10 +140,10 @@ func (s *Server) unifiedModelsHandler(openaiHandler *openai.OpenAIAPIHandler, cl
// Route to Claude handler if User-Agent starts with "claude-cli"
if strings.HasPrefix(userAgent, "claude-cli") {
log.Debugf("Routing /v1/models to Claude handler for User-Agent: %s", userAgent)
// log.Debugf("Routing /v1/models to Claude handler for User-Agent: %s", userAgent)
claudeHandler.ClaudeModels(c)
} else {
log.Debugf("Routing /v1/models to OpenAI handler for User-Agent: %s", userAgent)
// log.Debugf("Routing /v1/models to OpenAI handler for User-Agent: %s", userAgent)
openaiHandler.OpenAIModels(c)
}
}

View File

@@ -329,6 +329,11 @@ func (c *QwenClient) APIRequest(ctx context.Context, modelName, endpoint string,
}
}
toolsResult := gjson.GetBytes(jsonBody, "tools")
if toolsResult.IsArray() && len(toolsResult.Array()) == 0 {
jsonBody, _ = sjson.DeleteBytes(jsonBody, "tools")
}
streamResult := gjson.GetBytes(jsonBody, "stream")
if streamResult.Exists() && streamResult.Type == gjson.True {
jsonBody, _ = sjson.SetBytes(jsonBody, "stream_options.include_usage", true)

View File

@@ -244,7 +244,7 @@ func ConvertOpenAIRequestToClaude(modelName string, rawJSON []byte, stream bool)
}
// Tools mapping: OpenAI tools -> Claude Code tools
if tools := root.Get("tools"); tools.Exists() && tools.IsArray() {
if tools := root.Get("tools"); tools.Exists() && tools.IsArray() && len(tools.Array()) > 0 {
var anthropicTools []interface{}
tools.ForEach(func(_, tool gjson.Result) bool {
if tool.Get("type").String() == "function" {

View File

@@ -231,7 +231,7 @@ func ConvertOpenAIRequestToCodex(modelName string, rawJSON []byte, stream bool)
// Map tools (flatten function fields)
tools := gjson.GetBytes(rawJSON, "tools")
if tools.IsArray() {
if tools.IsArray() && len(tools.Array()) > 0 {
out, _ = sjson.SetRaw(out, "tools", `[]`)
arr := tools.Array()
for i := 0; i < len(arr); i++ {

View File

@@ -215,7 +215,7 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, rawJSON []byte, _ bool) [
// tools -> request.tools[0].functionDeclarations
tools := gjson.GetBytes(rawJSON, "tools")
if tools.IsArray() {
if tools.IsArray() && len(tools.Array()) > 0 {
out, _ = sjson.SetRawBytes(out, "request.tools", []byte(`[{"functionDeclarations":[]}]`))
fdPath := "request.tools.0.functionDeclarations"
for _, t := range tools.Array() {

View File

@@ -215,7 +215,7 @@ func ConvertOpenAIRequestToGemini(modelName string, rawJSON []byte, _ bool) []by
// tools -> tools[0].functionDeclarations
tools := gjson.GetBytes(rawJSON, "tools")
if tools.IsArray() {
if tools.IsArray() && len(tools.Array()) > 0 {
out, _ = sjson.SetRawBytes(out, "tools", []byte(`[{"functionDeclarations":[]}]`))
fdPath := "tools.0.functionDeclarations"
for _, t := range tools.Array() {