Commit Graph
22 Commits
Author SHA1 Message Date
AskaEth cfdc094c30 fix(chat): 设置项「她正忙时按发送」不再空转 —— 发送前按偏好决定是否先打断
设置页那个开关此前没有任何发送路径读它:interruptMode 全仓只出现在 AppSettings
(定义 / 读写)与 SettingsScreen(渲染文案),于是把它切成「打断」后行为与「追加队列」
一模一样,ChatSocket.sendInterrupt 更是零调用方(死 API)。这正是一直挂在文档
devdocs/02 协同项 A2 上的欠账(后端 v0.56 已支持 scope,客户端没接)。

现在按契约 v0.56 §3.1 接上,判据抽成与发送路由同类位置的纯函数
interruptScopeForSend(mode, busy: Boolean):String?

1. 追加队列(默认档)⇒ 恒定返回 null,一个 interrupt 帧都不发,线上请求与今天逐字节相同;
2. 打断(wireScope = "current")且会话正忙 ⇒ 这条消息之前先发 interrupt{scope:"current"}
   (只取消在跑回合、保留待处理队列,队列里的消息按编排器续跑,一条都不丢);
3. 打断但会话空闲 ⇒ 不发(命中空闲会话是 no-op,白发一条帧只多一次往返,还会在 logcat
   里制造「这里打断过」的假象)。

「正忙」只认服务端 session_busy 帧给的 busyMode != null,不用 queueDepth——队列深度
非零不等于有回合在跑(pending_ack / pending_drain 也会动它)。

接线点在 ChatViewModel.deliver() 的通道分支之前(app/src/main/kotlin/top/yeij/cyrene/
ui/chat/ChatViewModel.kt)。放在那里而不是 emitAndDeliver 开头是刻意的:上面每一段本端
拒绝(附件超限 / 图片处理失败 / 附件上传失败 / 引用不合法)都会「回滚、什么都不发」,
先打断她的回合再什么都不发是凭空的破坏。每次投递只经过那里一次,所以一次投递最多一条
打断帧,任何后续分支与重试都不会重复发。

偏好每次发送现读(不缓存、不订阅 Flow):「在设置页切成打断、然后立刻发的那一条」正是
本次要修的场景,缓存值要等 Flow 推到才更新,冷启动那一下必然没到——那就等于留了一个
静默不生效的窗口。读失败(IO / 损坏)回落默认档,也就是最少动作的那一档,与 AppSettings
把未知取值解成默认档是同一条纪律。

打断帧发不出去(只有「WS 未连接」一种原因)静默、不阻断本次发送:本次消息的成败与它
无关(REST 通道不看 WS 连接),且一直有既有的回执 / 回滚路径如实上报;反过来「打断失败」
没有对应得上的动作(重试等于把消息再发一遍,正是幂等键在防的事),喊一声只会误导。
于是打断没生效 = 行为退回默认档,是用户看得懂的状态,不是被藏起来的事。

测试:新增 InterruptScopeTest 8 条(两档 × 忙闲四格穷举 + 默认档零行为变化 + 偏好回落
方向),全仓 884 → 892。assembleDebug 与 testDebugUnitTest 全绿(0 失败 0 错误)。
设置页那两条文案原本就与 scope:current 的真实语义相符(「已排队的消息保留,继续依次
回答」),未改一个字。

文档:02 的 A2 状态表、05 的 A2 条目都写着「客户端尚未接入该字段」;03 里「打断模式 →
UI 限制一次只发一条」的前提(interrupt 会清空 pending)也随之失效,三处一并补记更正。
2026-10-04 22:29:57 +08:00
AskaEth b8f0833137 docs: 收下后端回执十二 + 登记本轮三条接入结论 + 05 锚点补记二(含两条新教训)
devdocs/02(与后端会话共用的协作文档):
- 收下他们的**回执十二**:knowledge 的根因(参数角色缺席 + 收尾静默分支)与修法、并行
  tool_use/tool_result 配对的新 P0(客户端不需要适配)、契约 v0.64 的只读
  GET /admin/llm/usage、IM 入站文件「能拿到字节」(真机验证只能由主人做)、
  llm_usage.session_id 恒为 NULL。
