Coverage for agentos/tools/bridge.py: 78%
37 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-06 11:37 +0800
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-06 11:37 +0800
2"""
3Tool Bridge — 连接 ToolRegistry (BaseTool) 和 ToolExecutor (Tool + callable)。
5让 BaseTool 子类可以无缝注册到 ToolAgent 使用的 ToolExecutor 中。
6"""
7from __future__ import annotations
8import json, asyncio
9from typing import Callable
10from agentos.tools.base import BaseTool
11from agentos.tools.registry import ToolRegistry
12from agentos.llm.base import Tool as LLMTool, ToolFunction, ToolParameter
15def base_tool_to_llm_tool(tool: BaseTool) -> LLMTool:
16 """将 BaseTool 的 parameters schema 转换为 LLM Tool 对象。"""
17 params = tool.parameters or {"type": "object", "properties": {}, "required": []}
18 tool_params: dict[str, ToolParameter] = {}
19 required_list: list[str] = params.get("required", [])
21 for name, schema in params.get("properties", {}).items():
22 tool_params[name] = ToolParameter(
23 type=schema.get("type", "string"),
24 description=schema.get("description", ""),
25 enum=schema.get("enum"),
26 required=name in required_list,
27 )
29 return LLMTool(
30 function=ToolFunction(
31 name=tool.name,
32 description=tool.description,
33 parameters=tool_params,
34 required=required_list,
35 )
36 )
39def make_handler(tool: BaseTool) -> Callable[..., str]:
40 """创建适配 callable,让 ToolExecutor 能调用 BaseTool。"""
41 def sync_handler(**kwargs) -> str:
42 try:
43 loop = asyncio.get_event_loop()
44 if loop.is_running():
45 import concurrent.futures
46 with concurrent.futures.ThreadPoolExecutor() as executor:
47 future = executor.submit(asyncio.run, tool.execute(kwargs))
48 result = future.result(timeout=30)
49 else:
50 result = asyncio.run(tool.execute(kwargs))
51 except RuntimeError:
52 result = asyncio.run(tool.execute(kwargs))
54 if result.error:
55 return json.dumps({"error": result.error})
56 return result.output or ""
58 return sync_handler
61def bridge_registry_to_executor(registry: ToolRegistry, executor) -> None:
62 """将 ToolRegistry 中所有已注册的 BaseTool 桥接到 ToolExecutor。"""
63 for name in registry.list_names():
64 tool = registry.get(name)
65 if tool is None:
66 continue
67 llm_tool = base_tool_to_llm_tool(tool)
68 handler = make_handler(tool)
69 executor.register(llm_tool, handler)