fix(rectification): make every gap a live row with retries, give an empty Case a start, and say why a run stopped
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
This commit is contained in:
@@ -133,8 +133,12 @@ test("one assistant article owns the stem and options; the slot class is gone",
|
||||
assert.doesNotMatch(chat, /rectification-question-slot/);
|
||||
assert.doesNotMatch(chat, /composeCollectSpokenAssistantText/);
|
||||
assert.match(chat, /role="status"/);
|
||||
assert.match(chat, /当前没有可回答的问题,正在等待服务端更新/);
|
||||
assert.match(chat, /题目加载失败,请刷新/);
|
||||
// Was: /当前没有可回答的问题,正在等待服务端更新/ and /题目加载失败,请刷新/ — bare copy
|
||||
// that told the reader to wait for the server with nothing happening. The gap is
|
||||
// now a live timeline row with timed refetches, then copy and a reload (BUG-505).
|
||||
assert.doesNotMatch(chat, /等待服务端更新|题目加载失败,请刷新/);
|
||||
assert.match(chat, /RECTIFICATION_QUESTION_PREPARING_LABEL/);
|
||||
assert.match(chat, /RECTIFICATION_QUESTION_UNAVAILABLE_COPY/);
|
||||
assert.match(chat, /question_source/);
|
||||
});
|
||||
|
||||
|
||||
@@ -144,12 +144,17 @@ test("collect_spoken stem lives on turn.question inside the same assistant artic
|
||||
|
||||
test("missing current_question is explicit only for resumable cases", () => {
|
||||
const chat = readFileSync(new URL("../src/components/rectification-agentic-chat.tsx", import.meta.url), "utf8");
|
||||
assert.match(chat, /const showMissingQuestion = Boolean\([\s\S]*caseSnapshotLoaded[\s\S]*resumableCase[\s\S]*currentQuestion === null/);
|
||||
// Was: `const showMissingQuestion = Boolean(... caseSnapshotLoaded ... resumableCase ...
|
||||
// currentQuestion === null` plus the copy /当前没有可回答的问题,正在等待服务端更新/ and
|
||||
// /题目加载失败,请刷新/. Those were bare waiting sentences; the same inputs now feed
|
||||
// `rectificationQuestionGapState`, which yields a live row with retries and then a
|
||||
// reload button, and is still gated on a resumable case (BUG-505).
|
||||
assert.match(chat, /const questionGap = rectificationQuestionGapState\(\{[\s\S]*questionMissing: currentQuestion === null,[\s\S]*snapshotLoaded: caseSnapshotLoaded,[\s\S]*resumableCase,/);
|
||||
assert.match(chat, /const resumableCase = caseStatus !== null && isResumableStatus\(caseStatus\)/);
|
||||
assert.match(chat, /当前没有可回答的问题,正在等待服务端更新/);
|
||||
assert.match(chat, /题目加载失败,请刷新/);
|
||||
assert.doesNotMatch(chat, /等待服务端更新|题目加载失败,请刷新/);
|
||||
assert.match(chat, /RECTIFICATION_QUESTION_UNAVAILABLE_COPY/);
|
||||
assert.match(chat, /readonly && \(/);
|
||||
assert.doesNotMatch(chat, /showMissingQuestion[\s\S]*caseStatus.*TERMINAL/);
|
||||
assert.doesNotMatch(chat, /questionGap[\s\S]*caseStatus.*TERMINAL/);
|
||||
});
|
||||
|
||||
test("choice options render inside the same assistant message, not a sibling slot", () => {
|
||||
|
||||
Reference in New Issue
Block a user