diff --git a/cp-webapp/src/components/chat/index.tsx b/cp-webapp/src/components/chat/index.tsx index 5049e58..9f4bbc9 100644 --- a/cp-webapp/src/components/chat/index.tsx +++ b/cp-webapp/src/components/chat/index.tsx @@ -230,54 +230,75 @@ const ChatView = ({ disabled, messages, isStreaming, sendMessage, stop }: ChatVi )} {/* Render all messages directly */} - {messages.map((message, index) => ( -
- {isAssistantMessage(message) ? ( - - ) : ( - - )} -
- ))} + {messages.map((message, index) => { + const isLastMessage = index === messages.length - 1; + const isLastAssistantMessage = isLastMessage && isAssistantMessage(message); + + // Skip rendering the last assistant message if it's empty AND the stream was canceled + // (The dedicated "canceled" bubble below will handle showing the message) + if (isLastAssistantMessage && !message.content && wasCanceled) { + return null; + } + + return ( +
+ {isAssistantMessage(message) ? ( + + ) : ( + + )} +
+ ); + })} {/* Show streaming indicator or canceled message when appropriate */} - {(isStreaming || wasCanceled) && - // Only show the streaming/canceled bubble if: - // 1. There are no messages, OR - // 2. The last message is not from assistant, OR - // 3. The last message is from assistant but has no content - // 4. AND we're not currently streaming to the last message (which would mean it already exists) - (!messages.length || - messages[messages.length - 1].role !== 'assistant' || - !messages[messages.length - 1].content) && - !( - isStreaming && - messages.length && - messages[messages.length - 1].role === 'assistant' - ) && ( + {/* Show canceled message bubble ONLY if needed */} + {(() => { + // Show canceled message if: + // 1. Stream was canceled (`wasCanceled` is true) + // 2. AND EITHER: + // a) There are no messages OR + // b) The last message is not an assistant message OR + // c) The last message IS an assistant message BUT it has no content + // (This covers the case where the map loop returned null for the empty canceled bubble) + const showCanceledMessage = + wasCanceled && + (!messages.length || + messages[messages.length - 1].role !== 'assistant' || + !messages[messages.length - 1].content); + + // If condition not met, no extra bubble needed + if (!showCanceledMessage) { + return null; + } + + // Render the "Stream canceled" bubble + return (
- )} + ); + })()}