mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-09-07 16:56:36 +08:00
fix tool use with function calling is unsupported error
This commit is contained in:
@@ -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]]:
|
||||||
|
|||||||
@@ -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]]:
|
||||||
|
|||||||
Reference in New Issue
Block a user