import json from typing import Any, Dict import httpx from langchain_core.tools import BaseTool class RestApiTool(BaseTool): """RESTful API 调用工具""" name: str = "rest_api" description: str = ( "调用 RESTful API。输入为 JSON 字符串,示例:" '{"method":"GET","url":"https://example.com/api","params":{},"headers":{},"body":null,"timeout":30}' ) def _run(self, payload: str) -> str: """执行 RESTful API 请求""" try: data = json.loads(payload) except Exception as e: return f"请求参数解析失败: {e}" method = str(data.get("method", "GET")).upper() url = data.get("url") params: Dict[str, Any] = data.get("params") or {} headers: Dict[str, Any] = data.get("headers") or {} body = data.get("body") timeout = float(data.get("timeout", 30)) if not url: return "缺少 url" try: with httpx.Client(timeout=timeout) as client: response = client.request( method=method, url=url, params=params, headers=headers, json=body, ) return json.dumps( { "status_code": response.status_code, "headers": dict(response.headers), "text": response.text, }, ensure_ascii=False, ) except Exception as e: return f"请求失败: {e}" async def _arun(self, payload: str) -> str: """工具的异步版本""" try: data = json.loads(payload) except Exception as e: return f"请求参数解析失败: {e}" method = str(data.get("method", "GET")).upper() url = data.get("url") params: Dict[str, Any] = data.get("params") or {} headers: Dict[str, Any] = data.get("headers") or {} body = data.get("body") timeout = float(data.get("timeout", 30)) if not url: return "缺少 url" try: async with httpx.AsyncClient(timeout=timeout) as client: response = await client.request( method=method, url=url, params=params, headers=headers, json=body, ) return json.dumps( { "status_code": response.status_code, "headers": dict(response.headers), "text": response.text, }, ensure_ascii=False, ) except Exception as e: return f"请求失败: {e}"