tfrere commited on
Commit
ebdfd67
·
1 Parent(s): f56e233

update frontend

Browse files
backend/requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+
backend/routes/questions.py CHANGED
@@ -37,10 +37,13 @@ async def get_benchmark_questions(session_id: str):
37
  if single_dataset and len(single_dataset['train']) > 0:
38
  # Get a random sample (up to 2) from single-shot questions
39
  sample_indices = random.sample(range(len(single_dataset['train'])), min(2, len(single_dataset['train'])))
 
40
  for idx in sample_indices:
 
41
  questions.append({
42
  "id": str(idx),
43
  "question": single_dataset['train'][idx].get("question", ""),
 
44
  "type": "single_shot"
45
  })
46
  print(f"Loaded {len(questions)} single-shot questions")
@@ -55,10 +58,13 @@ async def get_benchmark_questions(session_id: str):
55
  # Get remaining questions from multi-hop questions
56
  remaining = 2 - len(questions)
57
  sample_indices = random.sample(range(len(multi_dataset['train'])), min(remaining, len(multi_dataset['train'])))
 
58
  for idx in sample_indices:
 
59
  questions.append({
60
  "id": str(idx),
61
  "question": multi_dataset['train'][idx].get("question", ""),
 
62
  "type": "multi_hop"
63
  })
64
  print(f"Loaded {len(questions)} multi-hop questions")
 
37
  if single_dataset and len(single_dataset['train']) > 0:
38
  # Get a random sample (up to 2) from single-shot questions
39
  sample_indices = random.sample(range(len(single_dataset['train'])), min(2, len(single_dataset['train'])))
40
+ print(f"Dataset structure: {single_dataset['train'][0].keys()}")
41
  for idx in sample_indices:
42
+ print(f"Question {idx} data: {single_dataset['train'][idx]}")
43
  questions.append({
44
  "id": str(idx),
45
  "question": single_dataset['train'][idx].get("question", ""),
46
+ "answer": single_dataset['train'][idx].get("self_answer", "No answer available"),
47
  "type": "single_shot"
48
  })
49
  print(f"Loaded {len(questions)} single-shot questions")
 
58
  # Get remaining questions from multi-hop questions
59
  remaining = 2 - len(questions)
60
  sample_indices = random.sample(range(len(multi_dataset['train'])), min(remaining, len(multi_dataset['train'])))
61
+ print(f"Multi-hop dataset structure: {multi_dataset['train'][0].keys()}")
62
  for idx in sample_indices:
63
+ print(f"Multi-hop question {idx} data: {multi_dataset['train'][idx]}")
64
  questions.append({
65
  "id": str(idx),
66
  "question": multi_dataset['train'][idx].get("question", ""),
67
+ "answer": multi_dataset['train'][idx].get("self_answer", "No answer available"),
68
  "type": "multi_hop"
69
  })
70
  print(f"Loaded {len(questions)} multi-hop questions")
backend/tasks/createBench.py CHANGED
@@ -122,6 +122,8 @@ class CreateBenchTask:
122
  # Process the output line
123
  line = line.strip()
124
  if line:
 
 
125
  # Filter and format the line as needed
126
  if "ERROR" in line:
127
  self._add_log(f"[ERROR] {line}")
 
122
  # Process the output line
123
  line = line.strip()
124
  if line:
125
+ # Log raw output for debugging
126
+ self._add_log(f"[DEBUG] Raw output: {line}")
127
  # Filter and format the line as needed
128
  if "ERROR" in line:
129
  self._add_log(f"[ERROR] {line}")
frontend/src/App.js CHANGED
@@ -1,391 +1,22 @@
1
- import React, { useState, useEffect } from "react";
2
- import {
3
- Box,
4
- Container,
5
- CssBaseline,
6
- Typography,
7
- CircularProgress,
8
- } from "@mui/material";
9
  import {
10
  BrowserRouter as Router,
11
  Routes,
12
  Route,
13
  Navigate,
14
- useNavigate,
15
- useSearchParams,
16
  } from "react-router-dom";
17
  import getTheme from "./config/theme";
18
  import { useThemeMode } from "./hooks/useThemeMode";
19
  import { ThemeProvider } from "@mui/material/styles";
