inspect-ai 0.3.96__py3-none-any.whl → 0.3.97__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. inspect_ai/_eval/eval.py +10 -2
  2. inspect_ai/_eval/task/util.py +32 -3
  3. inspect_ai/_util/registry.py +7 -0
  4. inspect_ai/_util/timer.py +13 -0
  5. inspect_ai/_view/www/dist/assets/index.css +275 -195
  6. inspect_ai/_view/www/dist/assets/index.js +8568 -7376
  7. inspect_ai/_view/www/src/app/App.css +1 -0
  8. inspect_ai/_view/www/src/app/App.tsx +27 -10
  9. inspect_ai/_view/www/src/app/appearance/icons.ts +5 -0
  10. inspect_ai/_view/www/src/app/content/RecordTree.module.css +22 -0
  11. inspect_ai/_view/www/src/app/content/RecordTree.tsx +370 -0
  12. inspect_ai/_view/www/src/app/content/RenderedContent.module.css +5 -0
  13. inspect_ai/_view/www/src/app/content/RenderedContent.tsx +32 -19
  14. inspect_ai/_view/www/src/app/content/record_processors/store.ts +101 -0
  15. inspect_ai/_view/www/src/app/content/record_processors/types.ts +3 -0
  16. inspect_ai/_view/www/src/app/content/types.ts +5 -0
  17. inspect_ai/_view/www/src/app/log-view/LogView.tsx +1 -0
  18. inspect_ai/_view/www/src/app/log-view/LogViewContainer.tsx +35 -28
  19. inspect_ai/_view/www/src/app/log-view/LogViewLayout.tsx +1 -8
  20. inspect_ai/_view/www/src/app/log-view/navbar/PrimaryBar.tsx +2 -4
  21. inspect_ai/_view/www/src/app/log-view/navbar/ResultsPanel.tsx +13 -3
  22. inspect_ai/_view/www/src/app/log-view/navbar/ScoreGrid.module.css +15 -0
  23. inspect_ai/_view/www/src/app/log-view/navbar/ScoreGrid.tsx +14 -10
  24. inspect_ai/_view/www/src/app/log-view/tabs/InfoTab.tsx +9 -3
  25. inspect_ai/_view/www/src/app/log-view/tabs/JsonTab.tsx +1 -3
  26. inspect_ai/_view/www/src/app/log-view/tabs/SamplesTab.tsx +8 -2
  27. inspect_ai/_view/www/src/app/log-view/types.ts +1 -0
  28. inspect_ai/_view/www/src/app/plan/ModelCard.module.css +7 -0
  29. inspect_ai/_view/www/src/app/plan/ModelCard.tsx +5 -2
  30. inspect_ai/_view/www/src/app/plan/PlanCard.tsx +13 -8
  31. inspect_ai/_view/www/src/app/routing/navigationHooks.ts +63 -8
  32. inspect_ai/_view/www/src/app/routing/url.ts +45 -0
  33. inspect_ai/_view/www/src/app/samples/InlineSampleDisplay.module.css +2 -1
  34. inspect_ai/_view/www/src/app/samples/InlineSampleDisplay.tsx +15 -8
  35. inspect_ai/_view/www/src/app/samples/SampleDialog.module.css +3 -0
  36. inspect_ai/_view/www/src/app/samples/SampleDialog.tsx +16 -5
  37. inspect_ai/_view/www/src/app/samples/SampleDisplay.module.css +9 -1
  38. inspect_ai/_view/www/src/app/samples/SampleDisplay.tsx +68 -31
  39. inspect_ai/_view/www/src/app/samples/chat/ChatMessage.module.css +12 -7
  40. inspect_ai/_view/www/src/app/samples/chat/ChatMessage.tsx +17 -5
  41. inspect_ai/_view/www/src/app/samples/chat/ChatMessageRow.module.css +9 -0
  42. inspect_ai/_view/www/src/app/samples/chat/ChatMessageRow.tsx +48 -18
  43. inspect_ai/_view/www/src/app/samples/chat/ChatView.tsx +0 -1
  44. inspect_ai/_view/www/src/app/samples/chat/ChatViewVirtualList.module.css +4 -0
  45. inspect_ai/_view/www/src/app/samples/chat/ChatViewVirtualList.tsx +41 -1
  46. inspect_ai/_view/www/src/app/samples/chat/messages.ts +7 -0
  47. inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.module.css +0 -3
  48. inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.tsx +1 -1
  49. inspect_ai/_view/www/src/app/samples/chat/tools/ToolInput.module.css +1 -1
  50. inspect_ai/_view/www/src/app/samples/chat/tools/ToolOutput.module.css +1 -1
  51. inspect_ai/_view/www/src/app/samples/descriptor/score/NumericScoreDescriptor.tsx +5 -1
  52. inspect_ai/_view/www/src/app/samples/descriptor/score/PassFailScoreDescriptor.tsx +11 -6
  53. inspect_ai/_view/www/src/app/samples/list/SampleList.tsx +7 -0
  54. inspect_ai/_view/www/src/app/samples/list/SampleRow.tsx +5 -18
  55. inspect_ai/_view/www/src/app/samples/sample-tools/SortFilter.tsx +1 -1
  56. inspect_ai/_view/www/src/app/samples/scores/SampleScoresGrid.tsx +18 -5
  57. inspect_ai/_view/www/src/app/samples/scores/SampleScoresView.module.css +0 -6
  58. inspect_ai/_view/www/src/app/samples/scores/SampleScoresView.tsx +4 -1
  59. inspect_ai/_view/www/src/app/samples/transcript/ApprovalEventView.tsx +4 -2
  60. inspect_ai/_view/www/src/app/samples/transcript/ErrorEventView.tsx +6 -4
  61. inspect_ai/_view/www/src/app/samples/transcript/InfoEventView.module.css +1 -1
  62. inspect_ai/_view/www/src/app/samples/transcript/InfoEventView.tsx +13 -6
  63. inspect_ai/_view/www/src/app/samples/transcript/InputEventView.tsx +6 -4
  64. inspect_ai/_view/www/src/app/samples/transcript/LoggerEventView.tsx +4 -2
  65. inspect_ai/_view/www/src/app/samples/transcript/ModelEventView.tsx +11 -8
  66. inspect_ai/_view/www/src/app/samples/transcript/SampleInitEventView.tsx +14 -8
  67. inspect_ai/_view/www/src/app/samples/transcript/SampleLimitEventView.tsx +13 -8
  68. inspect_ai/_view/www/src/app/samples/transcript/SandboxEventView.tsx +25 -16
  69. inspect_ai/_view/www/src/app/samples/transcript/ScoreEventView.tsx +7 -5
  70. inspect_ai/_view/www/src/app/samples/transcript/SpanEventView.tsx +11 -28
  71. inspect_ai/_view/www/src/app/samples/transcript/StepEventView.tsx +12 -20
  72. inspect_ai/_view/www/src/app/samples/transcript/SubtaskEventView.tsx +12 -31
  73. inspect_ai/_view/www/src/app/samples/transcript/ToolEventView.tsx +25 -29
  74. inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualList.tsx +297 -0
  75. inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.module.css +0 -8
  76. inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.tsx +43 -25
  77. inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.module.css +43 -0
  78. inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.tsx +109 -43
  79. inspect_ai/_view/www/src/app/samples/transcript/state/StateEventView.tsx +19 -8
  80. inspect_ai/_view/www/src/app/samples/transcript/transform/treeify.ts +128 -60
  81. inspect_ai/_view/www/src/app/samples/transcript/transform/utils.ts +14 -4
  82. inspect_ai/_view/www/src/app/samples/transcript/types.ts +6 -4
  83. inspect_ai/_view/www/src/app/types.ts +12 -1
  84. inspect_ai/_view/www/src/components/Card.css +6 -3
  85. inspect_ai/_view/www/src/components/Card.tsx +15 -2
  86. inspect_ai/_view/www/src/components/CopyButton.tsx +4 -6
  87. inspect_ai/_view/www/src/components/ExpandablePanel.module.css +20 -14
  88. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +17 -22
  89. inspect_ai/_view/www/src/components/LargeModal.tsx +5 -1
  90. inspect_ai/_view/www/src/components/LiveVirtualList.tsx +25 -1
  91. inspect_ai/_view/www/src/components/MarkdownDiv.css +4 -0
  92. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +2 -2
  93. inspect_ai/_view/www/src/components/TabSet.module.css +6 -1
  94. inspect_ai/_view/www/src/components/TabSet.tsx +8 -2
  95. inspect_ai/_view/www/src/state/hooks.ts +83 -13
  96. inspect_ai/_view/www/src/state/logPolling.ts +2 -2
  97. inspect_ai/_view/www/src/state/logSlice.ts +1 -2
  98. inspect_ai/_view/www/src/state/logsSlice.ts +9 -9
  99. inspect_ai/_view/www/src/state/samplePolling.ts +1 -1
  100. inspect_ai/_view/www/src/state/sampleSlice.ts +134 -7
  101. inspect_ai/_view/www/src/state/scoring.ts +1 -1
  102. inspect_ai/_view/www/src/state/scrolling.ts +39 -6
  103. inspect_ai/_view/www/src/state/store.ts +5 -0
  104. inspect_ai/_view/www/src/state/store_filter.ts +47 -44
  105. inspect_ai/_view/www/src/utils/debugging.ts +95 -0
  106. inspect_ai/_view/www/src/utils/format.ts +2 -2
  107. inspect_ai/_view/www/src/utils/json.ts +29 -0
  108. inspect_ai/agent/__init__.py +2 -1
  109. inspect_ai/agent/_agent.py +12 -0
  110. inspect_ai/agent/_react.py +184 -48
  111. inspect_ai/agent/_types.py +14 -1
  112. inspect_ai/analysis/beta/__init__.py +0 -2
  113. inspect_ai/analysis/beta/_dataframe/columns.py +11 -16
  114. inspect_ai/analysis/beta/_dataframe/evals/table.py +65 -40
  115. inspect_ai/analysis/beta/_dataframe/events/table.py +24 -36
  116. inspect_ai/analysis/beta/_dataframe/messages/table.py +24 -15
  117. inspect_ai/analysis/beta/_dataframe/progress.py +35 -5
  118. inspect_ai/analysis/beta/_dataframe/record.py +13 -9
  119. inspect_ai/analysis/beta/_dataframe/samples/columns.py +1 -1
  120. inspect_ai/analysis/beta/_dataframe/samples/table.py +156 -46
  121. inspect_ai/analysis/beta/_dataframe/util.py +14 -12
  122. inspect_ai/model/_call_tools.py +1 -1
  123. inspect_ai/model/_providers/anthropic.py +18 -5
  124. inspect_ai/model/_providers/azureai.py +7 -2
  125. inspect_ai/model/_providers/util/llama31.py +3 -3
  126. {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.97.dist-info}/METADATA +1 -1
  127. {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.97.dist-info}/RECORD +131 -126
  128. {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.97.dist-info}/WHEEL +1 -1
  129. inspect_ai/_view/www/src/app/samples/transcript/TranscriptView.module.css +0 -48
  130. inspect_ai/_view/www/src/app/samples/transcript/TranscriptView.tsx +0 -276
  131. {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.97.dist-info}/entry_points.txt +0 -0
  132. {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.97.dist-info}/licenses/LICENSE +0 -0
  133. {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.97.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,8 @@ interface ChatMessageRowProps {
13
13
  toolCallStyle: ChatViewToolCallStyle;
14
14
  indented?: boolean;
15
15
  padded?: boolean;
16
+ getMessageUrl?: (id: string) => string | undefined;
17
+ highlightUserMessage?: boolean;
16
18
  }
17
19
 
18
20
  /**
@@ -24,40 +26,68 @@ export const ChatMessageRow: FC<ChatMessageRowProps> = ({
24
26
  resolvedMessage,
25
27
  toolCallStyle,
26
28
  indented,
27
- padded,
29
+ getMessageUrl,
30
+ highlightUserMessage,
28
31
  }) => {
29
32
  if (number) {
30
33
  return (
31
- <div className={styles.grid}>
34
+ <>
32
35
  <div
33
36
  className={clsx(
34
- "text-size-smaller",
35
- "text-style-secondary",
36
- styles.number,
37
+ styles.grid,
38
+ styles.container,
39
+ highlightUserMessage && resolvedMessage.message.role === "user"
40
+ ? styles.user
41
+ : undefined,
37
42
  )}
38
43
  >
39
- {number}
44
+ <div
45
+ className={clsx(
46
+ "text-size-smaller",
47
+ "text-style-secondary",
48
+ styles.number,
49
+ )}
50
+ >
51
+ {number}
52
+ </div>
53
+ <ChatMessage
54
+ id={`${parentName}-chat-messages`}
55
+ message={resolvedMessage.message}
56
+ toolMessages={resolvedMessage.toolMessages}
57
+ indented={indented}
58
+ toolCallStyle={toolCallStyle}
59
+ getMessageUrl={getMessageUrl}
60
+ />
40
61
  </div>
62
+
63
+ {resolvedMessage.message.role === "user" ? (
64
+ <div style={{ height: "10px" }}></div>
65
+ ) : undefined}
66
+ </>
67
+ );
68
+ } else {
69
+ return (
70
+ <div
71
+ className={clsx(
72
+ styles.container,
73
+ styles.simple,
74
+ highlightUserMessage && resolvedMessage.message.role === "user"
75
+ ? styles.user
76
+ : undefined,
77
+ )}
78
+ >
41
79
  <ChatMessage
42
80
  id={`${parentName}-chat-messages`}
43
81
  message={resolvedMessage.message}
44
82
  toolMessages={resolvedMessage.toolMessages}
45
83
  indented={indented}
46
84
  toolCallStyle={toolCallStyle}
47
- padded={padded}
85
+ getMessageUrl={getMessageUrl}
48
86
  />
87
+ {resolvedMessage.message.role === "user" ? (
88
+ <div style={{ height: "10px" }}></div>
89
+ ) : undefined}
49
90
  </div>
50
91
  );
51
- } else {
52
- return (
53
- <ChatMessage
54
- id={`${parentName}-chat-messages`}
55
- message={resolvedMessage.message}
56
- toolMessages={resolvedMessage.toolMessages}
57
- indented={indented}
58
- toolCallStyle={toolCallStyle}
59
- padded={padded}
60
- />
61
- );
62
92
  }
63
93
  };
@@ -40,7 +40,6 @@ export const ChatView: FC<ChatViewProps> = ({
40
40
  resolvedMessage={msg}
41
41
  indented={indented}
42
42
  toolCallStyle={toolCallStyle}
43
- padded={index < collapsedMessages.length - 1}
44
43
  />
45
44
  );
46
45
  })}
@@ -2,3 +2,7 @@
2
2
  width: 100%;
3
3
  margin-top: 1em;
4
4
  }
5
+
6
+ .item {
7
+ padding-bottom: 1em;
8
+ }
@@ -4,18 +4,24 @@ import { Messages } from "../../../@types/log";
4
4
  import { ChatMessageRow } from "./ChatMessageRow";
5
5
  import { ResolvedMessage, resolveMessages } from "./messages";
6
6
 
7
+ import clsx from "clsx";
7
8
  import { LiveVirtualList } from "../../../components/LiveVirtualList";
8
9
  import { ChatViewToolCallStyle } from "./types";
9
10
 
11
+ import { ContextProp, ItemProps } from "react-virtuoso";
12
+ import styles from "./ChatViewVirtualList.module.css";
13
+
10
14
  interface ChatViewVirtualListProps {
11
15
  id: string;
12
16
  className?: string | string[];
13
17
  messages: Messages;
18
+ initialMessageId?: string | null;
14
19
  toolCallStyle: ChatViewToolCallStyle;
15
20
  indented: boolean;
16
21
  numbered?: boolean;
17
22
  scrollRef?: RefObject<HTMLDivElement | null>;
18
23
  running?: boolean;
24
+ getMessageUrl?: (id: string) => string | undefined;
19
25
  }
20
26
 
21
27
  /**
@@ -25,17 +31,30 @@ export const ChatViewVirtualList: FC<ChatViewVirtualListProps> = memo(
25
31
  ({
26
32
  id,
27
33
  messages,
34
+ initialMessageId,
28
35
  className,
29
36
  toolCallStyle,
30
37
  indented,
31
38
  numbered = true,
32
39
  scrollRef,
33
40
  running,
41
+ getMessageUrl,
34
42
  }) => {
35
43
  const collapsedMessages = useMemo(() => {
36
44
  return resolveMessages(messages);
37
45
  }, [messages]);
38
46
 
47
+ const initialMessageIndex = useMemo(() => {
48
+ if (initialMessageId === null || initialMessageId === undefined) {
49
+ return undefined;
50
+ }
51
+
52
+ const index = collapsedMessages.findIndex((message) => {
53
+ return message.message.id === initialMessageId;
54
+ });
55
+ return index !== -1 ? index : undefined;
56
+ }, [initialMessageId, collapsedMessages]);
57
+
39
58
  const renderRow = (index: number, item: ResolvedMessage): ReactNode => {
40
59
  const number =
41
60
  collapsedMessages.length > 1 && numbered ? index + 1 : undefined;
@@ -47,11 +66,30 @@ export const ChatViewVirtualList: FC<ChatViewVirtualListProps> = memo(
47
66
  resolvedMessage={item}
48
67
  indented={indented}
49
68
  toolCallStyle={toolCallStyle}
50
- padded={index < collapsedMessages.length - 1}
69
+ getMessageUrl={getMessageUrl}
70
+ highlightUserMessage={true}
51
71
  />
52
72
  );
53
73
  };
54
74
 
75
+ const Item = ({
76
+ children,
77
+ ...props
78
+ }: ItemProps<any> & ContextProp<any>) => {
79
+ return (
80
+ <div
81
+ className={clsx(styles.item)}
82
+ data-index={props["data-index"]}
83
+ data-item-group-index={props["data-item-group-index"]}
84
+ data-item-index={props["data-item-index"]}
85
+ data-known-size={props["data-known-size"]}
86
+ style={props.style}
87
+ >
88
+ {children}
89
+ </div>
90
+ );
91
+ };
92
+
55
93
  return (
56
94
  <LiveVirtualList<ResolvedMessage>
57
95
  id="chat-virtual-list"
@@ -59,8 +97,10 @@ export const ChatViewVirtualList: FC<ChatViewVirtualListProps> = memo(
59
97
  scrollRef={scrollRef}
60
98
  data={collapsedMessages}
61
99
  renderRow={renderRow}
100
+ initialTopMostItemIndex={initialMessageIndex}
62
101
  live={running}
63
102
  showProgress={running}
103
+ components={{ Item }}
64
104
  />
65
105
  );
66
106
  },
@@ -23,6 +23,7 @@ export const resolveMessages = (messages: Messages) => {
23
23
  // can use to lookup the tool responses
24
24
 
25
25
  const resolvedMessages: ResolvedMessage[] = [];
26
+ let index = 0;
26
27
  for (const message of messages) {
27
28
  if (message.role === "tool") {
28
29
  // Add this tool message onto the previous message
@@ -35,6 +36,12 @@ export const resolveMessages = (messages: Messages) => {
35
36
  } else {
36
37
  resolvedMessages.push({ message, toolMessages: [] });
37
38
  }
39
+
40
+ // Create a stable id for the item, if it doesn't have one
41
+ if (message.id === undefined) {
42
+ message.id = `msg-${index}`;
43
+ }
44
+ index++;
38
45
  }
39
46
 
40
47
  // Capture system messages (there could be multiple)
@@ -1,6 +1,3 @@
1
- .output {
2
- }
3
-
4
1
  .toolCallView {
5
2
  display: grid;
6
3
  row-gap: 1em;
@@ -125,7 +125,7 @@ export const ToolCallView: FC<ToolCallViewProps> = ({
125
125
  collapse={collapse}
126
126
  border={true}
127
127
  lines={15}
128
- className={styles.output}
128
+ className={clsx("text-size-small")}
129
129
  >
130
130
  <MessageContent contents={normalizedContent} />
131
131
  </ExpandablePanel>
@@ -8,7 +8,7 @@
8
8
  margin-top: 0.25em;
9
9
  }
10
10
 
11
- .toolView pre[class*="language-"] {
11
+ .toolView {
12
12
  padding: 0.5em !important;
13
13
  }
14
14
 
@@ -12,7 +12,7 @@
12
12
  padding: 0.5em 0.5em 0.5em 0.5em;
13
13
  white-space: pre-wrap;
14
14
  margin-bottom: 0;
15
- font-size: 1em !important;
15
+ font-size: 0.8rem !important;
16
16
  }
17
17
 
18
18
  .textCode {
@@ -14,10 +14,14 @@ export const numericScoreDescriptor = (values: Value2[]): ScoreDescriptor => {
14
14
  min: Math.min(...onlyNumeric),
15
15
  max: Math.max(...onlyNumeric),
16
16
  compare: (a, b) => {
17
+ // Non numerics could happen if some scores are errors
17
18
  if (typeof a.value === "number" && typeof b.value === "number") {
18
19
  return compareWithNan(a.value, b.value);
20
+ } else if (typeof a.value === "number" && typeof b.value !== "number") {
21
+ return -1;
22
+ } else if (typeof a.value !== "number" && typeof b.value === "number") {
23
+ return 1;
19
24
  } else {
20
- console.warn("Comparing non-numerics using a numeric score descriptor");
21
25
  return 0;
22
26
  }
23
27
  },
@@ -69,13 +69,18 @@ export const passFailScoreDescriptor = (values: Value2[]): ScoreDescriptor => {
69
69
  }
70
70
  },
71
71
  compare: (a: SelectedScore, b: SelectedScore) => {
72
- if (typeof a.value !== "string" || typeof b.value !== "string") {
73
- throw new Error(
74
- "Unexpectedly using the pass fail scorer on non-string values",
75
- );
72
+ if (typeof a.value !== "string" && typeof b.value !== "string") {
73
+ return 0;
74
+ } else if (typeof a.value === "string" && typeof b.value !== "string") {
75
+ return -1;
76
+ } else if (typeof a.value !== "string" && typeof b.value === "string") {
77
+ return 1;
78
+ } else {
79
+ const sort =
80
+ order.indexOf(String(a.value || "")) -
81
+ order.indexOf(String(b.value || ""));
82
+ return sort;
76
83
  }
77
- const sort = order.indexOf(a.value || "") - order.indexOf(b.value || "");
78
- return sort;
79
84
  },
80
85
  };
81
86
  };
@@ -145,6 +145,13 @@ export const SampleList: FC<SampleListProps> = memo((props) => {
145
145
  completed={item.completed}
146
146
  scoreRendered={item.scoreRendered}
147
147
  gridColumnsTemplate={gridColumnsTemplate}
148
+ sampleUrl={sampleNavigation.getSampleUrl(
149
+ item.data.id,
150
+ item.data.epoch,
151
+ )}
152
+ showSample={() => {
153
+ sampleNavigation.showSample(item.index);
154
+ }}
148
155
  />
149
156
  );
150
157
  } else if (item.type === "separator") {
@@ -5,7 +5,6 @@ import { MarkdownDiv } from "../../../components/MarkdownDiv";
5
5
  import { PulsingDots } from "../../../components/PulsingDots";
6
6
  import { useStore } from "../../../state/store";
7
7
  import { arrayToString, inputString } from "../../../utils/format";
8
- import { useSampleNavigation } from "../../routing/navigationHooks";
9
8
  import { SampleErrorView } from "../error/SampleErrorView";
10
9
  import styles from "./SampleRow.module.css";
11
10
 
@@ -18,6 +17,8 @@ interface SampleRowProps {
18
17
  scoreRendered: ReactNode;
19
18
  gridColumnsTemplate: string;
20
19
  height: number;
20
+ showSample: () => void;
21
+ sampleUrl?: string;
21
22
  }
22
23
 
23
24
  export const SampleRow: FC<SampleRowProps> = ({
@@ -29,6 +30,8 @@ export const SampleRow: FC<SampleRowProps> = ({
29
30
  scoreRendered,
30
31
  gridColumnsTemplate,
31
32
  height,
33
+ showSample,
34
+ sampleUrl,
32
35
  }) => {
33
36
  const streamSampleData = useStore(
34
37
  (state) => state.capabilities.streamSampleData,
@@ -39,14 +42,6 @@ export const SampleRow: FC<SampleRowProps> = ({
39
42
  // Determine if this sample can be viewed (completed or streaming)
40
43
  const isViewable = completed || streamSampleData;
41
44
 
42
- // Get sample navigation utilities
43
- const sampleNavigation = useSampleNavigation();
44
-
45
- // Use sample navigation hook to get sample URL
46
- const sampleUrl = isViewable
47
- ? sampleNavigation.getSampleUrl(sample.id, sample.epoch)
48
- : undefined;
49
-
50
45
  const rowContent = (
51
46
  <div
52
47
  id={`sample-${id}`}
@@ -127,13 +122,5 @@ export const SampleRow: FC<SampleRowProps> = ({
127
122
  );
128
123
 
129
124
  // Render the row content either as a link or directly
130
- return (
131
- <div
132
- onClick={
133
- isViewable ? () => sampleNavigation.showSample(index) : undefined
134
- }
135
- >
136
- {rowContent}
137
- </div>
138
- );
125
+ return <div onClick={showSample}>{rowContent}</div>;
139
126
  };
@@ -1,5 +1,6 @@
1
1
  import clsx from "clsx";
2
2
  import { ChangeEvent, FC, useCallback } from "react";
3
+ import { ScoreLabel } from "../../../app/types";
3
4
  import { SampleSummary } from "../../../client/api/types";
4
5
  import {
5
6
  kEpochAscVal,
@@ -9,7 +10,6 @@ import {
9
10
  kScoreAscVal,
10
11
  kScoreDescVal,
11
12
  } from "../../../constants";
12
- import { ScoreLabel } from "../../../app/types";
13
13
  import { isNumeric } from "../../../utils/type";
14
14
  import { SamplesDescriptor } from "../descriptor/samplesDescriptor";
15
15
  import styles from "./SortFilter.module.css";
@@ -1,22 +1,24 @@
1
1
  import clsx from "clsx";
2
- import { FC, Fragment } from "react";
2
+ import { FC, Fragment, RefObject } from "react";
3
3
  import { EvalSample } from "../../../@types/log";
4
4
  import { SampleSummary } from "../../../client/api/types";
5
5
  import { EmptyPanel } from "../../../components/EmptyPanel";
6
- import { MarkdownDiv } from "../../../components/MarkdownDiv";
7
6
  import { useEvalDescriptor } from "../../../state/hooks";
8
- import { MetaDataGrid } from "../../content/MetaDataGrid";
7
+ import { RecordTree } from "../../content/RecordTree";
8
+ import { RenderedContent } from "../../content/RenderedContent";
9
9
  import { SampleScores } from "./SampleScores";
10
10
  import styles from "./SampleScoresGrid.module.css";
11
11
 
12
12
  interface SampleScoresGridProps {
13
13
  evalSample: EvalSample;
14
14
  className?: string | string[];
15
+ scrollRef: RefObject<HTMLDivElement | null>;
15
16
  }
16
17
 
17
18
  export const SampleScoresGrid: FC<SampleScoresGridProps> = ({
18
19
  evalSample,
19
20
  className,
21
+ scrollRef,
20
22
  }) => {
21
23
  const evalDescriptor = useEvalDescriptor();
22
24
  if (!evalDescriptor) {
@@ -84,7 +86,13 @@ export const SampleScoresGrid: FC<SampleScoresGridProps> = ({
84
86
  />
85
87
  </div>
86
88
  <div className={clsx("text-size-base", styles.cell)}>
87
- <MarkdownDiv markdown={explanation} />
89
+ <RenderedContent
90
+ id={`${scorer}-explanation`}
91
+ entry={{
92
+ name: "Explanation",
93
+ value: explanation,
94
+ }}
95
+ />
88
96
  </div>
89
97
 
90
98
  {Object.keys(metadata).length > 0 ? (
@@ -100,7 +108,12 @@ export const SampleScoresGrid: FC<SampleScoresGridProps> = ({
100
108
  Metadata
101
109
  </div>
102
110
  <div className={clsx(styles.fullWidth)}>
103
- <MetaDataGrid entries={metadata} />
111
+ <RecordTree
112
+ id={`${scorer}-metadataa`}
113
+ scrollRef={scrollRef}
114
+ record={metadata}
115
+ defaultExpandLevel={0}
116
+ />
104
117
  </div>
105
118
  <div
106
119
  className={clsx(
@@ -1,9 +1,3 @@
1
- .container {
2
- margin-top: 0.5em;
3
- padding-left: 0;
4
- padding-right: 0;
5
- }
6
-
7
1
  .label {
8
2
  padding-right: 2em !important;
9
3
  padding-left: 0 !important;
@@ -4,7 +4,7 @@ import { Card, CardBody } from "../../../components/Card";
4
4
  import { MarkdownDiv } from "../../../components/MarkdownDiv";
5
5
  import { inputString } from "../../../utils/format";
6
6
 
7
- import { FC } from "react";
7
+ import { FC, RefObject } from "react";
8
8
  import ExpandablePanel from "../../../components/ExpandablePanel";
9
9
  import { useEvalDescriptor } from "../../../state/hooks";
10
10
  import { SampleScoresGrid } from "./SampleScoresGrid";
@@ -13,11 +13,13 @@ import styles from "./SampleScoresView.module.css";
13
13
  interface SampleScoresViewProps {
14
14
  sample?: EvalSample;
15
15
  className?: string | string[];
16
+ scrollRef: RefObject<HTMLDivElement | null>;
16
17
  }
17
18
 
18
19
  export const SampleScoresView: FC<SampleScoresViewProps> = ({
19
20
  sample,
20
21
  className,
22
+ scrollRef,
21
23
  }) => {
22
24
  const evalDescriptor = useEvalDescriptor();
23
25
  if (!evalDescriptor) {
@@ -70,6 +72,7 @@ export const SampleScoresView: FC<SampleScoresViewProps> = ({
70
72
  <SampleScoresGrid
71
73
  evalSample={sample}
72
74
  className={clsx(styles.scores)}
75
+ scrollRef={scrollRef}
73
76
  />
74
77
  </CardBody>
75
78
  </Card>
@@ -2,9 +2,10 @@ import { FC } from "react";
2
2
  import { ApprovalEvent } from "../../../@types/log";
3
3
  import { ApplicationIcons } from "../../appearance/icons";
4
4
  import { EventRow } from "./event/EventRow";
5
+ import { EventNode } from "./types";
5
6
 
6
7
  interface ApprovalEventViewProps {
7
- event: ApprovalEvent;
8
+ eventNode: EventNode<ApprovalEvent>;
8
9
  className?: string | string[];
9
10
  }
10
11
 
@@ -12,9 +13,10 @@ interface ApprovalEventViewProps {
12
13
  * Renders the ApprovalEventView component.
13
14
  */
14
15
  export const ApprovalEventView: FC<ApprovalEventViewProps> = ({
15
- event,
16
+ eventNode,
16
17
  className,
17
18
  }) => {
19
+ const event = eventNode.event;
18
20
  return (
19
21
  <EventRow
20
22
  title={decisionLabel(event.decision)}
@@ -4,10 +4,10 @@ import { ANSIDisplay } from "../../../components/AnsiDisplay";
4
4
  import { formatDateTime } from "../../../utils/format";
5
5
  import { ApplicationIcons } from "../../appearance/icons";
6
6
  import { EventPanel } from "./event/EventPanel";
7
+ import { EventNode } from "./types";
7
8
 
8
9
  interface ErrorEventViewProps {
9
- id: string;
10
- event: ErrorEvent;
10
+ eventNode: EventNode<ErrorEvent>;
11
11
  className?: string | string[];
12
12
  }
13
13
 
@@ -15,13 +15,15 @@ interface ErrorEventViewProps {
15
15
  * Renders the ErrorEventView component.
16
16
  */
17
17
  export const ErrorEventView: FC<ErrorEventViewProps> = ({
18
- id,
19
- event,
18
+ eventNode,
20
19
  className,
21
20
  }) => {
21
+ const event = eventNode.event;
22
+ const id = eventNode.id;
22
23
  return (
23
24
  <EventPanel
24
25
  id={id}
26
+ depth={eventNode.depth}
25
27
  title="Error"
26
28
  className={className}
27
29
  subTitle={formatDateTime(new Date(event.timestamp))}
@@ -1,3 +1,3 @@
1
1
  .panel {
2
- margin: 0.5em 0;
2
+ margin: 0.2em 0;
3
3
  }
@@ -1,3 +1,4 @@
1
+ import clsx from "clsx";
1
2
  import { FC } from "react";
2
3
  import { InfoEvent } from "../../../@types/log";
3
4
  import { JSONPanel } from "../../../components/JsonPanel";
@@ -6,10 +7,10 @@ import { formatDateTime } from "../../../utils/format";
6
7
  import { ApplicationIcons } from "../../appearance/icons";
7
8
  import { EventPanel } from "./event/EventPanel";
8
9
  import styles from "./InfoEventView.module.css";
10
+ import { EventNode } from "./types";
9
11
 
10
12
  interface InfoEventViewProps {
11
- id: string;
12
- event: InfoEvent;
13
+ eventNode: EventNode<InfoEvent>;
13
14
  className?: string | string[];
14
15
  }
15
16
 
@@ -17,20 +18,26 @@ interface InfoEventViewProps {
17
18
  * Renders the InfoEventView component.
18
19
  */
19
20
  export const InfoEventView: FC<InfoEventViewProps> = ({
20
- id,
21
- event,
21
+ eventNode,
22
22
  className,
23
23
  }) => {
24
+ const event = eventNode.event;
24
25
  const panels = [];
25
26
  if (typeof event.data === "string") {
26
- panels.push(<MarkdownDiv markdown={event.data} className={styles.panel} />);
27
+ panels.push(
28
+ <MarkdownDiv
29
+ markdown={event.data}
30
+ className={clsx(styles.panel, "text-size-base")}
31
+ />,
32
+ );
27
33
  } else {
28
34
  panels.push(<JSONPanel data={event.data} className={styles.panel} />);
29
35
  }
30
36
 
31
37
  return (
32
38
  <EventPanel
33
- id={id}
39
+ id={eventNode.id}
40
+ depth={eventNode.depth}
34
41
  title={"Info" + (event.source ? ": " + event.source : "")}
35
42
  className={className}
36
43
  subTitle={formatDateTime(new Date(event.timestamp))}
@@ -4,10 +4,10 @@ import { ANSIDisplay } from "../../../components/AnsiDisplay";
4
4
  import { formatDateTime } from "../../../utils/format";
5
5
  import { ApplicationIcons } from "../../appearance/icons";
6
6
  import { EventPanel } from "./event/EventPanel";
7
+ import { EventNode } from "./types";
7
8
 
8
9
  interface InputEventViewProps {
9
- id: string;
10
- event: InputEvent;
10
+ eventNode: EventNode<InputEvent>;
11
11
  className?: string | string[];
12
12
  }
13
13
 
@@ -15,13 +15,15 @@ interface InputEventViewProps {
15
15
  * Renders the ErrorEventView component.
16
16
  */
17
17
  export const InputEventView: FC<InputEventViewProps> = ({
18
- id,
19
- event,
18
+ eventNode,
20
19
  className,
21
20
  }) => {
21
+ const event = eventNode.event;
22
+ const id = eventNode.id;
22
23
  return (
23
24
  <EventPanel
24
25
  id={id}
26
+ depth={eventNode.depth}
25
27
  title="Input"
26
28
  className={className}
27
29
  subTitle={formatDateTime(new Date(event.timestamp))}
@@ -7,9 +7,10 @@ import { FC } from "react";
7
7
  import { parsedJson as maybeParseJson } from "../../../utils/json";
8
8
  import { MetaDataGrid } from "../../content/MetaDataGrid";
9
9
  import styles from "./LoggerEventView.module.css";
10
+ import { EventNode } from "./types";
10
11
 
11
12
  interface LoggerEventViewProps {
12
- event: LoggerEvent;
13
+ eventNode: EventNode<LoggerEvent>;
13
14
  className?: string | string[];
14
15
  }
15
16
 
@@ -17,9 +18,10 @@ interface LoggerEventViewProps {
17
18
  * Renders the LoggerEventView component.
18
19
  */
19
20
  export const LoggerEventView: FC<LoggerEventViewProps> = ({
20
- event,
21
+ eventNode,
21
22
  className,
22
23
  }) => {
24
+ const event = eventNode.event;
23
25
  const obj = maybeParseJson(event.message.message);
24
26
  return (
25
27
  <EventRow