Files
hunjing/docs/contracts/api-conventions.md
T
chenxin 42513d13c6 📝 docs: 建立魂镜完整 1.0 设计文档体系
- 产品层:产品宪章与永久禁域、产品定义、完整 1.0 范围与发布门、道家文化语言体系、指标与反指标
- 研究层:参考项目研究(deepseek-harness、pi、MemOS、模型网关)、灵台原生引擎研究(业界原生引擎架构理念与道家文化出处)
- 架构层:系统、Agent 运行时(周天体系)、插件系统、灵台引擎(C++ 双形态)、媒体与设备、社区协作市场、前端富内容渲染、数据、记忆与知识
- 契约层:协议与稳定标识、API 总体约定、Native API、兼容网关、实时与 Webhook、内部端口、统一 ContentBlock 与流式(含分支对话交互态)、灵台 C ABI 与 gRPC Service、API 表面、HTTP 与事件、运行观测
- 决策:ADR-001 至 ADR-023(模块化单体、每 attempt 持久化、候选记忆、OAuth 2.1、灵台引擎、双形态部署、大周天演化、宪章、三界作用域、私箧与保全态、叩心、周天统一等)
- 交付:WP-01 至 WP-15 实施 TODO 与设计阶段交接文档
- 工程:AGENTS.md 工程规则(含 C++/灵台规范)、CLAUDE.md 引用、.gitignore
2026-09-09 21:07:14 +08:00

7.2 KiB
Raw Blame History

API 总体约定

1. API 分面

分面 基地址 使用者 稳定性
Native API https://api.<deployment-domain>/v1 Web、Tauri、第三方应用 公开稳定
OpenAI-compatible https://gateway.<deployment-domain>/openai/v1 OpenAI SDK/兼容客户端 对齐所声明子集
Anthropic-compatible https://gateway.<deployment-domain>/anthropic/v1 Anthropic SDK/兼容客户端 对齐所声明子集
Provider Webhook https://api.<deployment-domain>/webhooks/v1 支付、媒体等 Provider Provider 签名契约
Internal Port 进程内接口或私有网络 Core、Worker、Sandbox、Plugin Runtime 不公开

Native、兼容和内部接口不能共享权限推断。兼容入口只提供模型推理,不直接读写角色、记忆、社区、设备和交易资源。

2. 认证

2.1 1.0 认证组合

客户端 凭据 传输位置
Web OAuth 2.1 登录后的 __Host-hunjing_session Cookie 请求头
Tauri Desktop/Mobile Authorization Code + PKCE 获得的短期 access token Authorization: Bearer
第三方用户应用 OAuth 2.1 access token Authorization: Bearer
Service Account 可轮换、限 scope 的 opaque API key Authorization: Bearer
OpenAI-compatible Service account/API key Authorization: Bearer
Anthropic-compatible Service account/API key x-api-key;OAuth 客户端可用 Authorization: Bearer

所有凭据只能通过 Header 传递,不得进入 URL、query、业务 JSON、SSE data 或 WebSocket URL。Cookie 本身是 HTTP Header;Web 的状态变更请求还必须通过 Origin 校验和 Hunjing-CSRF-Token 双提交校验。

2.0 才设计自研加密登录、刷新和设备令牌协议。1.0 不自创密码学认证协议。

2.2 OAuth 端点

OAuth/OIDC 元数据不放在 /v1:

GET  /.well-known/oauth-authorization-server
GET  /.well-known/openid-configuration
GET  /.well-known/jwks.json
GET  /oauth2/authorize
POST /oauth2/token
POST /oauth2/revoke
GET  /oauth2/userinfo
  • Web 使用 Authorization Code;服务端建立 HttpOnly、Secure、SameSite=Lax Session Cookie。
  • Tauri 使用 Authorization Code + PKCE,回调采用已登记的 loopback/deep link。
  • Refresh token 只发送到 /oauth2/token,支持轮换和重用检测。
  • Service Account API key 只显示一次,数据库只保存哈希、前缀、scope、过期和撤销状态。

3. 通用请求头

Header 必需 语义
Authorization 或 Web Cookie 是 调用主体认证;公开匿名读取除外
Content-Type 有 body 时 JSON 为 application/json
Accept 推荐 JSON、SSE 或具体媒体类型
traceparent 推荐 W3C Trace Context
tracestate 否 供应商追踪状态,不含敏感数据
baggage 否 登记的低敏、低基数键;不参与授权
Hunjing-Request-ID 推荐 业务请求关联;缺失时服务端生成
Idempotency-Key 条件必需 创建 Run、支付、退款、结算和副作用命令
If-Match 更新时推荐 ETag 乐观并发
Hunjing-CSRF-Token Cookie 状态变更 与受保护 Cookie 值匹配

