@@ -165,3 +165,157 @@ export function apply(ctx: Context, config: Config) {
165165 - ` session ` - 当前会话对象
166166 - 返回:` Tool ` 实例
167167 - 用途:创建并返回工具的实例
168+ - ` meta ` : 工具元数据(推荐填写)
169+ - ` source ` : 工具来源
170+ - 常见值:` core ` 、` extension ` 、` mcp ` 、` action `
171+ - ` group ` : 工具所属分组
172+ - 如:` search ` 、` plugin-common `
173+ - ` tags ` : 工具标签列表
174+ - 用于分类、筛选和展示
175+ - ` defaultAvailability ` : 工具的默认可用性配置
176+ - ` enabled ` : 是否默认启用
177+ - ` main ` : 是否在主聊天模式中默认可用
178+ - ` chatluna ` : 是否在 ChatLuna 主能力中默认可用
179+ - ` characterScope ` : 是否在伪装插件中默认可用
180+ - ` all ` : 群聊和私聊都默认可用
181+ - ` group ` : 仅群聊默认可用
182+ - ` private ` : 仅私聊默认可用
183+ - ` none ` : 默认不在伪装插件中启用
184+
185+ ### 工具元数据
186+
187+ 当前 ChatLuna 的工具注册,通常都会补充 ` meta ` 字段。虽然它不是强制项,但推荐在开发插件时始终填写,便于工具系统、配置界面和其他上层功能正确识别工具来源、分组与默认启用范围。
188+
189+ 示例:
190+
191+ ``` ts
192+ plugin .registerTool (' web_search' , {
193+ description: SEARCH_TOOL_DESCRIPTION ,
194+ selector() {
195+ return true
196+ },
197+ createTool(params ) {
198+ return new SearchTool (... )
199+ },
200+ meta: {
201+ source: ' extension' ,
202+ group: ' search' ,
203+ tags: [' search' , ' web' ],
204+ defaultAvailability: {
205+ enabled: true ,
206+ main: true ,
207+ chatluna: true ,
208+ characterScope: ' all'
209+ }
210+ }
211+ })
212+ ```
213+
214+ 如果你的工具是为伪装插件的回复流程服务的,建议你明确设置 ` characterScope ` ,避免工具默认暴露到不合适的会话范围。
215+
216+ ## 为伪装插件的回复工具挂载自定义字段
217+
218+ [ chatluna-character] ( ../../ecosystem/other/character.md ) 伪装插件支持一种实验性的「工具调用回复」模式。在该模式下,模型不再通过 XML 块输出回复内容,而是通过调用一个名为 ` character_reply ` 的工具来完成状态更新、消息发送、触发条件设置等操作。
219+
220+ 外部插件可以通过 ` ctx.chatluna_character.registerReplyToolField() ` 方法,向 ` character_reply ` 工具注册额外的自定义参数字段。
221+
222+ > [ !TIP] 最佳实践
223+ > 建议只在此处注册与消息交互有关的能力,如:戳一戳、撤回消息等,因为它们几乎不需要模型查看工具返回的结果,并且更适合在模型完成消息回复时一起操作。
224+
225+ 当模型调用 ` character_reply ` 时,伪装插件会自动将这些自定义字段连同内置字段一起传递给模型,并在工具被调用时执行对应的回调。
226+
227+ ### CharacterReplyToolField 接口
228+
229+ 注册的字段需要符合 ` CharacterReplyToolField ` 接口:
230+
231+ ``` ts
232+ interface CharacterReplyToolField {
233+ /** 字段名称,将作为 character_reply 工具的参数名 */
234+ name: string
235+
236+ /** JSON Schema,描述该字段的类型与结构 */
237+ schema: Record <string , unknown >
238+
239+ /**
240+ * 可用性检查(可选)。
241+ * 返回 false 时,该字段不会出现在工具参数中,也不会被调用。
242+ */
243+ isAvailable? : (
244+ ctx : Context ,
245+ session : Session ,
246+ config : Config | GuildConfig | PrivateConfig
247+ ) => boolean
248+
249+ /**
250+ * 工具被调用时的回调。
251+ * 当模型在调用 character_reply 时传入了该字段的值,此回调会被执行。
252+ */
253+ invoke? : (
254+ ctx : Context ,
255+ session : Session ,
256+ value : unknown ,
257+ config : Config | GuildConfig | PrivateConfig
258+ ) => Promise <void > | void
259+
260+ /**
261+ * 渲染回调。
262+ * 将工具调用的结果转换为 XML 字符串,插入到 <action> 块中。
263+ * 用于将工具调用的输出回写到对话历史中,以便模型在后续轮次中看到之前的操作。
264+ */
265+ render? : (
266+ ctx : Context ,
267+ session : Session ,
268+ value : unknown ,
269+ config : Config | GuildConfig | PrivateConfig
270+ ) => string | string [] | undefined
271+ }
272+ ```
273+
274+ ### 注册字段
275+
276+ 调用 ` ctx.chatluna_character.registerReplyToolField() ` 注册字段。该方法返回一个注销函数,调用后可移除已注册的字段。
277+
278+ ``` ts
279+ import { Context } from ' koishi'
280+ import type {} from ' koishi-plugin-chatluna-character'
281+
282+ export function apply(ctx : Context ) {
283+ // 注册一个自定义字段
284+ const dispose = ctx .chatluna_character .registerReplyToolField ({
285+ name: ' poke' ,
286+
287+ schema: {
288+ type: ' string' ,
289+ description: ' Platform user ID to poke.'
290+ },
291+
292+ // 仅在非私聊的 OneBot 平台上可用
293+ isAvailable(ctx , session ) {
294+ return ! session .isDirect && session .platform === ' onebot'
295+ },
296+
297+ // 模型调用 character_reply 并传入 poke 字段时执行
298+ async invoke(ctx , session , value ) {
299+ if (typeof value !== ' string' ) return
300+ // 执行戳一戳操作……
301+ },
302+
303+ // 将工具调用结果渲染为 XML,写入对话历史
304+ render(ctx , session , value ) {
305+ if (typeof value !== ' string' ) return undefined
306+ return ` <poke user_id="${value }" /> `
307+ }
308+ })
309+
310+ // 插件卸载时自动注销
311+ ctx .on (' dispose' , dispose )
312+ }
313+ ```
314+
315+ ### 工作流程
316+
317+ 注册的字段会参与以下流程:
318+
319+ 1 . ** 构建工具参数** :伪装插件在创建 ` character_reply ` 工具时,遍历所有已注册字段,对通过 ` isAvailable ` 检查的字段,将其 ` schema ` 添加到工具的参数定义中。
320+ 2 . ** 执行回调** :当模型调用 ` character_reply ` 并传入了某个自定义字段的值时,伪装插件会调用该字段的 ` invoke ` 回调。
321+ 3 . ** 渲染到历史** :在将工具调用结果写入对话历史时,伪装插件会调用每个字段的 ` render ` 回调,将返回的 XML 字符串插入到 ` <action> ` 块中,使模型在后续轮次中可以看到之前的操作记录。
0 commit comments