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

better layout and fdg

Browse files
src/components/force-directed-graph.tsx CHANGED
@@ -143,7 +143,7 @@ export default function ForceDirectedGraph({
143
 
144
  mainNodes.forEach((node) => {
145
  const oldNode = nodesMap.get(node)!;
146
- nodesMap.set(node, { ...oldNode, type: "fixed", radius: 7, isMainNode: true });
147
  });
148
 
149
  // position the main nodes in a circle
 
143
 
144
  mainNodes.forEach((node) => {
145
  const oldNode = nodesMap.get(node)!;
146
+ nodesMap.set(node, { ...oldNode, id: node, type: "fixed", radius: 7, isMainNode: true });
147
  });
148
 
149
  // position the main nodes in a circle
src/components/game-component.tsx CHANGED
@@ -65,8 +65,14 @@ const Switch = ({
65
  };
66
 
67
  type Message = {
68
- role: "user" | "assistant";
69
  content: string;
 
 
 
 
 
 
70
  };
71
 
72
  const buildPrompt = (
@@ -132,8 +138,8 @@ export default function GameComponent({
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 {
@@ -261,6 +267,16 @@ export default function GameComponent({
261
 
262
  const selectedLink = currentPageLinks[answerInt - 1];
263
 
 
 
 
 
 
 
 
 
 
 
264
  console.log(
265
  "Model picked selectedLink",
266
  selectedLink,
@@ -293,7 +309,7 @@ export default function GameComponent({
293
  scrollToBottom();
294
  }, [convo, partialText]);
295
 
296
- const toggleMessageExpand = (index: number) => {
297
  setExpandedMessages((prev) => ({
298
  ...prev,
299
  [index]: !prev[index],
@@ -326,6 +342,22 @@ export default function GameComponent({
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 */}
@@ -531,61 +563,149 @@ export default function GameComponent({
531
  <div className="overflow-y-auto h-[calc(100%-2.5rem)] space-y-2 pr-2">
532
  {convo.map((message, index) => {
533
  const isExpanded = expandedMessages[index] || false;
534
- const isLongUserMessage =
535
- message.role === "user" && message.content.length > 300;
536
- const shouldTruncate = isLongUserMessage && !isExpanded;
537
-
538
- return (
539
- <div
540
- key={index}
541
- className={`p-2 rounded-lg text-xs ${
542
- message.role === "assistant"
543
- ? "bg-blue-50 border border-blue-100"
544
- : "bg-gray-50 border border-gray-100"
545
- }`}
546
- >
547
- <div className="flex items-center gap-1 mb-1 text-xs font-medium text-muted-foreground">
548
- {message.role === "assistant" ? (
549
- <>
550
- <Bot className="h-3 w-3" />
551
- <span>Assistant</span>
552
- </>
553
- ) : (
554
- <>
555
- <User className="h-3 w-3" />
556
- <span>User</span>
557
- </>
558
- )}
559
- </div>
560
-
561
- <div>
562
- <p className="whitespace-pre-wrap text-xs">
563
- {shouldTruncate
564
- ? message.content.substring(0, 300) + "..."
565
- : message.content}
566
- </p>
567
 
568
- {isLongUserMessage && (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
  <Button
570
  variant="ghost"
571
  size="sm"
572
- className="mt-1 h-5 text-xs flex items-center gap-1 text-muted-foreground hover:text-foreground"
573
  onClick={() => toggleMessageExpand(index)}
574
  >
575
- {isExpanded ? (
576
- <>
577
- <ChevronUp className="h-3 w-3" /> Show less
578
- </>
579
  ) : (
580
- <>
581
- <ChevronDown className="h-3 w-3" /> Show more
582
- </>
583
  )}
584
  </Button>
585
- )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  </div>
587
- </div>
588
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  })}
590
 
591
  {modelStatus === "thinking" && (
@@ -597,6 +717,7 @@ export default function GameComponent({
597
  <p className="whitespace-pre-wrap text-xs">{partialText}</p>
598
  </div>
599
  )}
 
600
  <div ref={messagesEndRef} />
601
  </div>
602
  </Card>
 
65
  };
66
 
67
  type Message = {
68
+ role: "user" | "assistant" | "game" | "result";
69
  content: string;
70
+ metadata?: {
71
+ page?: string;
72
+ links?: string[];
73
+ status?: "playing" | "won" | "lost";
74
+ path?: string[];
75
+ };
76
  };
77
 
78
  const buildPrompt = (
 
138
  const [autoRunning, setAutoRunning] = useState<boolean>(true);
139
  const [convo, setConvo] = useState<Message[]>([]);
140
  const [expandedMessages, setExpandedMessages] = useState<
141
+ Record<number | string, boolean>
142
+ >({ game: false });
143
  const messagesEndRef = useRef<HTMLDivElement>(null);
144
 
145
  const {
 
267
 
268
  const selectedLink = currentPageLinks[answerInt - 1];
269
 
270
+ // Add a game status message after each move
271
+ pushConvo({
272
+ role: "game",
273
+ content: `Model selected link ${answerInt}: ${selectedLink}`,
274
+ metadata: {
275
+ page: currentPage,
276
+ links: [...currentPageLinks],
277
+ },
278
+ });
279
+
280
  console.log(
281
  "Model picked selectedLink",
282
  selectedLink,
 
309
  scrollToBottom();
310
  }, [convo, partialText]);
311
 
312
+ const toggleMessageExpand = (index: number | string) => {
313
  setExpandedMessages((prev) => ({
314
  ...prev,
315
  [index]: !prev[index],
 
342
  currentPage,
343
  ]);
344
 
345
+ // Add a result message when the game ends
346
+ useEffect(() => {
347
+ if (gameStatus !== "playing" && convo.length > 0 && convo[convo.length - 1].role !== "result") {
348
+ pushConvo({
349
+ role: "result",
350
+ content: gameStatus === "won"
351
+ ? `${model} successfully navigated from ${visitedNodes[0]} to ${targetPage} in ${hops} moves!`
352
+ : `${model} failed to reach ${targetPage} within the ${maxHops} hop limit.`,
353
+ metadata: {
354
+ status: gameStatus,
355
+ path: [...visitedNodes],
356
+ },
357
+ });
358
+ }
359
+ }, [gameStatus]);
360
+
361
  return (
362
  <div className="grid grid-cols-1 md:grid-cols-12 gap-2 h-[calc(100vh-200px)] grid-rows-[auto_1fr_1fr]">
363
  {/* Condensed Game Status Card */}
 
563
  <div className="overflow-y-auto h-[calc(100%-2.5rem)] space-y-2 pr-2">
564
  {convo.map((message, index) => {
565
  const isExpanded = expandedMessages[index] || false;
566
+
567
+ if (message.role === "user" || message.role === "assistant") {
568
+ const isLongUserMessage =
569
+ message.role === "user" && message.content.length > 300;
570
+ const shouldTruncate = isLongUserMessage && !isExpanded;
571
+
572
+ return (
573
+ <div
574
+ key={`message-${index}`}
575
+ className={`p-2 rounded-lg text-xs ${
576
+ message.role === "assistant"
577
+ ? "bg-blue-50 border border-blue-100"
578
+ : "bg-gray-50 border border-gray-100"
579
+ }`}
580
+ >
581
+ <div className="flex items-center gap-1 mb-1 text-xs font-medium text-muted-foreground">
582
+ {message.role === "assistant" ? (
583
+ <>
584
+ <Bot className="h-3 w-3" />
585
+ <span>Assistant</span>
586
+ </>
587
+ ) : (
588
+ <>
589
+ <User className="h-3 w-3" />
590
+ <span>User</span>
591
+ </>
592
+ )}
593
+ </div>
 
 
 
 
 
594
 
595
+ <div>
596
+ <p className="whitespace-pre-wrap text-xs">
597
+ {shouldTruncate
598
+ ? message.content.substring(0, 300) + "..."
599
+ : message.content}
600
+ </p>
601
+
602
+ {isLongUserMessage && (
603
+ <Button
604
+ variant="ghost"
605
+ size="sm"
606
+ className="mt-1 h-5 text-xs flex items-center gap-1 text-muted-foreground hover:text-foreground"
607
+ onClick={() => toggleMessageExpand(index)}
608
+ >
609
+ {isExpanded ? (
610
+ <>
611
+ <ChevronUp className="h-3 w-3" /> Show less
612
+ </>
613
+ ) : (
614
+ <>
615
+ <ChevronDown className="h-3 w-3" /> Show more
616
+ </>
617
+ )}
618
+ </Button>
619
+ )}
620
+ </div>
621
+ </div>
622
+ );
623
+ } else if (message.role === "game") {
624
+ // Game status block
625
+ return (
626
+ <div
627
+ key={`game-${index}`}
628
+ className="p-2 rounded-lg bg-yellow-50 border border-yellow-100 text-xs"
629
+ >
630
+ <div className="flex items-center justify-between mb-1">
631
+ <div className="flex items-center gap-1 text-xs font-medium text-muted-foreground">
632
+ <Info className="h-3 w-3" />
633
+ <span>Game Status</span>
634
+ </div>
635
  <Button
636
  variant="ghost"
637
  size="sm"
638
+ className="h-5 text-xs flex items-center gap-1 text-muted-foreground hover:text-foreground p-0"
639
  onClick={() => toggleMessageExpand(index)}
640
  >
641
+ {expandedMessages[index] ? (
642
+ <ChevronUp className="h-3 w-3" />
 
 
643
  ) : (
644
+ <ChevronDown className="h-3 w-3" />
 
 
645
  )}
646
  </Button>
647
+ </div>
648
+
649
+ <div>
650
+ <p className="font-medium">{message.content}</p>
651
+ {message.metadata?.page && (
652
+ <p className="mt-1">Current page: {message.metadata.page}</p>
653
+ )}
654
+ {message.metadata?.links && (
655
+ <p className="mt-1">
656
+ Available links: {message.metadata.links.length}
657
+ {!isExpanded && message.metadata.links.length > 0 && (
658
+ <span className="text-muted-foreground">
659
+ {" "}({message.metadata.links.slice(0, 3).join(", ")}
660
+ {message.metadata.links.length > 3 ? "..." : ""})
661
+ </span>
662
+ )}
663
+ </p>
664
+ )}
665
+
666
+ {isExpanded && message.metadata?.links && (
667
+ <div className="mt-2 space-y-1">
668
+ {message.metadata.links.map((link, i) => (
669
+ <div key={i} className="text-xs text-muted-foreground">
670
+ {i+1}. {link}
671
+ </div>
672
+ ))}
673
+ </div>
674
+ )}
675
+ </div>
676
  </div>
677
+ );
678
+ } else if (message.role === "result") {
679
+ // Result block
680
+ const isWon = message.metadata?.status === "won";
681
+ return (
682
+ <div
683
+ key={`result-${index}`}
684
+ className={`p-2 rounded-lg text-xs ${
685
+ isWon
686
+ ? "bg-green-50 border border-green-100"
687
+ : "bg-red-50 border border-red-100"
688
+ }`}
689
+ >
690
+ <div className="flex items-center gap-1 mb-1 text-xs font-medium text-muted-foreground">
691
+ <Flag className="h-3 w-3" />
692
+ <span>{isWon ? "Victory!" : "Game Over"}</span>
693
+ </div>
694
+
695
+ <div>
696
+ <p>{message.content}</p>
697
+
698
+ {message.metadata?.path && (
699
+ <p className="mt-1 text-xs text-muted-foreground">
700
+ Path: {message.metadata.path.join(" → ")}
701
+ </p>
702
+ )}
703
+ </div>
704
+ </div>
705
+ );
706
+ }
707
+
708
+ return null;
709
  })}
710
 
711
  {modelStatus === "thinking" && (
 
717
  <p className="whitespace-pre-wrap text-xs">{partialText}</p>
718
  </div>
719
  )}
720
+
721
  <div ref={messagesEndRef} />
722
  </div>
723
  </Card>