Saying no to a spoken collect left the next stem only on current_question, so the preparing spinner never cleared. Persist the ack, link asked_turn_id, and emit run.completed with turnId (BUG-525).
Co-authored-by: Cursor <cursoragent@cursor.com>
The chat used to show "当前没有可回答的问题,正在等待服务端更新" / "当前问题暂时无法显示"
/ "题目加载失败,请刷新" as bare copy above the composer. The gap between a
settled turn and its next question is now a state: `preparing` renders the
same timeline live row the reply uses ("正在准备下一个问题…") and refetches the
Case on a 2s timer up to two retries; `unavailable` renders one line and a
44px reload button. A snapshot that never arrived at hydration is the same
gap. A resumed Case with no turns and no server-started opening shows
"这段校正还没有开始。" with one 开始提问 action. Stopping a run keeps what
streamed and says so instead of "暂时不可用"; the opening turn's live row
names what is happening; a 402 explains itself for 600ms before leaving.
BUG-505, BUG-507
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
Agent set-focus was writing or dropping choice schema, so probes never scored. Force server-owned options, fail closed when focus list RPC errors, and require the probe year in spokenPrompt.
Co-authored-by: Cursor <cursoragent@cursor.com>
Focuses now carry asked_turn_id so GET rebuilds stem and options on the
same turn. Agent writes spokenPrompt; the live question slot is gone.
Co-authored-by: Cursor <cursoragent@cursor.com>