2.4 KiB
2.4 KiB
创作 Agent 流式失败保留可见回复修复 2026-05-05
1. 问题
方洞挑战等轻量玩法复用 usePlatformCreationAgentFlowController 与 creationAgentSse.ts 消费 reply_delta / session / error。当上游 LLM 已经返回部分 replyText,但后续因为超时、上游断流、SSE 解析或最终 JSON 解析失败而发送 error 事件时,前端会在 finally 里退出流式态。
旧 UI 只在 isStreamingReply=true 时展示临时 assistant 气泡,因此用户会先看到一段回答,然后回答突然消失,只剩错误提示。
2. 目标
- 已经展示给用户的流式回复不能因为最终失败从聊天区消失。
- SSE
error仍然终止本轮提交,并保留错误提示。 - 后端错误不能只压成
上游服务请求失败,应优先把 LLM 流错误原因放到业务message。 - 不修改 SpacetimeDB schema、消息表结构或玩法运行规则。
3. 前端契约
readCreationAgentSessionFromSse() 在收到 reply_delta 后再收到 error 时,必须先触发 onUpdate(text),再抛出错误。调用方可以从最近一次可见文本中恢复 UI。
usePlatformCreationAgentFlowController.submitMessage() 的失败收尾规则:
- 提交时仍先追加 optimistic user message。
- 每次
onUpdate同步更新streamingReplyText与最近可见回复引用。 - 如果
streamMessage()抛错且最近可见回复非空,把该文本追加为本地 assistantwarning消息。 - 再设置
error,最后关闭isStreamingReply。 - 成功拿到最终 session 时,以后端 session snapshot 为准,并清空最近可见回复。
这条本地 warning 消息只用于失败态 UI 保留,不代表该 assistant 消息已经写入 SpacetimeDB。
4. 后端契约
creation_agent_llm_turn 在 LlmClient::stream_text() 失败时,返回:
<玩法 generation_failed 文案>:<LlmError Display>
同时写 warn 日志,便于结合 logs/llm-raw 定位上游原始输入输出。
方洞挑战 SSE 错误提取优先级:
error.details.messageerror.message- 其它嵌套 JSON message
- 原始 body 文本
- 状态码兜底
5. 验收
reply_delta后收到error时,测试应断言onUpdate已经收到可见文本。- 控制器测试应断言失败后本地消息列表包含 user 消息和 assistant warning 消息。
cargo check -p api-server通过。npm run typecheck与编码检查通过。