@zhin.js/adapter-icqq 1.1.14 → 1.1.16

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/PERMITS.md +14 -18
  3. package/README.md +12 -0
  4. package/adapters/icqq/index.js +15 -0
  5. package/adapters/icqq/index.ts +15 -0
  6. package/agents/icqq/conversation.js +72 -0
  7. package/agents/icqq/conversation.ts +67 -0
  8. package/agents/icqq/messages.js +144 -0
  9. package/agents/icqq/messages.ts +144 -0
  10. package/agents/icqq/skills/icqq-conversation/SKILL.md +24 -0
  11. package/agents/icqq/skills/icqq-conversation/tools/conversation_info/index.js +61 -0
  12. package/agents/icqq/skills/icqq-conversation/tools/conversation_info/index.ts +61 -0
  13. package/agents/icqq/skills/icqq-directory/SKILL.md +9 -11
  14. package/agents/icqq/skills/icqq-directory/tools/user_info/index.js +2 -1
  15. package/agents/icqq/skills/icqq-directory/tools/user_info/index.ts +2 -1
  16. package/agents/icqq/skills/icqq-group-admin/SKILL.md +32 -15
  17. package/agents/icqq/skills/icqq-group-admin/tools/announce/index.js +2 -1
  18. package/agents/icqq/skills/icqq-group-admin/tools/announce/index.ts +2 -1
  19. package/agents/icqq/skills/icqq-group-admin/tools/essence/index.js +2 -1
  20. package/agents/icqq/skills/icqq-group-admin/tools/essence/index.ts +2 -1
  21. package/agents/icqq/skills/icqq-group-admin/tools/group_invite/index.js +5 -3
  22. package/agents/icqq/skills/icqq-group-admin/tools/group_invite/index.ts +5 -3
  23. package/agents/icqq/skills/icqq-group-admin/tools/group_kick/index.js +14 -11
  24. package/agents/icqq/skills/icqq-group-admin/tools/group_kick/index.ts +13 -9
  25. package/agents/icqq/skills/icqq-group-admin/tools/group_leave/index.js +33 -0
  26. package/agents/icqq/skills/icqq-group-admin/tools/group_leave/index.ts +32 -0
  27. package/agents/icqq/skills/icqq-group-admin/tools/recall_member_message/index.js +33 -0
  28. package/agents/icqq/skills/icqq-group-admin/tools/recall_member_message/index.ts +32 -0
  29. package/agents/icqq/skills/icqq-group-admin/tools/set_anonymous/index.js +3 -2
  30. package/agents/icqq/skills/icqq-group-admin/tools/set_anonymous/index.ts +3 -2
  31. package/agents/icqq/skills/icqq-group-admin/tools/set_mute/index.js +4 -3
  32. package/agents/icqq/skills/icqq-group-admin/tools/set_mute/index.ts +4 -3
  33. package/agents/icqq/skills/icqq-group-admin/tools/set_title/index.js +4 -3
  34. package/agents/icqq/skills/icqq-group-admin/tools/set_title/index.ts +4 -3
  35. package/agents/icqq/skills/icqq-group-directory/SKILL.md +16 -0
  36. package/agents/icqq/skills/{icqq-directory → icqq-group-directory}/tools/group_member_info/index.js +3 -2
  37. package/agents/icqq/skills/{icqq-directory → icqq-group-directory}/tools/group_member_info/index.ts +3 -2
  38. package/agents/icqq/skills/icqq-group-interaction/SKILL.md +18 -0
  39. package/agents/icqq/skills/{icqq-interaction → icqq-group-interaction}/tools/group_sign/index.js +3 -2
  40. package/agents/icqq/skills/{icqq-interaction → icqq-group-interaction}/tools/group_sign/index.ts +3 -2
  41. package/agents/icqq/skills/{icqq-interaction → icqq-group-interaction}/tools/poke/index.js +2 -1
  42. package/agents/icqq/skills/{icqq-interaction → icqq-group-interaction}/tools/poke/index.ts +2 -1
  43. package/agents/icqq/skills/icqq-group-state/SKILL.md +7 -6
  44. package/agents/icqq/skills/icqq-group-state/tools/group_files/index.js +2 -1
  45. package/agents/icqq/skills/icqq-group-state/tools/group_files/index.ts +2 -1
  46. package/agents/icqq/skills/icqq-interaction/SKILL.md +5 -10
  47. package/agents/icqq/skills/icqq-interaction/tools/send_user_like/index.js +3 -2
  48. package/agents/icqq/skills/icqq-interaction/tools/send_user_like/index.ts +3 -2
  49. package/agents/icqq/skills/icqq-messages/SKILL.md +28 -0
  50. package/agents/icqq/skills/icqq-messages/tools/forward_messages/index.js +42 -0
  51. package/agents/icqq/skills/icqq-messages/tools/forward_messages/index.ts +40 -0
  52. package/agents/icqq/skills/icqq-messages/tools/quote_reply/index.js +24 -0
  53. package/agents/icqq/skills/icqq-messages/tools/quote_reply/index.ts +24 -0
  54. package/agents/icqq/skills/icqq-messages/tools/recall_own_message/index.js +18 -0
  55. package/agents/icqq/skills/icqq-messages/tools/recall_own_message/index.ts +17 -0
  56. package/agents/icqq/system.md +4 -0
  57. package/commands/icqq/endpoint/definition.js +9 -7
  58. package/commands/icqq/endpoint/definition.ts +9 -9
  59. package/lib/endpoint.d.ts +1 -0
  60. package/lib/endpoint.js +12 -1
  61. package/lib/group-moderation.d.ts +5 -0
  62. package/lib/group-moderation.js +46 -0
  63. package/lib/i18n.d.ts +1 -0
  64. package/lib/i18n.js +47 -0
  65. package/lib/icqq-inbound.js +15 -0
  66. package/lib/icqq-login-assist.d.ts +2 -0
  67. package/lib/icqq-login-assist.js +8 -7
  68. package/lib/protocol.d.ts +1 -0
  69. package/lib/protocol.js +14 -1
  70. package/package.json +16 -16
  71. package/prompt-sections/platform/index.js +1 -2
  72. package/prompt-sections/platform/index.ts +1 -2
  73. package/schema.json +250 -42
  74. package/src/endpoint.ts +14 -1
  75. package/src/group-moderation.ts +52 -0
  76. package/src/i18n.ts +48 -0
  77. package/src/icqq-inbound.ts +14 -0
  78. package/src/icqq-login-assist.ts +10 -7
  79. package/src/protocol.ts +13 -1
