stillerman commited on
Commit
8565da5
·
1 Parent(s): c1d2ac2

much better layout

Browse files
src/components/force-directed-graph.tsx CHANGED
@@ -292,7 +292,7 @@ export default function ForceDirectedGraph({
292
  (n) => n + fontSize * 0.2
293
  );
294
 
295
- const isInCurrentRun = node.runIds.includes(runId);
296
 
297
  // Apply opacity based on node type and properties
298
  const opacity = isInCurrentRun ? 1.0 : STYLES.minNodeOpacity;
 
292
  (n) => n + fontSize * 0.2
293
  );
294
 
295
+ const isInCurrentRun = node.runIds?.includes(runId);
296
 
297
  // Apply opacity based on node type and properties
298
  const opacity = isInCurrentRun ? 1.0 : STYLES.minNodeOpacity;
src/components/game-component.tsx CHANGED
@@ -1,9 +1,19 @@
1
  "use client";
2
 
3
- import { useState, useEffect, useCallback, useRef } from "react";
4
  import { Card } from "@/components/ui/card";
5
  import { Button } from "@/components/ui/button";
6
- import { Flag, Clock, Hash, ArrowRight, Bot, User, ChevronDown, ChevronUp, Info } from "lucide-react";
 
 
 
 
 
 
 
 
 
 
7
  import { useInference } from "@/lib/inference";
8
  import { Label } from "@/components/ui/label";
9
  import { cn } from "@/lib/utils";
@@ -15,10 +25,16 @@ import {
15
  } from "@/components/ui/tooltip";
16
 
17
  import { API_BASE } from "@/lib/constants";
18
-
 
19
  // Simple Switch component since it's not available in the UI components