20
- import BenchmarkGenerator from "./components/BenchmarkGenerator";
21
- import BenchmarkCreateForm from "./components/BenchmarkCreateForm";
22
- import BenchmarkDisplay from "./components/BenchmarkDisplay";
23
- import BenchmarkEvaluation from "./components/BenchmarkEvaluation";
24
- import EvaluationDisplay from "./components/EvaluationDisplay";
25
-
26
- // Composant d'en-tête commun
27
- const Header = () => (
28
- <Box sx={{ textAlign: "center", mb: 8 }}>
29
- <h1>Yourbench Demo</h1>
30
- <p>
31
- Quickly create <b>zero-shot benchmarks</b> from your documents – keeping
32
- models accurate and adaptable
33
- </p>
34
- </Box>
35
- );
36
-
37
- // Page d'accueil avec le formulaire
38
- function HomePage() {
39
- const navigate = useNavigate();
40
-
41
- const handleStartGeneration = (sid) => {
42
- navigate(`/benchmark-generation?session=${sid}`);
43
- };
44
-
45
- return (
46
- <>
47
- <Header />
48
- <BenchmarkCreateForm onStartGeneration={handleStartGeneration} />
49
- </>
50
- );
51
- }
52
-
53
- // Page de génération de benchmark
54
- function BenchmarkGenerationPage() {
55
- const navigate = useNavigate();
56
- const [searchParams] = useSearchParams();
57
- const sessionId = searchParams.get("session");
58
- const [isValidSession, setIsValidSession] = useState(true);
59
-
60
- // Vérifier la validité de la session
61
- useEffect(() => {
62
- if (!sessionId) {
63
- setIsValidSession(false);
64
- }
65
- }, [sessionId]);
66
-
67
- const handleGenerationComplete = (result) => {
68
- console.log("Benchmark generation completed:", result);
69
- if (result && result.success) {
70
- navigate(`/benchmark-display?session=${sessionId}`);
71
- }
72
- };
73
-
74
- if (!isValidSession) {
75
- return <Navigate to="/" />;
76
- }
77
-
78
- return (
79
- <>
80
- <Header />
81
- <BenchmarkGenerator
82
- sessionId={sessionId}
83
- onComplete={handleGenerationComplete}
84
- />
85
- </>
86
- );
87
- }
88
-
89
- // Page d'affichage du benchmark
90
- function BenchmarkDisplayPage() {
91
- const navigate = useNavigate();
92
- const [searchParams] = useSearchParams();
93
- const sessionId = searchParams.get("session");
94
- const [benchmarkQuestions, setBenchmarkQuestions] = useState([]);
95
- const [datasetUrl, setDatasetUrl] = useState(null);
96
- const [isValidSession, setIsValidSession] = useState(true);
97
- const [isLoading, setIsLoading] = useState(true);
98
-
99
- // Récupérer les questions du benchmark depuis l'API
100
- useEffect(() => {
101
- console.log("BenchmarkDisplayPage useEffect - sessionId:", sessionId);
102
-
103
- if (!sessionId) {
104
- console.log("Session ID manquante, redirection vers l'accueil");
105
- setIsValidSession(false);
106
- return;
107
- }
108
-
109
- setIsLoading(true);
110
-
111
- const fetchBenchmarkQuestions = async () => {
112
- console.log(
113
- "Tentative de récupération des questions pour la session:",
114
- sessionId
115
- );
116
- try {
117
- const apiUrl = `http://localhost:3001/benchmark-questions/${sessionId}`;
118
- console.log("Appel API:", apiUrl);
119
-
120
- const response = await fetch(apiUrl);
121
- console.log("Réponse API reçue:", response.status);
122
-
123
- // Check if the response status is 404 (Not Found) or other error
124
- if (!response.ok) {
125
- if (response.status === 404) {
126
- console.error("Session non trouvée");
127
- setIsValidSession(false);
128
- return;
129
- } else {
130
- console.error(`Erreur serveur: ${response.status}`);
131
- setIsLoading(false);
132
- return;
133
- }
134
- }
135
-
136
- const data = await response.json();
137
- console.log("Données API:", data);
138
-
139
- if (data.success && data.questions && data.questions.length > 0) {
140
- console.log("Questions chargées avec succès:", data.questions);
141
- setBenchmarkQuestions(data.questions);
142
- } else {
143
- console.warn(
144
- "Échec du chargement des questions, utilisation des valeurs par défaut"
145
- );
146
- }
147
-
148
- if (data.dataset_url) {
149
- setDatasetUrl(data.dataset_url);
150
- } else {
151
- const url = `https://huggingface.co/datasets/yourbench/yourbench_${sessionId}`;
152
- setDatasetUrl(url);
153
- console.log("URL du dataset générée:", url);
154
- }
155
- } catch (error) {
156
- console.error("Erreur lors de la récupération des questions:", error);
157
- setIsValidSession(false);
158
- } finally {
159
- setIsLoading(false);
160
- }
161
- };
162
-
163
- fetchBenchmarkQuestions();
164
- }, [sessionId]);
165
-
166
- const handleStartEvaluation = () => {
167
- console.log("Starting evaluation with session ID:", sessionId);
168
- navigate(`/benchmark-evaluation?session=${sessionId}`);
169
- };
170
-
171
- // Questions par défaut si l'API échoue
172
- const defaultSampleQuestions = [
173
- {
174
- id: 1,
175
- question: "What are the key features discussed in the document?",
176
- type: "single_shot",
177
- },
178
- {
179
- id: 2,
180
- question:
181
- "How does the proposed solution address the challenges mentioned in section 2 in relation to the overall market trends?",
182
- type: "multi_hop",
183
- },
184
- ];
185
-
186
- if (!isValidSession) {
187
- return <Navigate to="/" />;
188
- }
189
-
190
- return (
191
- <>
192
- <Header />
193
- {isLoading ? (
194
- <Box
195
- sx={{
196
- display: "flex",
197
- justifyContent: "center",
198
- alignItems: "center",
199
- mt: 8,
200
- mb: 8,
201
- }}
202
- >
203
- <CircularProgress size={60} />
204
- </Box>
205
- ) : (
206
- <BenchmarkDisplay
207
- onStartEvaluation={handleStartEvaluation}
208
- sessionId={sessionId}
209
- datasetUrl={datasetUrl}
210
- sampleQuestions={
211
- benchmarkQuestions.length > 0
212
- ? benchmarkQuestions
213
- : defaultSampleQuestions
214
- }
215
- />
216
- )}
217
- </>
218
- );
219
- }
220
-
221
- // Page d'évaluation du benchmark
222
- function BenchmarkEvaluationPage() {
223
- const navigate = useNavigate();
224
- const [searchParams] = useSearchParams();
225
- const sessionId = searchParams.get("session");
226
- const [isValidSession, setIsValidSession] = useState(true);
227
- const [isLoading, setIsLoading] = useState(true);
228
-
229
- // Vérifier la validité de la session
230
- useEffect(() => {
231
- if (!sessionId) {
232
- console.log(
233
- "Session ID manquante pour l'évaluation, redirection vers l'accueil"
234
- );
235
- setIsValidSession(false);
236
- return;
237
- }
238
-
239
- // Verify session exists by calling the API
240
- const checkSession = async () => {
241
- try {
242
- const response = await fetch(
243
- `http://localhost:3001/benchmark-questions/${sessionId}`
244
- );
245
-
246
- if (!response.ok) {
247
- console.error(
248
- `Session invalide ou erreur serveur: ${response.status}`
249
- );
250
- setIsValidSession(false);
251
- }
252
- } catch (error) {
253
- console.error("Erreur lors de la vérification de la session:", error);
254
- setIsValidSession(false);
255
- } finally {
256
- setIsLoading(false);
257
- }
258
- };
259
-
260
- checkSession();
261
- }, [sessionId]);
262
-
263
- const handleEvaluationComplete = (result) => {
264
- console.log("Évaluation terminée:", result);
265
- // On reste sur la même page car les résultats sont affichés directement
266
- // dans le composant BenchmarkEvaluation
267
- };
268
-
269
- if (!isValidSession) {
270
- return <Navigate to="/" />;
271
- }
272
-
273
- return (
274
- <>
275
- <Header />
276
- {isLoading ? (
277
- <Box
278
- sx={{
279
- display: "flex",
280
- justifyContent: "center",
281
- alignItems: "center",
282
- mt: 8,
283
- mb: 8,
284
- }}
285
- >
286
- <CircularProgress size={60} />
287
- </Box>
288
- ) : (
289
- <BenchmarkEvaluation
290
- sessionId={sessionId}
291
- onComplete={handleEvaluationComplete}
292
- />
293
- )}
294
- </>
295
- );
296
- }
297
-
298
- // Page d'affichage des résultats d'évaluation
299
- function EvaluationDisplayPage() {
300
- const navigate = useNavigate();
301
- const [searchParams] = useSearchParams();
302
- const sessionId = searchParams.get("session");
303
- const [isValidSession, setIsValidSession] = useState(true);
304
- const [isLoading, setIsLoading] = useState(true);
305
-
306
- // Vérifier la validité de la session
307
- useEffect(() => {
308
- if (!sessionId) {
309
- console.log(
310
- "Session ID manquante pour l'affichage des résultats, redirection vers l'accueil"
311
- );
312
- setIsValidSession(false);
313
- return;
314
- }
315
-
316
- // Verify session exists by calling the API
317
- const checkSession = async () => {
318
- try {
319
- const response = await fetch(
320
- `http://localhost:3001/benchmark-questions/${sessionId}`
321
- );
322
-
323
- if (!response.ok) {
324
- console.error(
325
- `Session invalide ou erreur serveur: ${response.status}`
326
- );
327
- setIsValidSession(false);
328
- }
329
- } catch (error) {
330
- console.error("Erreur lors de la vérification de la session:", error);
331
- setIsValidSession(false);
332
- } finally {
333
- setIsLoading(false);
334
- }
335
- };
336
-
337
- checkSession();
338
- }, [sessionId]);
339
-
340
- if (!isValidSession) {
341
- return <Navigate to="/" />;
342
- }
343
-
344
- return (
345
- <>
346
- <Header />
347
- {isLoading ? (
348
- <Box
349
- sx={{
350
- display: "flex",
351
- justifyContent: "center",
352
- alignItems: "center",
353
- mt: 8,
354
- mb: 8,
355
- }}
356
- >
357
- <CircularProgress size={60} />
358
- </Box>
359
- ) : (
360
- <EvaluationDisplay sessionId={sessionId} />
361
- )}
362
- </>
363
- );
364
- }
365
-
366
- // Raccourcis clavier
367
- function KeyboardShortcuts() {
368
- useEffect(() => {
369
- const handleKeyDown = (e) => {
370
- if (e.key === "p") {
371
- console.log("Debug key pressed: Clearing auth data and refreshing");
372
- localStorage.removeItem("hf_oauth");
373
- localStorage.removeItem("auth_return_to");
374
- alert("Auth data cleared. Page will reload.");
375
- window.location.reload();
376
- }
377
- };
378
-
379
- window.addEventListener("keydown", handleKeyDown);
380
- return () => {
381
- window.removeEventListener("keydown", handleKeyDown);
382
- };
383
- }, []);
384
-
385
- return null;
386
- }
387
 
