zcbot/web/templates
caoqianming 7356d25652 core(§7 Phase G G4): chat 发送 + SSE 流式回复
- web/broker.py RunBroker:in-process pub/sub,subscribe/emit/close/
  unsubscribe;同 run_id 多订阅者 fan-out(刷新 / 多 tab / 桌面+移动
  都能同时看流);_done 集合让晚到订阅者立刻收 done(不挂)。
- web/sinks.py WebEventSink:实现 §7 A sink 协议,把 AgentLoop._emit
  桥到 broker.emit(run_id, ev),AgentLoop 完全不知 web 存在。
- 异步策略 = asyncio.to_thread(不改 core):POST /tasks/{tid}/messages
  async handler → INSERT runs 行 + asyncio.create_task(to_thread(
  _run_agent_bg)),_run_agent_bg 工作线程跑 build_agent + agent.run,
  sink 通过 loop.call_soon_threadsafe 跨线程把 event 桥回 asyncio queue。
- GET /tasks/{tid}/runs/{rid}/events:StreamingResponse async gen,
  响应头 text/event-stream + Cache-Control: no-cache + X-Accel-
  Buffering: no(nginx 反代友好);第一帧 retry/connected 让 ES 立
  即建立,30s 无 event 发 : ping 心跳。SSE multi-line data 每行加
  data: 前缀(SSE spec),客户端 ES 自动还原 \n 拼接的 HTML。
- _render_event_fragment 渲染 text/tool_call/tool_result/error
  HTML 片段;run_start/llm_start/llm_end/done 发空 data(只让客户端
  识别 event type)。
- 新模板:_frag_text/_frag_tool_call/_frag_tool_result/_frag_error +
  _send_response(POST 响应:user msg 卡 + msg-assistant streaming
  容器带 sse-connect/sse-swap/sse-close)。
- chat.html 加 send 表单(Enter 发,Shift+Enter 换行,HTMX hx-post /
  hx-target=#chat-stream / hx-swap=beforeend / 提交后 reset);chat
  section 改 id=chat-stream;非 active task 隐藏表单。
- CSS:.streaming .run-indicator 红点脉冲 / .send-form 输入框 /
  .tool-result-inline 追加式样式 / .msg-error 错误卡。
- runs 表写状态:POST 时 status=running,正常完结 ok + tokens_p/c,
  异常 error + error 文本(DB 写失败不放大噪声,已 emit error 给前端)。
- lifespan bind_loop(asyncio.get_running_loop()) 让 broker 拿到
  loop 引用,emit 跨线程才能 call_soon_threadsafe。
- RUN 故障兜底加 3 条:SSE 经 nginx 卡住、浏览器 send 无反应、并发
  POST messages idx 冲突(已知 TODO)。

Smoke 双层全绿:
- broker 单元 8 case (subscribe/emit/get/fan-out/跨 run 隔离/close/
  late subscribe instant done/unsubscribe/未 bind silent drop)
- 端到端 24 case (POST 200 + sse-connect/run_id 抽取 + content-type/
  x-accel-buffering/cache-control 头对 + event 序列 run_start→done
  + text 片段 <strong> + tool_call <details> + tool_result preview
  + empty body 400 + 各种 404 + late done + runs 行 INSERT)

版本 0.3 → 0.4。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:19:25 +08:00
..
_frag_error.html core(§7 Phase G G4): chat 发送 + SSE 流式回复 2026-05-15 09:19:25 +08:00
_frag_text.html core(§7 Phase G G4): chat 发送 + SSE 流式回复 2026-05-15 09:19:25 +08:00
_frag_tool_call.html core(§7 Phase G G4): chat 发送 + SSE 流式回复 2026-05-15 09:19:25 +08:00
_frag_tool_result.html core(§7 Phase G G4): chat 发送 + SSE 流式回复 2026-05-15 09:19:25 +08:00
_send_response.html core(§7 Phase G G4): chat 发送 + SSE 流式回复 2026-05-15 09:19:25 +08:00
base.html core(§7 Phase G G1): Web UI 脚手架 + cli.py web 子命令 2026-05-14 13:37:54 +08:00
chat.html core(§7 Phase G G4): chat 发送 + SSE 流式回复 2026-05-15 09:19:25 +08:00
home.html core(§7 Phase G G2): task list 页 + /tasks/{id} 占位 2026-05-14 15:52:11 +08:00