20
- const Switch = ({ checked, onCheckedChange, disabled, id }: {
21
- checked: boolean;
 
 
 
 
 
22
  onCheckedChange: (checked: boolean) => void;
23
  disabled?: boolean;
24
  id?: string;
@@ -112,14 +128,19 @@ export default function GameComponent({
112
  const [gameStatus, setGameStatus] = useState<"playing" | "won" | "lost">(
113
  "playing"
114
  );
115
- const [continuousPlay, setContinuousPlay] = useState<boolean>(false);
116
- const [autoRunning, setAutoRunning] = useState<boolean>(false);
117
-
118
  const [convo, setConvo] = useState<Message[]>([]);
119
- const [expandedMessages, setExpandedMessages] = useState<Record<number, boolean>>({});
 
 
120
  const messagesEndRef = useRef<HTMLDivElement>(null);
121
 
122
- const { status: modelStatus, partialText, inference } = useInference({
 
 
 
 
123
  apiKey:
124
  window.localStorage.getItem("huggingface_access_token") || undefined,
125
  });
@@ -165,6 +186,29 @@ export default function GameComponent({
165
  setVisitedNodes((prev) => [...prev, link]);
166
  };
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  const makeModelMove = async () => {
169
  const prompt = buildPrompt(
170
  currentPage,
@@ -250,25 +294,40 @@ export default function GameComponent({
250
  }, [convo, partialText]);
251
 
252
  const toggleMessageExpand = (index: number) => {
253
- setExpandedMessages(prev => ({
254
  ...prev,
255
- [index]: !prev[index]
256
  }));
257
  };
258
 
259
  // Effect for continuous play mode
260
  useEffect(() => {
261
- if (continuousPlay && autoRunning && player === "model" && gameStatus === "playing" && modelStatus !== "thinking" && !linksLoading) {
 
 
 
 
 
 
 
262
  const timer = setTimeout(() => {
263
  makeModelMove();
264
  }, 1000);
265
-
266
  return () => clearTimeout(timer);
267
  }
268
- }, [continuousPlay, autoRunning, player, gameStatus, modelStatus, linksLoading, currentPage]);
 
 
 
 
 
 
 
 
269
 
270
  return (
271
- <div className="grid grid-cols-1 md:grid-cols-12 gap-2 h-[calc(100vh-200px)] grid-rows-[auto_1fr]">
272
  {/* Condensed Game Status Card */}
273
  <Card className="p-2 col-span-12 h-12 row-start-1">
274
  <div className="flex items-center justify-between h-full">
@@ -333,7 +392,11 @@ export default function GameComponent({
333
  setContinuousPlay(checked);
334
  if (!checked) setAutoRunning(false);
335
  }}
336
- disabled={(modelStatus === "thinking" || linksLoading) || (continuousPlay && autoRunning)}
 
 
 
 
337
  />
338
  <Label htmlFor="continuous-play" className="text-xs">
339
  Auto
@@ -370,97 +433,100 @@ export default function GameComponent({
370
  </Card>
371
 
372
  {/* Links panel - larger now */}
373
- <Card className="p-3 md:col-span-6 h-full overflow-hidden row-start-2">
374
- <h2 className="text-lg font-bold mb-2">
375
- Available Links
376
- <TooltipProvider>
377
- <Tooltip>
378
- <TooltipTrigger asChild>
379
- <span className="ml-2 text-xs text-muted-foreground cursor-help inline-flex items-center">
380
- <Info className="h-3 w-3 mr-1" />
381
- Why are some links missing?
382
- </span>
383
- </TooltipTrigger>
384
- <TooltipContent className="max-w-[300px] p-3">
385
- <p>
386
- We're playing on a pruned version of Simple Wikipedia so that
387
- every path between articles is possible. See dataset details{" "}
388
- <a
389
- href="https://huggingface.co/datasets/HuggingFaceTB/simplewiki-pruned-350k"
390
- target="_blank"
391
- rel="noopener noreferrer"
392
- className="text-blue-600 underline hover:text-blue-800"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  >
394
- here
395
- </a>
396
- .
397
- </p>
398
- </TooltipContent>
399
- </Tooltip>
400
- </TooltipProvider>
401
- </h2>
402
-
403
- {gameStatus === "playing" ? (
404
- <div className="grid grid-cols-3 gap-x-1 gap-y-0 overflow-y-auto h-[calc(100%-2.5rem)]">
405
- {currentPageLinks
406
- .sort((a, b) => a.localeCompare(b))
407
- .map((link) => (
408
- <Button
409
- key={link}
410
- variant="outline"
411
- size="sm"
412
- className="justify-start overflow-hidden text-ellipsis whitespace-nowrap"
413
- onClick={() => handleLinkClick(link)}
414
- disabled={player === "model" || modelStatus === "thinking"}
415
- >
416
- {link}
417
- </Button>
418
- ))}
419
- </div>
420
- ) : (
421
- <div className="flex items-center justify-center h-[calc(100%-2.5rem)]">
422
- {gameStatus === "won" ? (
423
- <div className="bg-green-100 text-green-800 p-4 rounded-md w-full">
424
- <h3 className="font-bold">
425
- {player === "model" ? `${model} won!` : "You won!"}
426
- </h3>
427
- <p>
428
- {player === "model" ? "It" : "You"} reached {targetPage} in{" "}
429
- {hops} hops.
430
- </p>
431
- <Button
432
- onClick={onReset}
433
- variant="outline"
434
- size="sm"
435
- className="mt-2"
436
- >
437
- New Game
438
- </Button>
439
- </div>
440
- ) : (
441
- <div className="bg-red-100 text-red-800 p-4 rounded-md w-full">
442
- <h3 className="font-bold">Game Over</h3>
443
- <p>
444
- {player === "model" ? `${model} didn't` : "You didn't"} reach{" "}
445
- {targetPage} within {maxHops} hops.
446
- </p>
447
- <Button
448
- onClick={onReset}
449
- variant="outline"
450
- size="sm"
451
- className="mt-2"
452
- >
453
- New Game
454
- </Button>
455
- </div>
456
- )}
457
- </div>
458
- )}
459
- </Card>
460
 
461
- {/* Reasoning panel - larger now */}
462
  {player === "model" && (
463
- <Card className="p-3 md:col-span-6 h-full overflow-hidden row-start-2">
464
  <h2 className="text-lg font-bold mb-2">LLM Reasoning</h2>
465
  <div className="overflow-y-auto h-[calc(100%-2.5rem)] space-y-2 pr-2">
466
  {convo.map((message, index) => {
@@ -536,18 +602,33 @@ export default function GameComponent({
536
  </Card>
537
  )}
538
 
539
- {player === "me" && (
540
- <Card className="p-3 md:col-span-6 h-full overflow-hidden row-start-2">
541
- <h2 className="text-lg font-bold mb-2">Wikipedia View</h2>
 
542
  <iframe
 
 
 
 
 
 
 
 
 
543
  src={`https://simple.wikipedia.org/wiki/${currentPage.replace(
544
  " ",
545
  "_"
546
  )}`}
547
- className="w-full h-full"
548
  />
549
- </Card>
550
- )}
 
 
 
 
 
551
  </div>
552
  );
553
  }
 
1
  "use client";
2
 
3
+ import { useState, useEffect, useCallback, useRef, useMemo } from "react";
4
  import { Card } from "@/components/ui/card";
5
  import { Button } from "@/components/ui/button";
6
+ import {
7
+ Flag,
8
+ Clock,
9
+ Hash,
10
+ ArrowRight,
11
+ Bot,
12
+ User,
13
+ ChevronDown,
14
+ ChevronUp,
15
+ Info,
16
+ } from "lucide-react";
17
  import { useInference } from "@/lib/inference";
18
  import { Label } from "@/components/ui/label";
19
  import { cn } from "@/lib/utils";
 
25
  } from "@/components/ui/tooltip";
26
 
27
  import { API_BASE } from "@/lib/constants";
28
+ import ForceDirectedGraph from "./force-directed-graph";
29
+ import qwen3Data from "../../results/qwen3.json"
30
  // Simple Switch component since it's not available in the UI components
31
+ const Switch = ({
32
+ checked,
33
+ onCheckedChange,
34
+ disabled,
35
+ id,
36
+ }: {
37
+ checked: boolean;
38
  onCheckedChange: (checked: boolean) => void;
39
  disabled?: boolean;
40
  id?: string;
 
128
  const [gameStatus, setGameStatus] = useState<"playing" | "won" | "lost">(
129
  "playing"
130
  );
131
+ const [continuousPlay, setContinuousPlay] = useState<boolean>(true);
132
+ const [autoRunning, setAutoRunning] = useState<boolean>(true);
 
133
  const [convo, setConvo] = useState<Message[]>([]);
134
+ const [expandedMessages, setExpandedMessages] = useState<
135
+ Record<number, boolean>
136
+ >({});
137
  const messagesEndRef = useRef<HTMLDivElement>(null);
138
 
139
+ const {
140
+ status: modelStatus,
141
+ partialText,
142
+ inference,
143
+ } = useInference({
144
  apiKey:
145
  window.localStorage.getItem("huggingface_access_token") || undefined,
146
  });
 
186
  setVisitedNodes((prev) => [...prev, link]);
187
  };
188
 
189
+ const currentRuns = useMemo(() => {
190
+ const q3runs = qwen3Data.runs.filter((run) => run.result === "win");
191
+
192
+ if (visitedNodes.length === 0) {
193
+ return q3runs;
194
+ }
195
+
196
+ return [
197
+ {
198
+ steps: [
199
+ {
200
+ type: "start",
201
+ article: startPage,
202
+ },
203
+ ...visitedNodes.map((node) => ({ type: "move", article: node })),
204
+ ],
205
+ start_article: startPage,
206
+ destination_article: targetPage,
207
+ },
208
+ ...q3runs,
209
+ ];
210
+ }, [visitedNodes, startPage, targetPage]);
211
+
212
  const makeModelMove = async () => {
213
  const prompt = buildPrompt(
214
  currentPage,
 
294
  }, [convo, partialText]);
295
 
296
  const toggleMessageExpand = (index: number) => {
297
+ setExpandedMessages((prev) => ({
298
  ...prev,
299
+ [index]: !prev[index],
300
  }));
301
  };
302
 
303
  // Effect for continuous play mode
304
  useEffect(() => {
305
+ if (
306
+ continuousPlay &&
307
+ autoRunning &&
308
+ player === "model" &&
309
+ gameStatus === "playing" &&
310
+ modelStatus !== "thinking" &&
311
+ !linksLoading
312
+ ) {
313
  const timer = setTimeout(() => {
314
  makeModelMove();
315
  }, 1000);
316
+
317
  return () => clearTimeout(timer);
318
  }
319
+ }, [
320
+ continuousPlay,
321
+ autoRunning,
322
+ player,
323
+ gameStatus,
324
+ modelStatus,
325
+ linksLoading,
326
+ currentPage,
327
+ ]);
328
 
329
  return (
330
+ <div className="grid grid-cols-1 md:grid-cols-12 gap-2 h-[calc(100vh-200px)] grid-rows-[auto_1fr_1fr]">
331
  {/* Condensed Game Status Card */}
332
  <Card className="p-2 col-span-12 h-12 row-start-1">
333
  <div className="flex items-center justify-between h-full">
 
392
  setContinuousPlay(checked);
393
  if (!checked) setAutoRunning(false);
394
  }}
395
+ disabled={
396
+ modelStatus === "thinking" ||
397
+ linksLoading ||
398
+ (continuousPlay && autoRunning)
399
+ }
400
  />
401
  <Label htmlFor="continuous-play" className="text-xs">
402
  Auto
 
433
  </Card>
434
 
435
  {/* Links panel - larger now */}
436
+ {player === "me" && (
437
+ <Card className="p-3 md:col-span-6 h-full overflow-hidden row-span-2 row-start-2">
438
+ <h2 className="text-lg font-bold mb-2">
439
+ Available Links
440
+ <TooltipProvider>
441
+ <Tooltip>
442
+ <TooltipTrigger asChild>
443
+ <span className="ml-2 text-xs text-muted-foreground cursor-help inline-flex items-center">
444
+ <Info className="h-3 w-3 mr-1" />
445
+ Why are some links missing?
446
+ </span>
447
+ </TooltipTrigger>
448
+ <TooltipContent className="max-w-[300px] p-3">
449
+ <p>
450
+ We're playing on a pruned version of Simple Wikipedia so
451
+ that every path between articles is possible. See dataset
452
+ details{" "}
453
+ <a
454
+ href="https://huggingface.co/datasets/HuggingFaceTB/simplewiki-pruned-350k"
455
+ target="_blank"
456
+ rel="noopener noreferrer"
457
+ className="text-blue-600 underline hover:text-blue-800"
458
+ >
459
+ here
460
+ </a>
461
+ .
462
+ </p>
463
+ </TooltipContent>
464
+ </Tooltip>
465
+ </TooltipProvider>
466
+ </h2>
467
+
468
+ {gameStatus === "playing" ? (
469
+ <div className="grid grid-cols-3 gap-x-1 gap-y-0 overflow-y-auto h-[calc(100%-2.5rem)]">
470
+ {currentPageLinks
471
+ .sort((a, b) => a.localeCompare(b))
472
+ .map((link) => (
473
+ <Button
474
+ key={link}
475
+ variant="outline"
476
+ size="sm"
477
+ className="justify-start overflow-hidden text-ellipsis whitespace-nowrap"
478
+ onClick={() => handleLinkClick(link)}
479
+ disabled={player === "model" || modelStatus === "thinking"}
480
  >
481
+ {link}
482
+ </Button>
483
+ ))}
484
+ </div>
485
+ ) : (
486
+ <div className="flex items-center justify-center h-[calc(100%-2.5rem)]">
487
+ {gameStatus === "won" ? (
488
+ <div className="bg-green-100 text-green-800 p-4 rounded-md w-full">
489
+ <h3 className="font-bold">
490
+ {player === "model" ? `${model} won!` : "You won!"}
491
+ </h3>
492
+ <p>
493
+ {player === "model" ? "It" : "You"} reached {targetPage} in{" "}
494
+ {hops} hops.
495
+ </p>
496
+ <Button
497
+ onClick={onReset}
498
+ variant="outline"
499
+ size="sm"
500
+ className="mt-2"
501
+ >
502
+ New Game
503
+ </Button>
504
+ </div>
505
+ ) : (
506
+ <div className="bg-red-100 text-red-800 p-4 rounded-md w-full">
507
+ <h3 className="font-bold">Game Over</h3>
508
+ <p>
509
+ {player === "model" ? `${model} didn't` : "You didn't"}{" "}
510
+ reach {targetPage} within {maxHops} hops.
511
+ </p>
512
+ <Button
513
+ onClick={onReset}
514
+ variant="outline"
515
+ size="sm"
516
+ className="mt-2"
517
+ >
518
+ New Game
519
+ </Button>
520
+ </div>
521
+ )}
522
+ </div>
523
+ )}
524
+ </Card>
525
+ )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
 
527
+ {/* Reasoning panel - spans full height on left side */}
528
  {player === "model" && (
529
+ <Card className="p-3 md:col-span-6 h-full overflow-hidden row-span-2 row-start-2">
530
  <h2 className="text-lg font-bold mb-2">LLM Reasoning</h2>
531
  <div className="overflow-y-auto h-[calc(100%-2.5rem)] space-y-2 pr-2">
532
  {convo.map((message, index) => {
 
602
  </Card>
603
  )}
604
 
605
+ {/* Wikipedia view - top right quadrant */}
606
+ <Card className="p-3 md:col-span-6 h-full overflow-hidden row-start-2">
607
+ <h2 className="text-lg font-bold mb-2">Wikipedia View</h2>
608
+ <div className="relative w-full h-[calc(100%-2.5rem)] overflow-hidden">
609
  <iframe
610
+ style={{
611
+ transform: "scale(0.5, 0.5)",
612
+ width: "calc(100% * 2)",
613
+ height: "calc(100% * 2)",
614
+ transformOrigin: "top left",
615
+ position: "absolute",
616
+ top: 0,
617
+ left: 0,
618
+ }}
619
  src={`https://simple.wikipedia.org/wiki/${currentPage.replace(
620
  " ",
621
  "_"
622
  )}`}
623
+ className="border-0"
624
  />
625
+ </div>
626
+ </Card>
627
+
628
+ {/* Force directed graph - bottom right quadrant */}
629
+ <Card className="p-3 md:col-span-6 h-full overflow-hidden row-start-3">
630
+ <ForceDirectedGraph runs={currentRuns} runId={0} />
631
+ </Card>
632
  </div>
633
  );
634
  }
src/components/play-tab.tsx CHANGED
@@ -35,7 +35,7 @@ export default function PlayTab({
35
  startArticle?: string;
36
  destinationArticle?: string;
37
  }) {
38
- const [player, setPlayer] = useState<"me" | "model">("me");
39
  const [selectedModel, setSelectedModel] = useState<string | undefined>(
40
  "deepseek-ai/DeepSeek-V3-0324"
41
  );
 
35
  startArticle?: string;
36
  destinationArticle?: string;
37
  }) {
38
+ const [player, setPlayer] = useState<"me" | "model">("model");
39
  const [selectedModel, setSelectedModel] = useState<string | undefined>(
40
  "deepseek-ai/DeepSeek-V3-0324"
41
  );