feat(tui): improve message error handling and display states

tui-experimental-design
Dax Raad 2026-03-21 20:22:09 -04:00
parent ad110878c9
commit b892d91bae
1 changed files with 24 additions and 23 deletions

View File

@ -1336,6 +1336,7 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
const messages = createMemo(() => sync.data.message[props.message.sessionID] ?? []) const messages = createMemo(() => sync.data.message[props.message.sessionID] ?? [])
const final = createMemo(() => { const final = createMemo(() => {
if (props.message.error) return true
return props.message.finish && !["tool-calls", "unknown"].includes(props.message.finish) return props.message.finish && !["tool-calls", "unknown"].includes(props.message.finish)
}) })
@ -1347,6 +1348,8 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
return props.message.time.completed - user.time.created return props.message.time.completed - user.time.created
}) })
const interrupted = createMemo(() => props.message.error?.name === "MessageAbortedError")
const keybind = useKeybind() const keybind = useKeybind()
return ( return (
@ -1374,7 +1377,7 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
</text> </text>
</box> </box>
</Show> </Show>
<Show when={props.message.error && props.message.error.name !== "MessageAbortedError"}> <Show when={props.message.error && !interrupted()}>
<box <box
border={["left"]} border={["left"]}
paddingTop={1} paddingTop={1}
@ -1389,28 +1392,26 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
</box> </box>
</Show> </Show>
<Switch> <Switch>
<Match when={props.last || final() || props.message.error?.name === "MessageAbortedError"}> <Match when={props.last || final()}>
<box paddingLeft={2}> <box paddingLeft={2} marginTop={1}>
<text marginTop={1}> <Show when={!duration()}>
<span <Spinner color={local.agent.color(props.message.agent)}>
style={{ <span style={{ fg: theme.text }}>{Locale.titlecase(props.message.mode)}</span>
fg: <span style={{ fg: theme.textMuted }}> · {props.message.modelID}</span>
props.message.error?.name === "MessageAbortedError" </Spinner>
? theme.textMuted </Show>
: local.agent.color(props.message.agent), <Show when={duration()}>
}} <text fg={interrupted() ? theme.textMuted : theme.text}>
> <span style={{ fg: theme.text }}>{Locale.titlecase(props.message.mode)}</span>
{" "} <span style={{ fg: theme.textMuted }}> · {props.message.modelID}</span>
</span>{" "} <Show when={!interrupted()}>
<span style={{ fg: theme.text }}>{Locale.titlecase(props.message.mode)}</span> <span style={{ fg: theme.textMuted }}> · {Locale.duration(duration())}</span>
<span style={{ fg: theme.textMuted }}> · {props.message.modelID}</span> </Show>
<Show when={duration()}> <Show when={interrupted()}>
<span style={{ fg: theme.textMuted }}> · {Locale.duration(duration())}</span> <span style={{ fg: theme.textMuted }}> · interrupted</span>
</Show> </Show>
<Show when={props.message.error?.name === "MessageAbortedError"}> </text>
<span style={{ fg: theme.textMuted }}> · interrupted</span> </Show>
</Show>
</text>
</box> </box>
</Match> </Match>
</Switch> </Switch>