fix(openai_cli): 支持非 function 类型 tool 的透传还原,保留 prompt_cache_key 字段

This commit is contained in:
fawney19
2026-02-21 02:32:32 +08:00
parent 314e4a497d
commit 457fe83a4f

View File

@@ -233,16 +233,23 @@ class OpenAICliNormalizer(FormatNormalizer):
if internal.tools: if internal.tools:
# Responses API 使用扁平结构: {type, name, description, parameters} # Responses API 使用扁平结构: {type, name, description, parameters}
# 而非 Chat Completions 的嵌套结构: {type, function: {name, ...}} # 而非 Chat Completions 的嵌套结构: {type, function: {name, ...}}
result["tools"] = [ rebuilt_tools: list[dict[str, Any]] = []
{ for t in internal.tools:
"type": "function", # 非 function 类型(如 custom/web_search直接还原原始 dict
"name": t.name, raw_tool = t.extra.get("openai_cli_raw_tool")
"description": t.description or "", if isinstance(raw_tool, dict):
"parameters": t.parameters or {}, rebuilt_tools.append(raw_tool)
**(t.extra.get("openai_tool") or {}), else:
} rebuilt_tools.append(
for t in internal.tools {
] "type": "function",
"name": t.name,
"description": t.description or "",
"parameters": t.parameters or {},
**(t.extra.get("openai_tool") or {}),
}
)
result["tools"] = rebuilt_tools
if internal.tool_choice: if internal.tool_choice:
result["tool_choice"] = self._tool_choice_to_openai(internal.tool_choice) result["tool_choice"] = self._tool_choice_to_openai(internal.tool_choice)
@@ -304,7 +311,6 @@ class OpenAICliNormalizer(FormatNormalizer):
# 删除 Codex 不支持的字段 # 删除 Codex 不支持的字段
for key in ( for key in (
"previous_response_id", "previous_response_id",
"prompt_cache_key",
"service_tier", "service_tier",
"max_completion_tokens", "max_completion_tokens",
): ):
@@ -1647,7 +1653,11 @@ class OpenAICliNormalizer(FormatNormalizer):
for tool in tools: for tool in tools:
if not isinstance(tool, dict): if not isinstance(tool, dict):
continue continue
if tool.get("type") == "function" and isinstance(tool.get("function"), dict):
tool_type = tool.get("type")
# 标准嵌套结构: {type: "function", function: {name, description, parameters}}
if tool_type == "function" and isinstance(tool.get("function"), dict):
fn = tool["function"] fn = tool["function"]
name = str(fn.get("name") or "") name = str(fn.get("name") or "")
if not name: if not name:
@@ -1669,7 +1679,30 @@ class OpenAICliNormalizer(FormatNormalizer):
) )
continue continue
# 兼容:部分实现可能直接给 {name, description, parameters} # 非 function 类型(如 type: "custom", "web_search" 等):保留原始 dict 以便透传还原
if tool_type and tool_type != "function":
if not tool.get("name"):
logger.debug(
"[OpenAICliNormalizer] 跳过无 name 的非 function tool: type={}",
tool_type,
)
continue
name = str(tool["name"])
out.append(
ToolDefinition(
name=name,
description=tool.get("description"),
parameters=(
tool.get("parameters")
if isinstance(tool.get("parameters"), dict)
else None
),
extra={"openai_cli_raw_tool": tool},
)
)
continue
# 兼容:扁平 function 结构 {name, description, parameters}(无 type 或 type=function
name = str(tool.get("name") or "") name = str(tool.get("name") or "")
if name: if name:
out.append( out.append(