- 追加**我方登记**:v0.63 那两条(reason / 404)都已接入并推送;after 正向增量的两条口径;
  及一条要他们确认的**我方主动口径** —— unreadable 且 mime 是 text/ 时让 reason 压过正文渲染。
- 他们点出的三处旧口径(1049/1110/1309 行)我核过,**都在他们自己的回执段落里**,按同一条规矩
  请他们自己更正,我们没有动手。

devdocs/05(我方进度与交接):
- 锚点更新:HEAD、884 测试、本轮 5 条落地、待办重排、家务办完。
- 新增「本轮未验证的」一节:把**验过的**与**没验过的**分开写(404 兜底验通;after 只验到「真请求
  打出去了」、补洞端到端仍未验;W24/W23 的设备侧只验到能开的程度)。
- 两条新教训:① 那个「未响应弹窗」是模拟器/宿主机被拖垮(日志里系统自己的
  PointerEventDispatcher 卡了 37 秒),uiautomator dump 要省着用;② **一次性告知不能挂在会被销毁的
  状态上** —— 404 兜底第一版就是这么悄悄失效的,只有真机看一眼才能发现。

本次提交只动文档,无代码改动。代码侧本轮四个提交(28c3142 / 1794e53 / b5c0b13 / 2d382b1)都已推到
origin/android。
2026-10-04 22:22:51 +08:00
AskaEth e4915a6904 docs(02): 收下后端回执十一(四点确认 + knowledge 缺陷已立案 + IM-1/U1 在实施)
后端会话直接写进了本机 devdocs/02(与主树共用同一份文件),这里把它落成一次提交,
免得长期挂在工作区、也便于将来对时间线。

回执十一的四点:sess-* 不加 404 例外(与我们的答复一致);documents[].reason 他们不会擅自改文案
(要改会同时升契约并回执);404 session_not_found 的用法确认;日期更正已互相认账。

另两条与我们相关的:
- 我们登记的 knowledge 工具失败(E2E-DOC 那条,纯文本也复现)他们已按更正后的口径立案排查,
  修复推库后会补一条回执(含根因文件:行)。他们同时要求「无论回合因何结束都落一条可见的
  assistant 消息」,边界保留:被 interrupt 取消 / 被 stale gen 取代 / 静默内部流程仍不落库。
- IM-1(各适配器入站内联受支持格式的文件字节)与 U1(llm_usage 落库 + 只读汇总端点
  GET /api/v1/admin/llm/usage,后续契约 v0.64)在实施中 —— 后者对我们只有将来做管理页时才算增量。