服务端响应回显 Hunjing-Request-ID、traceparent,资源响应提供 ETag。敏感 Header 必须在反向代理、APM 和应用日志完全脱敏。

4. 资源与 JSON

  • 字段统一 snake_case;ID 使用契约前缀,并按协议与稳定标识校验 UUID version。
  • 时间是 UTC RFC 3339;时长是非负 _ms 整数。
  • 金额是 {amount_minor: integer, currency: "USD"} 或明确 Decimal string,不使用浮点。
  • 不适用字段省略;已知未知值用 null;真实零值用 0。
  • 创建成功返回 201 + Location;同步读取/修改返回 200;无 body 删除返回 204;异步操作返回 202 + Job/Run。
  • 资源直接作为成功 body 返回,不套无意义的 {data: ...};列表除外。

4.1 列表

{
  "data": [],
  "next_cursor": "opaque-or-null",
  "has_more": false
}

查询统一使用 limit(默认 50,最大 200)、cursor、order=asc|desc。Cursor 是 opaque,并绑定排序和稳定过滤条件;客户端不得解析。

4.2 乐观并发

可变资源响应提供 ETag: "<resource-version>"。PATCH、发布、合并、权限变更和关键状态动作带 If-Match;版本过期返回 412 precondition_failed,不做静默覆盖。

5. 命令与状态动作

  • CRUD 使用 POST/GET/PATCH/DELETE。
  • 非 CRUD、具有领域语义且需审计的动作使用子资源:
POST /v1/runs/{run_id}/cancellations
POST /v1/approvals/{approval_id}/decisions
POST /v1/releases/{release_id}/publications
POST /v1/orders/{order_id}/refunds

不使用含糊的 /action 或把命令塞进 PATCH status。命令响应包含其创建的资源或 202 Job。

6. 幂等

Idempotency-Key 是调用方生成的 opaque string,最长 128 字符。服务端按“认证主体 + HTTP 方法 + 路径模板 + Key”隔离,并保存规范化请求哈希:

  • 相同 Key、相同请求:返回原响应和原资源 ID;
  • 相同 Key、不同请求:409 idempotency_conflict;
  • 未知副作用结果:返回原操作状态,不自动重复执行;
  • Webhook 使用 Provider event ID 独立去重。

聊天消息与 Run 原子创建时,一个 Key 覆盖消息和 Run 两个资源。

7. 错误

{
  "error": {
    "code": "validation_failed",
    "message": "请求字段不合法。",
    "trace_id": "trace_01...",
    "request_id": "request_01...",
    "details": {
      "field_errors": [
        {"path": "content.0.text", "reason": "required"}
      ]
    }
  }
}
  • code 是稳定机器值;message 可本地化;details 不稳定但必须脱敏。
  • 401 不泄露凭据是否存在;跨租户/跨域对象按场景返回 404。
  • 429 返回 Retry-After;SDK 只自动重试网络、408、409(安全时)、429 和 5xx。
  • 流式 HTTP 200 后错误通过事件发送,最终资源状态仍可通过 GET 查询。

8. API 版本

  • 公共路径使用 major /v1;兼容入口保留其协议 /v1。
  • 向后兼容增加字段不升 major;客户端必须忽略未知字段和枚举。
  • 破坏性变更进入 /v2,不在同一字段上改变语义。
  • Preview 能力通过明确 Hunjing-Preview Header 和独立 Schema,不用 X- 前缀。
  • 1.0 实现阶段不为未发布旧契约保留兼容层;正式发布后按公开弃用策略处理。

9. 文件上传

大文件不经过 JSON base64:

  1. POST /v1/uploads 创建 Upload;
  2. 服务端返回单次或 multipart 预签名 URL、允许 MIME、大小和过期;
  3. 客户端直传对象存储;
  4. POST /v1/uploads/{upload_id}/completions 完成并触发校验/扫描;
  5. 成功后产生 file_ 或 media_ 资源。

预签名 URL 属短期对象访问 capability,不是用户登录或 API 凭据,因此是“凭据不得进入 URL”的唯一受控例外。它必须短期、绑定对象路径/方法/大小/MIME,优先单次使用;不得进入 Referer、业务日志、社区内容、Message、Audit、SSE 或诊断响应。未经完成和扫描的 Upload 不能被 Agent、社区或市场引用。