refactor(antigravity): 提取并同步 Schema 清理逻辑至 schema_cleaner.go
主要变更: 1. 重构代码结构: - 将 CleanJSONSchema 及其相关辅助函数从 request_transformer.go 提取到独立的 schema_cleaner.go 文件中,实现逻辑解耦。 2. 逻辑优化与修正: - 参考 Antigravity-Manager (json_schema.rs) 的实现逻辑,修正了 Schema 清洗策略。
This commit is contained in:
@@ -1320,6 +1320,14 @@ func (s *AntigravityGatewayService) ForwardGemini(ctx context.Context, c *gin.Co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 清理 Schema
|
||||
if cleanedBody, err := cleanGeminiRequest(injectedBody); err == nil {
|
||||
injectedBody = cleanedBody
|
||||
log.Printf("[Antigravity] Cleaned request schema in forwarded request for account %s", account.Name)
|
||||
} else {
|
||||
log.Printf("[Antigravity] Failed to clean schema: %v", err)
|
||||
}
|
||||
|
||||
// 包装请求
|
||||
wrappedBody, err := s.wrapV1InternalRequest(projectID, mappedModel, injectedBody)
|
||||
if err != nil {
|
||||
@@ -1752,6 +1760,19 @@ func (s *AntigravityGatewayService) handleGeminiStreamingResponse(c *gin.Context
|
||||
if u := extractGeminiUsage(parsed); u != nil {
|
||||
usage = u
|
||||
}
|
||||
// Check for MALFORMED_FUNCTION_CALL
|
||||
if candidates, ok := parsed["candidates"].([]any); ok && len(candidates) > 0 {
|
||||
if cand, ok := candidates[0].(map[string]any); ok {
|
||||
if fr, ok := cand["finishReason"].(string); ok && fr == "MALFORMED_FUNCTION_CALL" {
|
||||
log.Printf("[Antigravity] MALFORMED_FUNCTION_CALL detected in forward stream")
|
||||
if content, ok := cand["content"]; ok {
|
||||
if b, err := json.Marshal(content); err == nil {
|
||||
log.Printf("[Antigravity] Malformed content: %s", string(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if firstTokenMs == nil {
|
||||
@@ -1901,6 +1922,20 @@ func (s *AntigravityGatewayService) handleGeminiStreamToNonStreaming(c *gin.Cont
|
||||
usage = u
|
||||
}
|
||||
|
||||
// Check for MALFORMED_FUNCTION_CALL
|
||||
if candidates, ok := parsed["candidates"].([]any); ok && len(candidates) > 0 {
|
||||
if cand, ok := candidates[0].(map[string]any); ok {
|
||||
if fr, ok := cand["finishReason"].(string); ok && fr == "MALFORMED_FUNCTION_CALL" {
|
||||
log.Printf("[Antigravity] MALFORMED_FUNCTION_CALL detected in forward non-stream collect")
|
||||
if content, ok := cand["content"]; ok {
|
||||
if b, err := json.Marshal(content); err == nil {
|
||||
log.Printf("[Antigravity] Malformed content: %s", string(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保留最后一个有 parts 的响应
|
||||
if parts := extractGeminiParts(parsed); len(parts) > 0 {
|
||||
lastWithParts = parsed
|
||||
@@ -2541,3 +2576,55 @@ func isImageGenerationModel(model string) bool {
|
||||
modelLower == "gemini-2.5-flash-image-preview" ||
|
||||
strings.HasPrefix(modelLower, "gemini-2.5-flash-image-")
|
||||
}
|
||||
|
||||
// cleanGeminiRequest 清理 Gemini 请求体中的 Schema
|
||||
func cleanGeminiRequest(body []byte) ([]byte, error) {
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(body, &payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
modified := false
|
||||
|
||||
// 1. 清理 Tools
|
||||
if tools, ok := payload["tools"].([]any); ok && len(tools) > 0 {
|
||||
for _, t := range tools {
|
||||
toolMap, ok := t.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// function_declarations (snake_case) or functionDeclarations (camelCase)
|
||||
var funcs []any
|
||||
if f, ok := toolMap["functionDeclarations"].([]any); ok {
|
||||
funcs = f
|
||||
} else if f, ok := toolMap["function_declarations"].([]any); ok {
|
||||
funcs = f
|
||||
}
|
||||
|
||||
if len(funcs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, f := range funcs {
|
||||
funcMap, ok := f.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if params, ok := funcMap["parameters"].(map[string]any); ok {
|
||||
antigravity.DeepCleanUndefined(params)
|
||||
cleaned := antigravity.CleanJSONSchema(params)
|
||||
funcMap["parameters"] = cleaned
|
||||
modified = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !modified {
|
||||
return body, nil
|
||||
}
|
||||
|
||||
return json.Marshal(payload)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user