Files
DevFlow/docs/02-架构设计/专项设计/uclaw两侧勘察补全-2026-10-04.md
T
lxy b994cf2c54 文档: 设计定稿与评估纪律登记
- 无人值守长任务设计定稿,含效率与可观测补遗
- u-relay wire 协议规格与五项评估结论
- 新能力引入评估纪律五项清单
- todo 销账与狗粮短板分析登记
2026-10-04 16:27:32 +08:00

8.0 KiB
Raw Blame History

u-claw 两侧细勘察补全(多轮会话锚定 + 协议漂移)

2026-10-04 · 上游:devflow集成u-claw-可行性研究-2026-09-28.md 第六节待补槽位「u-claw 侧收尾:WS 渠道的多轮会话锚定细节(request_id↔chain 映射、会话持久化边界)」。 勘察基线:u-claw HEAD 021a230(基线 d8dc003 后 18 提交)/ u-relay 现行源码 / u-ppt 参考实现未变。 全部结论以源码为准(wsch.go 405 行全文 + chainpool.go + agentd.go + u-relay src)。

一、多轮会话锚定:channel 级单 chain 模型(结论定案)

WS 渠道不是 per-request 会话,是 channel 级单 chain 粘性会话:

wsChannel (1:1)
  └─ chain = NewSessionChain("ws", cwd, statePath, ...)   // wsch.go:113 run() 启动时建一次
       ├─ TakeSummary()  每轮取摘要 → RenderWithSummary 注入下轮 prompt   // process():224
       ├─ HandleWithResult(prompt, progressWatcher)        // 常驻 claude -p 子进程
       └─ 会话自动连续(各轮 session_id 相同,无需 --resume)  // agentd.go:6 注释
  • request_id 仅是单次指令标识(配对进度/结果帧),不映射 chain——所有 request_id 共享同一 chain 与同一 claude 进程
  • 上下文维持:常驻进程各轮 session_id 相同(agentd.go:6),链层另有摘要注入(TakeSummary→RenderWithSummary)双保险;崩溃/超时后 ensureAlive 自动重启并 --resume 上次会话 ID 恢复(agentd.go:154)
  • 持久化边界:会话状态文件 sessionStatePath("ws")(exports.go:96,落 ~/.u-claw/sessions/);会话 jsonl 落 claude 自己的项目目录(cwd 对应);跨进程重启后上下文不丢(--resume + 会话文件保留)
  • devflow 侧含义:接入后 devflow 与 u-claw 的对话天然是一条连续会话(同一 channel_id 下所有 ask_uclaw 调用共享上下文)——多轮追问无需传会话 ID,但也意味着 devflow 内不同 devflow 会话若共用 channel_id 会互相污染上下文(见 §4 设计含义 D-2)

二、协议漂移:可行性文档已过时(重要修正)

2026-09-28 可行性文档记载 /ws/device + {kind,device_id,token} hello——已漂移,e8113c5「中继握手协议对齐服务端」重定义了角色:

维度 可行性文档(9-28 记载) 现行源码(10-04 实证)
端点 /ws/device / /ws/miniapp /ws/agent(执行端,u-claw 连此) / /ws/commander(控制端,devflow 连此)
hello {kind, device_id, token} {kind:"commander", channel_id, token}(commander);agent 端 {kind:"agent", channel_id, token}
帧路由 Event→Miniapp / Command→Device Event(执行端发)→同 channel_id 全部 Commander;Command(控制端发)→同 channel_id 绑定的 Agent(conn.rs:114, relay.rs:117-119)
心跳 ping/pong(relay 本地回) 同款仍在:30s ping / 90s 读死线 / 写死线 10s(wsch.go:45-50;miniapp 侧同款)
鉴权 全局共享 token(鉴权债) 配对语义已改:Commander 持 token 申请绑定 channel_id(broadcast.rs:138 Pair{channel_id, token}),Agent 端 token 校验;但 relay 侧仍是 env U_RELAY_TOKEN 单 token(relay.rs:9-10, main.rs:28 fail-fast),per-channel token 未做——鉴权债部分缩小

接入实施时必须按本节现行协议实现,不能照抄 9-28 文档或 u-ppt relay.ts 原样(u-ppt 用的还是旧 Miniapp/Device 语义,需确认 u-ppt 是否已随 e8113c5 升级,若未升级则 u-ppt relay.ts 仅作 TS 结构参考、协议字段按本节改)。

