Spaces:
Build error
Build error
File size: 5,742 Bytes
55d48a7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | import { useState, useEffect, useCallback } from 'react';
import { localModelHealthMonitor, type ModelHealthStatus } from '~/lib/services/localModelHealthMonitor';
export interface UseLocalModelHealthOptions {
autoStart?: boolean;
checkInterval?: number;
}
export interface UseLocalModelHealthReturn {
healthStatuses: ModelHealthStatus[];
getHealthStatus: (provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => ModelHealthStatus | undefined;
startMonitoring: (provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string, checkInterval?: number) => void;
stopMonitoring: (provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => void;
performHealthCheck: (provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => Promise<void>;
isHealthy: (provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => boolean;
getOverallHealth: () => { healthy: number; unhealthy: number; checking: number; unknown: number };
}
/**
* React hook for monitoring local model health
*/
export function useLocalModelHealth(options: UseLocalModelHealthOptions = {}): UseLocalModelHealthReturn {
const { checkInterval } = options;
const [healthStatuses, setHealthStatuses] = useState<ModelHealthStatus[]>([]);
// Update health statuses when they change
useEffect(() => {
const handleStatusChanged = (status: ModelHealthStatus) => {
setHealthStatuses((current) => {
const index = current.findIndex((s) => s.provider === status.provider && s.baseUrl === status.baseUrl);
if (index >= 0) {
const updated = [...current];
updated[index] = status;
return updated;
} else {
return [...current, status];
}
});
};
localModelHealthMonitor.on('statusChanged', handleStatusChanged);
// Initialize with current statuses
setHealthStatuses(localModelHealthMonitor.getAllHealthStatuses());
return () => {
localModelHealthMonitor.off('statusChanged', handleStatusChanged);
};
}, []);
// Get health status for a specific provider
const getHealthStatus = useCallback((provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => {
return localModelHealthMonitor.getHealthStatus(provider, baseUrl);
}, []);
// Start monitoring a provider
const startMonitoring = useCallback(
(provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string, interval?: number) => {
console.log(`[Health Monitor] Starting monitoring for ${provider} at ${baseUrl}`);
localModelHealthMonitor.startMonitoring(provider, baseUrl, interval || checkInterval);
},
[checkInterval],
);
// Stop monitoring a provider
const stopMonitoring = useCallback((provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => {
console.log(`[Health Monitor] Stopping monitoring for ${provider} at ${baseUrl}`);
localModelHealthMonitor.stopMonitoring(provider, baseUrl);
// Remove from local state
setHealthStatuses((current) => current.filter((s) => !(s.provider === provider && s.baseUrl === baseUrl)));
}, []);
// Perform manual health check
const performHealthCheck = useCallback(async (provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => {
await localModelHealthMonitor.performHealthCheck(provider, baseUrl);
}, []);
// Check if a provider is healthy
const isHealthy = useCallback(
(provider: 'Ollama' | 'LMStudio' | 'OpenAILike', baseUrl: string) => {
const status = getHealthStatus(provider, baseUrl);
return status?.status === 'healthy';
},
[getHealthStatus],
);
// Get overall health statistics
const getOverallHealth = useCallback(() => {
const stats = { healthy: 0, unhealthy: 0, checking: 0, unknown: 0 };
healthStatuses.forEach((status) => {
stats[status.status]++;
});
return stats;
}, [healthStatuses]);
return {
healthStatuses,
getHealthStatus,
startMonitoring,
stopMonitoring,
performHealthCheck,
isHealthy,
getOverallHealth,
};
}
/**
* Hook for monitoring a specific provider
*/
export function useProviderHealth(
provider: 'Ollama' | 'LMStudio' | 'OpenAILike',
baseUrl: string,
options: UseLocalModelHealthOptions = {},
) {
const { autoStart = true, checkInterval } = options;
const { getHealthStatus, startMonitoring, stopMonitoring, performHealthCheck, isHealthy } = useLocalModelHealth();
const [status, setStatus] = useState<ModelHealthStatus | undefined>();
// Update status when it changes
useEffect(() => {
const updateStatus = () => {
setStatus(getHealthStatus(provider, baseUrl));
};
const handleStatusChanged = (changedStatus: ModelHealthStatus) => {
if (changedStatus.provider === provider && changedStatus.baseUrl === baseUrl) {
setStatus(changedStatus);
}
};
localModelHealthMonitor.on('statusChanged', handleStatusChanged);
updateStatus();
return () => {
localModelHealthMonitor.off('statusChanged', handleStatusChanged);
};
}, [provider, baseUrl, getHealthStatus]);
// Auto-start monitoring if enabled
useEffect(() => {
if (autoStart && baseUrl) {
startMonitoring(provider, baseUrl, checkInterval);
return () => {
stopMonitoring(provider, baseUrl);
};
}
return undefined;
}, [autoStart, provider, baseUrl, checkInterval, startMonitoring, stopMonitoring]);
return {
status,
isHealthy: isHealthy(provider, baseUrl),
performHealthCheck: () => performHealthCheck(provider, baseUrl),
startMonitoring: (interval?: number) => startMonitoring(provider, baseUrl, interval),
stopMonitoring: () => stopMonitoring(provider, baseUrl),
};
}
|