@zhin.js/adapter-napcat 3.0.1 → 4.0.1

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 (140) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +43 -96
  3. package/adapters/napcat.ts +39 -0
  4. package/agent/tools/ai_tts.ts +21 -0
  5. package/agent/tools/del_group_notice.ts +22 -0
  6. package/agent/tools/delete_essence_msg.ts +21 -0
  7. package/agent/tools/delete_friend.ts +20 -0
  8. package/agent/tools/download_file.ts +19 -0
  9. package/agent/tools/forward_single_msg.ts +32 -0
  10. package/agent/tools/get_ai_characters.ts +19 -0
  11. package/agent/tools/get_essence_list.ts +19 -0
  12. package/agent/tools/get_friend_msg_history.ts +20 -0
  13. package/agent/tools/get_group_file_url.ts +21 -0
  14. package/agent/tools/get_group_info_ex.ts +19 -0
  15. package/agent/tools/get_group_msg_history.ts +21 -0
  16. package/agent/tools/get_group_notice.ts +19 -0
  17. package/agent/tools/get_group_root_files.ts +19 -0
  18. package/agent/tools/get_group_shut_list.ts +19 -0
  19. package/agent/tools/get_mini_app_ark.ts +22 -0
  20. package/agent/tools/get_user_status.ts +18 -0
  21. package/agent/tools/group_sign.ts +20 -0
  22. package/agent/tools/mark_msg_as_read.ts +19 -0
  23. package/agent/tools/ocr_image.ts +18 -0
  24. package/agent/tools/send_forward_msg.ts +31 -0
  25. package/agent/tools/send_group_notice.ts +23 -0
  26. package/agent/tools/send_like.ts +20 -0
  27. package/agent/tools/send_poke.ts +20 -0
  28. package/agent/tools/set_avatar.ts +19 -0
  29. package/agent/tools/set_emoji_reaction.ts +20 -0
  30. package/agent/tools/set_essence_msg.ts +21 -0
  31. package/agent/tools/set_group_portrait.ts +22 -0
  32. package/agent/tools/set_online_status.ts +20 -0
  33. package/agent/tools/set_profile.ts +23 -0
  34. package/agent/tools/set_signature.ts +19 -0
  35. package/agent/tools/set_title.ts +23 -0
  36. package/agent/tools/translate.ts +18 -0
  37. package/agent/tools/upload_group_file.ts +23 -0
  38. package/lib/http-endpoint.d.ts +26 -0
  39. package/lib/http-endpoint.js +147 -0
  40. package/lib/index.d.ts +11 -21
  41. package/lib/index.js +10 -59
  42. package/lib/napcat-agent-deps.d.ts +51 -0
  43. package/lib/napcat-agent-deps.js +33 -0
  44. package/lib/napcat-inbound.d.ts +12 -5
  45. package/lib/napcat-inbound.js +28 -13
  46. package/lib/onebot-get-msg.d.ts +13 -2
  47. package/lib/onebot-get-msg.js +0 -1
  48. package/lib/protocol.d.ts +151 -0
  49. package/lib/protocol.js +217 -0
  50. package/lib/webhook.d.ts +2 -0
  51. package/lib/webhook.js +14 -0
  52. package/lib/ws-endpoint.d.ts +61 -0
  53. package/lib/ws-endpoint.js +357 -0
  54. package/lib/ws-transport.d.ts +13 -0
  55. package/lib/ws-transport.js +75 -0
  56. package/lib/ws-types.d.ts +17 -0
  57. package/lib/ws-types.js +1 -0
  58. package/lib/wss-auth.d.ts +2 -0
  59. package/lib/wss-auth.js +16 -0
  60. package/lib/wss-endpoint.d.ts +25 -0
  61. package/lib/wss-endpoint.js +157 -0
  62. package/package.json +48 -32
  63. package/plugin.ts +13 -0
  64. package/schema.json +48 -0
  65. package/src/http-endpoint.ts +197 -0
  66. package/src/index.ts +66 -82
  67. package/src/napcat-agent-deps.ts +95 -0
  68. package/src/napcat-inbound.ts +34 -10
  69. package/src/onebot-get-msg.ts +8 -2
  70. package/src/protocol.ts +373 -0
  71. package/src/webhook.ts +16 -0
  72. package/src/ws-endpoint.ts +452 -0
  73. package/src/ws-transport.ts +105 -0
  74. package/src/ws-types.ts +20 -0
  75. package/src/wss-auth.ts +17 -0
  76. package/src/wss-endpoint.ts +205 -0
  77. package/client/NapCatManagement.tsx +0 -113
  78. package/client/index.tsx +0 -11
  79. package/client/tsconfig.json +0 -7
  80. package/client/utils/api.ts +0 -30
  81. package/dist/index.js +0 -27
  82. package/lib/adapter.d.ts +0 -36
  83. package/lib/adapter.d.ts.map +0 -1
  84. package/lib/adapter.js +0 -102
  85. package/lib/adapter.js.map +0 -1
  86. package/lib/agent-prompt.d.ts +0 -3
  87. package/lib/agent-prompt.d.ts.map +0 -1
  88. package/lib/agent-prompt.js +0 -106
  89. package/lib/agent-prompt.js.map +0 -1
  90. package/lib/endpoint-base.d.ts +0 -144
  91. package/lib/endpoint-base.d.ts.map +0 -1
  92. package/lib/endpoint-base.js +0 -341
  93. package/lib/endpoint-base.js.map +0 -1
  94. package/lib/endpoint-http.d.ts +0 -17
  95. package/lib/endpoint-http.d.ts.map +0 -1
  96. package/lib/endpoint-http.js +0 -106
  97. package/lib/endpoint-http.js.map +0 -1
  98. package/lib/endpoint-ws-client.d.ts +0 -20
  99. package/lib/endpoint-ws-client.d.ts.map +0 -1
  100. package/lib/endpoint-ws-client.js +0 -139
  101. package/lib/endpoint-ws-client.js.map +0 -1
  102. package/lib/endpoint-ws-server.d.ts +0 -20
  103. package/lib/endpoint-ws-server.d.ts.map +0 -1
  104. package/lib/endpoint-ws-server.js +0 -137
  105. package/lib/endpoint-ws-server.js.map +0 -1
  106. package/lib/index.d.ts.map +0 -1
  107. package/lib/index.js.map +0 -1
  108. package/lib/napcat-inbound.d.ts.map +0 -1
  109. package/lib/napcat-inbound.js.map +0 -1
  110. package/lib/onebot-get-msg.d.ts.map +0 -1
  111. package/lib/onebot-get-msg.js.map +0 -1
  112. package/lib/routes.d.ts +0 -4
  113. package/lib/routes.d.ts.map +0 -1
  114. package/lib/routes.js +0 -61
  115. package/lib/routes.js.map +0 -1
  116. package/lib/segment-mapper.d.ts +0 -2
  117. package/lib/segment-mapper.d.ts.map +0 -1
  118. package/lib/segment-mapper.js +0 -2
  119. package/lib/segment-mapper.js.map +0 -1
  120. package/lib/tools.d.ts +0 -8
  121. package/lib/tools.d.ts.map +0 -1
  122. package/lib/tools.js +0 -605
  123. package/lib/tools.js.map +0 -1
  124. package/lib/types.d.ts +0 -275
  125. package/lib/types.d.ts.map +0 -1
  126. package/lib/types.js +0 -6
  127. package/lib/types.js.map +0 -1
  128. package/plugin.yml +0 -3
  129. package/src/adapter.ts +0 -109
  130. package/src/agent-prompt.ts +0 -116
  131. package/src/endpoint-base.ts +0 -386
  132. package/src/endpoint-http.ts +0 -95
  133. package/src/endpoint-ws-client.ts +0 -137
  134. package/src/endpoint-ws-server.ts +0 -136
  135. package/src/routes.ts +0 -61
  136. package/src/segment-mapper.ts +0 -1
  137. package/src/tools.ts +0 -632
  138. package/src/types.ts +0 -266
  139. /package/{skills/napcat → agent}/PERMITS.md +0 -0
  140. /package/{skills/napcat/SKILL.md → agent/skills/napcat.md} +0 -0
