"use client"; import { useState, useEffect } from "react"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, Cell, } 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 }[]; } const EXAMPLES = [ { q: "What theory describes gravity as the curvature of spacetime caused by mass and energy?", type: "Factoid" }, { q: "What biological process converts sunlight and CO₂ into glucose in plants?", type: "Factoid" }, { q: "What molecule stores and transmits genetic information in all living cells?", type: "Factoid" }, { q: "What field of physics describes matter behavior at the subatomic scale using wave functions?", type: "Factoid" }, { q: "Which chemical element with atomic number 6 forms the backbone of all organic molecules?", type: "Factoid" }, ]; const FALLBACK_PROVIDERS: ProviderInfo[] = [ { id: "openai", name: "OpenAI / BotLearn", isLocal: false, hasApiKey: false, defaultModel: "gpt-4o-mini", models: [{ id: "gpt-4o-mini", name: "GPT-4o Mini", speed: "fast", quality: "medium" }] }, { 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: "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: "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" }] }, ]; const PIPE_COLORS = { llmOnly: "#6c6a64", baseline: "#0072CE", graphrag: "#FF6B00", }; export function PlaygroundContent() { const [providers, setProviders] = useState(FALLBACK_PROVIDERS); const [loading, setLoading] = useState(false); const [query, setQuery] = useState(""); const [provider, setProvider] = useState("openai"); const [model, setModel] = useState(""); const [adaptiveRouting, setAdaptiveRouting] = useState(true); const [llmOnly, setLlmOnly] = useState(null); const [baseline, setBaseline] = useState(null); const [graphrag, setGraphrag] = useState(null); const [complexity, setComplexity] = useState(0); const [queryType, setQueryType] = useState(""); const [recommended, setRecommended] = useState(""); const [demoMode, setDemoMode] = useState(false); useEffect(() => { fetch("/api/providers").then(r => r.json()).then(d => { if (d.providers) setProviders(d.providers); }).catch(() => {}); }, []); const selectedProvider = providers.find(p => p.id === provider) || providers[0]; const selectedModel = model || selectedProvider?.defaultModel || ""; const runComparison = async () => { if (!query.trim()) return; setLoading(true); try { const res = await fetch("/api/compare", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, adaptiveRouting, provider, model: selectedModel }), }); const data = await res.json(); setLlmOnly(data.llmOnly ?? null); setBaseline(data.baseline ?? null); setGraphrag(data.graphrag ?? null); setComplexity(data.complexity ?? 0); setQueryType(data.queryType ?? ""); setRecommended(data.recommended ?? ""); setDemoMode(data.demoMode ?? false); } catch { // silently fail } setLoading(false); }; const chartData = llmOnly && baseline && graphrag ? [ { name: "Tokens", "LLM-Only": llmOnly.tokens, "Basic RAG": baseline.tokens, "GraphRAG": graphrag.tokens, }, { name: "Latency (ms)", "LLM-Only": Math.round(llmOnly.latencyMs), "Basic RAG": Math.round(baseline.latencyMs), "GraphRAG": Math.round(graphrag.latencyMs), }, ] : []; const tokenReduction = baseline && graphrag && baseline.tokens > 0 ? Math.round((1 - graphrag.tokens / baseline.tokens) * 100) : null; return (
{/* Provider Selection */}
{!selectedProvider?.hasApiKey && !selectedProvider?.isLocal && ( Demo Mode — No API Key )}
{/* Query Input */}