S1-DeepResearch-32B / inference /server /tool_execution.py
ScienceOne-AI's picture
Upload 61 files
816198f verified
Raw
History Blame Contribute Delete
3.06 kB
from typing import Any, Tuple
import json
import asyncio
import os
import uuid
import importlib.util
from pathlib import Path
from utils.configs import USE_NLP_FORMAT_RETURN
async def execute_tool_call(name: Any, arguments: Any, all_tools, logger=None, USE_NLP_FORMAT_RETURN: bool | None = None, query_id = "") -> Tuple[str, str]:
"""
Execute a single tool call locally. Returns (tool_name, tool_response_json_str).
"""
if USE_NLP_FORMAT_RETURN is None:
USE_NLP_FORMAT_RETURN = USE_NLP_FORMAT_RETURN
if name == "parse_error_tool_call":
if USE_NLP_FORMAT_RETURN:
result = f"Error: Tool call is not a valid JSON. Tool call must contain a valid \"name\" and \"arguments\" field. Parse error: {arguments.get('parse_error', '')}"
else:
result = json.dumps({"error": f"Parse error: {arguments.get('parse_error', '')}", "raw": arguments.get('raw', '')}, ensure_ascii=False)
if logger:
logger.error(result)
return name or "parse_error_tool_call", result
tool = all_tools.get(name)
if tool is None:
result = json.dumps({"error": f"Unknown tool: {name}"}, ensure_ascii=False)
if logger:
logger.error(result)
return name or "unknown", result
# Ensure arguments is a dict
if not isinstance(arguments, dict):
arguments = {"_": arguments}
import functools
loop = asyncio.get_running_loop()
arguments["conversation_id"] = query_id
func = functools.partial(tool['function'], **arguments)
# 根据工具名称选择不同的超时时间
if name == "browse_url":
timeout = 5400 # browse 是 1.5 小时
else:
timeout = 1800 # 其他工具就是 30 分钟
try:
out = await asyncio.wait_for(loop.run_in_executor(None, func), timeout=timeout)
result = out if isinstance(out, str) else json.dumps(out, ensure_ascii=False) # 返回结果一定是字符串
except asyncio.TimeoutError:
if USE_NLP_FORMAT_RETURN:
result = f"The tool call timed out: execution exceeded {timeout} seconds for tool '{name}'."
else:
result = json.dumps({"error": f"Tool call timeout: exceeded {timeout}s", "tool": name, "arguments": arguments}, ensure_ascii=False)
if logger:
logger.error(result)
except TypeError as te:
if USE_NLP_FORMAT_RETURN:
result = f"Tool '{name}' failed due to argument mismatch: {str(te)}. Input arguments: {arguments}."
else:
result = json.dumps({"error": f"Argument mismatch for tool '{name}': {str(te)}", "received": arguments}, ensure_ascii=False)
if logger:
logger.error(result)
except Exception as e:
if USE_NLP_FORMAT_RETURN:
result = f"Tool '{name}' encountered an error: {str(e)}."
else:
result = json.dumps({"error": f"Tool '{name}' raised an exception: {str(e)}"}, ensure_ascii=False)
if logger:
logger.error(result)
return name, result