koishi-plugin-chatluna-toolbox 0.0.17 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  为 ChatLuna 提供可组合的工具能力,当前包含三类功能:
4
4
 
5
5
  - 原生工具(Native Tools)
6
- - XML 工具(XML Actions)
6
+ - Character XML 工具(XML Actions)
7
7
  - 变量扩展(Variables)
8
8
 
9
9
  插件目标是把常用的群聊动作能力(如戳一戳、消息表情、撤回消息)和上下文变量能力拆分为可配置模块,便于在 Koishi + ChatLuna 场景中按需启用。
@@ -21,7 +21,7 @@
21
21
 
22
22
  QQ 头像工具会把 HTTP/HTTPS 图片先转为 OneBot `base64://` 文件再提交,避免 OneBot 端无法访问 Koishi 临时图片地址。
23
23
 
24
- ### 2) XML 工具
24
+ ### 2) Character XML 工具
25
25
  支持从模型输出中解析 XML 动作标签并执行:
26
26
 
27
27
  - `<poke id="..."/>`
@@ -49,11 +49,11 @@ QQ 头像工具会把 HTTP/HTTPS 图片先转为 OneBot `base64://` 文件再提
49
49
 
50
50
  - 开启一个 OneBot 协议(NapCat 或 LLBot)
51
51
  - 按需开启原生工具
52
- - 按需开启 XML 工具
52
+ - 按需开启 Character XML 工具
53
53
  - 按需配置变量项
54
54
 
55
55
  ### 3. 配置 XML 参考提示词
56
- 在 `XML 工具` 分组中找到 `参考提示词`,可直接使用默认模板,或根据你的 Bot 规则进行调整。
56
+ 在 `Character XML 工具` 分组中找到 `参考提示词`,可直接使用默认模板,或根据你的 Bot 规则进行调整。
57
57
 
58
58
  ### 4. 构建
59
59
 
@@ -8,8 +8,8 @@ import type { SharedNavSection } from "shared-nav";
8
8
  export const NAV_SECTIONS: SharedNavSection[] = [
9
9
  { title: "基础设置", key: "basic" },
10
10
  { title: "原生工具", key: "nativeTools" },
11
- { title: "XML 工具", key: "xmlTools" },
12
- { title: "其他变量", key: "variables" },
11
+ { title: "Character XML 工具", key: "xmlTools" },
12
+ { title: "变量", key: "variables" },
13
13
  { title: "其他设置", key: "other" },
14
14
  ];
15
15
 