388
- // Composant principal avec les routes
389
  function App() {
390
  const { mode } = useThemeMode();
391
  const theme = getTheme(mode);
@@ -395,6 +26,7 @@ function App() {
395
  <CssBaseline />
396
  <Router>
397
  <Container maxWidth="md">
 
398
  <Box sx={{ pt: 12, pb: 4 }}>
399
  <KeyboardShortcuts />
400
  <Routes>
 
1
+ import React from "react";
2
+ import { Box, Container, CssBaseline } from "@mui/material";
 
 
 
 
 
 
3
  import {
4
  BrowserRouter as Router,
5
  Routes,
6
  Route,
7
  Navigate,
 
 
8
  } from "react-router-dom";
9
  import getTheme from "./config/theme";
10
  import { useThemeMode } from "./hooks/useThemeMode";
11
  import { ThemeProvider } from "@mui/material/styles";
12
+ import ExternalLinks from "./components/ExternalLinks";
13
+ import KeyboardShortcuts from "./components/KeyboardShortcuts";
14
+ import HomePage from "./pages/HomePage";
15
+ import BenchmarkGenerationPage from "./pages/BenchmarkGenerationPage";
16
+ import BenchmarkDisplayPage from "./pages/BenchmarkDisplayPage";
17
+ import BenchmarkEvaluationPage from "./pages/BenchmarkEvaluationPage";
18
+ import EvaluationDisplayPage from "./pages/EvaluationDisplayPage";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
 
20
  function App() {
21
  const { mode } = useThemeMode();
22
  const theme = getTheme(mode);
 
26
  <CssBaseline />
27
  <Router>
28
  <Container maxWidth="md">
29
+ <ExternalLinks />
30
  <Box sx={{ pt: 12, pb: 4 }}>
31
  <KeyboardShortcuts />
32
  <Routes>
frontend/src/components/BenchmarkCreateForm.jsx CHANGED
@@ -12,7 +12,7 @@ import {
12
  } from "@mui/material";
13
  import { useLocation } from "react-router-dom";
14
  import CloudUploadIcon from "@mui/icons-material/CloudUpload";
15
- import PlayArrowIcon from "@mui/icons-material/PlayArrow";
16
  import AuthContainer from "./shared/AuthContainer";
17
  import { useThemeMode } from "../hooks/useThemeMode";
18
  import getTheme from "../config/theme";
@@ -263,7 +263,6 @@ function BenchmarkCreateForm({ onStartGeneration }) {
263
  sx={{
264
  p: 4,
265
  mt: 3,
266
- mb: 3,
267
  display: "flex",
268
  flexDirection: "column",
269
  alignItems: "center",
@@ -271,7 +270,7 @@ function BenchmarkCreateForm({ onStartGeneration }) {
271
  minHeight: 200,
272
  }}
273
  >
274
- <PlayArrowIcon
275
  sx={{ fontSize: 60, color: "text.secondary", mb: 1 }}
276
  />
277
  <Typography variant="h6" component="div" gutterBottom>
@@ -282,7 +281,6 @@ function BenchmarkCreateForm({ onStartGeneration }) {
282
  color="primary"
283
  onClick={handleGenerateClick}
284
  sx={{ mt: 2 }}
285
- startIcon={<PlayArrowIcon />}
286
  >
287
  Generate Benchmark
288
  </Button>
 
12
  } from "@mui/material";
13
  import { useLocation } from "react-router-dom";
14
  import CloudUploadIcon from "@mui/icons-material/CloudUpload";
15
+ import AutoFixHighIcon from "@mui/icons-material/AutoFixHigh";
16
  import AuthContainer from "./shared/AuthContainer";
17
  import { useThemeMode } from "../hooks/useThemeMode";
18
  import getTheme from "../config/theme";
 
263
  sx={{
264
  p: 4,
265
  mt: 3,
 
266
  display: "flex",
267
  flexDirection: "column",
268
  alignItems: "center",
 
270
  minHeight: 200,
271
  }}
272
  >
273
+ <AutoFixHighIcon
274
  sx={{ fontSize: 60, color: "text.secondary", mb: 1 }}
275
  />
276
  <Typography variant="h6" component="div" gutterBottom>
 
281
  color="primary"
282
  onClick={handleGenerateClick}
283
  sx={{ mt: 2 }}
 
284
  >
285
  Generate Benchmark
286
  </Button>
frontend/src/components/BenchmarkDisplay.jsx CHANGED
@@ -43,12 +43,14 @@ const BenchmarkDisplay = ({
43
  {
44
  id: 1,
45
  question: "What are the key benefits of the described technology?",
 
46
  type: "single_shot",
47
  },
48
  {
49
  id: 2,
50
  question:
51
  "Based on the context about machine learning frameworks, how does TensorFlow compare to PyTorch in terms of deployment capabilities?",
 
52
  type: "multi_hop",
53
  },
54
  ];
@@ -83,8 +85,7 @@ const BenchmarkDisplay = ({
83
  };
84
 
85
  return (
86
- <Box sx={{ width: "100%", mt: 3 }}>
87
- {/* Header avec titre et bouton de téléchargement alignés */}
88
  <Box
89
  sx={{
90
  mb: 4,
@@ -98,9 +99,9 @@ const BenchmarkDisplay = ({
98
  <Typography variant="h6">Benchmark Created Successfully</Typography>
99
  </Box>
100
 
101
- <Tooltip title="Télécharger le benchmark complet">
102
  <Button
103
- variant="contained"
104
  color="primary"
105
  endIcon={
106
  isDownloading ? <CircularProgress size={16} /> : <DownloadIcon />
@@ -108,7 +109,7 @@ const BenchmarkDisplay = ({
108
  onClick={handleDownloadClick}
109
  disabled={isDownloading || !sessionId}
110
  >
111
- {isDownloading ? "Téléchargement..." : "Download Benchmark"}
112
  </Button>
113
  </Tooltip>
114
  </Box>
@@ -137,13 +138,24 @@ const BenchmarkDisplay = ({
137
  ? "Multi-hop Question"
138
  : "Single-shot Question"}
139
  </Typography>
140
- <Typography variant="body1">{q.question}</Typography>
 
 
 
 
 
 
 
 
 
 
 
141
  </CardContent>
142
  </Card>
143
  ))}
144
  </Box>
145
 
146
- <Box sx={{ display: "flex", justifyContent: "center", mt: 8 }}>
147
  <Button
148
  variant="contained"
149
  color="primary"
@@ -154,7 +166,7 @@ const BenchmarkDisplay = ({
154
  Start Evaluation
155
  </Button>
156
  </Box>
157
- </Box>
158
  );
159
  };
160
 
 
43
  {
44
  id: 1,
45
  question: "What are the key benefits of the described technology?",
46
+ answer: "No answer available",
47
  type: "single_shot",
48
  },
49
  {
50
  id: 2,
51
  question:
52
  "Based on the context about machine learning frameworks, how does TensorFlow compare to PyTorch in terms of deployment capabilities?",
53
+ answer: "No answer available",
54
  type: "multi_hop",
55
  },
56
  ];
 
85
  };
86
 
87
  return (
88
+ <>
 
89
  <Box
90
  sx={{
91
  mb: 4,
 
99
  <Typography variant="h6">Benchmark Created Successfully</Typography>
100
  </Box>
101
 
102
+ <Tooltip title="Download the complete benchmark">
103
  <Button
104
+ variant="outlined"
105
  color="primary"
106
  endIcon={
107
  isDownloading ? <CircularProgress size={16} /> : <DownloadIcon />
 
109
  onClick={handleDownloadClick}
110
  disabled={isDownloading || !sessionId}
111
  >
112
+ {isDownloading ? "Downloading..." : "Download Benchmark"}
113
  </Button>
114
  </Tooltip>
115
  </Box>
 
138
  ? "Multi-hop Question"
139
  : "Single-shot Question"}
140
  </Typography>
141
+ <Typography variant="body1" sx={{ mb: 2 }}>
142
+ <strong>Question:</strong> {q.question}
143
+ </Typography>
144
+ <Divider sx={{ my: 1.5 }} />
145
+ <Typography
146
+ variant="body1"
147
+ sx={{
148
+ borderRadius: 1,
149
+ }}
150
+ >
151
+ <strong>Answer:</strong> {q.answer || "No answer available"}
152
+ </Typography>
153
  </CardContent>
154
  </Card>
155
  ))}
156
  </Box>
157
 
158
+ <Box sx={{ display: "flex", justifyContent: "center", mt: 4 }}>
159
  <Button
160
  variant="contained"
161
  color="primary"
 
166
  Start Evaluation
167
  </Button>
168
  </Box>
169
+ </>
170
  );
171
  };
172
 
frontend/src/components/BenchmarkEvaluation.jsx CHANGED
@@ -356,7 +356,7 @@ const BenchmarkEvaluation = ({ sessionId, onComplete }) => {
356
  )}
357
 
358
  {/* Use the LogDisplay component for logs */}
359
- <LogDisplay logs={evaluationLogs} height={300} />
360
  </Paper>
361
  );
362
  };
 
356
  )}
357
 
358
  {/* Use the LogDisplay component for logs */}
359
+ <LogDisplay logs={evaluationLogs} height={150} />
360
  </Paper>
361
  );
362
  };
frontend/src/components/BenchmarkGenerator.jsx CHANGED
@@ -390,7 +390,7 @@ const BenchmarkGenerator = ({ sessionId, onComplete }) => {
390
  )}
391
 
392
  {/* Use the LogDisplay component */}
393
- <LogDisplay logs={generationLogs} height={300} />
394
  </Paper>
395
  );
396
  };
 
390
  )}
391
 
392
  {/* Use the LogDisplay component */}
393
+ <LogDisplay logs={generationLogs} height={150} />
394
  </Paper>
395
  );
396
  };
frontend/src/components/EvaluationDisplay.jsx CHANGED
@@ -16,7 +16,7 @@ import {
16
  Link,
17
  } from "@mui/material";
18
  import OpenInNewIcon from "@mui/icons-material/OpenInNew";
19
-
20
  const EvaluationDisplay = ({ sessionId }) => {
21
  const [results, setResults] = useState(null);
22
  const [loading, setLoading] = useState(true);
@@ -100,9 +100,13 @@ const EvaluationDisplay = ({ sessionId }) => {
100
  }
101
 
102
  return (
103
- <Box sx={{ mt: 4, mb: 6 }}>
104
- <Typography variant="h4" gutterBottom>
105
- Evaluation Results
 
 
 
 
106
  </Typography>
107
 
108
  <TableContainer
@@ -117,9 +121,7 @@ const EvaluationDisplay = ({ sessionId }) => {
117
  <TableRow>
118
  <TableCell>Rank</TableCell>
119
  <TableCell>Model</TableCell>
120
- <TableCell>Provider</TableCell>
121
  <TableCell align="center">Accuracy</TableCell>
122
- <TableCell align="center">Std Error</TableCell>
123
  <TableCell align="center">Eval Time</TableCell>
124
  <TableCell align="center">Status</TableCell>
125
  </TableRow>
@@ -154,13 +156,9 @@ const EvaluationDisplay = ({ sessionId }) => {
154
  <OpenInNewIcon sx={{ ml: 0.5, fontSize: 16 }} />
155
  </Link>
156
  </TableCell>
157
- <TableCell>{model.provider}</TableCell>
158
  <TableCell align="center">
159
  {model.success ? formatAccuracy(model.accuracy) : "-"}
160
  </TableCell>
161
- <TableCell align="center">
162
- {model.success ? formatAccuracy(model.accuracy_stderr) : "-"}
163
- </TableCell>
164
  <TableCell align="center">
165
  {model.success ? formatTime(model.evaluation_time) : "-"}
166
  </TableCell>
@@ -181,7 +179,7 @@ const EvaluationDisplay = ({ sessionId }) => {
181
  <Typography variant="body2" color="textSecondary">
182
  Need larger evaluation?{" "}
183
  <Link
184
- href="https://huggingface.co/spaces/yourbench/yourbench"
185
  target="_blank"
186
  rel="noopener noreferrer"
187
  >
@@ -189,7 +187,7 @@ const EvaluationDisplay = ({ sessionId }) => {
189
  </Link>
190
  </Typography>
191
  </Box>
192
- </Box>
193
  );
194
  };
195
 
 
16
  Link,
17
  } from "@mui/material";
18
  import OpenInNewIcon from "@mui/icons-material/OpenInNew";
19
+ import CheckCircleIcon from "@mui/icons-material/CheckCircle";
20
  const EvaluationDisplay = ({ sessionId }) => {
21
  const [results, setResults] = useState(null);
22
  const [loading, setLoading] = useState(true);
 
100
  }
101
 
102
  return (
103
+ <>
104
+ <Box sx={{ display: "flex", alignItems: "center", mb: 4 }}>
105
+ <CheckCircleIcon color="success" sx={{ mr: 1.5, fontSize: 28 }} />
106
+ <Typography variant="h6">Evaluation finished successfully</Typography>
107
+ </Box>
108
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
109
+ The bests models for this benchmark are
110
  </Typography>
111
 
112
  <TableContainer
 
121
  <TableRow>
122
  <TableCell>Rank</TableCell>
123
  <TableCell>Model</TableCell>
 
124
  <TableCell align="center">Accuracy</TableCell>
 
125
  <TableCell align="center">Eval Time</TableCell>
126
  <TableCell align="center">Status</TableCell>
127
  </TableRow>
 
156
  <OpenInNewIcon sx={{ ml: 0.5, fontSize: 16 }} />
157
  </Link>
158
  </TableCell>
 
159
  <TableCell align="center">
160
  {model.success ? formatAccuracy(model.accuracy) : "-"}
161
  </TableCell>
 
 
 
162
  <TableCell align="center">
163
  {model.success ? formatTime(model.evaluation_time) : "-"}
164
  </TableCell>
 
179
  <Typography variant="body2" color="textSecondary">
180
  Need larger evaluation?{" "}
181
  <Link
182
+ href="https://github.com/huggingface/lighteval"
183
  target="_blank"
184
  rel="noopener noreferrer"
185
  >
 
187
  </Link>
188
  </Typography>
189
  </Box>
190
+ </>
191
  );
192
  };
193
 
frontend/src/components/ExternalLinks.jsx ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { Box, Typography } from "@mui/material";
3
+ import OpenInNewIcon from "@mui/icons-material/OpenInNew";
4
+
5
+ const ExternalLinks = () => {
6
+ return (
7
+ <Box
8
+ sx={{
9
+ position: "fixed",
10
+ top: 24,
11
+ right: 24,
12
+ display: "flex",
13
+ gap: 2,
14
+ alignItems: "center",
15
+ zIndex: 1000,
16
+ }}
17
+ >
18
+ <Typography
19
+ variant="body2"
20
+ sx={{
21
+ display: "flex",
22
+ gap: 2,
23
+ alignItems: "center",
24
+ }}
25
+ >
26
+ <a
27
+ href="https://github.com/huggingface/yourbench"
28
+ target="_blank"
29
+ rel="noopener noreferrer"
30
+ style={{ textDecoration: "none", color: "inherit" }}
31
+ >
32
+ GitHub
33
+ <OpenInNewIcon sx={{ fontSize: "0.75rem", ml: 0.5, opacity: 0.6 }} />
34
+ </a>
35
+ <Typography component="span" sx={{ opacity: 0.5 }}>
36
+
37
+ </Typography>
38
+ <a
39
+ href="https://huggingface.co/datasets/sumuks/tempora"
40
+ target="_blank"
41
+ rel="noopener noreferrer"
42
+ style={{ textDecoration: "none", color: "inherit" }}
43
+ >
44
+ Dataset
45
+ <OpenInNewIcon sx={{ fontSize: "0.75rem", ml: 0.5, opacity: 0.6 }} />
46
+ </a>
47
+ <Typography component="span" sx={{ opacity: 0.5 }}>
48
+
49
+ </Typography>
50
+ <a
51
+ href="https://github.com/huggingface/yourbench/tree/main/docs"
52
+ target="_blank"
53
+ rel="noopener noreferrer"
54
+ style={{ textDecoration: "none", color: "inherit" }}
55
+ >
56
+ Documentation
57
+ <OpenInNewIcon sx={{ fontSize: "0.75rem", ml: 0.5, opacity: 0.6 }} />
58
+ </a>
59
+ </Typography>
60
+ </Box>
61
+ );
62
+ };
63
+
64
+ export default ExternalLinks;
frontend/src/components/Intro.jsx ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { Box } from "@mui/material";
3
+ import HFLogo from "./Logo/HFLogo";
4
+
5
+ const Intro = () => (
6
+ <Box sx={{ textAlign: "center", mb: 8 }}>
7
+ <Box
8
+ sx={{ height: "60px", mb: 4, display: "flex", justifyContent: "center" }}
9
+ >
10
+ <HFLogo />
11
+ </Box>
12
+ <h1>Yourbench Demo</h1>
13
+ <p>
14
+ YourBench is an <b>open-source framework</b> for generating{" "}
15
+ <b>domain-specific benchmarks</b> in a <b>zero-shot</b> manner. It aims to
16
+ keep your large language models on their toes—even as new data sources,
17
+ domains, and knowledge demands evolve.
18
+ </p>
19
+ </Box>
20
+ );
21
+
22
+ export default Intro;
frontend/src/components/KeyboardShortcuts.jsx ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect } from "react";
2
+
3
+ function KeyboardShortcuts() {
4
+ useEffect(() => {
5
+ const handleKeyDown = (e) => {
6
+ if (e.key === "p") {
7
+ console.log("Debug key pressed: Clearing auth data and refreshing");
8
+ localStorage.removeItem("hf_oauth");
9
+ localStorage.removeItem("auth_return_to");
10
+ alert("Auth data cleared. Page will reload.");
11
+ window.location.reload();
12
+ }
13
+ };
14
+
15
+ window.addEventListener("keydown", handleKeyDown);
16
+ return () => {
17
+ window.removeEventListener("keydown", handleKeyDown);
18
+ };
19
+ }, []);
20
+
21
+ return null;
22
+ }
23
+
24
+ export default KeyboardShortcuts;
frontend/src/components/Navigation/Navigation.js DELETED
@@ -1,504 +0,0 @@
1
- import React, { useState } from "react";
2
- import {
3
- AppBar,
4
- Toolbar,
5
- Box,
6
- Link as MuiLink,
7
- IconButton,
8
- Tooltip,
9
- ButtonBase,
10
- Typography,
11
- } from "@mui/material";
12
- import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
13
- import OpenInNewIcon from "@mui/icons-material/OpenInNew";
14
- import LightModeOutlinedIcon from "@mui/icons-material/LightModeOutlined";
15
- import DarkModeOutlinedIcon from "@mui/icons-material/DarkModeOutlined";
16
- import { alpha } from "@mui/material/styles";
17
- import MenuIcon from "@mui/icons-material/Menu";
18
- import { Menu, MenuItem, useMediaQuery, useTheme } from "@mui/material";
19
-
20
- const Navigation = ({ onToggleTheme, mode }) => {
21
- const location = useLocation();
22
- const navigate = useNavigate();
23
- const [searchParams] = useSearchParams();
24
- const [anchorEl, setAnchorEl] = useState(null);
25
- const theme = useTheme();
26
- const isMobile = useMediaQuery(theme.breakpoints.down("md"));
27
- const [hasChanged, setHasChanged] = useState(false);
28
-
29
- const handleThemeToggle = () => {
30
- setHasChanged(true);
31
- onToggleTheme();
32
- };
33
-
34
- const iconStyle = {
35
- fontSize: "1.125rem",
36
- ...(hasChanged && {
37
- animation: "rotateIn 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
38
- "@keyframes rotateIn": {
39
- "0%": {
40
- opacity: 0,
41
- transform:
42
- mode === "light"
43
- ? "rotate(-90deg) scale(0.8)"
44
- : "rotate(90deg) scale(0.8)",
45
- },
46
- "100%": {
47
- opacity: 1,
48
- transform: "rotate(0) scale(1)",
49
- },
50
- },
51
- }),
52
- };
53
-
54
- // Function to sync URL with parent HF page
55
- const syncUrlWithParent = (queryString, hash) => {
56
- // Check if we're in an HF Space iframe
57
- const isHFSpace = window.location !== window.parent.location;
58
- if (isHFSpace) {
59
- try {
60
- // Build complete URL with hash
61
- const fullPath = `${queryString}${hash ? "#" + hash : ""}`;
62
- window.parent.postMessage(
63
- {
64
- type: "urlUpdate",
65
- path: fullPath,
66
- },
67
- "https://huggingface.co"
68
- );
69
- } catch (e) {
70
- console.warn("Unable to sync URL with parent:", e);
71
- }
72
- }
73
- };
74
-
75
- const linkStyle = (isActive = false) => ({
76
- textDecoration: "none",
77
- color: isActive ? "text.primary" : "text.secondary",
78
- fontSize: "0.8125rem",
79
- opacity: isActive ? 1 : 0.8,
80
- display: "flex",
81
- alignItems: "center",
82
- gap: 0.5,
83
- paddingBottom: "2px",
84
- cursor: "pointer",
85
- position: "relative",
86
- "&:hover": {
87
- opacity: 1,
88
- color: "text.primary",
89
- },
90
- "&::after": isActive
91
- ? {
92
- content: '""',
93
- position: "absolute",
94
- bottom: "-4px",
95
- left: "0",
96
- width: "100%",
97
- height: "2px",
98
- backgroundColor: (theme) =>
99
- alpha(
100
- theme.palette.text.primary,
101
- theme.palette.mode === "dark" ? 0.3 : 0.2
102
- ),
103
- borderRadius: "2px",
104
- }
105
- : {},
106
- });
107
-
108
- const Separator = () => (
109
- <Box
110
- sx={(theme) => ({
111
- width: "4px",
112
- height: "4px",
113
- borderRadius: "100%",
114
- backgroundColor: alpha(
115
- theme.palette.text.primary,
116
- theme.palette.mode === "dark" ? 0.2 : 0.15
117
- ),
118
- })}
119
- />
120
- );
121
-
122
- const handleNavigation = (path) => (e) => {
123
- e.preventDefault();
124
- const searchString = searchParams.toString();
125
- const queryString = searchString ? `?${searchString}` : "";
126
- const newPath = `${path}${queryString}`;
127
-
128
- // Local navigation via React Router
129
- navigate(newPath);
130
-
131
- // If in HF Space, sync with parent
132
- if (window.location !== window.parent.location) {
133
- syncUrlWithParent(queryString, newPath);
134
- }
135
- };
136
-
137
- const handleMenuOpen = (event) => {
138
- setAnchorEl(event.currentTarget);
139
- };
140
-
141
- const handleMenuClose = () => {
142
- setAnchorEl(null);
143
- };
144
-
145
- return (
146
- <AppBar
147
- position="static"
148
- sx={{
149
- backgroundColor: "transparent",
150
- boxShadow: "none",
151
- width: "100%",
152
- }}
153
- >
154
- <Toolbar sx={{ justifyContent: "center" }}>
155
- {isMobile ? (
156
- <Box
157
- sx={{
158
- display: "flex",
159
- width: "100%",
160
- justifyContent: "space-between",
161
- alignItems: "center",
162
- }}
163
- >
164
- <IconButton
165
- onClick={handleMenuOpen}
166
- sx={{ color: "text.secondary" }}
167
- >
168
- <MenuIcon />
169
- </IconButton>
170
-
171
- <Menu
172
- anchorEl={anchorEl}
173
- open={Boolean(anchorEl)}
174
- onClose={handleMenuClose}
175
- PaperProps={{
176
- elevation: 3,
177
- sx: {
178
- mt: 1.5,
179
- minWidth: 220,
180
- borderRadius: "12px",
181
- border: (theme) =>
182
- `1px solid ${alpha(theme.palette.divider, 0.1)}`,
183
- backgroundColor: (theme) =>
184
- theme.palette.mode === "dark"
185
- ? alpha(theme.palette.background.paper, 0.8)
186
- : theme.palette.background.paper,
187
- backdropFilter: "blur(20px)",
188
- "& .MuiList-root": {
189
- py: 1,
190
- },
191
- "& .MuiMenuItem-root": {
192
- px: 2,
193
- py: 1,
194
- fontSize: "0.8125rem",
195
- color: "text.secondary",
196
- transition: "all 0.2s ease-in-out",
197
- position: "relative",
198
- "&:hover": {
199
- backgroundColor: (theme) =>
200
- alpha(
201
- theme.palette.text.primary,
202
- theme.palette.mode === "dark" ? 0.1 : 0.06
203
- ),
204
- color: "text.primary",
205
- },
206
- "&.Mui-selected": {
207
- backgroundColor: "transparent",
208
- color: "text.primary",
209
- "&::after": {
210
- content: '""',
211
- position: "absolute",
212
- left: "8px",
213
- width: "4px",
214
- height: "100%",
215
- top: "0",
216
- backgroundColor: (theme) =>
217
- alpha(
218
- theme.palette.text.primary,
219
- theme.palette.mode === "dark" ? 0.3 : 0.2
220
- ),
221
- borderRadius: "2px",
222
- },
223
- "&:hover": {
224
- backgroundColor: (theme) =>
225
- alpha(
226
- theme.palette.text.primary,
227
- theme.palette.mode === "dark" ? 0.1 : 0.06
228
- ),
229
- },
230
- },
231
- },
232
- },
233
- }}
234
- transformOrigin={{ horizontal: "left", vertical: "top" }}
235
- anchorOrigin={{ horizontal: "left", vertical: "bottom" }}
236
- >
237
- {/* Navigation Section */}
238
- <Box sx={{ px: 2, pb: 1.5, pt: 0.5 }}>
239
- <Typography variant="caption" sx={{ color: "text.disabled" }}>
240
- Navigation
241
- </Typography>
242
- </Box>
243
- <MenuItem
244
- onClick={(e) => {
245
- handleNavigation("/")(e);
246
- handleMenuClose();
247
- }}
248
- selected={location.pathname === "/"}
249
- >
250
- Leaderboard
251
- </MenuItem>
252
- <MenuItem
253
- onClick={(e) => {
254
- handleNavigation("/add")(e);
255
- handleMenuClose();
256
- }}
257
- selected={location.pathname === "/add"}
258
- >
259
- Submit model
260
- </MenuItem>
261
- <MenuItem
262
- onClick={(e) => {
263
- handleNavigation("/vote")(e);
264
- handleMenuClose();
265
- }}
266
- selected={location.pathname === "/vote"}
267
- >
268
- Vote for next model
269
- </MenuItem>
270
- <MenuItem
271
- onClick={(e) => {
272
- handleNavigation("/quote")(e);
273
- handleMenuClose();
274
- }}
275
- selected={location.pathname === "/quote"}
276
- >
277
- Citations
278
- </MenuItem>
279
-
280
- {/* Separator */}
281
- <Box
282
- sx={{
283
- my: 1,
284
- borderTop: (theme) =>
285
- `1px solid ${alpha(theme.palette.divider, 0.1)}`,
286
- }}
287
- />
288
-
289
- {/* External Links Section */}
290
- <Box sx={{ px: 2, pb: 1.5 }}>
291
- <Typography variant="caption" sx={{ color: "text.disabled" }}>
292
- External links
293
- </Typography>
294
- </Box>
295
- <MenuItem
296
- component={MuiLink}
297
- href="https://huggingface.co/spaces/open-llm-leaderboard/comparator"
298
- target="_blank"
299
- sx={{
300
- "& svg": {
301
- ml: "auto",
302
- fontSize: "0.875rem",
303
- opacity: 0.6,
304
- },
305
- }}
306
- >
307
- Compare models
308
- <OpenInNewIcon />
309
- </MenuItem>
310
- <MenuItem
311
- component={MuiLink}
312
- href="https://huggingface.co/docs/leaderboards/open_llm_leaderboard/about"
313
- target="_blank"
314
- sx={{
315
- "& svg": {
316
- ml: "auto",
317
- fontSize: "0.875rem",
318
- opacity: 0.6,
319
- },
320
- }}
321
- >
322
- About
323
- <OpenInNewIcon />
324
- </MenuItem>
325
- </Menu>
326
-
327
- <Tooltip
328
- title={
329
- mode === "light"
330
- ? "Switch to dark mode"
331
- : "Switch to light mode"
332
- }
333
- >
334
- <ButtonBase
335
- onClick={handleThemeToggle}
336
- sx={(theme) => ({
337
- color: "text.secondary",
338
- borderRadius: "100%",
339
- padding: 0,
340
- width: "36px",
341
- height: "36px",
342
- display: "flex",
343
- alignItems: "center",
344
- justifyContent: "center",
345
- transition: "all 0.2s ease-in-out",
346
- "&:hover": {
347
- color: "text.primary",
348
- backgroundColor: alpha(
349
- theme.palette.text.primary,
350
- theme.palette.mode === "dark" ? 0.1 : 0.06
351
- ),
352
- },
353
- "&.MuiButtonBase-root": {
354
- overflow: "hidden",
355
- },
356
- "& .MuiTouchRipple-root": {
357
- color: alpha(theme.palette.text.primary, 0.3),
358
- },
359
- })}
360
- >
361
- {mode === "light" ? (
362
- <DarkModeOutlinedIcon sx={iconStyle} />
363
- ) : (
364
- <LightModeOutlinedIcon sx={iconStyle} />
365
- )}
366
- </ButtonBase>
367
- </Tooltip>
368
- </Box>
369
- ) : (
370
- // Desktop version
371
- <Box
372
- sx={{
373
- display: "flex",
374
- gap: 2.5,
375
- alignItems: "center",
376
- padding: "0.5rem 0",
377
- }}
378
- >
379
- {/* Internal navigation */}
380
- <Box sx={{ display: "flex", gap: 2.5, alignItems: "center" }}>
381
- <Box
382
- onClick={handleNavigation("/")}
383
- sx={linkStyle(location.pathname === "/")}
384
- >
385
- Leaderboard
386
- </Box>
387
- <Box
388
- onClick={handleNavigation("/add")}
389
- sx={linkStyle(location.pathname === "/add")}
390
- >
391
- Submit model
392
- </Box>
393
- <Box
394
- onClick={handleNavigation("/vote")}
395
- sx={linkStyle(location.pathname === "/vote")}
396
- >
397
- Vote for next model
398
- </Box>
399
- <Box
400
- onClick={handleNavigation("/quote")}
401
- sx={linkStyle(location.pathname === "/quote")}
402
- >
403
- Citations
404
- </Box>
405
- </Box>
406
-
407
- <Separator />
408
-
409
- {/* External links */}
410
- <Box sx={{ display: "flex", gap: 2.5, alignItems: "center" }}>
411
- <MuiLink
412
- href="https://huggingface.co/spaces/open-llm-leaderboard/comparator"
413
- target="_blank"
414
- rel="noopener noreferrer"
415
- sx={{
416
- ...linkStyle(),
417
- "& svg": {
418
- fontSize: "0.75rem",
419
- ml: 0.5,
420
- opacity: 0.6,
421
- transition: "opacity 0.2s ease-in-out",
422
- },
423
- "&:hover svg": {
424
- opacity: 0.8,
425
- },
426
- }}
427
- >
428
- Compare models
429
- <OpenInNewIcon />
430
- </MuiLink>
431
- <MuiLink
432
- href="https://huggingface.co/docs/leaderboards/open_llm_leaderboard/about"
433
- target="_blank"
434
- rel="noopener noreferrer"
435
- sx={{
436
- ...linkStyle(),
437
- "& svg": {
438
- fontSize: "0.75rem",
439
- ml: 0.5,
440
- opacity: 0.6,
441
- transition: "opacity 0.2s ease-in-out",
442
- },
443
- "&:hover svg": {
444
- opacity: 0.8,
445
- },
446
- }}
447
- >
448
- About
449
- <OpenInNewIcon />
450
- </MuiLink>
451
- </Box>
452
-
453
- <Separator />
454
-
455
- {/* Dark mode toggle */}
456
- <Tooltip
457
- title={
458
- mode === "light"
459
- ? "Switch to dark mode"
460
- : "Switch to light mode"
461
- }
462
- >
463
- <ButtonBase
464
- onClick={handleThemeToggle}
465
- sx={(theme) => ({
466
- color: "text.secondary",
467
- borderRadius: "100%",
468
- padding: 0,
469
- width: "36px",
470
- height: "36px",
471
- display: "flex",
472
- alignItems: "center",
473
- justifyContent: "center",
474
- transition: "all 0.2s ease-in-out",
475
- "&:hover": {
476
- color: "text.primary",
477
- backgroundColor: alpha(
478
- theme.palette.text.primary,
479
- theme.palette.mode === "dark" ? 0.1 : 0.06
480
- ),
481
- },
482
- "&.MuiButtonBase-root": {
483
- overflow: "hidden",
484
- },
485
- "& .MuiTouchRipple-root": {
486
- color: alpha(theme.palette.text.primary, 0.3),
487
- },
488
- })}
489
- >
490
- {mode === "light" ? (
491
- <DarkModeOutlinedIcon sx={iconStyle} />
492
- ) : (
493
- <LightModeOutlinedIcon sx={iconStyle} />
494
- )}
495
- </ButtonBase>
496
- </Tooltip>
497
- </Box>
498
- )}
499
- </Toolbar>
500
- </AppBar>
501
- );
502
- };
503
-
504
- export default Navigation;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/pages/BenchmarkDisplayPage.jsx ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from "react";
2
+ import { Box, CircularProgress } from "@mui/material";
3
+ import { useNavigate, useSearchParams, Navigate } from "react-router-dom";
4
+ import Intro from "../components/Intro";
5
+ import BenchmarkDisplay from "../components/BenchmarkDisplay";
6
+
7
+ function BenchmarkDisplayPage() {
8
+ const navigate = useNavigate();
9
+ const [searchParams] = useSearchParams();
10
+ const sessionId = searchParams.get("session");
11
+ const [benchmarkQuestions, setBenchmarkQuestions] = useState([]);
12
+ const [datasetUrl, setDatasetUrl] = useState(null);
13
+ const [isValidSession, setIsValidSession] = useState(true);
14
+ const [isLoading, setIsLoading] = useState(true);
15
+
16
+ useEffect(() => {
17
+ console.log("BenchmarkDisplayPage useEffect - sessionId:", sessionId);
18
+
19
+ if (!sessionId) {
20
+ console.log("Session ID manquante, redirection vers l'accueil");
21
+ setIsValidSession(false);
22
+ return;
23
+ }
24
+
25
+ setIsLoading(true);
26
+
27
+ const fetchBenchmarkQuestions = async () => {
28
+ console.log(
29
+ "Tentative de récupération des questions pour la session:",
30
+ sessionId
31
+ );
32
+ try {
33
+ const apiUrl = `http://localhost:3001/benchmark-questions/${sessionId}`;
34
+ console.log("Appel API:", apiUrl);
35
+
36
+ const response = await fetch(apiUrl);
37
+ console.log("Réponse API reçue:", response.status);
38
+
39
+ if (!response.ok) {
40
+ if (response.status === 404) {
41
+ console.error("Session non trouvée");
42
+ setIsValidSession(false);
43
+ return;
44
+ } else {
45
+ console.error(`Erreur serveur: ${response.status}`);
46
+ setIsLoading(false);
47
+ return;
48
+ }
49
+ }
50
+
51
+ const data = await response.json();
52
+ console.log("Données API:", data);
53
+
54
+ if (data.success && data.questions && data.questions.length > 0) {
55
+ console.log("Questions chargées avec succès:", data.questions);
56
+ setBenchmarkQuestions(data.questions);
57
+ } else {
58
+ console.warn(
59
+ "Échec du chargement des questions, utilisation des valeurs par défaut"
60
+ );
61
+ }
62
+
63
+ if (data.dataset_url) {
64
+ setDatasetUrl(data.dataset_url);
65
+ } else {
66
+ const url = `https://huggingface.co/datasets/yourbench/yourbench_${sessionId}`;
67
+ setDatasetUrl(url);
68
+ console.log("URL du dataset générée:", url);
69
+ }
70
+ } catch (error) {
71
+ console.error("Erreur lors de la récupération des questions:", error);
72
+ setIsValidSession(false);
73
+ } finally {
74
+ setIsLoading(false);
75
+ }
76
+ };
77
+
78
+ fetchBenchmarkQuestions();
79
+ }, [sessionId]);
80
+
81
+ const handleStartEvaluation = () => {
82
+ console.log("Starting evaluation with session ID:", sessionId);
83
+ navigate(`/benchmark-evaluation?session=${sessionId}`);
84
+ };
85
+
86
+ const defaultSampleQuestions = [
87
+ {
88
+ id: 1,
89
+ question: "What are the key features discussed in the document?",
90
+ answer:
91
+ "The document discusses features such as scalability, integration capabilities, and security measures that are important for enterprise solutions.",
92
+ type: "single_shot",
93
+ },
94
+ {
95
+ id: 2,
96
+ question:
97
+ "How does the proposed solution address the challenges mentioned in section 2 in relation to the overall market trends?",
98
+ answer:
99
+ "The proposed solution addresses the challenges by incorporating AI-driven analytics that adapt to changing market conditions while maintaining compliance with industry regulations, thus providing a competitive edge in the evolving marketplace.",
100
+ type: "multi_hop",
101
+ },
102
+ ];
103
+
104
+ if (!isValidSession) {
105
+ return <Navigate to="/" />;
106
+ }
107
+
108
+ return (
109
+ <>
110
+ <Intro />
111
+ {isLoading ? (
112
+ <Box
113
+ sx={{
114
+ display: "flex",
115
+ justifyContent: "center",
116
+ alignItems: "center",
117
+ mt: 8,
118
+ mb: 8,
119
+ }}
120
+ >
121
+ <CircularProgress size={60} />
122
+ </Box>
123
+ ) : (
124
+ <Box
125
+ sx={{
126
+ border: "1px solid rgba(0, 0, 0, 0.12)",
127
+ borderRadius: 2,
128
+ p: 4,
129
+ bgcolor: "white",
130
+ }}
131
+ >
132
+ <BenchmarkDisplay
133
+ onStartEvaluation={handleStartEvaluation}
134
+ sessionId={sessionId}
135
+ datasetUrl={datasetUrl}
136
+ sampleQuestions={
137
+ benchmarkQuestions.length > 0
138
+ ? benchmarkQuestions
139
+ : defaultSampleQuestions
140
+ }
141
+ />
142
+ </Box>
143
+ )}
144
+ </>
145
+ );
146
+ }
147
+
148
+ export default BenchmarkDisplayPage;
frontend/src/pages/BenchmarkEvaluationPage.jsx ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from "react";
2
+ import { Box, CircularProgress } from "@mui/material";
3
+ import { useNavigate, useSearchParams, Navigate } from "react-router-dom";
4
+ import Intro from "../components/Intro";
5
+ import BenchmarkEvaluation from "../components/BenchmarkEvaluation";
6
+
7
+ function BenchmarkEvaluationPage() {
8
+ const navigate = useNavigate();
9
+ const [searchParams] = useSearchParams();
10
+ const sessionId = searchParams.get("session");
11
+ const [isValidSession, setIsValidSession] = useState(true);
12
+ const [isLoading, setIsLoading] = useState(true);
13
+
14
+ useEffect(() => {
15
+ if (!sessionId) {
16
+ console.log(
17
+ "Session ID manquante pour l'évaluation, redirection vers l'accueil"
18
+ );
19
+ setIsValidSession(false);
20
+ return;
21
+ }
22
+
23
+ const checkSession = async () => {
24
+ try {
25
+ const response = await fetch(
26
+ `http://localhost:3001/benchmark-questions/${sessionId}`
27
+ );
28
+
29
+ if (!response.ok) {
30
+ console.error(
31
+ `Session invalide ou erreur serveur: ${response.status}`
32
+ );
33
+ setIsValidSession(false);
34
+ }
35
+ } catch (error) {
36
+ console.error("Erreur lors de la vérification de la session:", error);
37
+ setIsValidSession(false);
38
+ } finally {
39
+ setIsLoading(false);
40
+ }
41
+ };
42
+
43
+ checkSession();
44
+ }, [sessionId]);
45
+
46
+ const handleEvaluationComplete = (result) => {
47
+ console.log("Évaluation terminée:", result);
48
+ };
49
+
50
+ if (!isValidSession) {
51
+ return <Navigate to="/" />;
52
+ }
53
+
54
+ return (
55
+ <>
56
+ <Intro />
57
+ {isLoading ? (
58
+ <Box
59
+ sx={{
60
+ display: "flex",
61
+ justifyContent: "center",
62
+ alignItems: "center",
63
+ mt: 8,
64
+ mb: 8,
65
+ }}
66
+ >
67
+ <CircularProgress size={60} />
68
+ </Box>
69
+ ) : (
70
+ <BenchmarkEvaluation
71
+ sessionId={sessionId}
72
+ onComplete={handleEvaluationComplete}
73
+ />
74
+ )}
75
+ </>
76
+ );
77
+ }
78
+
79
+ export default BenchmarkEvaluationPage;
frontend/src/pages/BenchmarkGenerationPage.jsx ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from "react";
2
+ import { Box, CircularProgress } from "@mui/material";
3
+ import { useNavigate, useSearchParams, Navigate } from "react-router-dom";
4
+ import Intro from "../components/Intro";
5
+ import BenchmarkGenerator from "../components/BenchmarkGenerator";
6
+
7
+ function BenchmarkGenerationPage() {
8
+ const navigate = useNavigate();
9
+ const [searchParams] = useSearchParams();
10
+ const sessionId = searchParams.get("session");
11
+ const [isValidSession, setIsValidSession] = useState(true);
12
+
13
+ useEffect(() => {
14
+ if (!sessionId) {
15
+ setIsValidSession(false);
16
+ }
17
+ }, [sessionId]);
18
+
19
+ const handleGenerationComplete = (result) => {
20
+ console.log("Benchmark generation completed:", result);
21
+ if (result && result.success) {
22
+ navigate(`/benchmark-display?session=${sessionId}`);
23
+ }
24
+ };
25
+
26
+ if (!isValidSession) {
27
+ return <Navigate to="/" />;
28
+ }
29
+
30
+ return (
31
+ <>
32
+ <Intro />
33
+ <BenchmarkGenerator
34
+ sessionId={sessionId}
35
+ onComplete={handleGenerationComplete}
36
+ />
37
+ </>
38
+ );
39
+ }
40
+
41
+ export default BenchmarkGenerationPage;
frontend/src/pages/EvaluationDisplayPage.jsx ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from "react";
2
+ import { Box, CircularProgress } from "@mui/material";
3
+ import { useSearchParams, Navigate } from "react-router-dom";
4
+ import Intro from "../components/Intro";
5
+ import EvaluationDisplay from "../components/EvaluationDisplay";
6
+
7
+ function EvaluationDisplayPage() {
8
+ const [searchParams] = useSearchParams();
9
+ const sessionId = searchParams.get("session");
10
+ const [isValidSession, setIsValidSession] = useState(true);
11
+ const [isLoading, setIsLoading] = useState(true);
12
+
13
+ useEffect(() => {
14
+ if (!sessionId) {
15
+ console.log(
16
+ "Session ID manquante pour l'affichage des résultats, redirection vers l'accueil"
17
+ );
18
+ setIsValidSession(false);
19
+ return;
20
+ }
21
+
22
+ const checkSession = async () => {
23
+ try {
24
+ const response = await fetch(
25
+ `http://localhost:3001/benchmark-questions/${sessionId}`
26
+ );
27
+
28
+ if (!response.ok) {
29
+ console.error(
30
+ `Session invalide ou erreur serveur: ${response.status}`
31
+ );
32
+ setIsValidSession(false);
33
+ }
34
+ } catch (error) {
35
+ console.error("Erreur lors de la vérification de la session:", error);
36
+ setIsValidSession(false);
37
+ } finally {
38
+ setIsLoading(false);
39
+ }
40
+ };
41
+
42
+ checkSession();
43
+ }, [sessionId]);
44
+
45
+ if (!isValidSession) {
46
+ return <Navigate to="/" />;
47
+ }
48
+
49
+ return (
50
+ <>
51
+ <Intro />
52
+ {isLoading ? (
53
+ <Box
54
+ sx={{
55
+ display: "flex",
56
+ justifyContent: "center",
57
+ alignItems: "center",
58
+ mt: 8,
59
+ mb: 8,
60
+ }}
61
+ >
62
+ <CircularProgress size={60} />
63
+ </Box>
64
+ ) : (
65
+ <Box
66
+ sx={{
67
+ border: "1px solid rgba(0, 0, 0, 0.12)",
68
+ borderRadius: 2,
69
+ p: 4,
70
+ bgcolor: "white",
71
+ }}
72
+ >
73
+ <EvaluationDisplay sessionId={sessionId} />
74
+ </Box>
75
+ )}
76
+ </>
77
+ );
78
+ }
79
+
80
+ export default EvaluationDisplayPage;
frontend/src/pages/HomePage.jsx ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { Box } from "@mui/material";
3
+ import { useNavigate } from "react-router-dom";
4
+ import Intro from "../components/Intro";
5
+ import BenchmarkCreateForm from "../components/BenchmarkCreateForm";
6
+
7
+ function HomePage() {
8
+ const navigate = useNavigate();
9
+
10
+ const handleStartGeneration = (sid) => {
11
+ navigate(`/benchmark-generation?session=${sid}`);
12
+ };
13
+
14
+ return (
15
+ <>
16
+ <Intro />
17
+ <Box
18
+ sx={{
19
+ border: "1px solid rgba(0, 0, 0, 0.12)",
20
+ borderRadius: 2,
21
+ p: 4,
22
+ bgcolor: "white",
23
+ }}
24
+ >
25
+ <BenchmarkCreateForm onStartGeneration={handleStartGeneration} />
26
+ </Box>
27
+ </>
28
+ );
29
+ }
30
+
31
+ export default HomePage;