import React, { useState, useEffect } from 'react'; import './../styles/App.css'; const DebateConfiguration = ({ onCreateDebate, onViewSessions, onViewSettings, isGuest }) => { const [formData, setFormData] = useState({ topic: '', proProvider: 'openai', proModel: 'gpt-4', conProvider: 'claude', conModel: 'claude-3-opus', maxRounds: 5, maxTokens: 500, webSearchEnabled: false, webSearchMode: 'auto' }); const [availableModels, setAvailableModels] = useState({ openai: [], claude: [], qwen: [], deepseek: [] }); const [availableProviders, setAvailableProviders] = useState([ { provider: 'openai', display_name: 'OpenAI' }, { provider: 'claude', display_name: 'Claude' }, { provider: 'qwen', display_name: 'Qwen' }, { provider: 'deepseek', display_name: 'DeepSeek' } ]); const [isLoading, setIsLoading] = useState(false); const [modelsLoading, setModelsLoading] = useState({}); useEffect(() => { // Load available providers when component mounts loadAvailableProviders(); }, []); const loadAvailableProviders = async () => { try { // Get all API keys from backend to determine which providers are available const providers = ['openai', 'claude', 'qwen', 'deepseek']; const available = []; for (const provider of providers) { try { const response = await fetch(`http://localhost:8000/api-keys/${provider}`); if (response.ok) { const data = await response.json(); if (data.api_key) { // For Qwen and DeepSeek, we can check if the key is valid if (provider === 'qwen' || provider === 'deepseek') { // For now, just check if key exists - we'll implement validation later if needed available.push({ provider: provider, display_name: provider.charAt(0).toUpperCase() + provider.slice(1) }); } else { // For OpenAI and Claude, we're skipping validation as requested available.push({ provider: provider, display_name: provider.charAt(0).toUpperCase() + provider.slice(1) }); } } } } catch (error) { // If there's an error getting the API key, skip this provider console.error(`Error getting API key for ${provider}:`, error); } } if (available.length > 0) { setAvailableProviders(available); // Update form data to use valid providers if (!available.some(p => p.provider === formData.proProvider)) { setFormData(prev => ({ ...prev, proProvider: available[0]?.provider || prev.proProvider })); } if (!available.some(p => p.provider === formData.conProvider)) { setFormData(prev => ({ ...prev, conProvider: available[0]?.provider || prev.conProvider })); } } else { // If no providers have API keys, show all providers but disable functionality setAvailableProviders([ { provider: 'openai', display_name: 'OpenAI' }, { provider: 'claude', display_name: 'Claude' }, { provider: 'qwen', display_name: 'Qwen' }, { provider: 'deepseek', display_name: 'DeepSeek' } ]); } } catch (error) { console.error('Error loading available providers:', error); } }; useEffect(() => { // Update model options when provider changes if (formData.proProvider) { loadModelsForProvider(formData.proProvider); } if (formData.conProvider) { loadModelsForProvider(formData.conProvider); } }, [formData.proProvider, formData.conProvider]); const loadModelsForProvider = async (provider) => { setModelsLoading(prev => ({ ...prev, [provider]: true })); try { // Special handling for Qwen - fetch directly from Qwen API if (provider === 'qwen') { try { // Call backend to get Qwen models (backend will fetch from Qwen API) const qwenResponse = await fetch(`http://localhost:8000/models/${provider}`); if (qwenResponse.ok) { const qwenData = await qwenResponse.json(); console.log('Backend Qwen models response:', qwenData); // Debug log const models = qwenData.models || []; console.log('Fetched Qwen models:', models); // Debug log setAvailableModels(prev => ({ ...prev, [provider]: models })); // Update selected model if current selection is not in the new list if (provider === formData.proProvider && models.length > 0) { const currentModelExists = models.some(model => model.model_identifier === formData.proModel); if (!currentModelExists) { setFormData(prev => ({ ...prev, proModel: models[0].model_identifier })); } } if (provider === formData.conProvider && models.length > 0) { const currentModelExists = models.some(model => model.model_identifier === formData.conModel); if (!currentModelExists) { setFormData(prev => ({ ...prev, conModel: models[0].model_identifier })); } } } else { console.error('Error fetching models from backend for Qwen:', qwenResponse.status, await qwenResponse.text()); // Use fallback models if API call fails const fallbackModels = [ { model_identifier: 'qwen3-max', display_name: 'Qwen3 Max' }, { model_identifier: 'qwen3-plus', display_name: 'Qwen3 Plus' }, { model_identifier: 'qwen3-flash', display_name: 'Qwen3 Flash' }, { model_identifier: 'qwen-max', display_name: 'Qwen Max' }, { model_identifier: 'qwen-plus', display_name: 'Qwen Plus' }, { model_identifier: 'qwen-turbo', display_name: 'Qwen Turbo' } ]; setAvailableModels(prev => ({ ...prev, [provider]: fallbackModels })); if (provider === formData.proProvider) { setFormData(prev => ({ ...prev, proModel: fallbackModels[0].model_identifier })); } if (provider === formData.conProvider) { setFormData(prev => ({ ...prev, conModel: fallbackModels[0].model_identifier })); } } } catch (error) { console.error('Network error when fetching Qwen models from backend:', error); // Use fallback models if network request fails const fallbackModels = [ { model_identifier: 'qwen-max', display_name: 'Qwen Max' }, { model_identifier: 'qwen-plus', display_name: 'Qwen Plus' }, { model_identifier: 'qwen-turbo', display_name: 'Qwen Turbo' } ]; setAvailableModels(prev => ({ ...prev, [provider]: fallbackModels })); if (provider === formData.proProvider) { setFormData(prev => ({ ...prev, proModel: fallbackModels[0].model_identifier })); } if (provider === formData.conProvider) { setFormData(prev => ({ ...prev, conModel: fallbackModels[0].model_identifier })); } } } else { // For other providers, use the backend API const response = await fetch(`http://localhost:8000/models/${provider}`); if (response.ok) { const data = await response.json(); setAvailableModels(prev => ({ ...prev, [provider]: data.models || [] })); // Update selected model if current selection is not in the new list if (provider === formData.proProvider && data.models && data.models.length > 0) { const currentModelExists = data.models.some(model => model.model_identifier === formData.proModel); if (!currentModelExists) { setFormData(prev => ({ ...prev, proModel: data.models[0].model_identifier })); } } if (provider === formData.conProvider && data.models && data.models.length > 0) { const currentModelExists = data.models.some(model => model.model_identifier === formData.conModel); if (!currentModelExists) { setFormData(prev => ({ ...prev, conModel: data.models[0].model_identifier })); } } } } } catch (error) { console.error(`Error loading models for ${provider}:`, error); } finally { setModelsLoading(prev => ({ ...prev, [provider]: false })); } }; const handleChange = (e) => { const { name, value, type, checked } = e.target; setFormData(prev => ({ ...prev, [name]: type === 'checkbox' ? checked : value })); }; const handleSubmit = async (e) => { e.preventDefault(); setIsLoading(true); // Validate inputs if (!formData.topic.trim()) { alert('请输入辩论主题'); setIsLoading(false); return; } // Create debate request object const debateRequest = { topic: formData.topic, participants: [ { model_identifier: formData.proModel, provider: formData.proProvider, stance: "pro" }, { model_identifier: formData.conModel, provider: formData.conProvider, stance: "con" } ], constraints: { max_rounds: parseInt(formData.maxRounds), max_tokens_per_turn: parseInt(formData.maxTokens), web_search_enabled: formData.webSearchEnabled, web_search_mode: formData.webSearchMode } }; try { const response = await fetch('http://localhost:8000/debate/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(debateRequest) }); if (!response.ok) { throw new Error(`创建辩论失败: ${response.statusText}`); } const result = await response.json(); alert(`辩论创建成功!会话ID: ${result.session_id}`); // Pass the session ID to the parent component onCreateDebate(result.session_id); } catch (error) { console.error('Error creating debate:', error); alert(`创建辩论失败: ${error.message}`); } finally { setIsLoading(false); } }; return (

辩论配置

{modelsLoading[formData.proProvider] ? (
加载模型中...
) : ( )} 正方
{modelsLoading[formData.conProvider] ? (
加载模型中...
) : ( )} 反方
{formData.webSearchEnabled && (
)}
{isGuest && (

请先登录后再创建辩论

)}
{onViewSettings && ( )}
); }; export default DebateConfiguration;