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:
@@ -0,0 +1,129 @@
|
||||
# dsh-plugin-acfun
|
||||
|
||||
DeepSeek Harness plugin for **AcFun (A站, acfun.cn)**: search videos, read video
|
||||
metadata, comment threads, danmaku (弹幕), the day/week ranking and playable
|
||||
stream URLs, and — only when you opt in — interact with your own account (like,
|
||||
tip bananas, favorite, follow, post comments).
|
||||
|
||||
This is the AcFun counterpart of the community Bilibili tool plugins. Reads are
|
||||
anonymous and work out of the box; every mutating call is gated behind
|
||||
`allowWriteActions: true` **and** an AcFun login cookie, so installing the bundle
|
||||
never silently gives the model write access to an account.
|
||||
|
||||
## Tools
|
||||
|
||||
| Tool | Kind | What it does |
|
||||
| --- | --- | --- |
|
||||
| `acfun_search` | read | Keyword video search; `sort: "views"` orders by play count (AcFun returns one fixed first page of up to 30). |
|
||||
| `acfun_video` | read | Full metadata for one video: author, channel, tags, stats, publish time, cover. |
|
||||
| `acfun_comments` | read | One page of a video's comment thread, in floor order. |
|
||||
| `acfun_danmaku` | read | One batch of a video's 弹幕, ordered by in-video position, with cursor paging. |
|
||||
| `acfun_rank` | read | Day or week ranking, all channels or one `channelId`. |
|
||||
| `acfun_playurl` | read | m3u8 quality ladder (1080P+ / 1080P / 720P / 540P / 360P). |
|
||||
| `acfun_interact` | write | `like`, `unlike`, `banana`, `favorite`, `unfavorite`, `follow`, `unfollow`. |
|
||||
| `acfun_post_comment` | write | Post a top-level comment or a reply. |
|
||||
|
||||
A model-facing skill (`skills/plugin-tool-acfun/SKILL.md`) teaches the tool
|
||||
sequence and the write-safety rules.
|
||||
|
||||
## Install
|
||||
|
||||
Install the workspace directory as a profile bundle:
|
||||
|
||||
```
|
||||
plugin_manager action=install_bundle target=C:\path\to\dsh-acfun
|
||||
```
|
||||
|
||||
The bundle inserts one Loader row (`id: acfun`) with the config below. A local
|
||||
directory is linked, so edits to the plugin need a Harness restart to load a
|
||||
fresh module generation.
|
||||
|
||||
To remove it, use `plugin_manager action=remove_bundle target=dsh-plugin-acfun`.
|
||||
|
||||
## Configuration
|
||||
|
||||
The row config lives in `cordis.patch.yml`; every key is optional.
|
||||
|
||||
| Key | Default | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `cookie` | `''` | Full AcFun `Cookie` header value. Prefer the environment variable so the secret does not enter the patch. |
|
||||
| `cookieEnv` | `ACFUN_COOKIE` | Environment variable read when `cookie` is empty. |
|
||||
| `allowWriteActions` | `false` | Master switch for `acfun_interact` and `acfun_post_comment`. |
|
||||
| `requestTimeoutMs` | `30000` | Per-HTTP-request timeout. |
|
||||
| `timeoutMs` | `45000` | Cooperative per-tool-call budget (write calls use at least 60 s). |
|
||||
|
||||
Example with the environment variable:
|
||||
|
||||
```powershell
|
||||
$env:ACFUN_COOKIE = 'auth_key=...; acPasstoken=...; _did=...'
|
||||
```
|
||||
|
||||
### Getting the cookie
|
||||
|
||||
1. Sign in to <https://www.acfun.cn/> in a desktop browser.
|
||||
2. Open DevTools → Network, reload any acfun.cn page, and copy the complete
|
||||
`Cookie` request header of the document request (it contains `auth_key`,
|
||||
`acPasstoken`, `_did`, and other session values).
|
||||
3. Paste it as one line into `cookie` or `ACFUN_COOKIE`.
|
||||
|
||||
Treat that string like a password: it grants full access to the account. The
|
||||
plugin never logs it.
|
||||
|
||||
## Safety model
|
||||
|
||||
- Reads cannot mutate anything and need no cookie.
|
||||
- Writes require both `allowWriteActions: true` and a cookie. With only one of
|
||||
them the tools return `WRITE_DISABLED` / `LOGIN_REQUIRED` and perform no HTTP
|
||||
write request.
|
||||
- Write tools are declared non-concurrency-safe so the harness will not run two
|
||||
account mutations in parallel.
|
||||
- A CAPTCHA/identity-verification challenge from AcFun (`result` 400001–410999)
|
||||
is surfaced as `CAPTCHA_REQUIRED`; the plugin never tries to solve it.
|
||||
|
||||
## Verification status
|
||||
|
||||
Verified live on 2026-10-27 against acfun.cn (anonymous):
|
||||
|
||||
- All six read tools — `acfun_search` (including `sort: "views"`), `acfun_video`,
|
||||
`acfun_comments`, `acfun_danmaku`, `acfun_rank`, `acfun_playurl` — return real
|
||||
API data and pass output-schema validation plus rendering
|
||||
(`node scripts/live-check.mjs`).
|
||||
- All eight tools register through a mock Cordis context and the write guard
|
||||
fails closed (`node scripts/self-check.mjs`).
|
||||
- Write routes exist and reject anonymous requests with `{"result":-401}`. The
|
||||
authenticated happy path was **not** exercised here because no AcFun
|
||||
account/cookie was available. Treat first use as a live test: check the result
|
||||
in the AcFun UI instead of retrying blindly.
|
||||
|
||||
## Known limitations
|
||||
|
||||
- AcFun's pc-direct search endpoint ignores `page`/`pageSize` and always returns
|
||||
its first page (30 entries), so `acfun_search` cannot paginate. `sort` is the
|
||||
only ordering control AcFun honours.
|
||||
- Bangumi (番剧) and article pages are not supported — `acfun_video` reports
|
||||
`UNSUPPORTED_RESOURCE` instead of guessing.
|
||||
- Danmaku paging beyond the first batch depends on AcFun's opaque `pcursor`;
|
||||
`acfun_danmaku` passes it through as `cursor`/`nextCursor`.
|
||||
- Play URLs are time-limited signed m3u8 links; re-run `acfun_playurl` when one
|
||||
expires. Downloading/merging streams is out of scope.
|
||||
- This plugin only talks to acfun.cn's public web endpoints; it is unofficial and
|
||||
can break when AcFun changes them.
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
node scripts/self-check.mjs # offline: exports, tool schemas, write guard
|
||||
node scripts/live-check.mjs # online: real reads + schema validation + render
|
||||
```
|
||||
|
||||
No build step, no runtime dependencies. Everything under `lib/` is plain ESM
|
||||
that imports only Node built-ins/globals. The bundle intentionally exports no
|
||||
`Config` schema: a workspace-linked bundle cannot resolve `@deepseek-ai/*`
|
||||
packages, so `lib/config.js` validates the row config and falls back to defaults
|
||||
with warnings instead of using schemastery.
|
||||
|
||||
See `docs/acfun-api.md` for the endpoint notes this plugin is based on.
|
||||
|
||||
## License
|
||||
|
||||
MIT — see `LICENSE`.
|
||||
Reference in New Issue
Block a user