'use client' import { useState, useEffect, useCallback } from 'react' import { useTranslations } from 'next-intl' import { Button } from '@/components/ui/button' type Tab = 'status' | 'health' | 'models' | 'apicall' export function DebugPanel() { const t = useTranslations('debug') const [activeTab, setActiveTab] = useState('status') const tabLabels: Record = { status: t('tabStatus'), health: t('tabHealth'), models: t('tabModels'), apicall: t('tabApiCall'), } return (
{(['status', 'health', 'models', 'apicall'] as const).map((tab) => ( ))}
{activeTab === 'status' && } {activeTab === 'health' && } {activeTab === 'models' && } {activeTab === 'apicall' && }
) } // --------------------------------------------------------------------------- // Status Tab // --------------------------------------------------------------------------- function StatusTab() { const t = useTranslations('debug') const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const fetchStatus = useCallback(async () => { setLoading(true) try { const res = await fetch('/api/debug?action=status') setData(await res.json()) } catch { setData({ error: 'Failed to fetch status' }) } finally { setLoading(false) } }, []) useEffect(() => { fetchStatus() }, [fetchStatus]) const reachable = data && !data.gatewayReachable === false && data.gatewayReachable !== false return (
{t('gateway')}: {loading ? ( {t('checking')} ) : ( {reachable ? t('reachable') : t('unreachable')} )}
        {loading ? t('loading') : JSON.stringify(data, null, 2)}
      
) } // --------------------------------------------------------------------------- // Health Tab // --------------------------------------------------------------------------- function HealthTab() { const t = useTranslations('debug') const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [heartbeat, setHeartbeat] = useState<{ ok: boolean; latencyMs: number; timestamp: number } | null>(null) const [hbLoading, setHbLoading] = useState(false) const fetchHealth = useCallback(async () => { setLoading(true) try { const res = await fetch('/api/debug?action=health') setData(await res.json()) } catch { setData({ healthy: false, error: 'Failed to fetch' }) } finally { setLoading(false) } }, []) useEffect(() => { fetchHealth() }, [fetchHealth]) const pingHeartbeat = async () => { setHbLoading(true) try { const res = await fetch('/api/debug?action=heartbeat') setHeartbeat(await res.json()) } catch { setHeartbeat({ ok: false, latencyMs: -1, timestamp: Date.now() }) } finally { setHbLoading(false) } } const healthy = data?.healthy === true || (data && !data.error && data.healthy !== false) return (
{t('health')}: {loading ? ( {t('checking')} ) : ( {healthy ? t('healthy') : t('unhealthy')} )} {heartbeat && ( {heartbeat.ok ? t('ok') : t('failed')} - {heartbeat.latencyMs}ms )}
{data && !loading && (
{Object.entries(data).map(([key, value]) => ( ))}
{key} {typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value)}
)}
) } // --------------------------------------------------------------------------- // Models Tab // --------------------------------------------------------------------------- interface ModelEntry { name?: string id?: string provider?: string context_length?: number [key: string]: any } function ModelsTab() { const t = useTranslations('debug') const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const fetchModels = useCallback(async () => { setLoading(true) try { const res = await fetch('/api/debug?action=models') setData(await res.json()) } catch { setData({ models: [] }) } finally { setLoading(false) } }, []) useEffect(() => { fetchModels() }, [fetchModels]) const models: ModelEntry[] = Array.isArray(data?.models) ? data.models : (Array.isArray(data?.data) ? data.data : []) return (
{t('models')}
{loading ? (

{t('loading')}

) : models.length === 0 ? (

{t('noModels')}

) : (
{models.map((m, i) => ( ))}
{t('colName')} {t('colProvider')} {t('colContextLength')}
{m.name || m.id || '?'} {m.provider || '-'} {m.context_length ?? '-'}
)}
) } // --------------------------------------------------------------------------- // API Call Tab // --------------------------------------------------------------------------- function ApiCallTab() { const t = useTranslations('debug') const [method, setMethod] = useState<'GET' | 'POST'>('GET') const [path, setPath] = useState('/api/') const [body, setBody] = useState('') const [response, setResponse] = useState(null) const [loading, setLoading] = useState(false) const send = async () => { setLoading(true) setResponse(null) try { let parsedBody: any = undefined if (method === 'POST' && body.trim()) { try { parsedBody = JSON.parse(body) } catch { setResponse({ error: 'Invalid JSON in body' }) setLoading(false) return } } const res = await fetch('/api/debug?action=call', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ method, path, body: parsedBody }), }) setResponse(await res.json()) } catch { setResponse({ error: 'Request failed' }) } finally { setLoading(false) } } return (
setPath(e.target.value)} placeholder="/api/" className="h-8 w-full px-2 rounded border border-border bg-secondary text-foreground text-sm font-mono" />
{method === 'POST' && (