Files
Genarrative/docs/technical/CREATION_AGENT_STREAM_FAILURE_RETENTION_FIX_2026-05-05.md
kdletters 995661e7cc
Some checks failed
CI / verify (push) Has been cancelled
Preserve partial creation replies on stream failure
2026-05-05 11:31:50 +08:00

2.4 KiB
Raw Permalink Blame History

创作 Agent 流式失败保留可见回复修复 2026-05-05

1. 问题

方洞挑战等轻量玩法复用 usePlatformCreationAgentFlowControllercreationAgentSse.ts 消费 reply_delta / session / error。当上游 LLM 已经返回部分 replyText但后续因为超时、上游断流、SSE 解析或最终 JSON 解析失败而发送 error 事件时,前端会在 finally 里退出流式态。

旧 UI 只在 isStreamingReply=true 时展示临时 assistant 气泡,因此用户会先看到一段回答,然后回答突然消失,只剩错误提示。

2. 目标

  1. 已经展示给用户的流式回复不能因为最终失败从聊天区消失。
  2. SSE error 仍然终止本轮提交,并保留错误提示。
  3. 后端错误不能只压成 上游服务请求失败,应优先把 LLM 流错误原因放到业务 message
  4. 不修改 SpacetimeDB schema、消息表结构或玩法运行规则。

3. 前端契约

readCreationAgentSessionFromSse() 在收到 reply_delta 后再收到 error 时,必须先触发 onUpdate(text),再抛出错误。调用方可以从最近一次可见文本中恢复 UI。

usePlatformCreationAgentFlowController.submitMessage() 的失败收尾规则:

  1. 提交时仍先追加 optimistic user message。
  2. 每次 onUpdate 同步更新 streamingReplyText 与最近可见回复引用。
  3. 如果 streamMessage() 抛错且最近可见回复非空,把该文本追加为本地 assistant warning 消息。
  4. 再设置 error,最后关闭 isStreamingReply
  5. 成功拿到最终 session 时,以后端 session snapshot 为准,并清空最近可见回复。

这条本地 warning 消息只用于失败态 UI 保留,不代表该 assistant 消息已经写入 SpacetimeDB。

4. 后端契约

creation_agent_llm_turnLlmClient::stream_text() 失败时,返回:

<玩法 generation_failed 文案><LlmError Display>

同时写 warn 日志,便于结合 logs/llm-raw 定位上游原始输入输出。

方洞挑战 SSE 错误提取优先级:

  1. error.details.message
  2. error.message
  3. 其它嵌套 JSON message
  4. 原始 body 文本
  5. 状态码兜底

5. 验收

  1. reply_delta 后收到 error 时,测试应断言 onUpdate 已经收到可见文本。
  2. 控制器测试应断言失败后本地消息列表包含 user 消息和 assistant warning 消息。
  3. cargo check -p api-server 通过。
  4. npm run typecheck 与编码检查通过。