From 736bc93b2a6dfd295f36efa81626a5e784e70ae0 Mon Sep 17 00:00:00 2001 From: MUHAMED FAZAL PS <107547381+muhamedfazalps@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:21:19 +0530 Subject: [PATCH 1/2] fix: consistent handler_module_path for subdirectory tools (#8578) --- astrbot/core/star/context.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/astrbot/core/star/context.py b/astrbot/core/star/context.py index 593bad9365..7bcffc6277 100644 --- a/astrbot/core/star/context.py +++ b/astrbot/core/star/context.py @@ -493,12 +493,18 @@ def add_llm_tools(self, *tools: FunctionTool) -> None: _parts = [] module_part = tool.__module__.split(".") flags = ["builtin_stars", "plugins"] + found_flag = False 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]) _parts.append("main") + found_flag = True break + if not found_flag: + # Subdirectory tool: construct path matching star_manager format + plugin_name = module_part[0] + _parts = ["data", "plugins", plugin_name, "main"] tool.handler_module_path = ".".join(_parts) module_path = tool.handler_module_path else: From 992aea9869f400c9c1f1e0093d5c144c76ddffbc Mon Sep 17 00:00:00 2001 From: MUHAMED FAZAL PS <107547381+muhamedfazalps@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:27:00 +0530 Subject: [PATCH 2/2] fix: address review feedback - add plugin naming pattern check and edge case handling Address feedback from Sourcery AI and Gemini Code Assist: - Only apply fallback path to known plugin naming patterns (astrbot_plugin_*) - Add defensive check for None/empty tool.__module__ - Fallback to tool.__module__ if _parts is empty --- astrbot/core/star/context.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/astrbot/core/star/context.py b/astrbot/core/star/context.py index 7bcffc6277..56007edf05 100644 --- a/astrbot/core/star/context.py +++ b/astrbot/core/star/context.py @@ -491,7 +491,7 @@ def add_llm_tools(self, *tools: FunctionTool) -> None: for tool in tools: if not module_path: _parts = [] - module_part = tool.__module__.split(".") + module_part = tool.__module__.split(".") if tool.__module__ else [] flags = ["builtin_stars", "plugins"] found_flag = False for i, part in enumerate(module_part): @@ -501,11 +501,13 @@ def add_llm_tools(self, *tools: FunctionTool) -> None: _parts.append("main") found_flag = True break - if not found_flag: + if not found_flag and module_part: # Subdirectory tool: construct path matching star_manager format + # Only apply to known plugin naming patterns (astrbot_plugin_*) plugin_name = module_part[0] - _parts = ["data", "plugins", plugin_name, "main"] - tool.handler_module_path = ".".join(_parts) + if plugin_name.startswith("astrbot_plugin_"): + _parts = ["data", "plugins", plugin_name, "main"] + tool.handler_module_path = ".".join(_parts) if _parts else tool.__module__ or "" module_path = tool.handler_module_path else: tool.handler_module_path = module_path