mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
Merge pull request #11899 from colesmcintosh/add-health-check-success-modal
Add success modal for health check responses
This commit is contained in:
commit
7abece4ad8
2 changed files with 84 additions and 2 deletions
|
|
@ -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<HealthCheckComponentProps> = ({
|
|||
cleanedError: string;
|
||||
fullError: string;
|
||||
} | null>(null);
|
||||
const [successModalVisible, setSuccessModalVisible] = useState(false);
|
||||
const [selectedSuccessDetails, setSelectedSuccessDetails] = useState<{
|
||||
modelName: string;
|
||||
response: any;
|
||||
} | null>(null);
|
||||
|
||||
const healthTableRef = useRef<TableInstance<any>>(null);
|
||||
|
||||
|
|
@ -59,9 +66,11 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
healthStatusMap[modelName] = {
|
||||
status: 'none',
|
||||
lastCheck: 'None',
|
||||
lastSuccess: 'None',
|
||||
loading: false,
|
||||
error: undefined,
|
||||
fullError: undefined,
|
||||
successResponse: undefined,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -101,9 +110,11 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
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<HealthCheckComponentProps> = ({
|
|||
[modelName]: {
|
||||
status: 'healthy',
|
||||
lastCheck: currentTime,
|
||||
loading: false
|
||||
lastSuccess: currentTime,
|
||||
loading: false,
|
||||
successResponse: response
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
@ -283,9 +296,11 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
[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<HealthCheckComponentProps> = ({
|
|||
[modelName]: {
|
||||
status: 'healthy',
|
||||
lastCheck: currentTime,
|
||||
loading: false
|
||||
lastSuccess: currentTime,
|
||||
loading: false,
|
||||
successResponse: response
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
@ -407,9 +424,11 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
[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<HealthCheckComponentProps> = ({
|
|||
setSelectedErrorDetails(null);
|
||||
};
|
||||
|
||||
const showSuccessModal = (modelName: string, response: any) => {
|
||||
setSelectedSuccessDetails({
|
||||
modelName,
|
||||
response
|
||||
});
|
||||
setSuccessModalVisible(true);
|
||||
};
|
||||
|
||||
const closeSuccessModal = () => {
|
||||
setSuccessModalVisible(false);
|
||||
setSelectedSuccessDetails(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-6">
|
||||
|
|
@ -517,6 +549,7 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
getStatusBadge,
|
||||
getDisplayModelName,
|
||||
showErrorModal,
|
||||
showSuccessModal,
|
||||
setSelectedModelId,
|
||||
)}
|
||||
data={modelData.data.map((model: any) => {
|
||||
|
|
@ -571,6 +604,39 @@ const HealthCheckComponent: React.FC<HealthCheckComponentProps> = ({
|
|||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
|
||||
{/* Success Modal */}
|
||||
<Modal
|
||||
title={selectedSuccessDetails ? `Health Check Response - ${selectedSuccessDetails.modelName}` : 'Response Details'}
|
||||
open={successModalVisible}
|
||||
onCancel={closeSuccessModal}
|
||||
footer={[
|
||||
<AntdButton key="close" onClick={closeSuccessModal}>
|
||||
Close
|
||||
</AntdButton>
|
||||
]}
|
||||
width={800}
|
||||
>
|
||||
{selectedSuccessDetails && (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text className="font-medium">Status:</Text>
|
||||
<div className="mt-2 p-3 bg-green-50 border border-green-200 rounded-md">
|
||||
<Text className="text-green-800">Health check passed successfully</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Response Details:</Text>
|
||||
<div className="mt-2 p-3 bg-gray-50 border border-gray-200 rounded-md max-h-96 overflow-y-auto">
|
||||
<pre className="text-sm text-gray-800 whitespace-pre-wrap">
|
||||
{JSON.stringify(selectedSuccessDetails.response, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<HealthCheckData>[] => [
|
||||
{
|
||||
|
|
@ -135,9 +138,22 @@ export const healthCheckColumns = (
|
|||
);
|
||||
}
|
||||
|
||||
const modelName = model.model_name;
|
||||
const hasSuccessResponse = healthStatus.status === 'healthy' && modelHealthStatuses[modelName]?.successResponse;
|
||||
|
||||
return (
|
||||
<div className="flex items-center space-x-2">
|
||||
{getStatusBadge(healthStatus.status)}
|
||||
{hasSuccessResponse && showSuccessModal && (
|
||||
<Tooltip title="View response details" placement="top">
|
||||
<button
|
||||
onClick={() => showSuccessModal(modelName, modelHealthStatuses[modelName]?.successResponse)}
|
||||
className="p-1 text-green-600 hover:text-green-800 hover:bg-green-50 rounded cursor-pointer transition-colors"
|
||||
>
|
||||
<InformationCircleIcon className="h-4 w-4" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue