Initial DSHWatch DSHWatch_Server scaffold
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
# 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 的摘要;其余在手机端可看原始。
|
||||
Reference in New Issue
Block a user