From 9956770cb004ec068840d9ea0976f93ee77044c0 Mon Sep 17 00:00:00 2001 From: CJACK Date: Sun, 1 Feb 2026 16:08:56 +0800 Subject: [PATCH] 1 --- core/sse_parser.py | 34 ++++++++++++++++++++++++++++++++++ routes/openai.py | 45 +++++---------------------------------------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/core/sse_parser.py b/core/sse_parser.py index 8963607..481c872 100644 --- a/core/sse_parser.py +++ b/core/sse_parser.py @@ -414,3 +414,37 @@ def should_filter_citation(text: str, search_enabled: bool) -> bool: if not search_enabled: return False return _CITATION_PATTERN.match(text) is not None + + +# ---------------------------------------------------------------------- +# 工具调用格式化 +# ---------------------------------------------------------------------- + +def format_openai_tool_calls( + detected_tools: List[Dict[str, Any]], + base_id: str = "" +) -> List[Dict[str, Any]]: + """将检测到的工具调用格式化为 OpenAI API 格式 + + Args: + detected_tools: parse_tool_calls 返回的工具调用列表 + base_id: 用于生成唯一 ID 的基础字符串(可选) + + Returns: + OpenAI 格式的 tool_calls 数组,例如: + [{"id": "call_xxx", "type": "function", "function": {"name": "...", "arguments": "..."}}] + """ + import random + import time + + tool_calls_data = [] + for idx, tool_info in enumerate(detected_tools): + tool_calls_data.append({ + "id": f"call_{base_id or int(time.time())}_{random.randint(1000,9999)}_{idx}", + "type": "function", + "function": { + "name": tool_info["name"], + "arguments": json.dumps(tool_info.get("input", {}), ensure_ascii=False) + } + }) + return tool_calls_data diff --git a/routes/openai.py b/routes/openai.py index ab67b9b..5063ec9 100644 --- a/routes/openai.py +++ b/routes/openai.py @@ -31,6 +31,7 @@ from core.sse_parser import ( extract_content_recursive, should_filter_citation, parse_tool_calls, + format_openai_tool_calls, ) from core.constants import ( KEEP_ALIVE_TIMEOUT, @@ -321,16 +322,7 @@ IMPORTANT: If calling tools, output ONLY the JSON. The response must start with if detected_tools: # 发送工具调用响应 - tool_calls_data = [] - for idx, tool_info in enumerate(detected_tools): - tool_calls_data.append({ - "id": f"call_{int(time.time())}_{random.randint(1000,9999)}_{idx}", - "type": "function", - "function": { - "name": tool_info["name"], - "arguments": json.dumps(tool_info["input"], ensure_ascii=False) - } - }) + tool_calls_data = format_openai_tool_calls(detected_tools) tool_chunk = { "id": completion_id, "object": "chat.completion.chunk", @@ -420,16 +412,7 @@ IMPORTANT: If calling tools, output ONLY the JSON. The response must start with finish_reason = "tool_calls" if detected_tools: - tool_calls_data = [] - for idx, tool_info in enumerate(detected_tools): - tool_calls_data.append({ - "id": f"call_{int(time.time())}_{random.randint(1000,9999)}_{idx}", - "type": "function", - "function": { - "name": tool_info["name"], - "arguments": json.dumps(tool_info["input"], ensure_ascii=False) - } - }) + tool_calls_data = format_openai_tool_calls(detected_tools) tool_chunk = { "id": completion_id, "object": "chat.completion.chunk", @@ -534,16 +517,7 @@ IMPORTANT: If calling tools, output ONLY the JSON. The response must start with message_obj["reasoning_content"] = final_reasoning # 添加工具调用 if detected_tools: - tool_calls_data = [] - for idx, tool_info in enumerate(detected_tools): - tool_calls_data.append({ - "id": f"call_{int(time.time())}_{random.randint(1000,9999)}_{idx}", - "type": "function", - "function": { - "name": tool_info["name"], - "arguments": json.dumps(tool_info["input"], ensure_ascii=False) - } - }) + tool_calls_data = format_openai_tool_calls(detected_tools) message_obj["tool_calls"] = tool_calls_data message_obj["content"] = None @@ -608,16 +582,7 @@ IMPORTANT: If calling tools, output ONLY the JSON. The response must start with message_obj["reasoning_content"] = final_reasoning # 添加工具调用 if detected_tools: - tool_calls_data = [] - for idx, tool_info in enumerate(detected_tools): - tool_calls_data.append({ - "id": f"call_{int(time.time())}_{random.randint(1000,9999)}_{idx}", - "type": "function", - "function": { - "name": tool_info["name"], - "arguments": json.dumps(tool_info["input"], ensure_ascii=False) - } - }) + tool_calls_data = format_openai_tool_calls(detected_tools) message_obj["tool_calls"] = tool_calls_data message_obj["content"] = None