diff --git a/apps/web/src/components/chat/ChatSlideOver.tsx b/apps/web/src/components/chat/ChatSlideOver.tsx index 89a18e5..7d8bae4 100644 --- a/apps/web/src/components/chat/ChatSlideOver.tsx +++ b/apps/web/src/components/chat/ChatSlideOver.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef } from 'react'; import { motion, AnimatePresence } from 'motion/react'; -import { X, Loader2 } from 'lucide-react'; +import { X, Loader2, AlertTriangle, RotateCcw } from 'lucide-react'; +import { Button } from '@/components/ui/button'; import { useChatSession } from '@/hooks/useChatSession'; import { ChatBubble } from './ChatBubble'; import { ChatInput } from './ChatInput'; @@ -41,7 +42,7 @@ function ChatSlideOverInner({ initiativeId: string; onClose: () => void; }) { - const { messages, agentStatus, sendMessage, closeSession, isSending } = + const { messages, agentStatus, agentError, sendMessage, closeSession, isSending } = useChatSession(target.type, target.id, initiativeId); const scrollRef = useRef(null); @@ -130,6 +131,32 @@ function ChatSlideOverInner({ )} + {agentStatus === 'crashed' && agentError && ( +
+
+ +
+

Agent error

+

{agentError}

+
+
+
+ +
+
+ )} {/* Input */} diff --git a/apps/web/src/hooks/useChatSession.ts b/apps/web/src/hooks/useChatSession.ts index ab07704..2ac18c7 100644 --- a/apps/web/src/hooks/useChatSession.ts +++ b/apps/web/src/hooks/useChatSession.ts @@ -3,7 +3,7 @@ import { toast } from 'sonner'; import { trpc } from '@/lib/trpc'; import { useLiveUpdates } from './useLiveUpdates'; -export type ChatAgentStatus = 'idle' | 'running' | 'waiting' | 'none'; +export type ChatAgentStatus = 'idle' | 'running' | 'waiting' | 'crashed' | 'none'; export interface ChatMessage { id: string; @@ -28,6 +28,7 @@ export interface UseChatSessionResult { session: ChatSession | null; messages: ChatMessage[]; agentStatus: ChatAgentStatus; + agentError: string | null; sendMessage: (message: string) => void; closeSession: () => void; isSending: boolean; @@ -88,11 +89,26 @@ export function useChatSession( return 'waiting'; case 'idle': return 'idle'; + case 'crashed': + return 'crashed'; default: return 'none'; } }, [session?.agentId, agentQuery.data]); + // Extract error message when agent crashed + const agentError = useMemo(() => { + if (agentStatus !== 'crashed' || !agentQuery.data) return null; + const result = (agentQuery.data as { result?: string }).result; + if (!result) return 'Agent crashed unexpectedly'; + try { + const parsed = JSON.parse(result); + return parsed.message ?? result; + } catch { + return result; + } + }, [agentStatus, agentQuery.data]); + // Send message mutation const sendMutation = trpc.sendChatMessage.useMutation({ onSuccess: () => { @@ -161,6 +177,7 @@ export function useChatSession( session, messages, agentStatus, + agentError, sendMessage, closeSession, isSending,