feat: AcFun tools plugin for DeepSeek Harness

Eight tools (search, video, comments, danmaku, rank, playurl, interact,
post_comment) over acfun.cn's public web API, a model-facing skill, a
bundle patch with a skill-filesystem row, and offline/live checks.

Reads are anonymous; writes require allowWriteActions plus a login cookie.
This commit is contained in:
tamakyi
2026-10-27 11:26:51 +08:00
commit f9bedde19e
19 changed files with 3530 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
# dsh-plugin-acfun
给 **DeepSeek Harness** 用的 **AcFun(A站)** 插件:搜索视频、读取视频详情、
评论、弹幕、日/周排行榜和可播放的 m3u8 地址;只有在你主动开启后,才能用自己
的账号进行互动(点赞、投蕉、收藏、关注、发评论)。
这是社区 B 站工具插件在 A 站上的对应实现。读取类工具默认匿名可用;所有写操作
必须同时满足 `allowWriteActions: true` **和** AcFun 登录 Cookie,因此装好插件
并不会悄悄把账号的写权限交给模型。
## 工具
| 工具 | 类型 | 作用 |
| --- | --- | --- |
| `acfun_search` | 读 | 关键词搜索视频;`sort: "views"` 按播放量排序(A 站只返回固定第一页,最多 30 条)。 |
| `acfun_video` | 读 | 单个视频完整信息:UP 主、分区、标签、播放/点赞/收藏/投蕉/评论/弹幕数、发布时间、封面。 |
| `acfun_comments` | 读 | 视频评论(按楼层序)的一页。 |
| `acfun_danmaku` | 读 | 视频弹幕一批,按视频内时间排序,支持 `cursor` 翻页。 |
| `acfun_rank` | 读 | 日榜 / 周榜,`channelId: 0` 为全站。 |
| `acfun_playurl` | 读 | m3u8 清晰度列表(1080P+ / 1080P / 720P / 540P / 360P)。 |
| `acfun_interact` | 写 | `like`、`unlike`、`banana`(投蕉)、`favorite`、`unfavorite`、`follow`、`unfollow`。 |
| `acfun_post_comment` | 写 | 发表评论或回复某条评论。 |
插件还附带一个面向模型的技能文件 `skills/plugin-tool-acfun/SKILL.md`,说明工具
调用顺序和写操作的安全规则。
## 安装
把工作区目录作为 bundle 安装:
```
plugin_manager action=install_bundle target=C:\path\to\dsh-acfun
```
插件会向 Loader 插入一行(`id: acfun`)。本地目录是链接安装,修改插件代码后
需要重启 Harness 才能加载新的模块实例。
卸载:`plugin_manager action=remove_bundle target=dsh-plugin-acfun`。
## 配置
配置位于 `cordis.patch.yml` 的 `acfun` 行,所有键都可省略。
| 键 | 默认值 | 含义 |
| --- | --- | --- |
| `cookie` | `''` | 完整的 AcFun `Cookie` 请求头。推荐用环境变量,避免密钥写进 patch。 |
| `cookieEnv` | `ACFUN_COOKIE` | `cookie` 为空时读取的环境变量名。 |
| `allowWriteActions` | `false` | `acfun_interact` / `acfun_post_comment` 的总开关。 |
| `requestTimeoutMs` | `30000` | 单次 HTTP 请求超时。 |
| `timeoutMs` | `45000` | 单次工具调用的协作式预算(写操作至少 60 秒)。 |
使用环境变量的例子:
```powershell
$env:ACFUN_COOKIE = 'auth_key=...; acPasstoken=...; _did=...'
```
### 获取 Cookie
1. 在桌面浏览器登录 <https://www.acfun.cn/>。
2. 打开开发者工具 → Network,刷新任意 acfun.cn 页面,复制文档请求的完整
`Cookie` 请求头(包含 `auth_key`、`acPasstoken`、`_did` 等会话值)。
3. 把整行粘贴到 `cookie` 或 `ACFUN_COOKIE`。
这串 Cookie 等同于账号密码,插件不会把它写进日志。
## 安全设计
- 读取类工具不会修改任何内容,也不需要 Cookie。
- 写操作必须同时具备 `allowWriteActions: true` 与 Cookie;只满足其一时工具会
返回 `WRITE_DISABLED` / `LOGIN_REQUIRED`,并且不会发出任何写请求。
- 写工具声明为非并发安全,Harness 不会并行执行两个账号操作。
- AcFun 返回人机验证/身份验证要求(`result` 400001–410999)时,插件以
`CAPTCHA_REQUIRED` 报告,绝不尝试绕过验证码。
## 验证情况
2026-10-27 对 acfun.cn 实测(匿名):
- 六个读取工具(`acfun_search` 含 `sort: "views"`、`acfun_video`、
`acfun_comments`、`acfun_danmaku`、`acfun_rank`、`acfun_playurl`)都返回真实
数据,并通过输出 schema 校验与渲染(`node scripts/live-check.mjs`)。
- 八个工具通过模拟 Cordis 上下文完成注册,写操作守卫正确失败关闭
(`node scripts/self-check.mjs`)。
- 写接口路由存在,匿名调用返回 `{"result":-401}`;但本次没有 AcFun 账号
Cookie,**未**验证登录后的成功路径。首次使用时请以 A 站页面上的实际结果为准,
不要在结果不明时重复调用。
## 已知限制
- A 站的 pc-direct 搜索接口忽略 `page`/`pageSize`,永远只返回第一页 30 条,
因此 `acfun_search` 无法翻页;排序只有 `sort` 一个有效参数。
- 不支持番剧(bangumi)与文章页面——`acfun_video` 会返回 `UNSUPPORTED_RESOURCE`,
不会瞎猜。
- 弹幕翻页依赖 A 站不透明的 `pcursor`,插件通过 `cursor`/`nextCursor` 透传。
- 播放地址是带签名的临时 m3u8 链接,过期后重新调用 `acfun_playurl`;下载/合并
流媒体不在本插件范围内。
- 插件只调用 acfun.cn 的公开 Web 接口,属于非官方实现,A 站改动接口后可能失效。
## 开发
```
node scripts/self-check.mjs # 离线:导出、工具 schema、写操作守卫
node scripts/live-check.mjs # 在线:真实读取 + schema 校验 + 渲染
```
无构建步骤、无运行时依赖。`lib/` 下全部是只依赖 Node 内置能力的纯 ESM。插件
故意不导出 `Config` schema:工作区链接安装的 bundle 无法解析 `@deepseek-ai/*`
包,所以由 `lib/config.js` 校验配置并带告警地回退到默认值。
接口逆向笔记见 [docs/acfun-api.md](docs/acfun-api.md)。
## 许可证
MIT,见 `LICENSE`。