inspect-ai 0.3.99__py3-none-any.whl → 0.3.101__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 (138) hide show
  1. inspect_ai/_cli/eval.py +2 -1
  2. inspect_ai/_display/core/config.py +11 -5
  3. inspect_ai/_display/core/panel.py +66 -2
  4. inspect_ai/_display/core/textual.py +5 -2
  5. inspect_ai/_display/plain/display.py +1 -0
  6. inspect_ai/_display/rich/display.py +2 -2
  7. inspect_ai/_display/textual/widgets/transcript.py +37 -9
  8. inspect_ai/_eval/eval.py +13 -1
  9. inspect_ai/_eval/evalset.py +3 -2
  10. inspect_ai/_eval/run.py +2 -0
  11. inspect_ai/_eval/score.py +2 -4
  12. inspect_ai/_eval/task/log.py +3 -1
  13. inspect_ai/_eval/task/run.py +59 -81
  14. inspect_ai/_util/content.py +11 -6
  15. inspect_ai/_util/interrupt.py +2 -2
  16. inspect_ai/_util/text.py +7 -0
  17. inspect_ai/_util/working.py +8 -37
  18. inspect_ai/_view/__init__.py +0 -0
  19. inspect_ai/_view/schema.py +2 -1
  20. inspect_ai/_view/www/CLAUDE.md +15 -0
  21. inspect_ai/_view/www/dist/assets/index.css +307 -171
  22. inspect_ai/_view/www/dist/assets/index.js +24733 -21641
  23. inspect_ai/_view/www/log-schema.json +77 -3
  24. inspect_ai/_view/www/package.json +9 -5
  25. inspect_ai/_view/www/src/@types/log.d.ts +9 -0
  26. inspect_ai/_view/www/src/app/App.tsx +1 -15
  27. inspect_ai/_view/www/src/app/appearance/icons.ts +4 -1
  28. inspect_ai/_view/www/src/app/content/MetaDataGrid.tsx +24 -6
  29. inspect_ai/_view/www/src/app/content/MetadataGrid.module.css +0 -5
  30. inspect_ai/_view/www/src/app/content/RenderedContent.tsx +220 -205
  31. inspect_ai/_view/www/src/app/log-view/LogViewContainer.tsx +2 -1
  32. inspect_ai/_view/www/src/app/log-view/tabs/SamplesTab.tsx +5 -0
  33. inspect_ai/_view/www/src/app/log-view/tabs/grouping.ts +4 -4
  34. inspect_ai/_view/www/src/app/routing/navigationHooks.ts +22 -25
  35. inspect_ai/_view/www/src/app/routing/url.ts +84 -4
  36. inspect_ai/_view/www/src/app/samples/InlineSampleDisplay.module.css +0 -5
  37. inspect_ai/_view/www/src/app/samples/SampleDialog.module.css +1 -1
  38. inspect_ai/_view/www/src/app/samples/SampleDisplay.module.css +7 -0
  39. inspect_ai/_view/www/src/app/samples/SampleDisplay.tsx +24 -17
  40. inspect_ai/_view/www/src/app/samples/SampleSummaryView.module.css +1 -2
  41. inspect_ai/_view/www/src/app/samples/chat/ChatMessage.tsx +8 -6
  42. inspect_ai/_view/www/src/app/samples/chat/ChatMessageRow.tsx +0 -4
  43. inspect_ai/_view/www/src/app/samples/chat/ChatViewVirtualList.tsx +3 -2
  44. inspect_ai/_view/www/src/app/samples/chat/MessageContent.tsx +2 -0
  45. inspect_ai/_view/www/src/app/samples/chat/MessageContents.tsx +2 -0
  46. inspect_ai/_view/www/src/app/samples/chat/messages.ts +1 -0
  47. inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.tsx +1 -0
  48. inspect_ai/_view/www/src/app/samples/list/SampleList.tsx +17 -5
  49. inspect_ai/_view/www/src/app/samples/list/SampleRow.tsx +1 -1
  50. inspect_ai/_view/www/src/app/samples/transcript/ErrorEventView.tsx +1 -2
  51. inspect_ai/_view/www/src/app/samples/transcript/InfoEventView.tsx +1 -1
  52. inspect_ai/_view/www/src/app/samples/transcript/InputEventView.tsx +1 -2
  53. inspect_ai/_view/www/src/app/samples/transcript/ModelEventView.module.css +1 -1
  54. inspect_ai/_view/www/src/app/samples/transcript/ModelEventView.tsx +1 -1
  55. inspect_ai/_view/www/src/app/samples/transcript/SampleInitEventView.tsx +1 -1
  56. inspect_ai/_view/www/src/app/samples/transcript/SampleLimitEventView.tsx +3 -2
  57. inspect_ai/_view/www/src/app/samples/transcript/SandboxEventView.tsx +4 -5
  58. inspect_ai/_view/www/src/app/samples/transcript/ScoreEventView.tsx +1 -1
  59. inspect_ai/_view/www/src/app/samples/transcript/SpanEventView.tsx +1 -2
  60. inspect_ai/_view/www/src/app/samples/transcript/StepEventView.tsx +1 -3
  61. inspect_ai/_view/www/src/app/samples/transcript/SubtaskEventView.tsx +1 -2
  62. inspect_ai/_view/www/src/app/samples/transcript/ToolEventView.tsx +3 -4
  63. inspect_ai/_view/www/src/app/samples/transcript/TranscriptPanel.module.css +42 -0
  64. inspect_ai/_view/www/src/app/samples/transcript/TranscriptPanel.tsx +77 -0
  65. inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualList.tsx +27 -71
  66. inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.module.css +13 -3
  67. inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.tsx +27 -2
  68. inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.module.css +1 -0
  69. inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.tsx +21 -22
  70. inspect_ai/_view/www/src/app/samples/transcript/outline/OutlineRow.module.css +45 -0
  71. inspect_ai/_view/www/src/app/samples/transcript/outline/OutlineRow.tsx +223 -0
  72. inspect_ai/_view/www/src/app/samples/transcript/outline/TranscriptOutline.module.css +10 -0
  73. inspect_ai/_view/www/src/app/samples/transcript/outline/TranscriptOutline.tsx +258 -0
  74. inspect_ai/_view/www/src/app/samples/transcript/outline/tree-visitors.ts +187 -0
  75. inspect_ai/_view/www/src/app/samples/transcript/state/StateEventRenderers.tsx +8 -1
  76. inspect_ai/_view/www/src/app/samples/transcript/state/StateEventView.tsx +3 -4
  77. inspect_ai/_view/www/src/app/samples/transcript/transform/hooks.ts +78 -0
  78. inspect_ai/_view/www/src/app/samples/transcript/transform/treeify.ts +340 -135
  79. inspect_ai/_view/www/src/app/samples/transcript/transform/utils.ts +3 -0
  80. inspect_ai/_view/www/src/app/samples/transcript/types.ts +2 -0
  81. inspect_ai/_view/www/src/app/types.ts +5 -1
  82. inspect_ai/_view/www/src/client/api/api-browser.ts +2 -2
  83. inspect_ai/_view/www/src/components/LiveVirtualList.tsx +6 -1
  84. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +1 -1
  85. inspect_ai/_view/www/src/components/PopOver.tsx +422 -0
  86. inspect_ai/_view/www/src/components/PulsingDots.module.css +9 -9
  87. inspect_ai/_view/www/src/components/PulsingDots.tsx +4 -1
  88. inspect_ai/_view/www/src/components/StickyScroll.tsx +183 -0
  89. inspect_ai/_view/www/src/components/TabSet.tsx +4 -0
  90. inspect_ai/_view/www/src/state/hooks.ts +52 -2
  91. inspect_ai/_view/www/src/state/logSlice.ts +4 -3
  92. inspect_ai/_view/www/src/state/samplePolling.ts +8 -0
  93. inspect_ai/_view/www/src/state/sampleSlice.ts +53 -9
  94. inspect_ai/_view/www/src/state/scrolling.ts +152 -0
  95. inspect_ai/_view/www/src/utils/attachments.ts +7 -0
  96. inspect_ai/_view/www/src/utils/python.ts +18 -0
  97. inspect_ai/_view/www/yarn.lock +290 -33
  98. inspect_ai/agent/_react.py +12 -7
  99. inspect_ai/agent/_run.py +2 -3
  100. inspect_ai/analysis/beta/__init__.py +2 -0
  101. inspect_ai/analysis/beta/_dataframe/samples/table.py +19 -18
  102. inspect_ai/dataset/_sources/csv.py +2 -6
  103. inspect_ai/dataset/_sources/hf.py +2 -6
  104. inspect_ai/dataset/_sources/json.py +2 -6
  105. inspect_ai/dataset/_util.py +23 -0
  106. inspect_ai/log/_log.py +1 -1
  107. inspect_ai/log/_recorders/eval.py +4 -3
  108. inspect_ai/log/_recorders/file.py +2 -9
  109. inspect_ai/log/_recorders/json.py +1 -0
  110. inspect_ai/log/_recorders/recorder.py +1 -0
  111. inspect_ai/log/_transcript.py +1 -1
  112. inspect_ai/model/_call_tools.py +6 -2
  113. inspect_ai/model/_openai.py +1 -1
  114. inspect_ai/model/_openai_responses.py +85 -41
  115. inspect_ai/model/_openai_web_search.py +38 -0
  116. inspect_ai/model/_providers/azureai.py +72 -3
  117. inspect_ai/model/_providers/openai.py +4 -1
  118. inspect_ai/model/_providers/openai_responses.py +5 -1
  119. inspect_ai/scorer/_metric.py +1 -2
  120. inspect_ai/scorer/_reducer/reducer.py +1 -1
  121. inspect_ai/solver/_task_state.py +2 -2
  122. inspect_ai/tool/_tool.py +6 -2
  123. inspect_ai/tool/_tool_def.py +27 -4
  124. inspect_ai/tool/_tool_info.py +2 -0
  125. inspect_ai/tool/_tools/_web_search/_google.py +43 -15
  126. inspect_ai/tool/_tools/_web_search/_tavily.py +46 -13
  127. inspect_ai/tool/_tools/_web_search/_web_search.py +214 -45
  128. inspect_ai/util/__init__.py +4 -0
  129. inspect_ai/util/_json.py +3 -0
  130. inspect_ai/util/_limit.py +230 -20
  131. inspect_ai/util/_sandbox/docker/compose.py +20 -11
  132. inspect_ai/util/_span.py +1 -1
  133. {inspect_ai-0.3.99.dist-info → inspect_ai-0.3.101.dist-info}/METADATA +3 -3
  134. {inspect_ai-0.3.99.dist-info → inspect_ai-0.3.101.dist-info}/RECORD +138 -124
  135. {inspect_ai-0.3.99.dist-info → inspect_ai-0.3.101.dist-info}/WHEEL +1 -1
  136. {inspect_ai-0.3.99.dist-info → inspect_ai-0.3.101.dist-info}/entry_points.txt +0 -0
  137. {inspect_ai-0.3.99.dist-info → inspect_ai-0.3.101.dist-info}/licenses/LICENSE +0 -0
  138. {inspect_ai-0.3.99.dist-info → inspect_ai-0.3.101.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,7 @@
1
+ import { useMemo } from "react";
2
+ import { useParams } from "react-router-dom";
1
3
  import { kSampleMessagesTabId, kSampleTranscriptTabId } from "../../constants";
4
+ import { useStore } from "../../state/store";
2
5
  import { directoryRelativeUrl } from "../../utils/uri";
3
6
 
4
7
  export const kLogRouteUrlPattern = "/logs/:logPath/:tabId?/:sampleTabId?";
@@ -46,6 +49,80 @@ export const sampleEventUrl = (
46
49
  return `${baseUrl}?event=${eventId}`;
47
50
  };
48
51
 
52
+ export const useSampleMessageUrl = (
53
+ messageId: string | null,
54
+ sampleId?: string | number,
55
+ sampleEpoch?: string | number,
56
+ ) => {
57
+ const {
58
+ logPath: urlLogPath,
59
+ sampleId: urlSampleId,
60
+ epoch: urlEpoch,
61
+ } = useParams<{
62
+ logPath?: string;
63
+ tabId?: string;
64
+ sampleId?: string;
65
+ epoch?: string;
66
+ }>();
67
+
68
+ const log_file = useStore((state) => state.logs.selectedLogFile);
69
+ const log_dir = useStore((state) => state.logs.logs.log_dir);
70
+
71
+ let targetLogPath = urlLogPath;
72
+ if (!targetLogPath && log_file) {
73
+ targetLogPath = makeLogPath(log_file, log_dir);
74
+ }
75
+
76
+ const eventUrl = useMemo(() => {
77
+ return messageId && targetLogPath
78
+ ? sampleMessageUrl(
79
+ messageId,
80
+ targetLogPath,
81
+ sampleId || urlSampleId,
82
+ sampleEpoch || urlEpoch,
83
+ )
84
+ : undefined;
85
+ }, [targetLogPath, messageId, sampleId, urlSampleId, sampleEpoch, urlEpoch]);
86
+ return eventUrl;
87
+ };
88
+
89
+ export const useSampleEventUrl = (
90
+ eventId: string,
91
+ sampleId?: string | number,
92
+ sampleEpoch?: string | number,
93
+ ) => {
94
+ const {
95
+ logPath: urlLogPath,
96
+ sampleId: urlSampleId,
97
+ epoch: urlEpoch,
98
+ } = useParams<{
99
+ logPath?: string;
100
+ tabId?: string;
101
+ sampleId?: string;
102
+ epoch?: string;
103
+ }>();
104
+
105
+ const log_file = useStore((state) => state.logs.selectedLogFile);
106
+ const log_dir = useStore((state) => state.logs.logs.log_dir);
107
+
108
+ let targetLogPath = urlLogPath;
109
+ if (!targetLogPath && log_file) {
110
+ targetLogPath = makeLogPath(log_file, log_dir);
111
+ }
112
+
113
+ const eventUrl = useMemo(() => {
114
+ return targetLogPath
115
+ ? sampleEventUrl(
116
+ eventId,
117
+ targetLogPath,
118
+ sampleId || urlSampleId,
119
+ sampleEpoch || urlEpoch,
120
+ )
121
+ : undefined;
122
+ }, [targetLogPath, eventId, sampleId, urlSampleId, sampleEpoch, urlEpoch]);
123
+ return eventUrl;
124
+ };
125
+
49
126
  export const sampleMessageUrl = (
50
127
  messageId: string,
51
128
  logPath: string,
@@ -63,8 +140,12 @@ export const sampleMessageUrl = (
63
140
  };
64
141
 
65
142
  export const logUrl = (log_file: string, log_dir?: string, tabId?: string) => {
143
+ return logUrlRaw(makeLogPath(log_file, log_dir), tabId);
144
+ };
145
+
146
+ export const makeLogPath = (log_file: string, log_dir?: string) => {
66
147
  const pathSegment = directoryRelativeUrl(log_file, log_dir);
67
- return logUrlRaw(pathSegment, tabId);
148
+ return pathSegment;
68
149
  };
69
150
 
70
151
  export const logUrlRaw = (log_segment: string, tabId?: string) => {
@@ -77,9 +158,8 @@ export const logUrlRaw = (log_segment: string, tabId?: string) => {
77
158
 
78
159
  export const supportsLinking = () => {
79
160
  return (
80
- location.hostname !== "localhost" &&
81
- location.hostname !== "127.0.0.1" &&
82
- location.protocol !== "vscode-webview:"
161
+ //location.hostname !== "localhost" &&
162
+ location.hostname !== "127.0.0.1" && location.protocol !== "vscode-webview:"
83
163
  );
84
164
  };
85
165
 
@@ -4,11 +4,6 @@
4
4
  flex-direction: column;
5
5
  }
6
6
 
7
- .body {
8
- margin-top: 1em;
9
- margin-bottom: 1em;
10
- }
11
-
12
7
  .scroller {
13
8
  overflow-y: auto;
14
9
  width: 100%;
@@ -1,3 +1,3 @@
1
1
  .modalBody {
2
- padding: 1em 0;
2
+ padding: 0 0;
3
3
  }
@@ -2,6 +2,13 @@
2
2
  padding-bottom: 1em;
3
3
  }
4
4
 
5
+ .tabControls {
6
+ position: sticky;
7
+ z-index: 1001;
8
+ top: 0;
9
+ background-color: var(--bs-body-bg);
10
+ }
11
+
5
12
  .fullWidth {
6
13
  width: 100%;
7
14
  }
@@ -15,6 +15,7 @@ import {
15
15
  RefObject,
16
16
  useCallback,
17
17
  useMemo,
18
+ useRef,
18
19
  } from "react";
19
20
  import { useNavigate, useParams } from "react-router-dom";
20
21
  import { EvalSample, Events } from "../../@types/log";
@@ -37,19 +38,14 @@ import { estimateSize } from "../../utils/json";
37
38
  import { printHeadingHtml, printHtml } from "../../utils/print";
38
39
  import { RecordTree } from "../content/RecordTree";
39
40
  import { useSampleDetailNavigation } from "../routing/navigationHooks";
40
- import {
41
- sampleMessageUrl,
42
- sampleUrl,
43
- supportsLinking,
44
- toFullUrl,
45
- } from "../routing/url";
41
+ import { sampleUrl } from "../routing/url";
46
42
  import { ModelTokenTable } from "../usage/ModelTokenTable";
47
43
  import { ChatViewVirtualList } from "./chat/ChatViewVirtualList";
48
44
  import { messagesFromEvents } from "./chat/messages";
49
45
  import styles from "./SampleDisplay.module.css";
50
46
  import { SampleSummaryView } from "./SampleSummaryView";
51
47
  import { SampleScoresView } from "./scores/SampleScoresView";
52
- import { TranscriptVirtualList } from "./transcript/TranscriptVirtualList";
48
+ import { TranscriptPanel } from "./transcript/TranscriptPanel";
53
49
 
54
50
  interface SampleDisplayProps {
55
51
  id: string;
@@ -87,7 +83,19 @@ export const SampleDisplay: FC<SampleDisplayProps> = ({ id, scrollRef }) => {
87
83
  // Navigation hook for URL updates
88
84
  const navigate = useNavigate();
89
85
 
90
- const sampleSummary = filteredSamples[selectedSampleIndex];
86
+ // Ref for samples tabs (used to meaure for offset)
87
+ const tabsRef: RefObject<HTMLUListElement | null> = useRef(null);
88
+ const tabsHeight = useMemo(() => {
89
+ if (tabsRef.current) {
90
+ const height = tabsRef.current.getBoundingClientRect().height;
91
+ return height;
92
+ }
93
+ return -1;
94
+ }, [tabsRef.current]);
95
+
96
+ const sampleSummary = useMemo(() => {
97
+ return filteredSamples[selectedSampleIndex];
98
+ }, [filteredSamples, selectedSampleIndex]);
91
99
 
92
100
  // Consolidate the events and messages into the proper list
93
101
  // whether running or not
@@ -115,12 +123,6 @@ export const SampleDisplay: FC<SampleDisplayProps> = ({ id, scrollRef }) => {
115
123
  epoch?: string;
116
124
  }>();
117
125
 
118
- const getMessageUrl = (id: string) => {
119
- return id && urlLogPath && supportsLinking()
120
- ? toFullUrl(sampleMessageUrl(id, urlLogPath, urlSampleId, urlEpoch))
121
- : undefined;
122
- };
123
-
124
126
  // Tab selection
125
127
  const onSelectedTab = useCallback(
126
128
  (e: MouseEvent<HTMLElement>) => {
@@ -171,7 +173,9 @@ export const SampleDisplay: FC<SampleDisplayProps> = ({ id, scrollRef }) => {
171
173
  }
172
174
 
173
175
  // Is the sample running?
174
- const running = isRunning(sampleSummary, runningSampleData);
176
+ const running = useMemo(() => {
177
+ return isRunning(sampleSummary, runningSampleData);
178
+ }, [sampleSummary, runningSampleData]);
175
179
 
176
180
  const sampleDetailNavigation = useSampleDetailNavigation();
177
181
 
@@ -182,6 +186,8 @@ export const SampleDisplay: FC<SampleDisplayProps> = ({ id, scrollRef }) => {
182
186
  ) : undefined}
183
187
  <TabSet
184
188
  id={tabsetId}
189
+ tabsRef={tabsRef}
190
+ className={clsx(styles.tabControls)}
185
191
  tabControlsClassName={clsx("text-size-base")}
186
192
  tabPanelsClassName={clsx(styles.tabPanel)}
187
193
  tools={tools}
@@ -198,11 +204,12 @@ export const SampleDisplay: FC<SampleDisplayProps> = ({ id, scrollRef }) => {
198
204
  }
199
205
  scrollable={false}
200
206
  >
201
- <TranscriptVirtualList
207
+ <TranscriptPanel
202
208
  key={`${baseId}-transcript-display-${id}`}
203
209
  id={`${baseId}-transcript-display-${id}`}
204
210
  events={sampleEvents || []}
205
211
  initialEventId={sampleDetailNavigation.event}
212
+ topOffset={tabsHeight}
206
213
  running={running}
207
214
  scrollRef={scrollRef}
208
215
  />
@@ -221,11 +228,11 @@ export const SampleDisplay: FC<SampleDisplayProps> = ({ id, scrollRef }) => {
221
228
  id={`${baseId}-chat-${id}`}
222
229
  messages={sampleMessages}
223
230
  initialMessageId={sampleDetailNavigation.message}
231
+ topOffset={tabsHeight}
224
232
  indented={true}
225
233
  scrollRef={scrollRef}
226
234
  toolCallStyle="complete"
227
235
  running={running}
228
- getMessageUrl={getMessageUrl}
229
236
  />
230
237
  </TabPanel>
231
238
  <TabPanel
@@ -10,8 +10,7 @@
10
10
  display: grid;
11
11
  grid-column-gap: 1em;
12
12
  border-bottom: solid var(--bs-border-color) 1px;
13
- margin-bottom: 1em;
14
- padding: 0em 1em 1em 1em;
13
+ padding: 1em 1em 1em 1em;
15
14
  }
16
15
 
17
16
  .centerLabel {
@@ -9,6 +9,11 @@ import {
9
9
  import { CopyButton } from "../../../components/CopyButton";
10
10
  import ExpandablePanel from "../../../components/ExpandablePanel";
11
11
  import { ApplicationIcons } from "../../appearance/icons";
12
+ import {
13
+ supportsLinking,
14
+ toFullUrl,
15
+ useSampleMessageUrl,
16
+ } from "../../routing/url";
12
17
  import styles from "./ChatMessage.module.css";
13
18
  import { MessageContents } from "./MessageContents";
14
19
  import { ChatViewToolCallStyle } from "./types";
@@ -19,7 +24,6 @@ interface ChatMessageProps {
19
24
  toolMessages: ChatMessageTool[];
20
25
  indented?: boolean;
21
26
  toolCallStyle: ChatViewToolCallStyle;
22
- getMessageUrl?: (id: string) => string | undefined;
23
27
  }
24
28
 
25
29
  export const ChatMessage: FC<ChatMessageProps> = ({
@@ -28,10 +32,8 @@ export const ChatMessage: FC<ChatMessageProps> = ({
28
32
  toolMessages,
29
33
  indented,
30
34
  toolCallStyle,
31
- getMessageUrl,
32
35
  }) => {
33
- const messageUrl =
34
- message.id && getMessageUrl ? getMessageUrl(message.id) : undefined;
36
+ const messageUrl = useSampleMessageUrl(message.id);
35
37
 
36
38
  const collapse = message.role === "system" || message.role === "user";
37
39
  return (
@@ -46,10 +48,10 @@ export const ChatMessage: FC<ChatMessageProps> = ({
46
48
  >
47
49
  <div className={clsx(styles.messageGrid, "text-style-label")}>
48
50
  {message.role}
49
- {messageUrl ? (
51
+ {supportsLinking() && messageUrl ? (
50
52
  <CopyButton
51
53
  icon={ApplicationIcons.link}
52
- value={messageUrl}
54
+ value={toFullUrl(messageUrl)}
53
55
  className={clsx(styles.copyLink)}
54
56
  />
55
57
  ) : (
@@ -13,7 +13,6 @@ interface ChatMessageRowProps {
13
13
  toolCallStyle: ChatViewToolCallStyle;
14
14
  indented?: boolean;
15
15
  padded?: boolean;
16
- getMessageUrl?: (id: string) => string | undefined;
17
16
  highlightUserMessage?: boolean;
18
17
  }
19
18
 
@@ -26,7 +25,6 @@ export const ChatMessageRow: FC<ChatMessageRowProps> = ({
26
25
  resolvedMessage,
27
26
  toolCallStyle,
28
27
  indented,
29
- getMessageUrl,
30
28
  highlightUserMessage,
31
29
  }) => {
32
30
  if (number) {
@@ -56,7 +54,6 @@ export const ChatMessageRow: FC<ChatMessageRowProps> = ({
56
54
  toolMessages={resolvedMessage.toolMessages}
57
55
  indented={indented}
58
56
  toolCallStyle={toolCallStyle}
59
- getMessageUrl={getMessageUrl}
60
57
  />
61
58
  </div>
62
59
 
@@ -82,7 +79,6 @@ export const ChatMessageRow: FC<ChatMessageRowProps> = ({
82
79
  toolMessages={resolvedMessage.toolMessages}
83
80
  indented={indented}
84
81
  toolCallStyle={toolCallStyle}
85
- getMessageUrl={getMessageUrl}
86
82
  />
87
83
  {resolvedMessage.message.role === "user" ? (
88
84
  <div style={{ height: "10px" }}></div>
@@ -16,6 +16,7 @@ interface ChatViewVirtualListProps {
16
16
  className?: string | string[];
17
17
  messages: Messages;
18
18
  initialMessageId?: string | null;
19
+ topOffset?: number;
19
20
  toolCallStyle: ChatViewToolCallStyle;
20
21
  indented: boolean;
21
22
  numbered?: boolean;
@@ -32,13 +33,13 @@ export const ChatViewVirtualList: FC<ChatViewVirtualListProps> = memo(
32
33
  id,
33
34
  messages,
34
35
  initialMessageId,
36
+ topOffset,
35
37
  className,
36
38
  toolCallStyle,
37
39
  indented,
38
40
  numbered = true,
39
41
  scrollRef,
40
42
  running,
41
- getMessageUrl,
42
43
  }) => {
43
44
  const collapsedMessages = useMemo(() => {
44
45
  return resolveMessages(messages);
@@ -66,7 +67,6 @@ export const ChatViewVirtualList: FC<ChatViewVirtualListProps> = memo(
66
67
  resolvedMessage={item}
67
68
  indented={indented}
68
69
  toolCallStyle={toolCallStyle}
69
- getMessageUrl={getMessageUrl}
70
70
  highlightUserMessage={true}
71
71
  />
72
72
  );
@@ -98,6 +98,7 @@ export const ChatViewVirtualList: FC<ChatViewVirtualListProps> = memo(
98
98
  data={collapsedMessages}
99
99
  renderRow={renderRow}
100
100
  initialTopMostItemIndex={initialMessageIndex}
101
+ offsetTop={topOffset}
101
102
  live={running}
102
103
  showProgress={running}
103
104
  components={{ Item }}
@@ -54,6 +54,7 @@ export const MessageContent: FC<MessageContentProps> = ({ contents }) => {
54
54
  type: "text",
55
55
  text: content,
56
56
  refusal: null,
57
+ internal: null,
57
58
  },
58
59
  index === contents.length - 1,
59
60
  );
@@ -78,6 +79,7 @@ export const MessageContent: FC<MessageContentProps> = ({ contents }) => {
78
79
  type: "text",
79
80
  text: contents,
80
81
  refusal: null,
82
+ internal: null,
81
83
  };
82
84
  return messageRenderers["text"].render(
83
85
  "text-message-content",
@@ -108,6 +108,7 @@ const resolveToolMessage = (toolMessage?: ChatMessageTool): ContentTool[] => {
108
108
  type: "text",
109
109
  text: content,
110
110
  refusal: null,
111
+ internal: null,
111
112
  },
112
113
  ],
113
114
  },
@@ -123,6 +124,7 @@ const resolveToolMessage = (toolMessage?: ChatMessageTool): ContentTool[] => {
123
124
  type: "text",
124
125
  text: con,
125
126
  refusal: null,
127
+ internal: null,
126
128
  },
127
129
  ],
128
130
  } as ContentTool;
@@ -129,6 +129,7 @@ const normalizeContent = (
129
129
  type: "text",
130
130
  text: content,
131
131
  refusal: null,
132
+ internal: null,
132
133
  };
133
134
  } else {
134
135
  return content;
@@ -175,6 +175,7 @@ const normalizeContent = (
175
175
  type: "text",
176
176
  text: String(output),
177
177
  refusal: null,
178
+ internal: null,
178
179
  },
179
180
  ],
180
181
  },
@@ -113,11 +113,19 @@ export const SampleList: FC<SampleListProps> = memo((props) => {
113
113
  e.preventDefault();
114
114
  e.stopPropagation();
115
115
  break;
116
- case "Enter":
117
- sampleNavigation.showSample(selectedSampleIndex);
118
- e.preventDefault();
119
- e.stopPropagation();
116
+ case "Enter": {
117
+ const item = items[selectedSampleIndex];
118
+ if (item.type === "sample") {
119
+ sampleNavigation.showSample(
120
+ item.index,
121
+ item.data.id,
122
+ item.data.epoch,
123
+ );
124
+ e.preventDefault();
125
+ e.stopPropagation();
126
+ }
120
127
  break;
128
+ }
121
129
  }
122
130
  },
123
131
  [
@@ -150,7 +158,11 @@ export const SampleList: FC<SampleListProps> = memo((props) => {
150
158
  item.data.epoch,
151
159
  )}
152
160
  showSample={() => {
153
- sampleNavigation.showSample(item.index);
161
+ sampleNavigation.showSample(
162
+ item.index,
163
+ item.data.id,
164
+ item.data.epoch,
165
+ );
154
166
  }}
155
167
  />
156
168
  );
@@ -115,7 +115,7 @@ export const SampleRow: FC<SampleRowProps> = ({
115
115
  ) : completed ? (
116
116
  scoreRendered
117
117
  ) : (
118
- <PulsingDots />
118
+ <PulsingDots subtle={false} />
119
119
  )}
120
120
  </div>
121
121
  </div>
@@ -19,10 +19,9 @@ export const ErrorEventView: FC<ErrorEventViewProps> = ({
19
19
  className,
20
20
  }) => {
21
21
  const event = eventNode.event;
22
- const id = eventNode.id;
23
22
  return (
24
23
  <EventPanel
25
- id={id}
24
+ eventNodeId={eventNode.id}
26
25
  depth={eventNode.depth}
27
26
  title="Error"
28
27
  className={className}
@@ -36,7 +36,7 @@ export const InfoEventView: FC<InfoEventViewProps> = ({
36
36
 
37
37
  return (
38
38
  <EventPanel
39
- id={eventNode.id}
39
+ eventNodeId={eventNode.id}
40
40
  depth={eventNode.depth}
41
41
  title={"Info" + (event.source ? ": " + event.source : "")}
42
42
  className={className}
@@ -19,10 +19,9 @@ export const InputEventView: FC<InputEventViewProps> = ({
19
19
  className,
20
20
  }) => {
21
21
  const event = eventNode.event;
22
- const id = eventNode.id;
23
22
  return (
24
23
  <EventPanel
25
- id={id}
24
+ eventNodeId={eventNode.id}
26
25
  depth={eventNode.depth}
27
26
  title="Input"
28
27
  className={className}
@@ -32,7 +32,7 @@
32
32
  }
33
33
 
34
34
  .progress {
35
- margin-left: 2em;
35
+ margin-left: 0.5em;
36
36
  }
37
37
 
38
38
  .toolConfig {
@@ -69,7 +69,7 @@ export const ModelEventView: FC<ModelEventViewProps> = ({
69
69
 
70
70
  return (
71
71
  <EventPanel
72
- id={eventNode.id}
72
+ eventNodeId={eventNode.id}
73
73
  depth={eventNode.depth}
74
74
  className={className}
75
75
  title={formatTitle(panelTitle, totalUsage, callTime)}
@@ -56,7 +56,7 @@ export const SampleInitEventView: FC<SampleInitEventViewProps> = ({
56
56
 
57
57
  return (
58
58
  <EventPanel
59
- id={eventNode.id}
59
+ eventNodeId={eventNode.id}
60
60
  depth={eventNode.depth}
61
61
  className={className}
62
62
  title="Sample"
@@ -1,3 +1,4 @@
1
+ import clsx from "clsx";
1
2
  import { FC } from "react";
2
3
  import { SampleLimitEvent, Type10 } from "../../../@types/log";
3
4
  import { ApplicationIcons } from "../../appearance/icons";
@@ -55,13 +56,13 @@ export const SampleLimitEventView: FC<SampleLimitEventViewProps> = ({
55
56
 
56
57
  return (
57
58
  <EventPanel
58
- id={eventNode.id}
59
+ eventNodeId={eventNode.id}
59
60
  depth={eventNode.depth}
60
61
  title={title}
61
62
  icon={icon}
62
63
  className={className}
63
64
  >
64
- {eventNode.event.message}
65
+ <div className={clsx("text-size-smaller")}>{eventNode.event.message}</div>
65
66
  </EventPanel>
66
67
  );
67
68
  };
@@ -25,10 +25,9 @@ export const SandboxEventView: FC<SandboxEventViewProps> = ({
25
25
  className,
26
26
  }) => {
27
27
  const event = eventNode.event;
28
- const id = eventNode.id;
29
28
  return (
30
29
  <EventPanel
31
- id={id}
30
+ eventNodeId={eventNode.id}
32
31
  depth={eventNode.depth}
33
32
  className={className}
34
33
  title={`Sandbox: ${event.action}`}
@@ -36,11 +35,11 @@ export const SandboxEventView: FC<SandboxEventViewProps> = ({
36
35
  subTitle={formatTiming(event.timestamp, event.working_start)}
37
36
  >
38
37
  {event.action === "exec" ? (
39
- <ExecView id={`${id}-exec`} event={event} />
38
+ <ExecView id={`${eventNode.id}-exec`} event={event} />
40
39
  ) : event.action === "read_file" ? (
41
- <ReadFileView id={`${id}-read-file`} event={event} />
40
+ <ReadFileView id={`${eventNode.id}-read-file`} event={event} />
42
41
  ) : (
43
- <WriteFileView id={`${id}-write-file`} event={event} />
42
+ <WriteFileView id={`${eventNode.id}-write-file`} event={event} />
44
43
  )}
45
44
  </EventPanel>
46
45
  );
@@ -31,7 +31,7 @@ export const ScoreEventView: FC<ScoreEventViewProps> = ({
31
31
 
32
32
  return (
33
33
  <EventPanel
34
- id={eventNode.id}
34
+ eventNodeId={eventNode.id}
35
35
  depth={eventNode.depth}
36
36
  title={(event.intermediate ? "Intermediate " : "") + "Score"}
37
37
  className={clsx(className, "text-size-small")}
@@ -21,7 +21,6 @@ export const SpanEventView: FC<SpanEventViewProps> = ({
21
21
  className,
22
22
  }) => {
23
23
  const event = eventNode.event;
24
- const id = eventNode.id;
25
24
  const descriptor = spanDescriptor(event);
26
25
  const title =
27
26
  descriptor.name ||
@@ -30,7 +29,7 @@ export const SpanEventView: FC<SpanEventViewProps> = ({
30
29
 
31
30
  return (
32
31
  <EventPanel
33
- id={id}
32
+ eventNodeId={eventNode.id}
34
33
  depth={eventNode.depth}
35
34
  childIds={children.map((child) => child.id)}
36
35
  className={clsx("transcript-span", className)}
@@ -21,8 +21,6 @@ export const StepEventView: FC<StepEventViewProps> = ({
21
21
  className,
22
22
  }) => {
23
23
  const event = eventNode.event;
24
- const id = eventNode.id;
25
-
26
24
  const descriptor = stepDescriptor(event);
27
25
  const title =
28
26
  descriptor.name ||
@@ -31,7 +29,7 @@ export const StepEventView: FC<StepEventViewProps> = ({
31
29
 
32
30
  return (
33
31
  <EventPanel
34
- id={id}
32
+ eventNodeId={eventNode.id}
35
33
  depth={eventNode.depth}
36
34
  childIds={children.map((child) => child.id)}
37
35
  className={clsx("transcript-step", className)}
@@ -23,7 +23,6 @@ export const SubtaskEventView: FC<SubtaskEventViewProps> = ({
23
23
  className,
24
24
  }) => {
25
25
  const event = eventNode.event;
26
- const id = eventNode.id;
27
26
  const body: ReactNode[] = [];
28
27
  if (event.type === "fork") {
29
28
  body.push(
@@ -48,7 +47,7 @@ export const SubtaskEventView: FC<SubtaskEventViewProps> = ({
48
47
  const type = event.type === "fork" ? "Fork" : "Subtask";
49
48
  return (
50
49
  <EventPanel
51
- id={id}
50
+ eventNodeId={eventNode.id}
52
51
  depth={eventNode.depth}
53
52
  className={className}
54
53
  title={formatTitle(