Final UI V3
# UI V3 Changelog Major updates and improvements in this release: ## Core Changes - Complete NEW REWRITTEN UI system overhaul (V3) with semantic design tokens - New settings management system with drag-and-drop capabilities - Enhanced provider system supporting multiple AI services - Improved theme system with better dark mode support - New component library with consistent design patterns ## Technical Updates - Reorganized project architecture for better maintainability - Performance optimizations and bundle size improvements - Enhanced security features and access controls - Improved developer experience with better tooling - Comprehensive testing infrastructure ## New Features - Background rays effect for improved visual feedback - Advanced tab management system - Automatic and manual update support - Enhanced error handling and visualization - Improved accessibility across all components For detailed information about all changes and improvements, please see the full changelog.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class AmazonBedrockStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check AWS health status page
|
||||
const statusPageResponse = await fetch('https://health.aws.amazon.com/health/status');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for Bedrock and general AWS status
|
||||
const hasBedrockIssues =
|
||||
text.includes('Amazon Bedrock') &&
|
||||
(text.includes('Service is experiencing elevated error rates') ||
|
||||
text.includes('Service disruption') ||
|
||||
text.includes('Degraded Service'));
|
||||
|
||||
const hasGeneralIssues = text.includes('Service disruption') || text.includes('Multiple services affected');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentMatches = text.matchAll(/(\d{4}-\d{2}-\d{2})\s+(.*?)\s+Impact:(.*?)(?=\n|$)/g);
|
||||
|
||||
for (const match of incidentMatches) {
|
||||
const [, date, title, impact] = match;
|
||||
|
||||
if (title.includes('Bedrock') || title.includes('AWS')) {
|
||||
incidents.push(`${date}: ${title.trim()} - Impact: ${impact.trim()}`);
|
||||
}
|
||||
}
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All services operational';
|
||||
|
||||
if (hasBedrockIssues) {
|
||||
status = 'degraded';
|
||||
message = 'Amazon Bedrock service issues reported';
|
||||
} else if (hasGeneralIssues) {
|
||||
status = 'degraded';
|
||||
message = 'AWS experiencing general issues';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://health.aws.amazon.com/health/status');
|
||||
const apiEndpoint = 'https://bedrock.us-east-1.amazonaws.com/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: incidents.slice(0, 5),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Amazon Bedrock status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://health.aws.amazon.com/health/status');
|
||||
const apiEndpoint = 'https://bedrock.us-east-1.amazonaws.com/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class AnthropicStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.anthropic.com/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for specific Anthropic status indicators
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasDegradedPerformance = text.includes('Degraded Performance');
|
||||
const hasPartialOutage = text.includes('Partial Outage');
|
||||
const hasMajorOutage = text.includes('Major Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentSection = text.match(/Past Incidents(.*?)(?=\n\n)/s);
|
||||
|
||||
if (incidentSection) {
|
||||
const incidentLines = incidentSection[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && line.includes('202')); // Only get dated incidents
|
||||
|
||||
incidents.push(...incidentLines.slice(0, 5));
|
||||
}
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (hasMajorOutage) {
|
||||
status = 'down';
|
||||
message = 'Major service outage';
|
||||
} else if (hasPartialOutage) {
|
||||
status = 'down';
|
||||
message = 'Partial service outage';
|
||||
} else if (hasDegradedPerformance) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing degraded performance';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.anthropic.com/');
|
||||
const apiEndpoint = 'https://api.anthropic.com/v1/messages';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Anthropic status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.anthropic.com/');
|
||||
const apiEndpoint = 'https://api.anthropic.com/v1/messages';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class CohereStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.cohere.com/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for specific Cohere status indicators
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasIncidents = text.includes('Active Incidents');
|
||||
const hasDegradation = text.includes('Degraded Performance');
|
||||
const hasOutage = text.includes('Service Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentSection = text.match(/Past Incidents(.*?)(?=\n\n)/s);
|
||||
|
||||
if (incidentSection) {
|
||||
const incidentLines = incidentSection[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && line.includes('202')); // Only get dated incidents
|
||||
|
||||
incidents.push(...incidentLines.slice(0, 5));
|
||||
}
|
||||
|
||||
// Check specific services
|
||||
const services = {
|
||||
api: {
|
||||
operational: text.includes('API Service') && text.includes('Operational'),
|
||||
degraded: text.includes('API Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('API Service') && text.includes('Service Outage'),
|
||||
},
|
||||
generation: {
|
||||
operational: text.includes('Generation Service') && text.includes('Operational'),
|
||||
degraded: text.includes('Generation Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('Generation Service') && text.includes('Service Outage'),
|
||||
},
|
||||
};
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (services.api.outage || services.generation.outage || hasOutage) {
|
||||
status = 'down';
|
||||
message = 'Service outage detected';
|
||||
} else if (services.api.degraded || services.generation.degraded || hasDegradation || hasIncidents) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing issues';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.cohere.com/');
|
||||
const apiEndpoint = 'https://api.cohere.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Cohere status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.cohere.com/');
|
||||
const apiEndpoint = 'https://api.cohere.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class DeepseekStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
/*
|
||||
* Check status page - Note: Deepseek doesn't have a public status page yet
|
||||
* so we'll check their API endpoint directly
|
||||
*/
|
||||
const apiEndpoint = 'https://api.deepseek.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
// Check their website as a secondary indicator
|
||||
const websiteStatus = await this.checkEndpoint('https://deepseek.com');
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (apiStatus !== 'reachable' || websiteStatus !== 'reachable') {
|
||||
status = apiStatus !== 'reachable' ? 'down' : 'degraded';
|
||||
message = apiStatus !== 'reachable' ? 'API appears to be down' : 'Service may be experiencing issues';
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: [], // No public incident tracking available yet
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Deepseek status:', error);
|
||||
|
||||
return {
|
||||
status: 'degraded',
|
||||
message: 'Unable to determine service status',
|
||||
incidents: ['Note: Limited status information available'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class GoogleStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.cloud.google.com/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for Vertex AI and general cloud status
|
||||
const hasVertexAIIssues =
|
||||
text.includes('Vertex AI') &&
|
||||
(text.includes('Incident') ||
|
||||
text.includes('Disruption') ||
|
||||
text.includes('Outage') ||
|
||||
text.includes('degraded'));
|
||||
|
||||
const hasGeneralIssues = text.includes('Major Incidents') || text.includes('Service Disruption');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentMatches = text.matchAll(/(\d{4}-\d{2}-\d{2})\s+(.*?)\s+Impact:(.*?)(?=\n|$)/g);
|
||||
|
||||
for (const match of incidentMatches) {
|
||||
const [, date, title, impact] = match;
|
||||
|
||||
if (title.includes('Vertex AI') || title.includes('Cloud')) {
|
||||
incidents.push(`${date}: ${title.trim()} - Impact: ${impact.trim()}`);
|
||||
}
|
||||
}
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All services operational';
|
||||
|
||||
if (hasVertexAIIssues) {
|
||||
status = 'degraded';
|
||||
message = 'Vertex AI service issues reported';
|
||||
} else if (hasGeneralIssues) {
|
||||
status = 'degraded';
|
||||
message = 'Google Cloud experiencing issues';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.cloud.google.com/');
|
||||
const apiEndpoint = 'https://generativelanguage.googleapis.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: incidents.slice(0, 5),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Google status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.cloud.google.com/');
|
||||
const apiEndpoint = 'https://generativelanguage.googleapis.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class GroqStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://groqstatus.com/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasIncidents = text.includes('Active Incidents');
|
||||
const hasDegradation = text.includes('Degraded Performance');
|
||||
const hasOutage = text.includes('Service Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentMatches = text.matchAll(/(\d{4}-\d{2}-\d{2})\s+(.*?)\s+Status:(.*?)(?=\n|$)/g);
|
||||
|
||||
for (const match of incidentMatches) {
|
||||
const [, date, title, status] = match;
|
||||
incidents.push(`${date}: ${title.trim()} - ${status.trim()}`);
|
||||
}
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (hasOutage) {
|
||||
status = 'down';
|
||||
message = 'Service outage detected';
|
||||
} else if (hasDegradation || hasIncidents) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing issues';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://groqstatus.com/');
|
||||
const apiEndpoint = 'https://api.groq.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: incidents.slice(0, 5),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Groq status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://groqstatus.com/');
|
||||
const apiEndpoint = 'https://api.groq.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class HuggingFaceStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.huggingface.co/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for "All services are online" message
|
||||
const allServicesOnline = text.includes('All services are online');
|
||||
|
||||
// Get last update time
|
||||
const lastUpdateMatch = text.match(/Last updated on (.*?)(EST|PST|GMT)/);
|
||||
const lastUpdate = lastUpdateMatch ? `${lastUpdateMatch[1]}${lastUpdateMatch[2]}` : '';
|
||||
|
||||
// Check individual services and their uptime percentages
|
||||
const services = {
|
||||
'Huggingface Hub': {
|
||||
operational: text.includes('Huggingface Hub') && text.includes('Operational'),
|
||||
uptime: text.match(/Huggingface Hub[\s\S]*?(\d+\.\d+)%\s*uptime/)?.[1],
|
||||
},
|
||||
'Git Hosting and Serving': {
|
||||
operational: text.includes('Git Hosting and Serving') && text.includes('Operational'),
|
||||
uptime: text.match(/Git Hosting and Serving[\s\S]*?(\d+\.\d+)%\s*uptime/)?.[1],
|
||||
},
|
||||
'Inference API': {
|
||||
operational: text.includes('Inference API') && text.includes('Operational'),
|
||||
uptime: text.match(/Inference API[\s\S]*?(\d+\.\d+)%\s*uptime/)?.[1],
|
||||
},
|
||||
'HF Endpoints': {
|
||||
operational: text.includes('HF Endpoints') && text.includes('Operational'),
|
||||
uptime: text.match(/HF Endpoints[\s\S]*?(\d+\.\d+)%\s*uptime/)?.[1],
|
||||
},
|
||||
Spaces: {
|
||||
operational: text.includes('Spaces') && text.includes('Operational'),
|
||||
uptime: text.match(/Spaces[\s\S]*?(\d+\.\d+)%\s*uptime/)?.[1],
|
||||
},
|
||||
};
|
||||
|
||||
// Create service status messages with uptime
|
||||
const serviceMessages = Object.entries(services).map(([name, info]) => {
|
||||
if (info.uptime) {
|
||||
return `${name}: ${info.uptime}% uptime`;
|
||||
}
|
||||
|
||||
return `${name}: ${info.operational ? 'Operational' : 'Issues detected'}`;
|
||||
});
|
||||
|
||||
// Determine overall status
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = allServicesOnline
|
||||
? `All services are online (Last updated on ${lastUpdate})`
|
||||
: 'Checking individual services';
|
||||
|
||||
// Only mark as degraded if we explicitly detect issues
|
||||
const hasIssues = Object.values(services).some((service) => !service.operational);
|
||||
|
||||
if (hasIssues) {
|
||||
status = 'degraded';
|
||||
message = `Service issues detected (Last updated on ${lastUpdate})`;
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.huggingface.co/');
|
||||
const apiEndpoint = 'https://api-inference.huggingface.co/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: serviceMessages,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking HuggingFace status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.huggingface.co/');
|
||||
const apiEndpoint = 'https://api-inference.huggingface.co/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class HyperbolicStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
/*
|
||||
* Check API endpoint directly since Hyperbolic is a newer provider
|
||||
* and may not have a public status page yet
|
||||
*/
|
||||
const apiEndpoint = 'https://api.hyperbolic.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
// Check their website as a secondary indicator
|
||||
const websiteStatus = await this.checkEndpoint('https://hyperbolic.ai');
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (apiStatus !== 'reachable' || websiteStatus !== 'reachable') {
|
||||
status = apiStatus !== 'reachable' ? 'down' : 'degraded';
|
||||
message = apiStatus !== 'reachable' ? 'API appears to be down' : 'Service may be experiencing issues';
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: [], // No public incident tracking available yet
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Hyperbolic status:', error);
|
||||
|
||||
return {
|
||||
status: 'degraded',
|
||||
message: 'Unable to determine service status',
|
||||
incidents: ['Note: Limited status information available'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class MistralStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.mistral.ai/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasIncidents = text.includes('Active Incidents');
|
||||
const hasDegradation = text.includes('Degraded Performance');
|
||||
const hasOutage = text.includes('Service Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentSection = text.match(/Recent Events(.*?)(?=\n\n)/s);
|
||||
|
||||
if (incidentSection) {
|
||||
const incidentLines = incidentSection[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && !line.includes('No incidents'));
|
||||
|
||||
incidents.push(...incidentLines.slice(0, 5));
|
||||
}
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (hasOutage) {
|
||||
status = 'down';
|
||||
message = 'Service outage detected';
|
||||
} else if (hasDegradation || hasIncidents) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing issues';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.mistral.ai/');
|
||||
const apiEndpoint = 'https://api.mistral.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Mistral status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.mistral.ai/');
|
||||
const apiEndpoint = 'https://api.mistral.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class OpenAIStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.openai.com/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check individual services
|
||||
const services = {
|
||||
api: {
|
||||
operational: text.includes('API ? Operational'),
|
||||
degraded: text.includes('API ? Degraded Performance'),
|
||||
outage: text.includes('API ? Major Outage') || text.includes('API ? Partial Outage'),
|
||||
},
|
||||
chat: {
|
||||
operational: text.includes('ChatGPT ? Operational'),
|
||||
degraded: text.includes('ChatGPT ? Degraded Performance'),
|
||||
outage: text.includes('ChatGPT ? Major Outage') || text.includes('ChatGPT ? Partial Outage'),
|
||||
},
|
||||
};
|
||||
|
||||
// Extract recent incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentMatches = text.match(/Past Incidents(.*?)(?=\w+ \d+, \d{4})/s);
|
||||
|
||||
if (incidentMatches) {
|
||||
const recentIncidents = incidentMatches[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && line.includes('202')); // Get only dated incidents
|
||||
|
||||
incidents.push(...recentIncidents.slice(0, 5));
|
||||
}
|
||||
|
||||
// Determine overall status
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
const messages: string[] = [];
|
||||
|
||||
if (services.api.outage || services.chat.outage) {
|
||||
status = 'down';
|
||||
|
||||
if (services.api.outage) {
|
||||
messages.push('API: Major Outage');
|
||||
}
|
||||
|
||||
if (services.chat.outage) {
|
||||
messages.push('ChatGPT: Major Outage');
|
||||
}
|
||||
} else if (services.api.degraded || services.chat.degraded) {
|
||||
status = 'degraded';
|
||||
|
||||
if (services.api.degraded) {
|
||||
messages.push('API: Degraded Performance');
|
||||
}
|
||||
|
||||
if (services.chat.degraded) {
|
||||
messages.push('ChatGPT: Degraded Performance');
|
||||
}
|
||||
} else if (services.api.operational) {
|
||||
messages.push('API: Operational');
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.openai.com/');
|
||||
const apiEndpoint = 'https://api.openai.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message: messages.join(', ') || 'Status unknown',
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking OpenAI status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.openai.com/');
|
||||
const apiEndpoint = 'https://api.openai.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class OpenRouterStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.openrouter.ai/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for specific OpenRouter status indicators
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasIncidents = text.includes('Active Incidents');
|
||||
const hasDegradation = text.includes('Degraded Performance');
|
||||
const hasOutage = text.includes('Service Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentSection = text.match(/Past Incidents(.*?)(?=\n\n)/s);
|
||||
|
||||
if (incidentSection) {
|
||||
const incidentLines = incidentSection[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && line.includes('202')); // Only get dated incidents
|
||||
|
||||
incidents.push(...incidentLines.slice(0, 5));
|
||||
}
|
||||
|
||||
// Check specific services
|
||||
const services = {
|
||||
api: {
|
||||
operational: text.includes('API Service') && text.includes('Operational'),
|
||||
degraded: text.includes('API Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('API Service') && text.includes('Service Outage'),
|
||||
},
|
||||
routing: {
|
||||
operational: text.includes('Routing Service') && text.includes('Operational'),
|
||||
degraded: text.includes('Routing Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('Routing Service') && text.includes('Service Outage'),
|
||||
},
|
||||
};
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (services.api.outage || services.routing.outage || hasOutage) {
|
||||
status = 'down';
|
||||
message = 'Service outage detected';
|
||||
} else if (services.api.degraded || services.routing.degraded || hasDegradation || hasIncidents) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing issues';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.openrouter.ai/');
|
||||
const apiEndpoint = 'https://openrouter.ai/api/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking OpenRouter status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.openrouter.ai/');
|
||||
const apiEndpoint = 'https://openrouter.ai/api/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class PerplexityStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.perplexity.ai/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for specific Perplexity status indicators
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasIncidents = text.includes('Active Incidents');
|
||||
const hasDegradation = text.includes('Degraded Performance');
|
||||
const hasOutage = text.includes('Service Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentSection = text.match(/Past Incidents(.*?)(?=\n\n)/s);
|
||||
|
||||
if (incidentSection) {
|
||||
const incidentLines = incidentSection[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && line.includes('202')); // Only get dated incidents
|
||||
|
||||
incidents.push(...incidentLines.slice(0, 5));
|
||||
}
|
||||
|
||||
// Check specific services
|
||||
const services = {
|
||||
api: {
|
||||
operational: text.includes('API Service') && text.includes('Operational'),
|
||||
degraded: text.includes('API Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('API Service') && text.includes('Service Outage'),
|
||||
},
|
||||
inference: {
|
||||
operational: text.includes('Inference Service') && text.includes('Operational'),
|
||||
degraded: text.includes('Inference Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('Inference Service') && text.includes('Service Outage'),
|
||||
},
|
||||
};
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (services.api.outage || services.inference.outage || hasOutage) {
|
||||
status = 'down';
|
||||
message = 'Service outage detected';
|
||||
} else if (services.api.degraded || services.inference.degraded || hasDegradation || hasIncidents) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing issues';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.perplexity.ai/');
|
||||
const apiEndpoint = 'https://api.perplexity.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Perplexity status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.perplexity.ai/');
|
||||
const apiEndpoint = 'https://api.perplexity.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class TogetherStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
// Check status page
|
||||
const statusPageResponse = await fetch('https://status.together.ai/');
|
||||
const text = await statusPageResponse.text();
|
||||
|
||||
// Check for specific Together status indicators
|
||||
const isOperational = text.includes('All Systems Operational');
|
||||
const hasIncidents = text.includes('Active Incidents');
|
||||
const hasDegradation = text.includes('Degraded Performance');
|
||||
const hasOutage = text.includes('Service Outage');
|
||||
|
||||
// Extract incidents
|
||||
const incidents: string[] = [];
|
||||
const incidentSection = text.match(/Past Incidents(.*?)(?=\n\n)/s);
|
||||
|
||||
if (incidentSection) {
|
||||
const incidentLines = incidentSection[1]
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line && line.includes('202')); // Only get dated incidents
|
||||
|
||||
incidents.push(...incidentLines.slice(0, 5));
|
||||
}
|
||||
|
||||
// Check specific services
|
||||
const services = {
|
||||
api: {
|
||||
operational: text.includes('API Service') && text.includes('Operational'),
|
||||
degraded: text.includes('API Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('API Service') && text.includes('Service Outage'),
|
||||
},
|
||||
inference: {
|
||||
operational: text.includes('Inference Service') && text.includes('Operational'),
|
||||
degraded: text.includes('Inference Service') && text.includes('Degraded Performance'),
|
||||
outage: text.includes('Inference Service') && text.includes('Service Outage'),
|
||||
},
|
||||
};
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (services.api.outage || services.inference.outage || hasOutage) {
|
||||
status = 'down';
|
||||
message = 'Service outage detected';
|
||||
} else if (services.api.degraded || services.inference.degraded || hasDegradation || hasIncidents) {
|
||||
status = 'degraded';
|
||||
message = 'Service experiencing issues';
|
||||
} else if (!isOperational) {
|
||||
status = 'degraded';
|
||||
message = 'Service status unknown';
|
||||
}
|
||||
|
||||
// If status page check fails, fallback to endpoint check
|
||||
if (!statusPageResponse.ok) {
|
||||
const endpointStatus = await this.checkEndpoint('https://status.together.ai/');
|
||||
const apiEndpoint = 'https://api.together.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking Together status:', error);
|
||||
|
||||
// Fallback to basic endpoint check
|
||||
const endpointStatus = await this.checkEndpoint('https://status.together.ai/');
|
||||
const apiEndpoint = 'https://api.together.ai/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
return {
|
||||
status: endpointStatus === 'reachable' && apiStatus === 'reachable' ? 'operational' : 'degraded',
|
||||
message: `Status page: ${endpointStatus}, API: ${apiStatus}`,
|
||||
incidents: ['Note: Limited status information due to CORS restrictions'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { BaseProviderChecker } from '~/components/@settings/tabs/providers/service-status/base-provider';
|
||||
import type { StatusCheckResult } from '~/components/@settings/tabs/providers/service-status/types';
|
||||
|
||||
export class XAIStatusChecker extends BaseProviderChecker {
|
||||
async checkStatus(): Promise<StatusCheckResult> {
|
||||
try {
|
||||
/*
|
||||
* Check API endpoint directly since XAI is a newer provider
|
||||
* and may not have a public status page yet
|
||||
*/
|
||||
const apiEndpoint = 'https://api.xai.com/v1/models';
|
||||
const apiStatus = await this.checkEndpoint(apiEndpoint);
|
||||
|
||||
// Check their website as a secondary indicator
|
||||
const websiteStatus = await this.checkEndpoint('https://x.ai');
|
||||
|
||||
let status: StatusCheckResult['status'] = 'operational';
|
||||
let message = 'All systems operational';
|
||||
|
||||
if (apiStatus !== 'reachable' || websiteStatus !== 'reachable') {
|
||||
status = apiStatus !== 'reachable' ? 'down' : 'degraded';
|
||||
message = apiStatus !== 'reachable' ? 'API appears to be down' : 'Service may be experiencing issues';
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
message,
|
||||
incidents: [], // No public incident tracking available yet
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error checking XAI status:', error);
|
||||
|
||||
return {
|
||||
status: 'degraded',
|
||||
message: 'Unable to determine service status',
|
||||
incidents: ['Note: Limited status information available'],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user