fix: consistent handler_module_path for subdirectory tools#8679
fix: consistent handler_module_path for subdirectory tools#8679muhamedfazalps wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the add_llm_tools method in astrbot/core/star/context.py to support subdirectory tools by constructing a path matching the star_manager format when standard flags are not found in the module path. The reviewer suggested adding defensive checks to prevent potential AttributeError or IndexError in cases where tool.__module__ is missing, empty, or unexpected.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| 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"] |
There was a problem hiding this comment.
To prevent potential AttributeError or IndexError when tool.__module__ is None, empty, or otherwise unexpected, we should defensively check that tool.__module__ is a valid string and that module_part is not empty before accessing its first element.
| 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"] | |
| module_part = tool.__module__.split(".") if isinstance(getattr(tool, "__module__", None), str) else [] | |
| 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 and module_part and module_part[0]: | |
| # Subdirectory tool: construct path matching star_manager format | |
| plugin_name = module_part[0] | |
| _parts = ["data", "plugins", plugin_name, "main"] |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The fallback branch that sets
handler_module_pathfor cases where noplugins/builtin_starsflag is found unconditionally maps todata.plugins.<module_part[0]>.main; consider tightening this to only apply to known plugin naming patterns (e.g.,astrbot_plugin_...) to avoid misrouting non-plugin tools. - The logic for constructing
handler_module_path(both the flag-based path and the new fallback path) appears to mirrorstar_managerconventions; consider extracting this into a shared helper to keep the module path rules in one place and reduce the risk of future drift.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The fallback branch that sets `handler_module_path` for cases where no `plugins`/`builtin_stars` flag is found unconditionally maps to `data.plugins.<module_part[0]>.main`; consider tightening this to only apply to known plugin naming patterns (e.g., `astrbot_plugin_...`) to avoid misrouting non-plugin tools.
- The logic for constructing `handler_module_path` (both the flag-based path and the new fallback path) appears to mirror `star_manager` conventions; consider extracting this into a shared helper to keep the module path rules in one place and reduce the risk of future drift.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
…ge 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
Problem
Fixes #8578
When tools are in plugin subdirectories (e.g.
tools/,utils/),handler_module_pathwas missing thedata.plugins.prefix thatstar_manageruses. This brokestartswithmatching in deactivate/activate, disabling all subdirectory tools on reload.Root Cause
add_llm_tools()looks forpluginsorbuiltin_starsintool.__module__(e.g.astrbot_plugin_xxx.tools.safe_edit), but these flags don't exist in the module path for subdirectory tools.Fix
When the flag is not found, construct path as
data.plugins.<plugin_name>.mainto matchstar_managerformat.Testing
__init__.pystill workIf this fix helped you, consider buying me a coffee!
Summary by Sourcery
Bug Fixes: