Files
fire-safety-ymd/docs/specs/fire-safety-ymd-superagent-openapi-connectivity.md
T
2026-09-06 01:40:15 +08:00

174 lines
9.8 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.
# SuperAgent Open API 连通性基线 Spec
| 项 | 内容 |
| --- | --- |
| 状态 | Implemented |
| 日期 | 2026-09-04 |
| 负责人 | fire-safety-ymd 后端 |
| 需求来源 | 用户 checkpoint `fire-safety-ymd-superagent-openapi-connectivity` |
| 关联 Change Request | 无 |
## 1. 背景
fire-safety-ymd 需要由 Go 后端调用既有 SuperAgent 平台,并在后续让 SuperAgent 通过本项目 MCP 工具查询 PostgreSQL/PostGIS 消防数据。
TH Hotel 项目已经验证了“创建 Open Agent Session、流式发送消息、解析公开 Trace、严格判断完成状态和断流恢复”的调用形态。本 checkpoint 只迁移协议经验和安全边界,使用 Go 独立实现,不复制 Java、酒店业务、AgentBus、邮件、OSS 或任务结果写入逻辑。当前 SuperAgent 外部应用策略关闭了 Trace:同一 Key 使用 `include_trace=true` 返回 HTTP 403、Provider code 为 `open_agent_trace_disabled`,使用 `include_trace=false` 返回 HTTP 200,因此本项目默认采用无 Trace 模式,同时保留显式 Trace 开关。
## 2. 目标
- 建立独立、可测试的 Go SuperAgent Open API Adapter。
- 分离 `CreateSession` 与 `StreamMessage`,为后续一个本地对话复用一个 SuperAgent Session 做准备。
- 使用严格 SSE 成功条件,拒绝部分回答和不完整协议结果。
- 通过 `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE` 选择无 Trace 或公开 Trace;两种模式均不返回部分答案。
- 初始 SSE 断流后通过既有 Run 恢复,不重新发送原始消息。
- 提供默认关闭的 CLI 连通性探针,只发送固定无敏感信息消息。
- 所有自动化测试使用本地模拟 Provider,不需要真实 Secret 或网络。
## 3. 非目标
- 不实现浏览器或业务聊天 API。
- 不持久化本地会话与 SuperAgent Session 的映射。
- 不实现 `/mcp` endpoint 或消防工具。
- 不连接 PostgreSQL/PostGIS。
- 不创建或配置 SuperAgent Profile、外部应用、API Key 或 MCP Server。
- 不把 SuperAgent 输出写入消防业务事实。
## 4. 用户与场景
当前用户是开发和联调人员:在安全配置测试环境后,通过 CLI 探针验证 Go 服务能创建 Session、发送无敏感信息消息并取得严格完成的最终回答。
后续的用户对话 API v1 已在独立 Spec 中实现对该 Adapter 的复用、单进程会话映射、并发冲突和客户端 SSE;真实身份、持久化与主动取消仍需另行设计。
## 5. Definition of Ready
- 目标与非目标已确认:是。
- 协议基线已确认:以 TH Hotel 仓库保存的 2026-07-12 SuperAgent Open API 文档和当前实现为输入,真实环境上线前重新验证。
- 权限和安全边界已确认:Secret 仅由本项目环境变量注入;没有用户业务数据进入探针。
- Trace 策略已确认:默认无 Trace;如需 `include_trace=true`,外部应用必须允许 `trace_policy.enabled=true`。
- 外部依赖已确认:实现只使用 Go 标准库。
- 未确认问题已列出:Profile、外部应用、scope、真实 Base URL 和 API Key 均由平台管理员后续提供。
## 6. 协议与客户端契约
### 6.1 创建 Session
```text
POST /api/open/agent-sessions
```
请求包含:
- `external_subject_id`:调用方提供的稳定、非敏感主体标识。
- `idempotency_key`:创建 Session 的稳定幂等键。
- `metadata`:不包含 Secret 的关联元数据。
客户端接受响应中的 `session_id`,并兼容 `id` 字段。
### 6.2 流式发送消息
```text
POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=false
```
`include_trace` 由 `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE` 控制,默认值为 `false`;只有外部应用
策略明确开启 Trace 时才设置为 `true`。请求包含 `message`、稳定 `idempotency_key` 和安全
`metadata`。Session ID 由上层明确传入,Adapter 不在每条消息前隐式创建新 Session。
### 6.3 鉴权与关联 Header
- `Authorization: Bearer <Open API Key>`
- `X-Request-ID: <稳定请求关联 ID>`
- `X-CSRF-Token` 与 `Cookie: csrf_token=...` 使用同一个每请求随机值。
- SSE 使用 `Accept: text/event-stream` 和 `Cache-Control: no-cache`。
## 7. SSE 成功与恢复规则
一次调用只有满足对应模式的严格条件才成功:
- 无 Trace(`include_trace=false`):收到历史 `messages`/`values` 中最终 AI 消息,且其
`response_metadata.finish_reason=stop`,同时收到非空顶层 `event: message.final` 和顶层
`event: end`;最终回答只采用 `message.final.text`。
- Trace(`include_trace=true`):收到最终内容(优先 `message.final`,兼容累计
`message.delta` 和历史 `messages`/`values` AI 消息)、`run.completed` 且 `status=success`,
并收到顶层 `event: end`。
- 两种模式都不能收到顶层 `error` 或 `run.failed`;断流、缺少必要条件或协议错误不得返回部分答案。
无 Trace 不向调用方返回公开工具/步骤轨迹,但只控制 Trace 暴露和完成判定,不禁止 SuperAgent
在执行中调用已配置的 MCP 工具。是否实际调用工具仍须使用完整对话和 MCP 服务日志验收。
解析器必须支持 `event:`、多行 `data:`、`id:`、心跳注释和空行分帧,并按 SSE event ID 去重。
初始流提前结束时:
- 不重新 POST 消息。
- 从 `Content-Location` 获取同源 Run URL;必要时使用已解析的 Run ID 构造 URL。
- 查询 Run 状态,再订阅 `{run_url}/events`。
- 恢复请求携带 `Last-Event-ID`。
- 使用有上限的指数退避并服从调用方 context 取消。
- 恢复耗尽或进入失败终态时返回明确错误,不返回部分答案。
## 8. 配置契约
| 环境变量 | 默认值 | 说明 |
| --- | --- | --- |
| `FIRE_SAFETY_SUPERAGENT_ENABLED` | `false` | 总开关,默认不调用真实 Provider |
| `FIRE_SAFETY_SUPERAGENT_BASE_URL` | 空 | SuperAgent Open API Base URL |
| `FIRE_SAFETY_SUPERAGENT_OPEN_API_KEY` | 空 | Secret,启用时必填 |
| `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE` | `false` | 是否请求公开 Trace;`true` 要求外部应用策略开启 `trace_policy.enabled` |
| `FIRE_SAFETY_SUPERAGENT_CONNECT_TIMEOUT` | `15s` | 建连超时 |
| `FIRE_SAFETY_SUPERAGENT_RECOVERY_MAX_ATTEMPTS` | `5` | SSE 恢复最大次数;最大可配置为 20 |
| `FIRE_SAFETY_SUPERAGENT_RECOVERY_INITIAL_BACKOFF` | `250ms` | 首次恢复退避 |
| `FIRE_SAFETY_SUPERAGENT_MAX_MESSAGE_BYTES` | `65536` | 单条消息 UTF-8 字节上限;最大可配置为 16 MiB |
| `FIRE_SAFETY_SUPERAGENT_PROBE_SUBJECT_ID` | 固定探针主体 | 仅 CLI 探针使用 |
| `FIRE_SAFETY_SUPERAGENT_PROBE_TIMEOUT` | `10m` | 探针总超时 |
启用时配置缺失或不合法必须启动失败;错误不得包含 API Key。
## 9. 安全规则
- 不读取 TH Hotel 的环境变量或 Secret,不共享 API Key。
- Base URL 必须是绝对 HTTP/HTTPS URL,且不得带 userinfo、query 或 fragment。
- `Content-Location` 和恢复 URL 必须与配置 Base URL 同源,防止向其他主机转发 Authorization。
- 错误只暴露安全状态和经过限制的 Provider error code,不返回响应正文。
- 客户端不记录消息、Header、Cookie、API Key 或 SSE 原始数据。
- Probe 使用固定安全消息;不得用它发送真实火情、联系人或生产数据。
## 10. 需求追踪表
| 需求项 | 后端状态 | 测试状态 | 文档位置 | 当前状态 |
| --- | --- | --- | --- | --- |
| 环境配置与安全默认值 | Done | Passed | 本文第 8 节 | Implemented |
| CreateSession | Done | Passed | 本文第 6.1 节 | Implemented |
| StreamMessage 与按模式严格成功条件 | Done | Passed | 本文第 6.2、7 节 | Implemented |
| SSE 断流恢复 | Done | Passed | 本文第 7 节 | Implemented |
| CLI 探针 | Done | Automated passed;2026-09-06 live no-Trace passed | 项目集成指南 | Verified |
## 11. 验收标准
- Given 未启用 SuperAgent,When 执行真实调用,Then 返回受控禁用错误且不发起网络请求。
- Given 配置完整,When 创建 Session,Then请求具备鉴权、幂等、关联和 CSRF Header,且能解析 Session ID。
- Given `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE=false` 且收到 `finish_reason=stop`、非空顶层 `message.final` 与 `end`,Then 返回 `message.final.text` 和安全元数据,不要求 `run.completed`。
- Given `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE=true` 且同时收到最终内容、成功完成和 `end`,Then 返回最终回答与安全元数据。
- Given 对应模式缺少任一必要成功条件,When 无法恢复,Then 返回协议错误且不返回部分回答。
- Given 初始 SSE 提前结束且存在 Run URL,When 恢复,Then只 GET Run/events、携带 `Last-Event-ID`,消息 POST 次数仍为 1。
- Given未设置真实环境变量,When 运行全部测试,Then 不访问外网且测试通过。
## 12. 测试范围
- 配置默认值、合法值和错误值。
- Session 请求路径、Header、CSRF、请求体和响应解析。
- 无 Trace 的历史 messages/values 最终 AI 消息、`finish_reason=stop`、非空顶层 `message.final` 和顶层 `end`。
- Trace SSE 的最终内容、`run.completed(status=success)`、历史 messages/values 兼容、事件 ID 去重和多行 data。
- 缺少 final/completed/end、顶层 error、run.failed 和非法 JSON。
- 提前 EOF 恢复、Last-Event-ID、同源 URL 和不重复 POST。
- HTTP 非 2xx、超大控制响应和 context 取消。
## 13. Definition of Done
- 实现满足本文契约。
- `gofmt`、`go test ./...` 和 `go vet ./...` 通过。
- 没有真实 Secret、用户数据、构建产物或无关用户变更。
- 项目索引、集成指南、安全边界和 `PROJECT_STATE.md` 已同步。
- 默认无 Trace 能在不开放 `trace_policy` 时完成严格成功判定;Trace 模式仍保留 `run.completed` 成功门禁。
- 真实环境未配置时明确说明未做 live connectivity test。