本次提交只增文档,无代码改动。
2026-10-04 22:01:01 +08:00
AskaEth a84d473e2f docs: 收下后端回执十(契约 v0.63:documents[].reason + messages 对已删会话回 404)+ 答复 sess-* 提问 + 锚点补记两条新待办 2026-10-04 21:51:08 +08:00
AskaEth 9f92a8ade5 docs(05): 恢复锚点更新 —— 记上凭据落地位置(dev-secrets.local.md,gitignore)、新 HEAD、模拟器启动参数 2026-10-04 21:50:31 +08:00
AskaEth 92ee7fedbd docs(05): 落「恢复锚点」(当前状态 / 已完成模块清单 / 待办 / 家务)—— 便于上下文压缩后接续 2026-10-04 21:46:56 +08:00
AskaEth 647cf47cf2 docs(05): 更正 ① W16 搜索的结论 —— 本来就是好的,先前「设备上不可用」是我的测量假象(含教训:动代码前先用像素确认症状) 2026-10-04 21:46:26 +08:00
AskaEth 3ff4f45166 docs: 更正文档里的日期标注 —— 本轮都发生在 2026-10-04 深夜,之前误写成 10-05(含后端回执九那一行) 2026-10-04 21:42:37 +08:00
AskaEth c67aa2da48 docs(05): 存档本轮装机验收的设备证据(W18/W15/W19 通过、W16 确认不可用、四条新坑) 2026-10-04 21:41:45 +08:00
AskaEth e8c6389fde docs(02): 收下后端 GC 策略与回复 + 更正 knowledge 工具失败的范围(纯文本也复现)+ 一条 adb reverse 方法论 2026-10-04 21:41:20 +08:00
AskaEth 5d8ab15c0e docs(02): 登记 unreadable 缺原因字段 + 文本层 PDF 的措辞别扭(均已如实处理,未替服务端编话) 2026-10-04 21:18:05 +08:00
AskaEth 020687a82b docs(02): 收下后端回执八(v0.60 存储端点 / v0.61 PDF 文本层 / K1 API Key 落盘 / 两条行为变化) 2026-10-04 21:13:14 +08:00
AskaEth b579732db6 docs: 落 W15/W16 批次(重试复键的取舍、会话内搜索的形状)+ 六条契约口径登记 2026-10-04 20:50:23 +08:00
AskaEth 76d49b73d1 docs(05): 落 W13/W14 批次与实机验收、W13 的两条文档不符、W14 取字节无 logcat 的证据改法、回执七要点 2026-10-04 19:52:57 +08:00
AskaEth 9e039863fa docs(02): 收下后端的回执七(大附件护栏修复上线、API Key 仅内存表、IM 文件边界、v0.60 预告) 2026-10-04 19:43:52 +08:00
AskaEth 8633ec9f06 docs(05): 落 W11/W12 批次与实机验收、SAF 双扩展名 bug 的修复、GMS ANR 与 dump 重试两个新坑 2026-10-04 19:28:53 +08:00
AskaEth a0d6e3479f docs(02): logs REST 已接上(闭环)+ 五条契约口径建议补写 + 铸不出 viewer 账号的验收缺口 2026-10-04 19:20:15 +08:00
AskaEth c94ea09b59 docs(02): 登记纯附件回合(Android 端首测)没有助手消息 + 两次 knowledge 工具失败 2026-10-04 19:12:52 +08:00
AskaEth e59ef08cf9 docs(05): 落 W8–W10 批次状态、模拟器与该轮自动化的坑、契约 v0.59、附件预览欠账 2026-10-04 19:09:10 +08:00
AskaEth 2369dd2115 meta(docs): devdocs/ 纳入版本库 —— 交接与协同文档不再只存在于本机
主人 2026-10-04 指示「项目仓库也可以写进去」。因此把 devdocs/ 从 .gitignore 移除并首次入库:

- `05-开发进度与交接.md` —— 跨会话交接锚点:当前状态、易忘的实现约定、踩过的坑、实机验收方法
- `02-前后端协同事项.md` —— 与后端会话的**交换文档**(两边都会读写:我们登记缺口,对面写回执)
- `01/03/04/06/07` + `DESIGN.md` —— 路线、客户端细化方案、构建环境、迁移说明、给后端会话的交接

**凭据扫描已过**:无账号口令、无 token/refreshToken 明文、无 API key 或私钥。
文档里只记「登录凭据不写进文档,问主人」这条口径本身。

(此前忽略它的理由已不成立:文档现在承担跨会话交接与前后端协同两件正事,
只留在本机磁盘会随机器丢失,而这批内容的价值恰恰在「后来人读得到」。)
2026-10-04 19:00:18 +08:00
AskaEth 0587f5a45f chore: devdocs 移出版本控制
设计/协作文档只保留在本地,不再随仓库分发。
2026-09-08 20:50:40 +08:00
AskaEth 84de51c7b7 feat: 初始化 Android 客户端(M0 骨架 + M1 登录 + M2 基础模块)
M0:Gradle 9.7.1 / AGP 9.2.1 / Kotlin 2.4 / Miuix 0.9.3,minSdk 33,compileSdk 37。
M1:登录页(服务器地址可配、服务端/本地错误分流、EncryptedSharedPreferences、自动登录与静默重登、401 登出)。
M2 基础模块:消息内容解析器(<p>/<action>/<narration> + 流式增量)、WebSocket 客户端、REST 数据层与分页去重。
45 个单元测试全绿,真机验证通过(登录页 + 启动图标)。
devdocs/ 收录设计文档、前后端协同事项与细化方案。
2026-09-08 20:40:58 +08:00