fix(chat): display error messages for failed assistant messages
This commit is contained in:
@@ -526,6 +526,26 @@ const ChatMessage: React.FC<ChatMessageProps> = ({
|
||||
}
|
||||
const assistantSummaryForCopy = assistantSummaryRef.current;
|
||||
|
||||
const assistantErrorText = React.useMemo(() => {
|
||||
if (isUser) {
|
||||
return undefined;
|
||||
}
|
||||
const errorInfo = (message.info as { error?: unknown } | undefined)?.error as
|
||||
| { data?: { message?: unknown }; message?: unknown; name?: unknown }
|
||||
| undefined;
|
||||
if (!errorInfo) {
|
||||
return undefined;
|
||||
}
|
||||
const dataMessage = typeof errorInfo.data?.message === 'string' ? errorInfo.data.message : undefined;
|
||||
const errorMessage = typeof errorInfo.message === 'string' ? errorInfo.message : undefined;
|
||||
const errorName = typeof errorInfo.name === 'string' ? errorInfo.name : undefined;
|
||||
const detail = dataMessage || errorMessage || errorName;
|
||||
if (!detail) {
|
||||
return undefined;
|
||||
}
|
||||
return `Opencode failed to send message with error:\n\`${detail}\``;
|
||||
}, [isUser, message.info]);
|
||||
|
||||
const messageTextContent = React.useMemo(() => {
|
||||
if (isUser) {
|
||||
const textParts = displayParts
|
||||
@@ -540,12 +560,16 @@ const ChatMessage: React.FC<ChatMessageProps> = ({
|
||||
return combined.replace(/\n\s*\n+/g, '\n');
|
||||
}
|
||||
|
||||
if (assistantErrorText && assistantErrorText.trim().length > 0) {
|
||||
return assistantErrorText;
|
||||
}
|
||||
|
||||
if (assistantSummaryForCopy && assistantSummaryForCopy.trim().length > 0) {
|
||||
return assistantSummaryForCopy;
|
||||
}
|
||||
|
||||
return flattenAssistantTextParts(displayParts);
|
||||
}, [assistantSummaryForCopy, displayParts, isUser]);
|
||||
}, [assistantErrorText, assistantSummaryForCopy, displayParts, isUser]);
|
||||
|
||||
const hasTextContent = messageTextContent.length > 0;
|
||||
|
||||
@@ -767,6 +791,7 @@ const ChatMessage: React.FC<ChatMessageProps> = ({
|
||||
agentMention={agentMention}
|
||||
onRevert={handleRevert}
|
||||
isFirstMessage={isFirstMessage}
|
||||
errorMessage={assistantErrorText}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -808,6 +833,7 @@ const ChatMessage: React.FC<ChatMessageProps> = ({
|
||||
showReasoningTraces={showReasoningTraces}
|
||||
agentMention={agentMention}
|
||||
turnGroupingContext={turnGroupingContext}
|
||||
errorMessage={assistantErrorText}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -130,6 +130,7 @@ interface MessageBodyProps {
|
||||
turnGroupingContext?: TurnGroupingContext;
|
||||
onRevert?: () => void;
|
||||
isFirstMessage?: boolean;
|
||||
errorMessage?: string;
|
||||
}
|
||||
|
||||
const UserMessageBody: React.FC<{
|
||||
@@ -318,6 +319,7 @@ const AssistantMessageBody: React.FC<Omit<MessageBodyProps, 'isUser'>> = ({
|
||||
onAuxiliaryContentComplete,
|
||||
showReasoningTraces = false,
|
||||
turnGroupingContext,
|
||||
errorMessage,
|
||||
}) => {
|
||||
|
||||
void _streamPhase;
|
||||
@@ -1051,7 +1053,9 @@ const AssistantMessageBody: React.FC<Omit<MessageBodyProps, 'isUser'>> = ({
|
||||
summaryBody &&
|
||||
summaryBody.trim().length > 0;
|
||||
|
||||
const shouldShowFooter = hasTextContent && assistantTextParts.length > 0 && hasStopFinish && isLastAssistantInTurn;
|
||||
const showErrorMessage = Boolean(errorMessage);
|
||||
|
||||
const shouldShowFooter = isLastAssistantInTurn && hasTextContent && (hasStopFinish || Boolean(errorMessage));
|
||||
const [isSummaryHovered, setIsSummaryHovered] = React.useState(false);
|
||||
|
||||
const footerButtons = (
|
||||
@@ -1131,6 +1135,13 @@ const AssistantMessageBody: React.FC<Omit<MessageBodyProps, 'isUser'>> = ({
|
||||
className="leading-normal overflow-hidden text-foreground/90 [&_p:last-child]:mb-0 [&_ul:last-child]:mb-0 [&_ol:last-child]:mb-0"
|
||||
>
|
||||
{renderedParts}
|
||||
{showErrorMessage && (
|
||||
<FadeInOnReveal key="assistant-error">
|
||||
<div className="group/assistant-text relative break-words">
|
||||
<SimpleMarkdownRenderer content={errorMessage ?? ''} />
|
||||
</div>
|
||||
</FadeInOnReveal>
|
||||
)}
|
||||
{showSummaryBody && (
|
||||
<FadeInOnReveal key="summary-body">
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user