dsh-shlr-bilitoolkit 0.1.26 → 0.1.28
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 +10 -3
- package/README.md +2 -2
- package/dist/apis/dynamic.d.ts +0 -1
- package/dist/apis/dynamic.js +5 -9
- package/dist/dsh.js +16 -10
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -5,9 +5,16 @@
|
|
|
5
5
|
**必须调用 bili_gen_qr,并把返回的二维码图片展示给用户扫码**——用 qrDataUrl 以 Markdown 图片 `` 渲染(或引用 qrImageUrl / qrImagePath)。
|
|
6
6
|
禁止只给链接、用 ASCII、让用户自己跑命令。用户确认后调 bili_login_status 完成登录。
|
|
7
7
|
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
## 能力按需加载
|
|
9
|
+
除常驻工具(bili_gen_qr / bili_login_status / bili_recommend / bili_video_detail / bili_search / bili_open)外,其它 B 站能力默认**懒加载**:
|
|
10
|
+
1. 先调 `bili_open()`(不带参数)看有哪些分组、每组含哪些工具;
|
|
11
|
+
2. 再 `bili_open({ group: "comment" })` 或直接 `bili_open({ tool: "bili_comment_list" })` 打开;
|
|
12
|
+
3. **下一轮起**该组工具才可调用。打开的组会一直保留,不会被回收。
|
|
13
|
+
|
|
14
|
+
## 多步查询走 run_code(省 token)
|
|
15
|
+
需要多个 B 站数据时(如「视频详情 + 热评 + UP主资料」),写进 `run_code` 一段代码里完成,不要连续调用多个工具:
|
|
16
|
+
- 独立的只读调用用 `Promise.all` 并发;写操作保持逐条 `await`(串行,也避免风控)。
|
|
17
|
+
- **只 `return` / `console.log` 你需要的字段**——中间工具的完整返回不会进对话,能大幅减少 token。
|
|
11
18
|
|
|
12
19
|
## 其它
|
|
13
20
|
写操作(点赞 / 收藏 / 投币 / 关注 / 评论 / 私信 / 三连 / 发动态 / 改资料)会真实修改账号状态,执行前先与用户确认。
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-shlr-bilitoolkit
|
|
2
2
|
|
|
3
|
-
0.1.
|
|
3
|
+
0.1.28 起默认恢复「工具懒加载」(按需开组,`BILI_LAZY=0` 可关)
|
|
4
4
|
|
|
5
5
|
B 站(哔哩哔哩)接口封装的 **TypeScript** 移植版,作为 [dsh](https://dshmp.com)(DeepSeek Harness)插件提供「视频 / 搜索 / 空间」等读取能力。
|
|
6
6
|
|
|
@@ -80,7 +80,7 @@ const [ups, _] = await client.space.videos(574115689, 1, 10);
|
|
|
80
80
|
- **数据目录**:Cookie / 缓存 / 二维码 / 设备号统一放在一个目录里,默认 `bili_data/`(相对 dsh 工作目录),避免散落污染工作目录。可用 `BILI_DATA_DIR` 改目录;`BILI_COOKIE_FILE` / `BILI_CACHE_FILE` / `BILI_QR_FILE` / `BILI_DEVICE_FILE` 可精确指定单个文件。设备号(私信 `dev_id`)会落盘到 `bili_data/bili_device.json`,跨重启保持稳定,避免被 B 站当成新设备触发风控。兼容旧版:若新目录还没有 Cookie、而旧位置(`./bili_cookies.json`)有,会继续沿用旧的。
|
|
81
81
|
- **扫码登录(独立获取 Cookie)**:运行 `npm run login`,终端会打印 ASCII 二维码,用「哔哩哔哩」App 扫码并确认后,Cookie 自动写入 `bili_data/bili_cookies.json`。也可在对话里先调 `bili_login_status` 查登录态、调 `bili_gen_qr` 拿二维码链接与可直接展示的 `ascii` 二维码。写操作(点赞 / 收藏 / 投币 / 关注 / 评论 / 私信 / 三连)都依赖该 Cookie 中的 `SESSDATA` / `bili_jct`。
|
|
82
82
|
- **缓存持久化**:除 Cookie 外,客户端还会把 WBI 签名密钥(`B 站每天轮换`)、`bvid→aid` 映射这类稳定 / 带 TTL 的数据写入本地 JSON 缓存(`BILI_CACHE_FILE`,默认 `bili_data/bili_cache.json`),用临时文件 + 原子替换落盘、文件损坏会自动自愈。冷启动或跨进程时直接复用,避免每次都请求 `nav` 接口;密钥过期或失效时 `refresh()` 会重新拉取并覆盖缓存。若签名反复报 `-403/-352`,可调用 `bili_cache_clear` 强制清空缓存后重试(不影响 Cookie / 登录态)。
|
|
83
|
-
- **计费 /
|
|
83
|
+
- **计费 / 缓存与懒加载**:默认**按需加载(懒加载)**——49 个工具 schema 约 5200 token,常驻太占上下文窗口;默认只注册「常驻核心 + `bili_open`」约 700 token,其余 `bili_open({ group })` 按需开组(下一轮生效),且**开过不回收**、前缀很快稳定、持续吃缓存命中。`BILI_LAZY=0` 退回全量注册(前缀稳定、命中最大化,适合不在意窗口);`BILI_LAZY_EVICT=1` 可按 LRU 限制同时开组数(上限 `BILI_LAZY_EVICT_MAX`,默认 3)。列表类工具默认**精简返回**(`full=true` 取全量)。
|
|
84
84
|
|
|
85
85
|
> **给 Agent 的约定**:仓库根目录的 [`AGENTS.md`](./AGENTS.md) 写明了登录流程——需要登录时必须调用 `bili_gen_qr` 并把二维码**图片**展示给用户,而不是只给链接或 ASCII。把这份 `AGENTS.md` 放到 dsh 的工作目录(或确保你的 dsh 会读取它),agent 就会按约定输出登录二维码。
|
|
86
86
|
|
package/dist/apis/dynamic.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ import { Dynamic } from "../models.js";
|
|
|
8
8
|
export declare class DynamicAPI {
|
|
9
9
|
private client;
|
|
10
10
|
constructor(client: BiliClient);
|
|
11
|
-
private _detailCache;
|
|
12
11
|
detail(dynamicId: string | number): Promise<Dynamic>;
|
|
13
12
|
feed(page?: number, offset?: string, type?: string): Promise<[Dynamic[], string, boolean]>;
|
|
14
13
|
space(uid: number, offset?: string): Promise<[Dynamic[], string, boolean, number]>;
|
package/dist/apis/dynamic.js
CHANGED
|
@@ -26,19 +26,15 @@ export class DynamicAPI {
|
|
|
26
26
|
client;
|
|
27
27
|
constructor(client) {
|
|
28
28
|
this.client = client;
|
|
29
|
-
this._detailCache = {};
|
|
30
29
|
}
|
|
31
|
-
_detailCache;
|
|
32
30
|
async detail(dynamicId) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return cached;
|
|
31
|
+
// 动态 id 常超出 JS 安全整数范围(>2^53),绝不能过 Number,否则丢精度、接口报 4101105
|
|
32
|
+
// 不做内存缓存:动态可能被删/改,缓存会返回脏数据,而它只省 HTTP、不省 LLM token。
|
|
33
|
+
const id = String(dynamicId);
|
|
37
34
|
const payload = await this.client.get(endpoints.DYNAMIC_DETAIL, { id, features: FEATURES }, { Referer: `https://t.bilibili.com/${id}` });
|
|
38
35
|
const dynamic = Dynamic.fromApi((payload?.data ?? {}).item);
|
|
39
36
|
if (!dynamic)
|
|
40
37
|
throw new BiliApiError("未找到该动态");
|
|
41
|
-
this._detailCache[id] = dynamic;
|
|
42
38
|
return dynamic;
|
|
43
39
|
}
|
|
44
40
|
async feed(page = 1, offset, type = "all") {
|
|
@@ -182,7 +178,7 @@ export class DynamicAPI {
|
|
|
182
178
|
}
|
|
183
179
|
async repost(dynamicId, text = "") {
|
|
184
180
|
const form = {
|
|
185
|
-
dynamic_id: String(
|
|
181
|
+
dynamic_id: String(dynamicId),
|
|
186
182
|
content: text || "",
|
|
187
183
|
csrf: this.client.csrf,
|
|
188
184
|
csrf_token: this.client.csrf,
|
|
@@ -192,7 +188,7 @@ export class DynamicAPI {
|
|
|
192
188
|
}
|
|
193
189
|
async thumb(dynamicId, liked = true) {
|
|
194
190
|
const body = JSON.stringify({
|
|
195
|
-
dyn_id_str: String(
|
|
191
|
+
dyn_id_str: String(dynamicId),
|
|
196
192
|
up: liked ? 1 : 2,
|
|
197
193
|
});
|
|
198
194
|
await this.client.post(endpoints.DYNAMIC_THUMB, body, {
|
package/dist/dsh.js
CHANGED
|
@@ -1139,7 +1139,10 @@ export const TOOLS = [
|
|
|
1139
1139
|
let toolsRegistry = null;
|
|
1140
1140
|
const openGroups = new Map();
|
|
1141
1141
|
const groupLru = [];
|
|
1142
|
-
|
|
1142
|
+
// 同时最多保留几组(仅 BILI_LAZY_EVICT=1 时生效)。默认不淘汰:开过就留着,
|
|
1143
|
+
// 前缀很快稳定、持续吃缓存命中;反复淘汰会不停改工具列表、造成缓存未命中。
|
|
1144
|
+
const MAX_OPEN_GROUPS = Number(process.env.BILI_LAZY_EVICT_MAX ?? 3) || 3;
|
|
1145
|
+
const EVICT_GROUPS = process.env.BILI_LAZY_EVICT === "1" || process.env.BILI_LAZY_EVICT === "true";
|
|
1143
1146
|
// 常驻核心:登录链路必须随时可用 + 最常用的几个读取
|
|
1144
1147
|
export const CORE_IDS = [
|
|
1145
1148
|
"bili_gen_qr",
|
|
@@ -1258,10 +1261,14 @@ const lazyTools = [
|
|
|
1258
1261
|
groupLru.push(group);
|
|
1259
1262
|
return { ok: true, group, alreadyOpen: true, tools: GROUPS[group].ids };
|
|
1260
1263
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1264
|
+
// 默认不淘汰(单调累加):前缀稳定、持续吃缓存命中。
|
|
1265
|
+
// 仅在 BILI_LAZY_EVICT=1 时按 LRU 淘汰,限制同时开组数。
|
|
1266
|
+
if (EVICT_GROUPS) {
|
|
1267
|
+
while (groupLru.length >= MAX_OPEN_GROUPS) {
|
|
1268
|
+
const oldest = groupLru.shift();
|
|
1269
|
+
if (oldest)
|
|
1270
|
+
closeGroup(oldest);
|
|
1271
|
+
}
|
|
1265
1272
|
}
|
|
1266
1273
|
const disposers = [];
|
|
1267
1274
|
const loaded = [];
|
|
@@ -1306,12 +1313,11 @@ export function apply(ctx) {
|
|
|
1306
1313
|
// 捕获工具注册表,供懒加载模式下的 bili_open 动态注册
|
|
1307
1314
|
toolsRegistry =
|
|
1308
1315
|
ctx?.tools && typeof ctx.tools.register === "function" ? ctx.tools : null;
|
|
1309
|
-
//
|
|
1310
|
-
//
|
|
1311
|
-
//
|
|
1312
|
-
// 想极致压缩每轮 schema 时,才用 BILI_LAZY=1 开启懒加载。
|
|
1316
|
+
// 默认开懒加载(理由见上方「懒加载」注释):49 个工具约 5200 token 常驻太占窗口,
|
|
1317
|
+
// 按需加载后默认前缀只剩「核心 + bili_open」约 700 token。
|
|
1318
|
+
// BILI_LAZY=0 可强制全量注册(前缀稳定、缓存命中最大化,适合不在意窗口的场景)。
|
|
1313
1319
|
const lazyEnabled = !!toolsRegistry &&
|
|
1314
|
-
(process.env.BILI_LAZY === "
|
|
1320
|
+
!(process.env.BILI_LAZY === "0" || process.env.BILI_LAZY === "false");
|
|
1315
1321
|
if (!lazyEnabled) {
|
|
1316
1322
|
for (const t of TOOLS)
|
|
1317
1323
|
registerOne(ctx, t);
|