8.5 KiB
HWLAB Cloud Workbench Reference(历史路径)
本文不再承载 Cloud Workbench 需求规格正文。
统一规格出处是 UniDesk OA:
历史 layout smoke、浏览器排障和实现细节只作为运行参考,不定义需求边界。需要修改 Web 工作台、同源 CLI、trace/result 或公开入口口径时,只更新 UniDesk OA。
Workbench 运行参考
Workbench 页面和组件必须明确区分“未加载完成”和“已加载但为空”。未加载完成时不得渲染由 workspace、localStorage、默认对象或 stub 记录拼出来的伪数据;这类数据只能作为内部恢复线索,不能在列表、表格、卡片或状态栏中冒充真实加载结果。已经确认后端返回且集合为空时,才显示空态文案。
Workbench 状态对象必须服从 UniDesk OA Web SPEC 中已经定下来的单一权威 API 绑定。Session rail 的会话集合只允许消费 /v1/agent/conversations 成功返回的 conversation 集合;当前 selected conversation 如果需要出现在左侧列表中,必须通过显式 query/path/body 传入稳定 conversation id,由该列表 API 在同一响应中返回,后端不得隐藏读取 workspace selected、localStorage、Web snapshot 或上一轮页面状态。前端不得用 workspace selected snapshot、stub、localStorage 或 route 状态补出 session tab,也不得把前端拼接出的 status、final response、markdown、running 动效或 stub 传回后端变成事实。Session 运行状态必须按 sessionId 绑定到单一 session 状态 API;Code Agent turn、trace 阅读和 final response 必须按 traceId 绑定到单一 trace/result snapshot API。任何权威 API 失败时只能保留上一份成功结果或显示未加载/错误态,不得切换到另一条 fallback 路径形成一条会话、旧 running 态或劣化 markdown。
Workbench 投影写路径必须做到 0 隐式 fallback。Admission、projection event、terminal/finalizer 等上游写入如果无法把 session/message/turn/checkpoint facts 写入 durable read model,不能 catch 后返回空值继续表现为成功;admission 阶段必须显式失败并把错误传给调用方,后台投影阶段必须至少写入 trace diagnostic 和 OTel error span。只有成功落库的 Workbench facts 才能驱动控制页、观察页、session rail、耗时和 final response;前端或 read path 不得用内存 trace、local optimistic state、历史 snapshot 或多来源仲裁去修补失败写入。
MDTODO 发起 Workbench 执行时,HWPOD 执行上下文的唯一权威来源是 Project Management source registry。Workbench Launch 服务端必须通过 taskRef -> sourceId/fileRef -> source 解析 launchContext.executionContext,并把同一份 contextFingerprint 写入 session owner、Workbench facts、project-management link 和 OTel span;浏览器传入的 HWPOD 字段只能作为任务元数据,不能作为权威执行上下文。sourceKind=hwpod-workspace 但缺少 hwpodId、nodeId 或 workspaceRootRef 时,launch 必须显式失败,不能创建“看似成功但无法执行”的空 session。
MDTODO 首轮 Code Agent prompt 必须包含 hwpodId、mdtodoRootRef 和 hwpodWorkspaceArgs,并要求所有 hwpod/hwpod-ctl 命令携带该参数。Agent 不得猜测容器本地路径,不得创建、复制或修补本地 .hwlab/hwpod-spec.yaml fallback。Workbench session header 可以显示 source、HWPOD 和 MDTODO root 的只读短标识;workspace host path 的长期可观测性默认使用 basename/label、hash 或 redacted 形态。
Cloud Web 的通用加载态使用 web/hwlab-cloud-web/src/components/common/LoadingState.vue。新增或修复页面加载态时优先复用该组件,并通过明确的 ready/loading 状态控制展示;不要在每个组件里重新实现一套 spinner、点状动画或默认占位数据。紧凑区域可以使用组件的 compact 形态,文案默认保持“加载中”。
Session rail 是该规则的高频区域。/v1/agent/conversations 还未返回时,即使 workspace 中已有 selectedConversationId、sessionId、traceId 或 selected conversation snapshot,也不能把选中 session stub 渲染成单条 .session-tab,更不能让它占满整个 session 列表高度。加载窗口应只显示 LoadingState,并隐藏当前 trace 元信息、复制/删除等依赖真实 active tab 的动作;待 conversations ready 后再渲染真实 session tabs,或在真实空集合时显示空态。
Workbench 只能维护一条会话恢复与提交路径。首次打开、新建后继续、从左侧 session rail 切换、直接进入 /workbench/sessions/<conversationId> 恢复时,都必须以当前 route/active conversation id 作为会话真相,并通过同一条 conversation detail hydration 路径得到 messages、turn state、trace/status 和 markdown 渲染输入;不得另写只消费列表 snapshot、workspace stub 或 localStorage selected id 的恢复分支。
Workbench 的 URL 反射必须服从用户当前导航和组件生命周期。activeConversationId、hydrate、select conversation 或列表刷新等异步状态只能在当前 route 仍属于 Workbench section、路径仍是 /workbench//workspace 系列且 Workbench 组件仍 active 时,才允许把 URL 反射到 /workbench/sessions/<conversationId>;用户已经点击 Dashboard、API Keys、Admin、Settings 或其他非 Workbench 导航后,晚到的 Workbench 响应只能更新 store,不得再调用 router.replace/router.push 把全局 route 拉回 Workbench。新增 session 恢复或 URL 反射入口时必须复用共享路由守卫,例如 web/hwlab-cloud-web/src/router/workbench-navigation.ts,不要在业务组件里各自手写跳转判断。
Workspace 中的 selectedConversationId、selectedAgentSessionId 和 selected snapshot 只能作为恢复线索。只有它们的 conversation id 与当前 active conversation id 完全一致,且已经拿到真实 detail 或真实 messages snapshot 时,才允许驱动 composer、message list、final response markdown 和 trace 入口。conversation id 不一致、detail 仍在加载、或 snapshot 只有 trace/session stub 时,不得覆盖当前消息、pending user message、pending agent message、final response markdown 或右上角运行详情入口。
提交消息必须形成新的 selection epoch。submitMessage() 开始后,前端应先把 workspace selection 对齐到当前 route/active conversation,再插入本轮 pending user message 和 pending agent message;任何更早的 hydrate/select/list 响应如果属于旧 epoch,不能再覆盖本轮消息、composer 所属会话或 final response 渲染结果。向 /v1/agent/chat 发起请求时,payload 中的 conversationId 必须等于当前 route/active conversation id;如果本地 workspace selected session 仍指向旧会话,应先对齐本地状态,而不是把提交落到旧会话。
Session rail 的运行中状态以目标 conversation 的真实 in-flight turn 为准。某个会话正在执行 Code Agent 请求时,对应 .session-tab 保持原有单行标题和最近用户消息时间,但必须暴露 data-running="true" 并显示执行中动效;turn 进入 completed、failed 或 canceled 后清除动效并回到 data-running="false"。切换会话、恢复会话或取消请求不能改变 session tab 的标题来源:左侧只展示用户第一句话和以最后一条用户消息发送时间计算的更新时间。
关闭 Workbench 加载态问题时,浏览器验收应从当前 node/lane 的 public origin 进入,并在同源会话中对目标列表 API 施加短暂延迟,观察 in-flight DOM 和恢复 DOM。延迟窗口应能看到 #session-tabs[data-loading="true"]、.session-tab 数量为 0、.loading-state 和 .loading-spinner 存在、#session-status 为“加载中”;延迟结束后应恢复为真实数据或真实空态。延迟时间应低于前端请求超时,避免把接口 timeout 后的降级状态误判为恢复态。