Files
dsh-acfun/index.js
T
tamakyi f9bedde19e 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.
2026-10-27 11:26:51 +08:00

87 lines
2.9 KiB
JavaScript

/**
* dsh-plugin-acfun — AcFun (A站) reads and interactions as DeepSeek Harness
* tools.
*
* Host-only bundle: no Client half, no runtime imports of `@deepseek-ai/*`.
* That is deliberate — a workspace-linked bundle resolves bare specifiers from
* its own directory, so importing `@deepseek-ai/dsh-tools` or schemastery
* would fail to activate. Tool definitions are therefore plain objects and the
* config schema is validated in `lib/config.js`.
*
* Reads work anonymously. Every mutating call additionally requires
* `allowWriteActions: true` plus a login cookie, so installing the bundle never
* gives the model write access to an AcFun account by accident.
*/
import { resolveConfig } from './lib/config.js'
import { AcfunProvider } from './lib/provider.js'
import { ACFUN_GUIDANCE, createAcfunTools } from './lib/tools.js'
/** Cordis plugin name used by loader diagnostics. */
export const name = 'dsh-plugin-acfun'
/** Services required before the plugin starts. */
export const inject = ['tools', 'systemPrompt']
/**
* Register one setup factory as a plugin-owned effect when the context offers
* `effect`, falling back to a direct call for older Cordis minors.
*
* @param {any} ctx - plugin context.
* @param {() => (() => void) | void} factory - performs registrations and returns a disposer.
*/
function asEffect(ctx, factory) {
if (typeof ctx.effect === 'function') {
ctx.effect(factory)
return
}
const dispose = factory()
if (typeof dispose === 'function' && typeof ctx.on === 'function') {
// Older Cordis minors without `effect` still expose the dispose event.
ctx.on('dispose', dispose)
}
}
/**
* Activate the plugin: register the seven AcFun tools plus one system-prompt
* guidance section.
*
* @param {any} ctx - Cordis context with `tools` and `systemPrompt`.
* @param {unknown} config - the Loader row config (see cordis.patch.yml).
*/
export function apply(ctx, config) {
const resolved = resolveConfig(config)
if (resolved.warnings.length > 0 && typeof ctx.logger?.warn === 'function') {
for (const warning of resolved.warnings) ctx.logger.warn(`[dsh-plugin-acfun] ${warning}`)
}
const provider = new AcfunProvider({
cookie: resolved.cookie,
requestTimeoutMs: resolved.requestTimeoutMs,
allowWriteActions: resolved.allowWriteActions,
})
asEffect(ctx, () => {
const disposers = createAcfunTools(provider, resolved).map((definition) => ctx.tools.register(definition))
return () => {
for (const dispose of disposers) {
if (typeof dispose === 'function') dispose()
}
}
})
asEffect(ctx, () => {
const dispose = ctx.systemPrompt.section({
name: 'tool:acfun',
order: 112,
text: ACFUN_GUIDANCE,
})
return typeof dispose === 'function' ? dispose : undefined
})
}
export { AcfunProvider } from './lib/provider.js'
export { ACFUN_GUIDANCE, createAcfunTools } from './lib/tools.js'
export { resolveConfig } from './lib/config.js'