inspect-ai 0.3.69__py3-none-any.whl → 0.3.71__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 (242) hide show
  1. inspect_ai/_cli/eval.py +27 -9
  2. inspect_ai/_display/core/display.py +2 -0
  3. inspect_ai/_display/core/footer.py +13 -3
  4. inspect_ai/_display/plain/display.py +6 -2
  5. inspect_ai/_display/rich/display.py +19 -6
  6. inspect_ai/_display/textual/app.py +9 -3
  7. inspect_ai/_display/textual/display.py +4 -0
  8. inspect_ai/_display/textual/widgets/samples.py +4 -10
  9. inspect_ai/_display/textual/widgets/transcript.py +35 -18
  10. inspect_ai/_eval/eval.py +14 -2
  11. inspect_ai/_eval/evalset.py +6 -1
  12. inspect_ai/_eval/run.py +6 -0
  13. inspect_ai/_eval/task/run.py +49 -23
  14. inspect_ai/_eval/task/task.py +26 -3
  15. inspect_ai/_util/content.py +20 -1
  16. inspect_ai/_util/interrupt.py +6 -0
  17. inspect_ai/_util/logger.py +19 -0
  18. inspect_ai/_util/rich.py +7 -8
  19. inspect_ai/_util/text.py +13 -0
  20. inspect_ai/_util/transcript.py +20 -6
  21. inspect_ai/_util/working.py +50 -0
  22. inspect_ai/_view/www/App.css +6 -0
  23. inspect_ai/_view/www/dist/assets/index.css +171 -99
  24. inspect_ai/_view/www/dist/assets/index.js +5972 -2770
  25. inspect_ai/_view/www/eslint.config.mjs +24 -1
  26. inspect_ai/_view/www/log-schema.json +619 -21
  27. inspect_ai/_view/www/package.json +8 -3
  28. inspect_ai/_view/www/src/App.tsx +2 -2
  29. inspect_ai/_view/www/src/appearance/icons.ts +3 -1
  30. inspect_ai/_view/www/src/components/AnsiDisplay.tsx +4 -3
  31. inspect_ai/_view/www/src/components/Card.tsx +9 -8
  32. inspect_ai/_view/www/src/components/DownloadButton.tsx +2 -1
  33. inspect_ai/_view/www/src/components/EmptyPanel.tsx +2 -2
  34. inspect_ai/_view/www/src/components/ErrorPanel.tsx +4 -3
  35. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +13 -5
  36. inspect_ai/_view/www/src/components/FindBand.tsx +3 -3
  37. inspect_ai/_view/www/src/components/HumanBaselineView.tsx +3 -3
  38. inspect_ai/_view/www/src/components/LabeledValue.tsx +5 -4
  39. inspect_ai/_view/www/src/components/LargeModal.tsx +18 -13
  40. inspect_ai/_view/www/src/components/{LightboxCarousel.css → LightboxCarousel.module.css} +22 -18
  41. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +36 -27
  42. inspect_ai/_view/www/src/components/MessageBand.tsx +2 -1
  43. inspect_ai/_view/www/src/components/NavPills.tsx +9 -8
  44. inspect_ai/_view/www/src/components/ProgressBar.tsx +2 -1
  45. inspect_ai/_view/www/src/components/TabSet.tsx +21 -15
  46. inspect_ai/_view/www/src/index.tsx +2 -2
  47. inspect_ai/_view/www/src/metadata/MetaDataGrid.tsx +11 -9
  48. inspect_ai/_view/www/src/metadata/MetaDataView.tsx +3 -2
  49. inspect_ai/_view/www/src/metadata/MetadataGrid.module.css +1 -0
  50. inspect_ai/_view/www/src/metadata/RenderedContent.tsx +16 -1
  51. inspect_ai/_view/www/src/plan/DatasetDetailView.tsx +3 -2
  52. inspect_ai/_view/www/src/plan/DetailStep.tsx +2 -1
  53. inspect_ai/_view/www/src/plan/PlanCard.tsx +2 -5
  54. inspect_ai/_view/www/src/plan/PlanDetailView.tsx +6 -9
  55. inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +2 -1
  56. inspect_ai/_view/www/src/plan/SolverDetailView.tsx +3 -3
  57. inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +2 -2
  58. inspect_ai/_view/www/src/samples/SampleDialog.tsx +3 -3
  59. inspect_ai/_view/www/src/samples/SampleDisplay.module.css +9 -1
  60. inspect_ai/_view/www/src/samples/SampleDisplay.tsx +30 -3
  61. inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +4 -0
  62. inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +25 -4
  63. inspect_ai/_view/www/src/samples/SamplesTools.tsx +2 -1
  64. inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +3 -19
  65. inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +2 -1
  66. inspect_ai/_view/www/src/samples/chat/ChatMessageRow.tsx +2 -1
  67. inspect_ai/_view/www/src/samples/chat/ChatView.tsx +2 -1
  68. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +22 -7
  69. inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +35 -6
  70. inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +2 -2
  71. inspect_ai/_view/www/src/samples/chat/messages.ts +15 -2
  72. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +13 -4
  73. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.module.css +2 -2
  74. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +18 -19
  75. inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.module.css +1 -1
  76. inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.tsx +4 -3
  77. inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.tsx +2 -2
  78. inspect_ai/_view/www/src/samples/error/FlatSampleErrorView.tsx +2 -3
  79. inspect_ai/_view/www/src/samples/error/SampleErrorView.tsx +3 -2
  80. inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +2 -1
  81. inspect_ai/_view/www/src/samples/list/SampleHeader.tsx +2 -1
  82. inspect_ai/_view/www/src/samples/list/SampleList.tsx +57 -45
  83. inspect_ai/_view/www/src/samples/list/SampleRow.tsx +2 -1
  84. inspect_ai/_view/www/src/samples/list/SampleSeparator.tsx +2 -1
  85. inspect_ai/_view/www/src/samples/sample-tools/EpochFilter.tsx +2 -2
  86. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +4 -3
  87. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +2 -5
  88. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +2 -2
  89. inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +2 -1
  90. inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +2 -2
  91. inspect_ai/_view/www/src/samples/transcript/ApprovalEventView.tsx +2 -1
  92. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +2 -1
  93. inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +2 -1
  94. inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +2 -1
  95. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.module.css +4 -0
  96. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.tsx +12 -2
  97. inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +1 -1
  98. inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +25 -28
  99. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +2 -1
  100. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +9 -4
  101. inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +2 -2
  102. inspect_ai/_view/www/src/samples/transcript/SandboxEventView.module.css +32 -0
  103. inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +153 -0
  104. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +2 -2
  105. inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +12 -5
  106. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +18 -14
  107. inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +5 -5
  108. inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +53 -16
  109. inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +2 -1
  110. inspect_ai/_view/www/src/samples/transcript/event/EventNavs.tsx +2 -1
  111. inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +6 -3
  112. inspect_ai/_view/www/src/samples/transcript/event/EventRow.tsx +3 -2
  113. inspect_ai/_view/www/src/samples/transcript/event/EventSection.tsx +2 -2
  114. inspect_ai/_view/www/src/samples/transcript/event/EventTimingPanel.module.css +28 -0
  115. inspect_ai/_view/www/src/samples/transcript/event/EventTimingPanel.tsx +115 -0
  116. inspect_ai/_view/www/src/samples/transcript/event/utils.ts +29 -0
  117. inspect_ai/_view/www/src/samples/transcript/state/StateDiffView.tsx +2 -1
  118. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +3 -3
  119. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +11 -8
  120. inspect_ai/_view/www/src/samples/transcript/types.ts +3 -1
  121. inspect_ai/_view/www/src/types/log.d.ts +312 -137
  122. inspect_ai/_view/www/src/usage/ModelTokenTable.tsx +6 -10
  123. inspect_ai/_view/www/src/usage/ModelUsagePanel.module.css +4 -0
  124. inspect_ai/_view/www/src/usage/ModelUsagePanel.tsx +32 -9
  125. inspect_ai/_view/www/src/usage/TokenTable.tsx +4 -6
  126. inspect_ai/_view/www/src/usage/UsageCard.tsx +2 -1
  127. inspect_ai/_view/www/src/utils/format.ts +8 -5
  128. inspect_ai/_view/www/src/utils/json.ts +24 -0
  129. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +6 -5
  130. inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +18 -8
  131. inspect_ai/_view/www/src/workspace/error/TaskErrorPanel.tsx +2 -1
  132. inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +2 -1
  133. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +3 -3
  134. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +4 -3
  135. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +5 -4
  136. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +5 -8
  137. inspect_ai/_view/www/src/workspace/sidebar/EvalStatus.tsx +5 -4
  138. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +2 -1
  139. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +2 -1
  140. inspect_ai/_view/www/src/workspace/sidebar/SidebarLogEntry.tsx +2 -2
  141. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoreView.tsx +2 -1
  142. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoresView.tsx +2 -2
  143. inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +2 -2
  144. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +2 -5
  145. inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +12 -11
  146. inspect_ai/_view/www/yarn.lock +241 -5
  147. inspect_ai/log/__init__.py +2 -0
  148. inspect_ai/log/_condense.py +4 -0
  149. inspect_ai/log/_log.py +72 -12
  150. inspect_ai/log/_recorders/eval.py +6 -1
  151. inspect_ai/log/_samples.py +5 -1
  152. inspect_ai/log/_transcript.py +89 -2
  153. inspect_ai/model/__init__.py +2 -0
  154. inspect_ai/model/_call_tools.py +8 -1
  155. inspect_ai/model/_chat_message.py +22 -7
  156. inspect_ai/model/_conversation.py +11 -9
  157. inspect_ai/model/_generate_config.py +25 -4
  158. inspect_ai/model/_model.py +164 -72
  159. inspect_ai/model/_model_call.py +10 -3
  160. inspect_ai/model/_model_output.py +3 -0
  161. inspect_ai/model/_openai.py +106 -40
  162. inspect_ai/model/_providers/anthropic.py +145 -26
  163. inspect_ai/model/_providers/bedrock.py +7 -0
  164. inspect_ai/model/_providers/cloudflare.py +20 -7
  165. inspect_ai/model/_providers/google.py +29 -8
  166. inspect_ai/model/_providers/groq.py +66 -27
  167. inspect_ai/model/_providers/hf.py +6 -0
  168. inspect_ai/model/_providers/mistral.py +78 -51
  169. inspect_ai/model/_providers/openai.py +66 -4
  170. inspect_ai/model/_providers/openai_o1.py +10 -0
  171. inspect_ai/model/_providers/providers.py +2 -2
  172. inspect_ai/model/_providers/util/tracker.py +92 -0
  173. inspect_ai/model/_providers/vllm.py +13 -5
  174. inspect_ai/model/_reasoning.py +15 -2
  175. inspect_ai/scorer/_model.py +23 -19
  176. inspect_ai/solver/_basic_agent.py +1 -3
  177. inspect_ai/solver/_bridge/patch.py +0 -2
  178. inspect_ai/solver/_human_agent/agent.py +14 -10
  179. inspect_ai/solver/_human_agent/commands/__init__.py +7 -3
  180. inspect_ai/solver/_human_agent/commands/submit.py +76 -30
  181. inspect_ai/solver/_limit.py +4 -4
  182. inspect_ai/solver/_plan.py +0 -3
  183. inspect_ai/solver/_task_state.py +7 -0
  184. inspect_ai/tool/__init__.py +2 -0
  185. inspect_ai/tool/_tool.py +3 -1
  186. inspect_ai/tool/_tools/_computer/_resources/tool/_run.py +1 -1
  187. inspect_ai/tool/_tools/_web_browser/_resources/.pylintrc +8 -0
  188. inspect_ai/tool/_tools/_web_browser/_resources/.vscode/launch.json +24 -0
  189. inspect_ai/tool/_tools/_web_browser/_resources/.vscode/settings.json +25 -0
  190. inspect_ai/tool/_tools/_web_browser/_resources/Dockerfile +5 -6
  191. inspect_ai/tool/_tools/_web_browser/_resources/README.md +10 -11
  192. inspect_ai/tool/_tools/_web_browser/_resources/accessibility_tree.py +71 -0
  193. inspect_ai/tool/_tools/_web_browser/_resources/accessibility_tree_node.py +323 -0
  194. inspect_ai/tool/_tools/_web_browser/_resources/cdp/__init__.py +5 -0
  195. inspect_ai/tool/_tools/_web_browser/_resources/cdp/a11y.py +279 -0
  196. inspect_ai/tool/_tools/_web_browser/_resources/cdp/dom.py +9 -0
  197. inspect_ai/tool/_tools/_web_browser/_resources/cdp/dom_snapshot.py +293 -0
  198. inspect_ai/tool/_tools/_web_browser/_resources/cdp/page.py +94 -0
  199. inspect_ai/tool/_tools/_web_browser/_resources/constants.py +2 -0
  200. inspect_ai/tool/_tools/_web_browser/_resources/images/usage_diagram.svg +2 -0
  201. inspect_ai/tool/_tools/_web_browser/_resources/playwright_browser.py +50 -0
  202. inspect_ai/tool/_tools/_web_browser/_resources/playwright_crawler.py +31 -359
  203. inspect_ai/tool/_tools/_web_browser/_resources/playwright_page_crawler.py +280 -0
  204. inspect_ai/tool/_tools/_web_browser/_resources/pyproject.toml +65 -0
  205. inspect_ai/tool/_tools/_web_browser/_resources/rectangle.py +64 -0
  206. inspect_ai/tool/_tools/_web_browser/_resources/rpc_client_helpers.py +146 -0
  207. inspect_ai/tool/_tools/_web_browser/_resources/scale_factor.py +64 -0
  208. inspect_ai/tool/_tools/_web_browser/_resources/test_accessibility_tree_node.py +180 -0
  209. inspect_ai/tool/_tools/_web_browser/_resources/test_playwright_crawler.py +15 -9
  210. inspect_ai/tool/_tools/_web_browser/_resources/test_rectangle.py +15 -0
  211. inspect_ai/tool/_tools/_web_browser/_resources/test_web_client.py +44 -0
  212. inspect_ai/tool/_tools/_web_browser/_resources/web_browser_rpc_types.py +39 -0
  213. inspect_ai/tool/_tools/_web_browser/_resources/web_client.py +198 -48
  214. inspect_ai/tool/_tools/_web_browser/_resources/web_client_new_session.py +26 -25
  215. inspect_ai/tool/_tools/_web_browser/_resources/web_server.py +178 -39
  216. inspect_ai/tool/_tools/_web_browser/_web_browser.py +38 -19
  217. inspect_ai/tool/_tools/_web_search.py +3 -3
  218. inspect_ai/util/__init__.py +2 -1
  219. inspect_ai/util/_concurrency.py +14 -8
  220. inspect_ai/util/_display.py +12 -0
  221. inspect_ai/util/_sandbox/context.py +15 -0
  222. inspect_ai/util/_sandbox/docker/docker.py +7 -5
  223. inspect_ai/util/_sandbox/environment.py +32 -1
  224. inspect_ai/util/_sandbox/events.py +183 -0
  225. inspect_ai/util/_sandbox/local.py +3 -3
  226. inspect_ai/util/_sandbox/self_check.py +131 -43
  227. inspect_ai/util/_subtask.py +11 -0
  228. {inspect_ai-0.3.69.dist-info → inspect_ai-0.3.71.dist-info}/METADATA +3 -3
  229. {inspect_ai-0.3.69.dist-info → inspect_ai-0.3.71.dist-info}/RECORD +233 -211
  230. {inspect_ai-0.3.69.dist-info → inspect_ai-0.3.71.dist-info}/WHEEL +1 -1
  231. inspect_ai/_view/www/src/components/VirtualList.module.css +0 -19
  232. inspect_ai/_view/www/src/components/VirtualList.tsx +0 -292
  233. inspect_ai/tool/_tools/_web_browser/_resources/accessibility_node.py +0 -312
  234. inspect_ai/tool/_tools/_web_browser/_resources/dm_env_servicer.py +0 -275
  235. inspect_ai/tool/_tools/_web_browser/_resources/images/usage_diagram.png +0 -0
  236. inspect_ai/tool/_tools/_web_browser/_resources/test_accessibility_node.py +0 -176
  237. inspect_ai/tool/_tools/_web_browser/_resources/test_dm_env_servicer.py +0 -135
  238. inspect_ai/tool/_tools/_web_browser/_resources/test_web_environment.py +0 -71
  239. inspect_ai/tool/_tools/_web_browser/_resources/web_environment.py +0 -184
  240. {inspect_ai-0.3.69.dist-info → inspect_ai-0.3.71.dist-info}/LICENSE +0 -0
  241. {inspect_ai-0.3.69.dist-info → inspect_ai-0.3.71.dist-info}/entry_points.txt +0 -0
  242. {inspect_ai-0.3.69.dist-info → inspect_ai-0.3.71.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,32 @@
1
+ .contents {
2
+ margin-top: 0.5em;
3
+ }
4
+
5
+ .contents > :last-child {
6
+ margin-bottom: 0;
7
+ }
8
+
9
+ .twoColumn {
10
+ display: grid;
11
+ grid-template-columns: auto 1fr;
12
+ column-gap: 1.5em;
13
+ }
14
+
15
+ .exec {
16
+ margin-top: 0.5em;
17
+ }
18
+
19
+ .result {
20
+ margin-top: 0.5em;
21
+ }
22
+
23
+ .fileLabel {
24
+ margin-top: 0;
25
+ margin-bottom: 0;
26
+ }
27
+
28
+ .wrapPre {
29
+ white-space: pre-wrap;
30
+ word-wrap: break-word;
31
+ overflow-wrap: break-word;
32
+ }
@@ -0,0 +1,153 @@
1
+ import { ApplicationIcons } from "../../appearance/icons";
2
+ import ExpandablePanel from "../../components/ExpandablePanel";
3
+ import { MarkdownDiv } from "../../components/MarkdownDiv";
4
+ import { MetaDataGrid } from "../../metadata/MetaDataGrid";
5
+ import { SandboxEvent } from "../../types/log";
6
+ import { EventPanel } from "./event/EventPanel";
7
+ import { EventSection } from "./event/EventSection";
8
+ import { TranscriptEventState } from "./types";
9
+
10
+ import clsx from "clsx";
11
+ import { FC } from "react";
12
+ import styles from "./SandboxEventView.module.css";
13
+ import { formatTiming } from "./event/utils";
14
+
15
+ interface SandboxEventViewProps {
16
+ id: string;
17
+ event: SandboxEvent;
18
+ eventState: TranscriptEventState;
19
+ setEventState: (state: TranscriptEventState) => void;
20
+ className?: string | string[];
21
+ }
22
+
23
+ /**
24
+ * Renders the SandboxEventView component.
25
+ */
26
+ export const SandboxEventView: FC<SandboxEventViewProps> = ({
27
+ id,
28
+ event,
29
+ eventState,
30
+ setEventState,
31
+ className,
32
+ }) => {
33
+ return (
34
+ <EventPanel
35
+ id={id}
36
+ className={className}
37
+ title={`Sandbox: ${event.action}`}
38
+ icon={ApplicationIcons.sandbox}
39
+ subTitle={formatTiming(event.timestamp, event.working_start)}
40
+ selectedNav={eventState.selectedNav || ""}
41
+ setSelectedNav={(selectedNav) => {
42
+ setEventState({ ...eventState, selectedNav });
43
+ }}
44
+ collapsed={eventState.collapsed}
45
+ setCollapsed={(collapsed) => {
46
+ setEventState({ ...eventState, collapsed });
47
+ }}
48
+ >
49
+ {event.action === "exec" ? (
50
+ <ExecView event={event} />
51
+ ) : event.action === "read_file" ? (
52
+ <ReadFileView event={event} />
53
+ ) : (
54
+ <WriteFileView event={event} />
55
+ )}
56
+ </EventPanel>
57
+ );
58
+ };
59
+
60
+ interface ExecViewProps {
61
+ event: SandboxEvent;
62
+ }
63
+
64
+ const ExecView: FC<ExecViewProps> = ({ event }) => {
65
+ if (event.cmd === null) {
66
+ return undefined;
67
+ }
68
+ const cmd = event.cmd;
69
+ const options = event.options;
70
+ const input = event.input;
71
+ const result = event.result;
72
+ const output = event.output;
73
+
74
+ return (
75
+ <div className={clsx(styles.exec)}>
76
+ <EventSection title={`Command`}>
77
+ <div className={clsx(styles.twoColumn)}>
78
+ <pre className={clsx(styles.wrapPre)}>{cmd}</pre>
79
+ <pre className={clsx(styles.wrapPre)}>
80
+ {input !== null ? input?.trim() : undefined}
81
+ </pre>
82
+
83
+ {options !== null ? (
84
+ <EventSection title={`Options`}>
85
+ <MetaDataGrid
86
+ entries={options as Record<string, unknown>}
87
+ plain={true}
88
+ />
89
+ </EventSection>
90
+ ) : undefined}
91
+ </div>
92
+ </EventSection>
93
+ <EventSection title={`Result`}>
94
+ {output ? (
95
+ <ExpandablePanel collapse={false}>
96
+ <MarkdownDiv markdown={output} />
97
+ </ExpandablePanel>
98
+ ) : undefined}
99
+ <div className={clsx(styles.result)}>Exited with code {result}</div>
100
+ </EventSection>
101
+ </div>
102
+ );
103
+ };
104
+
105
+ interface ReadFileViewProps {
106
+ event: SandboxEvent;
107
+ }
108
+
109
+ const ReadFileView: FC<ReadFileViewProps> = ({ event }) => {
110
+ if (event.file === null) {
111
+ return undefined;
112
+ }
113
+ const file = event.file;
114
+ const output = event.output;
115
+ return <FileView file={file} contents={output?.trim()} />;
116
+ };
117
+
118
+ interface WriteFileViewProps {
119
+ event: SandboxEvent;
120
+ }
121
+
122
+ const WriteFileView: FC<WriteFileViewProps> = ({ event }) => {
123
+ if (event.file === null) {
124
+ return undefined;
125
+ }
126
+ const file = event.file;
127
+ const input = event.input;
128
+
129
+ return <FileView file={file} contents={input?.trim()} />;
130
+ };
131
+
132
+ interface FileViewProps {
133
+ file: string;
134
+ contents?: string;
135
+ }
136
+
137
+ const FileView: FC<FileViewProps> = ({ file, contents }) => {
138
+ return (
139
+ <div>
140
+ <EventSection title="File">
141
+ <pre className={clsx(styles.fileLabel)}>{file}</pre>
142
+ </EventSection>
143
+
144
+ {contents ? (
145
+ <EventSection title="Contents">
146
+ <ExpandablePanel collapse={false}>
147
+ <pre>{contents}</pre>
148
+ </ExpandablePanel>
149
+ </EventSection>
150
+ ) : undefined}
151
+ </div>
152
+ );
153
+ };
@@ -1,4 +1,4 @@
1
- import { Fragment } from "react";
1
+ import { FC, Fragment } from "react";
2
2
  import { ApplicationIcons } from "../../appearance/icons";
3
3
  import { MarkdownDiv } from "../../components/MarkdownDiv";
4
4
  import { MetaDataGrid } from "../../metadata/MetaDataGrid";
@@ -21,7 +21,7 @@ interface ScoreEventViewProps {
21
21
  /**
22
22
  * Renders the ScoreEventView component.
23
23
  */
24
- export const ScoreEventView: React.FC<ScoreEventViewProps> = ({
24
+ export const ScoreEventView: FC<ScoreEventViewProps> = ({
25
25
  id,
26
26
  event,
27
27
  eventState,
@@ -1,5 +1,5 @@
1
1
  import clsx from "clsx";
2
- import { RefObject, useCallback, useState } from "react";
2
+ import { FC, RefObject, useCallback, useState } from "react";
3
3
  import { StepEvent } from "../../types/log";
4
4
  import { formatDateTime } from "../../utils/format";
5
5
  import { EventPanel } from "./event/EventPanel";
@@ -18,7 +18,7 @@ interface StepEventViewProps {
18
18
  /**
19
19
  * Renders the StepEventView component.
20
20
  */
21
- export const StepEventView: React.FC<StepEventViewProps> = ({
21
+ export const StepEventView: FC<StepEventViewProps> = ({
22
22
  event,
23
23
  eventState,
24
24
  setEventState,
@@ -37,7 +37,7 @@ export const StepEventView: React.FC<StepEventViewProps> = ({
37
37
  (state: TranscriptEventState) => {
38
38
  setTranscriptState({ ...state });
39
39
  },
40
- [transcriptState, setTranscriptState],
40
+ [setTranscriptState],
41
41
  );
42
42
 
43
43
  return (
@@ -47,7 +47,7 @@ export const StepEventView: React.FC<StepEventViewProps> = ({
47
47
  title={title}
48
48
  subTitle={formatDateTime(new Date(event.timestamp))}
49
49
  icon={descriptor.icon}
50
- collapse={false}
50
+ collapse={descriptor.collapse}
51
51
  text={text}
52
52
  selectedNav={eventState.selectedNav || ""}
53
53
  setSelectedNav={(selectedNav) => {
@@ -115,7 +115,7 @@ const summarize = (children: EventNode[]) => {
115
115
  */
116
116
  const stepDescriptor = (
117
117
  event: StepEvent,
118
- ): { icon?: string; name?: string; endSpace?: boolean } => {
118
+ ): { icon?: string; name?: string; endSpace?: boolean; collapse?: boolean } => {
119
119
  const rootStepDescriptor = {
120
120
  endSpace: true,
121
121
  };
@@ -161,6 +161,13 @@ const stepDescriptor = (
161
161
  return {
162
162
  ...rootStepDescriptor,
163
163
  name: "Sample Init",
164
+ collapse: true,
165
+ };
166
+ case "init":
167
+ return {
168
+ ...rootStepDescriptor,
169
+ name: "Init",
170
+ collapse: true,
164
171
  };
165
172
  default:
166
173
  return {
@@ -1,10 +1,10 @@
1
1
  import clsx from "clsx";
2
- import { Fragment } from "react";
2
+ import { FC, Fragment } from "react";
3
3
  import { ApplicationIcons } from "../../appearance/icons";
4
4
  import { MetaDataView } from "../../metadata/MetaDataView";
5
- import { Input2, Input4, Result1, SubtaskEvent } from "../../types/log";
6
- import { formatDateTime } from "../../utils/format";
5
+ import { Input2, Input5, Result2, SubtaskEvent } from "../../types/log";
7
6
  import { EventPanel } from "./event/EventPanel";
7
+ import { formatTiming, formatTitle } from "./event/utils";
8
8
  import styles from "./SubtaskEventView.module.css";
9
9
  import { TranscriptView } from "./TranscriptView";
10
10
  import { TranscriptEventState } from "./types";
@@ -21,7 +21,7 @@ interface SubtaskEventViewProps {
21
21
  /**
22
22
  * Renders the StateEventView component.
23
23
  */
24
- export const SubtaskEventView: React.FC<SubtaskEventViewProps> = ({
24
+ export const SubtaskEventView: FC<SubtaskEventViewProps> = ({
25
25
  id,
26
26
  event,
27
27
  eventState,
@@ -73,8 +73,12 @@ export const SubtaskEventView: React.FC<SubtaskEventViewProps> = ({
73
73
  <EventPanel
74
74
  id={id}
75
75
  className={className}
76
- title={`${type}: ${event.name}`}
77
- subTitle={formatDateTime(new Date(event.timestamp))}
76
+ title={formatTitle(
77
+ `${type}: ${event.name}`,
78
+ undefined,
79
+ event.working_time,
80
+ )}
81
+ subTitle={formatTiming(event.timestamp, event.working_start)}
78
82
  collapse={false}
79
83
  selectedNav={eventState.selectedNav || ""}
80
84
  setSelectedNav={(selectedNav) => {
@@ -91,25 +95,25 @@ export const SubtaskEventView: React.FC<SubtaskEventViewProps> = ({
91
95
  };
92
96
 
93
97
  interface SubtaskSummaryProps {
94
- input: Input2 | Input4;
95
- result: Result1;
98
+ input: Input2 | Input5;
99
+ result: Result2;
96
100
  }
97
101
  /**
98
102
  * Renders the StateEventView component.
99
103
  */
100
- const SubtaskSummary: React.FC<SubtaskSummaryProps> = ({ input, result }) => {
101
- result = typeof result === "object" ? result : { result };
104
+ const SubtaskSummary: FC<SubtaskSummaryProps> = ({ input, result }) => {
105
+ const output = typeof result === "object" ? result : { result };
102
106
  return (
103
107
  <div className={clsx(styles.subtaskSummary)}>
104
108
  <div className={clsx("text-style-label")}>Input</div>
105
109
  <div className={clsx("text-size-large", styles.subtaskLabel)}></div>
106
110
  <div className={clsx("text-style-label")}>Output</div>
107
- <Rendered values={input} />
111
+ {input ? <Rendered values={input} /> : undefined}
108
112
  <div className={clsx("text-size-title-secondary", styles.subtaskLabel)}>
109
113
  <i className={ApplicationIcons.arrows.right} />
110
114
  </div>
111
115
  <div>
112
- <Rendered values={result} />
116
+ <Rendered values={output} />
113
117
  </div>
114
118
  </div>
115
119
  );
@@ -123,7 +127,7 @@ interface RenderedProps {
123
127
  * Recursively renders content based on the type of `values`.
124
128
  value.
125
129
  */
126
- const Rendered: React.FC<RenderedProps> = ({ values }) => {
130
+ const Rendered: FC<RenderedProps> = ({ values }) => {
127
131
  if (Array.isArray(values)) {
128
132
  return values.map((val) => {
129
133
  return <Rendered values={val} />;
@@ -139,7 +143,7 @@ const Rendered: React.FC<RenderedProps> = ({ values }) => {
139
143
  }
140
144
  };
141
145
 
142
- const None: React.FC = () => {
146
+ const None: FC = () => {
143
147
  return (
144
148
  <span className={clsx("text-size-small", "text-style-secondary")}>
145
149
  [None]
@@ -1,6 +1,5 @@
1
1
  import { ApplicationIcons } from "../../appearance/icons";
2
2
  import { ToolEvent } from "../../types/log";
3
- import { formatDateTime } from "../../utils/format";
4
3
  import { resolveToolInput } from "../chat/tools/tool";
5
4
  import { ToolCallView } from "../chat/tools/ToolCallView";
6
5
  import { ApprovalEventView } from "./ApprovalEventView";
@@ -8,7 +7,8 @@ import { EventPanel } from "./event/EventPanel";
8
7
  import { TranscriptView } from "./TranscriptView";
9
8
  import { TranscriptEventState } from "./types";
10
9
 
11
- import { useMemo } from "react";
10
+ import { FC, useMemo } from "react";
11
+ import { formatTiming, formatTitle } from "./event/utils";
12
12
  import styles from "./ToolEventView.module.css";
13
13
 
14
14
  interface ToolEventViewProps {
@@ -23,7 +23,7 @@ interface ToolEventViewProps {
23
23
  /**
24
24
  * Renders the ToolEventView component.
25
25
  */
26
- export const ToolEventView: React.FC<ToolEventViewProps> = ({
26
+ export const ToolEventView: FC<ToolEventViewProps> = ({
27
27
  id,
28
28
  event,
29
29
  eventState,
@@ -46,9 +46,9 @@ export const ToolEventView: React.FC<ToolEventViewProps> = ({
46
46
  return (
47
47
  <EventPanel
48
48
  id={id}
49
- title={title}
49
+ title={formatTitle(title, undefined, event.working_time)}
50
50
  className={className}
51
- subTitle={formatDateTime(new Date(event.timestamp))}
51
+ subTitle={formatTiming(event.timestamp, event.working_start)}
52
52
  icon={ApplicationIcons.solvers.use_tools}
53
53
  selectedNav={eventState.selectedNav || ""}
54
54
  setSelectedNav={(selectedNav) => {
@@ -1,5 +1,4 @@
1
1
  import React, { RefObject, useCallback, useState } from "react";
2
- import { VirtualList } from "../../components/VirtualList";
3
2
  import { Events } from "../../types/log";
4
3
  import { ApprovalEventView } from "./ApprovalEventView";
5
4
  import { ErrorEventView } from "./ErrorEventView";
@@ -17,6 +16,8 @@ import { ToolEventView } from "./ToolEventView";
17
16
  import { EventNode, EventType, TranscriptEventState } from "./types";
18
17
 
19
18
  import clsx from "clsx";
19
+ import { Virtuoso } from "react-virtuoso";
20
+ import { SandboxEventView } from "./SandboxEventView";
20
21
  import styles from "./TranscriptView.module.css";
21
22
 
22
23
  interface TranscriptViewProps {
@@ -83,7 +84,7 @@ export const TranscriptVirtualList: React.FC<TranscriptVirtualListProps> = (
83
84
  (state: TranscriptEventState) => {
84
85
  setTranscriptState(state);
85
86
  },
86
- [transcriptState, setTranscriptState],
87
+ [setTranscriptState],
87
88
  );
88
89
 
89
90
  return (
@@ -115,9 +116,11 @@ export const TranscriptVirtualListComponent: React.FC<
115
116
  (eventId: string, state: TranscriptEventState) => {
116
117
  setTranscriptState({ ...transcriptState, [eventId]: state });
117
118
  },
118
- [setTranscriptState],
119
+ [transcriptState, setTranscriptState],
119
120
  );
120
121
 
122
+ const [followOutput, setFollowOutput] = useState(false);
123
+
121
124
  const renderRow = (item: EventNode, index: number) => {
122
125
  const bgClass = item.depth % 2 == 0 ? styles.darkenedBg : styles.normalBg;
123
126
  const paddingClass = index === 0 ? styles.first : undefined;
@@ -139,12 +142,24 @@ export const TranscriptVirtualListComponent: React.FC<
139
142
  };
140
143
 
141
144
  return (
142
- <VirtualList
145
+ <Virtuoso
146
+ customScrollParent={scrollRef?.current ? scrollRef.current : undefined}
147
+ style={{ height: "100%", width: "100%" }}
143
148
  data={eventNodes}
144
- tabIndex={0}
145
- renderRow={renderRow}
146
- scrollRef={scrollRef}
147
- className={styles.nodes}
149
+ itemContent={(index: number, data: EventNode) => {
150
+ return renderRow(data, index);
151
+ }}
152
+ increaseViewportBy={{ top: 1000, bottom: 1000 }}
153
+ overscan={{
154
+ main: 10,
155
+ reverse: 10,
156
+ }}
157
+ followOutput={followOutput}
158
+ atBottomStateChange={(atBottom: boolean) => {
159
+ setFollowOutput(atBottom);
160
+ }}
161
+ skipAnimationFrameInResizeObserver={true}
162
+ className={clsx("transcript")}
148
163
  />
149
164
  );
150
165
  };
@@ -164,6 +179,13 @@ export const TranscriptComponent: React.FC<TranscriptComponentProps> = ({
164
179
  setTranscriptState,
165
180
  eventNodes,
166
181
  }) => {
182
+ const setEventState = useCallback(
183
+ (state: TranscriptEventState, eventId: string) => {
184
+ setTranscriptState({ ...transcriptState, [eventId]: state });
185
+ },
186
+ [setTranscriptState, transcriptState],
187
+ );
188
+
167
189
  const rows = eventNodes.map((eventNode, index) => {
168
190
  const clz = [styles.eventNode];
169
191
  if (eventNode.depth % 2 == 0) {
@@ -174,12 +196,6 @@ export const TranscriptComponent: React.FC<TranscriptComponentProps> = ({
174
196
  }
175
197
 
176
198
  const eventId = `${id}-event${index}`;
177
- const setEventState = useCallback(
178
- (state: TranscriptEventState) => {
179
- setTranscriptState({ ...transcriptState, [eventId]: state });
180
- },
181
- [setTranscriptState, transcriptState],
182
- );
183
199
 
184
200
  const row = (
185
201
  <div
@@ -194,7 +210,9 @@ export const TranscriptComponent: React.FC<TranscriptComponentProps> = ({
194
210
  node={eventNode}
195
211
  className={clsx(clz)}
196
212
  eventState={transcriptState[eventId] || {}}
197
- setEventState={setEventState}
213
+ setEventState={(state: TranscriptEventState) => {
214
+ setEventState(state, eventId);
215
+ }}
198
216
  />
199
217
  </div>
200
218
  );
@@ -373,6 +391,17 @@ export const RenderedEventNode: React.FC<RenderedEventNodeProps> = ({
373
391
  case "approval":
374
392
  return <ApprovalEventView event={node.event} className={className} />;
375
393
 
394
+ case "sandbox":
395
+ return (
396
+ <SandboxEventView
397
+ id={id}
398
+ event={node.event}
399
+ className={className}
400
+ eventState={eventState}
401
+ setEventState={setEventState}
402
+ />
403
+ );
404
+
376
405
  default:
377
406
  return null;
378
407
  }
@@ -390,8 +419,14 @@ const fixupEventStream = (events: Events) => {
390
419
  // Filter pending events
391
420
  const finalEvents = events.filter((e) => !e.pending);
392
421
 
422
+ // See if the find an init step
423
+ const hasInitStep =
424
+ events.findIndex((e) => {
425
+ return e.event === "step" && e.name === "init";
426
+ }) !== -1;
427
+
393
428
  const fixedUp = [...finalEvents];
394
- if (initEvent) {
429
+ if (!hasInitStep && initEvent) {
395
430
  fixedUp.splice(initEventIndex, 0, {
396
431
  timestamp: initEvent.timestamp,
397
432
  event: "step",
@@ -399,6 +434,7 @@ const fixupEventStream = (events: Events) => {
399
434
  type: null,
400
435
  name: "sample_init",
401
436
  pending: false,
437
+ working_start: 0,
402
438
  });
403
439
 
404
440
  fixedUp.splice(initEventIndex + 2, 0, {
@@ -408,6 +444,7 @@ const fixupEventStream = (events: Events) => {
408
444
  type: null,
409
445
  name: "sample_init",
410
446
  pending: false,
447
+ working_start: 0,
411
448
  });
412
449
  }
413
450
 
@@ -1,5 +1,6 @@
1
1
  import clsx from "clsx";
2
2
 
3
+ import { FC } from "react";
3
4
  import styles from "./EventNav.module.css";
4
5
 
5
6
  interface EventNavProps {
@@ -11,7 +12,7 @@ interface EventNavProps {
11
12
  /**
12
13
  * Component to render a single navigation item.
13
14
  */
14
- export const EventNav: React.FC<EventNavProps> = ({
15
+ export const EventNav: FC<EventNavProps> = ({
15
16
  target,
16
17
  title,
17
18
  selectedNav,
@@ -1,6 +1,7 @@
1
1
  import clsx from "clsx";
2
2
  import { EventNav } from "./EventNav";
3
3
 
4
+ import { FC } from "react";
4
5
  import styles from "./EventNavs.module.css";
5
6
 
6
7
  interface EventNavsProps {
@@ -12,7 +13,7 @@ interface EventNavsProps {
12
13
  /**
13
14
  * Component to render navigation items.
14
15
  */
15
- export const EventNavs: React.FC<EventNavsProps> = ({
16
+ export const EventNavs: FC<EventNavsProps> = ({
16
17
  navs,
17
18
  selectedNav,
18
19
  setSelectedNav,
@@ -55,16 +55,19 @@ export const EventPanel: React.FC<EventPanelProps> = ({
55
55
  const defaultPillId = pillId(0);
56
56
 
57
57
  const gridColumns = [];
58
+
59
+ // chevron
58
60
  if (hasCollapse) {
59
61
  gridColumns.push("minmax(0, max-content)");
60
62
  }
63
+
64
+ // icon
61
65
  if (icon) {
62
66
  gridColumns.push("max-content");
63
67
  }
68
+
69
+ // title
64
70
  gridColumns.push("minmax(0, max-content)");
65
- if (subTitle) {
66
- gridColumns.push("minmax(0, max-content)");
67
- }
68
71
  gridColumns.push("auto");
69
72
  gridColumns.push("minmax(0, max-content)");
70
73
  gridColumns.push("minmax(0, max-content)");
@@ -1,4 +1,5 @@
1
1
  import clsx from "clsx";
2
+ import { FC, ReactNode } from "react";
2
3
  import { ApplicationIcons } from "../../../appearance/icons";
3
4
  import styles from "./EventRow.module.css";
4
5
 
@@ -6,12 +7,12 @@ interface EventRowProps {
6
7
  title: string;
7
8
  icon: string;
8
9
  className?: string | string[];
9
- children?: React.ReactNode | React.ReactNode[];
10
+ children?: ReactNode | ReactNode[];
10
11
  }
11
12
  /**
12
13
  * Renders the EventRow component.
13
14
  */
14
- export const EventRow: React.FC<EventRowProps> = ({
15
+ export const EventRow: FC<EventRowProps> = ({
15
16
  title,
16
17
  icon,
17
18
  className,
@@ -1,5 +1,5 @@
1
1
  import clsx from "clsx";
2
- import { ReactNode } from "react";
2
+ import { FC, ReactNode } from "react";
3
3
  import styles from "./EventSection.module.css";
4
4
 
5
5
  interface EventSectionProps {
@@ -11,7 +11,7 @@ interface EventSectionProps {
11
11
  /**
12
12
  * Renders the Event Section component.
13
13
  */
14
- export const EventSection: React.FC<EventSectionProps> = ({
14
+ export const EventSection: FC<EventSectionProps> = ({
15
15
  title,
16
16
  children,
17
17
  className,
@@ -0,0 +1,28 @@
1
+ .wrapper {
2
+ display: grid;
3
+ grid-template-columns: 0 auto auto;
4
+ column-gap: 1.5em;
5
+ row-gap: 0.2em;
6
+ }
7
+
8
+ .col2 {
9
+ grid-column: 2;
10
+ }
11
+
12
+ .col1_3 {
13
+ grid-column: 1/3;
14
+ }
15
+
16
+ .col3 {
17
+ grid-column: 3;
18
+ }
19
+
20
+ .separator {
21
+ grid-column: -1/1;
22
+ height: 1px;
23
+ background-color: var(--bs-light-border-subtle);
24
+ }
25
+
26
+ .topMargin {
27
+ margin-top: 1em;
28
+ }