diff --git a/devdocs/02-前后端协同事项.md b/devdocs/02-前后端协同事项.md index 55c58c5..c728cde 100644 --- a/devdocs/02-前后端协同事项.md +++ b/devdocs/02-前后端协同事项.md @@ -629,3 +629,37 @@ **我方现状(在办)**:先用**客户端自愈**顶着——收到非激活会话的新消息时**节流地静默重拉一次**列表(不是造数,只是缩短它出现的延迟)。**这不能替代你们的增量面**:它每次仍是一次完整 `GET /sessions`,会话多了会变贵。 **影响面(我方)**:抽屉红点滞后(用户以为没人说话)。**不需要你们动客户端。** + +--- + +## 客户端→后端(2026-10-06 夜 · **「我方现在实际依赖的线形状」清单** + 两条已登记缺口 + 一条告知) + +> 我们这两天连续改动(W38~W47)。有几处**开始把语义建在你们的行为上**。按你们「形状变动先登记」的承诺,我们**把我们实际依赖的东西列清** —— 这些若不慎改动,会**静默**打坏客户端。 + +### 一、我方现在依赖的线形状(**改前请先登记**) + +1. **`clientMsgId` 幂等 —— 我们现在把重试建在它上面。** + 未连接时客户端会把消息排进队列,连接恢复后**复用同一个 `clientMsgId` 重发**。依赖三条都保持现状:`(session_id, client_msg_id)` 的唯一仲裁、WS `chat_duplicate`、REST `{duplicate:true}`。 + ⇒ **这是我们敢「无条件重发」的唯一安全基础**,它一变,我们的队列逻辑立刻不安全。 +2. **REST `stream:true` 的回执是「小 JSON」**(`200 {stream:true}` / `202 {queued:true}` / `200 {duplicate:true}` / `409 chat_busy` / `503`)。 + 我们**用「收到这个 ack」判定「已受理」**,**不等**整轮生成。 + ⚠️ **若哪天它变成内容流、或不再先回 ack**,我们的「已受理 / 未受理」判定会坏 —— 那当然是我们的问题,但**请先登记**,我们好一起改。 +3. **`turn_begin.kind` 的取值集合**(上一轮已立为契约面):我们用它判「这一路是不是并行路」(**逐字**等于 `"parallel"`)。 +4. **鉴权失败的形状**:我们对 WS 握手只认 **`code == 401`** 才算「需要重新登录」。 + 若你们把「会话已死」的信号换成别的状态码 / 别的 `code`,我们**会判不出来**(会一直重连,而不是提示「需要重新登录」)。 +5. **会话不存在时 `GET /sessions/{id}/messages` 回 `404 session_not_found`**:我们据此把那一目标为「已消失」并切回主会话,并给用户一句说明。 +6. **WS 握手 `history` 只回放主会话最近 50 条**:我们据此设计**次级会话首屏走 REST**。 + 这不是 bug、也不是抱怨 —— 是我们的既定前提。**若哪天你们改成回放「当前会话」**,请告知,我们会把这边的兜底简化掉。 + +### 二、两条已登记的缺口(不催,但让你们知道影响面) +- **工具调用记录**(今日 `b8399b5`):落库的助手消息缺工具字段 ⇒ **工具卡在回合结束后消失**。你们**已经**把工具调用落进 `flow_graphs`,缺的只是「取出来给聊天端」。 +- **未读增量**(今日 `324be57`):`message_persisted` 不带 `unreadCount` ⇒ **非激活会话的红点滞后**(我们先用客户端自愈顶着,不能替代)。 + +### 三、一条告知:客户端**已不再使用 `GET /api/v1/health`** +我们删掉了「先探 `/health` 再决定发不发」那套(W45),改成 **WS 未就绪就直接试 REST**,网络类失败才进队列。 +⇒ **`/health` 对我们不再有契约依赖**(照旧存在没问题,我们只是不调了)。若你们在做「各端在调哪些端点」的统计,这条会显示为**消失**,属预期。 + +### 四、一条纯给你们的便利(联调取证) +客户端现在有一行**路由日志**:`adb logcat -s CyreneRoute`(仅 debug 构建),一行打出 +`wsDispatched / socket / mirror / wsObject / route / reason / outcome / fromQueue`。 +以后要判断「客户端到底有没有尝试发、走的哪条路」,**直接问我们要那一行**,比从你们的入站日志反推可靠得多 —— 今天我们就因为**从对端日志反推**而误判了三次(对端看不到「没发出去的请求」)。