diff --git a/web/src/pages/Benchmarks/index.jsx b/web/src/pages/Benchmarks/index.jsx index ca74470..ff74f1a 100644 --- a/web/src/pages/Benchmarks/index.jsx +++ b/web/src/pages/Benchmarks/index.jsx @@ -40,6 +40,49 @@ const CATEGORIES = [ { key: 'video', label: '视频模型', icon: Zap }, ]; +/* ─── Default benchmark data (fallback when API unavailable) ─── */ +const DEFAULT_MODELS = [ + // ── OpenAI ── + { name: 'GPT-4o', provider: 'OpenAI', intelligence: 55, speed: 150, price: 2.50, latency: 0.8, context_window: '128K', type: 'general', category: 'language' }, + { name: 'GPT-4o Mini', provider: 'OpenAI', intelligence: 42, speed: 420, price: 0.15, latency: 0.4, context_window: '128K', type: 'general', category: 'language' }, + { name: 'o1', provider: 'OpenAI', intelligence: 58, speed: 30, price: 15.00, latency: 8.0, context_window: '200K', type: 'reasoning', category: 'language' }, + { name: 'o1-mini', provider: 'OpenAI', intelligence: 48, speed: 75, price: 3.00, latency: 3.0, context_window: '128K', type: 'reasoning', category: 'language' }, + { name: 'o3-mini', provider: 'OpenAI', intelligence: 50, speed: 85, price: 4.40, latency: 2.5, context_window: '200K', type: 'reasoning', category: 'language' }, + { name: 'GPT-4o Realtime', provider: 'OpenAI', intelligence: 54, speed: 55, price: 5.00, latency: 0.2, context_window: '128K', type: 'general', category: 'language' }, + // ── Anthropic ── + { name: 'Claude Sonnet 4', provider: 'Anthropic', intelligence: 56, speed: 120, price: 3.00, latency: 1.0, context_window: '200K', type: 'general', category: 'language' }, + { name: 'Claude Haiku 3.5', provider: 'Anthropic', intelligence: 44, speed: 380, price: 0.80, latency: 0.5, context_window: '200K', type: 'general', category: 'language' }, + { name: 'Claude Opus 4', provider: 'Anthropic', intelligence: 59, speed: 40, price: 15.00, latency: 4.0, context_window: '200K', type: 'general', category: 'language' }, + // ── Google ── + { name: 'Gemini 2.5 Pro', provider: 'Google', intelligence: 57, speed: 200, price: 1.25, latency: 1.2, context_window: '1M', type: 'general', category: 'language' }, + { name: 'Gemini 2.0 Flash', provider: 'Google', intelligence: 46, speed: 550, price: 0.10, latency: 0.3, context_window: '1M', type: 'general', category: 'language' }, + { name: 'Gemini 2.5 Flash', provider: 'Google', intelligence: 48, speed: 480, price: 0.15, latency: 0.4, context_window: '1M', type: 'general', category: 'language' }, + // ── DeepSeek ── + { name: 'DeepSeek-V3', provider: 'DeepSeek', intelligence: 52, speed: 220, price: 0.27, latency: 0.6, context_window: '128K', type: 'general', category: 'language' }, + { name: 'DeepSeek-R1', provider: 'DeepSeek', intelligence: 56, speed: 55, price: 0.55, latency: 8.0, context_window: '128K', type: 'reasoning', category: 'language' }, + // ── Meta ── + { name: 'Llama 3.1 405B', provider: 'Meta', intelligence: 50, speed: 60, price: 2.80, latency: 3.0, context_window: '128K', type: 'general', category: 'language' }, + { name: 'Llama 3.1 70B', provider: 'Meta', intelligence: 44, speed: 180, price: 0.59, latency: 1.0, context_window: '128K', type: 'general', category: 'language' }, + // ── Mistral ── + { name: 'Mistral Large 2', provider: 'Mistral', intelligence: 51, speed: 140, price: 2.00, latency: 1.5, context_window: '128K', type: 'general', category: 'language' }, + { name: 'Mistral Small', provider: 'Mistral', intelligence: 40, speed: 350, price: 0.20, latency: 0.4, context_window: '32K', type: 'general', category: 'language' }, + // ── 国内模型 ── + { name: 'Qwen-Max-0428', provider: 'Alibaba Cloud', intelligence: 52, speed: 160, price: 2.00, latency: 1.2, context_window: '128K', type: 'general', category: 'language' }, + { name: 'Qwen-Plus', provider: 'Alibaba Cloud', intelligence: 44, speed: 280, price: 0.80, latency: 0.6, context_window: '128K', type: 'general', category: 'language' }, + { name: 'Doubao-Pro-32k', provider: 'ByteDance', intelligence: 48, speed: 250, price: 0.60, latency: 0.8, context_window: '32K', type: 'general', category: 'language' }, + { name: 'GLM-4-Plus', provider: 'Zhipu AI', intelligence: 47, speed: 200, price: 1.00, latency: 0.9, context_window: '128K', type: 'general', category: 'language' }, + { name: 'MiniMax-Text-01', provider: 'MiniMax', intelligence: 45, speed: 210, price: 0.80, latency: 0.7, context_window: '1M', type: 'general', category: 'language' }, + { name: 'Kimi-k2', provider: 'Moonshot', intelligence: 53, speed: 120, price: 2.00, latency: 1.8, context_window: '128K', type: 'general', category: 'language' }, + // ── 图像模型 ── + { name: 'DALL·E 3', provider: 'OpenAI', intelligence: 48, speed: 15, price: 40.00, latency: 5.0, context_window: '-', type: 'general', category: 'image' }, + { name: 'Stable Diffusion 3', provider: 'Stability AI', intelligence: 44, speed: 8, price: 6.50, latency: 8.0, context_window: '-', type: 'general', category: 'image' }, + { name: 'Midjourney 6', provider: 'Midjourney', intelligence: 50, speed: 12, price: 30.00, latency: 10.0, context_window: '-', type: 'general', category: 'image' }, + { name: 'Flux.1 Pro', provider: 'Black Forest Labs', intelligence: 47, speed: 10, price: 5.00, latency: 6.0, context_window: '-', type: 'general', category: 'image' }, + // ── 视频模型 ── + { name: 'Sora', provider: 'OpenAI', intelligence: 46, speed: 0.5, price: 100.00, latency: 30.0, context_window: '-', type: 'general', category: 'video' }, + { name: 'Runway Gen-3', provider: 'Runway', intelligence: 43, speed: 0.8, price: 50.00, latency: 25.0, context_window: '-', type: 'general', category: 'video' }, +]; + const Benchmarks = () => { const { t } = useTranslation(); const [models, setModels] = useState([]); @@ -50,24 +93,26 @@ const Benchmarks = () => { const [activeCategory, setActiveCategory] = useState('all'); useEffect(() => { - const fetchData = async () => { + // Show default data immediately for instant rendering + setModels(DEFAULT_MODELS); + // Try to fetch backend data in background + (async () => { try { const res = await API.get('/api/option/'); - if (res.data.success && res.data.data) { - const option = res.data.data.find( - (o) => o.key === 'benchmark_data.models', - ); - if (option && option.value) { - setModels(JSON.parse(option.value)); + if (res.data?.success && res.data?.data) { + const option = res.data.data.find((o) => o.key === 'benchmark_data.models'); + if (option?.value) { + const parsed = JSON.parse(option.value); + if (Array.isArray(parsed) && parsed.length > 0) { + setModels(parsed); + } } } } catch { - // fallback: use embeded default data - } finally { - setLoading(false); + // keep default data } - }; - fetchData(); + })(); + setLoading(false); }, []); const filteredModels = useMemo(() => {