Why: 卡流机制与中栏过程/回复分离的用户五项裁定(2026-09-30)入库:显式路由、卡片权威+引用回填、默认关、CF0 先行、完备性剧本修订;Cursor 式过程折叠决策(D41)。 Evidence: 提案 docs/proposals/2026-09-30-cardflow-and-process-split.md;usage.md 增过程折叠/长回复折叠/长结果进卡片三节;plugin-development.md 增通道外溢验收项(06 §2.7)。 Impact: 文档;决策编号 D39–D43(D34–D38 为认证提案预留段)。 Refs: Dev 任务卡 feature/cardflow-r1。
5.6 KiB
5.6 KiB
卡流机制与中栏过程/回复分离 —— 设计与实施提案
状态:已批准(2026-09-30 用户五项裁定);owner:weichen。
前置:界面交互底座(D25–D33:收件箱/卡片/双现/互定位地基)、界面重构与多用户认证(R1/R2/R4 已实施)。
输入:目标系统设计全集 V2.2.1(~/downloads/agent-system-design 06 §3.3「助手卡片流」:AI 回复简短、长结果一律引导到右侧卡片);用户 2026-09-30 评估裁定。
1. 背景与裁定
评估报告结论:把目标系统「中栏短回复 + 右栏卡片承载产物」的交互泛化为基座通用能力。用户五项裁定:
- 接受模型显式路由为唯一切分机制(否决后处理自动拆分——拆分失败永远退化为现状,不丢内容);
- 认可数据模型:产物全文权威在卡片(ActivityCard),消息只存引用部件 + 锚点渲染,上下文组装回填;
- 默认关,用户手动打开(设置 → 界面 →「长结果进右侧卡片」);
- CF0 先行(中栏长回复折叠止痛,纯前端);
- 认可对话完备性剧本修订:右栏不算「页面」,但卡内内容必须能从中栏锚点无跳转展开(验收项)。
同日新增需求:中栏过程/回复分离(Cursor 式)——流式期间思考/工具/中间轮解说照常显示,一旦最终回复开始流式,过程即时折叠,只显式显示回复,可手动展开回看。
2. 决策(D39 起:D34–D38 为认证提案 §5.1 预留段,虽未登记仍保持预留)
| # | 决策 | 理由 |
|---|---|---|
| D39 | 内容卡显式路由:助手长产物经内置工具 submit_card 提交为收件箱 kind=result 卡;切分判据写进 prompt 模块 style.cardflow 的 outputContract(产物型进卡:报告/纪要/方案/对比/文档草稿;解释型长回答留中栏);不做后处理自动拆分 |
拆分发生在生成侧:可断言、可审计;失败模式安全(不出卡 = 全文留中栏) |
| D40 | 卡片为产物权威载体:全文存 ActivityCard(cardsvc 持久化),消息 parts 只存 Part.card{cardId} 引用 + 摘要锚点;ctxasm 组装时对 card 部件回填卡片正文(上限默认 12000 字,超限记 Truncations),上下文观测如实显示 |
与「registry 工具大结果→artifact+ref」模式同构;下一轮模型不失忆;时间线审计保留引用记录 |
| D41 | 中栏过程/回复分离:工具轮文本部件带 process=true(终轮文本无标记);live 流式期间 phase=responding 即时折叠过程(acting 重展开,交错轮不粘滞);终态 >800 字长回复折叠(CF0);LiveState 文本按 delta index 分桶(除末桶外均过程) |
用户裁定(Cursor 式);live 投影与落库消息同构,终态对账无跳变 |
| D42 | 开关挂两层:用户设置 ui.cardflow(boolean,默认 false,effect=new-run)控制工具注册与 prompt 注入;画像 PromptModules 可显式引用/排除 style.cardflow 覆盖 |
「用户可选」与画像机制严丝合缝;设置面 schema 驱动自动出现 |
| D43 | 完备性剧本修订(D31 增补):右栏收件箱不算「页面」;开启卡流时,零页面走查增加双态用例,卡内全文必须可从中栏锚点部件无跳转展开(窄屏/右栏收起时阅读不残废) | 「内容被藏起来」是分栏设计最高风险;中栏自足摘要是硬规则 |
3. 实施切分(三期)
| 期 | 内容 | 仓 |
|---|---|---|
| R1 过程分离 | D36 全部(backend 工具轮 process 标记 + Stream 注入缝;frontend 分桶/即时折叠/CF0) | backend / frontend |
| R1 卡流 | D34/D35/D37:core CardPart.CardID;backend submit_card 工具+锚点回填+style-cardflow 模块+设置+ctxasm 回填+mock #cardflow;frontend 锚点部件(展开全文/跳收件箱)+result 卡体限高 |
core / backend / frontend / ui / documents |
| R2 收尾 | D32 另一半(卡→消息真定位,现误接 openInbox);result/待办轻分组;窄屏回退验证;双态零页面走查定稿 | frontend / documents |
跨仓顺序遵守 multi-repo 五步:core 先合入 → backend(同步 vendored core 副本)→ frontend/ui → Dev gitlink PR → 组合验证。
4. 契约与行为要点
CardPart{Kind, Data []UINode, CardID ID}:CardID 非空 = 收件箱引用部件(submit_card);空 = 插件内嵌卡(现状不变)。submit_card(title, summary, body):runner 内置工具(不经注册表,同 update_todos 先例),仅ui.cardflow=true时声明;执行 =CreateCard(kind=result, status=done, tone=ok, body=[markdown+摘要kv])+ 消息追加引用部件 + 工具返回「已发卡,对话中只留简短结论」;finishRun 持久化助手消息后把卡AnchorMessageID回填为该消息 ID。- 中栏锚点部件:
📄 {标题} · N 字 ▸ 展开全文 · ↗ 收件箱——展开内联渲染卡片 body(数据从 store.cards 取),跳转走 openInbox;旧正则兜底保留(插件卡)。 - 卡片内容流式(v1 一次性出卡)、飞书/微信通道投影(2.7 约束:新卡型必须能回答「这张卡在群里长什么样」——写入插件开发指南验收项)、与 artifact 统一、跨会话项目级收件箱:均留远期。
5. 边界与不做
- 不改
ResolveSystem签名(注入 = 向 prof.PromptModules 副本追加模块 id);不动 SSE 协议版本。 autoCollapseProcess偏好暂不加设置 UI(默认 true 即目标行为)。- 收件箱 pendingCount 语义不变(内容卡 status=done 不计入待办)。