文档: 待办与决策更新
This commit is contained in:
94
docs/todo.md
94
docs/todo.md
@@ -849,3 +849,97 @@
|
||||
**关联**:CR-260620-02 审查 LOW-1 / F-09 决策e
|
||||
**状态**:✅ 已实施(删 aiChat.ts confirmNewConvWhileGenerating key zh/en + 改 TopBar/Sidebar 3 处 stale 注释,vue-tsc EXIT 0,2026-06-20)
|
||||
|
||||
---
|
||||
|
||||
### 🔍 2026-06-22 miniapp 功能走查(workflow wf_ddd49ac8 · 5 域并行核验 + 主代终态抽查)
|
||||
|
||||
> 用户 /review miniapp + workflow 汇总安排。5 agent 独立 grep/read 核验源码(不信注释/文档) + 主代终态核验(ws.ts 真路径 `src/api/ws.ts`、`relay.rs:255/355`、remote_bridge 命令数 10 非 11)。**18 findings → 去重 P1×5 / P2×3 / P3×1**,2 项 refuted。关联 F-260620-01 阶段4(真机联调前置)。**守 session-role-diagnose-only:本会话仅走查 + 登记,未实施代码。**
|
||||
|
||||
**P1(阻塞真机/可靠性·5 项)**:
|
||||
|
||||
- [ ] P1-D-260622 [P1🔴·真机分发最高阻断] — **token/deviceId 硬编码 + 无配对绑定 + 无 storage 持久化**。`config.ts:35-39` 硬编码本机 device_id+token(注释自认「联调期硬编码,后续做配对绑定」),`:52-54` setConfig 仅内存赋值无 `uni.setStorageSync`。真机分发不能用本机硬编码 device_id。修:settings 页输入 + setConfig 持久化 storage + getConfig 读回退 default。— `apps/df-miniapp/src/config.ts`
|
||||
- [ ] P1-A-260622 [P1🔴·可靠性] — **心跳 pong 闭环缺失**。`ws.ts:226` 发 `{control_kind:'ping'}`,`relay.rs:355` miniapp 入站全标 `MessageKind::Command` 透传 device,但 ping 无 cmd 字段 → `remote_bridge.rs:143` match 无 ping 分支 → device 收不到有效命令无 pong 回;`useAiChat.ts:440` onControl 仅 console.log 无 pong 处理;`ws.ts:245-257` 重连仅靠 onClose/onError 无心跳超时。移动网络 TCP 半连接高发,device 静默挂死无感知。修:relay 解析 ping 构造 Control 类型 + device 响应 pong + miniapp 维护 lastPongTime 看门狗(3×interval 未收 pong 主动重连)。— `ws.ts` + `relay.rs:handle_inbound_text` + `useAiChat.ts`
|
||||
- [x] P1-B-260622 [P1🔴·首屏连不上·✅2026-06-23核验已修] — **握手判定脆弱**。`ws.ts:185` `text.includes('"error"')` 字符匹配判握手失败(真机业务消息含 error 字符误判);同时 `ws.ts:181` 注释「relay 无显式 ack」错——`relay.rs:255` 实发 `{control_kind:"hello_ack"}` 但代码漏检。修:handleHandshakeResponse 改结构化解析——判 `msg.kind==='control' && msg.control_kind==='hello_ack'` 为成功,error 判 `msg.error` 字段存在性。— `apps/df-miniapp/src/api/ws.ts`
|
||||
- [x] P1-C-260622 [P1🔴·体验阻断·✅2026-06-23 核验已修] — **冷启动不恢复会话历史**。`App.vue:8-10` onLaunch 仅 connect,`chat/index.vue:62-64` onShow 仅 scrollToBottom,`useAiChat.ts:61` activeConversationId 初始 null → 真机首次打开空白。修:连接成功后 refreshConversations;chat onShow 中 activeConversationId=null 且有会话时自动选最近会话 + switchConversation(load_messages)。— `App.vue` + `chat/index.vue` + `useAiChat.ts`
|
||||
- [x] P1-E-260622 [P1🟡·多轮场景·✅2026-06-23] — **continueLoop/stopLoop 无 UI 入口**。`useAiChat.ts:699-700` 已导出,`useAiChat.ts:241-250` AiMaxRoundsReached 仅 clearWatchdog + 系统气泡「请去桌面端处理」,chat/index.vue 全文无调用。多轮场景用户真机无法继续/停止。修:max rounds 时 chat 渲染继续/停止按钮调 continueLoop/stopLoop。— `apps/df-miniapp/src/pages/chat/index.vue`
|
||||
|
||||
**P2(UX/健壮性)**:
|
||||
|
||||
- [x] P2-B-260622 [P2·quickfix·✅2026-06-23核验已修] — **deviceOnline 离线不复位**。`useAiChat.ts:76-77` 注释自认「MVP 不做超时复位」,全 src 无 `deviceOnline.value=false`,onStatus 断开/重连只 clearWatchdog。device 断线状态滞后。修:onStatus 回调 disconnected/reconnecting 加 `deviceOnline.value=false`(一行)。— `useAiChat.ts`
|
||||
- [x] P2-C-260622 [P2·quickfix·✅2026-06-23] — **路由表注释陈旧(双侧)**。`types/relay.ts:86` 称「8 条」实际 match 10 条;`remote_bridge.rs:13-25` 注释列 9 条实际 10(F-#95 扩展 list_conversations/load_messages 未同步注释)。修:双侧注释补 list_conversations/load_messages + 数字改 10。— `types/relay.ts:86-88` + `remote_bridge.rs:13-25`
|
||||
|
||||
**P3/defer**:
|
||||
|
||||
- [x] P2-A-260622 [P2·defer·✅2026-06-23] — **messages 内存态无上限(OOM)**。`useAiChat.ts:56` reactive 无 MAX_MESSAGE。联调短会话无风险,长会话再做(MAX_MESSAGES=100 + truncate 保留最新 50)。— **已修**:watch trim MAX_STORE_MESSAGES=500(渲染另有 visibleMessages slice 200 兜底)。
|
||||
- [x] P3-A-260622 [P3·defer·✅2026-06-23] — **输入框单行非 textarea**。`chat/index.vue:176-184` `<input type="text">`。MVP 单行可接受,多行场景再升级 textarea auto-height。— **已改 input→textarea auto-height**(max-height 120px + flex-end 对齐;⚠️ 原生层级遮联想浮层风险待用户实测,fallback cover-view)。
|
||||
|
||||
**已驳回(refuted·不记 todo)**:regenerate 双 user 气泡(UI 展示层非逻辑错,switchConversation 即清)/ 看门狗 130s(实现正确无需修)/ 审批卡+流式光标(完成项核对,非问题)。
|
||||
|
||||
**真机分发前置序(P1 按依赖)**:P1-D(token/配对)→ P1-A(心跳闭环)→ P1-B(握手解析)→ P1-C(冷启动恢复)→ P1-E(max UI)。P2-B/C 可同批 quickfix(注释对齐 + 一行复位)。
|
||||
|
||||
**用户补充核验(2026-06-22 用户详读源码+设计文档,主代逐项核源码判真伪)**:
|
||||
|
||||
> ⚠️ 用户分析 P0 三项(协议三重不匹配 / EventBus 未接 / 桥接层占位)**经源码核验全部失实**,系基于 Phase3 阶段1-3 落地前的设计文档「计划态」描述,未核当前代码。证据:
|
||||
> - **P0-1 协议**:`crates/df-tunnel/src/tunnel.rs:457/327/424` tunnel 纯透传 payload `Value` 上抛 on_command,**不**做 `from_value::<TunnelCommand>` 强类型反序列化(方案A 阶段1 已落地 commit 0fb5af5)→ miniapp `{cmd,args}` 反序列化在桥接层 `remote_bridge.rs:96 from_payload` 成功,非阻断。tunnel.rs:457 注释自证「不反序列化为 TunnelCommand 强类型」。
|
||||
> - **P0-2 EventBus**:`src-tauri/src/lib.rs:128` `state.ai_event_bus.subscribe()`(tunnel subscriber 已接)+ `remote_bridge.rs:303/332/358/388` + `commands/ai/mod.rs:209/225` `publish_event` 跨端透传。**已双写接入**(todo line 760 commit 0fb5af5/612de4c emit 双写 chat19/audit12/guard3/stream_recv2/agentic18)。`event_bus.rs:53/115` 的 `#![allow(dead_code)]`+「骨架阶段」注释是**过时历史标注**(publish_event 现有调用方 remote_bridge/mod),非未接入。
|
||||
> - **P0-3 桥接层**:`remote_bridge.rs` 完整实装(`handle_remote_command`:121 + `MiniCommand`:83 + `from_payload`:96 + match 路由 10 条 + `route_list/load_messages` publish_event)+ **已 wire** `lib.rs:150-154` `on_command = Arc::new(...handle_remote_command...)` + `:171` `.connect(&relay_url,&device_id,&token,on_command.clone())`。非占位/设计态。`remote_bridge.rs:40-42` 的 `#![allow(dead_code)]`+「零调用方」注释写于联调前,现 lib.rs 已调(过时标注,待清)。
|
||||
|
||||
**属实补充项(用户提出 + 主代核源码确认,追加 todo)**:
|
||||
|
||||
- [x] P1-F-260622 [P1🟡·✅2026-06-23] — **消息操作缺失(复制 / regenerate UI 入口)**。`regenerate()`(`useAiChat.ts:520`)已实现但 chat 页无入口;复制消息功能全缺(桌面端有 hover 操作栏)。修:消息气泡加长按/点击操作(复制全文 / regenerate)。— `apps/df-miniapp/src/pages/chat/index.vue`
|
||||
- [x] P1-G-260622 [P1🟡·体验·✅2026-06-23] — **Markdown 渲染简陋**。`MdView.vue` 用 rich-text 无代码高亮 / 图片预览 / 链接拦截(MdView.vue 注释自认弱点);流式无节流(注释承认「长回复卡顿后续 P1 加 setTimeout 节流」)。修:评估 mp-html CLI local import `<node>` 子组件不渲染问题的修复,或换方案 + 流式 setTimeout 节流。— `apps/df-miniapp/src/components/MdView.vue`
|
||||
- [x] P2-D-260622 [P2·健壮·✅2026-06-23核验已修] — **断连期间操作静默丢失**。`wsClient.send()` 失败仅 console.warn + 返 false,但 `stop()/approve()/authorizeDir()` 忽略返回值 → 用户点「批准」UI 已乐观移除 pending 但命令未发出。修:这些方法检查 send 返回值,失败 toast 提示 + 不移除 pending。— `apps/df-miniapp/src/composables/useAiChat.ts`
|
||||
- [x] P2-E-260622 [P2·健壮·✅2026-06-23] — **审批乐观移除无失败回退**。approve() 即 splice pending,若 device 端 tool_call_id 已被桌面端处理致审批失败,miniapp 已移除 UI 误导用户以为成功。修:approve 失败(超时 / AiError 事件)回填 pending。— `useAiChat.ts`
|
||||
- [ ] P3-B-260622 [P3·真机前置] — **manifest appid 占位**。`PLACEHOLDER` 无法真机调试,需微信公众平台注册的真 appid。— `apps/df-miniapp/src/manifest.json`
|
||||
- [x] P3-C-260622 [P3·清理·✅2026-06-23 核验已清] — **mp-html 死依赖残留**。package.json 仍引 `mp-html@^2.5.2` 但 MdView 已改 rich-text 弃用。确认不回退 mp-html 则移除依赖(当前 `src/components/mp-html/` 预留保留,依 [[dead-code-reserve-keep]] 待回退决策)。— `apps/df-miniapp/package.json` — **核验:package.json 已无 mp-html + grep 全 src 零引用,已清(陈旧 todo)**。
|
||||
- [x] P3-D-260622 [P3·体验·✅2026-06-23] — **token 用量 UI 缺失**。`tokenUsage` 状态有但页面未展示。— `apps/df-miniapp/src/pages/chat/index.vue`
|
||||
|
||||
### ✅ 2026-06-23 miniapp 全功能审查加固(workflow wll7qabgr + 主代串行)
|
||||
|
||||
> 6 区域并行审查(chat/会话页/useAiChat/连接层/组件/工程;2 区域限流主代补审)。**自主实施**(逐批 vue-tsc 0 + build DONE 核验):
|
||||
> - **F1** `AiConvStateChanged` idle/error 终态漏 clearWatchdog → 补 clearWatchdog(兑现注释承诺,防 timer 泄漏假超时)
|
||||
> - **F2** regenerate() 无 generating 守卫 → 加守卫 + toast(防 send 静默 return 无反馈)
|
||||
> - **F3** flushCurrentText 启发式回填错位 → 引入 currentAssistantMsgId 按 id 精确回填(治 retry/error/compressed 气泡穿插污染)
|
||||
> - **F9** stop() 无终态兜底 + **chat 页无停止按钮** → stopping 标志乐观复位 + 忽略迟到 delta + 生成中显「停止」按钮(原 generating 时 send 禁用且无停止入口,用户无法中断生成)
|
||||
> - **F21** 连接状态裸枚举字符串 → 中文文案 + 断开/重连中点状态栏手动重连
|
||||
> - switch 加 default warn / ws.ts 二进制帧 warn / scheduleReconnect 加 MAX_RECONNECT_ATTEMPTS=20 + 手动重连复位计数
|
||||
> - 删 pages/test 死页(uniapp alpha tap 排查探针,grep 零引用)
|
||||
>
|
||||
> **06-22 走查项核验销账**(源码已修,标 [x]):P2-B deviceOnline 复位 ✅ / P2-D 断连操作 send 返回值检查 ✅ / P1-B 握手结构化解析 ✅
|
||||
>
|
||||
> **06-22 项部分缓解**(alternative approach):P1-A 心跳 pong 闭环 → 当前用「任意入站消息」活性检测(HEARTBEAT_DEAD_FACTOR)替代 pong 往返,半开死连接已有兜底;pong 精确闭环见 MINIDEC-260623-06 ⏸️ / P1-C 冷启动恢复 → active conv id 已持久化 + 握手发 list_conversations;冷启动自动 load_messages 待核
|
||||
>
|
||||
> **剩余开放项 → 待决策**(见 [待决策.md](./待决策.md) df-miniapp 组):MINIDEC-260623-01 配置层(=旧 P1-D)/ 02 配对 / 06 心跳历史协议 / 07 regenerate+备份组件漂移。(03 重连续流 / 04 审批双源 / 05 会话页重命名 已实施,见下)。06-22 走查剩余 [ ]:P1-A(缓解)/P1-E(MaxRounds UI)/P1-F(复制+regenerate UI)/P1-G(Markdown 渲染)/P2-C(注释)/P2-E(审批回填)/P3-A/B/C/D。
|
||||
|
||||
### ✅ 2026-06-23 miniapp 用户需求批(req1/2/3 · 用户决策后实施)
|
||||
|
||||
> 用户 3 要求:(1) 会话重命名对齐桌面端 (2) 断网消息不丢失+从远端拉完整 (3) 审批断网重连恢复卡片状态。逐批 cargo check 0 + vue-tsc 0 + build DONE 核验。
|
||||
> - **req1 会话重命名**:remote_bridge `rename_conversation` 路由(调 ai_conversation_rename + 推 AiConversationList 刷新)+ useAiChat `renameConversation`(乐观本地更新)+ conversations/index.vue 长按 `uni.showModal` 编辑。
|
||||
> - **req2 断网不丢消息**:useAiChat `syncOnConnect` —— ws 'connected' 触发发 load_messages 拉当前会话完整历史(断网 missed 消息恢复 + 兼修冷启动空白 P1-C-260622)。
|
||||
> - **req3 审批重连恢复**:remote_bridge `sync_pending` 路由(读 AiSession.pending_approvals 按 conv 过滤,重发 AiApprovalRequired/AiDirAuthRequired)+ useAiChat onStatus 'connected' 清 pendingApprovals + 发 sync_pending 重建 + handleEvent 同 id 去重防竞态。**审批卡改从 pendingApprovals 独立面板渲染**(与 messages 解耦,避重连 load_messages 替换 messages 的竞态;落地 MINIDEC-04 单一渲染源决策 a),内联工具卡保留状态徽标/参数/结果。
|
||||
> - **P1-C-260622 冷启动恢复** 顺带修复(syncOnConnect 初始连接也拉历史 + active conv id 已持久化)。
|
||||
|
||||
### ✅ 2026-06-23 miniapp 🟡 收尾批(P1-E/F + P2-C/A + P3-D/C · 自主推进)
|
||||
|
||||
> 用户定「自用」后低风险收尾项一次性做完。逐项 vue-tsc 0 + build DONE 核验。
|
||||
> - **P1-E MaxRounds 继续/停止**:useAiChat `maxRoundsActive` ref(AiMaxRoundsReached 置 true,continueLoop/stopLoop/send/switch/new 清)+ chat 「已达最大轮次」面板(继续一轮/停止按钮)。
|
||||
> - **P1-F 重发 + 复制**:chat 输入栏「重发」按钮(调 regenerate,非生成中且有消息时显)+ 消息 @longpress 复制全文(uni.setClipboardData)。
|
||||
> - **P3-D token 用量**:顶栏显 🪙 total(ai.tokenUsage)。
|
||||
> - **P2-C 注释陈旧**:relay.ts 路由表 12→14(+ rename/sync_pending)+ remote_bridge.rs 表头补两行。
|
||||
> - **P2-A messages 内存上限**:useAiChat watch trim MAX_STORE_MESSAGES=500(渲染另有 visibleMessages slice 200)。
|
||||
> - **P3-C mp-html 死依赖**:核验 package.json 已无 + grep 全 src 零引用(陈旧 todo,无需改)。
|
||||
> - **MINIDEC-07** 随 P1-F 选 a(regenerate 加 UI 不删)+ 备份组件保留预留,已落。
|
||||
>
|
||||
> **剩余 [ ](非阻塞)**:P1-A 心跳 pong(已缓解=MINIDEC-06 暂缓)/ P3-B manifest appid(真机前置,需注册)。(P1-G/P2-E/P3-A 见下 polish 批已落)
|
||||
|
||||
### ✅ 2026-06-23 miniapp polish 批(workflow wll377z2c 设计 → 串行实施)
|
||||
|
||||
> workflow 3 agent 并行设计(无限流)→ 汇总排序 → 主代串行实施,逐项 vue-tsc 0 + build DONE。
|
||||
> - **P2-E 审批失败回填**(low):useAiChat `lastApprovedTc` ref —— approve(approved=true) 记录,device 返 AiError 回填 pendingApprovals + toast「审批操作未生效,请重试」让用户重试;AiApprovalResult/AiToolCallCompleted 确认 → 清;切会话/新建/断连 → 清。
|
||||
> - **P1-G Markdown 渲染**(medium):新建 `utils/mdRenderer.ts` —— marked HTML 后处理注入 inline style(pre 深底等宽/code 橙色/a 蓝下划线/table border),规避 marked renderer v18 签名风险(rich-text 不认 class)。chat/index.vue renderMd + MdView.vue 接入。**链接跳转 rich-text 不可行**(<a> 节点事件屏蔽)降级展示+长按复制,跳转留 mp-html 后续。
|
||||
> - **P3-A textarea 多行**(high):input→textarea auto-height(max-height 120px + .bar flex-end 对齐)。⚠️ **原生层级遮联想浮层风险待用户实测**(textarea 原生组件渲染在 WebView 之上,可能遮盖 .mention-pop);若遮挡严重,fallback 联想浮层改 cover-view(单独任务,本次未做)。
|
||||
>
|
||||
> **miniapp 自用阶段功能全部闭环**。剩 P1-A(暂缓)/P3-B(appid 真机前置,需你注册)。
|
||||
|
||||
**与主走查重复(用户项 = 已登记,跳过)**:用户 P1-5(配置硬编码)= P1-D / P1-6(MaxRounds UI)= P1-E / P2-11(deviceOnline 不复位)= P2-B / P2-9(R1 并发防护)= `remote_bridge.rs:27-33` `check_generating_reject` **已实现**(send_message 路由前置 generating 检查)。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user