fix tool use with function calling is unsupported error

This commit is contained in:
Toddy
2025-03-21 05:04:53 +00:00
parent b3a057b6ba
commit a8dc98ab6a
2 changed files with 48 additions and 24 deletions
+29 -8
View File
@@ -26,22 +26,43 @@ def _has_image_parts(contents: List[Dict[str, Any]]) -> bool:
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]: def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
"""构建工具""" """构建工具"""
tools = []
def _merge_tools(tools: List[Dict[str, Any]]) -> Dict[str, Any]:
record = dict()
for item in tools:
if not item or not isinstance(item, dict):
continue
for k, v in item.items():
if k == "functionDeclarations" and v and isinstance(v, list):
functions = record.get("functionDeclarations", [])
functions.extend(v)
record["functionDeclarations"] = functions
else:
record[k] = v
return record
tool = dict()
if payload and isinstance(payload, dict) and "tools" in payload:
items = payload.get("tools", [])
if items and isinstance(items, list):
tool.update(_merge_tools(items))
if ( if (
settings.TOOLS_CODE_EXECUTION_ENABLED settings.TOOLS_CODE_EXECUTION_ENABLED
and not (model.endswith("-search") or "-thinking" in model) and not (model.endswith("-search") or "-thinking" in model)
and not _has_image_parts(payload.get("contents", [])) and not _has_image_parts(payload.get("contents", []))
): ):
tools.append({"code_execution": {}}) tool["codeExecution"] = {}
if model.endswith("-search"): if model.endswith("-search"):
tools.append({"googleSearch": {}}) tool["googleSearch"] = {}
if payload and isinstance(payload, dict) and "tools" in payload: # 解决 "Tool use with function calling is unsupported" 问题
items = payload.get("tools", []) if tool.get("functionDeclarations"):
if items and isinstance(items, list): tool.pop("googleSearch", None)
tools.extend(items) tool.pop("codeExecution", None)
return tools return [tool]
def _get_safety_settings(model: str) -> List[Dict[str, str]]: def _get_safety_settings(model: str) -> List[Dict[str, str]]:
+19 -16
View File
@@ -31,7 +31,7 @@ def _build_tools(
request: ChatRequest, messages: List[Dict[str, Any]] request: ChatRequest, messages: List[Dict[str, Any]]
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
"""构建工具""" """构建工具"""
tools = [] tool = dict()
model = request.model model = request.model
if ( if (
@@ -44,23 +44,21 @@ def _build_tools(
) )
and not _has_image_parts(messages) and not _has_image_parts(messages)
): ):
tools.append({"code_execution": {}}) tool["codeExecution"] = {}
if model.endswith("-search"): if model.endswith("-search"):
tools.append({"googleSearch": {}}) tool["googleSearch"] = {}
# 将 request 中的 tools 合并到 tools 中 # 将 request 中的 tools 合并到 tools 中
if request.tools: if request.tools:
function_declarations = [] function_declarations = []
for tool in request.tools: for item in request.tools:
if not tool or not isinstance(tool, dict): if not item or not isinstance(item, dict):
continue continue
if tool.get("type", "") == "function" and tool.get("function"): if item.get("type", "") == "function" and item.get("function"):
function = deepcopy(tool.get("function")) function = deepcopy(item.get("function"))
parameters = function.get("parameters", {}) parameters = function.get("parameters", {})
if parameters.get("type") == "object" and not parameters.get( if parameters.get("type") == "object" and not parameters.get("properties", {}):
"properties", {}
):
function.pop("parameters", None) function.pop("parameters", None)
function_declarations.append(function) function_declarations.append(function)
@@ -68,14 +66,19 @@ def _build_tools(
if function_declarations: if function_declarations:
# 按照 function 的 name 去重 # 按照 function 的 name 去重
names, functions = set(), [] names, functions = set(), []
for item in function_declarations: for fc in function_declarations:
if item.get("name") not in names: if fc.get("name") not in names:
names.add(item.get("name")) names.add(fc.get("name"))
functions.append(item) functions.append(fc)
tools.append({"functionDeclarations": functions}) tool["functionDeclarations"] = functions
return tools # 解决 "Tool use with function calling is unsupported" 问题
if tool.get("functionDeclarations"):
tool.pop("googleSearch", None)
tool.pop("codeExecution", None)
return [tool]
def _get_safety_settings(model: str) -> List[Dict[str, str]]: def _get_safety_settings(model: str) -> List[Dict[str, str]]: