13 KiB
v0.2 hwlab-cloud-web 服务规格
hwlab-cloud-web 是 v0.2 浏览器工作台,运行在 hwlab-v02 namespace,内部端口 8080,公网经 FRP 暴露为 http://74.48.78.17:19666/。
在系统中的职责划分
- 向用户提供 Cloud Workbench、Code Agent 对话、live status、device-pod 右侧面板、trace 展示和帮助内容。
- 只消费
hwlab-cloud-api,不直接访问 Postgres、gateway、device-pod Service、FRP、Kubernetes 或 provider Secret。 - 为浏览器提供同源代理,避免前端直接跨域调用内部 ClusterIP。
- Cloud Web 与
hwlab-cli client必须共享同一组非视觉业务 API。浏览器遇到的 Code Agent continuation、trace/result、device-pod list/status 和 device-pod job 问题,必须能通过hwlab-cli client走同一19666Cloud Web path 复现;不能让 CLI 长期绕到19667Cloud API 后把 Web 路径缺口误判为业务已通过。 - Cloud Web 只承担浏览器 UI 和
hwlab-cli client的同源代理。AgentRun runner 内的hwpod不走 Cloud Web;Cloud Web 不转发 AgentRun Device Pod API key,也不保留 device-pod lease 路由。 - 浏览器启动后必须从
GET /v1/workbench/workspacehydrate 账号 workspace;同一个账号在多个浏览器标签页、多个浏览器或 CLI profile 中应看到同一个workspaceId、selected conversation/session/thread、provider profile 和 active trace。浏览器 localStorage 只能作为短期缓存,并必须绑定 actor,不能作为 workspace authority。 - Cloud Web trace 展示与
hwlab-cli client agent trace --render web必须共享同一套 trace row 纯转换路径。Web 发生 row 顺序错乱、final response 缺失、assistant 消息被吞、tool call 只显示泛化占位或噪声事件淹没时,先用 CLI 输出同一渲染 row 摘要和 noise event count 复现;CLI 可复现说明是 trace row 转换问题,CLI 不可复现再进入 DOM/CSS/滚动状态调查。默认展示应压制 AgentRun backend echo、token/rate-limit/status/terminal echo 等低价值事件,但原始 trace JSON 仍必须保留用于--full/下载排障。 - Cloud Web Code Agent composer 必须无锁:运行中 turn 不得把输入框或发送按钮 disabled。浏览器提交时必须按共享 composer policy 自动分流,空闲/终态走
POST /v1/agent/chat开新 turn,存在 active running trace 时走POST /v1/agent/chat/steer引导当前 turn。hwlab-cli client agent composer status必须能用同一 policy 输出locked=false、disabled=false、submitMode=turn|steer、route和targetTraceId,用于复现 Web 输入框是否被旧逻辑锁住。 - Code Agent result
completed只有在同时包含真实 provider/model/trace/conversation 元数据、providerTrace和可展示的 final assistant response 时,才能被 Web 标记为真实完成;provider=agentrun-v01只是执行基础设施标识,不得替代上游 provider/model,也不得把 SOURCE、fixture、echo、mock 或 stub 当成 DEV-LIVE 完成。 - 同一 conversation/session 的后续用户消息必须在 AgentRun runner reuse window 有效时复用已存在的 AgentRun run/runner 继续新 command/turn;只有 runner 不可用、已过期或协议明确要求新 runner 时才重新 bundle 和启动 runner。每条消息都重新 bundle/runner 属于 v0.2 AgentRun 接入缺口,不能只靠 trace 显示原因当成已完成。
- AgentRun 会话连续性只有一个标准路径:Cloud Web/CLI 提交的
threadId必须经 Cloud API adapter 写入 AgentRun commandpayload.threadId和SessionRef.threadId。前端、CLI、API 和 AgentRun 的协议字段、trace、result 和 conversation facts 都以该字段为唯一 thread identity。 - Cloud Web 提交 Code Agent turn 时只发送当前用户消息、共享 workspace 的
conversationId/sessionId/threadId、workspace revision 和必要运行元数据;不得发送conversationContext/messages,也不得把浏览器历史拼入 prompt。历史消息只用于本地 UI 展示和 trace/inspect 可见性,不能替代 AgentRun/Codex stdio 原生thread/resume。 - 同一 AgentRun run 复用多条 command 时,Web trace 展示只显示当前 command 归属事件和必要 run 级状态;旧 command 的 assistant/tool/terminal 尾部不能堆到新 command 末尾。取消轮次的可读进展必须作为脱敏 conversation facts 进入 UI/trace/inspect 证据,而不是靠旧 trace 尾部串线让后续轮次“碰巧看到”;这些 facts 不得作为下一轮模型上下文或 prompt 拼接来源。
内部架构
web/hwlab-cloud-web/app.ts是浏览器端主入口,和app-device-pod.ts、app-conversation.ts、app-trace.ts、app-helpers.ts共同组成实际 bundle 输入集合,组织 Workbench 状态、Code Agent 会话缓存、trace 轮询和 device-pod 面板。internal/dev-entrypoint/http.mjs提供静态服务、health 和 HTTP proxy 基础能力。internal/dev-entrypoint/cloud-web-routes.mjs定义可代理到 cloud-api 的同源 API route 和认证边界。web/hwlab-cloud-web/auth.ts管理工作台登录态;真正的用户权限 authority 仍应收敛到 cloud-api。
API 接口说明
| 接口 | 说明 |
|---|---|
GET / |
Cloud Workbench 首屏。 |
GET /health、GET /health/live |
返回 cloud-web 自身 health 和 build metadata。 |
GET /help |
返回可用 route 摘要。 |
GET /v1、GET /v1/... |
同源代理到 hwlab-cloud-api;公开的 Code Agent result/trace 轮询按 route policy 处理。 |
GET/PATCH /v1/workbench/workspace... |
同源代理到 cloud-api 的账号 workspace authority,用于 Web/CLI 共享工作区和 revision 冲突保护。 |
POST /v1/agent/chat、POST /v1/agent/chat/steer、POST /v1/agent/chat/cancel |
同源代理到 cloud-api 的 Code Agent 入口;steer 必须走同一个 19666 Web path,由 cloud-api/AgentRun 判断目标 turn 是否可接收。 |
POST /v1/device-pods/... |
受控同源代理到 cloud-api 的 Device Pod job/操作入口;只要 Cloud API 已提供对应能力,Cloud Web 不能只代理 list/status 而让 job POST 在 19666 返回 404。 |
POST /v1/m3/io、POST /json-rpc |
同源代理到受控 API;不能绕过 cloud-api 直连硬件服务。 |
测试规格
Cloud Web 的默认校验入口是 bun run --cwd web/hwlab-cloud-web check。该入口必须在 v0.2 CI 的 hwlab-cloud-web 镜像发布前执行,且保持秒级或低十秒级,不引入浏览器、Playwright、公网或真实 provider 依赖。
Cloud Web check 必须先对实际 bundle 输入集合运行 TypeScript 语义检查。语法检查和 Bun build 只能证明源码可解析或可打包,不能稳定发现未绑定标识符;isRequestTraceEvent is not defined 这类错误必须由 semantic check 在发布前拦截。实现上可以生成与 dist build 相同顺序的临时 app entry,再执行 tsc --noEmit 或等价 TS checker;只跑 node --check、bun build 或源码字符串断言不满足本规格。
Cloud Web 单元测试必须自动发现并执行 repo-owned web/hwlab-cloud-web/**/*.test.ts,不允许只维护硬编码文件清单。app-trace 的 trace row/render helper 必须有纯逻辑单测,直接构造 request、setup、commandExecution、assistant markdown 和 completion events,证明 trace 展示路径不会因为漏定义 helper、事件分类漂移或 markdown body 渲染变更而在浏览器运行期崩溃。
Cloud Web check 通过后仍需执行 bundle build 和 dist freshness 校验,确保实际发布的 dist/app.js 来自同一组 TypeScript 输入。默认 check 不恢复旧 quick prompt、旧 layout smoke、旧 M3 evidence、旧 DEV/D601 browser gate 或 Playwright;这些只能作为显式专项诊断,不得进入默认 CI/CD 关键路径。
T1
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:访问 http://74.48.78.17:19666/ 和 /health/live,确认页面和 health 均来自 v02 cloud-web,而不是 DEV/PROD 端口。
T2
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:从同源 19666 提交 Code Agent 短连接请求并轮询 result,确认请求经 cloud-web proxy 到 hwlab-cloud-api,且 trace 可回放。
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:对运行中 Code Agent trace 调用 hwlab-cli client agent steer <traceId> --message ...,确认请求走 Cloud Web 同源 POST /v1/agent/chat/steer;Web 层不能返回 serviceId=hwlab-cloud-web 的 404,目标不存在、非运行中或 runner 拒绝时必须透传 cloud-api/AgentRun 的结构化业务状态。
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:先启动一个真实运行中的 Code Agent turn,再运行 hwlab-cli client agent composer status,确认输出 composer.locked=false、composer.disabled=false、composer.submitMode=steer、composer.route=/v1/agent/chat/steer 和当前 targetTraceId;随后运行 hwlab-cli client agent composer submit --message ...,确认 CLI 按 Web composer policy 自动走 steer,而不是手动指定 steer URL 或新开 turn。
T2.1
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:对浏览器暴露的 Code Agent trace 运行 hwlab-cli client agent trace <traceId> --render web --limit 80,确认 CLI 与 Web 使用同一 trace row 转换;若 final response 缺失、assistant row 顺序错乱或噪声事件过多,先用 CLI 固定复现再修实现。
T2.2
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:在同一 conversation/session 连续发送两条 Code Agent 消息,确认第二条复用第一条的 AgentRun runId 和 runner jobName、生成新的 commandId,且不重新 materialize bundle/启动新 runner;result completed 必须包含真实 provider/model/providerTrace/trace/conversation 和 final assistant response。复用失败原因只能作为诊断,不作为本测试通过条件。
T2.3
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:对一轮已取消但取消前存在 assistant/tool 进展的 trace 发送同一 conversation/session/thread 后续问题,确认请求和 result 只携带标准 threadId,不出现历史 thread 别名字段;--render web 输出不得把上一 command 的尾部 assistant/tool/terminal row 堆到新 command 末尾。
T3
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:打开 Workbench device-pod 面板,确认 status/freshness/blocker 显示来自 /v1/device-pods,未登录或未授权时必须显示认证/授权 blocker,不得把 fixture 或 blocked fallback 写成真实硬件 DEV-LIVE。
T3.1
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:通过 19666 Cloud Web 同源 path 对当前允许的 device-pod job/操作 POST 做只读或 dry-run 级验证,确认与 19667 Cloud API 的 route policy 对齐;如果 Cloud API 返回业务级 4xx,Cloud Web 也应透传业务错误,不应在 Web 层直接 404。
T4
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:运行 bun run --cwd web/hwlab-cloud-web check,确认输出或日志显示已执行 Cloud Web TypeScript 语义检查、自动发现的单元测试、bundle build 和 dist freshness 校验;不得用只跑 bun build 或浏览器手工刷新替代该检查。
T5
阅读 docs/reference/spec-v02-hwlab-cloud-web.md,然后用 cli 手动测试以下内容:确认 trace 渲染相关单测覆盖 request、setup、commandExecution、assistant markdown 和 completion row;该测试必须能在无浏览器、无 Playwright、无公网、无真实 provider 的环境中执行。
规格的实现情况
| 规格项 | 状态 | 说明 |
|---|---|---|
| Workbench 首屏 | 已实现 | 当前页面直接进入工作台,不是 landing page。 |
| cloud-api 同源代理 | 已实现 | 受 route policy 控制;device-pod job POST 必须与 Cloud API route policy 对齐。 |
| Code Agent UI/trace/result | 已实现 | 支持 provider profile、timeout、trace 轮询和取消。 |
| Code Agent 无锁 composer | 已实现 | Web/CLI 共享 composer policy;运行中输入框保持可编辑并自动走 steer。 |
| 账号 workspace hydrate/sync | 已实现 | 启动读取 account_workspaces,Code Agent 请求携带 workspace revision,终态再同步 workspace。 |
| device-pod 面板 | 未完全实现 | 当前主要消费 fake/只读 device-pod payload。 |
| 完整多用户 admin/user UI | 未完全实现 | 登录态存在,权限 authority 仍需按 spec-user-access 收敛到 cloud-api。 |