"use client" import * as React from 'react' import { RotateCw } from 'lucide-react' import { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert' import { Button } from '@open-mercato/ui/primitives/button' import { IconButton } from '@open-mercato/ui/primitives/icon-button' import { StatusBadge } from '@open-mercato/ui/primitives/status-badge' import { useT } from '@open-mercato/shared/lib/i18n/context' import type { HealthIndicator, HealthIndicatorId, WebSearchHealthPayload } from '../../lib/systemHealth' import { HealthRow } from './HealthRow' import { HealthStateBadge } from './HealthStateBadge' import { formatProbeAge } from './vocabulary' const INDICATOR_LABEL_KEY: Record = { webSearch: 'agent_orchestrator.overview.health.webSearch', mcp: 'agent_orchestrator.overview.health.mcp', opencode: 'agent_orchestrator.overview.health.opencode', opencodeMcp: 'agent_orchestrator.overview.health.opencodeMcp', } const RUNTIME_ORDER: HealthIndicatorId[] = ['mcp', 'opencode', 'opencodeMcp'] export type SystemHealthPanelProps = { indicators: readonly HealthIndicator[] webSearch: WebSearchHealthPayload | null fetchFailed: boolean isLoading: boolean /** Whether this operator may spend a billable probe. */ canProbe: boolean probingAdapterId: string | null onRecheck: () => void onTestAdapter: (adapterId: string) => void } export function SystemHealthPanel({ indicators, webSearch, fetchFailed, isLoading, canProbe, probingAdapterId, onRecheck, onTestAdapter, }: SystemHealthPanelProps) { const t = useT() // One clock reading per render keeps every row's age consistent with the others. const nowMs = Date.now() const byId = React.useMemo(() => { const map = new Map() for (const indicator of indicators) map.set(indicator.id, indicator) return map }, [indicators]) const webSearchIndicator = byId.get('webSearch') const enabledAdapters = webSearch?.adapters.filter((adapter) => adapter.enabled) ?? [] const disabledAdapters = webSearch?.adapters.filter((adapter) => !adapter.enabled) ?? [] const disabledIds = disabledAdapters.map((adapter) => adapter.id).join(', ') // The panel owns its own inset: `PopoverContent` defaults to `p-0`, and this // component is meant to drop into any host without the caller remembering to // pad it. return (

{t('agent_orchestrator.overview.health.title', 'System health')}

{canProbe ? ( ) : null}
{fetchFailed ? ( {t('agent_orchestrator.health.fetchError', 'Could not read system health.')} ) : null}

{t('agent_orchestrator.health.sectionRuntime', 'Runtime')}

    {RUNTIME_ORDER.map((id) => { const indicator = byId.get(id) if (!indicator) return null return ( } /> ) })}
{webSearchIndicator ? (

{t('agent_orchestrator.health.sectionWebSearch', 'Web search')}

{enabledAdapters.length > 0 ? (
    {enabledAdapters.map((adapter) => { const age = formatProbeAge(adapter.checkedAt, nowMs) const verified = adapter.ready && adapter.probed === true const detail = verified ? [adapter.latencyMs !== null ? `${adapter.latencyMs}ms` : null, age] .filter(Boolean) .join(' ยท ') || null : adapter.detail return ( {verified ? ( {adapter.ok ? t('agent_orchestrator.overview.webSearch.adapter.ok', 'OK') : t('agent_orchestrator.overview.webSearch.adapter.problem', 'Problem')} ) : ( {adapter.ready ? t('agent_orchestrator.health.notVerified', 'Not verified') : t('agent_orchestrator.overview.webSearch.adapter.problem', 'Problem')} )} {canProbe && adapter.ready ? ( ) : null} } /> ) })}
) : null} {disabledIds ? (

{t('agent_orchestrator.overview.webSearch.disabledAdapters', 'Installed but off: {ids}', { ids: disabledIds, })}

) : null} {webSearch?.problems.length ? (
    {webSearch.problems.map((problem) => (
  • {`${problem.packageName}: ${problem.reason}`}
  • ))}
) : null}
) : null}

{formatProbeAge(webSearch?.checkedAt ?? null, nowMs) ? t('agent_orchestrator.health.checkedAgo', 'Checked {age} ago', { age: formatProbeAge(webSearch?.checkedAt ?? null, nowMs) as string, }) : t('agent_orchestrator.health.neverChecked', 'Never checked')}

) }