控制面
会话生命周期、回合锁 SessionTurnLock、取消、权限 / 提问 / MCP 确认挂起、客户端注册。Desktop / TUI:agent/startTurn。CLI:阻塞 agent/chat(cancelOnDisconnect: true)。/goal 走 GoalRunner,不占死整段回合锁。live session LRU 目标 16,不驱逐忙碌会话;agent/cancel 只停该 session 的回合与 bash job。
codepapr-host/1桌面、TUI、CLI、测试、以后的 WebUI 都是同一套 JSON-RPC 客户端。区别只在传输和 initialize.capabilities。Tauri 是桌面壳,不是 Agent 执行面。发给模型的字节怎么叠,见 上下文分层。
排障时先问:这是调度问题、权威状态问题,还是工具/模型循环问题。
会话生命周期、回合锁 SessionTurnLock、取消、权限 / 提问 / MCP 确认挂起、客户端注册。Desktop / TUI:agent/startTurn。CLI:阻塞 agent/chat(cancelOnDisconnect: true)。/goal 走 GoalRunner,不占死整段回合锁。live session LRU 目标 16,不驱逐忙碌会话;agent/cancel 只停该 session 的回合与 bash job。
权威在工作区 .CodePapr/project.sqlite(优先 node:sqlite):messages Archive、context_surfaces、memory_entries、todo。VFS overlay 让终端 read 看见桌面未保存缓冲。HostEventBus 带单调 sequence。
agentRunner 组请求、跑工具、子代理 runSubagentSession、压缩、Recall。bash(macOS SBPL 沙箱)、browser(本机 Chrome CDP)、MCP(stdio / SSE / Streamable-HTTP)、LSP 都在 Host。workspace/list / read 有条数、时间和字节预算;LSP / MCP 帧有上限。
方法名冻结在 protocol.ts。不要在 UI 发明别名。断线补偿只认 sequence。
agent/chat agent/startTurn agent/startGoal agent/cancel agent/compact agent/runVerifier agent/app_run + 权限/提问/MCP 决议。改变状态。
agent/getEvents(afterSequence 分页回放,带 hasMore / oldestSequence / replayUnavailable)agent/turnStatus agent/goalStatus agent/pendingInteractions workspace/read。只读事实。
agent/stream:text / reasoning / tool-start / tool-end / turn/* / goal-progress / goal-finished / context-compacted / context-pruned / 权限提问 MCP。每条带 sequence。
用户一句普通话。Desktop/TUI startTurn,CLI chat。等 turn/finished。
用户 /goal。Host 跑拆步 → worker chat → Verifier。外层等 goal-finished,不要把内层 turn/finished 当结束。
checkpoint 写 Surface(started→completed)。prune 只裁 live log 工具噪声。Archive 用户原文不动。
Client 死不等于 Session 死。租约重连后 getEvents(afterSequence)。已见序号必须丢弃,避免乐观 UI 闪两遍。
能力写在 initialize.capabilities。没有能力的客户端不要去画权限框或 .papr 面板。
聊天 startTurn,/goal 直接 startGoal。反向 RPC:权限、提问、MCP 确认、tools.app。Monaco overlay 同步到 Host。Worker 路径只是回退。
同样 startTurn。/goal 升格为 Goal,等 goal-finished。有权限/提问,没有 .papr。Transcript 在 .CodePapr/tui/,权威库仍是 sqlite。
阻塞到回合(或整个 Goal)结束。cancelOnDisconnect: true:关掉终端就取消。默认 session cli-<pid>。
UI 可以乐观画一条用户消息。重放、压缩、记忆、检查点都以 Host 库为准。
Archive 原文。tool 结果折进 assistant tool_invocations,hydrate 时再展开合成 tool 消息。不把 role=tool 当独立行写入。
当前模型历史的选择权威。compaction 行 started → completed;Host 启动把残留 started 标 interrupted。
唯一记忆账本。短指令进 Bootstrap,procedure 按回合召回,citation / untrusted 不进自动召回。旧 memory.json 只读迁移,不再回写。
环形缓冲 + 单调序号。桌面 deliverHostAgentStream 丢弃 sequence ≤ last。
扩展产品时按「谁拥有权威」动手,而不是在最近的 React 文件里加逻辑。
先改 packages/@codepapr/host/src/protocol.ts 冻结集合,再接线 inProcessHost.ts。UI 只映射,不发明方法名。
Host agentTools。MCP 走 Host 传输(stdio / SSE / HTTP)。不要再往 Rust 加一套 Agent 工具。
core ImmutablePrefix + Host agentRunner。Desktop 只传用户原文、mode、图片、Recall 插入。
hostGoal.ts + hostVerifier.ts。TUI/CLI 不要把 /goal 展开成一次性 prompt。
macOS:Host SBPL 默认开。Linux / Windows:无内核层,静态拒绝 ~ / $VAR / .. / 未授权绝对路径。CODEPAPR_HOST_SANDBOX=0 关掉 SBPL 后同样走静态预检。
01 Prefix 只放稳定 system + 排序工具定义 + 采样。Skills / 记忆 / 角色放 02 Bootstrap。工具列表增删会拆缓存。量 Prefix 命中要对着真实模型,mock 测不出来。
软预算逼近用 checkpoint(摘要 + 尾部)。工具噪声用 prune。不要每轮都 compact。Surface 失败保留上一个 completed generation。
Goal 外层不持锁;每轮 worker 才进锁。根 task 的 currentDepth 必须是 0,否则 exploreMaxDepth: 1 会禁掉 explore。Recall 排除 untrusted,检查点正文加权进语料。
workspace/list 用 Dirent,4000 条 / 250ms 预算。workspace/read 按 maxBytes 有界读、行范围走流,拒绝 NUL。LSP / stdio MCP 分块组帧(8MB / 16MB / pending 64),溢出杀进程。
有意未合并的边界:Host 无头 browser 用本机 Chrome CDP;桌面仍有 Rust headless_chrome。synthetic: true 只存在桌面乐观层,不进 Host Archive。不要把这两条当成「缺了 P0」。
实现落点:inProcessHost.ts、agentRunner.ts、hostGoal.ts、hostProjectStore.ts、hostRecall.ts、hostSandbox.ts、protocol.ts。协议文档 docs/HOST.md。系统设计 docs/ARCHITECTURE.md。