package/dist/index.js CHANGED
@@ -234,8 +234,8 @@ const st = /* @__PURE__ */ b({
234
234
  }, gt = /* @__PURE__ */ M(st, [["__cssModules", ht]]), pt = [
235
235
  { title: "基础设置", key: "basic" },
236
236
  { title: "原生工具", key: "nativeTools" },
237
- { title: "XML 工具", key: "xmlTools" },
238
- { title: "其他变量", key: "variables" },
237
+ { title: "Character XML 工具", key: "xmlTools" },
238
+ { title: "变量", key: "variables" },
239
239
  { title: "其他设置", key: "other" }
240
240
  ], mt = [
241
241
  "chatluna-toolbox",
package/lib/index.js CHANGED
@@ -421,6 +421,7 @@ __export(index_exports, {
421
421
  createLogger: () => createLogger,
422
422
  createPokeTool: () => createPokeTool,
423
423
  createRandomProvider: () => createRandomProvider,
424
+ createSearchGroupMemberTool: () => createSearchGroupMemberTool,
424
425
  createSetGroupBanTool: () => createSetGroupBanTool,
425
426
  createSetGroupCardTool: () => createSetGroupCardTool,
426
427
  createSetGroupSpecialTitleTool: () => createSetGroupSpecialTitleTool,
@@ -440,6 +441,7 @@ __export(index_exports, {
440
441
  registerVariables: () => registerVariables,
441
442
  registerXmlTools: () => registerXmlTools,
442
443
  resolveOneBotProtocol: () => resolveOneBotProtocol,
444
+ searchGroupMember: () => searchGroupMember,
443
445
  sendDeleteMessage: () => sendDeleteMessage,
444
446
  sendGroupBan: () => sendGroupBan,
445
447
  sendMsgEmoji: () => sendMsgEmoji,
@@ -447,7 +449,8 @@ __export(index_exports, {
447
449
  sendSetGroupCard: () => sendSetGroupCard,
448
450
  sendSetGroupSpecialTitle: () => sendSetGroupSpecialTitle,
449
451
  sendSetProfile: () => sendSetProfile,
450
- sendSetQQAvatar: () => sendSetQQAvatar
452
+ sendSetQQAvatar: () => sendSetQQAvatar,
453
+ usage: () => usage
451
454
  });
452
455
  module.exports = __toCommonJS(index_exports);
453
456
 
@@ -471,101 +474,81 @@ var DEFAULT_POKE_TOOL_DESCRIPTION = "\u5BF9\u6307\u5B9A\u7528\u6237\u6267\u884C\
471
474
  var DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION = "\u4FEE\u6539\u81EA\u5DF1\u7684 QQ \u8D44\u6599\uFF0C\u53EF\u8BBE\u7F6E\u6635\u79F0\u3001\u7B7E\u540D\u548C\u6027\u522B\u3002";
472
475
  var DEFAULT_SET_QQ_AVATAR_TOOL_DESCRIPTION = "\u4FEE\u6539\u673A\u5668\u4EBA QQ \u5934\u50CF\u3002\u63D0\u4F9B imageUrl\uFF1BHTTP/HTTPS \u56FE\u7247\u4F1A\u5148\u7531 Koishi \u8BFB\u53D6\u5E76\u8F6C\u4E3A OneBot base64 \u6587\u4EF6\uFF0C\u907F\u514D\u4E34\u65F6 URL \u8FC7\u671F\u6216 OneBot \u7AEF\u65E0\u6CD5\u8BBF\u95EE\u3002";
473
476
  var DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION = "\u4FEE\u6539\u7FA4\u6210\u5458\u7684\u7FA4\u6635\u79F0\u3002";
477
+ var DEFAULT_SEARCH_GROUP_MEMBER_TOOL_DESCRIPTION = "\u6839\u636E qqid \u7CBE\u786E\u67E5\u8BE2\u7FA4\u6210\u5458\u7684\u7FA4\u6635\u79F0\u4E0E QQ \u6635\u79F0\uFF0C\u6216\u6839\u636E\u7FA4\u6635\u79F0/QQ \u6635\u79F0\u641C\u7D22 qqid\u3002\u9ED8\u8BA4\u67E5\u8BE2\u5F53\u524D\u7FA4\u804A\uFF0C\u53EF\u901A\u8FC7 groupId \u67E5\u8BE2\u6307\u5B9A\u7FA4\u3002";
474
478
  var DEFAULT_SET_GROUP_BAN_TOOL_DESCRIPTION = "\u7528\u4E8E\u7BA1\u7406\u7FA4\u6210\u5458\u7981\u8A00\u72B6\u6001\uFF0C\u53EF\u8BBE\u7F6E\u7981\u8A00\u65F6\u957F\u6216\u89E3\u9664\u7981\u8A00\u3002";
475
479
  var DEFAULT_SET_GROUP_SPECIAL_TITLE_TOOL_DESCRIPTION = "\u4FEE\u6539\u6216\u6E05\u9664\u7FA4\u6210\u5458\u7684 QQ \u7FA4\u4E13\u5C5E\u5934\u8854\u3002";
476
480
  var DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION = "\u5BF9\u6307\u5B9A\u6D88\u606F\u6DFB\u52A0\u8868\u60C5\u56DE\u5E94\u3002";
477
481
  var DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION = "\u6839\u636E\u6D88\u606F ID \u64A4\u56DE\u6307\u5B9A\u6D88\u606F\u3002";
478
482
 
479
483
  // src/schema/native-tools.ts
480
- var NativeToolsSchema = import_koishi2.Schema.object({
484
+ var EnabledNativeToolsSchema = import_koishi2.Schema.array(
485
+ import_koishi2.Schema.union([
486
+ import_koishi2.Schema.const("poke").description("\u6233\u4E00\u6233"),
487
+ import_koishi2.Schema.const("setSelfProfile").description("\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F"),
488
+ import_koishi2.Schema.const("setQQAvatar").description("\u4FEE\u6539 QQ \u5934\u50CF"),
489
+ import_koishi2.Schema.const("setGroupCard").description("\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0"),
490
+ import_koishi2.Schema.const("searchGroupMember").description("\u641C\u7D22\u7FA4\u6210\u5458"),
491
+ import_koishi2.Schema.const("setGroupBan").description("\u7981\u8A00\u7FA4\u6210\u5458"),
492
+ import_koishi2.Schema.const("setGroupSpecialTitle").description("\u4FEE\u6539\u7FA4\u6210\u5458\u4E13\u5C5E\u5934\u8854"),
493
+ import_koishi2.Schema.const("setMsgEmoji").description("\u6D88\u606F\u8868\u60C5"),
494
+ import_koishi2.Schema.const("deleteMessage").description("\u64A4\u56DE\u6D88\u606F")
495
+ ])
496
+ ).role("checkbox").extra("default", void 0).description(
497
+ "\u9009\u62E9\u8981\u6CE8\u518C\u5230 ChatLuna \u7684\u539F\u751F\u5DE5\u5177\uFF0C\u5DE5\u5177\u540D\u79F0\u548C\u63CF\u8FF0\u901A\u5E38\u65E0\u9700\u4FEE\u6539\uFF0C\u53EF\u5728\u4E0B\u65B9\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u8C03\u6574"
498
+ );
499
+ var NativeToolAdvancedSettingsSchema = import_koishi2.Schema.object({
481
500
  poke: import_koishi2.Schema.object({
482
- enabled: import_koishi2.Schema.boolean().default(false).description(`\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u6233\u4E00\u6233\uFF0C\u4E0E**XML \u6233\u4E00\u6233\u8C03\u7528**\u4E8C\u9009\u4E00`),
501
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
483
502
  toolName: import_koishi2.Schema.string().default("poke_user").description("\u5DE5\u5177\u540D\u79F0"),
484
503
  description: import_koishi2.Schema.string().default(DEFAULT_POKE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
485
504
  }).description("\u6233\u4E00\u6233\u5DE5\u5177").collapse(),
486
505
  setSelfProfile: import_koishi2.Schema.object({
487
- enabled: import_koishi2.Schema.boolean().default(false).description(
488
- `\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F\uFF0C\u652F\u6301\u6635\u79F0 / \u7B7E\u540D / \u6027\u522B`
489
- ),
506
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
490
507
  toolName: import_koishi2.Schema.string().default("set_self_profile").description("\u5DE5\u5177\u540D\u79F0"),
491
508
  description: import_koishi2.Schema.string().default(DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
492
509
  }).description("\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F\u5DE5\u5177").collapse(),
493
510
  setQQAvatar: import_koishi2.Schema.object({
494
- enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u4FEE\u6539\u673A\u5668\u4EBA QQ \u5934\u50CF"),
511
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
495
512
  toolName: import_koishi2.Schema.string().default("set_qq_avatar").description("\u5DE5\u5177\u540D\u79F0"),
496
513
  description: import_koishi2.Schema.string().default(DEFAULT_SET_QQ_AVATAR_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
497
514
  }).description("\u4FEE\u6539 QQ \u5934\u50CF\u5DE5\u5177").collapse(),
498
515
  setGroupCard: import_koishi2.Schema.object({
499
- enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0"),
516
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
500
517
  toolName: import_koishi2.Schema.string().default("set_group_card").description("\u5DE5\u5177\u540D\u79F0"),
501
518
  description: import_koishi2.Schema.string().default(DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
502
519
  }).description("\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0\u5DE5\u5177").collapse(),
520
+ searchGroupMember: import_koishi2.Schema.object({
521
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
522
+ toolName: import_koishi2.Schema.string().default("search_group_member").description("\u5DE5\u5177\u540D\u79F0"),
523
+ description: import_koishi2.Schema.string().default(DEFAULT_SEARCH_GROUP_MEMBER_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
524
+ }).description("\u641C\u7D22\u7FA4\u6210\u5458\u5DE5\u5177").collapse(),
503
525
  setGroupBan: import_koishi2.Schema.object({
504
- enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u7981\u8A00\u7FA4\u6210\u5458"),
526
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
505
527
  toolName: import_koishi2.Schema.string().default("set_group_ban").description("\u5DE5\u5177\u540D\u79F0"),
506
528
  description: import_koishi2.Schema.string().default(DEFAULT_SET_GROUP_BAN_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
507
529
  }).description("\u7981\u8A00\u5DE5\u5177").collapse(),
508
530
  setGroupSpecialTitle: import_koishi2.Schema.object({
509
- enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u4FEE\u6539\u7FA4\u6210\u5458\u4E13\u5C5E\u5934\u8854"),
531
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
510
532
  toolName: import_koishi2.Schema.string().default("set_group_special_title").description("\u5DE5\u5177\u540D\u79F0"),
511
533
  description: import_koishi2.Schema.string().default(DEFAULT_SET_GROUP_SPECIAL_TITLE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
512
534
  }).description("\u4FEE\u6539\u7FA4\u6210\u5458\u4E13\u5C5E\u5934\u8854\u5DE5\u5177").collapse(),
513
535
  setMsgEmoji: import_koishi2.Schema.object({
514
- enabled: import_koishi2.Schema.boolean().default(false).description(
515
- `\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u7ED9\u6D88\u606F\u6DFB\u52A0\u8868\u60C5\uFF0C\u9700\`chatluna-character\`\u5F00\u542F\`enableMessageId\`\uFF0C\u4E0E**XML \u8868\u60C5\u56DE\u5E94\u8C03\u7528**\u4E8C\u9009\u4E00\uFF0C\u70B9\u51FB\u67E5\u770B[\u8868\u60C5\u5BF9\u7167\u8868](https://bot.q.qq.com/wiki/develop/pythonsdk/model/emoji.html)`
516
- ),
536
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
517
537
  toolName: import_koishi2.Schema.string().default("set_msg_emoji").description("\u5DE5\u5177\u540D\u79F0"),
518
538
  description: import_koishi2.Schema.string().default(DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
519
539
  }).description("\u6D88\u606F\u8868\u60C5\u5DE5\u5177").collapse(),
520
540
  deleteMessage: import_koishi2.Schema.object({
521
- enabled: import_koishi2.Schema.boolean().default(false).description(
522
- `\u6CE8\u518C ChatLuna \u539F\u751F\u5DE5\u5177\uFF1A\u64A4\u56DE\u6D88\u606F\uFF0C\u9700\`chatluna-character\`\u5F00\u542F\`enableMessageId\`\uFF0C\u4E0E**XML \u6D88\u606F\u64A4\u56DE\u8C03\u7528**\u4E8C\u9009\u4E00`
523
- ),
541
+ enabled: import_koishi2.Schema.boolean().default(false).hidden(),
524
542
  toolName: import_koishi2.Schema.string().default("delete_msg").description("\u5DE5\u5177\u540D\u79F0"),
525
543
  description: import_koishi2.Schema.string().default(DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
526
544
  }).description("\u64A4\u56DE\u6D88\u606F\u5DE5\u5177").collapse()
527
- }).default({
528
- poke: {
529
- enabled: false,
530
- toolName: "poke_user",
531
- description: DEFAULT_POKE_TOOL_DESCRIPTION
532
- },
533
- setSelfProfile: {
534
- enabled: false,
535
- toolName: "set_self_profile",
536
- description: DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION
537
- },
538
- setQQAvatar: {
539
- enabled: false,
540
- toolName: "set_qq_avatar",
541
- description: DEFAULT_SET_QQ_AVATAR_TOOL_DESCRIPTION
542
- },
543
- setGroupCard: {
544
- enabled: false,
545
- toolName: "set_group_card",
546
- description: DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION
547
- },
548
- setGroupBan: {
549
- enabled: false,
550
- toolName: "set_group_ban",
551
- description: DEFAULT_SET_GROUP_BAN_TOOL_DESCRIPTION
552
- },
553
- setGroupSpecialTitle: {
554
- enabled: false,
555
- toolName: "set_group_special_title",
556
- description: DEFAULT_SET_GROUP_SPECIAL_TITLE_TOOL_DESCRIPTION
557
- },
558
- setMsgEmoji: {
559
- enabled: false,
560
- toolName: "set_msg_emoji",
561
- description: DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION
562
- },
563
- deleteMessage: {
564
- enabled: false,
565
- toolName: "delete_msg",
566
- description: DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION
567
- }
568
- }).description("\u539F\u751F\u5DE5\u5177");
545
+ }).description("\u9AD8\u7EA7\u8BBE\u7F6E").collapse();
546
+ var NativeToolsSchema = import_koishi2.Schema.intersect([
547
+ import_koishi2.Schema.object({
548
+ enabledNativeTools: EnabledNativeToolsSchema
549
+ }).description(""),
550
+ NativeToolAdvancedSettingsSchema
551
+ ]).description("\u539F\u751F\u5DE5\u5177");
569
552
 
570
553
  // src/schema/xml-tools.ts
571
554
  var import_koishi3 = require("koishi");
@@ -620,7 +603,7 @@ var XmlToolsSchema = import_koishi3.Schema.object({
620
603
  `\u542F\u7528 XML \u7FA4\u6210\u5458\u7981\u8A00\u8C03\u7528\uFF0C\u4E0E**\u7981\u8A00\u5DE5\u5177**\u4E8C\u9009\u4E00`
621
604
  ),
622
605
  referencePrompt: import_koishi3.Schema.string().role("textarea").default(DEFAULT_XML_REFERENCE_PROMPT).description("\u6A21\u578B\u56DE\u590D XML \u53C2\u8003\u63D0\u793A\u8BCD\u3002\u81EA\u884C\u5199\u5165\u63D0\u793A\u8BCD\u4E2D\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u6CE8\u5165\uFF1B\u82E5\u5F00\u542F\u201C\u5C06 XML \u5DE5\u5177\u6CE8\u5165\u5B9E\u9A8C\u6027[\u5DE5\u5177\u8C03\u7528\u56DE\u590D](https://chatluna.chat/ecosystem/other/character.html#%E9%A2%84%E8%AE%BE)\u7684\u53C2\u6570\u4E2D\u201D\uFF0C\u5219\u65E0\u9700\u589E\u52A0\u989D\u5916\u63D0\u793A\u8BCD")
623
- }).description("XML \u5DE5\u5177");
606
+ }).description("Character XML \u5DE5\u5177");
624
607
 
625
608
  // src/schema/variables.ts
626
609
  var import_koishi4 = require("koishi");
@@ -716,7 +699,7 @@ var VariablesSchema = import_koishi4.Schema.object({
716
699
  },
717
700
  groupShutList: { variableName: "groupShutList" },
718
701
  random: { variableName: "random", min: 0, max: 100 }
719
- }).description("\u5176\u4ED6\u53D8\u91CF");
702
+ }).description("\u53D8\u91CF");
720
703
 
721
704
  // src/schema/index.ts
722
705
  var OtherSettingsSchema = import_koishi5.Schema.object({
@@ -930,10 +913,135 @@ function createPokeTool(deps) {
930
913
  }();
931
914
  }
932
915
 
933
- // src/features/native-tools/tools/set-group-ban.ts
916
+ // src/features/native-tools/tools/search-group-member.ts
934
917
  var import_zod3 = require("zod");
935
918
  var import_tools3 = require("@langchain/core/tools");
919
+ var MAX_RESULTS = 10;
920
+ function pickFirst(...values) {
921
+ for (const value of values) {
922
+ if (value === null || value === void 0) continue;
923
+ const text = String(value).trim();
924
+ if (text) return text;
925
+ }
926
+ return "";
927
+ }
936
928
  function resolveGroupId(session, groupId) {
929
+ return groupId?.trim() || session.guildId?.trim() || (session.event?.guild?.id || "");
930
+ }
931
+ function normalizeId(value) {
932
+ return /^\d+$/.test(value) ? Number(value) : value;
933
+ }
934
+ function getUserId(member) {
935
+ return pickFirst(
936
+ member.user_id,
937
+ member.userId,
938
+ member.id,
939
+ member.qq,
940
+ member.uid
941
+ );
942
+ }
943
+ function getGroupCard(member) {
944
+ return pickFirst(member.card, member.remark, member.displayName);
945
+ }
946
+ function getNickname(member) {
947
+ return pickFirst(
948
+ member.nick,
949
+ member.nickname,
950
+ member.name,
951
+ member.user?.nickname,
952
+ member.user?.name
953
+ );
954
+ }
955
+ function matchByName(member, query) {
956
+ const keyword = query.toLowerCase();
957
+ return [getGroupCard(member), getNickname(member)].filter(Boolean).some((value) => value.toLowerCase().includes(keyword));
958
+ }
959
+ async function fetchGroupMembers(session, groupId) {
960
+ const internal = session.bot.internal;
961
+ if (!internal) return [];
962
+ if (typeof internal.getGroupMemberList === "function") {
963
+ const result = await internal.getGroupMemberList(normalizeId(groupId));
964
+ return Array.isArray(result) ? result : [];
965
+ }
966
+ if (typeof internal._request === "function") {
967
+ const result = await internal._request("get_group_member_list", {
968
+ group_id: normalizeId(groupId)
969
+ });
970
+ if (Array.isArray(result)) return result;
971
+ const data = result?.data;
972
+ return Array.isArray(data) ? data : [];
973
+ }
974
+ throw new Error("\u5F53\u524D OneBot \u9002\u914D\u5668\u4E0D\u652F\u6301 get_group_member_list \u63A5\u53E3\u3002");
975
+ }
976
+ function formatMember(index, member) {
977
+ const userId = getUserId(member) || "\u672A\u77E5";
978
+ const groupCard = getGroupCard(member) || "\u65E0";
979
+ const nickname = getNickname(member) || "\u65E0";
980
+ return `${index}. qqid\uFF1A${userId}\uFF0C\u7FA4\u6635\u79F0\uFF1A${groupCard}\uFF0CQQ\u6635\u79F0\uFF1A${nickname}`;
981
+ }
982
+ async function searchGroupMember(params) {
983
+ try {
984
+ const { session, query, groupId, log } = params;
985
+ const mode = params.mode || "auto";
986
+ if (!["auto", "byName", "byQQ"].includes(mode)) {
987
+ return "mode must be auto, byName, or byQQ.";
988
+ }
989
+ const queryText = query.trim();
990
+ if (!queryText) return "query is required.";
991
+ const {
992
+ error,
993
+ session: validatedSession
994
+ } = ensureOneBotSession(session);
995
+ if (error) return error;
996
+ const resolvedGroupId = resolveGroupId(validatedSession, groupId);
997
+ if (!resolvedGroupId) {
998
+ return "Missing groupId. Provide groupId explicitly or run inside a group session.";
999
+ }
1000
+ const members = await fetchGroupMembers(validatedSession, resolvedGroupId);
1001
+ const shouldSearchQQ = mode === "byQQ" || mode === "auto" && /^\d+$/.test(queryText);
1002
+ const matches = members.filter(
1003
+ (member) => shouldSearchQQ ? getUserId(member) === queryText : matchByName(member, queryText)
1004
+ );
1005
+ if (matches.length === 0) return "\u672A\u627E\u5230\u5339\u914D\u7684\u7FA4\u6210\u5458\u3002";
1006
+ const visibleMatches = matches.slice(0, MAX_RESULTS);
1007
+ const header = matches.length > MAX_RESULTS ? `\u4EC5\u663E\u793A\u524D ${MAX_RESULTS} \u6761\uFF0C\u5171 ${matches.length} \u6761\u5339\u914D\uFF1A` : `\u627E\u5230 ${matches.length} \u4E2A\u5339\u914D\u6210\u5458\uFF1A`;
1008
+ const message = [
1009
+ header,
1010
+ ...visibleMatches.map((member, index) => formatMember(index + 1, member))
1011
+ ].join("\n");
1012
+ log?.("info", `\u7FA4 ${resolvedGroupId} \u6210\u5458\u641C\u7D22\u5B8C\u6210\uFF1A${matches.length} \u6761\u5339\u914D`);
1013
+ return message;
1014
+ } catch (error) {
1015
+ params.log?.("warn", "search_group_member failed", error);
1016
+ return `search_group_member failed: ${error.message}`;
1017
+ }
1018
+ }
1019
+ function createSearchGroupMemberTool(deps) {
1020
+ const { toolName, description, log } = deps;
1021
+ return new class extends import_tools3.StructuredTool {
1022
+ name = toolName || "search_group_member";
1023
+ description = description || DEFAULT_SEARCH_GROUP_MEMBER_TOOL_DESCRIPTION;
1024
+ schema = import_zod3.z.object({
1025
+ groupId: import_zod3.z.string().optional().describe("Target group ID. Defaults to current session group."),
1026
+ query: import_zod3.z.string().min(1, "query is required").describe("qqid, group card, or QQ nickname to search."),
1027
+ mode: import_zod3.z.enum(["auto", "byName", "byQQ"]).optional().describe("Search mode. Defaults to auto.")
1028
+ });
1029
+ async _call(input, _manager, runnable) {
1030
+ return searchGroupMember({
1031
+ session: getSession(runnable),
1032
+ groupId: input.groupId,
1033
+ query: input.query,
1034
+ mode: input.mode,
1035
+ log
1036
+ });
1037
+ }
1038
+ }();
1039
+ }
1040
+
1041
+ // src/features/native-tools/tools/set-group-ban.ts
1042
+ var import_zod4 = require("zod");
1043
+ var import_tools4 = require("@langchain/core/tools");
1044
+ function resolveGroupId2(session, groupId) {
937
1045
  return groupId?.trim() || (session.guildId || "").trim() || (session.channelId || "").trim() || (session.roomId || "").trim();
938
1046
  }
939
1047
  function parseDuration(duration) {
@@ -952,7 +1060,7 @@ async function sendGroupBan(params) {
952
1060
  session: validatedSession
953
1061
  } = ensureOneBotSession(session);
954
1062
  if (error) return error;
955
- const resolvedGroupId = resolveGroupId(validatedSession, groupId);
1063
+ const resolvedGroupId = resolveGroupId2(validatedSession, groupId);
956
1064
  if (!resolvedGroupId) {
957
1065
  return "Missing groupId. Provide groupId explicitly or run inside a group session.";
958
1066
  }
@@ -982,13 +1090,13 @@ async function sendGroupBan(params) {
982
1090
  }
983
1091
  function createSetGroupBanTool(deps) {
984
1092
  const { toolName, description, protocol, log } = deps;
985
- return new class extends import_tools3.StructuredTool {
1093
+ return new class extends import_tools4.StructuredTool {
986
1094
  name = toolName || "set_group_ban";
987
1095
  description = description || DEFAULT_SET_GROUP_BAN_TOOL_DESCRIPTION;
988
- schema = import_zod3.z.object({
989
- groupId: import_zod3.z.string().optional().describe("Target group ID. Defaults to current session group."),
990
- userId: import_zod3.z.string().min(1, "userId is required").describe("Target member user ID."),
991
- duration: import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number().int().min(0)]).describe("Mute duration in seconds. Use 0 to unmute.")
1096
+ schema = import_zod4.z.object({
1097
+ groupId: import_zod4.z.string().optional().describe("Target group ID. Defaults to current session group."),
1098
+ userId: import_zod4.z.string().min(1, "userId is required").describe("Target member user ID."),
1099
+ duration: import_zod4.z.union([import_zod4.z.string(), import_zod4.z.number().int().min(0)]).describe("Mute duration in seconds. Use 0 to unmute.")
992
1100
  });
993
1101
  async _call(input, _manager, runnable) {
994
1102
  const session = getSession(runnable);
@@ -1005,8 +1113,8 @@ function createSetGroupBanTool(deps) {
1005
1113
  }
1006
1114
 
1007
1115
  // src/features/native-tools/tools/set-group-card.ts
1008
- var import_zod4 = require("zod");
1009
- var import_tools4 = require("@langchain/core/tools");
1116
+ var import_zod5 = require("zod");
1117
+ var import_tools5 = require("@langchain/core/tools");
1010
1118
  async function sendSetGroupCard(params) {
1011
1119
  try {
1012
1120
  const { session, userId, card, groupId, log } = params;
@@ -1037,13 +1145,13 @@ async function sendSetGroupCard(params) {
1037
1145
  }
1038
1146
  function createSetGroupCardTool(deps) {
1039
1147
  const { toolName, description, log } = deps;
1040
- return new class extends import_tools4.StructuredTool {
1148
+ return new class extends import_tools5.StructuredTool {
1041
1149
  name = toolName || "set_group_card";
1042
1150
  description = description || DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION;
1043
- schema = import_zod4.z.object({
1044
- groupId: import_zod4.z.string().optional().describe("Target group ID. Defaults to current session group."),
1045
- userId: import_zod4.z.string().min(1, "userId is required").describe("Target member user ID."),
1046
- card: import_zod4.z.string().min(1, "card is required").describe("New group card for the member.")
1151
+ schema = import_zod5.z.object({
1152
+ groupId: import_zod5.z.string().optional().describe("Target group ID. Defaults to current session group."),
1153
+ userId: import_zod5.z.string().min(1, "userId is required").describe("Target member user ID."),
1154
+ card: import_zod5.z.string().min(1, "card is required").describe("New group card for the member.")
1047
1155
  });
1048
1156
  async _call(input, _manager, runnable) {
1049
1157
  return sendSetGroupCard({
@@ -1058,9 +1166,9 @@ function createSetGroupCardTool(deps) {
1058
1166
  }
1059
1167
 
1060
1168
  // src/features/native-tools/tools/set-group-special-title.ts
1061
- var import_zod5 = require("zod");
1062
- var import_tools5 = require("@langchain/core/tools");
1063
- function resolveGroupId2(session, groupId) {
1169
+ var import_zod6 = require("zod");
1170
+ var import_tools6 = require("@langchain/core/tools");
1171
+ function resolveGroupId3(session, groupId) {
1064
1172
  return groupId?.trim() || (session.guildId || "").trim() || (session.channelId || "").trim() || (session.roomId || "").trim();
1065
1173
  }
1066
1174
  async function sendSetGroupSpecialTitle(params) {
@@ -1072,7 +1180,7 @@ async function sendSetGroupSpecialTitle(params) {
1072
1180
  session: validatedSession
1073
1181
  } = ensureOneBotSession(session);
1074
1182
  if (error) return error;
1075
- const resolvedGroupId = resolveGroupId2(validatedSession, groupId);
1183
+ const resolvedGroupId = resolveGroupId3(validatedSession, groupId);
1076
1184
  if (!resolvedGroupId) {
1077
1185
  return "Missing groupId. Provide groupId explicitly or run inside a group session.";
1078
1186
  }
@@ -1099,13 +1207,13 @@ async function sendSetGroupSpecialTitle(params) {
1099
1207
  }
1100
1208
  function createSetGroupSpecialTitleTool(deps) {
1101
1209
  const { toolName, description, protocol, log } = deps;
1102
- return new class extends import_tools5.StructuredTool {
1210
+ return new class extends import_tools6.StructuredTool {
1103
1211
  name = toolName || "set_group_special_title";
1104
1212
  description = description || DEFAULT_SET_GROUP_SPECIAL_TITLE_TOOL_DESCRIPTION;
1105
- schema = import_zod5.z.object({
1106
- groupId: import_zod5.z.string().optional().describe("Target group ID. Defaults to current session group."),
1107
- userId: import_zod5.z.string().min(1, "userId is required").describe("Target member user ID."),
1108
- title: import_zod5.z.string().describe("New special title. Use an empty string to clear it.")
1213
+ schema = import_zod6.z.object({
1214
+ groupId: import_zod6.z.string().optional().describe("Target group ID. Defaults to current session group."),
1215
+ userId: import_zod6.z.string().min(1, "userId is required").describe("Target member user ID."),
1216
+ title: import_zod6.z.string().describe("New special title. Use an empty string to clear it.")
1109
1217
  });
1110
1218
  async _call(input, _manager, runnable) {
1111
1219
  const session = getSession(runnable);
@@ -1122,8 +1230,8 @@ function createSetGroupSpecialTitleTool(deps) {
1122
1230
  }
1123
1231
 
1124
1232
  // src/features/native-tools/tools/set-msg-emoji.ts
1125
- var import_zod6 = require("zod");
1126
- var import_tools6 = require("@langchain/core/tools");
1233
+ var import_zod7 = require("zod");
1234
+ var import_tools7 = require("@langchain/core/tools");
1127
1235
  async function sendMsgEmoji(params) {
1128
1236
  try {
1129
1237
  const { session, messageId, emojiId, log, protocol } = params;
@@ -1154,12 +1262,12 @@ async function sendMsgEmoji(params) {
1154
1262
  }
1155
1263
  function createSetMsgEmojiTool(deps) {
1156
1264
  const { toolName, description, log, protocol } = deps;
1157
- return new class extends import_tools6.StructuredTool {
1265
+ return new class extends import_tools7.StructuredTool {
1158
1266
  name = toolName || "set_msg_emoji";
1159
1267
  description = description || DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION;
1160
- schema = import_zod6.z.object({
1161
- messageId: import_zod6.z.string().min(1, "message_id is required").describe("Target message ID."),
1162
- emojiId: import_zod6.z.string().min(1, "emoji_id is required").describe("Emoji ID to send.")
1268
+ schema = import_zod7.z.object({
1269
+ messageId: import_zod7.z.string().min(1, "message_id is required").describe("Target message ID."),
1270
+ emojiId: import_zod7.z.string().min(1, "emoji_id is required").describe("Emoji ID to send.")
1163
1271
  });
1164
1272
  async _call(input, _manager, runnable) {
1165
1273
  const session = getSession(runnable);
@@ -1175,8 +1283,8 @@ function createSetMsgEmojiTool(deps) {
1175
1283
  }
1176
1284
 
1177
1285
  // src/features/native-tools/tools/profile.ts
1178
- var import_zod7 = require("zod");
1179
- var import_tools7 = require("@langchain/core/tools");
1286
+ var import_zod8 = require("zod");
1287
+ var import_tools8 = require("@langchain/core/tools");
1180
1288
  var genders = {
1181
1289
  unknown: "0",
1182
1290
  male: "1",
@@ -1203,13 +1311,13 @@ async function sendSetProfile(params) {
1203
1311
  }
1204
1312
  function createSetProfileTool(deps) {
1205
1313
  const { toolName, description, log, protocol } = deps;
1206
- return new class extends import_tools7.StructuredTool {
1314
+ return new class extends import_tools8.StructuredTool {
1207
1315
  name = toolName || "set_self_profile";
1208
1316
  description = description || DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION;
1209
- schema = import_zod7.z.object({
1210
- nickname: import_zod7.z.string().min(1, "nickname is required").describe("The new nickname for the bot."),
1211
- signature: import_zod7.z.string().optional().describe("Optional: the new personal signature."),
1212
- gender: import_zod7.z.enum(["unknown", "male", "female"]).optional().describe("Optional: the new gender.")
1317
+ schema = import_zod8.z.object({
1318
+ nickname: import_zod8.z.string().min(1, "nickname is required").describe("The new nickname for the bot."),
1319
+ signature: import_zod8.z.string().optional().describe("Optional: the new personal signature."),
1320
+ gender: import_zod8.z.enum(["unknown", "male", "female"]).optional().describe("Optional: the new gender.")
1213
1321
  });
1214
1322
  async _call(input, _manager, runnable) {
1215
1323
  return sendSetProfile({
@@ -1225,8 +1333,8 @@ function createSetProfileTool(deps) {
1225
1333
  }
1226
1334
 
1227
1335
  // src/features/native-tools/tools/set-qq-avatar.ts
1228
- var import_zod8 = require("zod");
1229
- var import_tools8 = require("@langchain/core/tools");
1336
+ var import_zod9 = require("zod");
1337
+ var import_tools9 = require("@langchain/core/tools");
1230
1338
  function isHttpUrl(value) {
1231
1339
  return /^https?:\/\//i.test(value);
1232
1340
  }
@@ -1285,11 +1393,11 @@ async function sendSetQQAvatar(params) {
1285
1393
  }
1286
1394
  function createSetQQAvatarTool(deps) {
1287
1395
  const { ctx, toolName, description, log } = deps;
1288
- return new class extends import_tools8.StructuredTool {
1396
+ return new class extends import_tools9.StructuredTool {
1289
1397
  name = toolName || "set_qq_avatar";
1290
1398
  description = description || DEFAULT_SET_QQ_AVATAR_TOOL_DESCRIPTION;
1291
- schema = import_zod8.z.object({
1292
- imageUrl: import_zod8.z.string().min(1, "imageUrl is required").describe("Image URL or local file path readable by the OneBot side.")
1399
+ schema = import_zod9.z.object({
1400
+ imageUrl: import_zod9.z.string().min(1, "imageUrl is required").describe("Image URL or local file path readable by the OneBot side.")
1293
1401
  });
1294
1402
  async _call(input, _manager, runnable) {
1295
1403
  return sendSetQQAvatar({
@@ -1325,12 +1433,18 @@ function resolveToolDescription(value, fallback) {
1325
1433
  const trimmedValue = value.trim();
1326
1434
  return trimmedValue || fallback;
1327
1435
  }
1436
+ function isNativeToolEnabled(config, toolKey) {
1437
+ if (config.enabledNativeTools) {
1438
+ return config.enabledNativeTools.includes(toolKey);
1439
+ }
1440
+ return config[toolKey].enabled ?? false;
1441
+ }
1328
1442
  function resolveOneBotProtocol(config, log) {
1329
1443
  return config.oneBotProtocol;
1330
1444
  }
1331
1445
  function registerNativeTools(deps) {
1332
1446
  const { ctx, config, plugin, protocol, log } = deps;
1333
- if (config.poke.enabled) {
1447
+ if (isNativeToolEnabled(config, "poke")) {
1334
1448
  const toolName = resolveToolName(config.poke.toolName, "poke_user");
1335
1449
  const description = resolveToolDescription(
1336
1450
  config.poke.description,
@@ -1345,7 +1459,7 @@ function registerNativeTools(deps) {
1345
1459
  });
1346
1460
  log?.("info", `\u6233\u4E00\u6233\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1347
1461
  }
1348
- if (config.setSelfProfile.enabled) {
1462
+ if (isNativeToolEnabled(config, "setSelfProfile")) {
1349
1463
  const toolName = resolveToolName(
1350
1464
  config.setSelfProfile.toolName,
1351
1465
  "set_self_profile"
@@ -1363,7 +1477,7 @@ function registerNativeTools(deps) {
1363
1477
  });
1364
1478
  log?.("info", `\u8BBE\u7F6E\u8D44\u6599\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1365
1479
  }
1366
- if (config.setQQAvatar.enabled) {
1480
+ if (isNativeToolEnabled(config, "setQQAvatar")) {
1367
1481
  const toolName = resolveToolName(
1368
1482
  config.setQQAvatar.toolName,
1369
1483
  "set_qq_avatar"
@@ -1381,7 +1495,7 @@ function registerNativeTools(deps) {
1381
1495
  });
1382
1496
  log?.("info", `QQ \u5934\u50CF\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1383
1497
  }
1384
- if (config.setGroupCard.enabled) {
1498
+ if (isNativeToolEnabled(config, "setGroupCard")) {
1385
1499
  const toolName = resolveToolName(
1386
1500
  config.setGroupCard.toolName,
1387
1501
  "set_group_card"
@@ -1399,7 +1513,25 @@ function registerNativeTools(deps) {
1399
1513
  });
1400
1514
  log?.("info", `\u7FA4\u6635\u79F0\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1401
1515
  }
1402
- if (config.setGroupBan.enabled) {
1516
+ if (isNativeToolEnabled(config, "searchGroupMember")) {
1517
+ const toolName = resolveToolName(
1518
+ config.searchGroupMember.toolName,
1519
+ "search_group_member"
1520
+ );
1521
+ const description = resolveToolDescription(
1522
+ config.searchGroupMember.description,
1523
+ DEFAULT_SEARCH_GROUP_MEMBER_TOOL_DESCRIPTION
1524
+ );
1525
+ plugin.registerTool(toolName, {
1526
+ selector: () => true,
1527
+ authorization: (session) => session?.platform === "onebot",
1528
+ description,
1529
+ createTool: () => createSearchGroupMemberTool({ toolName, description, log }),
1530
+ meta: createNativeToolMeta("onebot", ["group"])
1531
+ });
1532
+ log?.("info", `\u7FA4\u6210\u5458\u641C\u7D22\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1533
+ }
1534
+ if (isNativeToolEnabled(config, "setGroupBan")) {
1403
1535
  const toolName = resolveToolName(
1404
1536
  config.setGroupBan.toolName,
1405
1537
  "set_group_ban"
@@ -1417,7 +1549,7 @@ function registerNativeTools(deps) {
1417
1549
  });
1418
1550
  log?.("info", `\u7FA4\u6210\u5458\u7981\u8A00\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1419
1551
  }
1420
- if (config.setGroupSpecialTitle.enabled) {
1552
+ if (isNativeToolEnabled(config, "setGroupSpecialTitle")) {
1421
1553
  const toolName = resolveToolName(
1422
1554
  config.setGroupSpecialTitle.toolName,
1423
1555
  "set_group_special_title"
@@ -1440,7 +1572,7 @@ function registerNativeTools(deps) {
1440
1572
  });
1441
1573
  log?.("info", `\u7FA4\u4E13\u5C5E\u5934\u8854\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1442
1574
  }
1443
- if (config.setMsgEmoji.enabled) {
1575
+ if (isNativeToolEnabled(config, "setMsgEmoji")) {
1444
1576
  const toolName = resolveToolName(
1445
1577
  config.setMsgEmoji.toolName,
1446
1578
  "set_msg_emoji"
@@ -1458,7 +1590,7 @@ function registerNativeTools(deps) {
1458
1590
  });
1459
1591
  log?.("info", `\u6D88\u606F\u8868\u60C5\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
1460
1592
  }
1461
- if (config.deleteMessage.enabled) {
1593
+ if (isNativeToolEnabled(config, "deleteMessage")) {
1462
1594
  const toolName = resolveToolName(
1463
1595
  config.deleteMessage.toolName,
1464
1596
  "delete_msg"
@@ -1869,7 +2001,7 @@ function registerXmlTools(deps) {
1869
2001
  }
1870
2002
 
1871
2003
  // src/features/variables/providers/bot-info.ts
1872
- function pickFirst(...values) {
2004
+ function pickFirst2(...values) {
1873
2005
  for (const value of values) {
1874
2006
  if (value === null || value === void 0) continue;
1875
2007
  const text = String(value).trim();
@@ -1956,7 +2088,7 @@ function renderBotInfo(session, member, items) {
1956
2088
  switch (item) {
1957
2089
  case "nickname": {
1958
2090
  const name2 = String(
1959
- pickFirst(
2091
+ pickFirst2(
1960
2092
  member?.card,
1961
2093
  member?.remark,
1962
2094
  member?.displayName,
@@ -1974,7 +2106,7 @@ function renderBotInfo(session, member, items) {
1974
2106
  break;
1975
2107
  case "role": {
1976
2108
  const role = normalizeRole(
1977
- pickFirst(
2109
+ pickFirst2(
1978
2110
  member?.role,
1979
2111
  member?.roleName,
1980
2112
  member?.permission,
@@ -1985,7 +2117,7 @@ function renderBotInfo(session, member, items) {
1985
2117
  break;
1986
2118
  }
1987
2119
  case "level": {
1988
- const level = pickFirst(
2120
+ const level = pickFirst2(
1989
2121
  member?.level,
1990
2122
  member?.levelName,
1991
2123
  member?.level_name,
@@ -1995,7 +2127,7 @@ function renderBotInfo(session, member, items) {
1995
2127
  break;
1996
2128
  }
1997
2129
  case "title": {
1998
- const title = pickFirst(
2130
+ const title = pickFirst2(
1999
2131
  member?.title,
2000
2132
  member?.specialTitle,
2001
2133
  member?.special_title
@@ -2014,14 +2146,14 @@ function renderBotInfo(session, member, items) {
2014
2146
  break;
2015
2147
  }
2016
2148
  case "area": {
2017
- const area = pickFirst(member?.area, member?.region, member?.location);
2149
+ const area = pickFirst2(member?.area, member?.region, member?.location);
2018
2150
  if (area !== null) values.push(`\u5730\u533A:${area}`);
2019
2151
  break;
2020
2152
  }
2021
2153
  case "joinTime": {
2022
2154
  const joinTime = formatDateOnly(
2023
2155
  normalizeTimestamp(
2024
- pickFirst(
2156
+ pickFirst2(
2025
2157
  member?.join_time,
2026
2158
  member?.joined_at,
2027
2159
  member?.joinTime,
@@ -2035,7 +2167,7 @@ function renderBotInfo(session, member, items) {
2035
2167
  case "lastSentTime": {
2036
2168
  const lastSentTime = formatDateTime(
2037
2169
  normalizeTimestamp(
2038
- pickFirst(
2170
+ pickFirst2(
2039
2171
  member?.last_sent_time,
2040
2172
  member?.lastSentTime,
2041
2173
  member?.lastSpeakTimestamp
@@ -2232,7 +2364,7 @@ function formatDateTime2(value) {
2232
2364
  if (Number.isNaN(date.valueOf())) return "\u672A\u77E5";
2233
2365
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
2234
2366
  }
2235
- function pickFirst2(...values) {
2367
+ function pickFirst3(...values) {
2236
2368
  for (const value of values) {
2237
2369
  if (value === null || value === void 0) continue;
2238
2370
  const text = String(value).trim();
@@ -2241,12 +2373,12 @@ function pickFirst2(...values) {
2241
2373
  return "";
2242
2374
  }
2243
2375
  function normalizeShutItem(item) {
2244
- const userId = pickFirst2(
2376
+ const userId = pickFirst3(
2245
2377
  item.uin,
2246
2378
  item.user_id
2247
2379
  );
2248
2380
  if (!userId) return null;
2249
- const cardName = pickFirst2(
2381
+ const cardName = pickFirst3(
2250
2382
  item.cardName,
2251
2383
  item.remark,
2252
2384
  item.nick,
@@ -2255,7 +2387,7 @@ function normalizeShutItem(item) {
2255
2387
  );
2256
2388
  const shutUpTimeText = formatDateTime2(
2257
2389
  normalizeTimestamp2(
2258
- pickFirst2(
2390
+ pickFirst3(
2259
2391
  item.shutUpTime,
2260
2392
  item.shut_up_time
2261
2393
  )
@@ -2584,7 +2716,7 @@ function formatDateTime3(value) {
2584
2716
  if (Number.isNaN(date.valueOf())) return "";
2585
2717
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
2586
2718
  }
2587
- function pickFirst3(...values) {
2719
+ function pickFirst4(...values) {
2588
2720
  for (const value of values) {
2589
2721
  if (value === null || value === void 0) continue;
2590
2722
  const text = String(value).trim();
@@ -2642,7 +2774,7 @@ function renderUserInfo(session, member, items) {
2642
2774
  switch (item) {
2643
2775
  case "nickname": {
2644
2776
  const name2 = String(
2645
- pickFirst3(
2777
+ pickFirst4(
2646
2778
  member?.card,
2647
2779
  member?.remark,
2648
2780
  member?.displayName,
@@ -2661,7 +2793,7 @@ function renderUserInfo(session, member, items) {
2661
2793
  break;
2662
2794
  case "role": {
2663
2795
  const role = normalizeRole2(
2664
- pickFirst3(
2796
+ pickFirst4(
2665
2797
  member?.role,
2666
2798
  member?.roleName,
2667
2799
  member?.permission,
@@ -2672,7 +2804,7 @@ function renderUserInfo(session, member, items) {
2672
2804
  break;
2673
2805
  }
2674
2806
  case "level": {
2675
- const level = pickFirst3(
2807
+ const level = pickFirst4(
2676
2808
  member?.level,
2677
2809
  member?.levelName,
2678
2810
  member?.level_name,
@@ -2682,7 +2814,7 @@ function renderUserInfo(session, member, items) {
2682
2814
  break;
2683
2815
  }
2684
2816
  case "title": {
2685
- const title = pickFirst3(
2817
+ const title = pickFirst4(
2686
2818
  member?.title,
2687
2819
  member?.specialTitle,
2688
2820
  member?.special_title
@@ -2701,14 +2833,14 @@ function renderUserInfo(session, member, items) {
2701
2833
  break;
2702
2834
  }
2703
2835
  case "area": {
2704
- const area = pickFirst3(member?.area, member?.region, member?.location);
2836
+ const area = pickFirst4(member?.area, member?.region, member?.location);
2705
2837
  if (area !== null) values.push(`\u5730\u533A:${area}`);
2706
2838
  break;
2707
2839
  }
2708
2840
  case "joinTime": {
2709
2841
  const joinTime = formatDateOnly3(
2710
2842
  normalizeTimestamp3(
2711
- pickFirst3(
2843
+ pickFirst4(
2712
2844
  member?.join_time,
2713
2845
  member?.joined_at,
2714
2846
  member?.joinTime,
@@ -2722,7 +2854,7 @@ function renderUserInfo(session, member, items) {
2722
2854
  case "lastSentTime": {
2723
2855
  const lastSentTime = formatDateTime3(
2724
2856
  normalizeTimestamp3(
2725
- pickFirst3(
2857
+ pickFirst4(
2726
2858
  member?.last_sent_time,
2727
2859
  member?.lastSentTime,
2728
2860
  member?.lastSpeakTimestamp
@@ -2824,7 +2956,7 @@ function apply(ctx, config) {
2824
2956
  registerNativeTools({ ctx, config, plugin, protocol, log });
2825
2957
  xmlRuntime = enableXmlRuntime ? registerXmlTools({ ctx, config, protocol, log }) : null;
2826
2958
  if (characterCtx && xmlRuntime?.start()) {
2827
- log("info", "XML \u5DE5\u5177\u5DF2\u542F\u7528");
2959
+ log("info", "Character XML \u5DE5\u5177\u5DF2\u542F\u7528");
2828
2960
  }
2829
2961
  log("info", "toolbox \u521D\u59CB\u5316\u5B8C\u6210");
2830
2962
  };
@@ -2853,7 +2985,7 @@ function apply(ctx, config) {
2853
2985
  });
2854
2986
  if (!xmlRuntime) return;
2855
2987
  const started = xmlRuntime.start();
2856
- if (started) log("info", "XML \u5DE5\u5177\u5DF2\u542F\u7528");
2988
+ if (started) log("info", "Character XML \u5DE5\u5177\u5DF2\u542F\u7528");
2857
2989
  });
2858
2990
  }
2859
2991
  ctx.on("dispose", dispose);
@@ -2865,6 +2997,15 @@ function apply(ctx, config) {
2865
2997
  });
2866
2998
  }
2867
2999
  }
3000
+
3001
+ // src/index.ts
3002
+ var usage = `
3003
+ ## \u4F7F\u7528\u8BF4\u660E
3004
+
3005
+ Character XML \u5DE5\u5177\u4EC5\u4F9B [koishi-plugin-chatluna-character](https://github.com/ChatLunaLab/chatluna-character) \u4F7F\u7528\uFF1B\u5982\u679C\u4F60\u53EA\u5B89\u88C5\u4E86 ChatLuna \u4E3B\u63D2\u4EF6\uFF0C\u8BF7\u4E0D\u8981\u5F00\u542F\u8FD9\u4E00\u9879\u3002
3006
+
3007
+ \u5982\u679C\u4F60\u4E0D\u786E\u5B9A\u5F53\u524D\u73AF\u5883\u662F\u5426\u9700\u8981\u8FD9\u7EC4\u80FD\u529B\uFF0C\u4F18\u5148\u4FDD\u6301\u5173\u95ED\uFF0C\u6309 README \u7684\u8BF4\u660E\u9010\u9879\u542F\u7528\u5373\u53EF\u3002
3008
+ `;
2868
3009
  // Annotate the CommonJS export names for ESM import in node:
2869
3010
  0 && (module.exports = {
2870
3011
  BasicSettingsSchema,
@@ -2886,6 +3027,7 @@ function apply(ctx, config) {
2886
3027
  createLogger,
2887
3028
  createPokeTool,
2888
3029
  createRandomProvider,
3030
+ createSearchGroupMemberTool,
2889
3031
  createSetGroupBanTool,
2890
3032
  createSetGroupCardTool,
2891
3033
  createSetGroupSpecialTitleTool,
@@ -2905,6 +3047,7 @@ function apply(ctx, config) {
2905
3047
  registerVariables,
2906
3048
  registerXmlTools,
2907
3049
  resolveOneBotProtocol,
3050
+ searchGroupMember,
2908
3051
  sendDeleteMessage,
2909
3052
  sendGroupBan,
2910
3053
  sendMsgEmoji,
@@ -2912,5 +3055,6 @@ function apply(ctx, config) {
2912
3055
  sendSetGroupCard,
2913
3056
  sendSetGroupSpecialTitle,
2914
3057
  sendSetProfile,
2915
- sendSetQQAvatar
3058
+ sendSetQQAvatar,
3059
+ usage
2916
3060
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-toolbox",
3
- "description": "为 ChatLuna 提供更多原生工具、XML 工具与变量,仅支持 onebot 平台。",
4
- "version": "0.0.17",
3
+ "description": "为 ChatLuna 提供更多原生工具、Character XML 工具与变量,仅支持 onebot 平台。",
4
+ "version": "0.0.19",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [