import React, { useState, useEffect } from 'react'; import AttentionPreview from '@/components/AttentionPreview'; import AttentionModal from '@/components/AttentionModal'; import ResponseDisplay from '@/components/ResponseDisplay'; import PromptDisplay from '@/components/PromptDisplay'; import AttentionStats from '@/components/AttentionStats'; interface TestCase { category: string; query: string; description: string; } interface AttentionData { tokens: string[]; attention_matrix: number[][]; num_layers: number; num_heads: number; } interface LLMCall { step_num: number; step_type: string; prompt: string; // Full prompt text response: string; // Full response text tokens: string[]; // All tokens (input + output) input_tokens?: string[]; // Input tokens only output_tokens?: string[]; // Output tokens only input_token_count?: number; output_token_count?: number; total_token_count?: number; attention_data: AttentionData; tool_info?: any; } interface Trajectory { id: string; timestamp: string; test_case: TestCase; response: string; tokens: string[]; attention_data: AttentionData; llm_calls?: LLMCall[]; // Multiple LLM calls for ReAct agents reasoning_steps?: any[]; // ReAct reasoning steps metadata: { model: string; temperature: number; max_tokens: number; device: string; total_llm_calls?: number; total_steps?: number; step_breakdown?: any; }; } export default function Home() { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [trajectories, setTrajectories] = useState([]); const [selectedTrajectoryIndex, setSelectedTrajectoryIndex] = useState(0); const [selectedLLMCallIndex, setSelectedLLMCallIndex] = useState(0); const [isModalOpen, setIsModalOpen] = useState(false); useEffect(() => { loadTrajectories(); }, []); const loadTrajectories = async () => { try { setLoading(true); setError(null); // Try to fetch manifest file const manifestResponse = await fetch('/trajectories/manifest.json'); if (!manifestResponse.ok) { // Try to load from a single results.json for backward compatibility try { const resultsResponse = await fetch('/results.json'); if (resultsResponse.ok) { const data = await resultsResponse.json(); setTrajectories(Array.isArray(data) ? data : [data]); return; } } catch (e) { // No results.json either } setError('No trajectory files found. Please run the agent first.'); return; } const manifest = await manifestResponse.json(); if (!manifest || manifest.length === 0) { setError('No trajectories in manifest. Please run the agent first.'); return; } // Load each trajectory file from manifest const loadedTrajectories: Trajectory[] = []; for (const entry of manifest) { try { const trajResponse = await fetch(`/trajectories/${entry.filename}`); if (trajResponse.ok) { const trajData = await trajResponse.json(); loadedTrajectories.push(trajData); } } catch (e) { console.error(`Failed to load ${entry.filename}:`, e); } } // Sort by timestamp (newest first) loadedTrajectories.sort((a, b) => b.timestamp.localeCompare(a.timestamp)); setTrajectories(loadedTrajectories); if (loadedTrajectories.length === 0) { setError('No valid trajectories could be loaded.'); } } catch (err: any) { console.error('Failed to load trajectories:', err); setError(err.message || 'Failed to load trajectory files'); } finally { setLoading(false); } }; const currentTrajectory = trajectories[selectedTrajectoryIndex]; const currentLLMCall = currentTrajectory?.llm_calls?.[selectedLLMCallIndex]; // Use LLM call data if available, otherwise fall back to main trajectory data const displayData = currentLLMCall ? { prompt: currentLLMCall.prompt, // Full prompt from LLM call response: currentLLMCall.response, // Full response from LLM call tokens: currentLLMCall.output_tokens || currentLLMCall.tokens, // Output tokens for response display input_tokens: currentLLMCall.input_tokens, // Input tokens for prompt display attention_data: currentLLMCall.attention_data } : currentTrajectory ? { prompt: currentTrajectory.test_case.query, // Use query as prompt if no LLM calls response: currentTrajectory.response, tokens: currentTrajectory.tokens, input_tokens: undefined, attention_data: currentTrajectory.attention_data } : null; const categoryColors: { [key: string]: string } = { 'Math': 'bg-blue-100 text-blue-800 border-blue-300', 'Knowledge': 'bg-green-100 text-green-800 border-green-300', 'Reasoning': 'bg-purple-100 text-purple-800 border-purple-300', 'Code': 'bg-orange-100 text-orange-800 border-orange-300', 'Creative': 'bg-pink-100 text-pink-800 border-pink-300', 'Tool Use': 'bg-indigo-100 text-indigo-800 border-indigo-300', 'ReAct': 'bg-purple-100 text-purple-800 border-purple-300', 'General': 'bg-gray-100 text-gray-800 border-gray-300', 'Custom': 'bg-yellow-100 text-yellow-800 border-yellow-300' }; const handleTrajectorySelect = (index: number) => { setSelectedTrajectoryIndex(index); setSelectedLLMCallIndex(0); // Reset to first LLM call when switching trajectories }; if (loading) { return (

Loading trajectories...

); } if (error && trajectories.length === 0) { return (

No Trajectories Found

{error}

To generate trajectories:

  1. Go to the project root directory
  2. Run: python main.py
  3. Refresh this page
); } return (
{/* Header */}

Attention Visualization

Explore how language models process information through attention mechanisms

{trajectories.length > 0 && (

{trajectories.length} trajectory{trajectories.length !== 1 ? 'ies' : ''} loaded

)}
{/* Trajectory Tabs */} {trajectories.length > 1 && (
{trajectories.map((traj, index) => { const colors = categoryColors[traj.test_case.category] || categoryColors['General']; return ( ); })}
)} {/* Main Content */} {currentTrajectory && (
{/* Left Panel - Trajectory Info */}

Trajectory Details

{currentTrajectory.test_case.category}

{currentTrajectory.timestamp}

{currentTrajectory.test_case.description}

{/* LLM Call Selector for ReAct agents */} {currentTrajectory.llm_calls && currentTrajectory.llm_calls.length > 1 && (

LLM Calls

{currentTrajectory.llm_calls.map((call, idx) => ( ))}
)}

Model Settings

Model: {currentTrajectory.metadata.model}
Temperature: {currentTrajectory.metadata.temperature}
Max Tokens: {currentTrajectory.metadata.max_tokens}
Device: {currentTrajectory.metadata.device}
{currentTrajectory.metadata.total_llm_calls && (
Total LLM Calls: {currentTrajectory.metadata.total_llm_calls}
)}
{/* Center/Right Panel - Visualization */}
{/* Query Display - Always show the original query first */}

User Query

                    {currentTrajectory.test_case.query}
                  
{/* Show current LLM call info if viewing a specific call */} {currentLLMCall && ( <>

LLM Call {currentLLMCall.step_num} - {currentLLMCall.step_type}

Input: {currentLLMCall.input_token_count || currentLLMCall.input_tokens?.length || 0} tokens Output: {currentLLMCall.output_token_count || currentLLMCall.output_tokens?.length || 0} tokens
{/* Full Prompt Display */} {currentLLMCall.prompt && ( )} )} {displayData && ( <> {/* Full Model Response Display */} {displayData.attention_data.attention_matrix.length > 0 && ( <>

Attention Patterns

setIsModalOpen(true)} />

Click the preview above to view the full attention pattern

setIsModalOpen(false)} tokens={displayData.attention_data.tokens} attentionWeights={displayData.attention_data.attention_matrix} /> )} )}
)} {/* Footer */}

To generate more trajectories, run: python agent.py or python main.py

); }