diff --git a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx index 045a1f10db7..aac92e98c12 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard/HealthCheckComponent.tsx @@ -14,9 +14,11 @@ import { Table as TableInstance } from '@tanstack/react-table'; interface HealthStatus { status: string; lastCheck: string; + lastSuccess?: string; loading: boolean; error?: string; fullError?: string; + successResponse?: any; } interface HealthCheckComponentProps { @@ -43,6 +45,11 @@ const HealthCheckComponent: React.FC = ({ cleanedError: string; fullError: string; } | null>(null); + const [successModalVisible, setSuccessModalVisible] = useState(false); + const [selectedSuccessDetails, setSelectedSuccessDetails] = useState<{ + modelName: string; + response: any; + } | null>(null); const healthTableRef = useRef>(null); @@ -59,9 +66,11 @@ const HealthCheckComponent: React.FC = ({ healthStatusMap[modelName] = { status: 'none', lastCheck: 'None', + lastSuccess: 'None', loading: false, error: undefined, fullError: undefined, + successResponse: undefined, }; }); @@ -101,9 +110,11 @@ const HealthCheckComponent: React.FC = ({ healthStatusMap[targetModelName] = { status: checkData.status || 'unknown', lastCheck: checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : 'None', + lastSuccess: checkData.status === 'healthy' ? (checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : 'None') : 'None', loading: false, error: fullError ? extractMeaningfulError(fullError) : undefined, fullError: fullError, + successResponse: checkData.status === 'healthy' ? checkData : undefined, }; } }); @@ -261,7 +272,9 @@ const HealthCheckComponent: React.FC = ({ [modelName]: { status: 'healthy', lastCheck: currentTime, - loading: false + lastSuccess: currentTime, + loading: false, + successResponse: response } })); } @@ -283,9 +296,11 @@ const HealthCheckComponent: React.FC = ({ [modelName]: { status: checkData.status || prev[modelName]?.status || 'unknown', lastCheck: checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : prev[modelName]?.lastCheck || 'None', + lastSuccess: checkData.status === 'healthy' ? (checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : prev[modelName]?.lastSuccess || 'None') : prev[modelName]?.lastSuccess || 'None', loading: false, error: fullError ? extractMeaningfulError(fullError) : prev[modelName]?.error, fullError: fullError || prev[modelName]?.fullError, + successResponse: checkData.status === 'healthy' ? checkData : prev[modelName]?.successResponse, } })); } @@ -361,7 +376,9 @@ const HealthCheckComponent: React.FC = ({ [modelName]: { status: 'healthy', lastCheck: currentTime, - loading: false + lastSuccess: currentTime, + loading: false, + successResponse: response } })); } @@ -407,9 +424,11 @@ const HealthCheckComponent: React.FC = ({ [modelName]: { status: checkData.status || currentStatus?.status || 'unknown', lastCheck: checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : currentStatus?.lastCheck || 'None', + lastSuccess: checkData.status === 'healthy' ? (checkData.checked_at ? new Date(checkData.checked_at).toLocaleString() : currentStatus?.lastSuccess || 'None') : currentStatus?.lastSuccess || 'None', loading: false, error: fullError ? extractMeaningfulError(fullError) : currentStatus?.error, fullError: fullError || currentStatus?.fullError, + successResponse: checkData.status === 'healthy' ? checkData : currentStatus?.successResponse, } }; }); @@ -469,6 +488,19 @@ const HealthCheckComponent: React.FC = ({ setSelectedErrorDetails(null); }; + const showSuccessModal = (modelName: string, response: any) => { + setSelectedSuccessDetails({ + modelName, + response + }); + setSuccessModalVisible(true); + }; + + const closeSuccessModal = () => { + setSuccessModalVisible(false); + setSelectedSuccessDetails(null); + }; + return (
@@ -517,6 +549,7 @@ const HealthCheckComponent: React.FC = ({ getStatusBadge, getDisplayModelName, showErrorModal, + showSuccessModal, setSelectedModelId, )} data={modelData.data.map((model: any) => { @@ -571,6 +604,39 @@ const HealthCheckComponent: React.FC = ({
)} + + {/* Success Modal */} + + Close + + ]} + width={800} + > + {selectedSuccessDetails && ( +
+
+ Status: +
+ Health check passed successfully +
+
+ +
+ Response Details: +
+
+                  {JSON.stringify(selectedSuccessDetails.response, null, 2)}
+                
+
+
+
+ )} +
); }; diff --git a/ui/litellm-dashboard/src/components/model_dashboard/health_check_columns.tsx b/ui/litellm-dashboard/src/components/model_dashboard/health_check_columns.tsx index 81270cf0aed..14cb200858a 100644 --- a/ui/litellm-dashboard/src/components/model_dashboard/health_check_columns.tsx +++ b/ui/litellm-dashboard/src/components/model_dashboard/health_check_columns.tsx @@ -23,9 +23,11 @@ interface HealthCheckData { interface HealthStatus { status: string; lastCheck: string; + lastSuccess?: string; loading: boolean; error?: string; fullError?: string; + successResponse?: any; } export const healthCheckColumns = ( @@ -38,6 +40,7 @@ export const healthCheckColumns = ( getStatusBadge: (status: string) => JSX.Element, getDisplayModelName: (model: any) => string, showErrorModal?: (modelName: string, cleanedError: string, fullError: string) => void, + showSuccessModal?: (modelName: string, response: any) => void, setSelectedModelId?: (modelId: string) => void, ): ColumnDef[] => [ { @@ -135,9 +138,22 @@ export const healthCheckColumns = ( ); } + const modelName = model.model_name; + const hasSuccessResponse = healthStatus.status === 'healthy' && modelHealthStatuses[modelName]?.successResponse; + return (
{getStatusBadge(healthStatus.status)} + {hasSuccessResponse && showSuccessModal && ( + + + + )}
); },