makecindy / makecindy/cindy

bug: Art 连续多轮生成图片后移动端历史消息丢失并发生顺序错位

Open
#4,449 0 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.