Files
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

160 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`:
```text
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 使用契约前缀,并按[协议与稳定标识](README.md#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 列表
```json
{
"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、具有领域语义且需审计的动作使用子资源:
```text
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. 错误
```json
{
"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、社区或市场引用。