长会话网关返回损坏的 HTTP 200,且手机端前置说明导致 /compact 失效
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
**提交人**: jermy
**客户端版本**: 0.1.37
---
## 现象
在 Cindy 桌面通过 Claude Code runtime 使用主机管理的模型路由时,一个长会话在约 37 万 tokens(模型标称 1M 上下文)后突然无法继续。后续每次发送消息都得到:
```text
API Error: API returned an empty or malformed response (HTTP 200) — check for a proxy or gateway intercepting the request
```
同一模型在新建会话中可以正常回复,因此不是账号、网络或模型整体不可用。Claude Code 的请求经过 Cindy 本地网关;旧会话没有出现自动压缩记录,且当时距离 1M 上限仍较远。
此外,从手机客户端向该旧会话发送 `/compact` 时,客户端自动在命令前加入“客户端说明”。最终送入 Claude Code 的消息结构类似:
```text
[客户端说明] ...
/compact
```
因此 `/compact` 不再位于消息开头,被当作普通用户消息发送给模型,没有触发 Claude Code 本地压缩命令,随后继续撞上同一个网关空响应。
## 复现步骤
### 问题一:长会话网关响应损坏
1. 在 Cindy 中创建 Claude Code 会话,使用支持 1M 上下文的主机管理模型路由。
2. 进行较长、包含多轮工具调用和文件操作的对话,使有效上下文增长到约 37 万 tokens。
3. 正常发送下一条用户消息。
4. 观察 Claude Code transcript:网关返回 HTTP 200,但响应体为空或不符合预期的流式协议。
5. 重试或继续发送消息,错误稳定复现;新建同模型会话则正常。
### 问题二:手机端破坏斜杠命令
1. 从 Cindy 手机端打开一个 Claude Code 会话。
2. 发送 `/compact`。
3. 检查 Claude Code transcript。
4. 可以看到系统自动追加的客户端说明位于 `/compact` 之前,导致命令未被识别。
## 期望行为
1. Cindy 本地模型网关应返回 Claude Code 可解析的标准流式响应;如果上游失败,应返回明确、可分类、可重试的错误码和错误体,不能以 HTTP 200 返回空或损坏内容。
2. 对长会话请求,如果上游或网关存在大小限制,应在到达限制前触发可恢复的压缩、给出明确限制信息,或提供自动迁移/恢复机制,不能让会话永久无法继续。
3. 手机端发送 Claude Code 斜杠命令时,命令必须原样透传,或把客户端说明放入独立的系统上下文,不能在命令正文前插入文本。
4. `/compact` 应在手机端与桌面端保持一致,能够触发 Claude Code 的本地压缩流程。
## 实际行为
1. 网关连续返回格式损坏的 HTTP 200,Claude Code只能记录 synthetic API error,旧会话无法继续。
2. 切换到 256K 模型会明确提示上下文超过 256K,但切回原 1M 模型仍收到损坏的 HTTP 200。
3. 手机端 `/compact` 被前置说明文本破坏,变成普通模型请求,无法用于恢复旧会话。
4. 用户只能新建会话并人工迁移上下文,原会话无法自愈。
---
**OS**: darwin arm64 (25.5.0)
**界面语言**: zh-CN
Contributor guide
Research direction
Start by tracing Cindy’s local model gateway and the mobile message-construction path, then compare their handling of Claude Code transcripts and slash commands. Reproduce both failures with a long session and a mobile `/compact` request. Done means the gateway returns parseable responses or explicit errors, and `/compact` reaches Claude Code unchanged and triggers its normal compression flow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, react-native, typescript
- Domain
- api, backend, mobile
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100