dsh-shlr-bilitoolkit 0.1.17 → 0.1.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/AGENTS.md +5 -6
- package/dist/dsh.d.ts +2 -0
- package/dist/dsh.js +111 -80
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
(Agent 必读)
|
|
1
|
+
# AGENTS.md — dsh-shlr-bilitoolkit(Agent 必读)
|
|
2
2
|
|
|
3
3
|
## 登录(务必遵守)
|
|
4
|
-
用户要登录 B
|
|
5
|
-
**必须调用
|
|
6
|
-
|
|
7
|
-
禁止:只给链接、用 ASCII/文本二维码、让用户自己跑命令。用户扫码确认后调用 `bili_login_status` 完成登录并保存 Cookie。
|
|
4
|
+
用户要登录 B 站,或任何操作返回未登录(-101 / 未登录 / CookieError)时:
|
|
5
|
+
**必须调用 bili_gen_qr,并把返回的二维码图片展示给用户扫码**——用 qrDataUrl 以 Markdown 图片 `` 渲染(或引用 qrImageUrl / qrImagePath)。
|
|
6
|
+
禁止只给链接、用 ASCII、让用户自己跑命令。用户确认后调 bili_login_status 完成登录。
|
|
8
7
|
|
|
9
8
|
## 其它
|
|
10
|
-
-
|
|
9
|
+
- 非常驻的 B 站能力懒加载:`bili_open()` 看分组,`bili_open({ group })` 打开(下一轮生效)。
|
|
11
10
|
- 写操作会真实修改账号状态,执行前先与用户确认。
|
package/dist/dsh.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export interface DshTool {
|
|
|
30
30
|
* 这里统一处理:丢 undefined、NaN/Infinity 转 null、bigint 转字符串。
|
|
31
31
|
*/
|
|
32
32
|
export declare function toLosslessJson(value: unknown): unknown;
|
|
33
|
+
/** 列表工具统一出口:full=true 返回完整 toDict,否则瘦身。 */
|
|
34
|
+
export declare function listPayload(items: any[], full: boolean, keep?: string[]): any[];
|
|
33
35
|
export declare const TOOLS: DshTool[];
|
|
34
36
|
export declare const CORE_IDS: string[];
|
|
35
37
|
export declare const GROUPS: Record<string, {
|
package/dist/dsh.js
CHANGED
|
@@ -109,21 +109,51 @@ export function toLosslessJson(value) {
|
|
|
109
109
|
}
|
|
110
110
|
return value; // string / boolean / null / undefined
|
|
111
111
|
}
|
|
112
|
+
// ---- 列表返回瘦身 ----
|
|
113
|
+
// 工具结果会进历史、之后每轮重发,所以列表默认只返回关键字段 + 更少条数;
|
|
114
|
+
// full=true 时返回完整 toDict。HEAVY_KEYS 是各类模型里普遍偏长 / 噪音的字段。
|
|
115
|
+
const HEAVY_KEYS = [
|
|
116
|
+
"cover", "cover_url", "description", "desc", "avatar", "avatar_url",
|
|
117
|
+
"face", "pic", "first_frame", "badge", "badge_url", "jump_url",
|
|
118
|
+
];
|
|
119
|
+
const VIDEO_KEEP = [
|
|
120
|
+
"bvid", "title", "author", "view", "danmaku", "duration", "pubdate", "link",
|
|
121
|
+
];
|
|
122
|
+
function slimDict(d, keep) {
|
|
123
|
+
if (keep) {
|
|
124
|
+
const out = {};
|
|
125
|
+
for (const k of keep)
|
|
126
|
+
if (k in d)
|
|
127
|
+
out[k] = d[k];
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
const out = {};
|
|
131
|
+
for (const [k, v] of Object.entries(d))
|
|
132
|
+
if (!HEAVY_KEYS.includes(k))
|
|
133
|
+
out[k] = v;
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
/** 列表工具统一出口:full=true 返回完整 toDict,否则瘦身。 */
|
|
137
|
+
export function listPayload(items, full, keep) {
|
|
138
|
+
const dicts = items.map((x) => (x && typeof x.toDict === "function" ? x.toDict() : x));
|
|
139
|
+
return full ? dicts : dicts.map((d) => slimDict(d, keep));
|
|
140
|
+
}
|
|
112
141
|
export const TOOLS = [
|
|
113
142
|
{
|
|
114
143
|
id: "bili_recommend",
|
|
115
|
-
description: "获取 B 站首页推荐视频流,返回视频列表(标题 / UP主 / 播放量 /
|
|
144
|
+
description: "获取 B 站首页推荐视频流,返回视频列表(标题 / UP主 / 播放量 / 链接)。默认精简字段,full=true 返回完整字段。",
|
|
116
145
|
parameters: {
|
|
117
146
|
type: "object",
|
|
118
147
|
properties: {
|
|
119
148
|
pages: { type: "integer", description: "抓取页数", default: 1 },
|
|
120
149
|
pageSize: { type: "integer", description: "每页条数", default: 10 },
|
|
150
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
121
151
|
},
|
|
122
152
|
},
|
|
123
153
|
handler: async (a) => {
|
|
124
154
|
const c = await getClient();
|
|
125
155
|
const videos = await c.video.recommend(Number(a.pages ?? 1), Number(a.pageSize ?? 10));
|
|
126
|
-
return videos.
|
|
156
|
+
return listPayload(videos, Boolean(a.full ?? false), VIDEO_KEEP);
|
|
127
157
|
},
|
|
128
158
|
},
|
|
129
159
|
{
|
|
@@ -162,7 +192,7 @@ export const TOOLS = [
|
|
|
162
192
|
},
|
|
163
193
|
{
|
|
164
194
|
id: "bili_search",
|
|
165
|
-
description: "搜索 B
|
|
195
|
+
description: "搜索 B 站视频或用户。默认精简字段,full=true 返回完整字段。",
|
|
166
196
|
parameters: {
|
|
167
197
|
type: "object",
|
|
168
198
|
properties: {
|
|
@@ -174,19 +204,21 @@ export const TOOLS = [
|
|
|
174
204
|
default: "totalrank",
|
|
175
205
|
description: "排序(仅视频)",
|
|
176
206
|
},
|
|
177
|
-
pageSize: { type: "integer", default:
|
|
207
|
+
pageSize: { type: "integer", default: 10 },
|
|
208
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
178
209
|
},
|
|
179
210
|
required: ["keyword"],
|
|
180
211
|
},
|
|
181
212
|
handler: async (a) => {
|
|
182
213
|
const c = await getClient();
|
|
183
|
-
const
|
|
214
|
+
const full = Boolean(a.full ?? false);
|
|
215
|
+
const ps = Number(a.pageSize ?? 10);
|
|
184
216
|
if (String(a.type ?? "video") === "user") {
|
|
185
217
|
const [users, total] = await c.search.users(a.keyword, 1, ps);
|
|
186
|
-
return { total, users: users
|
|
218
|
+
return { total, users: listPayload(users, full) };
|
|
187
219
|
}
|
|
188
220
|
const [videos, total] = await c.search.videos(a.keyword, 1, ps, a.order ?? "totalrank");
|
|
189
|
-
return { total, videos: videos
|
|
221
|
+
return { total, videos: listPayload(videos, full, VIDEO_KEEP) };
|
|
190
222
|
},
|
|
191
223
|
},
|
|
192
224
|
{
|
|
@@ -204,7 +236,7 @@ export const TOOLS = [
|
|
|
204
236
|
},
|
|
205
237
|
{
|
|
206
238
|
id: "bili_space_videos",
|
|
207
|
-
description: "获取某 UP
|
|
239
|
+
description: "获取某 UP 主的投稿视频列表。默认精简字段,full=true 返回完整字段。",
|
|
208
240
|
parameters: {
|
|
209
241
|
type: "object",
|
|
210
242
|
properties: {
|
|
@@ -214,14 +246,15 @@ export const TOOLS = [
|
|
|
214
246
|
enum: ["pubdate", "click", "stow"],
|
|
215
247
|
default: "pubdate",
|
|
216
248
|
},
|
|
217
|
-
pageSize: { type: "integer", default:
|
|
249
|
+
pageSize: { type: "integer", default: 10 },
|
|
250
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
218
251
|
},
|
|
219
252
|
required: ["uid"],
|
|
220
253
|
},
|
|
221
254
|
handler: async (a) => {
|
|
222
255
|
const c = await getClient();
|
|
223
|
-
const [videos, total] = await c.space.videos(Number(a.uid), 1, Number(a.pageSize ??
|
|
224
|
-
return { total, videos: videos.
|
|
256
|
+
const [videos, total] = await c.space.videos(Number(a.uid), 1, Number(a.pageSize ?? 10), a.order ?? "pubdate");
|
|
257
|
+
return { total, videos: listPayload(videos, Boolean(a.full ?? false), VIDEO_KEEP) };
|
|
225
258
|
},
|
|
226
259
|
},
|
|
227
260
|
// ---- 专栏 ----
|
|
@@ -237,70 +270,76 @@ export const TOOLS = [
|
|
|
237
270
|
},
|
|
238
271
|
{
|
|
239
272
|
id: "bili_article_list",
|
|
240
|
-
description: "获取某 UP
|
|
273
|
+
description: "获取某 UP 主的专栏列表。默认精简字段,full=true 返回完整字段。",
|
|
241
274
|
parameters: {
|
|
242
275
|
type: "object",
|
|
243
276
|
properties: {
|
|
244
277
|
mid: { type: "integer" },
|
|
245
|
-
pageSize: { type: "integer", default:
|
|
278
|
+
pageSize: { type: "integer", default: 10 },
|
|
279
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
246
280
|
},
|
|
247
281
|
required: ["mid"],
|
|
248
282
|
},
|
|
249
283
|
handler: async (a) => {
|
|
250
284
|
const c = await getClient();
|
|
251
|
-
const [articles, total] = await c.article.listByUser(Number(a.mid), 1, Number(a.pageSize ??
|
|
252
|
-
return { total, articles: articles.
|
|
285
|
+
const [articles, total] = await c.article.listByUser(Number(a.mid), 1, Number(a.pageSize ?? 10));
|
|
286
|
+
return { total, articles: listPayload(articles, Boolean(a.full ?? false)) };
|
|
253
287
|
},
|
|
254
288
|
},
|
|
255
289
|
// ---- 动态 ----
|
|
256
290
|
{
|
|
257
291
|
id: "bili_dynamic_feed",
|
|
258
|
-
description: "
|
|
292
|
+
description: "获取「关注」动态流(需登录),返回动态列表。默认精简字段,full=true 返回完整字段。",
|
|
259
293
|
parameters: {
|
|
260
294
|
type: "object",
|
|
261
295
|
properties: {
|
|
262
296
|
page: { type: "integer", default: 1 },
|
|
263
297
|
type: { type: "string", default: "all" },
|
|
298
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
264
299
|
},
|
|
265
300
|
},
|
|
266
301
|
handler: async (a) => {
|
|
267
302
|
const c = await getClient();
|
|
268
303
|
const [items, offset, hasMore] = await c.dynamic.feed(Number(a.page ?? 1), undefined, a.type ?? "all");
|
|
269
|
-
return { offset, hasMore, dynamics: items.
|
|
304
|
+
return { offset, hasMore, dynamics: listPayload(items, Boolean(a.full ?? false)) };
|
|
270
305
|
},
|
|
271
306
|
},
|
|
272
307
|
{
|
|
273
308
|
id: "bili_dynamic_space",
|
|
274
|
-
description: "
|
|
309
|
+
description: "获取某用户的动态列表。默认精简字段,full=true 返回完整字段。",
|
|
275
310
|
parameters: {
|
|
276
311
|
type: "object",
|
|
277
|
-
properties: {
|
|
312
|
+
properties: {
|
|
313
|
+
uid: { type: "integer" },
|
|
314
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
315
|
+
},
|
|
278
316
|
required: ["uid"],
|
|
279
317
|
},
|
|
280
318
|
handler: async (a) => {
|
|
281
319
|
const c = await getClient();
|
|
282
320
|
const [items, offset, hasMore, total] = await c.dynamic.space(Number(a.uid));
|
|
283
|
-
return { total, offset, hasMore, dynamics: items.
|
|
321
|
+
return { total, offset, hasMore, dynamics: listPayload(items, Boolean(a.full ?? false)) };
|
|
284
322
|
},
|
|
285
323
|
},
|
|
286
324
|
// ---- 评论 ----
|
|
287
325
|
{
|
|
288
326
|
id: "bili_comment_list",
|
|
289
|
-
description: "获取评论列表(视频 / 动态 /
|
|
327
|
+
description: "获取评论列表(视频 / 动态 / 专栏)。默认精简字段,full=true 返回完整字段。",
|
|
290
328
|
parameters: {
|
|
291
329
|
type: "object",
|
|
292
330
|
properties: {
|
|
293
331
|
target: { type: "string", enum: ["video", "dynamic", "article"], default: "video" },
|
|
294
332
|
id: { type: "string", description: "视频 bvid / 动态 id / 专栏 cv 号" },
|
|
295
333
|
sort: { type: "string", enum: ["time", "like", "reply"], default: "time" },
|
|
296
|
-
pageSize: { type: "integer", default:
|
|
334
|
+
pageSize: { type: "integer", default: 10 },
|
|
335
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
297
336
|
},
|
|
298
337
|
required: ["id"],
|
|
299
338
|
},
|
|
300
339
|
handler: async (a) => {
|
|
301
340
|
const c = await getClient();
|
|
302
341
|
const target = String(a.target ?? "video");
|
|
303
|
-
const ps = Number(a.pageSize ??
|
|
342
|
+
const ps = Number(a.pageSize ?? 10);
|
|
304
343
|
const sort = a.sort ?? "time";
|
|
305
344
|
let items;
|
|
306
345
|
if (target === "dynamic")
|
|
@@ -309,28 +348,29 @@ export const TOOLS = [
|
|
|
309
348
|
[items] = await c.comment.listArticle(a.id, 1, ps, sort);
|
|
310
349
|
else
|
|
311
350
|
[items] = await c.comment.listVideo(a.id, 1, ps, sort);
|
|
312
|
-
return { comments: items.
|
|
351
|
+
return { comments: listPayload(items, Boolean(a.full ?? false)) };
|
|
313
352
|
},
|
|
314
353
|
},
|
|
315
354
|
// ---- 关注关系 ----
|
|
316
355
|
{
|
|
317
356
|
id: "bili_relation_list",
|
|
318
|
-
description: "
|
|
357
|
+
description: "获取某用户的关注列表或粉丝列表。默认精简字段,full=true 返回完整字段。",
|
|
319
358
|
parameters: {
|
|
320
359
|
type: "object",
|
|
321
360
|
properties: {
|
|
322
361
|
uid: { type: "integer" },
|
|
323
362
|
type: { type: "string", enum: ["followings", "followers"], default: "followings" },
|
|
324
|
-
pageSize: { type: "integer", default:
|
|
363
|
+
pageSize: { type: "integer", default: 10 },
|
|
364
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
325
365
|
},
|
|
326
366
|
required: ["uid"],
|
|
327
367
|
},
|
|
328
368
|
handler: async (a) => {
|
|
329
369
|
const c = await getClient();
|
|
330
370
|
const [users, total] = String(a.type ?? "followings") === "followers"
|
|
331
|
-
? await c.relation.followers(Number(a.uid), 1, Number(a.pageSize ??
|
|
332
|
-
: await c.relation.followings(Number(a.uid), 1, Number(a.pageSize ??
|
|
333
|
-
return { total, users: users.
|
|
371
|
+
? await c.relation.followers(Number(a.uid), 1, Number(a.pageSize ?? 10))
|
|
372
|
+
: await c.relation.followings(Number(a.uid), 1, Number(a.pageSize ?? 10));
|
|
373
|
+
return { total, users: listPayload(users, Boolean(a.full ?? false)) };
|
|
334
374
|
},
|
|
335
375
|
},
|
|
336
376
|
// ---- 消息中心 ----
|
|
@@ -545,37 +585,43 @@ export const TOOLS = [
|
|
|
545
585
|
},
|
|
546
586
|
{
|
|
547
587
|
id: "bili_space_collection",
|
|
548
|
-
description: "
|
|
588
|
+
description: "获取某个合集内的视频列表。默认精简字段,full=true 返回完整字段。",
|
|
549
589
|
parameters: {
|
|
550
590
|
type: "object",
|
|
551
591
|
properties: {
|
|
552
592
|
seasonId: { type: "integer" },
|
|
553
593
|
mid: { type: "integer", description: "UP 主 uid(可选,用于正确 Referer)" },
|
|
554
|
-
pageSize: { type: "integer", default:
|
|
594
|
+
pageSize: { type: "integer", default: 10 },
|
|
595
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
555
596
|
},
|
|
556
597
|
required: ["seasonId"],
|
|
557
598
|
},
|
|
558
599
|
handler: async (a) => {
|
|
559
|
-
const [col, videos, total] = await (await getClient()).space.collection(Number(a.seasonId), 1, Number(a.pageSize ??
|
|
560
|
-
return {
|
|
600
|
+
const [col, videos, total] = await (await getClient()).space.collection(Number(a.seasonId), 1, Number(a.pageSize ?? 10), a.mid != null ? Number(a.mid) : undefined);
|
|
601
|
+
return {
|
|
602
|
+
collection: col.toDict(),
|
|
603
|
+
total,
|
|
604
|
+
videos: listPayload(videos, Boolean(a.full ?? false), VIDEO_KEEP),
|
|
605
|
+
};
|
|
561
606
|
},
|
|
562
607
|
},
|
|
563
608
|
// ---- 收藏夹 ----
|
|
564
609
|
{
|
|
565
610
|
id: "bili_fav_folder_videos",
|
|
566
|
-
description: "
|
|
611
|
+
description: "获取某个收藏夹内的视频列表(需登录)。默认精简字段,full=true 返回完整字段。",
|
|
567
612
|
parameters: {
|
|
568
613
|
type: "object",
|
|
569
614
|
properties: {
|
|
570
615
|
folderId: { type: "integer" },
|
|
571
616
|
order: { type: "string", enum: ["mtime", "view", "pubtime"], default: "mtime" },
|
|
572
|
-
pageSize: { type: "integer", default:
|
|
617
|
+
pageSize: { type: "integer", default: 10 },
|
|
618
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
573
619
|
},
|
|
574
620
|
required: ["folderId"],
|
|
575
621
|
},
|
|
576
622
|
handler: async (a) => {
|
|
577
|
-
const [videos, total] = await (await getClient()).interact.folderVideos(Number(a.folderId), 1, Number(a.pageSize ??
|
|
578
|
-
return { total, videos: videos.
|
|
623
|
+
const [videos, total] = await (await getClient()).interact.folderVideos(Number(a.folderId), 1, Number(a.pageSize ?? 10), a.order ?? "mtime");
|
|
624
|
+
return { total, videos: listPayload(videos, Boolean(a.full ?? false), VIDEO_KEEP) };
|
|
579
625
|
},
|
|
580
626
|
},
|
|
581
627
|
{
|
|
@@ -708,14 +754,15 @@ export const TOOLS = [
|
|
|
708
754
|
},
|
|
709
755
|
{
|
|
710
756
|
id: "bili_comment_replies",
|
|
711
|
-
description: "
|
|
757
|
+
description: "获取某条评论下的楼中楼回复列表。默认精简字段,full=true 返回完整字段。",
|
|
712
758
|
parameters: {
|
|
713
759
|
type: "object",
|
|
714
760
|
properties: {
|
|
715
761
|
target: { type: "string", enum: ["video", "dynamic", "article"], default: "video" },
|
|
716
762
|
id: { type: "string" },
|
|
717
763
|
rootRpid: { type: "integer", description: "根评论 rpid" },
|
|
718
|
-
pageSize: { type: "integer", default:
|
|
764
|
+
pageSize: { type: "integer", default: 10 },
|
|
765
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
719
766
|
},
|
|
720
767
|
required: ["id", "rootRpid"],
|
|
721
768
|
},
|
|
@@ -723,7 +770,7 @@ export const TOOLS = [
|
|
|
723
770
|
const c = await getClient();
|
|
724
771
|
const target = String(a.target ?? "video");
|
|
725
772
|
const root = Number(a.rootRpid);
|
|
726
|
-
const ps = Number(a.pageSize ??
|
|
773
|
+
const ps = Number(a.pageSize ?? 10);
|
|
727
774
|
let items;
|
|
728
775
|
if (target === "video")
|
|
729
776
|
[items] = await c.comment.repliesVideo(a.id, root, 1, ps);
|
|
@@ -733,7 +780,7 @@ export const TOOLS = [
|
|
|
733
780
|
[items] = await c.comment.repliesArticle(a.id, root, 1, ps);
|
|
734
781
|
else
|
|
735
782
|
throw new Error("target 只支持 video / dynamic / article");
|
|
736
|
-
return { replies: items.
|
|
783
|
+
return { replies: listPayload(items, Boolean(a.full ?? false)) };
|
|
737
784
|
},
|
|
738
785
|
},
|
|
739
786
|
{
|
|
@@ -827,11 +874,12 @@ export const TOOLS = [
|
|
|
827
874
|
// ---- 消息中心补充 ----
|
|
828
875
|
{
|
|
829
876
|
id: "bili_notify_list",
|
|
830
|
-
description: "消息中心列表:回复我的 / @我的 /
|
|
877
|
+
description: "消息中心列表:回复我的 / @我的 / 收到的赞(需登录)。默认精简字段,full=true 返回完整字段。",
|
|
831
878
|
parameters: {
|
|
832
879
|
type: "object",
|
|
833
880
|
properties: {
|
|
834
881
|
type: { type: "string", enum: ["replies", "ats", "likes"], default: "replies" },
|
|
882
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
835
883
|
},
|
|
836
884
|
},
|
|
837
885
|
handler: async (a) => {
|
|
@@ -844,7 +892,7 @@ export const TOOLS = [
|
|
|
844
892
|
[items] = await c.notify.likes();
|
|
845
893
|
else
|
|
846
894
|
[items] = await c.notify.replies();
|
|
847
|
-
return { notices: items.
|
|
895
|
+
return { notices: listPayload(items, Boolean(a.full ?? false)) };
|
|
848
896
|
},
|
|
849
897
|
},
|
|
850
898
|
// ---- 私信补充 ----
|
|
@@ -856,18 +904,19 @@ export const TOOLS = [
|
|
|
856
904
|
},
|
|
857
905
|
{
|
|
858
906
|
id: "bili_message_history",
|
|
859
|
-
description: "
|
|
907
|
+
description: "获取与某用户的私信聊天记录(需登录)。默认精简字段,full=true 返回完整字段。",
|
|
860
908
|
parameters: {
|
|
861
909
|
type: "object",
|
|
862
910
|
properties: {
|
|
863
911
|
talkerUid: { type: "integer" },
|
|
864
|
-
size: { type: "integer", default:
|
|
912
|
+
size: { type: "integer", default: 10 },
|
|
913
|
+
full: { type: "boolean", default: false, description: "true 返回完整字段" },
|
|
865
914
|
},
|
|
866
915
|
required: ["talkerUid"],
|
|
867
916
|
},
|
|
868
917
|
handler: async (a) => {
|
|
869
|
-
const msgs = await (await getClient()).message.history(Number(a.talkerUid), Number(a.size ??
|
|
870
|
-
return { messages: msgs.
|
|
918
|
+
const msgs = await (await getClient()).message.history(Number(a.talkerUid), Number(a.size ?? 10));
|
|
919
|
+
return { messages: listPayload(msgs, Boolean(a.full ?? false)) };
|
|
871
920
|
},
|
|
872
921
|
},
|
|
873
922
|
{
|
|
@@ -1074,7 +1123,6 @@ const MAX_OPEN_GROUPS = 3;
|
|
|
1074
1123
|
export const CORE_IDS = [
|
|
1075
1124
|
"bili_gen_qr",
|
|
1076
1125
|
"bili_login_status",
|
|
1077
|
-
"bili_cache_clear",
|
|
1078
1126
|
"bili_recommend",
|
|
1079
1127
|
"bili_video_detail",
|
|
1080
1128
|
"bili_search",
|
|
@@ -1097,6 +1145,7 @@ export const GROUPS = {
|
|
|
1097
1145
|
message: { hint: "私信:发送 / 未读 / 聊天记录 / 撤回", ids: ["bili_send_message", "bili_message_unread", "bili_message_history", "bili_message_recall"] },
|
|
1098
1146
|
notify: { hint: "消息中心:未读 / 回复·@·赞 列表", ids: ["bili_notify_unread", "bili_notify_list"] },
|
|
1099
1147
|
profile: { hint: "个人资料:查看 / 修改", ids: ["bili_profile_info", "bili_profile_update"] },
|
|
1148
|
+
misc: { hint: "维护:清空本地缓存", ids: ["bili_cache_clear"] },
|
|
1100
1149
|
};
|
|
1101
1150
|
const TOOL_BY_ID = new Map(TOOLS.map((t) => [t.id, t]));
|
|
1102
1151
|
function groupOfTool(id) {
|
|
@@ -1143,31 +1192,29 @@ function buildDef(tool) {
|
|
|
1143
1192
|
return defineTool(options);
|
|
1144
1193
|
}
|
|
1145
1194
|
const lazyTools = [
|
|
1146
|
-
{
|
|
1147
|
-
id: "bili_catalog",
|
|
1148
|
-
description: "列出 B 站能力分组与每组包含的工具。要用某个 B 站能力但不确定工具名时,先调本工具,再调 bili_open 打开对应分组(打开后下一轮起该组工具可调用)。",
|
|
1149
|
-
parameters: { type: "object", properties: {} },
|
|
1150
|
-
handler: async () => ({
|
|
1151
|
-
groups: Object.entries(GROUPS).map(([name, g]) => ({
|
|
1152
|
-
group: name,
|
|
1153
|
-
hint: g.hint,
|
|
1154
|
-
tools: g.ids,
|
|
1155
|
-
open: openGroups.has(name),
|
|
1156
|
-
})),
|
|
1157
|
-
how: "bili_open({ group }) 或 bili_open({ tool }) 打开;bili_close({ group }) 关闭以节省上下文。",
|
|
1158
|
-
}),
|
|
1159
|
-
},
|
|
1160
1195
|
{
|
|
1161
1196
|
id: "bili_open",
|
|
1162
|
-
description: "
|
|
1197
|
+
description: "B 站能力开关。不带参数调用=列出所有能力分组;带 group(分组名)或 tool(工具名)调用=打开该组,打开后下一轮起可调用。同时最多保留 3 组,超出自动关闭最久未用的。",
|
|
1163
1198
|
parameters: {
|
|
1164
1199
|
type: "object",
|
|
1165
1200
|
properties: {
|
|
1166
|
-
group: { type: "string", description: "
|
|
1201
|
+
group: { type: "string", description: "分组名(不带参调用可列出)" },
|
|
1167
1202
|
tool: { type: "string", description: "或直接给工具名,自动打开其所在组" },
|
|
1168
1203
|
},
|
|
1169
1204
|
},
|
|
1170
1205
|
handler: async (a) => {
|
|
1206
|
+
// 不带参数:列出能力目录
|
|
1207
|
+
if (a.group == null && a.tool == null) {
|
|
1208
|
+
return {
|
|
1209
|
+
groups: Object.entries(GROUPS).map(([name, g]) => ({
|
|
1210
|
+
group: name,
|
|
1211
|
+
hint: g.hint,
|
|
1212
|
+
tools: g.ids,
|
|
1213
|
+
open: openGroups.has(name),
|
|
1214
|
+
})),
|
|
1215
|
+
how: "带 group 或 tool 再次调用本工具即可打开;同时最多保留 3 组。",
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1171
1218
|
if (!toolsRegistry) {
|
|
1172
1219
|
return { ok: false, message: "当前运行时不支持动态注册,懒加载不可用" };
|
|
1173
1220
|
}
|
|
@@ -1212,22 +1259,6 @@ const lazyTools = [
|
|
|
1212
1259
|
return { ok: true, group, tools: loaded, note: "该组工具已打开,下一轮起可调用。" };
|
|
1213
1260
|
},
|
|
1214
1261
|
},
|
|
1215
|
-
{
|
|
1216
|
-
id: "bili_close",
|
|
1217
|
-
description: "关闭一组已打开的 B 站工具,释放上下文。不确定分组名先用 bili_catalog。",
|
|
1218
|
-
parameters: {
|
|
1219
|
-
type: "object",
|
|
1220
|
-
properties: { group: { type: "string" } },
|
|
1221
|
-
required: ["group"],
|
|
1222
|
-
},
|
|
1223
|
-
handler: async (a) => {
|
|
1224
|
-
const group = String(a.group ?? "").trim();
|
|
1225
|
-
if (!openGroups.has(group))
|
|
1226
|
-
return { ok: false, message: "该组未打开" };
|
|
1227
|
-
closeGroup(group);
|
|
1228
|
-
return { ok: true, closed: group };
|
|
1229
|
-
},
|
|
1230
|
-
},
|
|
1231
1262
|
];
|
|
1232
1263
|
/** 用最可用的注册入口注册一个内部工具。 */
|
|
1233
1264
|
function registerOne(ctx, tool) {
|