bug: Art 连续多轮生成图片后移动端历史消息丢失并发生顺序错位
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 问题描述 / What happened
在 Desktop 上使用 Art 插件连续多轮生成或修改图片时,移动端会出现历史消息丢失和顺序错位:
- 前面已经完成的用户消息、assistant 回复或图片结果无法显示;
- 在移动端继续输入新消息后,已有历史消息的位置发生变化或顺序不正确;
- Desktop 端本地会话数据仍然存在,重新完整加载后部分消息可以恢复。
本次任务中,Art 连续生成图片产生了大量 thinking、tool_use、tool_result 和 assistant 消息。移动端最终只显示最近一段消息,历史窗口不再连续。
期望行为:移动端应保持完整的历史顺序;Device Link 发生拥塞、断连或实时消息丢失后,应根据服务端历史补齐缺失消息;移动端继续输入不应改变已有历史消息的顺序。
## 环境 / Environment
- Cindy 版本或 commit: 0.1.81
- 平台与系统版本: Desktop Windows;复现设备为已连接的移动端
- 安装方式: Cindy Desktop 安装包
- 相关插件: cindy-art
## 复现步骤 / Steps to reproduce
1. 在 Desktop 上创建或打开一个任务。
2. 调用 cindy-art 生成一张图片。
3. 连续发送多轮修改要求,例如重新生成、只修改一个角色、保留另一角色、修改画风并再次生成。
4. 在移动端打开同一个任务。
5. 等待多轮图片生成完成,观察移动端历史消息。
6. 在移动端继续输入一条新消息。
7. 观察前面的历史是否消失,以及新消息插入后历史顺序是否发生变化。
## 日志与截图 / Logs & screenshots
相关任务的本地消息库中约有 142 条消息,其中发现两条异常大的图片工具调用消息:
- rowid=34406,role=tool_use,content length 约 2,797,248 bytes
- rowid=34412,role=tool_use,content length 约 2,797,220 bytes
这些消息来自将本地参考图片编码为 base64 后调用 mcp:cindy:media。
Device Link 同时出现以下日志:
txt
[2026-09-14T19:23:23.692+08:00] [INFO ] [device-link]
device-link recovery ... pending=26/14121 ...
[2026-09-14T19:23:23.955+08:00] [INFO ] [device-link]
device-link recovery ... pending=26/14121 recoveryFrames=8/8 ...
[2026-09-14T19:23:24.176+08:00] [WARN ] [device-link-dispatch]
push delivery failures {
peer: '7dd01352',
channel: 'usage:codex-account-changed',
code: 'BACKPRESSURE',
count: 1
}
初步怀疑:
1. 大型媒体 tool_use 消息导致 Device Link 可靠帧和实时 push 出现 backpressure。
2. 移动端漏收部分 local-db:messages:created 消息。
3. apps/mobile/src/session/historyWindowGap.ts 当前使用 30 分钟时间间隔判断历史空洞;本次连续生成发生在几分钟内,因此消息缺失不会被识别为历史空洞。
4. 后续 apps/mobile/src/session/remoteSessionStore.ts 的 setLatestMessageWindow() 刷新最新窗口时,可能丢弃无法确认连续性的旧缓存。
5. 移动端新输入触发消息重新锚定后,最终表现为历史缺失和顺序错位。
请重点确认:
- 大型图片输入是否在进入 Device Link 可靠消息流前被完整投递;
- local-db:messages:created 丢失后是否有基于消息数量或游标连续性的补偿机制;
- 30 分钟历史空洞阈值是否无法覆盖短时间内高密度消息缺失;
- 最新窗口刷新是否会在 push 丢失时错误丢弃旧历史;
- 移动端 optimistic message 与服务端 user message 是否可能在不完整窗口上重新锚定。
相关代码位置:
- apps/desktop/src/main/device-link/mobileToolProjection.ts
- apps/desktop/src/main/device-link/dispatch.ts
- apps/mobile/src/session/remoteSessionStore.ts
- apps/mobile/src/session/historyWindowGap.ts
- apps/mobile/app/sessions/[sessionId].tsx
未附带 base64 内容、完整本地路径、凭证或其他个人数据。
Contributor guide
Research direction
Trace message delivery and recovery across apps/desktop/src/main/device-link/mobileToolProjection.ts, apps/desktop/src/main/device-link/dispatch.ts, apps/mobile/src/session/remoteSessionStore.ts, and apps/mobile/src/session/historyWindowGap.ts; begin with the reported backpressure and recovery logs. Reproduce the multi-round cindy-art session and verify that missed messages are recovered in order, history remains complete after refreshing the latest window, and a mobile optimistic message does not reorder existing history.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, react-native, typescript
- Domain
- distributed-systems, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100