@@ -286,10 +286,50 @@ def _normalize_tools_for_internal_api(tools: Any) -> Any:
286286 return normalized_tools
287287
288288
289- def _ensure_empty_tool_schema_for_claude (tools : Any , model_name : str ) -> Any :
289+ def _ensure_empty_tool_schema_for_claude (tools : Any , model_name : str , mode : str = "geminicli" ) -> Any :
290290 if "claude" not in (model_name or "" ).lower () or not isinstance (tools , list ):
291291 return tools
292292
293+ # antigravity 通道(Vertex AI)的 Claude 模型不认识 Anthropic 原生的
294+ # {"custom": {...}} 包装(会报 "Unknown name \"custom\": Cannot find field"),
295+ # 仍然使用标准 Gemini functionDeclarations/parametersJsonSchema 格式,
296+ # 这里只需确保 schema 非空即可。
297+ if mode == "antigravity" :
298+ normalized_tools = []
299+ for tool in tools :
300+ if not isinstance (tool , dict ):
301+ normalized_tools .append (tool )
302+ continue
303+
304+ normalized_tool = tool .copy ()
305+ declarations = normalized_tool .get ("functionDeclarations" )
306+ if declarations is None :
307+ declarations = normalized_tool .get ("function_declarations" )
308+ if isinstance (declarations , list ):
309+ normalized_declarations = []
310+ for declaration in declarations :
311+ if not isinstance (declaration , dict ):
312+ normalized_declarations .append (declaration )
313+ continue
314+
315+ normalized_declaration = declaration .copy ()
316+ schema = (
317+ normalized_declaration .get ("parametersJsonSchema" )
318+ or normalized_declaration .pop ("parameters_json_schema" , None )
319+ or normalized_declaration .get ("parameters" )
320+ or {"type" : "object" , "properties" : {}}
321+ )
322+ normalized_declaration .pop ("parameters" , None )
323+ normalized_declaration ["parametersJsonSchema" ] = schema
324+ normalized_declarations .append (normalized_declaration )
325+
326+ normalized_tool .pop ("function_declarations" , None )
327+ normalized_tool ["functionDeclarations" ] = normalized_declarations
328+
329+ normalized_tools .append (normalized_tool )
330+
331+ return normalized_tools
332+
293333 normalized_tools = []
294334 for tool in tools :
295335 if not isinstance (tool , dict ):
@@ -785,10 +825,11 @@ async def normalize_gemini_request(
785825 # 1. 安全设置覆盖
786826 if "tools" in result :
787827 result ["tools" ] = _normalize_tools_for_internal_api (result .get ("tools" ))
788- # Claude models (both GeminiCLI internal API and Vertex AI / antigravity mode)
789- # expect tools wrapped in Anthropic-native {"custom": {..., "input_schema": ...}}
790- # blocks rather than functionDeclarations/parametersJsonSchema.
791- result ["tools" ] = _ensure_empty_tool_schema_for_claude (result .get ("tools" ), model )
828+ # GeminiCLI 内部 API 的 Claude 模型需要 Anthropic 原生
829+ # {"custom": {..., "input_schema": ...}} 格式;antigravity/Vertex AI
830+ # 通道的 Claude 模型则仍使用标准的
831+ # functionDeclarations/parametersJsonSchema 格式。
832+ result ["tools" ] = _ensure_empty_tool_schema_for_claude (result .get ("tools" ), model , mode )
792833
793834 if "lite" in model .lower ():
794835 result ["safetySettings" ] = LITE_SAFETY_SETTINGS
0 commit comments