@@ -0,0 +1,61 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { currentConversation } from '../../../../conversation.js';
5
+ export default defineAgentTool({
6
+ description: '读取当前 ICQQ 会话及机器人自己的群/频道身份;区分调用者权限、机器人平台权限和不支持的操作',
7
+ adapter: 'icqq',
8
+ requiresApproval: 'never',
9
+ inputSchema: z.object({}),
10
+ async execute(_input, context) {
11
+ const conversation = currentConversation(context);
12
+ const client = context.$client;
13
+ const roles = context.principal.roles;
14
+ const common = {
15
+ conversation,
16
+ requester: {
17
+ roles,
18
+ canRequestGroupModeration: roles.some(role => ['master', 'admin', 'trusted', 'owner'].includes(role)),
19
+ canRequestLeave: roles.includes('master'),
20
+ },
21
+ operations: {
22
+ quoteReply: conversation.kind !== 'channel',
23
+ forwardMessages: conversation.kind !== 'channel',
24
+ recallOwnMessage: conversation.kind !== 'channel',
25
+ recallMemberMessage: conversation.kind === 'group',
26
+ leaveGroup: conversation.kind === 'group',
27
+ },
28
+ };
29
+ if (conversation.kind === 'group') {
30
+ const id = Number(conversation.id);
31
+ const [group, self] = await Promise.all([
32
+ client.getGroupInfo(id, true),
33
+ client.getGroupMemberInfo(id, client.uin, true),
34
+ ]);
35
+ context.signal.throwIfAborted();
36
+ const role = group.owner_id === client.uin ? 'owner' : self.role;
37
+ return {
38
+ ...common,
39
+ group: { id: group.group_id, name: group.group_name, ownerId: group.owner_id, memberCount: group.member_count },
40
+ bot: { id: client.uin, role, canModerateMembers: role === 'owner' || role === 'admin', canLeave: role === 'admin' || role === 'member' },
41
+ };
42
+ }
43
+ if (conversation.kind === 'channel') {
44
+ const guildId = conversation.parent?.id;
45
+ const guild = guildId ? client.guilds.get(guildId) : undefined;
46
+ const channel = guild?.channels.get(conversation.id);
47
+ const members = guildId ? await client.getGuildMemberList(guildId) : [];
48
+ context.signal.throwIfAborted();
49
+ const self = members.find(member => member.tiny_id === client.tiny_id);
50
+ const role = self?.role === 4 ? 'owner' : self?.role === 2 ? 'admin'
51
+ : self?.role === 5 ? 'channel_admin' : self?.role === 1 ? 'member' : 'unknown';
52
+ return {
53
+ ...common,
54
+ guild: { id: guildId, name: guild?.guild_name },
55
+ channel: { id: conversation.id, name: channel?.channel_name, type: channel?.channel_type },
56
+ bot: { id: client.tiny_id, role, channelAdminScope: 'unknown' },
57
+ };
58
+ }
59
+ return { ...common, bot: { id: client.uin, role: 'not_applicable' } };
60
+ },
61
+ });
@@ -0,0 +1,61 @@
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
+ import { z } from 'zod';
3
+ import { currentConversation } from '../../../../conversation.js';
4
+
5
+ export default defineAgentTool({
6
+ description: '读取当前 ICQQ 会话及机器人自己的群/频道身份;区分调用者权限、机器人平台权限和不支持的操作',
7
+ adapter: 'icqq',
8
+ requiresApproval: 'never',
9
+ inputSchema: z.object({}),
10
+ async execute(_input, context) {
11
+ const conversation = currentConversation(context);
12
+ const client = context.$client;
13
+ const roles = context.principal.roles;
14
+ const common = {
15
+ conversation,
16
+ requester: {
17
+ roles,
18
+ canRequestGroupModeration: roles.some(role => ['master', 'admin', 'trusted', 'owner'].includes(role)),
19
+ canRequestLeave: roles.includes('master'),
20
+ },
21
+ operations: {
22
+ quoteReply: conversation.kind !== 'channel',
23
+ forwardMessages: conversation.kind !== 'channel',
24
+ recallOwnMessage: conversation.kind !== 'channel',
25
+ recallMemberMessage: conversation.kind === 'group',
26
+ leaveGroup: conversation.kind === 'group',
27
+ },
28
+ };
29
+ if (conversation.kind === 'group') {
30
+ const id = Number(conversation.id);
31
+ const [group, self] = await Promise.all([
32
+ client.getGroupInfo(id, true),
33
+ client.getGroupMemberInfo(id, client.uin, true),
34
+ ]);
35
+ context.signal.throwIfAborted();
36
+ const role = group.owner_id === client.uin ? 'owner' : self.role;
37
+ return {
38
+ ...common,
39
+ group: { id: group.group_id, name: group.group_name, ownerId: group.owner_id, memberCount: group.member_count },
40
+ bot: { id: client.uin, role, canModerateMembers: role === 'owner' || role === 'admin', canLeave: role === 'admin' || role === 'member' },
41
+ };
42
+ }
43
+ if (conversation.kind === 'channel') {
44
+ const guildId = conversation.parent?.id;
45
+ const guild = guildId ? client.guilds.get(guildId) : undefined;
46
+ const channel = guild?.channels.get(conversation.id);
47
+ const members = guildId ? await client.getGuildMemberList(guildId) : [];
48
+ context.signal.throwIfAborted();
49
+ const self = members.find(member => member.tiny_id === client.tiny_id);
50
+ const role = self?.role === 4 ? 'owner' : self?.role === 2 ? 'admin'
51
+ : self?.role === 5 ? 'channel_admin' : self?.role === 1 ? 'member' : 'unknown';
52
+ return {
53
+ ...common,
54
+ guild: { id: guildId, name: guild?.guild_name },
55
+ channel: { id: conversation.id, name: channel?.channel_name, type: channel?.channel_type },
56
+ bot: { id: client.tiny_id, role, channelAdminScope: 'unknown' },
57
+ };
58
+ }
59
+ return { ...common, bot: { id: client.uin, role: 'not_applicable' } };
60
+ },
61
+ });
@@ -2,19 +2,17 @@
2
2
  name: icqq-directory
