'use client'; import React, { useEffect, useState } from 'react'; import Link from 'next/link'; import { CheckCircle2, XCircle, AlertCircle, RefreshCw, Server, Cpu, Radio, Key, Loader2, Settings2, ScrollText, } from 'lucide-react'; import { getStatus, updateProviderConfig } from '@/lib/api'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import type { ProviderStatus, SystemStatus } from '@/types'; import { pickAppText } from '@/lib/i18n/core'; import { useAppI18n } from '@/lib/i18n/provider'; type ProviderFormState = { enabled: boolean; model: string; apiKey: string; apiBase: string; requestTimeoutSeconds: string; }; export default function StatusPage() { const { locale } = useAppI18n(); const [status, setStatus] = useState(null); const [error, setError] = useState(null); const [loading, setLoading] = useState(true); const [selectedProvider, setSelectedProvider] = useState(null); const [providerForm, setProviderForm] = useState(() => ({ enabled: false, model: '', apiKey: '', apiBase: '', requestTimeoutSeconds: '', })); const [savingProvider, setSavingProvider] = useState(false); const [providerError, setProviderError] = useState(null); const loadStatus = async () => { setLoading(true); setError(null); try { const data = await getStatus(); setStatus(data); } catch (err: any) { setError(err.message || pickAppText(locale, '连接后端失败', 'Failed to connect to the backend')); } finally { setLoading(false); } }; useEffect(() => { loadStatus(); }, []); const openProviderDialog = (provider: ProviderStatus) => { setSelectedProvider(provider); setProviderError(null); setProviderForm({ enabled: Boolean(provider.enabled || provider.has_key), model: status?.model || '', apiKey: '', apiBase: provider.api_base || provider.default_api_base || provider.detail || '', requestTimeoutSeconds: '', }); }; const handleSaveProvider = async () => { if (!selectedProvider) return; const providerId = selectedProvider.id || selectedProvider.name; setSavingProvider(true); setProviderError(null); try { const timeout = providerForm.requestTimeoutSeconds.trim() ? Number(providerForm.requestTimeoutSeconds.trim()) : undefined; if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) { throw new Error(pickAppText(locale, '请求超时必须是正数', 'Request timeout must be a positive number')); } await updateProviderConfig(providerId, { enabled: providerForm.enabled, model: providerForm.model.trim() || undefined, api_key: providerForm.apiKey.trim() || undefined, api_base: providerForm.apiBase.trim() || undefined, request_timeout_seconds: timeout, }); await loadStatus(); setSelectedProvider(null); } catch (err: any) { setProviderError(err.message || pickAppText(locale, '保存提供商配置失败', 'Failed to save provider settings')); } finally { setSavingProvider(false); } }; if (loading) { return (
); } if (error) { return (

{pickAppText(locale, '无法连接到 Boardware Agent Sandbox 后端', 'Unable to connect to the Boardware Agent Sandbox backend')}

{error}

{pickAppText(locale, '请确认后端服务已启动,并且当前页面可以访问它。', 'Please confirm the backend service is running and reachable from this page.')}

); } if (!status) return null; return (

{pickAppText(locale, '配置', 'Settings')}

{pickAppText( locale, '集中管理模型、工具、集成和实例运行状态。Task 和通知只在各自页面处理。', 'Manage models, tools, integrations, and instance runtime status. Tasks and notifications stay in their own pages.' )}

{/* System Info */} {pickAppText(locale, '实例运行', 'Instance runtime')}

{pickAppText(locale, '运行与调试', 'Runtime and debugging')}

{pickAppText(locale, '查看每次对话的运行日志和当前实例运行状态。', 'Inspect per-chat runtime logs and current instance status.')}

{/* Model Config */} {pickAppText(locale, '智能体配置', 'Agent configuration')} {/* Providers */} {pickAppText(locale, '提供商', 'Providers')}
{status.providers.map((p) => ( ))}
!open && setSelectedProvider(null)}> {pickAppText(locale, '配置提供商', 'Configure provider')} {selectedProvider ? ` · ${providerLabel(selectedProvider)}` : ''} {pickAppText(locale, '启用后会把它设为当前实例默认提供商。API Key 留空会保留已保存的值。', 'When enabled, this becomes the default provider for this instance. Leave API key empty to keep the saved value.')}

{pickAppText(locale, '关闭会从配置中移除这个提供商', 'Turning this off removes this provider from config')}

setProviderForm((prev) => ({ ...prev, enabled: checked }))} />
setProviderForm((prev) => ({ ...prev, model: event.target.value }))} placeholder="qwen-plus" disabled={!providerForm.enabled} />
setProviderForm((prev) => ({ ...prev, apiKey: event.target.value }))} placeholder={selectedProvider?.api_key_masked || pickAppText(locale, '留空保持不变', 'Leave blank to keep existing')} disabled={!providerForm.enabled || Boolean(selectedProvider?.is_oauth)} />
setProviderForm((prev) => ({ ...prev, apiBase: event.target.value }))} placeholder={selectedProvider?.default_api_base || 'https://api.example.com/v1'} disabled={!providerForm.enabled || Boolean(selectedProvider?.is_oauth)} />
setProviderForm((prev) => ({ ...prev, requestTimeoutSeconds: event.target.value }))} placeholder={pickAppText(locale, '默认', 'Default')} disabled={!providerForm.enabled} />
{providerError ? (

{providerError}

) : null}
{/* Channels */} {pickAppText(locale, '通道', 'Channels')}
{status.channels.map((ch) => (
{ch.enabled ? pickAppText(locale, '开启', 'On') : pickAppText(locale, '关闭', 'Off')} {ch.name}
))}
); } function InfoRow({ label, value, ok, }: { label: string; value: string; ok?: boolean; }) { return (
{label}
{value} {ok !== undefined && (ok ? ( ) : ( ))}
); } function providerLabel(provider: ProviderStatus): string { return provider.label || provider.name; }