Files
hunjing/docs/contracts/realtime-and-webhooks.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

169 lines
5.4 KiB
Markdown
Raw 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 与 Webhook
## 1. 传输选择
| 场景 | 传输 | 原因 |
| --- | --- | --- |
| Run 文本/工具/状态输出 | SSE | 单向、可重连、HTTP 友好 |
| 实时语音 | WebSocket | 双向音频和控制 |
| 协同编辑/presence | WebSocket | 双向低延迟 |
| 设备会话 | WebSocket | 双向命令、状态和取消 |
| 普通通知 | SSE 或分页 GET | 无需双向连接 |
| 外部系统通知 | HTTPS Webhook | 异步推送 |
WebSocket 认证也只通过 Header:Web 使用 Cookie handshake;Tauri 使用 `Authorization: Bearer`。禁止 query token。
## 2. Run SSE
```http
GET /v1/runs/{run_id}/events
Accept: text/event-stream
Last-Event-ID: event_01...
```
事件格式沿用 `http-and-events.md`:`id`、`type`、`run_id`、`turn_id`、`sequence`、`created_at`、`data`。
规则:
- 连接先发送当前 `run.snapshot`,再发送新事件;
- `Last-Event-ID` 在保留窗口内重放;超出窗口返回 `409 event_cursor_expired`,客户端 GET Run/Message 后重连;
- `content.block.delta` 是预览,`content.block.completed` 提供 Block 权威快照,`message.completed` 指向权威 Message;
- `heartbeat` 不写业务表;
- `run.completed|failed|cancelled` 是终止事件;
- 客户端对 event ID 去重,不仅依赖 TCP 恰好一次。
## 3. WebSocket 通用握手
```http
GET /v1/realtime/voice/{session_id}
Upgrade: websocket
Sec-WebSocket-Protocol: hunjing.realtime.v1
Authorization: Bearer ...
```
Web 使用 Cookie 替代 Authorization。连接成功后第一帧:
```json
{
"type": "session.ready",
"session_id": "...",
"resume_token": "short-lived-opaque",
"capabilities": [],
"heartbeat_interval_ms": 15000
}
```
`resume_token` 只在后续同认证主体的 Header `Hunjing-Realtime-Resume` 使用,不放 URL;短期、单会话、可撤销。
JSON 控制帧统一包含 `type`、`event_id`、`sequence`、`sent_at`。二进制帧只承载协商后的音频/媒体块,元数据由前置 JSON frame 描述。
## 4. 实时语音
```text
POST /v1/realtime-voice-sessions
WS /v1/realtime/voice/{session_id}
POST /v1/realtime-voice-sessions/{session_id}/terminations
```
主要帧:
```text
input_audio.start
input_audio.chunk
input_audio.commit
transcript.delta
transcript.completed
agent.text.delta
output_audio.start
output_audio.chunk
output_audio.completed
response.interrupt
session.error
session.completed
```
- 音频 codec、采样率、语言和端点检测在 Session 创建时协商。
- `response.interrupt` 取消当前模型和 TTS,不删除已固化用户段。
- 服务端施加最大帧、带宽、静音、会话时长和费用预算。
- 原始音频保留策略在 Session 创建响应明确返回。
## 5. 协同编辑
```text
POST /v1/collaboration-sessions
WS /v1/realtime/collaboration/{session_id}
```
帧:`presence.joined/left`、`document.operation`、`document.ack`、`cursor.updated`、`review.updated`、`session.error`。每个 operation 带 client operation ID、base version 和资源 ID;服务端按 ACL 校验。不能通过协同通道编辑支付账、审批记录或已发布不可变版本。
## 6. 设备会话
```text
POST /v1/device-sessions
WS /v1/realtime/devices/{session_id}
```
帧:`capability.state`、`capture.started/chunk/completed`、`permission.changed`、`session.pause/resume/terminate`、`device.error`。每帧校验 DeviceGrant;撤权后连接立即停止相关 capability。Tauri 不暴露通用 Shell frame。
## 7. 社区通知
```http
GET /v1/notifications/events
Accept: text/event-stream
```
只发送薄事件:notification ID、type、resource ID、created_at;正文通过 Native API 按当前权限读取。屏蔽或权限变化后旧通知不能成为资源读取旁路。
## 8. Hunjing Outbound Webhook
```text
GET /v1/webhook-endpoints
POST /v1/webhook-endpoints
PATCH /v1/webhook-endpoints/{endpoint_id}
DELETE /v1/webhook-endpoints/{endpoint_id}
POST /v1/webhook-endpoints/{endpoint_id}/secret-rotations
```
投递 Header:
```http
Hunjing-Webhook-ID: webhook_event_01...
Hunjing-Webhook-Timestamp: 178...
Hunjing-Webhook-Signature: v1=<base64url-hmac>
```
签名输入是:`id + "." + timestamp + "." + raw_body`。接收方验证原始字节、时间窗和 event ID 去重。Secret 明文只显示一次,支持新旧 Secret 短期重叠轮换。
Envelope:
```json
{
"id": "webhook_event_01...",
"type": "run.completed",
"created_at": "2026-09-03T08:00:00Z",
"data": {
"resource_id": "run_01...",
"personal_domain_id": "domain_01..."
}
}
```
Webhook 是薄通知,不包含消息正文、工具参数、支付敏感数据或诊断内容。接收方用自己的凭据读取资源。
投递至少一次、不保证顺序;2xx 确认,3xx 不跟随,失败指数退避并有死信/管理重放。删除事件可能无法再次读取资源,Envelope 保留最小墓碑信息。
## 9. Provider Inbound Webhook
```text
POST /webhooks/v1/payments/{provider}
POST /webhooks/v1/media/{provider}
POST /webhooks/v1/identity/{provider}
```
- 先读取 raw body,再按 Provider 官方 SDK/算法验签;
- 验签前不解析为业务命令;
- 按 Provider event ID 幂等,保存接收、验证、处理状态和不可逆 body hash;
- 不依赖事件顺序,必要时向 Provider 主动查询当前状态;
- 快速返回 Provider 要求的 2xx,重处理进入内部 Job;
- 业务结果由 Ledger/权威资源决定,不由单个 Webhook body 直接覆盖。