package/src/tools.ts DELETED
@@ -1,632 +0,0 @@
1
- /**
2
- * NapCat 扩展 Tool 注册
3
- * 覆盖 go-cqhttp 扩展与 NapCat 独有 API,全部通过 AI Tool 系统暴露。
4
- */
5
- import type { ContextInjectableKey, Tool, ToolScope } from 'zhin.js';
6
- import type { NapCatAdapter, NapCatEndpoint } from './adapter.js';
7
-
8
- function getEndpoint(adapter: NapCatAdapter, endpointId: string): NapCatEndpoint {
9
- const endpoint = adapter.endpoints.get(endpointId);
10
- if (!endpoint) throw new Error(`Endpoint ${endpointId} not found`);
11
- return endpoint;
12
- }
13
-
14
- type PropertyType = 'string' | 'number' | 'boolean' | 'object' | 'array';
15
-
16
- interface ToolSpec {
17
- name: string;
18
- description: string;
19
- params: Record<string, { type: PropertyType; description: string; default?: any; enum?: string[]; contextKey?: ContextInjectableKey }>;
20
- required: string[];
21
- execute: (adapter: NapCatAdapter, args: Record<string, any>) => Promise<any>;
22
- keywords: string[];
23
- permit?: string;
24
- scopes?: ToolScope[];
25
- preExecutable?: boolean;
26
- }
27
-
28
- const NAPCAT_TOOL_SPECS: ToolSpec[] = [
29
- // ── 消息与社交 ──────────────────────────────────────────────────
30
- {
31
- name: 'napcat_send_poke',
32
- description: '戳一戳(群聊或私聊)。group_id 不传时为私聊戳一戳。',
33
- params: {
34
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
35
- user_id: { type: 'number', description: '目标用户 QQ 号' },
36
- group_id: { type: 'number', description: '群号(不传则为私聊戳一戳)' },
37
- },
38
- required: ['endpoint_id', 'user_id'],
39
- keywords: ['戳一戳', 'poke', '戳', '拍一拍'],
40
- execute: async (adapter, args) => {
41
- const endpoint = getEndpoint(adapter, args.endpoint_id);
42
- await endpoint.sendPoke(args.user_id, args.group_id);
43
- return { success: true, message: `已戳 ${args.user_id}` };
44
- },
45
- },
46
- {
47
- name: 'napcat_set_emoji_reaction',
48
- description: '为消息添加表情回应(贴表情)。',
49
- params: {
50
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
51
- message_id: { type: 'number', description: '消息 ID' },
52
- emoji_id: { type: 'string', description: '表情 ID' },
53
- },
54
- required: ['endpoint_id', 'message_id', 'emoji_id'],
55
- keywords: ['表情回应', 'reaction', '贴表情', 'emoji'],
56
- execute: async (adapter, args) => {
57
- const endpoint = getEndpoint(adapter, args.endpoint_id);
58
- await endpoint.setMsgEmojiLike(args.message_id, args.emoji_id);
59
- return { success: true };
60
- },
61
- },
62
- {
63
- name: 'napcat_send_forward_msg',
64
- description: '发送合并转发消息(群聊或私聊)。messages 为转发节点数组。',
65
- params: {
66
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
67
- message_type: { type: 'string', description: 'private 或 group', enum: ['private', 'group'] },
68
- id: { type: 'number', description: '群号或 QQ 号' },
69
- messages: { type: 'string', description: '转发节点 JSON(node 数组)' },
70
- },
71
- required: ['endpoint_id', 'message_type', 'id', 'messages'],
72
- keywords: ['合并转发', 'forward', '转发消息'],
73
- execute: async (adapter, args) => {
74
- const endpoint = getEndpoint(adapter, args.endpoint_id);
75
- const messages = typeof args.messages === 'string' ? JSON.parse(args.messages) : args.messages;
76
- const result = await endpoint.sendForwardMsg(args.message_type, args.id, messages);
77
- return result;
78
- },
79
- },
80
- {
81
- name: 'napcat_forward_single_msg',
82
- description: '转发单条消息到指定好友或群。',
83
- params: {
84
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
85
- target_type: { type: 'string', description: 'friend 或 group', enum: ['friend', 'group'] },
86
- target_id: { type: 'number', description: '目标好友 QQ 号或群号' },
87
- message_id: { type: 'number', description: '要转发的消息 ID' },
88
- },
89
- required: ['endpoint_id', 'target_type', 'target_id', 'message_id'],
90
- keywords: ['转发', 'forward', '单条转发'],
91
- execute: async (adapter, args) => {
92
- const endpoint = getEndpoint(adapter, args.endpoint_id);
93
- if (args.target_type === 'friend') await endpoint.forwardFriendSingleMsg(args.target_id, args.message_id);
94
- else await endpoint.forwardGroupSingleMsg(args.target_id, args.message_id);
95
- return { success: true };
96
- },
97
- },
98
- {
99
- name: 'napcat_send_like',
100
- description: '给好友点赞(每人每天最多 10 次)。',
101
- params: {
102
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
103
- user_id: { type: 'number', description: '目标 QQ 号' },
104
- times: { type: 'number', description: '点赞次数(1-10)', default: 1 },
105
- },
106
- required: ['endpoint_id', 'user_id'],
107
- keywords: ['点赞', 'like', '赞', '好友赞'],
108
- execute: async (adapter, args) => {
109
- const endpoint = getEndpoint(adapter, args.endpoint_id);
110
- await endpoint.sendLike(args.user_id, args.times || 1);
111
- return { success: true, message: `已给 ${args.user_id} 点赞 ${args.times || 1} 次` };
112
- },
113
- },
114
-
115
- // ── 精华消息 ────────────────────────────────────────────────────
116
- {
117
- name: 'napcat_set_essence_msg',
118
- description: '设置群精华消息。',
119
- params: {
120
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
121
- message_id: { type: 'number', description: '消息 ID' },
122
- },
123
- required: ['endpoint_id', 'message_id'],
124
- keywords: ['精华', 'essence', '设精', '加精'],
125
- permit: 'platform(napcat,scene_admin)',
126
- scopes: ['group'],
127
- execute: async (adapter, args) => {
128
- const endpoint = getEndpoint(adapter, args.endpoint_id);
129
- await endpoint.setEssenceMsg(args.message_id);
130
- return { success: true };
131
- },
132
- },
133
- {
134
- name: 'napcat_delete_essence_msg',
135
- description: '移除群精华消息。',
136
- params: {
137
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
138
- message_id: { type: 'number', description: '消息 ID' },
139
- },
140
- required: ['endpoint_id', 'message_id'],
141
- keywords: ['取消精华', '移除精华', 'delete essence'],
142
- permit: 'platform(napcat,scene_admin)',
143
- scopes: ['group'],
144
- execute: async (adapter, args) => {
145
- const endpoint = getEndpoint(adapter, args.endpoint_id);
146
- await endpoint.deleteEssenceMsg(args.message_id);
147
- return { success: true };
148
- },
149
- },
150
- {
151
- name: 'napcat_get_essence_list',
152
- description: '获取群精华消息列表。',
153
- params: {
154
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
155
- group_id: { type: 'number', description: '群号' },
156
- },
157
- required: ['endpoint_id', 'group_id'],
158
- keywords: ['精华列表', 'essence list'],
159
- preExecutable: true,
160
- scopes: ['group'],
161
- execute: async (adapter, args) => {
162
- const endpoint = getEndpoint(adapter, args.endpoint_id);
163
- return endpoint.getEssenceMsgList(args.group_id);
164
- },
165
- },
166
-
167
- // ── 群公告 ──────────────────────────────────────────────────────
168
- {
169
- name: 'napcat_send_group_notice',
170
- description: '发送群公告。',
171
- params: {
172
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
173
- group_id: { type: 'number', description: '群号' },
174
- content: { type: 'string', description: '公告内容' },
175
- image: { type: 'string', description: '图片(URL 或 base64,可选)' },
176
- },
177
- required: ['endpoint_id', 'group_id', 'content'],
178
- keywords: ['群公告', 'notice', '公告', '发公告'],
179
- permit: 'platform(napcat,scene_admin)',
180
- scopes: ['group'],
181
- execute: async (adapter, args) => {
182
- const endpoint = getEndpoint(adapter, args.endpoint_id);
183
- await endpoint.sendGroupNotice(args.group_id, args.content, args.image);
184
- return { success: true };
185
- },
186
- },
187
- {
188
- name: 'napcat_get_group_notice',
189
- description: '获取群公告列表。',
190
- params: {
191
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
192
- group_id: { type: 'number', description: '群号' },
193
- },
194
- required: ['endpoint_id', 'group_id'],
195
- keywords: ['群公告', '获取公告', 'get notice'],
196
- preExecutable: true,
197
- scopes: ['group'],
198
- execute: async (adapter, args) => {
199
- const endpoint = getEndpoint(adapter, args.endpoint_id);
200
- return endpoint.getGroupNotice(args.group_id);
201
- },
202
- },
203
- {
204
- name: 'napcat_del_group_notice',
205
- description: '删除群公告。',
206
- params: {
207
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
208
- group_id: { type: 'number', description: '群号' },
209
- notice_id: { type: 'string', description: '公告 ID' },
210
- },
211
- required: ['endpoint_id', 'group_id', 'notice_id'],
212
- keywords: ['删除公告', 'delete notice'],
213
- permit: 'platform(napcat,scene_admin)',
214
- scopes: ['group'],
215
- execute: async (adapter, args) => {
216
- const endpoint = getEndpoint(adapter, args.endpoint_id);
217
- await endpoint.deleteGroupNotice(args.group_id, args.notice_id);
218
- return { success: true };
219
- },
220
- },
221
-
222
- // ── 群文件 ──────────────────────────────────────────────────────
223
- {
224
- name: 'napcat_upload_group_file',
225
- description: '上传文件到群。file 为本地路径或 URL。',
226
- params: {
227
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
228
- group_id: { type: 'number', description: '群号' },
229
- file: { type: 'string', description: '文件路径或 URL' },
230
- name: { type: 'string', description: '文件名' },
231
- folder: { type: 'string', description: '目标文件夹 ID(可选)' },
232
- },
233
- required: ['endpoint_id', 'group_id', 'file', 'name'],
234
- keywords: ['上传文件', 'upload file', '群文件'],
235
- scopes: ['group'],
236
- execute: async (adapter, args) => {
237
- const endpoint = getEndpoint(adapter, args.endpoint_id);
238
- await endpoint.uploadGroupFile(args.group_id, args.file, args.name, args.folder);
239
- return { success: true };
240
- },
241
- },
242
- {
243
- name: 'napcat_get_group_file_url',
244
- description: '获取群文件下载链接。',
245
- params: {
246
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
247
- group_id: { type: 'number', description: '群号' },
248
- file_id: { type: 'string', description: '文件 ID' },
249
- busid: { type: 'number', description: '文件类型 ID' },
250
- },
251
- required: ['endpoint_id', 'group_id', 'file_id', 'busid'],
252
- keywords: ['文件链接', 'file url', '下载文件'],
253
- preExecutable: true,
254
- scopes: ['group'],
255
- execute: async (adapter, args) => {
256
- const endpoint = getEndpoint(adapter, args.endpoint_id);
257
- return endpoint.getGroupFileUrl(args.group_id, args.file_id, args.busid);
258
- },
259
- },
260
- {
261
- name: 'napcat_get_group_root_files',
262
- description: '获取群根目录文件列表。',
263
- params: {
264
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
265
- group_id: { type: 'number', description: '群号' },
266
- },
267
- required: ['endpoint_id', 'group_id'],
268
- keywords: ['群文件列表', 'group files'],
269
- preExecutable: true,
270
- scopes: ['group'],
271
- execute: async (adapter, args) => {
272
- const endpoint = getEndpoint(adapter, args.endpoint_id);
273
- return endpoint.getGroupRootFiles(args.group_id);
274
- },
275
- },
276
-
277
- // ── 群管理增强 ──────────────────────────────────────────────────
278
- {
279
- name: 'napcat_get_group_shut_list',
280
- description: '获取群禁言列表。',
281
- params: {
282
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
283
- group_id: { type: 'number', description: '群号' },
284
- },
285
- required: ['endpoint_id', 'group_id'],
286
- keywords: ['禁言列表', 'shut list', '被禁言'],
287
- preExecutable: true,
288
- scopes: ['group'],
289
- execute: async (adapter, args) => {
290
- const endpoint = getEndpoint(adapter, args.endpoint_id);
291
- return endpoint.getGroupShutList(args.group_id);
292
- },
293
- },
294
- {
295
- name: 'napcat_set_group_portrait',
296
- description: '设置群头像。file 为图片 URL 或 base64。',
297
- params: {
298
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
299
- group_id: { type: 'number', description: '群号' },
300
- file: { type: 'string', description: '图片(URL 或 base64)' },
301
- },
302
- required: ['endpoint_id', 'group_id', 'file'],
303
- keywords: ['群头像', 'group portrait', '设置群头像'],
304
- permit: 'platform(napcat,scene_admin)',
305
- scopes: ['group'],
306
- execute: async (adapter, args) => {
307
- const endpoint = getEndpoint(adapter, args.endpoint_id);
308
- await endpoint.setGroupPortrait(args.group_id, args.file);
309
- return { success: true };
310
- },
311
- },
312
- {
313
- name: 'napcat_set_title',
314
- description: '设置群成员专属头衔。需要群主权限。',
315
- params: {
316
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
317
- group_id: { type: 'number', description: '群号' },
318
- user_id: { type: 'number', description: '目标成员 QQ 号' },
319
- title: { type: 'string', description: '头衔文字' },
320
- },
321
- required: ['endpoint_id', 'group_id', 'user_id', 'title'],
322
- keywords: ['头衔', 'title', '专属头衔', '设置头衔'],
323
- permit: 'platform(napcat,scene_owner)',
324
- scopes: ['group'],
325
- execute: async (adapter, args) => {
326
- const endpoint = getEndpoint(adapter, args.endpoint_id);
327
- await endpoint.setTitle(args.group_id, args.user_id, args.title);
328
- return { success: true, message: `已设置 ${args.user_id} 头衔为 "${args.title}"` };
329
- },
330
- },
331
- {
332
- name: 'napcat_group_sign',
333
- description: '群签到/群打卡。',
334
- params: {
335
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
336
- group_id: { type: 'number', description: '群号' },
337
- },
338
- required: ['endpoint_id', 'group_id'],
339
- keywords: ['签到', '打卡', 'sign', 'check in'],
340
- scopes: ['group'],
341
- execute: async (adapter, args) => {
342
- const endpoint = getEndpoint(adapter, args.endpoint_id);
343
- await endpoint.sendGroupSign(args.group_id);
344
- return { success: true };
345
- },
346
- },
347
-
348
- // ── AI 与多媒体 ────────────────────────────────────────────────
349
- {
350
- name: 'napcat_ai_tts',
351
- description: 'AI 文字转语音,在群聊中发送 AI 语音消息。',
352
- params: {
353
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
354
- group_id: { type: 'number', description: '群号' },
355
- character: { type: 'string', description: 'AI 语音角色 ID(可先用 napcat_get_ai_characters 查询)' },
356
- text: { type: 'string', description: '要转为语音的文字' },
357
- },
358
- required: ['endpoint_id', 'group_id', 'character', 'text'],
359
- keywords: ['AI语音', 'TTS', '文字转语音', 'ai record'],
360
- scopes: ['group'],
361
- execute: async (adapter, args) => {
362
- const endpoint = getEndpoint(adapter, args.endpoint_id);
363
- return endpoint.sendGroupAiRecord(args.group_id, args.character, args.text);
364
- },
365
- },
366
- {
367
- name: 'napcat_get_ai_characters',
368
- description: '获取 AI 语音角色列表,用于 napcat_ai_tts 的 character 参数。',
369
- params: {
370
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
371
- group_id: { type: 'number', description: '群号' },
372
- },
373
- required: ['endpoint_id', 'group_id'],
374
- keywords: ['AI角色', 'ai characters', '语音角色'],
375
- preExecutable: true,
376
- scopes: ['group'],
377
- execute: async (adapter, args) => {
378
- const endpoint = getEndpoint(adapter, args.endpoint_id);
379
- return endpoint.getAiCharacters(args.group_id);
380
- },
381
- },
382
- {
383
- name: 'napcat_ocr_image',
384
- description: '图片 OCR 文字识别。',
385
- params: {
386
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
387
- image: { type: 'string', description: '图片 file 参数(收到消息中的 file 字段或 URL)' },
388
- },
389
- required: ['endpoint_id', 'image'],
390
- keywords: ['OCR', '文字识别', '图片识别', 'ocr'],
391
- preExecutable: true,
392
- execute: async (adapter, args) => {
393
- const endpoint = getEndpoint(adapter, args.endpoint_id);
394
- return endpoint.ocrImage(args.image);
395
- },
396
- },
397
- {
398
- name: 'napcat_get_mini_app_ark',
399
- description: '签名小程序卡片(如 B 站分享卡片等)。',
400
- params: {
401
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
402
- type: { type: 'string', description: '卡片类型' },
403
- title: { type: 'string', description: '标题' },
404
- desc: { type: 'string', description: '描述' },
405
- pic_url: { type: 'string', description: '图片 URL' },
406
- jump_url: { type: 'string', description: '跳转 URL' },
407
- },
408
- required: ['endpoint_id', 'type', 'title', 'desc', 'pic_url', 'jump_url'],
409
- keywords: ['小程序', 'mini app', '卡片', 'ark'],
410
- execute: async (adapter, args) => {
411
- const endpoint = getEndpoint(adapter, args.endpoint_id);
412
- return endpoint.getMiniAppArk(args.type, args.title, args.desc, args.pic_url, args.jump_url);
413
- },
414
- },
415
-
416
- // ── 消息历史 ────────────────────────────────────────────────────
417
- {
418
- name: 'napcat_get_group_msg_history',
419
- description: '获取群消息历史记录。',
420
- params: {
421
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
422
- group_id: { type: 'number', description: '群号' },
423
- message_seq: { type: 'number', description: '起始消息序号(可选,不传从最新开始)' },
424
- count: { type: 'number', description: '获取条数(可选)' },
425
- },
426
- required: ['endpoint_id', 'group_id'],
427
- keywords: ['群消息历史', '聊天记录', 'message history'],
428
- preExecutable: true,
429
- scopes: ['group'],
430
- execute: async (adapter, args) => {
431
- const endpoint = getEndpoint(adapter, args.endpoint_id);
432
- return endpoint.getGroupMsgHistory(args.group_id, args.message_seq, args.count);
433
- },
434
- },
435
- {
436
- name: 'napcat_get_friend_msg_history',
437
- description: '获取私聊消息历史记录。',
438
- params: {
439
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
440
- user_id: { type: 'number', description: 'QQ 号' },
441
- message_seq: { type: 'number', description: '起始消息序号(可选)' },
442
- count: { type: 'number', description: '获取条数(可选)' },
443
- },
444
- required: ['endpoint_id', 'user_id'],
445
- keywords: ['私聊记录', '好友聊天记录', 'friend history'],
446
- preExecutable: true,
447
- execute: async (adapter, args) => {
448
- const endpoint = getEndpoint(adapter, args.endpoint_id);
449
- return endpoint.getFriendMsgHistory(args.user_id, args.message_seq, args.count);
450
- },
451
- },
452
-
453
- // ── 信息查询 ────────────────────────────────────────────────────
454
- {
455
- name: 'napcat_get_user_status',
456
- description: '获取用户在线状态。',
457
- params: {
458
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
459
- user_id: { type: 'number', description: '目标 QQ 号' },
460
- },
461
- required: ['endpoint_id', 'user_id'],
462
- keywords: ['在线状态', '用户状态', 'online status'],
463
- preExecutable: true,
464
- execute: async (adapter, args) => {
465
- const endpoint = getEndpoint(adapter, args.endpoint_id);
466
- return endpoint.ncGetUserStatus(args.user_id);
467
- },
468
- },
469
- {
470
- name: 'napcat_get_group_info_ex',
471
- description: '获取群组额外详细信息。',
472
- params: {
473
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
474
- group_id: { type: 'number', description: '群号' },
475
- },
476
- required: ['endpoint_id', 'group_id'],
477
- keywords: ['群详情', '群额外信息', 'group info ex'],
478
- preExecutable: true,
479
- scopes: ['group'],
480
- execute: async (adapter, args) => {
481
- const endpoint = getEndpoint(adapter, args.endpoint_id);
482
- return endpoint.getGroupInfoEx(args.group_id);
483
- },
484
- },
485
-
486
- // ── 个人设置 ────────────────────────────────────────────────────
487
- {
488
- name: 'napcat_set_profile',
489
- description: '修改 QQ 资料(昵称等)。',
490
- params: {
491
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
492
- nickname: { type: 'string', description: '昵称' },
493
- company: { type: 'string', description: '公司(可选)' },
494
- email: { type: 'string', description: '邮箱(可选)' },
495
- college: { type: 'string', description: '学校(可选)' },
496
- personal_note: { type: 'string', description: '个人说明(可选)' },
497
- },
498
- required: ['endpoint_id', 'nickname'],
499
- keywords: ['修改资料', '设置昵称', 'profile', 'set profile'],
500
- execute: async (adapter, args) => {
501
- const endpoint = getEndpoint(adapter, args.endpoint_id);
502
- await endpoint.setQQProfile(args.nickname, args.company, args.email, args.college, args.personal_note);
503
- return { success: true };
504
- },
505
- },
506
- {
507
- name: 'napcat_set_avatar',
508
- description: '修改 QQ 头像。',
509
- params: {
510
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
511
- file: { type: 'string', description: '图片(URL 或 base64)' },
512
- },
513
- required: ['endpoint_id', 'file'],
514
- keywords: ['头像', 'avatar', '设置头像', '换头像'],
515
- execute: async (adapter, args) => {
516
- const endpoint = getEndpoint(adapter, args.endpoint_id);
517
- await endpoint.setQQAvatar(args.file);
518
- return { success: true };
519
- },
520
- },
521
- {
522
- name: 'napcat_set_online_status',
523
- description: '设置在线状态(在线、隐身、忙碌等)。',
524
- params: {
525
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
526
- status: { type: 'number', description: '状态码(11=在线, 21=离开, 31=隐身, 41=忙碌, 50=请勿打扰, 60=Q我吧)' },
527
- ext_status: { type: 'number', description: '扩展状态码', default: 0 },
528
- },
529
- required: ['endpoint_id', 'status'],
530
- keywords: ['在线状态', '隐身', '忙碌', 'online', 'status'],
531
- execute: async (adapter, args) => {
532
- const endpoint = getEndpoint(adapter, args.endpoint_id);
533
- await endpoint.setOnlineStatus(args.status, args.ext_status || 0);
534
- return { success: true };
535
- },
536
- },
537
- {
538
- name: 'napcat_set_signature',
539
- description: '设置个人签名(个性签名)。',
540
- params: {
541
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
542
- signature: { type: 'string', description: '签名内容' },
543
- },
544
- required: ['endpoint_id', 'signature'],
545
- keywords: ['签名', '个性签名', 'signature', 'longnick'],
546
- execute: async (adapter, args) => {
547
- const endpoint = getEndpoint(adapter, args.endpoint_id);
548
- await endpoint.setSelfLongnick(args.signature);
549
- return { success: true };
550
- },
551
- },
552
- {
553
- name: 'napcat_translate',
554
- description: '英译中翻译。',
555
- params: {
556
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
557
- text: { type: 'string', description: '要翻译的英文文本' },
558
- },
559
- required: ['endpoint_id', 'text'],
560
- keywords: ['翻译', 'translate', '英译中'],
561
- preExecutable: true,
562
- execute: async (adapter, args) => {
563
- const endpoint = getEndpoint(adapter, args.endpoint_id);
564
- return endpoint.translateEn2Zh(args.text);
565
- },
566
- },
567
- {
568
- name: 'napcat_mark_msg_as_read',
569
- description: '标记消息为已读。',
570
- params: {
571
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
572
- message_id: { type: 'number', description: '消息 ID' },
573
- },
574
- required: ['endpoint_id', 'message_id'],
575
- keywords: ['已读', 'mark read', '标记已读'],
576
- execute: async (adapter, args) => {
577
- const endpoint = getEndpoint(adapter, args.endpoint_id);
578
- await endpoint.markMsgAsRead(args.message_id);
579
- return { success: true };
580
- },
581
- },
582
- {
583
- name: 'napcat_download_file',
584
- description: '下载文件到 NapCat 缓存目录,返回本地路径。',
585
- params: {
586
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
587
- url: { type: 'string', description: '文件 URL' },
588
- thread_count: { type: 'number', description: '下载线程数(可选,默认 1)', default: 1 },
589
- },
590
- required: ['endpoint_id', 'url'],
591
- keywords: ['下载', 'download', '下载文件'],
592
- execute: async (adapter, args) => {
593
- const endpoint = getEndpoint(adapter, args.endpoint_id);
594
- return endpoint.downloadFile(args.url, args.thread_count || 1);
595
- },
596
- },
597
- {
598
- name: 'napcat_delete_friend',
599
- description: '删除好友。',
600
- params: {
601
- endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
602
- user_id: { type: 'number', description: '好友 QQ 号' },
603
- },
604
- required: ['endpoint_id', 'user_id'],
605
- keywords: ['删除好友', 'delete friend', '删好友'],
606
- permit: 'platform(napcat,scene_admin)',
607
- execute: async (adapter, args) => {
608
- const endpoint = getEndpoint(adapter, args.endpoint_id);
609
- await endpoint.deleteFriend(args.user_id);
610
- return { success: true };
611
- },
612
- },
613
- ];
614
-
615
- export function createNapCatTools(adapter: NapCatAdapter): Tool[] {
616
- return NAPCAT_TOOL_SPECS.map((spec) => ({
617
- name: spec.name,
618
- description: spec.description,
619
- parameters: {
620
- type: 'object' as const,
621
- properties: spec.params,
622
- required: spec.required,
623
- },
624
- execute: (args: Record<string, any>) => spec.execute(adapter, args),
625
- tags: ['napcat', 'qq'],
626
- keywords: spec.keywords,
627
- platforms: ['napcat'],
628
- ...(spec.permit ? { permissions: [spec.permit] } : {}),
629
- scopes: spec.scopes || (['group', 'private'] as ToolScope[]),
630
- preExecutable: spec.preExecutable,
631
- }));
632
- }