This commit is contained in:
2026-02-26 13:43:44 +08:00
parent 2c2db92ae9
commit 68200cdfe6
51 changed files with 2107 additions and 351 deletions
+5 -5
View File
@@ -3,25 +3,25 @@ from langchain_core.tools import BaseTool
class CalculatorTool(BaseTool):
"""A simple calculator tool for mathematical operations"""
"""用于数学运算的简单计算器工具"""
name: str = "calculator"
description: str = "Perform mathematical calculations. Input should be a mathematical expression like '2 + 2' or '10 * (3 + 5)'"
def _run(self, expression: str) -> str:
"""Evaluate a mathematical expression"""
"""计算数学表达式"""
try:
# Security: Only allow safe mathematical operations
# 安全:仅允许安全的数学运算
allowed_chars = set("0123456789+-*/(). ")
if not all(c in allowed_chars for c in expression):
return "Error: Expression contains invalid characters"
# Evaluate the expression
# 计算表达式
result = eval(expression)
return f"Result: {result}"
except Exception as e:
return f"Error calculating expression: {str(e)}"
async def _arun(self, expression: str) -> str:
"""Async version of the tool"""
"""工具的异步版本"""
return self._run(expression)
+89
View File
@@ -0,0 +1,89 @@
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}"
+99
View File
@@ -0,0 +1,99 @@
import json
from typing import Any, Dict
import httpx
from langchain_core.tools import BaseTool
from config import Config
class SrApiQueryTool(BaseTool):
"""调用 SR API 执行 SQL 查询"""
name: str = "sr_api_query"
description: str = (
"调用 SR API 执行 SQL 查询。输入为 JSON 字符串,示例:"
'{"sql":"SELECT * FROM table","page":1,"rows":10,"orderBySelect":true,"timeout":30}'
)
def _run(self, payload: str) -> str:
"""执行 SQL 查询"""
try:
data = json.loads(payload)
except Exception as e:
return f"请求参数解析失败: {e}"
sql = data.get("sql")
page = int(data.get("page", 1))
rows = int(data.get("rows", 10))
order_by_select = bool(data.get("orderBySelect", True))
timeout = float(data.get("timeout", 30))
if not sql:
return "缺少 sql"
cfg = Config.get_section("sr_api")
url = cfg.get("url")
app_key = cfg.get("llzappkey")
secret_key = cfg.get("llzsercret")
if not url or not app_key or not secret_key:
return "sr_api 配置缺失 url/llzAppkey/llzSercret"
headers = {"llzAppkey": app_key, "llzSercret": secret_key}
body = {"sql": sql, "page": page, "rows": rows, "orderBySelect": order_by_select}
try:
with httpx.Client(timeout=timeout) as client:
response = client.post(url, json=body, headers=headers)
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}"
sql = data.get("sql")
page = int(data.get("page", 1))
rows = int(data.get("rows", 10))
order_by_select = bool(data.get("orderBySelect", True))
timeout = float(data.get("timeout", 30))
if not sql:
return "缺少 sql"
cfg = Config.get_section("sr_api")
url = cfg.get("url")
app_key = cfg.get("llzappkey")
secret_key = cfg.get("llzsercret")
if not url or not app_key or not secret_key:
return "sr_api 配置缺失 url/llzAppkey/llzSercret"
headers = {"llzAppkey": app_key, "llzSercret": secret_key}
body = {"sql": sql, "page": page, "rows": rows, "orderBySelect": order_by_select}
try:
async with httpx.AsyncClient(timeout=timeout) as client:
response = await client.post(url, json=body, headers=headers)
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}"
+9 -9
View File
@@ -4,22 +4,22 @@ import requests
class WebSearchTool(BaseTool):
"""A tool for searching the web (placeholder implementation)"""
"""网络搜索工具(占位实现)"""
name: str = "web_search"
description: str = "Search the web for information. Input should be a search query."
def _run(self, query: str) -> str:
"""Search the web for information"""
# This is a placeholder implementation
# In a real implementation, you would integrate with a search API
# like Serper, Tavily, or Google Search API
"""搜索网络信息"""
# 这是占位实现
# 真实实现需接入搜索 API
# 如 Serper、Tavily 或 Google Search API
return f"Web search functionality for query: '{query}' is not implemented. This is a placeholder. To implement real web search, you would need to:
return f"""Web search functionality for query: '{query}' is not implemented. This is a placeholder. To implement real web search, you would need to:
1. Sign up for a search API service (e.g., Serper, Tavily)
2. Add your API key to the .env file
3. Implement the actual search logic here"
2. Add your API key to the config/config.ini file
3. Implement the actual search logic here"""
async def _arun(self, query: str) -> str:
"""Async version of the tool"""
"""工具的异步版本"""
return self._run(query)