docs(hwlab): 收敛 workbench session trace 规格

This commit is contained in:
Codex
2026-06-17 02:42:30 +00:00
parent 6af7fd5fa9
commit 7162586212
3 changed files with 132 additions and 0 deletions
@@ -19,6 +19,7 @@
| 短名 | HWLAB接入 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-17-r0 |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |
@@ -115,6 +116,10 @@ HWLAB接入应消费 AgentRun events、command result、terminal status、failur
HWLAB 不得用 partial assistant、stdout、transport close、idle timeout 或日志尾部推断 completed。`eventsCapped=true`、final assistant 截断或 command 未终态时,HWLAB 应继续读取 AgentRun events/trace,而不是把当前摘要当作完整归档。
HWLAB接入应把 AgentRun result 和 events 投影为 HWLAB 自己的 Turn、Message、Part 和 TraceEvent 事实。AgentRun 是 execution backendWeb Workbench 的会话事实由 HWLAB 的 session/turn/message/trace model 承担;Web、CLI 和 REST snapshot 只能重放该投影,不能分别从 runnerTrace、terminalEvidence、workspace snapshot 或 result polling 生成多套 final response。
同一次用户提交、steer 或 retry 应在 admission 时生成稳定 turnId、traceId、userMessageId 和 assistantMessageId。初发 UI 可以基于这些标识做 optimistic 展示;AgentRun events/result 到达后必须用同 ID 确认或更新对应 message/part/turn/trace,而不是创建另一条会话消息。页面刷新、session 切换、SSE 重连和 CLI inspect/result 都必须恢复同一组标识和同一语义结果。
### 6.4 AR-HWLAB-REQ-004 HWPOD Runtime Context
| 编号 | 短名 | 主责模块 | 关联模块 |
@@ -135,6 +140,8 @@ HWLAB接入应使用 AgentRun durable cancel、SessionRef、thread continuation
取消必须幂等并写入 command/run 状态与 eventpending command 被取消后不得再创建 runner Job。会话续跑只认标准 SessionRef/threadId;无法续接时必须返回明确失败事实,不能拼接历史 prompt 或伪造继续会话。
取消、Steer、retry 和 follow-up 必须绑定明确 conversation/session/turn,不得通过“最新 session”、workspace selected、runner latest 或 trace polling 推断目标。命令输入区的发送、取消和 Steer 状态应来自 TurnSnapshot 与 message projection,而不是来自浏览器本地 pending 状态。
### 6.6 AR-HWLAB-REQ-006 自然语言单一路由
| 编号 | 短名 | 主责模块 | 关联模块 |
@@ -19,6 +19,7 @@
| 短名 | Web工作台 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-17-r0 |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |
@@ -70,6 +71,9 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同
| Trace生命周期展开/折叠 | Code Agent turn 进入运行态时,Web 自动展开对应 Trace阅读视图;turn 进入终态时,Web 自动折叠该 Trace阅读视图,但仍允许用户手动重新打开。 |
| 工作态高密度 | 面向持续排障、比较和重复操作的工业化界面密度要求:低圆角、低内边距、正文优先、辅助元信息折叠,避免装饰性卡片和大块留白抢占工作内容。 |
| 正式公开入口 | 目标 node/lane 在 YAML 中声明的 Cloud Web public URL,用作用户访问、Playwright 验收、文档说明和故障复现入口。 |
| Workbench Server State | Web 工作台从 REST snapshot、SSE event、trace page 和 submit optimistic 归一化得到的服务端事实缓存。 |
| Timeline Projection | 只从 messages、parts、turn status 和 trace events 派生用户可见 timeline row 的渲染投影,不发请求也不写事实状态。 |
| 初发刷新一致性 | 同一 prompt 在初次发送、切换 session 后回到该 session、刷新页面和 SSE 重连后,都以同一 userMessageId、assistantMessageId、turnId 和 traceId 还原同一语义结果。 |
## 4. 系统边界和接口
@@ -95,6 +99,73 @@ Web工作台负责 HWLAB 登录后的浏览器主入口,使用户能够在同
| PJ2026-01040105 | 同源体验 | 本规格 6.5 | Web 与 CLI 共享 composer policy、trace renderer 和同源 REST/JSON API 行为 | HWLAB CLI、API契约、Agent编排 | Web/CLI 排障和内测复现 |
| PJ2026-01040106 | Trace阅读 | 本规格 6.6 | Code Agent trace 去噪、详情收纳、耗时、正文优先和单一主按钮状态 | Agent编排、API契约、用户管理 | 用户排障和任务继续操作 |
| PJ2026-01040107 | 公开入口 | 本规格 6.7 | 正式 Cloud Web public URL、history fallback 和旧入口降级边界 | 平台运维、API契约、用户管理 | 用户访问、Playwright 验收、内测说明 |
| PJ2026-01040108 | 状态投影 | 本规格 6.8 | server-state、reducer、selectors、timeline projection 和初发刷新一致性 | API契约、Agent编排 | Web timeline、session rail、trace detail |
| PJ2026-01040109 | 前端模块 | 本规格 6.9 | API client、event client、server-state、UI state 和组件职责拆分 | API契约、公开入口 | 可维护前端实现 |
### 5.1 目标数据流程图
```mermaid
flowchart TD
U[用户 prompt/steer/retry/cancel] --> C[Composer UI]
C --> A[POST Turn Admission]
A --> O[Optimistic user/assistant message IDs]
A --> T[TurnSnapshot]
A --> E[SSE /workbench/events]
E --> R[Workbench Reducer]
M[GET session messages] --> R
TS[GET turn snapshot] --> R
TE[GET trace events page] --> R
O --> R
R --> S[Workbench Server State]
S --> P[Timeline Projection]
S --> SR[Session Rail Projection]
S --> TD[Trace Detail Projection]
P --> UI[主 timeline]
SR --> UI
TD --> UI
```
目标数据流必须保证:提交请求只负责 admission 和稳定标识;实时事件、REST snapshot、trace pagination、页面刷新 hydrate 和 session 切换补洞全部进入同一个 reducer;晚到响应只能更新其所属 session、turn 或 trace cache,不能改变当前 active conversation。
### 5.2 目标架构图
```mermaid
flowchart LR
subgraph Browser[Cloud Web]
API[WorkbenchApiClient]
EVT[WorkbenchEventClient]
STATE[WorkbenchServerState]
RED[WorkbenchReducer]
SEL[Selectors/Projection]
UI[Session Rail / Timeline / Composer / Trace Detail]
API --> RED
EVT --> RED
RED --> STATE
STATE --> SEL
SEL --> UI
end
subgraph CloudAPI[HWLAB Cloud API]
ROUTE[REST/SSE Routes]
RM[Workbench Read Model]
PROJ[Turn/Message/Trace Projection]
ADAPT[AgentRun Adapter]
end
subgraph AgentRun[AgentRun]
RUN[run/command/runner]
EV[events/result]
end
UI --> API
EVT --> ROUTE
API --> ROUTE
ROUTE --> RM
ROUTE --> PROJ
PROJ --> RM
ADAPT --> PROJ
RUN --> EV
EV --> ADAPT
```
Cloud Web 只拥有浏览器交互和投影;Cloud API 拥有 REST/SSE 合同和 read modelAgent编排和 HWLAB接入拥有执行事实映射;公开入口只负责将 Web/API/health 投递到目标 node/lane。
## 6. 原子需求
@@ -192,6 +263,30 @@ Web工作台的正式浏览器入口必须来自目标 node/lane YAML 声明的
平台运维负责把 YAML 声明的 public URL、FRP、Caddy、TLS 和 health 投递到运行面;Web工作台负责在该入口上完成登录、工作台、导航和错误展示。实现端口可以作为诊断入口暴露给维护者,但不得出现在用户主入口、内测验收入口或客户端默认配置中。
### 6.8 CLIENT-WB-REQ-008 状态投影
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-008 | 状态投影 | PJ2026-01040108 状态投影 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |
Web工作台应把 REST snapshot、SSE event、submit optimistic、trace pagination 和 page refresh hydrate 统一归入 Workbench Server State。Server State 应按 sessionId、conversationId、messageId、partId、turnId 和 traceId 归一化保存服务端事实;UI transient state 只保存 route、显式选择、composer draft、scroll、展开状态和临时交互状态。
Timeline Projection 只能从 messages、parts、turn status 和 trace events 派生用户可见 rows。Trace detail 只消费 TraceEventPagesession rail 只消费 session list 和 turn summarycomposer 只消费当前 route/selected conversation 与明确 running turn。组件、trace polling、submit/cancel 回调不得直接写 messages、final response 或 trace authority。
初发刷新一致性是 Web 工作台的硬约束:同一 prompt 从 admission 开始生成稳定 userMessageId、assistantMessageId、turnId 和 traceId;初发 UI 可以 optimistic 展示这些 ID,但刷新、切换 session、SSE 重连和 REST 补洞必须用同 ID 的 durable message、part、turn 和 trace projection 确认。若 trace events 缺失,只影响 trace detail;主 timeline 的用户消息、assistant final response 和 turn terminal 状态不得因此退化为“思考中”。
OpenCode 的参照边界是职责结构,不是技术栈照搬。可借鉴的边界包括 route/sessionKey 作为当前 session authority、per-session message/part cache、REST message page 与 optimistic message 通过同一 messageID 合并、SSE delta 只作为实时加速、完整 message/part snapshot 可重建刷新结果。HWLAB 不得继续让 workspace snapshot、trace polling、result polling、list summary 和 localStorage 共同竞争当前消息面板。
### 6.9 CLIENT-WB-REQ-009 前端模块
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-WB-REQ-009 | 前端模块 | PJ2026-01040109 前端模块 | [PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md) |
Web 工作台实现应按职能拆分为 API client、event/SSE client、server-state store、reducer、selectors/projection、trace event projection、composer UI state、session rail UI state 和具体 UI 组件。server-state 模块不得写 UI transient stateUI 组件不得直接合并 REST/SSE 响应;projection 模块不得发请求或写状态。
新增或重构的核心前端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-010401 Web工作台 draft-2026-06-17-r0; PJ2026-010403 API契约 draft-2026-06-17-r0`,并简述文件职责。实现文件不得只写 issue 编号、`latest``current` 作为规格引用。
## 7. 过程控制
本规格不单独索引过程 issue;跨 L1 的内测、灰度和阶段活动索引统一保留在 [PJ2026-01 HWLAB 总规格](PJ2026-01-HWLAB.md) 的 `7. 过程控制`
@@ -19,6 +19,7 @@
| 短名 | API契约 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-17-r0 |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |
@@ -59,6 +60,10 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
| 业务标识 | sessionId、traceId、runId、commandId、workspaceId、caseId 等用户可继续查询的稳定标识。 |
| 错误语义 | HTTP status、错误码、blocker、failureKind、route 和下一步提示组成的可定位失败表达。 |
| Conversation detail | `GET /v1/agent/conversations/{conversationId}` 这类按稳定 conversationId 查询当前会话消息和绑定事实的 RESTful detail resource。 |
| TurnSnapshot | 按 turnId 或 traceId 查询一次用户提交/steer/retry/cancel 生命周期、终态、message 指针和执行引用的 RESTful snapshot。 |
| TraceEventPage | 按 traceId 和 cursor/seq 分页查询 trace events 的 RESTful page;只表达 trace 明细,不决定主 timeline 的 final response。 |
| Message/Part | Web 和 CLI 共同渲染会话 timeline 的持久消息事实;message 表达角色、父子关系和终态摘要,part 表达文本、工具、文件、错误、trace 摘要等可组合内容。 |
| EventStream | Cloud Web origin 下的 SSE 实时入口,用于推送 server.connected、session、turn、message、part、trace 和 workspace lifecycle 事件。 |
## 4. 系统边界和接口
@@ -83,6 +88,8 @@ API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RE
| PJ2026-01040304 | 资源接口 | 本规格 6.4 | workspace、access、provider、HWPOD node-ops、gateway 和性能摘要入口 | 全部业务 L1 | Web、CLI、admin |
| PJ2026-01040305 | 错误输出 | 本规格 6.5 | JSON 成功/失败响应、错误码、route/status、脱敏和渐进披露 | 全部业务 L1 | 用户、脚本、排障 |
目标后端模块应至少拆分为 route/handler、schema/contract、read model、persistence/projection、AgentRun adapter、trace event pager、SSE/event publisher 和 compat wrapper。route 文件只负责 HTTP 入口、鉴权桥接和错误映射;schema/contract 只负责类型和字段;read model 只组装查询模型;adapter 只转换外部执行事实;projection 只写 durable factscompat wrapper 只提供旧 path 到新资源的兼容映射,不拥有第二套业务事实。
## 6. 原子需求
### 6.1 CLIENT-API-REQ-001 同源路由
@@ -127,6 +134,29 @@ Trace resource 必须支持按事件位置继续读取,例如 `sinceSeq` / `cu
`POST /v1/agent/chat``GET /v1/agent/turns/{traceId}` 和 result 入口可以返回 `traceUrl` 指针,但该指针必须指向 RESTful trace resource。trace resource 可以为了短返回默认裁剪事件,但完整事件补齐、终态 final response、AgentRun run/command identity、错误和脱敏边界仍由同一 trace resource 表达;客户端不得要求用户手动“回放 Trace”才能获得完成态 trace。
目标 Workbench RESTful API 资源设计如下。旧 `/v1/agent/*` 路径可以作为兼容 wrapper 暂存,但 Web 主路径应逐步收敛到这些资源语义。
| 资源 | Method / path | 请求字段 | 响应主体 | 状态码 | 权威边界 |
| --- | --- | --- | --- | --- | --- |
| WorkspaceSelection | `GET /v1/workbench/workspace` | `projectId`, `workspaceId` 可选 | selected ids、workspace revision、composer 配置、public origin 摘要 | 200/401/403 | 只读 selection/config,不返回或修补 message 事实 |
| WorkspaceSelection | `PATCH /v1/workbench/workspace` | 显式 selected project/workspace/conversation ids | 更新后的 selection/config | 200/400/401/403 | 只有显式 mutation 可改变 selection |
| Session list | `GET /v1/workbench/sessions` | `projectId`, `workspaceId`, `cursor`, `limit`, `includeSessionId` | session/conversation rail 摘要 page | 200/401/403 | 列表和排序,不替代 detail |
| Session detail | `GET /v1/workbench/sessions/{sessionId}` | path sessionId | session metadata、当前 conversation 指针 | 200/401/403/404 | session metadata,不拥有 trace events |
| Message page | `GET /v1/workbench/sessions/{sessionId}/messages` | `cursor`, `limit`, `before/after` | message + parts page、next cursor | 200/401/403/404 | 会话 timeline 的 message/part 事实 |
| Conversation detail | `GET /v1/agent/conversations/{conversationId}` | path conversationId | conversation metadata、message page seed、sessionId、threadId、lastTraceId、turn summary | 200/401/403/404 | 当前消息面板权威 detail |
| Turn admission | `POST /v1/workbench/sessions/{sessionId}/turns` | prompt/parts、delivery、workspace/project、client message ids | `202 Accepted` + turnId、traceId、userMessageId、assistantMessageId、status URLs | 202/400/401/403/409/422 | 只表示输入已接收,不表示执行完成 |
| Turn snapshot | `GET /v1/workbench/turns/{turnId}` | path turnId | status、terminal、message ids、traceId、AgentRun refs、failureKind | 200/401/403/404 | turn 状态补洞,不承载 trace events |
| Trace event page | `GET /v1/workbench/traces/{traceId}/events` | `afterSeq/cursor`, `limit` | ordered events、range、hasMore、next cursor | 200/401/403/404/410 | trace 明细分页,不决定主 timeline final response |
| EventStream | `GET /v1/workbench/events` | `projectId`, `workspaceId`, optional session/turn filters | SSE events + heartbeat | 200/401/403 | 实时加速和通知,不替代 REST snapshot |
| Cancel turn | `POST /v1/workbench/turns/{turnId}/cancel` | reason 可选 | updated TurnSnapshot | 200/202/401/403/404/409 | 精确取消目标 turn |
| Steer turn | `POST /v1/workbench/turns/{turnId}/steer` | text/parts、delivery | accepted steer TurnSnapshot 或 continuation id | 202/400/401/403/404/409 | 绑定明确 running turn |
| ProviderProfile | `GET /v1/workbench/provider-profiles` | project/workspace 可选 | profile summary list | 200/401/403 | 配置摘要,不输出 Secret |
| Diagnostic resource | `GET /v1/workbench/diagnostics/{resource}` | resource id/query | redacted health/status summary | 200/401/403/404 | 诊断可见性,不改变业务事实 |
所有 GET path 必须无业务副作用。需要 repair、finalize、sync 或 migration 时,应由后台 finalizer、显式 mutation 或持久化投影入口执行,不能隐藏在 workspace、conversation、turn 或 trace GET 中。所有分页响应必须包含稳定 cursor 或 seq 边界;所有错误响应必须包含 route、status、code/blocker、redacted actor、target resource 和下一步建议。
新增或重构的核心后端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 `SPEC: PJ2026-010403 API契约 draft-2026-06-17-r0; PJ2026-010205 HWLAB接入 draft-2026-06-17-r0`,并简述文件职责。实现文件不得只写 issue 编号、`latest``current` 作为规格引用。
### 6.4 CLIENT-API-REQ-004 资源与管理接口
| 编号 | 短名 | 主责模块 | 关联模块 |