makecindy / makecindy/cindy

bug: Mac sleep during mobile send can duplicate a conversation message after reconnect

Open
#4,481 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
2.7k
Forks
401
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 问题描述 / What happened

在手机通过 Device Link 向 Mac 发送一条对话消息后,如果 Mac 很快熄屏,Device Link 断开;Mac 唤醒并重连后,可能出现:消息实际已经被 Mac 接收或开始执行,但手机没有收到 invoke-result 或 user-message push;重连后的 projection、消息历史和实时订阅在不同时间点恢复,界面出现同步抖动;手机将消息误判为“未发送”,把原文恢复到输入框,用户再次点击发送后同一内容被执行两次。

期望行为:断链期间无法确认写请求是否已被 Mac 接收时,应保留同一条消息的可对账身份,直到重连后的权威同步明确给出“已接收”或“未接收”;状态未确认时不应恢复成一条使用新 clientId 的可重发消息;Mac 唤醒后的同步应最终收敛且不重复执行。

当前源码分析出的可能原因(待验证):

1. maker.input.enqueue 已经发出,但 Mac 熄屏导致回执丢失。Device Link 会将这类请求标记为 inFlight,客户端无法安全假设“未发送”。
2. Mac 唤醒后,getProjection、消息列表和实时 push 到达顺序不一致;消息可能已从 pending queue 进入 active turn,但手机暂时在这些来源中都查不到。
3. 普通直发路径在对账失败后会移除乐观消息并恢复草稿;用户再次发送时生成新的 clientId,绕过 Mac 端按 clientId 的去重。
4. 新建任务首条消息的 enqueue 失败探测在“已执行但尚未可见”的窗口内进入 enqueue-failed,随后用户用新 clientId 重发。

相关代码:
- apps/mobile/app/sessions/[sessionId].tsx:普通发送、断链重试、projection 对账和草稿恢复
- apps/mobile/src/session/newSessionCreation.ts:新建任务首条消息失败后的探测与恢复
- packages/device-link/src/client.ts:断线时将已发请求标记为 inFlight
- apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts:按 clientId 去重

## 环境 / Environment

- Cindy 版本或 commit / version or commit: 待补充
- 平台与版本 / platform & OS version: 手机端版本待补充;被控端 macOS 版本待补充
- 安装方式 / install method: 待补充
- 连接方式: 手机 → Device Link → Mac Desktop

## 复现步骤 / Steps to reproduce

1. 准备一台安装 Cindy Desktop 的 Mac,以及一台已连接同一 Cindy 账号的手机;确认手机可通过 Device Link 打开已有任务。
2. 在 Mac 打开目标任务,确保手机和 Mac 都在线,且没有其它正在执行的消息。
3. 在手机输入:请只回复唯一标记 DUP-RECONNECT-001,不要调用工具。
4. 点击发送后立刻让 Mac 熄屏(或合盖),保持 5–15 秒,使 Device Link 断开。关键时机是手机已开始发送但尚未收到成功回执或对应 user-message push。
5. 唤醒 Mac,等待 Device Link 自动重连,观察发送状态、任务消息列表、pending queue 和连接/同步提示。
6. 如果原文被恢复到输入框,先不要修改文本;等待 Mac 完成重连同步,确认历史中是否已经出现第一条消息。
7. 点击发送(若消息仍在输入框中),观察是否产生两次用户消息、两次 assistant 回复或两次可见执行效果。
8. 重复测试 Mac 立即熄屏、发送约 1 秒后熄屏、Mac 已显示收到消息后熄屏;另测试断网期间不手动重发,以区分自动重复与恢复草稿后的手动重复。

## 日志与截图 / Logs & screenshots

请提供手机端和 Mac Desktop / Device Link 端发送前后约 30 秒日志;是否只点击过一次发送按钮;消息 clientId、Device Link requestId、断开/重连时间(如日志中可见);重连后历史、输入框和 pending queue 截图。粘贴前请删除 token、账号标识、工作目录和私人消息正文。

Contributor guide

Open the contributing guide

Research direction

Start with apps/mobile/app/sessions/[sessionId].tsx for ordinary sending, reconnect retry, projection reconciliation, and draft recovery. Then inspect apps/mobile/src/session/newSessionCreation.ts, packages/device-link/src/client.ts, and apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts while reproducing the Mac sleep and reconnect sequence. Done means uncertain sends retain one reconciliation identity, authoritative sync converges, and the message cannot execute twice.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
desktop-dev, distributed-systems, mobile-dev, networking
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.