import React from 'react'; import { Box, Typography, Button, Divider, Alert, Paper } from '@mui/material'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; import StopCircleIcon from '@mui/icons-material/StopCircle'; import HourglassEmptyIcon from '@mui/icons-material/HourglassEmpty'; import AddIcon from '@mui/icons-material/Add'; import SmartToyIcon from '@mui/icons-material/SmartToy'; import AssignmentIcon from '@mui/icons-material/Assignment'; import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import InputIcon from '@mui/icons-material/Input'; import OutputIcon from '@mui/icons-material/Output'; import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; import { FinalStep, AgentTrace, AgentStep } from '@/types/agent'; import { DownloadGifButton } from './DownloadGifButton'; import { DownloadJsonButton } from './DownloadJsonButton'; interface CompletionViewProps { finalStep: FinalStep; trace?: AgentTrace; steps?: AgentStep[]; finalAnswer?: string | null; isGenerating: boolean; gifError: string | null; onGenerateGif: () => void; onDownloadJson: () => void; onBackToHome: () => void; } /** * Component displaying the completion status (success or failure) of a task */ export const CompletionView: React.FC = ({ finalStep, trace, steps, finalAnswer, isGenerating, gifError, onGenerateGif, onDownloadJson, onBackToHome, }) => { const getStatusConfig = () => { switch (finalStep.type) { case 'success': return { icon: , title: 'Task Completed Successfully!', color: 'success.main', }; case 'stopped': return { icon: , title: 'Task Stopped', color: 'warning.main', }; case 'max_steps_reached': return { icon: , title: 'Maximum Steps Reached', color: 'warning.main', }; case 'sandbox_timeout': return { icon: , title: 'Sandbox Timeout', color: 'error.main', }; case 'failure': default: return { icon: , title: 'Task Failed', color: 'error.main', }; } }; const statusConfig = getStatusConfig(); // Format model name for display const formatModelName = (modelId: string) => { const parts = modelId.split('/'); return parts.length > 1 ? parts[1] : modelId; }; return ( {/* Status Header - Compact */} { const rgba = finalStep.type === 'success' ? '102, 187, 106' : (finalStep.type === 'failure' || finalStep.type === 'sandbox_timeout') ? '244, 67, 54' : '255, 152, 0'; return `0 2px 8px ${theme.palette.mode === 'dark' ? `rgba(${rgba}, 0.3)` : `rgba(${rgba}, 0.2)`}`; }, }} > {React.cloneElement(statusConfig.icon, { sx: { fontSize: 24, color: 'white' } })} {statusConfig.title} {/* Single Report Box - Task + Agent + Response + Metrics */} theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.03)', borderRadius: 1.5, border: '1px solid', borderColor: 'divider', }} > {/* Task */} {trace?.instruction && ( Task {trace.instruction} )} {/* Agent Response */} {finalAnswer && ( Agent Response {finalAnswer} )} {/* Divider before metrics */} {/* Metrics */} {/* Agent */} {trace?.modelId && ( <> {formatModelName(trace.modelId)} {/* Divider */} )} {/* Steps Count */} {finalStep.metadata.numberOfSteps} {finalStep.metadata.numberOfSteps === 1 ? 'Step' : 'Steps'} {/* Divider */} {/* Duration */} {finalStep.metadata.duration.toFixed(1)}s {/* Divider */} {/* Input Tokens */} {finalStep.metadata.inputTokensUsed.toLocaleString()} {/* Divider */} {/* Output Tokens */} {finalStep.metadata.outputTokensUsed.toLocaleString()} {/* GIF Error Alert */} {gifError && ( {gifError} )} {/* Action Buttons */} {/* Download buttons */} {/* New Task button - larger and below */} ); };