三、执行语义与时限(新增已核实事实)

  • 串行 worker:每 channel 一条串行 worker goroutine,reqCh 缓冲 4,满则丢弃由发起方重试(wsch.go:108-109)——devflow 侧需配超时重试与队列已满可感知的语义(当前协议无「已丢弃」回执,devflow 端只能在超时后重发)
  • 单条指令硬超时 15min(wsExecTimeout,wsch.go:38):超时 AbortRunning 杀进程、回「处理超时」结果、链保 session ID 下条 --resume 续跑——devflow aichat 工具的 client 侧超时须 >15min 或对齐处理
  • 进度节流 2s(progressWatcher,wsch.go:368):assistant text=阶段叙述+tool_use=当前动作,2s 节流回传——devflow 工具卡「流式」粒度即此(块级,非逐 token)
  • 空闲超时链回收:chainPool idle 后整链回收(杀 claude 进程 ~500MB),来消息 --resume 重建冷启动 ~7s(chainpool.go:1-7)——devflow 侧期望「空闲后首次调用慢」为正常
  • 链池挤占语义:槽满 LRU 挤最旧 idle 链,活跃链不挤;hardCap 全忙时拒绝建链返错(chainpool.go:100-128)

四、devflow 侧接入设计含义(增量到第五节)

  • D-1 工具卡流式:ask_uclaw 工具卡可直接消费 agent_progress 帧(2s 块级)作流式显示,agent_result 全文为最终 tool result——零改造对齐 devflow 现有工具卡模式
  • D-2 channel_id 策略:单 chain 会话模型下,建议 devflow per-conv 生成 channel_id(如 devflow-{conv_id})接入——每个 devflow 会话映射独立 u-claw chain,会话隔离天然成立;代价是 u-claw 侧 chainPool 槽位占用(max 上限与 LRU 挤占,见 chainpool.go),需确认 u-claw 侧 max 配置余量(当前 max 值未在本次勘察范围,实施前核 ~/.u-claw/u-claw.yml)
  • D-3 超时对齐:devflow ask_uclaw 客户端超时建议 16min(>15min 硬上限),超时即回失败;进度 2s 节流下客户端 watchdog 应容忍 30s+ 无 progress(u-claw 长任务中间可能无 assistant 输出)
  • D-4 队列满丢弃无回执:reqCh 满时静默丢——devflow 侧在 15/16min 超时后重发(最多 2 次),并把「u-claw 渠道忙」文案明确给用户
  • D-5 offline 语义:relay 无离线缓存(9-28 已载),叠加本节串行+丢弃语义:devflow 发送前可先发探活 ping(30s 内无 pong 视为渠道不可达),不可达直接报「u-claw 离线」不进队列

五、接入实施批清单(更新版,覆盖 9-28 第五节)

  1. 协议实现(Rust 客户端):连 /ws/commander,hello {kind:"commander", channel_id: devflow-{conv_id}, token},按本节协议处理 Event 帧(agent_progress/agent_result 按 request_id 配对)——不照抄 u-ppt relay.ts 字段,仅参考结构
  2. 工具注册:ask_uclaw(prompt) → declare_tool!(Low/只读? 不,执行类 Medium),progress 帧接 ToolCard 流式,result 全文为 tool result
  3. 配置页:relay URL / channel 前缀 / token(keyring)——默认关
  4. 超时与重试:客户端 16min 超时 + 2 次重试 + 发送前探活 ping
  5. 可选 phase2:消息渠道形态(u-claw 代言 aichat)/ 反向 MCP——维持 9-28 形态 2/3 描述
  6. u-ppt 核对(实施前置小步) ✅2026-10-04 已核:u-ppt relay.ts 65bae53(2026-10-01)已随 e8113c5 升级 commander/channel_id 协议——端点自动补全 /ws/commander(:39)/hello {kind:'commander',channel_id,token}(:135)/10s 握手看门狗+hello_ack(:127)/30s ping+15s pong(:33)/指数退避 1s→30s(:36)/agent_request|progress|result 按 request_id 分发(:158) 六项与 u-relay 现行源码一致。relay.ts 可直接作参考实现(去 deck/SEP 专有逻辑),devflow 接入是 commander 协议第二个实现,非首个

六、基线更新

基线 HEAD(2026-10-04):
  devflow 9216d4c   u-relay e8113c5后现行(见 src)   u-claw 021a230   u-ppt 待核
漂移检查(下次):u-claw git log --oneline 021a230..HEAD;u-relay per-channel token 是否落地

关联

  • 上游:devflow集成u-claw-可行性研究-2026-09-28.md(本文件填其第六节末槽位)
  • u-claw 源:wsch.go(WS 渠道全文 405 行)/ internal/core/chainpool.go(链池)/ internal/core/agentd.go(常驻 claude + --resume)
  • u-relay 源:src/relay.rs(端点+握手)/ src/conn.rs(配对路由)/ src/broadcast.rs(Pair 协议)