From 5a25b9d78bed03ca142e56d5fc2a8f5e420f0825 Mon Sep 17 00:00:00 2001 From: LgCookie Date: Wed, 17 Dec 2025 21:56:25 +0800 Subject: [PATCH 1/2] fix #4097 --- astrbot/core/star/context.py | 21 +++------------------ astrbot/core/star/star_manager.py | 16 ++++++++-------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/astrbot/core/star/context.py b/astrbot/core/star/context.py index 9a52ec8bc..880542120 100644 --- a/astrbot/core/star/context.py +++ b/astrbot/core/star/context.py @@ -368,25 +368,10 @@ async def send_message( def add_llm_tools(self, *tools: FunctionTool) -> None: """添加 LLM 工具。""" tool_name = {tool.name for tool in self.provider_manager.llm_tools.func_list} - module_path = "" for tool in tools: - if not module_path: - _parts = [] - module_part = tool.__module__.split(".") - flags = ["packages", "plugins"] - for i, part in enumerate(module_part): - _parts.append(part) - if part in flags and i + 1 < len(module_part): - _parts.append(module_part[i + 1]) - break - tool.handler_module_path = ".".join(_parts) - module_path = tool.handler_module_path - else: - tool.handler_module_path = module_path - logger.info( - f"plugin(module_path {module_path}) added LLM tool: {tool.name}" - ) - + # Set `handler_module_path` moved to astrbot/core/star/star_manager.py, + # search `ft.__module__ == metadata.module_path` + logger.info(f"plugin added LLM tool: {tool.name} ({tool.__module__})") if tool.name in tool_name: logger.warning("替换已存在的 LLM 工具: " + tool.name) self.provider_manager.llm_tools.remove_func(tool.name) diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index 1f9f95ae5..ced91e736 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -515,15 +515,15 @@ async def load(self, specified_module_path=None, specified_dir_name=None): need_apply = [func_tool] for ft in need_apply: - if ( - ft.handler - and ft.handler.__module__ == metadata.module_path - ): + if ft.handler: + if ft.handler.__module__ == metadata.module_path: + ft.handler_module_path = metadata.module_path + ft.handler = functools.partial( + ft.handler, + metadata.star_cls, # type: ignore + ) + elif ft.__module__ == metadata.module_path: ft.handler_module_path = metadata.module_path - ft.handler = functools.partial( - ft.handler, - metadata.star_cls, # type: ignore - ) if ft.name in inactivated_llm_tools: ft.active = False From 56a954cef7fbc7847f8ae4eed9926b0abd95ebca Mon Sep 17 00:00:00 2001 From: LgCookie Date: Wed, 17 Dec 2025 22:30:29 +0800 Subject: [PATCH 2/2] make tools registered via `Context.add_llm_tools` show in web panel --- astrbot/core/star/context.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/astrbot/core/star/context.py b/astrbot/core/star/context.py index 880542120..ac1e72d01 100644 --- a/astrbot/core/star/context.py +++ b/astrbot/core/star/context.py @@ -1,3 +1,4 @@ +import asyncio import logging from asyncio import Queue from collections.abc import Awaitable, Callable @@ -375,6 +376,17 @@ def add_llm_tools(self, *tools: FunctionTool) -> None: if tool.name in tool_name: logger.warning("替换已存在的 LLM 工具: " + tool.name) self.provider_manager.llm_tools.remove_func(tool.name) + + # create a fake empty awaitable hander to register the tool into handler registry + # then it can show in the web panel + from astrbot.core.star.register.star_handler import get_handler_or_create + + fake_handler = lambda: asyncio.sleep(0) # noqa: E731 + fake_handler.__name__ = tool.name + fake_handler.__module__ = tool.__module__ + fake_handler.__doc__ = tool.description + get_handler_or_create(fake_handler, EventType.OnCallingFuncToolEvent) + self.provider_manager.llm_tools.func_list.append(tool) def register_web_api(