3
3
  platforms:
4
4
  - icqq
5
- description: ICQQ 好友、群和成员目录查询能力。
5
+ description: ICQQ 好友列表、群列表和用户资料查询。
6
6
  keywords:
7
- - "icqq"
8
- - "好友列表"
9
- - "群列表"
10
- - "成员信息"
7
+ - icqq
8
+ - 好友列表
9
+ - 群列表
10
+ - 用户资料
11
11
  tools:
12
- - "friend_list"
13
- - "group_list"
14
- - "user_info"
15
- - "group_member_info"
12
+ - friend_list
13
+ - group_list
14
+ - user_info
16
15
  ---
17
-
18
16
  # icqq-directory
19
17
 
20
- 查询用户或群成员前先获取稳定 QQ 号或群号。目录信息只向群主、管理员、master 或 trusted 披露;不要根据昵称猜测身份。
18
+ 先查询稳定 QQ 号或群号,不猜测昵称对应的 ID。目录信息只向群主、管理员、master 或 trusted 披露。
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -10,6 +11,6 @@ export default defineAgentTool({
10
11
  requiresApproval: 'never',
11
12
  async execute({ user_id }, context) {
12
13
  const profile = await context.$client.getProfile(user_id);
13
- return { success: true, message: `已获取 ${user_id} 的用户信息:${JSON.stringify(profile, null, 2)}` };
14
+ return { success: true, message: t(context.locale, 'userInfo', { p0: user_id, p1: JSON.stringify(profile, null, 2) }) };
14
15
  },
15
16
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from "../../../../messages.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
4
  export default defineAgentTool<{ user_id: number }>({
@@ -9,6 +10,6 @@ export default defineAgentTool<{ user_id: number }>({
9
10
  requiresApproval: 'never',
10
11
  async execute({ user_id }, context) {
11
12
  const profile = await context.$client.getProfile(user_id);
12
- return { success: true, message: `已获取 ${user_id} 的用户信息:${JSON.stringify(profile,null,2)}` };
13
+ return { success: true, message: t(context.locale, 'userInfo', { p0: user_id, p1: JSON.stringify(profile,null,2) }) };
13
14
  },
14
15
  });
@@ -2,24 +2,41 @@
2
2
  name: icqq-group-admin
3
3
  platforms:
4
4
  - icqq
5
- description: ICQQ 邀请、踢人、禁言、头衔、匿名、公告和精华管理能力。
5
+ description: ICQQ 群管理、撤回他人消息,以及仅主人可申请的退群操作;工具分别声明权限与审批要求。
6
6
  keywords:
7
- - "icqq"
8
- - "群管理"
9
- - "禁言"
10
- - "踢人"
11
- - "公告"
12
- - "精华"
7
+ - icqq
8
+ - 群管理
9
+ - 禁言
10
+ - 踢人
11
+ - 公告
12
+ - 精华
13
+ - 退群
14
+ - 撤回他人消息
13
15
  tools:
14
- - "group_invite"
15
- - "group_kick"
16
- - "set_mute"
17
- - "set_title"
18
- - "set_anonymous"
19
- - "announce"
20
- - "essence"
16
+ - group_invite
17
+ - group_kick
18
+ - set_mute
19
+ - set_title
20
+ - set_anonymous
21
+ - announce
22
+ - essence
23
+ - group_leave
24
+ - recall_member_message
25
+ scopes:
26
+ - group
21
27
  ---
22
-
23
28
  # icqq-group-admin
24
29
 
25
30
  仅在目标群和目标成员明确时加载。所有写操作遵守 Tool 审批与角色权限;不可逆或影响成员关系的操作先复核参数。
31
+
32
+ 自动管群必须先确认具体规则和目标群,不能仅凭权限许可自行制定触发条件。
33
+
34
+ 本技能的踢人工具每次都需人工审批,必须展示本次目标群、目标成员和理由;上一笔操作的批准不能授权下一笔踢人。
35
+
36
+ 已配置的自动审核流程可对入群 10 分钟内的明确广告直接踢出;该例外由审核流程核验,不授权本技能或普通对话绕过人工审批。
37
+
38
+ `group_leave` 仅主人(master)可发起,每次人工审批,只能退出当前群。Bot 为群主时拒绝执行,因为 SDK 的退群会解散群。
39
+
40
+ `recall_member_message` 沿用 master/admin/trusted/owner 发起权限,无需逐次审批;目标固定在当前群中的真实消息。执行前实时查询 Bot 与目标成员角色:管理员只能撤回普通成员,群主可撤回管理员或普通成员。平台时限与执行结果仍然有效,不自动重试未确认的结果。
41
+
42
+ 撤回 Bot 自己的消息不要求群管角色:使用 `icqq-messages` 的 `recall_own_message`。已配置自动群审核的撤回继续走原有审核路径,不因本工具新增审批,也不扩大审核类别或目标群。
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -13,6 +14,6 @@ export default defineAgentTool({
13
14
  permissions: ['role(master,admin,trusted,owner)'],
14
15
  async execute({ group_id, content }, context) {
15
16
  await context.$client.sendGroupNotice(group_id, content);
16
- return { success: true, message: '群公告已发送' };
17
+ return { success: true, message: t(context.locale, 'announcementSent') };
17
18
  },
18
19
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from "../../../../messages.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
4
  export default defineAgentTool<{ group_id: number; content: string }>({
@@ -12,6 +13,6 @@ export default defineAgentTool<{ group_id: number; content: string }>({
12
13
  permissions: ['role(master,admin,trusted,owner)'],
13
14
  async execute({ group_id, content }, context) {
14
15
  await context.$client.sendGroupNotice(group_id, content);
15
- return { success: true, message: '群公告已发送' };
16
+ return { success: true, message: t(context.locale, 'announcementSent') };
16
17
  },
17
18
  });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -19,6 +20,6 @@ export default defineAgentTool({
19
20
  else {
20
21
  await client.removeEssenceMessage(message_id);
21
22
  }
22
- return { success: true, message: action === 'add' ? '已设为精华' : '已移除精华' };
23
+ return { success: true, message: action === 'add' ? t(context.locale, 'essenceAdded') : t(context.locale, 'essenceRemoved') };
23
24
  },
24
25
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from "../../../../messages.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
4
  export default defineAgentTool<{ message_id: string; action: 'add' | 'remove' }>({
@@ -17,6 +18,6 @@ export default defineAgentTool<{ message_id: string; action: 'add' | 'remove' }>
17
18
  } else {
18
19
  await client.removeEssenceMessage(message_id);
19
20
  }
20
- return { success: true, message: action === 'add' ? '已设为精华' : '已移除精华' };
21
+ return { success: true, message: action === 'add' ? t(context.locale, 'essenceAdded') : t(context.locale, 'essenceRemoved') };
21
22
  },
22
23
  });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -8,16 +9,17 @@ export default defineAgentTool({
8
9
  user_id: z.number().describe('要邀请的 QQ号'),
9
10
  }),
10
11
  adapter: 'icqq',
12
+ scopes: ["group"],
11
13
  requiresApproval: 'always',
12
14
  async execute({ group_id, user_id }, context) {
13
15
  const client = context.$client;
14
16
  const groupInfo = client.pickGroup(group_id);
15
17
  if (!groupInfo)
16
- return { success: false, message: '目标群不存在' };
18
+ return { success: false, message: t(context.locale, 'groupMissing') };
17
19
  const memberInfo = client.pickMember(group_id, user_id);
18
20
  if (memberInfo)
19
- return { success: false, message: '目标成员已加入群' };
21
+ return { success: false, message: t(context.locale, 'memberExists') };
20
22
  await client.inviteFriend(group_id, user_id);
21
- return { success: true, message: `已尝试邀请 ${user_id} 加入群 ${group_id}` };
23
+ return { success: true, message: t(context.locale, 'inviteAttempted', { p0: user_id, p1: group_id }) };
22
24
  },
23
25
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from "../../../../messages.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
4
  export default defineAgentTool<{ group_id: number; user_id: number }>({
@@ -7,14 +8,15 @@ export default defineAgentTool<{ group_id: number; user_id: number }>({
7
8
  user_id: z.number().describe('要邀请的 QQ号'),
8
9
  }),
9
10
  adapter: 'icqq',
11
+ scopes: ["group"],
10
12
  requiresApproval: 'always',
11
13
  async execute({ group_id, user_id }, context) {
12
14
  const client = context.$client;
13
15
  const groupInfo= client.pickGroup(group_id);
14
- if(!groupInfo) return { success: false, message: '目标群不存在' };
16
+ if(!groupInfo) return { success: false, message: t(context.locale, 'groupMissing') };
15
17
  const memberInfo= client.pickMember(group_id,user_id);
16
- if(memberInfo) return { success: false, message: '目标成员已加入群' };
18
+ if(memberInfo) return { success: false, message: t(context.locale, 'memberExists') };
17
19
  await client.inviteFriend(group_id, user_id);
18
- return { success: true, message: `已尝试邀请 ${user_id} 加入群 ${group_id}` };
20
+ return { success: true, message: t(context.locale, 'inviteAttempted', { p0: user_id, p1: group_id }) };
19
21
  },
20
22
  });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -6,22 +7,24 @@ export default defineAgentTool({
6
7
  inputSchema: z.object({
7
8
  group_id: z.number().describe('目标群号'),
8
9
  user_id: z.number().describe('要踢出的成员 QQ号'),
10
+ reason: z.string().min(1).describe('本次踢人的具体原因,随目标群和成员一起供人工确认'),
9
11
  }),
10
12
  adapter: 'icqq',
11
13
  scopes: ['group'],
12
14
  permissions: ['role(master,admin,trusted,owner)'],
13
- requiresApproval: 'once',
15
+ requiresApproval: 'human',
14
16
  async execute({ group_id, user_id }, context) {
15
17
  const client = context.$client;
16
- const selfInfo = client.pickMember(group_id, client.uin);
17
- if (!selfInfo.is_admin && !selfInfo.is_owner)
18
- return { success: false, message: '机器人不是群主或管理员,无法踢出成员' };
19
- if (selfInfo.user_id === user_id)
20
- return { success: false, message: '机器人不能踢出自己' };
21
- const memberInfo = client.pickMember(group_id, user_id);
22
- if (!memberInfo)
23
- return { success: false, message: '目标成员不存在' };
24
- await client.setGroupKick(group_id, user_id);
25
- return { success: true, message: `已踢出 ${user_id} 成员` };
18
+ const [self, member] = await Promise.all([
19
+ client.getGroupMemberInfo(group_id, client.uin, true),
20
+ client.getGroupMemberInfo(group_id, user_id, true),
21
+ ]);
22
+ if (user_id === client.uin || (self.role !== 'owner' && self.role !== 'admin')
23
+ || member.role !== 'member')
24
+ return { success: false, message: t(context.locale, 'kickForbidden') };
25
+ context.signal.throwIfAborted();
26
+ if (!await client.setGroupKick(group_id, user_id))
27
+ return { success: false, message: t(context.locale, 'kickUnconfirmed') };
28
+ return { success: true, message: t(context.locale, 'memberKicked', { p0: user_id }) };
26
29
  },
27
30
  });
@@ -1,23 +1,27 @@
1
+ import { messages as t } from "../../../../messages.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
- export default defineAgentTool<{ group_id: number; user_id: number }>({
4
+ export default defineAgentTool<{ group_id: number; user_id: number; reason: string }>({
4
5
  description: '踢出 QQ 群中的某个成员',
5
6
  inputSchema: z.object({
6
7
  group_id: z.number().describe('目标群号'),
7
8
  user_id: z.number().describe('要踢出的成员 QQ号'),
9
+ reason: z.string().min(1).describe('本次踢人的具体原因,随目标群和成员一起供人工确认'),
8
10
  }),
9
11
  adapter: 'icqq',
10
12
  scopes:['group'],
11
13
  permissions: ['role(master,admin,trusted,owner)'],
12
- requiresApproval: 'once',
14
+ requiresApproval: 'human',
13
15
  async execute({ group_id, user_id }, context) {
14
16
  const client = context.$client;
15
- const selfInfo= client.pickMember(group_id,client.uin);
16
- if(!selfInfo.is_admin && !selfInfo.is_owner) return { success: false, message: '机器人不是群主或管理员,无法踢出成员' };
17
- if(selfInfo.user_id === user_id) return { success: false, message: '机器人不能踢出自己' };
18
- const memberInfo= client.pickMember(group_id,user_id);
19
- if(!memberInfo) return { success: false, message: '目标成员不存在' };
20
- await client.setGroupKick(group_id, user_id);
21
- return { success: true, message: `已踢出 ${user_id} 成员` };
17
+ const [self, member] = await Promise.all([
18
+ client.getGroupMemberInfo(group_id, client.uin, true),
19
+ client.getGroupMemberInfo(group_id, user_id, true),
20
+ ]);
21
+ if (user_id === client.uin || (self.role !== 'owner' && self.role !== 'admin')
22
+ || member.role !== 'member') return { success: false, message: t(context.locale, 'kickForbidden') };
23
+ context.signal.throwIfAborted();
24
+ if (!await client.setGroupKick(group_id, user_id)) return { success: false, message: t(context.locale, 'kickUnconfirmed') };
25
+ return { success: true, message: t(context.locale, 'memberKicked', { p0: user_id }) };
22
26
  },
23
27
  });
@@ -0,0 +1,33 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { currentGroup } from '../../../../conversation.js';
5
+ import { messages as t } from '../../../../messages.js';
6
+ export default defineAgentTool({
7
+ description: '让机器人退出当前 QQ 群;仅主人可发起且每次人工审批,机器人是群主时拒绝执行以免解散群',
8
+ adapter: 'icqq',
9
+ scopes: ['group'],
10
+ permissions: ['role(master)'],
11
+ requiresApproval: 'human',
12
+ risk: 'dangerous',
13
+ riskCategory: 'member',
14
+ inputSchema: z.object({
15
+ group_id: z.number().int().positive().describe('当前群号,展示于本次退群审批'),
16
+ reason: z.string().min(1).describe('本次退群原因,供主人逐次确认'),
17
+ }),
18
+ async execute({ group_id }, context) {
19
+ if (currentGroup(context) !== group_id)
20
+ return { success: false, message: t(context.locale, 'leaveForbidden') };
21
+ const client = context.$client;
22
+ const [group, self] = await Promise.all([
23
+ client.getGroupInfo(group_id, true),
24
+ client.getGroupMemberInfo(group_id, client.uin, true),
25
+ ]);
26
+ if (group.owner_id === client.uin || (self.role !== 'admin' && self.role !== 'member')) {
27
+ return { success: false, message: t(context.locale, 'leaveForbidden') };
28
+ }
29
+ context.signal.throwIfAborted();
30
+ const success = await client.setGroupLeave(group_id);
31
+ return { success, message: t(context.locale, success ? 'groupLeft' : 'leaveUnconfirmed') };
32
+ },
33
+ });
@@ -0,0 +1,32 @@
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
+ import { z } from 'zod';
3
+ import { currentGroup } from '../../../../conversation.js';
4
+ import { messages as t } from '../../../../messages.js';
5
+
6
+ export default defineAgentTool({
7
+ description: '让机器人退出当前 QQ 群;仅主人可发起且每次人工审批,机器人是群主时拒绝执行以免解散群',
8
+ adapter: 'icqq',
9
+ scopes: ['group'],
10
+ permissions: ['role(master)'],
11
+ requiresApproval: 'human',
12
+ risk: 'dangerous',
13
+ riskCategory: 'member',
14
+ inputSchema: z.object({
15
+ group_id: z.number().int().positive().describe('当前群号,展示于本次退群审批'),
16
+ reason: z.string().min(1).describe('本次退群原因,供主人逐次确认'),
17
+ }),
18
+ async execute({ group_id }, context) {
19
+ if (currentGroup(context) !== group_id) return { success: false, message: t(context.locale, 'leaveForbidden') };
20
+ const client = context.$client;
21
+ const [group, self] = await Promise.all([
22
+ client.getGroupInfo(group_id, true),
23
+ client.getGroupMemberInfo(group_id, client.uin, true),
24
+ ]);
25
+ if (group.owner_id === client.uin || (self.role !== 'admin' && self.role !== 'member')) {
26
+ return { success: false, message: t(context.locale, 'leaveForbidden') };
27
+ }
28
+ context.signal.throwIfAborted();
29
+ const success = await client.setGroupLeave(group_id);
30
+ return { success, message: t(context.locale, success ? 'groupLeft' : 'leaveUnconfirmed') };
31
+ },
32
+ });
@@ -0,0 +1,33 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { currentGroup, recallMessage, resolveMessage } from '../../../../conversation.js';
5
+ import { messages as t } from '../../../../messages.js';
6
+ export default defineAgentTool({
7
+ description: '撤回当前 QQ 群内他人的真实消息;需调用方具备群管发起权限及机器人具备实时平台权限,无需逐次审批',
8
+ adapter: 'icqq',
9
+ scopes: ['group'],
10
+ permissions: ['role(master,admin,trusted,owner)'],
11
+ requiresApproval: 'never',
12
+ inputSchema: z.object({
13
+ message_id: z.string().min(1).describe('当前群中要撤回的真实消息 ID'),
14
+ reason: z.string().min(1).describe('撤回的具体原因,自动处理必须依据已确认的群规'),
15
+ }),
16
+ async execute({ message_id }, context) {
17
+ const group = currentGroup(context);
18
+ const message = await resolveMessage(context, message_id);
19
+ const client = context.$client;
20
+ // Own messages do not depend on membership administration rights.
21
+ if (message.sender.user_id === client.uin)
22
+ return recallMessage(context, message_id);
23
+ const [self, target] = await Promise.all([
24
+ client.getGroupMemberInfo(group, client.uin, true),
25
+ client.getGroupMemberInfo(group, message.sender.user_id, true),
26
+ ]);
27
+ if (!(self.role === 'owner' && (target.role === 'admin' || target.role === 'member'))
28
+ && !(self.role === 'admin' && target.role === 'member')) {
29
+ return { success: false, message: t(context.locale, 'recallForbidden') };
30
+ }
31
+ return recallMessage(context, message_id);
32
+ },
33
+ });
@@ -0,0 +1,32 @@
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
+ import { z } from 'zod';
3
+ import { currentGroup, recallMessage, resolveMessage } from '../../../../conversation.js';
4
+ import { messages as t } from '../../../../messages.js';
5
+
6
+ export default defineAgentTool({
7
+ description: '撤回当前 QQ 群内他人的真实消息;需调用方具备群管发起权限及机器人具备实时平台权限,无需逐次审批',
8
+ adapter: 'icqq',
9
+ scopes: ['group'],
10
+ permissions: ['role(master,admin,trusted,owner)'],
11
+ requiresApproval: 'never',
12
+ inputSchema: z.object({
13
+ message_id: z.string().min(1).describe('当前群中要撤回的真实消息 ID'),
14
+ reason: z.string().min(1).describe('撤回的具体原因,自动处理必须依据已确认的群规'),
15
+ }),
16
+ async execute({ message_id }, context) {
17
+ const group = currentGroup(context);
18
+ const message = await resolveMessage(context, message_id);
19
+ const client = context.$client;
20
+ // Own messages do not depend on membership administration rights.
21
+ if (message.sender.user_id === client.uin) return recallMessage(context, message_id);
22
+ const [self, target] = await Promise.all([
23
+ client.getGroupMemberInfo(group, client.uin, true),
24
+ client.getGroupMemberInfo(group, message.sender.user_id, true),
25
+ ]);
26
+ if (!(self.role === 'owner' && (target.role === 'admin' || target.role === 'member'))
27
+ && !(self.role === 'admin' && target.role === 'member')) {
28
+ return { success: false, message: t(context.locale, 'recallForbidden') };
29
+ }
30
+ return recallMessage(context, message_id);
31
+ },
32
+ });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -16,8 +17,8 @@ export default defineAgentTool({
16
17
  const on = enable ?? true;
17
18
  const selfInfo = client.pickMember(group_id, client.uin);
18
19
  if (!selfInfo.is_admin && !selfInfo.is_owner)
19
- return { success: false, message: '机器人不是群主或管理员,无法开启或关闭匿名聊天' };
20
+ return { success: false, message: t(context.locale, 'anonymousForbidden') };
20
21
  await client.setGroupAnonymous(group_id, on);
21
- return { success: true, message: on ? '已开启匿名聊天' : '已关闭匿名聊天' };
22
+ return { success: true, message: on ? t(context.locale, 'anonymousEnabled') : t(context.locale, 'anonymousDisabled') };
22
23
  },
23
24
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from "../../../../messages.js";
1
2
  import { defineAgentTool } from '@zhin.js/tool';
2
3
  import { z } from 'zod';
3
4
  export default defineAgentTool<{ group_id: number; enable?: boolean }>({
@@ -14,8 +15,8 @@ export default defineAgentTool<{ group_id: number; enable?: boolean }>({
14
15
  const client = context.$client;
15
16
  const on = enable ?? true;
16
17
  const selfInfo= client.pickMember(group_id,client.uin);
17
- if(!selfInfo.is_admin && !selfInfo.is_owner) return { success: false, message: '机器人不是群主或管理员,无法开启或关闭匿名聊天' };
18
+ if(!selfInfo.is_admin && !selfInfo.is_owner) return { success: false, message: t(context.locale, 'anonymousForbidden') };
18
19
  await client.setGroupAnonymous(group_id, on);
19
- return { success: true, message: on ? '已开启匿名聊天' : '已关闭匿名聊天' };
20
+ return { success: true, message: on ? t(context.locale, 'anonymousEnabled') : t(context.locale, 'anonymousDisabled') };
20
21
  },
21
22
  });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../../messages.js";
2
3
  import { defineAgentTool } from '@zhin.js/tool';
3
4
  import { z } from 'zod';
4
5
  export default defineAgentTool({
@@ -15,11 +16,11 @@ export default defineAgentTool({
15
16
  const client = context.$client;
16
17
  const selfInfo = client.pickMember(group_id, client.uin);
17
18
  if (!selfInfo.is_admin && !selfInfo.is_owner)
18
- return { success: false, message: '机器人不是群主或管理员,无法禁言/解除禁言成员' };
19
+ return { success: false, message: t(context.locale, 'muteForbidden') };
19
20
  const memberInfo = client.pickMember(group_id, user_id);
20
21
  if (!memberInfo)
21
- return { success: false, message: '目标成员不存在' };
22
+ return { success: false, message: t(context.locale, 'memberMissing') };
22
23
  await client.setGroupBan(group_id, user_id, duration === 0 ? 0 : duration);
23
- return { success: true, message: `已${duration === 0 ? '解除' : ''}禁言 ${user_id} 成员${duration === 0 ? '' : `(${duration}秒)`}` };
24
+ return { success: true, message: duration === 0 ? t(context.locale, 'unmuted', { user: user_id }) : t(context.locale, 'muted', { user: user_id, seconds: duration ?? 0 }) };
24
25
  },
25
26
  });