/* What the reader sees when a turn does not happen. * * `BROWSER-UX-SPEC.md` §17, §71, §72 and §12 of the M8 brief. Three things this * has to get right, all of which the inherited toast got wrong: * * 1. **Say which failure it was.** The toast showed one line of the server's * message with a Retry button beside it, so "Ollama isn't running" and * "the model returned nothing" looked identical and read as equally * hopeless. `errors.js` sorts them into §71's five kinds and each carries * the thing to do about it. * 2. **Do not lose what was typed.** A05 requires the player's submitted * input to survive a failed generation. The composer keeps the text and * this says so out loud, because a reader who cannot see their sentence * assumes it is gone and retypes it. * 3. **Do not present partial prose as story.** Whatever streamed before the * failure is dropped from the transcript by the caller; if any arrived, it * is shown here, clearly labelled as not part of the story. * * Technical detail is present but folded away (§72), because the reader who * needs the raw message is not the reader who needs the first sentence. */ import { Link } from 'react-router-dom' import { KIND } from '../../errors' const ICON = { [KIND.MODEL]: '⚠', [KIND.GENERATION]: '↻', [KIND.STATE]: '◆', [KIND.KNOWLEDGE]: '❋', [KIND.SERVER]: '⚠', } export function FailureNotice({ failure, partial, onRetry, onDismiss }) { if (!failure) return null return (
{failure.title}
{failure.hint &&

{failure.hint}

}

Your story is unchanged, and what you typed is still in the box below.

{partial ? (
The narrator had begun writing — this was not kept
{partial}
) : null}
Show technical details
{failure.detail}
{failure.retryable && ( )} {failure.action && ( {failure.action.label} )}
) }