dsh-plugin-hooks-ordering

前言

DeepSeek-Harness 的插件生态支持 waterfall 和 serial 两种分发模式。在多插件协作场景下,Cordis 原生的钩子执行顺序依赖于插件的注册顺序,而这种顺序往往由插件的依赖注入(inject)机制驱动,对于互不感知的独立插件而言,这本质上是非确定性的。

这意味着插件无法可靠地声明相对顺序,例如“auth 必须在 logging 之前执行”。一旦相关插件的依赖关系发生微调,执行顺序可能随机翻转,导致逻辑错误。dsh-plugin-hooks-ordering 插件通过引入确定性的排序算法,解决了这一问题。

核心功能

该插件为 Cordis hooks 提供确定性的 before/after 排序,支持 waterfall 和 serial 两种分发模式,并提供 DeepSeek-Harness 层支持。具体能力包括:

  • 为 Cordis hooks 提供确定性的 before/after 排序。
  • 支持 waterfall 和 serial 两种分发模式。
  • 提供纯拓扑排序算法。
  • 支持约束图 DAG 日志记录。
  • 提供 DeepSeek-Harness (dsh) 层支持。

安装与依赖

安装时需要指定 peer dependency @deepseek-ai/cordis。

pnpm add @tengxiaohtx/dsh-plugin-hooks-ordering
pnpm add @deepseek-ai/cordis

使用方法

Waterfall 钩子

Waterfall 钩子使用洋葱模型,通过 prepend 监听器实现前后阶段控制。

  1. 导入 HookOrdering。
  2. 安装插件并控制目标钩子。
  3. 在 front 和 back 阶段注册参与者。
import HookOrdering from '@tengxiaohtx/dsh-plugin-hooks-ordering'

ctx.plugin(HookOrdering)

// 控制钩子,控制多次会抛出错误
ctx.hooksOrdering.control('request/assemble')

// 注册参与者:auth 必须在 logging 之前执行
ctx.hooksOrdering.register('request/assemble', 'front', {
  name: 'auth',
  before: ['logging'],
  run: (req) => authenticate(req),
})

ctx.hooksOrdering.register('request/assemble', 'front', {
  name: 'logging',
  run: (req) => log(req),
})

// 注册参与者:metrics 必须在最后执行
ctx.hooksOrdering.register('request/assemble', 'back', {
  name: 'metrics',
  run: (req) => emitMetrics(req),
})

Serial 钩子

Serial 钩子没有 next() 链,因此使用 front 协调器(短路)和 back 协调器(尽力而为)来控制顺序。

import { SerialHookOrdering } from '@tengxiaohtx/dsh-plugin-hooks-ordering'

ctx.plugin(SerialHookOrdering)
ctx.serialHooksOrdering.control('turn/stopping')

// front 阶段:运行在原生链之前,返回非 falsy 值会短路整个分发
ctx.serialHooksOrdering.register('turn/stopping', 'front', {
  name: 'guard',
  run: (turn) => (isAllowed(turn) ? undefined : 'DENIED'),
})

// back 阶段:尽力而为地最后运行
ctx.serialHooksOrdering.register('turn/stopping', 'back', {
  name: 'audit',
  run: (turn) => recordAudit(turn),
})

DAG 日志记录

插件支持将约束图(DAG)导出为 JSON,用于调试顺序问题。

  1. 安装时传入日志路径。
  2. 通过 dumpDag() 方法获取当前 JSON 字符串。
ctx.plugin(HookOrdering, { log: './hooks-ordering-dag.json' })

// 程序中获取 DAG
const dag = ctx.hooksOrdering.dumpDag()

DeepSeek-Harness 集成

插件提供 /dsh 入口,用于在 DeepSeek-Harness 层面控制真实的 dsh 钩子。

  1. 在 cordis.patch.yml 中添加插件配置。
  2. 插件会自动接管多个包贡献的钩子,如 agent/pre-step、tools/post-execute 等。
- insert:
    - id: hooks-ordering
      name: '@tengxiaohtx/dsh-plugin-hooks-ordering/dsh'
      config:
        # hooks: ['agent/pre-step', 'tools/post-execute', 'llm/stream', 'turn/stopping']

分层架构

该插件分为三层,可根据需要选择使用层级:

  1. 算法层:提供纯拓扑排序算法和 DAG 渲染器,零依赖,无 Cordis 依赖。
  2. Cordis 服务层:提供 HookOrdering 和 SerialHookOrdering 服务,可在任意 Cordis 应用中控制钩子。
  3. DeepSeek-Harness 层:提供 dsh 插件和 cordis.patch.yml,用于控制真实的 dsh 钩子。

注意事项

  • 该插件不修改或分叉 Cordis 框架。
  • 通过 prepend listener 实现洋葱模型。
  • front 阶段会短路 serial 分发。
  • back 阶段是尽力而为。

总结

dsh-plugin-hooks-ordering 为 Cordis 插件提供了稳定的钩子执行顺序控制。通过拓扑排序和分层设计,它在不破坏框架的前提下,解决了多插件协作中的依赖顺序不确定性问题。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