/** * ConfigPanel Component * * 配置面板组件 */ import { useState, useEffect } from 'react'; import { getConfig, updateConfig, type ServerConfig } from '../api/client'; interface ConfigPanelProps { onClose: () => void; } // 可用的模型列表 const AVAILABLE_MODELS = [ { id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4' }, { id: 'claude-3-5-sonnet-20241022', name: 'Claude 3.5 Sonnet' }, { id: 'claude-3-opus-20240229', name: 'Claude 3 Opus' }, { id: 'claude-3-haiku-20240307', name: 'Claude 3 Haiku' }, ]; export function ConfigPanel({ onClose }: ConfigPanelProps) { const [config, setConfig] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); // 表单状态 const [formData, setFormData] = useState({ model: '', maxTokens: 8192, temperature: 0.7, workdir: '', }); // 加载配置 useEffect(() => { async function loadConfig() { try { const response = await getConfig(); setConfig(response.data); setFormData({ model: response.data.model, maxTokens: response.data.maxTokens, temperature: response.data.temperature, workdir: response.data.workdir, }); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load config'); } finally { setLoading(false); } } loadConfig(); }, []); // 保存配置 const handleSave = async () => { setSaving(true); setError(null); setSuccess(false); try { const response = await updateConfig(formData); setConfig(response.data); setSuccess(true); setTimeout(() => setSuccess(false), 2000); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to save config'); } finally { setSaving(false); } }; // 重置为默认值 const handleReset = () => { if (config) { setFormData({ model: config.model, maxTokens: config.maxTokens, temperature: config.temperature, workdir: config.workdir, }); } }; if (loading) { return (
Loading configuration...
); } return (
{/* Header */}

Configuration

{/* Content */}
{/* Error message */} {error && (
{error}
)} {/* Success message */} {success && (
Configuration saved successfully!
)} {/* Model */}

Select the AI model to use for conversations

{/* Max Tokens */}
setFormData({ ...formData, maxTokens: parseInt(e.target.value) })} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" />
1K 8K 16K 32K

Maximum number of tokens in the response

{/* Temperature */}
setFormData({ ...formData, temperature: parseFloat(e.target.value) })} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer" />
Precise (0) Balanced (0.5) Creative (1)

Controls randomness in responses

{/* Working Directory */}
setFormData({ ...formData, workdir: e.target.value })} className="w-full px-3 py-2 bg-gray-900 border border-gray-700 rounded-lg text-white focus:outline-none focus:border-blue-500 font-mono text-sm" placeholder="/path/to/project" />

Root directory for file operations

{/* Server Info (Read-only) */} {config && (

Server Information

Allowed Paths: {config.allowedPaths.length || 'All'}
Denied Paths: {config.deniedPaths.length || 'None'}
)}
{/* Footer */}
); }