Files

168 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DSHWatch 通信协议细化(v0.1)
> 本文件是 docs/DESIGN.md §4 的细化,定义三段链路的字段级协议,便于后续按此写代码。仍属"对齐粒度"文档。
---
## 0. 概述
三跳:
1. 手表(DSHWatch) <-> 手机(DSHWatchPhone):BLE / @system.interconnect / Wearable MessageApi。
2. 手机 <-> 服务器(DSHWatch_Server):WebSocket。
3. 服务器 <-> DSH 插件(dsh-watch):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 的摘要;其余在手机端可看原始。