引擎契约
August 14, 2026 · View on GitHub
一个引擎是「实现 DSH Agent 接口的驱动」,由下游插件经 ctx.engineSwitch.register(engine) 注册:
| 字段 | 必填 | 说明 |
|---|---|---|
| id | ✅ | 引擎 id(非空字符串;deepseek 是保留字,注册抛错)。同时是预设目录名(by-id 映射锚点) |
| name | ✅ | 预设显示名 |
| description | ✅ | 预设描述 |
| presetDir | — | 预设目录绝对路径(含 agent.cordis.yml + preset.yml);有则框架落地到 ~/.dsh/.agent-presets/<id>/ |
| makeAgent | ✅ | (loopCtx, id, options, session, engineConfig) => DSH Agent |
makeAgent
产出一个实现 DSH Agent 接口的完整驱动(与原生 ReactLoop 同接口:send/followup/steer/inject/cancel/whenIdle/status/ctx/scope/session/inbox)。框架直接发布它,session 直接驱动它——通信原样到达引擎,不改写、不翻译。
透明性约束
- 引擎无感知预设:
makeAgent不接收 preset 概念。preset → 引擎的路由由框架完成,引擎只看到session/options/engineConfig。 - 会话无感知 switch:session 只跟
Agent打交道;换引擎 = 空白期内换驱动它的 Agent,session 自身不感知。
注册
下游插件 inject: ["engineSwitch"],在 apply 里注册:
export const inject = ["engineSwitch"];
export function apply(ctx) {
ctx.engineSwitch.register({
id: "my-engine",
name: "My Engine",
description: "…",
presetDir: fileURLToPath(new URL("./presets/my-engine/", import.meta.url)),
makeAgent(loopCtx, id, options, session, engineConfig) {
return new MyEngineAgent(loopCtx, id, options, session, engineConfig);
},
});
}
引擎私有配置
引擎的私有配置放 config.engines[engine.id](框架原样转发为 engineConfig,不解析、不校验);引擎自行校验 + 给默认值。
约束
makeAgent返回的 Agent 必须暴露 dsh-agent 的 Agent 契约(send/cancel/whenIdle/scope/ctx/session),路由工厂的 dispose/publish 依赖它。deepseek不是注册进来的引擎,是defaultEngine兜底的委托哨兵。