import { useState, useMemo, useEffect } from 'react'; import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Cpu } from 'lucide-react'; import ResponseBlock from './ResponseBlock'; import ResponseCarousel from './ResponseCarousel'; function buildModelLookup(providers) { const map = {}; for (const p of providers) { for (const m of p.models) { map[m.id] = { name: m.name, params: m.params || '' }; } } return map; } function useWindowWidth() { const [width, setWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1200); useEffect(() => { const onResize = () => setWidth(window.innerWidth); window.addEventListener('resize', onResize); return () => window.removeEventListener('resize', onResize); }, []); return width; } export default function ResultsArea({ results, multipleNeon, comparisonModelOrder = [], comparisonProviders = [], showPersonaPrompt = false, showPrePromptIndicator = false }) { const [carouselOffset, setCarouselOffset] = useState(0); const screenWidth = useWindowWidth(); const modelLookup = useMemo(() => buildModelLookup(comparisonProviders), [comparisonProviders]); const orderedComparisonIds = comparisonModelOrder; const sortComparisons = (responses) => { const byId = {}; for (const r of responses) byId[r.model_id] = r; const ordered = []; for (const id of orderedComparisonIds) { if (byId[id]) ordered.push(byId[id]); } for (const r of responses) { if (!orderedComparisonIds.includes(r.model_id)) ordered.push(r); } return ordered; }; const totalComparisons = orderedComparisonIds.length; const isMobile = screenWidth <= 480; const isTablet = screenWidth <= 900; const visible = isMobile ? 1 : (isTablet ? 1 : 2); const maxOffset = Math.max(0, totalComparisons - visible); const skipStart = () => setCarouselOffset(0); const prev = () => setCarouselOffset(o => Math.max(0, o - 1)); const next = () => setCarouselOffset(o => Math.min(maxOffset, o + 1)); const skipEnd = () => setCarouselOffset(maxOffset); const visibleComparisonIds = orderedComparisonIds.slice(carouselOffset, carouselOffset + visible); const visibleColumnHeaders = visibleComparisonIds.map(id => { const info = modelLookup[id]; return info ? { name: info.name, params: info.params } : { name: id.split('/').pop(), params: '' }; }); if (!results.length) { return null; } return (
{results.map((result, ri) => (
{multipleNeon ? ( <>
Q: {result.query}
{showPersonaPrompt && result.groups.map((group, gi) => { if (!group.system_prompt) return null; const rawId = (group.neon_model_id || '').split('@')[0]; const modelName = rawId.includes('/') ? rawId.split('/').pop() : rawId; const persona = group.neon_persona || ''; const label = `${modelName} - ${persona} pre-prompt:`; return (
{label} {group.system_prompt}
); })} {totalComparisons > visible && (
{carouselOffset + 1}–{Math.min(carouselOffset + visible, totalComparisons)} of {totalComparisons}
)}
Neon.ai 24B (quantized)
{visibleColumnHeaders.map((col, i) => (
{col.name} {col.params && {col.params}}
))}
{result.groups.map((group, gi) => { const neonResponse = group.responses.find(r => r.is_neon); const comparisonResponses = sortComparisons(group.responses.filter(r => !r.is_neon)); return (
{neonResponse ? ( ) : (
{comparisonResponses.map((r, ci) => ( ))} {group.responses.length === 0 && (
Waiting for responses...
)}
)}
); })} ) : ( <>
Q: {result.query}
{showPersonaPrompt && result.groups[0]?.system_prompt && (() => { const g = result.groups[0]; const rawId = (g.neon_model_id || '').split('@')[0]; const modelName = rawId.includes('/') ? rawId.split('/').pop() : rawId; const persona = g.neon_persona || ''; const label = `${modelName} - ${persona} pre-prompt:`; return (
{label} {g.system_prompt}
); })()} {result.groups.map((group, gi) => { const neonResponse = group.responses.find(r => r.is_neon); const comparisonResponses = sortComparisons(group.responses.filter(r => !r.is_neon)); return (
{neonResponse && ( )} {comparisonResponses.map((r, ci) => ( ))} {group.responses.length === 0 && (
Waiting for responses...
)}
); })} )}
))}
); }