diff --git a/admin/app/services/benchmark_service.ts b/admin/app/services/benchmark_service.ts index 3741d4a..5aeb6f5 100644 --- a/admin/app/services/benchmark_service.ts +++ b/admin/app/services/benchmark_service.ts @@ -116,6 +116,15 @@ export class BenchmarkService { throw new Error('No benchmark result found to submit') } + // Only allow full benchmarks with AI data to be submitted to repository + if (result.benchmark_type !== 'full') { + throw new Error('Only full benchmarks can be shared with the community. Run a Full Benchmark to share your results.') + } + + if (!result.ai_tokens_per_second || result.ai_tokens_per_second <= 0) { + throw new Error('Benchmark must include AI performance data. Ensure AI Assistant is installed and run a Full Benchmark.') + } + if (result.submitted_to_repository) { throw new Error('Benchmark result has already been submitted') } diff --git a/admin/inertia/pages/settings/benchmark.tsx b/admin/inertia/pages/settings/benchmark.tsx index 9a478ef..bbcb89d 100644 --- a/admin/inertia/pages/settings/benchmark.tsx +++ b/admin/inertia/pages/settings/benchmark.tsx @@ -1,4 +1,4 @@ -import { Head } from '@inertiajs/react' +import { Head, Link } from '@inertiajs/react' import { useState, useEffect } from 'react' import SettingsLayout from '~/layouts/SettingsLayout' import { useQuery, useMutation } from '@tanstack/react-query' @@ -31,6 +31,23 @@ export default function BenchmarkPage(props: { const [progress, setProgress] = useState(null) const [isRunning, setIsRunning] = useState(props.benchmark.status !== 'idle') const [showDetails, setShowDetails] = useState(false) + const [showAIRequiredAlert, setShowAIRequiredAlert] = useState(false) + + // Check if AI Assistant is installed + const { data: aiInstalled } = useQuery({ + queryKey: ['services', 'ai-installed'], + queryFn: async () => { + const res = await fetch('/api/system/services') + const data = await res.json() + const services = Array.isArray(data) ? data : (data.services || []) + const openWebUI = services.find((s: any) => + s.service_name === 'nomad_open_webui' || s.serviceName === 'nomad_open_webui' + ) + return openWebUI?.installed === true || openWebUI?.installed === 1 + }, + staleTime: 0, + refetchOnMount: true, + }) // Fetch latest result const { data: latestResult, refetch: refetchLatest } = useQuery({ @@ -124,6 +141,23 @@ export default function BenchmarkPage(props: { }, }) + // Check if the latest result is a full benchmark with AI data (eligible for sharing) + const canShareBenchmark = latestResult && + latestResult.benchmark_type === 'full' && + latestResult.ai_tokens_per_second !== null && + latestResult.ai_tokens_per_second > 0 && + !latestResult.submitted_to_repository + + // Handle Full Benchmark click with pre-flight check + const handleFullBenchmarkClick = () => { + if (!aiInstalled) { + setShowAIRequiredAlert(true) + return + } + setShowAIRequiredAlert(false) + runBenchmark.mutate('full') + } + // Simulate progress during sync benchmark (since we don't get SSE updates) useEffect(() => { if (!isRunning || progress?.status === 'completed' || progress?.status === 'error') return @@ -269,13 +303,30 @@ export default function BenchmarkPage(props: { onDismiss={() => setProgress(null)} /> )} + {showAIRequiredAlert && ( + setShowAIRequiredAlert(false)} + > + + Go to Apps to install AI Assistant → + + + )}

Run a benchmark to measure your system's CPU, memory, disk, and AI inference performance. The benchmark takes approximately 2-5 minutes to complete.

runBenchmark.mutate('full')} + onClick={handleFullBenchmarkClick} disabled={runBenchmark.isPending} icon='PlayIcon' > @@ -292,12 +343,21 @@ export default function BenchmarkPage(props: { runBenchmark.mutate('ai')} - disabled={runBenchmark.isPending} + disabled={runBenchmark.isPending || !aiInstalled} icon='SparklesIcon' + title={!aiInstalled ? 'AI Assistant must be installed to run AI benchmark' : undefined} > AI Only
+ {!aiInstalled && ( +

+ Note: AI Assistant is not installed. + + Install it + to run full benchmarks and share results with the community. +

+ )} )} @@ -331,7 +391,9 @@ export default function BenchmarkPage(props: {

Your NOMAD Score is a weighted composite of all benchmark results.

- {!latestResult.submitted_to_repository && ( + + {/* Share with Community - Only for full benchmarks with AI data */} + {canShareBenchmark && (

Share your benchmark score anonymously with the NOMAD community. Only your hardware specs and scores are sent — no identifying information. @@ -355,6 +417,17 @@ export default function BenchmarkPage(props: { )}

)} + + {/* Show message for partial benchmarks */} + {latestResult && !latestResult.submitted_to_repository && !canShareBenchmark && ( + + )} + {latestResult.submitted_to_repository && (