"use client"; import { useState, useEffect } from "react"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, } from "recharts"; interface PipelineResult { answer: string; tokens: number; latencyMs: number; costUsd: number; entities: string[]; relations: string[]; } interface ProviderInfo { id: string; name: string; isLocal: boolean; hasApiKey: boolean; defaultModel: string; models: { id: string; name: string; speed: string; quality: string }[]; notes?: string; } interface ComparisonState { loading: boolean; query: string; baseline: PipelineResult | null; graphrag: PipelineResult | null; complexity: number; queryType: string; recommended: string; provider: string; model: string; demoMode: boolean; } const EXAMPLES = [ "Were Scott Derrickson and Ed Wood of the same nationality?", "What government position was held by the woman who portrayed Nora Batty?", "Which magazine was started first, Arthur's Magazine or First for Women?", "Who was born first, Arthur Conan Doyle or Agatha Christie?", "What is the capital of the country where the Eiffel Tower is located?", ]; const FALLBACK_PROVIDERS: ProviderInfo[] = [ { id: "anthropic", name: "Anthropic Claude", isLocal: false, hasApiKey: false, defaultModel: "claude-sonnet-4-20250514", models: [{ id: "claude-sonnet-4-20250514", name: "Claude Sonnet 4", speed: "medium", quality: "high" }] }, { id: "openai", name: "OpenAI", isLocal: false, hasApiKey: false, defaultModel: "gpt-4o-mini", models: [{ id: "gpt-4o-mini", name: "GPT-4o Mini", speed: "fast", quality: "medium" }] }, { id: "gemini", name: "Google Gemini", isLocal: false, hasApiKey: false, defaultModel: "gemini-2.0-flash", models: [{ id: "gemini-2.0-flash", name: "Gemini 2.0 Flash", speed: "fast", quality: "medium" }] }, { id: "ollama", name: "Ollama (Local)", isLocal: true, hasApiKey: true, defaultModel: "llama3.2", models: [{ id: "llama3.2", name: "Llama 3.2 3B", speed: "fast", quality: "medium" }] }, { id: "groq", name: "Groq", isLocal: false, hasApiKey: false, defaultModel: "llama-3.3-70b-versatile", models: [{ id: "llama-3.3-70b-versatile", name: "Llama 3.3 70B", speed: "fast", quality: "high" }] }, { id: "mistral", name: "Mistral AI", isLocal: false, hasApiKey: false, defaultModel: "mistral-large-latest", models: [{ id: "mistral-large-latest", name: "Mistral Large", speed: "medium", quality: "high" }] }, { id: "deepseek", name: "DeepSeek", isLocal: false, hasApiKey: false, defaultModel: "deepseek-chat", models: [{ id: "deepseek-chat", name: "DeepSeek V3", speed: "fast", quality: "high" }] }, { id: "openrouter", name: "OpenRouter", isLocal: false, hasApiKey: false, defaultModel: "meta-llama/llama-3.3-70b-instruct", models: [{ id: "meta-llama/llama-3.3-70b-instruct", name: "Llama 3.3 70B", speed: "medium", quality: "high" }] }, { id: "cohere", name: "Cohere", isLocal: false, hasApiKey: false, defaultModel: "command-r-plus", models: [{ id: "command-r-plus", name: "Command R+", speed: "medium", quality: "high" }] }, { id: "xai", name: "xAI Grok", isLocal: false, hasApiKey: false, defaultModel: "grok-3-mini", models: [{ id: "grok-3-mini", name: "Grok 3 Mini", speed: "fast", quality: "medium" }] }, { id: "together", name: "Together AI", isLocal: false, hasApiKey: false, defaultModel: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo", models: [{ id: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo", name: "Llama 3.1 70B", speed: "fast", quality: "high" }] }, { id: "huggingface", name: "HuggingFace", isLocal: false, hasApiKey: false, defaultModel: "meta-llama/Llama-3.3-70B-Instruct", models: [{ id: "meta-llama/Llama-3.3-70B-Instruct", name: "Llama 3.3 70B", speed: "medium", quality: "high" }] }, ]; export function LiveCompare() { const [providers, setProviders] = useState(FALLBACK_PROVIDERS); const [state, setState] = useState({ loading: false, query: "", baseline: null, graphrag: null, complexity: 0, queryType: "", recommended: "", provider: "openai", model: "", demoMode: false, }); const [adaptiveRouting, setAdaptiveRouting] = useState(true); // Fetch available providers on mount useEffect(() => { fetch("/api/providers").then(r => r.json()).then(d => { if (d.providers) setProviders(d.providers); }).catch(() => {}); }, []); const selectedProvider = providers.find(p => p.id === state.provider) || providers[0]; const selectedModel = state.model || selectedProvider?.defaultModel || ""; const runComparison = async () => { if (!state.query.trim()) return; setState(s => ({ ...s, loading: true })); try { const res = await fetch("/api/compare", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: state.query, adaptiveRouting, provider: state.provider, model: selectedModel, }), }); const data = await res.json(); setState(s => ({ ...s, loading: false, baseline: data.baseline, graphrag: data.graphrag, complexity: data.complexity ?? 0, queryType: data.queryType ?? "", recommended: data.recommended ?? "", demoMode: data.demoMode ?? false, })); } catch { setState(s => ({ ...s, loading: false })); } }; const chartData = state.baseline && state.graphrag ? [ { name: "Tokens", Baseline: state.baseline.tokens, GraphRAG: state.graphrag.tokens }, { name: "Latency (ms)", Baseline: Math.round(state.baseline.latencyMs), GraphRAG: Math.round(state.graphrag.latencyMs) }, ] : []; return (
{/* Provider + Model Selector */}
{selectedProvider?.isLocal && ( Free / Local )} {!selectedProvider?.hasApiKey && !selectedProvider?.isLocal && ( Demo Mode )}
{/* Query Input */}
Ask a question