25 KiB
PJ2026-010403 API契约
修改历史
| 版本 | 对应 commit id | 更新日期 | 变更说明 |
|---|
当前正文仍在规格治理草稿中;未定稿前不新增版本号,不为单次编辑追加 待提交 版本。
正文
PJ2026-010403 API契约需求规格
1. 文档控制
| 字段 | 内容 |
|---|---|
| 编号 | PJ2026-010403 |
| 短名 | API契约 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-18-r1; PJ2026-0104010803 唯一投影 draft-2026-06-18-p0-unique-projection; PJ2026-01050105 Web鉴权 draft-2026-06-18-p0-auth |
| 需求规格模板 | ISO/IEC/IEEE 29148 需求规格模板 |
| 上级规格 | PJ2026-0104 客户端 |
| 规格治理索引 | 规格治理 |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 API 契约的稳定使命、范围、术语、系统边界、内部分工和原子需求。
2. 目的和范围
2.1 目的
API契约负责定义 Cloud Web、HWLAB CLI 和自动化脚本共同使用的 RESTful HTTP API 入口语义,使同一用户请求在 Web、CLI 和 HTTP 调用下使用一致的 method、path、query/body、schema、鉴权主体、错误语义和结果标识。
本课题的目标状态是:客户端入口可以通过同源 API 证明业务路径是否可用;后端业务事实改变时,API 契约负责稳定暴露字段和错误,而不在客户端侧发明第二套事实模型。
2.2 范围内
- Cloud Web 同源相对 REST/JSON path、route policy 和绝对 URL 禁止边界。
- Web session、API key、AuthPrincipal、actor 摘要和权限错误在客户端入口中的表达。
- Agent session、chat、steer、cancel、result、trace 和 inspect 的用户可见 API 形态。
- Workbench workspace、Admin Access、provider profile、HWPOD node-ops、gateway 和性能摘要等入口的字段稳定性。
- JSON 成功/失败响应、HTTP 状态、错误分类、脱敏、默认摘要和完整展开边界。
2.3 范围外
- 用户、组织、API key、额度、role、OpenFGA relation 和账本真相归 用户管理。
- AgentRun run、command、runner job、session continuation 和 provider runtime 归 Agent编排。
- HWPOD 资源身份、硬件操作、node 路由和原始硬件事实归 硬件池。
- CaseRun、评价、aggregate、回放和训练反馈归 HarnessRL。
- 运行端点、FRP/Caddy、Secret、rollout 和 Prometheus 监控归 平台运维。
3. 术语表
| 术语 | 定义 |
|---|---|
| 同源 API | Cloud Web origin 下的相对 REST/JSON HTTP API path,供浏览器和 HWLAB CLI 使用。 |
| route policy | 哪些 path 可以通过 Cloud Web 代理、哪些只能作为显式 Cloud API 诊断或内部服务调用的边界规则。 |
| AuthPrincipal | 后端根据 Web session 或 API key 恢复出的用户主体摘要。 |
| CanonicalPrincipal | /auth/session 和受保护业务 route 共享的最小身份结果,包含 authMethod、identityAuthority、sessionKind、actor 摘要和后端 capability 摘要;它是业务 route 的唯一身份输入。 |
| 业务标识 | sessionId、turnId、traceId、runId、commandId、caseId 等用户可继续查询的稳定标识;projectId、workspaceId 和 conversationId 只能作为筛选、metadata 或兼容映射字段,不作为前端鉴权 authority。 |
| 错误语义 | HTTP status、错误码、blocker、failureKind、route 和下一步提示组成的可定位失败表达。 |
| Session detail | GET /v1/workbench/sessions/{sessionId} 这类按稳定 sessionId 或后端认可 opaque session handle 查询当前会话 metadata、消息指针和状态的 RESTful detail resource。 |
| Conversation detail | 迁移期兼容资源;可返回 conversation metadata、sessionId、threadId 和 message seed,但不得继续作为 Web deep link 或前端 active session authority。 |
| 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 事件。 |
| WorkbenchProjectionWriter | PJ2026-0104010803 Workbench唯一投影 定义的唯一写入组件,把 AgentRun run、command、event 和 result 转换为 HWLAB durable Workbench facts。 |
| WorkbenchReadModel | PJ2026-0104010803 Workbench唯一投影 定义的唯一读模型,从 durable Workbench facts 组装 session detail、message page、turn snapshot、trace event page 和 session rail summary。 |
| projection commit | projection writer/finalizer 对 message、part、turn、trace 和 session summary 的一次幂等持久化提交;终态 commit 必须保持这些事实语义一致。 |
| projectedSeq | HWLAB durable trace event 的单调分页游标;与 AgentRun sourceSeq / sourceEventId 分离,用于 Workbench trace page、SSE replay 和 fake-server fixture。 |
| 读侧推理 | API route、read model、SSE consumer、compat wrapper、CLI renderer、Web reducer/selectors、fake-server 或测试断言根据 trace tail、message text、tool event、result cache、session summary、list row、workspace snapshot、localStorage 或 elapsed timeout 推断 lifecycle、terminal、running 或 final response 的行为;API契约禁止该模式。 |
4. 系统边界和接口
本规格把 API契约作为客户端方向下的接口语义层看待;本章只描述输入、输出和责任边界。
| 边界项 | 内容 |
|---|---|
| 外部使用者 | Cloud Web、HWLAB CLI、自动化脚本、平台管理员和需要同源 API 的浏览器客户端。 |
| 外部输入 | HTTP method、相对 path、JSON body、query、Web session cookie、Authorization header、sessionId、turnId、traceId 和业务参数;projectId、workspaceId、conversationId 只允许作为显式筛选或兼容 metadata 输入。 |
| 受控资源 | API path、schema、route policy、AuthPrincipal 摘要、错误码、响应摘要和兼容性契约。 |
| 外部输出 | JSON 响应、HTTP status、route、actor、业务标识、错误分类、脱敏状态、trace/result 指针和下一步查询提示。 |
| 用户接口 | Cloud Web 同源 API、HWLAB CLI 同源 REST request/client 命令、HTTP API。 |
| 系统边界 | API契约负责接口形态和错误表达;不拥有用户、Agent、硬件、CaseRun、账本或发布事实。 |
5. 内部分工与规格索引
| 编号 | 模块或课题 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
|---|---|---|---|---|---|
| PJ2026-01040301 | 同源路由 | 本规格 6.1 | Cloud Web 相对 REST/JSON path、route policy 和绝对 URL 禁止边界 | 平台入口、Web工作台 | HWLAB CLI、Cloud Web |
| PJ2026-01040302 | 鉴权主体 | 本规格 6.2 | Web session、API key、actor 摘要和权限错误表达 | 用户管理 | Web、CLI、业务 API |
| PJ2026-01040303 | Agent接口 | 本规格 6.3 | conversation、session、chat、steer、cancel、result、trace 和 inspect API 形态 | Agent编排、用户管理 | Web工作台、HWLAB CLI |
| 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 facts;compat wrapper 只提供旧 path 到新资源的兼容映射,不拥有第二套业务事实。
5.1 Workbench唯一投影 API 边界
PJ2026-0104010803 Workbench唯一投影 集中定义 AgentRun facts 到 Workbench durable facts 的目标架构、数据流、terminal commit 时序和 cloud-api 重启恢复时序。API契约在本文只保留接口边界:GET /v1/workbench/* 只读取 WorkbenchReadModel;SSE 只发布 projection commit notification;compat wrapper 只能调用同一 read model 或正式 mutation。
若 AgentRun 事实已经 terminal 但 Workbench projection 尚未追平,GET 响应应暴露 projectionStatus、lastProjectedSeq、sourceRunId、sourceCommandId、blocker 或等价诊断字段;不得在 GET 中同步调用 AgentRun、Code Agent manager、legacy conversation manager、billing finalizer、workspace repair、trace polling 或 result polling 来推进事实。读模型、SSE publisher、compat wrapper 和 CLI render 都不能各自解释 terminal、running、final response 或 trace pagination;它们只能重放 durable projection。
API 契约严禁读侧推理。GET /v1/workbench/*、/v1/agent/* compat wrapper、SSE event envelope 和 CLI render 只能返回唯一 Workbench durable projection 中已经存在的 lifecycle/final/status 字段;不得从 result?.status ?? trace?.status、最后一条 trace event completed、message text 是否为空、part/tool row 状态、session list summary、workspace selected state、轮询耗时或 elapsed timeout 合成 terminal、running、finalResponse 或 caught-up。投影缺失或矛盾时返回结构化 unknown/projecting/degraded/blocker,而不是在读侧选择一个优先级最高的事实源。
6. 原子需求
6.1 CLIENT-API-REQ-001 同源路由
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| CLIENT-API-REQ-001 | 同源路由 | PJ2026-01040301 同源路由 | PJ2026-010401 Web工作台、PJ2026-010402 HWLAB CLI、平台运维 |
API契约应定义 Cloud Web origin 下的相对 REST/JSON path 和 route policy,使浏览器与 HWLAB CLI 能通过同一同源入口访问业务 API。
同源路由必须拒绝把绝对 URL、内部服务地址或旧运行面端口作为正式用户入口。平台运维提供公开入口和代理支撑;API契约只规定客户端可依赖的 path 和错误形态。
API契约必须区分同源 API path 与浏览器 history route:/auth*、/v1*、/health* 等 API path 返回 JSON 语义,/workbench、/login 和其他 Cloud Web 页面路由由 Web工作台处理。API/edge 直达入口对页面路由返回 JSON 404 是正确边界,不应被改造成 SPA fallback;反过来,Web正式公开入口必须通过 route policy 把 API path 分流到 API 服务。
RESTful API 必须保持无状态请求语义:在相同 method、path、query、body、auth 主体和相同后端业务事实下,应返回同一语义结果;服务端不得为了补齐某个列表或状态而隐藏读取浏览器 workspace selected、localStorage、Web snapshot、上一次页面状态或其他客户端临时状态。列表窗口需要包含某个当前资源时,必须通过显式 query/path/body 传入稳定业务 id,例如 session list 通过显式 include session id 请求把当前 session 纳入同一列表响应;服务端只能从当前 Web session/API key 恢复 AuthPrincipal,校验该 id 对当前 actor 是否可见并返回后端事实,不得接受客户端拼接出的 project、workspace、status、final response、markdown、running 动效或 stub 作为事实来源。
当前会话消息恢复必须使用 session 主路径:GET /v1/workbench/sessions/{sessionId} 返回 session metadata 和消息指针,GET /v1/workbench/sessions/{sessionId}/messages 返回 message/part page,turn 和 trace 分别由 TurnSnapshot 与 TraceEventPage 补洞。GET /v1/workbench/workspace 可以返回 selected ids、workspace revision 和 composer 配置,但不得成为消息本体 authority;GET /v1/workbench/sessions 可以返回 rail 摘要和显式 include 的列表项,但不得替代当前 session detail/message page。前端恢复、深链、刷新和 session 切换必须以稳定 sessionId 或后端认可 opaque session handle 调用同一 detail/message resource,不得在 detail resource 失败时切到 workspace snapshot、conversation detail、列表摘要、JSON-RPC、内部 manager、浏览器缓存或空 stub 继续构造当前消息面板。
6.2 CLIENT-API-REQ-002 鉴权主体
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| CLIENT-API-REQ-002 | 鉴权主体 | PJ2026-01040302 鉴权主体 | 用户管理、PJ2026-010402 HWLAB CLI |
API契约应以 AuthPrincipal 摘要表达 Web session 和 API key 恢复出的当前用户,使 Web、CLI 和 HTTP API 可以一致处理未登录、无权限、账号禁用、额度不足和工具能力缺失。
鉴权主体的真相由用户管理负责。API 响应只输出 actor、authMethod、requiredAuthMethod、role/status、scope 摘要和错误分类,不输出 session token、完整 API key、password hash、Secret value 或可复用凭据。
/auth/session 是 Cloud Web 的最小身份验证端点。浏览器请求只依赖同源 hwlab_session cookie transport;前端不得向该端点传入 API key、user-billing token、cookie prefix、localStorage token 或第二套 authority。该端点成功时必须返回 canonical principal,至少包含:
| 字段 | 语义 | 脱敏边界 |
|---|---|---|
authenticated |
当前请求是否已通过认证 | 布尔值 |
authMethod |
认证 transport 来源,例如 web-session、user-billing-session、user-billing-api-key、local-bootstrap |
枚举,不输出 token |
identityAuthority |
身份事实归属,例如 hwlab-local、user-billing、bootstrap-recovery |
枚举,不输出底层凭据 |
sessionKind |
调用形态,例如 browser、api-key、recovery |
枚举 |
actor |
当前用户摘要,至少包含稳定 id、role、status;可包含 username/displayName | 不输出 password hash、session secret、完整邮箱验证 payload |
capabilities |
后端授权摘要,例如 web、workbench、codeAgent、billing、admin |
只输出 available、forbidden、unlinked、unavailable 或等价短枚举 |
valuesRedacted |
响应是否遵守脱敏边界 | 必须为 true |
未登录请求必须返回 401 和结构化 unauthenticated 结果;禁用、撤销或 recovery 能力不足必须返回 403 或业务 blocker,并保留 authMethod、identityAuthority、sessionKind 的可诊断摘要。响应不得输出 cookie、session token、API key secret、完整 user-billing token、provider Secret、DB DSN 或 raw dependency payload。
业务 route 只能消费认证层产生的 canonical principal 和权限配额的 capability 结果。Usage、Billing、API keys、Workbench、Code Agent 和 Admin route 不得自行调用 token/cookie 抽取函数来决定用户身份;如果需要访问 user-billing、API key 或账单后台,应由后端以 principal 为输入桥接业务服务,并把 available/forbidden/unlinked/unavailable 或结构化 blocker 返回给客户端。
6.3 CLIENT-API-REQ-003 Agent 用户接口
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| CLIENT-API-REQ-003 | Agent接口 | PJ2026-01040303 Agent接口 | Agent编排、用户管理、PJ2026-010401 Web工作台 |
API契约应定义显式 Agent session、turn、chat、steer、cancel、result、trace 和 inspect 的用户可见 RESTful HTTP 形态,使 Web 和 HWLAB CLI 能围绕同一 sessionId、turnId、traceId、runId 和 commandId 操作。conversationId、threadId 可以作为后端返回的 metadata 或兼容映射字段存在,但不得替代 sessionId 成为 Web deep link 或 active authority。
Agent 接口不得通过 session latest、浏览器历史、旧 cache 或内部 manager 生成第二套 final response。Agent编排提供执行事实,用户管理校验 owner 和权限,客户端只稳定暴露用户入口。
Trace 查询必须采用无状态 RESTful 资源形态:GET /v1/agent/traces/{traceId} 是客户端读取 Code Agent trace events、runnerTrace、terminalEvidence、finalResponse 和 traceSummary 的权威入口。请求只依赖 method、path、query、auth 主体和后端业务事实;Web 不得使用动作式 /v1/agent/chat/trace/{traceId} 作为恢复会话、切换 session 或 completed 消息加载 trace 的前端路径,也不得把浏览器 workspace snapshot、localStorage 或消息 stub 拼成 trace 响应。
Trace resource 必须支持按事件位置继续读取,例如 sinceSeq / cursor 与 limit 这类 query 参数。服务端返回超长 trace 时应按完整事件边界截断,并在同一个资源响应中给出 range、hasMore、nextSinceSeq 或等价阶段性位置,使客户端可以继续请求下一段;响应不得返回半条事件,不得要求 JSON-RPC、回放按钮、内部 manager path 或第二套 trace endpoint 才能补齐完整可读事件。分页请求必须保持无状态和幂等:同一 traceId、同一位置参数、同一权限主体下重复请求不得污染 trace 事实。
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 |
cursor, limit, includeSessionId,可选后端认可筛选字段 |
session/conversation rail 摘要 page | 200/401/403 | 当前用户可见 session 列表和排序,不替代 detail |
| Session detail | GET /v1/workbench/sessions/{sessionId} |
path sessionId | session metadata、message page 指针和当前 turn/trace 摘要 | 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,不替代 session 主路径 |
| Turn admission | POST /v1/workbench/sessions/{sessionId}/turns |
prompt/parts、delivery、client message ids、可选 metadata | 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 |
optional sessionId/turnId/traceId 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 边界;trace event page 的分页 cursor 使用 HWLAB projectedSeq,并保留 AgentRun sourceSeq/sourceEventId 作为来源审计字段,二者不得重叠或互相替代。所有错误响应必须包含 route、status、code/blocker、redacted actor、target resource 和下一步建议。
新增或重构的核心后端文件头部必须标注遵循的 SPEC 编号、短名和实现引用版本,例如 SPEC: PJ2026-0104010803 唯一投影 draft-2026-06-18-p0-unique-projection; PJ2026-010403 API契约 draft-2026-06-18-r1; PJ2026-010205 HWLAB接入 draft-2026-06-17-r0,并简述文件职责。实现文件不得只写 issue 编号、latest 或 current 作为规格引用。
6.4 CLIENT-API-REQ-004 资源与管理接口
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| CLIENT-API-REQ-004 | 资源接口 | PJ2026-01040304 资源接口 | 硬件池、用户管理、Agent编排、平台运维 |
API契约应定义 workbench workspace、Admin Access、provider profile、HWPOD node-ops、gateway 诊断和性能摘要等资源与管理入口,使 Web 和 HWLAB CLI 可以一致读取状态、提交操作和展示错误。
资源与管理接口只定义调用形态和字段稳定性。HWPOD node-ops 的硬件语义归硬件池,provider profile runtime 归 Agent编排,权限和账号归用户管理,运行健康和公开入口归平台运维。
Gateway 相关 API 只允许作为云端同源入口暴露:用户、Agent 或 smoke 调用 Cloud API / API契约中的 gateway/HWPOD path,由 HWPOD 服务再路由到主动出站的 AI 网关。API契约不得要求客户端直接访问用户 PC gateway,也不得把 gateway 本地端口、内网地址或临时 poll URL 写入正式客户端输出。
6.5 CLIENT-API-REQ-005 错误与输出合同
| 编号 | 短名 | 主责模块 | 关联模块 |
|---|---|---|---|
| CLIENT-API-REQ-005 | 错误输出 | PJ2026-01040305 错误输出 | PJ2026-010402 HWLAB CLI、PJ2026-010401 Web工作台、HarnessRL |
API契约应保证成功和失败都以可定位 JSON 形式表达,至少包含调用 route、HTTP status、错误码或 blocker、必要业务标识、脱敏 actor 或权限摘要,以及可继续查询的 result/trace/status 入口。
默认响应不得输出爆炸或泄漏敏感值;需要完整 trace、原始响应或长日志时,必须通过显式展开参数、下载入口或已有业务产物获取。错误输出只负责说明失败,不替代缺失能力实现。
7. 过程控制
本规格不单独索引过程 issue;跨 L1 的内测、灰度和阶段活动索引统一保留在 PJ2026-01 HWLAB 总规格 的 7. 过程控制。