🔧 架构解析

ChatEngine vs EnhancedChatEngine
双引擎架构解析

CmdCode 拥有两套对话引擎,分别对应普通工具循环和 PAVR 计划执行模式。它们通过 chat-factory.ts 的全局开关来决定谁才是当前会话的主角。

🤖 两个引擎的区别

对比项 ChatEngine EnhancedChatEngine
循环模式 普通工具循环 PAVR 计划层
激活条件 /pavr 关闭时 /pavr 开启时
执行流程 user → model → tool → model → tool → … → output user → Plan → Act → VerifyRespond
工具调用方式 模型自主决定,立即执行,无确认 先输出 JSON 计划,需用户确认后才执行
安全性 ⚡ 高效但无中间审核 ✅ 计划需确认,更安全可控
源码文件 src/chat.ts src/chat-enhanced.ts

ChatEngine — 普通工具循环

这是 CmdCode 的基础对话引擎,采用最直接的工具调用循环:用户发送消息后,模型直接调用工具,边调用边执行,执行结果立即送回模型继续处理,如此循环,直到生成最终回复。

👤 用户 🤖 模型 🔧 tool_call 🤖 模型 🔧 tool_call ✅ output

上下文截断优化

该引擎使用消息数量(maxHistoryMessages=100)和 token 上限(~110K)双重截断策略。当工具调用结果过大时,自动丢弃最旧的工具消息,防止上下文撑爆。

maxTurns 限制

该引擎最多执行 80 轮工具调用(曾从 40 提升至 80,以支持 SWE-bench 等复杂任务)。达到上限后强制停止并输出执行摘要。

EnhancedChatEngine — PAVR 计划层

EnhancedChatEngine 是在 ChatEngine 基础上叠加了 PAVR (Plan-Act-Verify-Respond) 计划层。模型不再边调用边执行,而是先输出 JSON 格式的执行计划,用户确认后才真正执行。

👤 用户 📋 Plan: JSON 计划 ✅ 用户确认 🔧 Act: 执行工具 🔍 Verify: 验证结果 💬 Respond: 回复用户

PAVR 的优势

chat-factory.ts — 工厂决定谁上场

两个引擎不是并存竞争,而是由 chat-factory.tsglobalPAVREnabled 全局开关决定 createChatEngine() 返回哪一个。

// chat-factory.ts export function createChatEngine(usePAVR?: boolean, config?: Config) { const shouldUsePAVR = usePAVR ?? globalPAVREnabled if (shouldUsePAVR) { return new EnhancedChatEngine(config) // ✅ PAVR 模式 } else { return new ChatEngine(config) // ⚡ 普通模式 } }

命令 /pavr 只是一个快捷开关,实际修改的就是 globalPAVREnabled 这个标志位。

💡 关键理解: EnhancedChatEngine = ChatEngine + PAVR 机制。两者共享底层工具调用(executeTool)和 API 调用逻辑,区别仅在于"是否先输出计划"。

📐 整体架构图

cli.ts(入口) ├── parseArgs() 解析参数 -p / 交互模式 ├── createChatEngine() → chat-factory.ts │ ┌─────────────────── globalPAVREnabled ───────────────────┐ │ │ │ │ │ true? false? │ │ │ ↓ ↓ │ │ │ EnhancedChatEngine ChatEngine │ │ │ (chat-enhanced.ts) (chat.ts) │ │ │ • PAVR 计划层 • 普通工具循环 │ │ │ • 80轮 maxTurns • 80轮 maxTurns │ │ │ • token感知截断 • token感知截断 │ │ └─────────────────────────────────────────────────────────┘ │ ├── if -p 单次模式? → engine.chat() → exit │ └── else REPL 模式: → replLoop()(engine) → I/O 循环 │ └── repl.ts: engine.chat() 驱动对话
⚠️ 注意: repl.ts 本身不创建引擎,它只是接收 cli.ts 传入的 engine 实例。repl.ts 中的 new ChatEngine() 仅在用户执行 /model 切换模型时用于重新初始化。

📝 总结

来源:CmdCode V0.5 源码分析 · chat.ts / chat-enhanced.ts / chat-factory.ts