diff --git a/desktop/src/components/ChatArea.tsx b/desktop/src/components/ChatArea.tsx
index 0909afc..da20cec 100644
--- a/desktop/src/components/ChatArea.tsx
+++ b/desktop/src/components/ChatArea.tsx
@@ -231,6 +231,18 @@ export function ChatArea({ compact, onOpenDetail }: { compact?: boolean; onOpenD
setPendingFiles([]);
};
+ const createRetryHandler = (msgId: string) => () => {
+ if (isStreaming) return;
+ // Find the user message immediately before this error
+ const idx = messages.findIndex(m => m.id === msgId);
+ if (idx > 0) {
+ const prevMsg = messages[idx - 1];
+ if (prevMsg.role === 'user' && prevMsg.content) {
+ sendToGateway(prevMsg.content);
+ }
+ }
+ };
+
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
@@ -433,6 +445,16 @@ export function ChatArea({ compact, onOpenDetail }: { compact?: boolean; onOpenD
onHeightChange={setHeight}
messageRefs={messageRefs}
setInput={setInput}
+ retryForMessage={(msgId: string) => {
+ const idx = messages.findIndex(m => m.id === msgId);
+ if (idx > 0) {
+ const prevMsg = messages[idx - 1];
+ if (prevMsg.role === 'user' && prevMsg.content) {
+ return () => { if (!isStreaming) sendToGateway(prevMsg.content); };
+ }
+ }
+ return undefined;
+ }}
/>
) : (
messages.map((message) => (
@@ -445,7 +467,7 @@ export function ChatArea({ compact, onOpenDetail }: { compact?: boolean; onOpenD
layout
transition={defaultTransition}
>
-
+
))
)}
@@ -575,7 +597,7 @@ export function ChatArea({ compact, onOpenDetail }: { compact?: boolean; onOpenD
);
}
-function MessageBubble({ message, setInput, onRetry }: { message: Message; setInput: (text: string) => void; onRetry?: () => void }) {
+function MessageBubble({ message, onRetry }: { message: Message; setInput?: (text: string) => void; onRetry?: () => void }) {
if (message.role === 'tool') {
return null;
}
@@ -679,17 +701,14 @@ function MessageBubble({ message, setInput, onRetry }: { message: Message; setIn
{message.error && (
{message.error}
-
+ {onRetry && (
+
+ )}
)}
{/* Download button for AI messages - show on hover */}
@@ -716,6 +735,7 @@ interface VirtualizedMessageRowProps {
onHeightChange: (height: number) => void;
messageRefs: MutableRefObject