Skip to content

阶段 5 F2:SSE、事件渲染、停止、👍👎、gen_ui_types - #35

Merged
Smilewithoutfalling merged 40 commits into
masterfrom
f2
Oct 16, 2026
Merged

Smilewithoutfalling merged 40 commits into
masterfrom
f2

Conversation

@Smilewithoutfalling

Copy link
Copy Markdown
Owner

阶段 5 F2:SSE、事件渲染、重放合成 done、停止(cancel)、👍👎、gen_ui_types。详见 DEVLOG [34]。

后端

  • analyze_stream(cancel=threading.Event):每个事件产出前检查(answer 也是检查点),done 前再查一次;取消 → fatal error + done,error_kind="cancelled",文案恒为 CANCELLED_MESSAGE。
  • POST /messages/{id}/cancel:CAS running → cancelled,已结束 409,用户消息 400。stream() finally 用 WHERE status='running' 的 CAS 收尾。
  • done_seen:流中途异常且没有 done → status=error + STREAM_ABORTED_MESSAGE,异常详情只进日志。SSE 客户端断开 → status=interrupted + DISCONNECTED_MESSAGE;重启清理 → interrupted + INTERRUPTED_MESSAGE。cancelled 只代表用户点停止。
  • ERROR_KINDS、MESSAGE_STATUSES、固定文案集中定义;scripts/gen_ui_types.py 生成 ui/web/src/generated/{events,banned_keys}.json,CI 跑 --check。
  • AST 约束测试:只有 service.py 写 error_kind(评测 ground_truth 白名单);service 的 kind 恰为 ERROR_KINDS - {interrupted};app/ 写入的 status 字面量 ⊆ MESSAGE_STATUSES 且全覆盖。

前端

  • sse.ts 自写 SSE 解析(任意字节切 chunk 测试);turn.ts 唯一 reducer,重放合成 done(seq = max+1),settle() 以库里 status 收尾,outcome() 只按 status / error_kind 分支。
  • 事件渲染(plan、code/exec 折叠、可恢复 error、markdown 结论、终止原因、警告);停止:先 await cancel,再等流自然结束;interrupted 重试;👍👎 + 补充说明。
  • react-markdown 10.1.0 + remark-gfm 4.0.1(精确版本,测试钉住),不开 raw HTML,过滤 javascript:,链接 noreferrer noopener。

已知取舍:晚到的取消

answer 发出之后、done 之前到达的取消算取消:answer 事件可能已到前端,但最终 status=cancelled、result_json 为空。前端当场保留气泡并标"已取消(未保存)",刷新后不显示,不回写答案。

未做

  • messages 表无 error_kind 列(落库后 dataset/llm/agent/execution/stream_aborted 都是 status=error),不在 F2 改 schema。
  • 错误文案脱敏(THREAT_MODEL T10)单独 PR。
  • 停止的 Playwright 端到端与实测停止耗时,随 F3 假模型服务。

验证

pytest 613 passed;vitest 37;Playwright 7;tsc / lint / build(0 内联 script)/ gen_ui_types --check 通过。

@Smilewithoutfalling
Smilewithoutfalling merged commit 50e9add into master Oct 16, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant