feat: add Tool component

This commit is contained in:
Junyan Qin
2025-07-06 21:03:33 +08:00
parent a60aa6f644
commit 5b044a1917
11 changed files with 84 additions and 66 deletions
+20 -43
View File
@@ -4,9 +4,7 @@ import typing
import traceback
from .. import loader
from ....plugin import context as plugin_context
import langbot_plugin.api.entities.builtin.resource.tool as resource_tool
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
@loader.loader_class('plugin-tool-loader')
@@ -16,63 +14,42 @@ class PluginToolLoader(loader.ToolLoader):
本加载器中不存储工具信息,仅负责从插件系统中获取工具信息。
"""
async def get_tools(self, enabled: bool = True) -> list[resource_tool.LLMTool]:
async def get_tools(self) -> list[resource_tool.LLMTool]:
# 从插件系统获取工具(内容函数)
all_functions: list[resource_tool.LLMTool] = []
for plugin in self.ap.plugin_mgr.plugins(
enabled=enabled, status=plugin_context.RuntimeContainerStatus.INITIALIZED
):
all_functions.extend(plugin.tools)
for tool in await self.ap.plugin_connector.list_tools():
tool_obj = resource_tool.LLMTool(
name=tool.metadata.name,
human_desc=tool.metadata.description.en_US,
description=tool.spec['llm_prompt'],
parameters=tool.spec['parameters'],
func=lambda parameters: {},
)
all_functions.append(tool_obj)
return all_functions
async def has_tool(self, name: str) -> bool:
"""检查工具是否存在"""
for plugin in self.ap.plugin_mgr.plugins(
enabled=True, status=plugin_context.RuntimeContainerStatus.INITIALIZED
):
for function in plugin.tools:
if function.name == name:
return True
for tool in await self.ap.plugin_connector.list_tools():
if tool.metadata.name == name:
return True
return False
async def _get_function_and_plugin(
self, name: str
) -> typing.Tuple[resource_tool.LLMTool, plugin_context.BasePlugin]:
"""获取函数和插件实例"""
for plugin in self.ap.plugin_mgr.plugins(
enabled=True, status=plugin_context.RuntimeContainerStatus.INITIALIZED
):
for function in plugin.tools:
if function.name == name:
return function, plugin.plugin_inst
return None, None
async def _get_tool(self, name: str) -> resource_tool.LLMTool:
for tool in await self.ap.plugin_connector.list_tools():
if tool.metadata.name == name:
return tool
return None
async def invoke_tool(self, query: pipeline_query.Query, name: str, parameters: dict) -> typing.Any:
async def invoke_tool(self, name: str, parameters: dict) -> typing.Any:
try:
function, plugin = await self._get_function_and_plugin(name)
if function is None:
return None
parameters = parameters.copy()
parameters = {'query': query, **parameters}
return await function.func(plugin, **parameters)
return await self.ap.plugin_connector.call_tool(name, parameters)
except Exception as e:
self.ap.logger.error(f'执行函数 {name} 时发生错误: {e}')
traceback.print_exc()
return f'error occurred when executing function {name}: {e}'
finally:
plugin = None
for p in self.ap.plugin_mgr.plugins():
if function in p.tools:
plugin = p
break
# TODO statistics
async def shutdown(self):
"""关闭工具"""