# DSHWatch 通信协议细化(v0.1) > 本文件是 docs/DESIGN.md §4 的细化,定义三段链路的字段级协议,便于后续按此写代码。仍属"对齐粒度"文档。 --- ## 0. 概述 三跳: 1. 手表(DSHWatch) <-> 手机(DSHWatchPhone):BLE / @system.interconnect / Wearable MessageApi。 2. 手机 <-> 服务器(DSHWatch_Server):WebSocket。 3. 服务器 <-> DSH 插件(dsh-watch-bridge):WebSocket。 手机在 1 和 2 之间做双向网关翻译。手表看到的永远是"整理过的短文本",不直接透传原始大 JSON。 --- ## 1. 手表 <-> 手机(BLE / interconnect) ### 1.1 物理通道 - 手表:@system.interconnect 的 connect.send({ data: obj })。 - 手机:小米穿戴 SDK MessageApi.sendMessage(nodeId, byte[])。 - 大数据(文本 > 约 1KB):按 base64 分片。官方 demo 用 header/data/end 三段;本项目沿用: 开始帧:{ "type":"header", "totalChunks": N, "id":"..." } 数据帧:{ "type":"data", "id":"...", "index": i, "chunk":"base64..." } 结束帧:{ "type":"end", "id":"..." } ### 1.2 消息信封 { "to": "phone" | "watch", "type": "hello" | "status" | "event" | "command" | "text" | "cancel" | "settings" | "ack" | "heartbeat", "seq": 123, "ts": 1760000000000, "payload": { ... } } ### 1.3 type 与 payload - hello:{ "role":"watch|phone", "version":"0.1" } - status:{ "online":bool, "harnessOnline":bool, "running":bool, "sessionId":"...", "sessionTitle":"...", "model":"...", "server":"..." } - event:{ "kind":"session/event|session/projection", "sessionId":"...", "summary":"...", "seq":123 } - command:{ "kind":"prompt|quick|select_session", "sessionId":"...", "content":"...", "quick":"..." } - text:{ "sessionId":"...", "text":"..." } - cancel:{ "sessionId":"..." } - settings:{ "serverUrl":"...", "userId":"...", "token":"..." } - ack:{ "ok":bool, "error":{ "code":"...", "message":"..." } } - heartbeat:{} ### 1.4 顺序与可靠性 - seq 手表端单调递增。 - 手机端收到后原样回 ack(ok)。 - 分片用 id 关联;缺失分片则丢弃该条并 ack 失败。 --- ## 2. 手机 <-> 服务器(WebSocket) 连接地址:ws(s)://host:port/ws(或 /)。 ### 2.1 握手 手机发送: { "type":"hello", "role":"client", "userId":"...", "token":"..." } 服务器回: { "type":"hello", "role":"client", "online":true, "harness":true, "status":{...} } ### 2.2 请求/响应 手机 -> 服务器: { "type":"request", "requestId":"uuid", "method":"session.prompt", "timeoutMs":30000, "params":{...} } 服务器 -> 手机(转发给 Harness 后回): { "type":"response", "requestId":"uuid", "ok":true, "result":{...} } { "type":"response", "requestId":"uuid", "ok":false, "error":{ "code":"...", "message":"..." } } ### 2.3 推送(服务器 -> 手机) { "type":"harness", "online":true } { "type":"status", "status":{...} } { "type":"event", "event":{ "type":"session/event", "sessionId":"...", "event":{...} } } { "type":"notice", "code":"...", "message":"..." } ### 2.4 method 白名单(插件透传) - harness.status / harness.prompt - session.list/create/history/prompt/cancel/rename/fork/models/selectModel/attachment - goal.create/edit/pause/resume/complete/clear - subagent.list/history/prompt/interrupt - workspace.list/create/rename/delete/insertBefore/insertSessionBefore/archiveSession - host.describe/pickDirectory/listDirectory/createDirectory/openPath - skill.list - agentPreset.list/select/read/copy/openDocument/remove - llm.providers/models/discoverModels - settings.describe/openDocument/update/replace/mutate - credentials.describe/set/unset --- ## 3. 服务器 <-> DSH 插件(WebSocket) ### 3.1 握手 插件 -> 服务器: { "type":"hello", "role":"dsh", "userId":"...", "token":"..." } 服务器回: { "type":"hello", "role":"dsh", "online":true, "status":{ "userId":"..." } } ### 3.2 转发 服务器 -> 插件(来自手机): { "type":"request", "requestId":"uuid", "method":"...", "params":{...} } 插件 -> 服务器: { "type":"response", "requestId":"uuid", "ok":true, "result":{...} } { "type":"response", "requestId":"uuid", "ok":false, "error":{...} } ### 3.3 推送 插件 -> 服务器: { "type":"status", "status":{...} } { "type":"event", "event":{...} } { "type":"ping" } # 心跳 ### 3.4 状态快照形态 { "online": true, "ts": 1760000000000, "version": "0.0.1", "cwd": "D:/...", "provider": "deepseek", "model": "deepseek-chat", "attachedSessions": 2, "activeSessionId": "session-xxx", "running": false, "sessions": [ { "sessionId":"...", "updatedAt":123, "running":false, "blank":false, "agentPreset":"..." } ] } --- ## 4. 错误码约定 auth-error / missing-userId / bad-request / harness-offline / harness-timeout / invoke-error / duplicate-requestId / invalid-JSON / unknown-path --- ## 5. 备注 - 服务器不落盘,纯内存转发。 - token 建议走 wss,且在服务端用环境变量或本地 config.json,不入 git。 - 客户端重连:指数退避(1s,2s,4s,8s,上限 30s)。 - 事件流可能很大,手表端只渲染 kind=session/event 且是 text 的摘要;其余在手机端可看原始。