superagent请求问题修复

This commit is contained in:
andy
2026-09-06 01:40:15 +08:00
parent ee9d2d7cf1
commit 7243319bbb
19 changed files with 388 additions and 74 deletions

View File

@@ -12,13 +12,14 @@
fire-safety-ymd 需要由 Go 后端调用既有 SuperAgent 平台,并在后续让 SuperAgent 通过本项目 MCP 工具查询 PostgreSQL/PostGIS 消防数据。
TH Hotel 项目已经验证了“创建 Open Agent Session、流式发送消息、解析公开 Trace、严格判断完成状态和断流恢复”的调用形态。本 checkpoint 只迁移协议经验和安全边界,使用 Go 独立实现,不复制 Java、酒店业务、AgentBus、邮件、OSS 或任务结果写入逻辑。
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 或网络。
@@ -43,6 +44,7 @@ TH Hotel 项目已经验证了“创建 Open Agent Session、流式发送消息
- 目标与非目标已确认:是。
- 协议基线已确认:以 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 均由平台管理员后续提供。
@@ -65,10 +67,12 @@ POST /api/open/agent-sessions
### 6.2 流式发送消息
```text
POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=true
POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=false
```
请求包含 `message`、稳定 `idempotency_key` 和安全 `metadata`。Session ID 由上层明确传入,Adapter 不在每条消息前隐式创建新 Session。
`include_trace` 由 `FIRE_SAFETY_SUPERAGENT_INCLUDE_TRACE` 控制,默认值为 `false`;只有外部应用
策略明确开启 Trace 时才设置为 `true`。请求包含 `message`、稳定 `idempotency_key` 和安全
`metadata`。Session ID 由上层明确传入,Adapter 不在每条消息前隐式创建新 Session。
### 6.3 鉴权与关联 Header
@@ -79,12 +83,18 @@ POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=true
## 7. SSE 成功与恢复规则
一次调用只有同时满足以下条件才成功:
一次调用只有满足对应模式的严格条件才成功:
1. 收到最终内容;优先使用 `message.final`,兼容累计 `message.delta` 和历史 `messages`/`values` AI 消息。
2. 收到 `run.completed` 且 `status=success`。
3. 收到顶层 `event: end`。
4. 没有收到顶层 `error` 或 `run.failed`。
- 无 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 去重。
@@ -104,6 +114,7 @@ POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=true
| `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` | 首次恢复退避 |
@@ -128,16 +139,17 @@ POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=true
| --- | --- | --- | --- | --- |
| 环境配置与安全默认值 | Done | Passed | 本文第 8 节 | Implemented |
| CreateSession | Done | Passed | 本文第 6.1 节 | Implemented |
| StreamMessage 与严格成功条件 | Done | Passed | 本文第 6.2、7 节 | Implemented |
| StreamMessage 与按模式严格成功条件 | Done | Passed | 本文第 6.2、7 节 | Implemented |
| SSE 断流恢复 | Done | Passed | 本文第 7 节 | Implemented |
| CLI 探针 | Done | Compile passed;live test pending | 项目集成指南 | 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完整 SSE,When 同时收到最终内容、成功完成和 `end`,Then 返回最终回答与安全元数据。
- Given SSE 缺少任一成功条件,When 无法恢复,Then 返回协议错误且不返回部分回答。
- 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 不访问外网且测试通过。
@@ -145,7 +157,8 @@ POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=true
- 配置默认值、合法值和错误值。
- Session 请求路径、Header、CSRF、请求体和响应解析。
- 当前 Trace SSE、历史 messages/values 兼容、事件 ID 去重和多行 data。
- 无 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 取消。
@@ -156,4 +169,5 @@ POST /api/open/agent-sessions/{session_id}/messages/stream?include_trace=true
- `gofmt`、`go test ./...` 和 `go vet ./...` 通过。
- 没有真实 Secret、用户数据、构建产物或无关用户变更。
- 项目索引、集成指南、安全边界和 `PROJECT_STATE.md` 已同步。
- 默认无 Trace 能在不开放 `trace_policy` 时完成严格成功判定;Trace 模式仍保留 `run.completed` 成功门禁。
- 真实环境未配置时明确说明未做 live connectivity test。