-
-
Notifications
You must be signed in to change notification settings - Fork 41
feat(extension-tools): refactor command tools to unified interface #649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…nd execute interface Replaced per-command tool registration (N tools) with two unified tools: - command_search: Search and list available Koishi commands with fuzzy matching - command_execute: Execute commands using plain text Koishi command syntax Features: - Advanced fuzzy matching algorithm supporting partial matches (e.g., "shot" matches "screenshot") - Alias support: Commands can now be searched by their aliases - Multi-keyword search with scoring and ranking - Add commandAutoExecute option to allow commands to run without confirmation (disabled by default for safety) Breaking Changes: - Command tools are no longer registered individually - Tools now use plain text command syntax instead of structured parameters
Walkthrough在配置接口中新增布尔字段 Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 分钟 需要额外关注的点:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/extension-tools/src/plugins/command.ts (2)
160-212: 考虑提取匹配分数为命名常量匹配算法逻辑清晰,但建议将分数值提取为命名常量,以提高可维护性和可读性。
const MATCH_SCORES = { EXACT: 100, WORD_EXACT: 90, PREFIX: 80, WORD_PREFIX: 70, CONTAINS: 60, WORD_CONTAINS: 50, REVERSE_CONTAINS: 40 } as const
396-414: 建议记录未知内容类型对于未知的内容类型,当前实现静默返回空字符串。建议添加日志以便调试潜在问题。
if ('image_url' in part) { // ... existing code } - return '' + // Log unknown content type for debugging + this.ctx.logger.debug('Unknown content part type: %o', part) + return ''
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
packages/extension-tools/src/locales/en-US.schema.ymlis excluded by!**/*.ymlpackages/extension-tools/src/locales/zh-CN.schema.ymlis excluded by!**/*.yml
📒 Files selected for processing (2)
packages/extension-tools/src/config.ts(2 hunks)packages/extension-tools/src/plugins/command.ts(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension-tools/src/plugins/command.ts (2)
packages/core/src/llm-core/platform/types.ts (1)
ChatLunaToolRunnable(107-115)packages/core/src/command.ts (1)
command(15-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: lint
🔇 Additional comments (4)
packages/extension-tools/src/config.ts (1)
155-159: 安全配置实现良好!该配置项的设计合理:
- 默认值设为
false是正确的安全默认值- 危险警告描述清晰地告知用户风险
- 正确放置在
command: Schema.const(true).required()分支内,只在启用命令功能时才显示packages/extension-tools/src/plugins/command.ts (3)
30-37: 确认 selector 逻辑是否符合预期
selector始终返回true,意味着这两个工具将始终对模型可用。考虑到原设计中单个命令有各自的selector配置,请确认这是预期行为。如果需要保留基于上下文的选择逻辑,可以考虑在工具调用时检查命令级别的 selector。
219-312: CommandSearchTool 实现良好!搜索工具的实现设计合理:
- 支持多关键词搜索
- 按相关性评分排序
- 输出格式清晰,包含别名、参数和选项信息
- 友好的空结果提示
381-381: Remove this review comment — the interpretation of the second parameter is incorrect.The second parameter in
session.execute(command, true)is aNextcallback for Koishi's middleware chain, not a flag to enable chained command execution. Passingtrueallows the executed command to continue the middleware/next chain. This is standard Koishi behavior and does not introduce command chaining security risks.Likely an incorrect or invalid review comment.
… in command execution - Remove console.log(commandList) debug statement that should not be in production - Fix matchedCommand finder to properly support command alias matching - Ensure aliases are checked for exact, prefix, and namespace matches just like primary command names - This fixes the issue where commands invoked via aliases (e.g., "ss" for "screenshot") would not match and cause null matchedCommand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/extension-tools/src/plugins/command.ts (1)
312-439: CommandExecuteTool 基本逻辑合理,但 baseCommandName 与错误信息有两个边界问题需要修正
- baseCommandName 未 trim 会在前导空格时失效
当前写法:对输入const baseCommandName = command.split(/\s+/)[0]" help"这样的字符串,split结果首元素是空串,导致matchedCommand永远为undefined,进而总是走默认的confirm: true分支(即使配置了某些命令confirm: false)。建议在split前先trim():
const baseCommandName = command.split(/\s+/)[0]
const baseCommandName = command.trim().split(/\s+/)[0]
- 异常信息直接使用
e.message在非 Error 场景下可能是undefined
这里catch (e)未声明类型,如果上游抛出的是字符串或普通对象,e.message可能为undefined,返回的错误信息就不友好:建议安全地归一化错误信息:return `Failed to execute command "${command}". Error: ${e.message}`
} catch (e) {this.ctx.logger.error(e)return `Failed to execute command "${command}". Error: ${e.message}`}
} catch (e) {this.ctx.logger.error(e)const errorMessage =e instanceof Error ? e.message : String(e)return `Failed to execute command "${command}". Error: ${errorMessage}`}另外,新版对
alias的匹配(含子命令前缀)已经覆盖了之前 review 中提到的别名场景,这点很好。
🧹 Nitpick comments (4)
packages/extension-tools/src/plugins/command.ts (4)
27-50: 统一注册 command_search / command_execute 的实现整体合理,但 commandList 为静态快照
commandList在apply阶段构建一次后直接闭包进两个工具,后续如果 Koishi 运行时有动态注册/卸载命令,搜索/执行工具将看不到最新变更。如果你预期命令集合在插件生命周期内基本固定,这样没问题;否则可以考虑在createTool()里延迟调用getCommandList或在工具内部提供刷新机制,以减少列表过期的风险。
91-100: alias 构建逻辑依赖 Koishi 私有字段,升级时可能易碎这里通过
ctx.$commander._commandList和cmd._aliases取命令及别名,属于 Koishi 的内部实现细节,未来升级时可能静默失效。建议:
- 如有公开 API(例如公开的 commands 列表或 alias 字段),优先改用公开接口;
- 如果目前只能用内部字段,最好加一条注释说明“依赖 Koishi 内部字段
_commandList/_aliases”,方便后续升级重点检查。当前
Object.keys(cmd._aliases)生成 alias 数组并透传进PickCommandType的逻辑本身是合理的。
147-210: matchCommand 注释示例与实现略有出入,可顺便防御空 keyword
- “Reverse check” 部分注释写的是
"screenshot" contains "shot",但实现是lowerKeyword.includes(lowerTarget),实际对应的是“长 keyword 包含短 target”(例如 keyword"screenshot command"命中 target"screenshot")。建议把注释示例改成和实现一致,避免后续阅读误解。- 为防止空字符串意外让所有 target 都得到分数,可以在函数开头对
keyword.trim()为空的情况直接返回0或在调用前过滤掉空 keyword。算法本身的分段打分设计清晰易懂,这里主要是可读性与健壮性的小优化。
217-309: CommandSearchTool 输出设计良好,但可更健壮地处理 arguments/options,并确认是否要继续尊重 selector
- 如果某些命令 JSON 中的
arguments或options是可选字段,当前直接调用cmd.arguments.map(...)/cmd.options.filter(...)在它们为undefined时会抛异常。建议增加兜底:const args = (cmd.arguments ?? []).map(...) const opts = (cmd.options ?? []) .filter((opt) => opt.name !== 'help') .map(...)- 现在搜索结果不再根据
selector做过滤,等于所有在commandList里的命令都会被列出;与旧版“按命令单独注册 tool + selector”相比是行为变化。确认这是否是有意而为(只靠confirm和全局配置控制风险),还是希望在搜索阶段就按当前会话 / preset 等条件利用selector过滤掉不适用的命令。整体上包含 alias、参数和选项说明的长描述对 LLM 非常友好,这块设计方向是对的。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
packages/extension-tools/package.jsonis excluded by!**/*.json
📒 Files selected for processing (1)
packages/extension-tools/src/plugins/command.ts(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension-tools/src/plugins/command.ts (3)
packages/core/src/llm-core/platform/types.ts (1)
ChatLunaToolRunnable(107-115)packages/core/src/command.ts (1)
command(15-29)packages/service-search/src/providers/wikipedia.ts (1)
content(173-183)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: lint
🔇 Additional comments (1)
packages/extension-tools/src/plugins/command.ts (1)
456-461: PickCommandType 新增 alias 字段与上游使用保持一致
alias?: string[]与getCommandList中构造的alias以及 CommandSearchTool / CommandExecuteTool 中的访问方式完全对齐,类型定义合理,没有发现问题。
Summary
Refactored the command tools from registering N individual tools (one per command) to just 2 unified tools with improved search and execution capabilities.
Changes
New Tools
Key Features
commandAutoExecuteconfig option (Breaking Changes
Technical Details