DeepSeek Harness101 插件生命周期 返回首页 官方文档 ↗

具名能力与依赖驱动组合

依赖能力,不要绑定提供方。

提供方公开具名能力,消费方声明需求,Cordis 负责启动、替换与清理。

greeter.ts
import { Service, type Context } from '@deepseek-ai/cordis'

export class GreeterService extends Service {
  constructor(ctx: Context) {
    super(ctx, 'greeter')
  }

  greet(who: string) {
    return `Hello, ${who}!`
  }
}

服务是挂载在 ctx 上的具名能力

Harness 自身的工具运行时、模型运行时和 Agent 管理器都遵循同一模型。

ctx.toolsctx.llmctx.agentsHarness 内置能力
组合边界

消费方只依赖 'tools' 或 'shell' 这样的能力名称,不导入具体实现。配置可以更换提供方,而消费代码保持不变。

运行时注册与编译时类型是两件事

Service 基类负责注册实例;TypeScript 声明合并让 ctx.greeter 在消费端获得类型。后者不会生成运行时代码。

运行时super(ctx, 'greeter')以名称注册实例,卸载时自动移除
编译时interface Context声明合并提供类型安全,不改变运行时
greeter.ts
declare module '@deepseek-ai/cordis' {
  interface Context {
    greeter: GreeterService
  }
}

export function apply(ctx: Context) {
  ctx.plugin(GreeterService)
}

inject 是持续生效的硬性依赖

Cordis 等待所有依赖出现后才运行 apply。决定启动时机的是依赖关系,不是 cordis.yml 中的文件顺序。

consumer.ts
export const name = 'consumer'
export const inject = ['greeter']

export function apply(ctx: Context) {
  console.log(ctx.greeter.greet('world'))
}
greeter 不存在PENDINGapply 不运行,不会部分启动
greeter 就绪ACTIVEctx.greeter 保证可用
静默退出不一定是成功加载

PENDING Fiber 不会维持 Node 事件循环。如果组合里没有其他活动项,进程可能以状态码 0 静默退出。

替换提供方会干净地重启消费者

inject 不是启动时的一次检查。依赖消失时,消费插件及其 effect 会卸载;新提供方出现后再重新加载。

旧 shellconsumer ACTIVE
提供方卸载consumer DISPOSED
新 shellconsumer ACTIVE

例如卸载 dsh-bash-local,再挂载另一个 shell 实现。所有 inject: ['shell'] 的插件都会针对新实现完整重启。

能降级运行的能力不要放进 inject

可选依赖缺失时插件仍需运行,因此在真正使用的位置调用 ctx.get() 并处理 undefined。

必需export const inject = ['tools']缺失时保持 PENDING
可选const metrics = ctx.get('metrics')缺失时得到 undefined
optional.ts
export function apply(ctx: Context) {
  const greeter = ctx.get('greeter')
  const output = greeter?.greet('maybe')
    ?? 'no greeter available'

  console.log(output)
}

隔离组可以拥有同名服务的不同实例

在 cordis.yml 的插件组上隔离 shell 后,每组内的插件只看到自己的 Bash 实例与配置。

group-ashell / timeoutMs: 5000plugin-a
互不可见
group-bshell / timeoutMs: 60000plugin-b
命名约束

每个应用的服务名称共用一个扁平命名空间。Harness 已使用 tools、llm 等普通名称,自定义服务应采用有辨识度的名称或前缀。

下一步,用事件实现无需共享服务的通信