feat(h5): web 联网能力、实时查询路由与 session Finish 对齐
- 新增 web 能力并挂载 platform/web(web_search/fetch_url) - 实时查询强制 web skill,router fallback 与 await session Finish - Session Broker 覆盖率/指标、stream replay 与相关单测/E2E 脚本 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
| 文档 | 问题 | 状态 | 阻塞原因 |
|
||||
|------|------|------|----------|
|
||||
| [h5-finish-before-run-gate-20260706.md](./h5-finish-before-run-gate-20260706.md) | Finish 先于 agent-run gate 导致 UI 永久 loading | 已修复(分支内) | 随 H5 session 分支合并 |
|
||||
| [h5-run-stream-replay-4b-20260706.md](./h5-run-stream-replay-4b-20260706.md) | Run SSE replay(4b) | 已修复(分支内) | 随 H5 session 分支合并 |
|
||||
| [h5-session-stream-replay-4c-20260706.md](./h5-session-stream-replay-4c-20260706.md) | Session SSE replay(4c) | 已修复(分支内) | 全量 soak 待执行 |
|
||||
| [h5-public-html-fake-delivery-guard-20260706.md](./h5-public-html-fake-delivery-guard-20260706.md) | H5 Agent 宣称「页面已生成」但 `public/*.html` 未落盘(无 write_file) | 待修复 | 等 H5 session / broker / SSE 收口分支合并后,与 `server.mjs`、`tkmind-proxy.mjs` 统一改 |
|
||||
| [h5-local-soak-20260706.md](./h5-local-soak-20260706.md) | 本地全开开关 soak 验收清单 | **待执行** | 等 P0–P1 开发全部完成后再跑 |
|
||||
|
||||
开工前:读对应 md 全文 + [h5-session-architecture-20260706.md](../h5-session-architecture-20260706.md),确认主线已合并再动 Finish 路径。
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# H5 Session 本地 Soak 测试
|
||||
|
||||
> **状态:自动化已通过(2026-07-06 14:57);手工场景待 john 账号验证**
|
||||
> 分支:`0706-bug干净` · 禁止 merge main / 上 103 / commit(除非另行指令)
|
||||
|
||||
## 前置
|
||||
|
||||
```bash
|
||||
# .env 建议全开(勿提交 Git)
|
||||
MEMIND_SESSION_BROKER_ENABLED=1
|
||||
MEMIND_SESSION_BROKER_METRICS=1 # 场景 8
|
||||
MEMIND_ROUTER_NORMALIZED_DECISION=1
|
||||
MEMIND_SSE_EVENT_TAXONOMY=1
|
||||
MEMIND_RUN_STREAM_REPLAY=1
|
||||
MEMIND_SESSION_STREAM_REPLAY=1 # 场景 5(4c)
|
||||
MEMIND_H5_HTML_FINISH_GUARD=1
|
||||
|
||||
pnpm dev
|
||||
# 访问 http://127.0.0.1:5173/ 全屏聊天
|
||||
```
|
||||
|
||||
**2026-07-06 检查**:本地 `.env` 已有 5 个开关,**缺少** `MEMIND_SESSION_STREAM_REPLAY`、`MEMIND_SESSION_BROKER_METRICS`。
|
||||
手工测场景 5/8 前请补上并 **重启 `pnpm dev`**。
|
||||
|
||||
**DB**:已执行 `migrateSchema`,`h5_session_stream_events` 表已创建。若 dev 在迁移前启动,需重启后 4c store 才会注入。
|
||||
|
||||
---
|
||||
|
||||
## 自动化验收(2026-07-06 14:57)
|
||||
|
||||
| 命令 | 结果 |
|
||||
|------|------|
|
||||
| `npm run verify:h5-session-patches` | ✅ pass(含单测 + broker coverage + goosed boundary + publish guards) |
|
||||
| `npm run verify:chat-finish-sync` | ✅ pass |
|
||||
| `npm run verify:mindspace-page-sync-guards` | ✅ pass |
|
||||
| `node scripts/check-session-broker-coverage.mjs` | ✅ pass |
|
||||
| `node scripts/check-goosed-proxy-boundary.mjs` | ✅ pass |
|
||||
| 本地服务探活 `5173` / `8081` | ✅ HTTP 200 |
|
||||
| `h5_session_stream_events` 表 | ✅ 迁移后存在 |
|
||||
|
||||
### 历史数据辅助(john,近 2h intent_routed)
|
||||
|
||||
| 指标 | 值 |
|
||||
|------|-----|
|
||||
| 采样条数 | 10 |
|
||||
| router timeout fallback | 2/10(睡前故事、讲笑话各 1 次) |
|
||||
| 其余 | `source: llm`,路由正常 |
|
||||
|
||||
> 自动化**不能**替代场景 1–8 的浏览器/DevTools 验证。
|
||||
|
||||
---
|
||||
|
||||
## 测试账号
|
||||
|
||||
| 用户 | 用途 |
|
||||
|------|------|
|
||||
| john | 主 soak 账号(已有 session 历史) |
|
||||
|
||||
## 场景清单
|
||||
|
||||
| # | 场景 | 操作 | 预期 | 结果 | 备注 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 普通 direct_chat | 「讲一个睡前故事吧」 | ~7s 内整段回复;loading 点消失 | ☐ 待人工 | 历史:7.1s,曾 router timeout |
|
||||
| 2 | 简单 hi | 「hi」 | 2–3s 回复;无永久 loading | ☐ 待人工 | Finish 竞态 |
|
||||
| 3 | agent 生成页 | 「帮我生成一个唐诗页面…」 | agent 路径;Finish 后 public HTML 落盘 | ☐ 待人工 | publish guards 已自动化 ✅ |
|
||||
| 4 | run SSE 重连 | 发消息 → DevTools 断网 3s → 恢复 | run events 从 Last-Event-ID 补发 | ☐ 待人工 | 4b,需 `MEMIND_RUN_STREAM_REPLAY=1` |
|
||||
| 5 | session SSE 重连 | 流式回复中断网 | 重连后 merge,不盲覆盖 | ☐ 待人工 | 4c,需补 `MEMIND_SESSION_STREAM_REPLAY=1` + 重启 dev |
|
||||
| 6 | MindSpace 小窗 | `/?preview=mindspace` 发消息 | 同全屏,Finish 不丢消息 | ☐ 待人工 | |
|
||||
| 7 | Router 稳定性 | 连发笑话/写诗/故事各 1 条 | 无频繁 1500ms timeout fallback | ☐ 待人工 | 历史 2/10 timeout;快路径已合入未 soak |
|
||||
| 8 | Broker metrics | 403 访问他人 session | Portal 日志含 `[session_broker.ownership.denied]` | ☐ 待人工 | 需 `MEMIND_SESSION_BROKER_METRICS=1` |
|
||||
|
||||
## 记录模板(每条失败场景填写)
|
||||
|
||||
```text
|
||||
场景 #:
|
||||
时间:
|
||||
sessionId / runId:
|
||||
现象:
|
||||
Network / Console:
|
||||
是否 blocker:
|
||||
```
|
||||
|
||||
## 结论(手工测试后填写)
|
||||
|
||||
- **自动化闸门**:✅ 通过(2026-07-06)
|
||||
- **整体 soak**:☐ 待人工
|
||||
- **blocker 列表**:(暂无)
|
||||
- **是否可进入 merge main 讨论**:等手工场景 1–8 完成后再定
|
||||
@@ -0,0 +1,59 @@
|
||||
# Patch 4c:Session SSE Replay(进行中,禁止 merge main / 上 103)
|
||||
|
||||
> **状态:代码 + 单测已完成(2026-07-06);全量 soak 待开发完成后执行。**
|
||||
|
||||
## 目标
|
||||
|
||||
解决 H5 session SSE 重连丢状态问题(§8.3):
|
||||
|
||||
- Portal 持久化经 sanitizer 后的 session 事件到 `h5_session_stream_events`
|
||||
- SSE 帧带 Portal `id:` cursor(与 run replay 4b 对齐)
|
||||
- 客户端带 `Last-Event-ID` 重连时,先从 DB 补发 missed events
|
||||
- 若补发以 `Finish`/`Error` 终态结束,则不再挂 upstream(避免重复 Finish)
|
||||
|
||||
## 开关
|
||||
|
||||
```bash
|
||||
MEMIND_SESSION_STREAM_REPLAY=1
|
||||
```
|
||||
|
||||
与 4b 独立:可只开 run replay、只开 session replay、或两者同开。
|
||||
|
||||
## 改动文件
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `session-stream.mjs` | replay 纯函数、flag |
|
||||
| `session-stream-store.mjs` | MySQL 读写 |
|
||||
| `session-stream*.test.mjs` | 单测 |
|
||||
| `db.mjs` / `schema.sql` | `h5_session_stream_events` 表 |
|
||||
| `tkmind-proxy.mjs` | 重连补发 + live persist + SSE `id:` |
|
||||
| `server.mjs` | store 注入、启动 flag 日志 |
|
||||
| `.env.example` / `docs/local-dev.md` | 文档 |
|
||||
|
||||
## 行为说明
|
||||
|
||||
| 场景 | 行为 |
|
||||
|------|------|
|
||||
| 首次订阅(无 Last-Event-ID) | 纯透传 goosed,live 持久化(开关开启时) |
|
||||
| 重连(有 Last-Event-ID) | DB 补发 → 若未到 terminal 再挂 upstream |
|
||||
| cursor miss | 全量补发(同 4b) |
|
||||
| direct chat session | 仍走 `sendDirectChatSessionEvents`,不经本路径 |
|
||||
|
||||
## 验证(全量开发完成后)
|
||||
|
||||
```bash
|
||||
npm run verify:h5-session-patches
|
||||
```
|
||||
|
||||
手工:
|
||||
|
||||
1. `.env` 加 `MEMIND_SESSION_STREAM_REPLAY=1`,重启 `pnpm dev`
|
||||
2. agent 路径发消息,DevTools 看 `/sessions/:id/events` 含 `id:` 行
|
||||
3. 流式过程中断网/刷新,确认重连后 token/Finish 不丢
|
||||
|
||||
## 与 4b 关系
|
||||
|
||||
- **4b**:`GET /agent/runs/:id/events` + `h5_agent_run_events`
|
||||
- **4c**:`GET /sessions/:id/events` + `h5_session_stream_events`
|
||||
- 双通道职责仍分离(§1.3)
|
||||
Reference in New Issue
Block a user