Cordis,底层的内核
Cordis 是来自 Koishi 社区的 TypeScript plugin 框架。DSH 没有实现自己的 plugin 系统。它直接使用此框架,这就是为什么 DSH plugin 同时也是 Cordis plugin。
Context 是 Service 的存储库
每个 plugin 都会接收一个 Context,通常命名为 ctx。Service 驻留在其上,使用如 ctx.tools、ctx.llm 或 ctx.sessions 等稳定键值。需要工具表的 plugin 访问该键,而非具体实现,因此该键背后的实现可以在 plugin 无感知的情况下进行更改。
import type { Context } from 'cordis'
// Services live on the context under stable keys.
// A plugin reaches for the key, not for a concrete class.
export function apply(ctx: Context) {
ctx.tools // the tool table
ctx.sessions // the append-only session log
ctx.llm // whichever model adapter is loaded
} 插件即实现 Service 的一切对象
实际上,这意味着一个带有 apply(ctx) 主体的函数,或者一个继承自 Service 的类,Cordis 会将其生命周期挂载到当前 Context 中。除了这一点,没有注册清单,也没有需要继承的插件基类。
加载顺序是声明式的,而非序列化的
插件在 inject 中列出其所需内容。Cordis 会将其置于等待状态,直到所有列出的服务都存在,然后才会调用 apply。无需手动维护引导顺序,插件如果在其依赖项之前加载,只需等待即可,而不会崩溃。
export const inject = ['tools', 'sessions']
export function apply(ctx: Context) {
// Cordis holds this plugin in a pending state until both
// services exist, so neither lookup below can be undefined.
const session = ctx.sessions.current()
ctx.tools.list().forEach((tool) => session.note(tool.name))
} 在 apply 内部,inject 中命名的所有内容都保证已存在。
副作用是可逆的
通过 ctx.on 和 ctx.effect 进行的注册会被记录。当插件卸载或重新加载时,Cordis 会遍历该记录并撤销每一项。监听器被移除,服务被释放,定时器被清除。这使得插件的热插拔是安全的,而非导致缓慢的内存泄漏。
export function apply(ctx: Context) {
const dispose = ctx.tools.register('read_file', async ({ path }) => {
return readFile(path, 'utf8')
})
// Returning the disposer is what makes the plugin removable:
// unloading it takes the tool back out of the table.
return dispose
} 调度事件的四种方式
插件既可以通过事件也可以通过服务进行通信,调度模式决定了监听器可以执行的操作。
emit 触发并遗忘。每个监听器都会运行,不返回任何内容。
parallel 每个监听器并发运行,调用者会等待所有监听器执行完毕。
serial 监听器按顺序运行,直到某个监听器返回一个值,该值即为结果。
waterfall 每个监听器都会接收 next,并可以转换参数、委托后续处理或短路逻辑。
这在 DSH 中是如何体现的
每一个 DSH 能力都是 Context 上的一个服务。阅读该列表是理解 harness 实际构成的最快方式。
- 模型适配器占用一个服务键。更换提供商意味着针对同一个键加载不同的插件。
- 每个工具都将自身注册到工具表中作为可逆副作用,因此移除工具就是卸载其插件。
- 会话服务拥有追加日志。存储后端是其背后的独立插件。
- 代理循环本身就是一个插件,这就是为什么像 Minimal 和 PTC 这样的预设在共享内核的同时差异如此之大。
Cordis 背后的组合性模型撰写在关于时空组合性(spatiotemporal composability)的论文中,该论文链接在 DSH 仓库中。