inspect-ai 0.3.81__py3-none-any.whl → 0.3.83__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 (297) hide show
  1. inspect_ai/__init__.py +2 -1
  2. inspect_ai/_cli/eval.py +35 -2
  3. inspect_ai/_cli/util.py +44 -1
  4. inspect_ai/_display/core/config.py +1 -1
  5. inspect_ai/_display/core/display.py +13 -4
  6. inspect_ai/_display/core/results.py +1 -1
  7. inspect_ai/_display/textual/app.py +14 -3
  8. inspect_ai/_display/textual/display.py +4 -0
  9. inspect_ai/_display/textual/widgets/samples.py +9 -3
  10. inspect_ai/_display/textual/widgets/task_detail.py +8 -8
  11. inspect_ai/_display/textual/widgets/tasks.py +17 -1
  12. inspect_ai/_display/textual/widgets/vscode.py +44 -0
  13. inspect_ai/_eval/eval.py +74 -25
  14. inspect_ai/_eval/evalset.py +22 -18
  15. inspect_ai/_eval/loader.py +34 -11
  16. inspect_ai/_eval/run.py +13 -15
  17. inspect_ai/_eval/score.py +13 -3
  18. inspect_ai/_eval/task/generate.py +8 -9
  19. inspect_ai/_eval/task/log.py +55 -6
  20. inspect_ai/_eval/task/run.py +51 -10
  21. inspect_ai/_eval/task/task.py +23 -9
  22. inspect_ai/_util/constants.py +2 -0
  23. inspect_ai/_util/file.py +30 -1
  24. inspect_ai/_util/json.py +37 -1
  25. inspect_ai/_util/registry.py +1 -0
  26. inspect_ai/_util/vscode.py +37 -0
  27. inspect_ai/_view/server.py +113 -1
  28. inspect_ai/_view/www/App.css +7 -1
  29. inspect_ai/_view/www/dist/assets/index.css +813 -415
  30. inspect_ai/_view/www/dist/assets/index.js +54475 -32003
  31. inspect_ai/_view/www/eslint.config.mjs +1 -1
  32. inspect_ai/_view/www/log-schema.json +137 -31
  33. inspect_ai/_view/www/node_modules/flatted/python/flatted.py +149 -0
  34. inspect_ai/_view/www/package.json +11 -2
  35. inspect_ai/_view/www/src/App.tsx +161 -853
  36. inspect_ai/_view/www/src/api/api-browser.ts +176 -5
  37. inspect_ai/_view/www/src/api/api-vscode.ts +75 -1
  38. inspect_ai/_view/www/src/api/client-api.ts +66 -10
  39. inspect_ai/_view/www/src/api/jsonrpc.ts +2 -0
  40. inspect_ai/_view/www/src/api/types.ts +107 -2
  41. inspect_ai/_view/www/src/appearance/icons.ts +2 -0
  42. inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +3 -3
  43. inspect_ai/_view/www/src/components/Card.tsx +6 -4
  44. inspect_ai/_view/www/src/components/DownloadPanel.tsx +2 -2
  45. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +56 -61
  46. inspect_ai/_view/www/src/components/FindBand.tsx +17 -9
  47. inspect_ai/_view/www/src/components/HumanBaselineView.tsx +1 -1
  48. inspect_ai/_view/www/src/components/JsonPanel.tsx +14 -24
  49. inspect_ai/_view/www/src/components/LargeModal.tsx +2 -35
  50. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +27 -11
  51. inspect_ai/_view/www/src/components/LinkButton.module.css +16 -0
  52. inspect_ai/_view/www/src/components/LinkButton.tsx +33 -0
  53. inspect_ai/_view/www/src/components/LiveVirtualList.module.css +11 -0
  54. inspect_ai/_view/www/src/components/LiveVirtualList.tsx +177 -0
  55. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +116 -26
  56. inspect_ai/_view/www/src/components/MessageBand.tsx +14 -9
  57. inspect_ai/_view/www/src/components/Modal.module.css +38 -0
  58. inspect_ai/_view/www/src/components/Modal.tsx +77 -0
  59. inspect_ai/_view/www/src/components/MorePopOver.tsx +3 -3
  60. inspect_ai/_view/www/src/components/NavPills.tsx +20 -8
  61. inspect_ai/_view/www/src/components/NoContentsPanel.module.css +12 -0
  62. inspect_ai/_view/www/src/components/NoContentsPanel.tsx +20 -0
  63. inspect_ai/_view/www/src/components/ProgressBar.module.css +5 -4
  64. inspect_ai/_view/www/src/components/ProgressBar.tsx +3 -2
  65. inspect_ai/_view/www/src/components/PulsingDots.module.css +81 -0
  66. inspect_ai/_view/www/src/components/PulsingDots.tsx +45 -0
  67. inspect_ai/_view/www/src/components/TabSet.tsx +4 -37
  68. inspect_ai/_view/www/src/components/ToolButton.tsx +3 -4
  69. inspect_ai/_view/www/src/index.tsx +26 -94
  70. inspect_ai/_view/www/src/logfile/remoteLogFile.ts +9 -1
  71. inspect_ai/_view/www/src/logfile/remoteZipFile.ts +30 -4
  72. inspect_ai/_view/www/src/metadata/RenderedContent.tsx +4 -6
  73. inspect_ai/_view/www/src/plan/DetailStep.module.css +4 -0
  74. inspect_ai/_view/www/src/plan/DetailStep.tsx +6 -3
  75. inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +1 -1
  76. inspect_ai/_view/www/src/plan/SolverDetailView.module.css +2 -1
  77. inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +9 -1
  78. inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +74 -28
  79. inspect_ai/_view/www/src/samples/SampleDialog.tsx +58 -22
  80. inspect_ai/_view/www/src/samples/SampleDisplay.module.css +4 -0
  81. inspect_ai/_view/www/src/samples/SampleDisplay.tsx +135 -104
  82. inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +10 -0
  83. inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +83 -36
  84. inspect_ai/_view/www/src/samples/SamplesTools.tsx +35 -30
  85. inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +2 -1
  86. inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +1 -1
  87. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +45 -53
  88. inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +6 -1
  89. inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +5 -0
  90. inspect_ai/_view/www/src/samples/chat/messages.ts +36 -0
  91. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.module.css +3 -0
  92. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +11 -1
  93. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +22 -46
  94. inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +34 -20
  95. inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.module.css +3 -3
  96. inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.tsx +1 -1
  97. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.module.css +4 -4
  98. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +10 -10
  99. inspect_ai/_view/www/src/samples/descriptor/types.ts +6 -5
  100. inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +22 -3
  101. inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +27 -2
  102. inspect_ai/_view/www/src/samples/list/SampleList.tsx +122 -85
  103. inspect_ai/_view/www/src/samples/list/SampleRow.module.css +6 -0
  104. inspect_ai/_view/www/src/samples/list/SampleRow.tsx +28 -15
  105. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +29 -18
  106. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +28 -28
  107. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +19 -9
  108. inspect_ai/_view/www/src/samples/sampleDataAdapter.ts +33 -0
  109. inspect_ai/_view/www/src/samples/sampleLimit.ts +2 -2
  110. inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +12 -27
  111. inspect_ai/_view/www/src/samples/scores/SampleScoresGrid.module.css +38 -0
  112. inspect_ai/_view/www/src/samples/scores/SampleScoresGrid.tsx +118 -0
  113. inspect_ai/_view/www/src/samples/scores/{SampleScoreView.module.css → SampleScoresView.module.css} +10 -1
  114. inspect_ai/_view/www/src/samples/scores/SampleScoresView.tsx +78 -0
  115. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +0 -13
  116. inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +0 -13
  117. inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +0 -13
  118. inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +4 -0
  119. inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +10 -24
  120. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +0 -13
  121. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +4 -22
  122. inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +15 -24
  123. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +0 -13
  124. inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +6 -28
  125. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +24 -34
  126. inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +4 -0
  127. inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +33 -17
  128. inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +197 -338
  129. inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.module.css +16 -0
  130. inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.tsx +44 -0
  131. inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +7 -4
  132. inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +81 -60
  133. inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.module.css +23 -0
  134. inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.tsx +27 -0
  135. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +29 -1
  136. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +102 -72
  137. inspect_ai/_view/www/src/scoring/utils.ts +87 -0
  138. inspect_ai/_view/www/src/state/appSlice.ts +244 -0
  139. inspect_ai/_view/www/src/state/hooks.ts +399 -0
  140. inspect_ai/_view/www/src/state/logPolling.ts +200 -0
  141. inspect_ai/_view/www/src/state/logSlice.ts +224 -0
  142. inspect_ai/_view/www/src/state/logsPolling.ts +118 -0
  143. inspect_ai/_view/www/src/state/logsSlice.ts +181 -0
  144. inspect_ai/_view/www/src/state/samplePolling.ts +314 -0
  145. inspect_ai/_view/www/src/state/sampleSlice.ts +140 -0
  146. inspect_ai/_view/www/src/state/sampleUtils.ts +21 -0
  147. inspect_ai/_view/www/src/state/scrolling.ts +206 -0
  148. inspect_ai/_view/www/src/state/store.ts +168 -0
  149. inspect_ai/_view/www/src/state/store_filter.ts +84 -0
  150. inspect_ai/_view/www/src/state/utils.ts +23 -0
  151. inspect_ai/_view/www/src/storage/index.ts +26 -0
  152. inspect_ai/_view/www/src/types/log.d.ts +36 -26
  153. inspect_ai/_view/www/src/types/markdown-it-katex.d.ts +21 -0
  154. inspect_ai/_view/www/src/types.ts +94 -32
  155. inspect_ai/_view/www/src/utils/attachments.ts +58 -23
  156. inspect_ai/_view/www/src/utils/json-worker.ts +79 -12
  157. inspect_ai/_view/www/src/utils/logger.ts +52 -0
  158. inspect_ai/_view/www/src/utils/polling.ts +100 -0
  159. inspect_ai/_view/www/src/utils/react.ts +30 -0
  160. inspect_ai/_view/www/src/utils/vscode.ts +1 -1
  161. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +184 -217
  162. inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +11 -53
  163. inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +8 -18
  164. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +1 -0
  165. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +40 -22
  166. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +16 -1
  167. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +159 -103
  168. inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.module.css +32 -0
  169. inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.tsx +32 -0
  170. inspect_ai/_view/www/src/workspace/navbar/ScoreGrid.module.css +35 -0
  171. inspect_ai/_view/www/src/workspace/navbar/ScoreGrid.tsx +117 -0
  172. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +12 -14
  173. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +6 -2
  174. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +4 -4
  175. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.module.css +3 -2
  176. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +28 -13
  177. inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +5 -10
  178. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +4 -4
  179. inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.module.css +22 -0
  180. inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.tsx +19 -0
  181. inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +128 -115
  182. inspect_ai/_view/www/src/workspace/tabs/grouping.ts +37 -5
  183. inspect_ai/_view/www/src/workspace/tabs/types.ts +4 -0
  184. inspect_ai/_view/www/src/workspace/types.ts +4 -3
  185. inspect_ai/_view/www/src/workspace/utils.ts +4 -4
  186. inspect_ai/_view/www/vite.config.js +6 -0
  187. inspect_ai/_view/www/yarn.lock +464 -355
  188. inspect_ai/agent/__init__.py +36 -0
  189. inspect_ai/agent/_agent.py +268 -0
  190. inspect_ai/agent/_as_solver.py +72 -0
  191. inspect_ai/agent/_as_tool.py +122 -0
  192. inspect_ai/{solver → agent}/_bridge/bridge.py +23 -37
  193. inspect_ai/{solver → agent}/_bridge/patch.py +9 -8
  194. inspect_ai/agent/_filter.py +46 -0
  195. inspect_ai/agent/_handoff.py +93 -0
  196. inspect_ai/{solver/_human_agent → agent/_human}/agent.py +11 -12
  197. inspect_ai/{solver/_human_agent → agent/_human}/commands/__init__.py +2 -3
  198. inspect_ai/{solver/_human_agent → agent/_human}/commands/clock.py +3 -1
  199. inspect_ai/{solver/_human_agent → agent/_human}/commands/score.py +5 -5
  200. inspect_ai/{solver/_human_agent → agent/_human}/install.py +6 -3
  201. inspect_ai/{solver/_human_agent → agent/_human}/service.py +7 -3
  202. inspect_ai/{solver/_human_agent → agent/_human}/state.py +5 -5
  203. inspect_ai/agent/_react.py +241 -0
  204. inspect_ai/agent/_run.py +36 -0
  205. inspect_ai/agent/_types.py +81 -0
  206. inspect_ai/log/_condense.py +26 -0
  207. inspect_ai/log/_log.py +17 -5
  208. inspect_ai/log/_recorders/buffer/__init__.py +14 -0
  209. inspect_ai/log/_recorders/buffer/buffer.py +30 -0
  210. inspect_ai/log/_recorders/buffer/database.py +685 -0
  211. inspect_ai/log/_recorders/buffer/filestore.py +259 -0
  212. inspect_ai/log/_recorders/buffer/types.py +84 -0
  213. inspect_ai/log/_recorders/eval.py +2 -11
  214. inspect_ai/log/_recorders/types.py +30 -0
  215. inspect_ai/log/_transcript.py +32 -2
  216. inspect_ai/model/__init__.py +7 -1
  217. inspect_ai/model/_call_tools.py +257 -52
  218. inspect_ai/model/_chat_message.py +7 -4
  219. inspect_ai/model/_conversation.py +13 -62
  220. inspect_ai/model/_display.py +85 -0
  221. inspect_ai/model/_generate_config.py +2 -2
  222. inspect_ai/model/_model.py +114 -14
  223. inspect_ai/model/_model_output.py +14 -9
  224. inspect_ai/model/_openai.py +16 -4
  225. inspect_ai/model/_openai_computer_use.py +162 -0
  226. inspect_ai/model/_openai_responses.py +319 -165
  227. inspect_ai/model/_providers/anthropic.py +20 -21
  228. inspect_ai/model/_providers/azureai.py +24 -13
  229. inspect_ai/model/_providers/bedrock.py +1 -7
  230. inspect_ai/model/_providers/cloudflare.py +3 -3
  231. inspect_ai/model/_providers/goodfire.py +2 -6
  232. inspect_ai/model/_providers/google.py +11 -10
  233. inspect_ai/model/_providers/groq.py +6 -3
  234. inspect_ai/model/_providers/hf.py +7 -3
  235. inspect_ai/model/_providers/mistral.py +7 -10
  236. inspect_ai/model/_providers/openai.py +47 -17
  237. inspect_ai/model/_providers/openai_o1.py +11 -4
  238. inspect_ai/model/_providers/openai_responses.py +12 -14
  239. inspect_ai/model/_providers/providers.py +2 -2
  240. inspect_ai/model/_providers/together.py +12 -2
  241. inspect_ai/model/_providers/util/chatapi.py +7 -2
  242. inspect_ai/model/_providers/util/hf_handler.py +4 -2
  243. inspect_ai/model/_providers/util/llama31.py +4 -2
  244. inspect_ai/model/_providers/vertex.py +11 -9
  245. inspect_ai/model/_providers/vllm.py +4 -4
  246. inspect_ai/scorer/__init__.py +2 -0
  247. inspect_ai/scorer/_metrics/__init__.py +2 -0
  248. inspect_ai/scorer/_metrics/grouped.py +84 -0
  249. inspect_ai/scorer/_score.py +26 -6
  250. inspect_ai/solver/__init__.py +2 -2
  251. inspect_ai/solver/_basic_agent.py +22 -9
  252. inspect_ai/solver/_bridge.py +31 -0
  253. inspect_ai/solver/_chain.py +20 -12
  254. inspect_ai/solver/_fork.py +5 -1
  255. inspect_ai/solver/_human_agent.py +52 -0
  256. inspect_ai/solver/_prompt.py +3 -1
  257. inspect_ai/solver/_run.py +59 -0
  258. inspect_ai/solver/_solver.py +14 -4
  259. inspect_ai/solver/_task_state.py +5 -3
  260. inspect_ai/tool/_tool_call.py +15 -8
  261. inspect_ai/tool/_tool_def.py +17 -12
  262. inspect_ai/tool/_tool_support_helpers.py +4 -4
  263. inspect_ai/tool/_tool_with.py +14 -11
  264. inspect_ai/tool/_tools/_bash_session.py +11 -2
  265. inspect_ai/tool/_tools/_computer/_common.py +18 -2
  266. inspect_ai/tool/_tools/_computer/_computer.py +18 -2
  267. inspect_ai/tool/_tools/_computer/_resources/tool/_constants.py +2 -0
  268. inspect_ai/tool/_tools/_computer/_resources/tool/_x11_client.py +17 -0
  269. inspect_ai/tool/_tools/_think.py +1 -1
  270. inspect_ai/tool/_tools/_web_browser/_web_browser.py +103 -62
  271. inspect_ai/util/__init__.py +2 -0
  272. inspect_ai/util/_anyio.py +27 -0
  273. inspect_ai/util/_sandbox/__init__.py +2 -1
  274. inspect_ai/util/_sandbox/context.py +32 -7
  275. inspect_ai/util/_sandbox/docker/cleanup.py +4 -0
  276. inspect_ai/util/_sandbox/docker/compose.py +2 -2
  277. inspect_ai/util/_sandbox/docker/docker.py +12 -1
  278. inspect_ai/util/_store_model.py +30 -7
  279. inspect_ai/util/_subprocess.py +13 -3
  280. inspect_ai/util/_subtask.py +1 -0
  281. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/METADATA +1 -1
  282. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/RECORD +295 -229
  283. inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +0 -169
  284. inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +0 -22
  285. /inspect_ai/{solver → agent}/_bridge/__init__.py +0 -0
  286. /inspect_ai/{solver/_human_agent → agent/_human}/__init__.py +0 -0
  287. /inspect_ai/{solver/_human_agent → agent/_human}/commands/command.py +0 -0
  288. /inspect_ai/{solver/_human_agent → agent/_human}/commands/instructions.py +0 -0
  289. /inspect_ai/{solver/_human_agent → agent/_human}/commands/note.py +0 -0
  290. /inspect_ai/{solver/_human_agent → agent/_human}/commands/status.py +0 -0
  291. /inspect_ai/{solver/_human_agent → agent/_human}/commands/submit.py +0 -0
  292. /inspect_ai/{solver/_human_agent → agent/_human}/panel.py +0 -0
  293. /inspect_ai/{solver/_human_agent → agent/_human}/view.py +0 -0
  294. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/WHEEL +0 -0
  295. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/entry_points.txt +0 -0
  296. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/licenses/LICENSE +0 -0
  297. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,32 @@
1
+ .statusContainer {
2
+ display: inline-block;
3
+ margin-top: 0.3em;
4
+ }
5
+
6
+ .status {
7
+ display: grid;
8
+ grid-template-columns: auto auto;
9
+ }
10
+
11
+ .statusText {
12
+ margin-top: 0.2em;
13
+ }
14
+
15
+ .metricsRows {
16
+ margin-top: 0.3em;
17
+ margin-left: 1.25em;
18
+ display: grid;
19
+ grid-template-columns: auto auto;
20
+ grid-template-rows: auto;
21
+ column-gap: 0.5em;
22
+ }
23
+
24
+ .icon {
25
+ font-size: var(--inspect-font-size-large);
26
+ margin-right: 0.3em;
27
+ margin-top: -0.1em;
28
+ }
29
+
30
+ .value {
31
+ font-weight: 600;
32
+ }
@@ -0,0 +1,32 @@
1
+ import clsx from "clsx";
2
+ import { RunningMetric } from "../../api/types";
3
+ import { ApplicationIcons } from "../../appearance/icons";
4
+
5
+ import { FC } from "react";
6
+ import styles from "./RunningStatusPanel.module.css";
7
+
8
+ export interface RunningPanelProps {
9
+ sampleCount: number;
10
+ displayMetrics?: RunningMetric[];
11
+ }
12
+
13
+ export const RunningStatusPanel: FC<RunningPanelProps> = ({ sampleCount }) => {
14
+ return (
15
+ <div>
16
+ <div className={clsx(styles.statusContainer)}>
17
+ <div className={clsx(styles.status)}>
18
+ <i className={clsx(ApplicationIcons.running, styles.icon)} />
19
+ <div
20
+ className={clsx(
21
+ styles.statusText,
22
+ "text-style-label",
23
+ "text-size-smaller",
24
+ )}
25
+ >
26
+ Running ({sampleCount} samples)
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ );
32
+ };
@@ -0,0 +1,35 @@
1
+ .table {
2
+ margin-bottom: 0;
3
+ }
4
+
5
+ .scorer,
6
+ .value {
7
+ padding-top: 0.2em !important;
8
+ padding-bottom: 0.2em !important;
9
+ }
10
+
11
+ .label,
12
+ .value {
13
+ text-align: center;
14
+ padding-left: 1em;
15
+ padding-right: 1em;
16
+ }
17
+
18
+ .label {
19
+ font-weight: 400;
20
+ padding-left: 1em;
21
+ padding-right: 1em;
22
+ }
23
+
24
+ .scorer {
25
+ font-weight: 400;
26
+ }
27
+
28
+ .groupSeparator {
29
+ padding-top: 2em;
30
+ border-bottom: hidden;
31
+ }
32
+
33
+ .tableBody {
34
+ border-top-color: var(--bs-light-border-subtle);
35
+ }
@@ -0,0 +1,117 @@
1
+ import clsx from "clsx";
2
+ import { FC, ReactNode } from "react";
3
+ import { formatPrettyDecimal } from "../../utils/format";
4
+ import { ResultsScorer } from "./ResultsPanel";
5
+
6
+ import styles from "./ScoreGrid.module.css";
7
+
8
+ interface ScoreGridProps {
9
+ scoreGroups: ResultsScorer[][];
10
+ showReducer?: boolean;
11
+ className?: string | string[];
12
+ striped?: boolean;
13
+ }
14
+
15
+ export const ScoreGrid: FC<ScoreGridProps> = ({
16
+ scoreGroups,
17
+ showReducer,
18
+ className,
19
+ striped,
20
+ }) => {
21
+ const columnCount = scoreGroups.reduce((prev, group) => {
22
+ return Math.max(prev, group[0].metrics.length);
23
+ }, 0);
24
+
25
+ const subTables: ReactNode[] = [];
26
+
27
+ let index = 0;
28
+ for (const scoreGroup of scoreGroups) {
29
+ const metrics = scoreGroup[0].metrics;
30
+
31
+ // Add header row
32
+
33
+ const cells: ReactNode[] = [];
34
+ for (let i = 0; i < columnCount; i++) {
35
+ if (metrics.length > i) {
36
+ cells.push(
37
+ <th
38
+ className={clsx(
39
+ "text-style-label",
40
+ "text-style-secondary",
41
+ "text-size-small",
42
+ styles.label,
43
+ )}
44
+ >
45
+ {metrics[i].name}
46
+ </th>,
47
+ );
48
+ } else {
49
+ cells.push(<td></td>);
50
+ }
51
+ }
52
+
53
+ const headerRow = (
54
+ <tr className={clsx(styles.headerRow)}>
55
+ <td></td>
56
+ {cells}
57
+ </tr>
58
+ );
59
+ const rows: ReactNode[] = [];
60
+ scoreGroup.forEach((g) => {
61
+ const cells: ReactNode[] = [];
62
+ for (let i = 0; i < columnCount; i++) {
63
+ if (metrics.length > i) {
64
+ cells.push(
65
+ <td className={clsx(styles.value, "text-size-small")}>
66
+ {formatPrettyDecimal(g.metrics[i].value)}
67
+ </td>,
68
+ );
69
+ } else {
70
+ cells.push(<td className={clsx(styles.value)}></td>);
71
+ }
72
+ }
73
+
74
+ rows.push(
75
+ <tr>
76
+ <th className={clsx(styles.scorer, "text-size-small")}>
77
+ {g.scorer} {showReducer && g.reducer ? `(${g.reducer})` : undefined}
78
+ </th>
79
+ {cells}
80
+ </tr>,
81
+ );
82
+ });
83
+
84
+ subTables.push(
85
+ <>
86
+ {index > 0 ? (
87
+ <tr>
88
+ <td
89
+ colSpan={columnCount + 1}
90
+ className={clsx(styles.groupSeparator)}
91
+ ></td>
92
+ </tr>
93
+ ) : undefined}
94
+ {headerRow}
95
+ <tbody className={clsx("table-group-divider", styles.tableBody)}>
96
+ {rows}
97
+ </tbody>
98
+ </>,
99
+ );
100
+
101
+ index++;
102
+ }
103
+
104
+ return (
105
+ <table
106
+ className={clsx(
107
+ className,
108
+ "table",
109
+ striped ? "table-striped" : undefined,
110
+ styles.table,
111
+ "table-bordered",
112
+ )}
113
+ >
114
+ {subTables}
115
+ </table>
116
+ );
117
+ };
@@ -1,10 +1,10 @@
1
1
  import clsx from "clsx";
2
2
  import { FC } from "react";
3
- import { SampleSummary } from "../../api/types";
4
3
  import { ExpandablePanel } from "../../components/ExpandablePanel";
5
4
  import { LabeledValue } from "../../components/LabeledValue";
6
5
  import { EvalDescriptor } from "../../samples/descriptor/types";
7
6
  import { scoreFilterItems } from "../../samples/sample-tools/filters";
7
+ import { useEvalDescriptor } from "../../state/hooks";
8
8
  import {
9
9
  EvalDataset,
10
10
  EvalPlan,
@@ -20,9 +20,8 @@ interface SecondaryBarProps {
20
20
  evalPlan?: EvalPlan;
21
21
  evalResults?: EvalResults;
22
22
  evalStats?: EvalStats;
23
- evalDescriptor?: EvalDescriptor;
24
- samples?: SampleSummary[];
25
23
  status?: string;
24
+ sampleCount?: number;
26
25
  }
27
26
 
28
27
  /**
@@ -33,10 +32,10 @@ export const SecondaryBar: FC<SecondaryBarProps> = ({
33
32
  evalPlan,
34
33
  evalResults,
35
34
  evalStats,
36
- samples,
37
- evalDescriptor,
38
35
  status,
36
+ sampleCount,
39
37
  }) => {
38
+ const evalDescriptor = useEvalDescriptor();
40
39
  if (!evalSpec || status !== "success") {
41
40
  return null;
42
41
  }
@@ -56,11 +55,11 @@ export const SecondaryBar: FC<SecondaryBarProps> = ({
56
55
  <LabeledValue
57
56
  key="sb-dataset"
58
57
  label="Dataset"
59
- className={(styles.staticCol, "text-size-small")}
58
+ className={clsx(styles.staticCol, "text-size-small")}
60
59
  >
61
60
  <DatasetSummary
62
61
  dataset={evalSpec.dataset}
63
- samples={samples}
62
+ sampleCount={sampleCount}
64
63
  epochs={epochs}
65
64
  />
66
65
  </LabeledValue>
@@ -122,9 +121,10 @@ export const SecondaryBar: FC<SecondaryBarProps> = ({
122
121
 
123
122
  return (
124
123
  <ExpandablePanel
124
+ id={"secondary-nav-bar"}
125
125
  className={clsx(styles.container, "text-size-small")}
126
126
  collapse={true}
127
- lines={4}
127
+ lines={5}
128
128
  >
129
129
  <div
130
130
  className={styles.valueGrid}
@@ -146,16 +146,16 @@ export const SecondaryBar: FC<SecondaryBarProps> = ({
146
146
 
147
147
  interface DatasetSummaryProps {
148
148
  dataset?: EvalDataset;
149
- samples?: SampleSummary[];
150
149
  epochs: number;
150
+ sampleCount?: number;
151
151
  }
152
152
 
153
153
  /**
154
154
  * A component that displays the dataset
155
155
  */
156
156
  const DatasetSummary: FC<DatasetSummaryProps> = ({
157
+ sampleCount,
157
158
  dataset,
158
- samples,
159
159
  epochs,
160
160
  }) => {
161
161
  if (!dataset) {
@@ -164,15 +164,13 @@ const DatasetSummary: FC<DatasetSummaryProps> = ({
164
164
 
165
165
  return (
166
166
  <div>
167
- {samples?.length
168
- ? formatDataset(samples.length, epochs, dataset.name)
169
- : ""}
167
+ {sampleCount ? formatDataset(sampleCount, epochs, dataset.name) : ""}
170
168
  </div>
171
169
  );
172
170
  };
173
171
 
174
172
  interface ScoreSummaryProps {
175
- evalDescriptor?: EvalDescriptor;
173
+ evalDescriptor?: EvalDescriptor | null;
176
174
  }
177
175
 
178
176
  /**
@@ -37,13 +37,17 @@ export const RunningPanel: FC<StatusProps> = ({ sampleCount }) => {
37
37
  );
38
38
  };
39
39
 
40
- interface StatusPanelProps {
40
+ export interface StatusPanelProps {
41
41
  icon: string;
42
42
  status: string;
43
43
  sampleCount: number;
44
44
  }
45
45
 
46
- const StatusPanel: FC<StatusPanelProps> = ({ icon, status, sampleCount }) => {
46
+ export const StatusPanel: FC<StatusPanelProps> = ({
47
+ icon,
48
+ status,
49
+ sampleCount,
50
+ }) => {
47
51
  return (
48
52
  <div className={styles.statusPanel}>
49
53
  <i className={clsx(icon, styles.statusIcon)} style={{}} />
@@ -1,16 +1,16 @@
1
1
  import clsx from "clsx";
2
2
  import { FC } from "react";
3
+ import { useStore } from "../../state/store";
3
4
  import styles from "./LogDirectoryTitleView.module.css";
4
5
 
5
6
  interface LogDirectoryTitleViewProps {
6
7
  log_dir?: string;
7
- offcanvas: boolean;
8
8
  }
9
9
 
10
10
  export const LogDirectoryTitleView: FC<LogDirectoryTitleViewProps> = ({
11
11
  log_dir,
12
- offcanvas,
13
12
  }) => {
13
+ const offCanvas = useStore((state) => state.app.offcanvas);
14
14
  if (log_dir) {
15
15
  const displayDir = prettyDir(log_dir);
16
16
  return (
@@ -28,14 +28,14 @@ export const LogDirectoryTitleView: FC<LogDirectoryTitleViewProps> = ({
28
28
  title={displayDir}
29
29
  className={clsx("text-size-base", styles.dirname)}
30
30
  >
31
- {offcanvas ? displayDir : ""}
31
+ {offCanvas ? displayDir : ""}
32
32
  </span>
33
33
  </div>
34
34
  );
35
35
  } else {
36
36
  return (
37
37
  <span className={clsx("text-size-title")}>
38
- {offcanvas ? "Log History" : ""}
38
+ {offCanvas ? "Log History" : ""}
39
39
  </span>
40
40
  );
41
41
  }
@@ -54,8 +54,9 @@
54
54
 
55
55
  .backdrop {
56
56
  position: fixed;
57
- inset: 0; /* top: 0; left: 0; right: 0; bottom: 0; */
58
- background-color: rgba(0, 0, 0, 0.5);
57
+ inset: 0;
58
+ background-color: var(--inspect-glass-color);
59
+ opacity: var(--inspect-glass-opacity);
59
60
  z-index: 9998;
60
61
  }
61
62
 
@@ -1,9 +1,11 @@
1
1
  import clsx from "clsx";
2
- import { FC } from "react";
2
+ import { FC, MouseEvent, useCallback, useRef } from "react";
3
3
  import { Fragment } from "react/jsx-runtime";
4
4
  import { EvalLogHeader, LogFiles } from "../../api/types";
5
5
  import { ApplicationIcons } from "../../appearance/icons";
6
6
  import { ProgressBar } from "../../components/ProgressBar";
7
+ import { useStatefulScrollPosition } from "../../state/scrolling";
8
+ import { useStore } from "../../state/store";
7
9
  import { LogDirectoryTitleView } from "./LogDirectoryTitleView";
8
10
  import styles from "./Sidebar.module.css";
9
11
  import { SidebarLogEntry } from "./SidebarLogEntry";
@@ -11,8 +13,6 @@ import { SidebarLogEntry } from "./SidebarLogEntry";
11
13
  interface SidebarProps {
12
14
  logs: LogFiles;
13
15
  logHeaders: Record<string, EvalLogHeader>;
14
- offcanvas: boolean;
15
- setOffcanvas: (offcanvas: boolean) => void;
16
16
  loading: boolean;
17
17
  selectedIndex: number;
18
18
  onSelectedIndexChanged: (index: number) => void;
@@ -21,29 +21,40 @@ interface SidebarProps {
21
21
  export const Sidebar: FC<SidebarProps> = ({
22
22
  logs,
23
23
  logHeaders,
24
- offcanvas,
25
- setOffcanvas,
26
24
  loading,
27
25
  selectedIndex,
28
26
  onSelectedIndexChanged,
29
27
  }) => {
30
- const handleToggle = () => {
31
- setOffcanvas(!offcanvas);
32
- };
28
+ const setOffCanvas = useStore((state) => state.appActions.setOffcanvas);
29
+ const offCanvas = useStore((state) => state.app.offcanvas);
30
+ const handleToggle = useCallback(() => {
31
+ setOffCanvas(!offCanvas);
32
+ }, [offCanvas, setOffCanvas]);
33
+
34
+ const sidebarContentsRef = useRef(null);
35
+ useStatefulScrollPosition(sidebarContentsRef, "sidebar-contents", 1000);
36
+
37
+ const handleClick = useCallback(
38
+ (e: MouseEvent<HTMLLIElement>) => {
39
+ const index = Number((e.currentTarget as HTMLLIElement).dataset.index);
40
+ onSelectedIndexChanged(index);
41
+ },
42
+ [onSelectedIndexChanged],
43
+ );
33
44
 
34
45
  return (
35
46
  <Fragment>
36
47
  {/* Optional backdrop for small screens, appears only when offcanvas is open */}
37
- {offcanvas && <div className={styles.backdrop} onClick={handleToggle} />}
48
+ {offCanvas && <div className={styles.backdrop} onClick={handleToggle} />}
38
49
 
39
50
  <div
40
51
  className={clsx(
41
52
  styles.sidebar,
42
- offcanvas ? styles.sidebarOpen : styles.sidebarClosed,
53
+ offCanvas ? styles.sidebarOpen : styles.sidebarClosed,
43
54
  )}
44
55
  >
45
56
  <div className={styles.header}>
46
- <LogDirectoryTitleView log_dir={logs.log_dir} offcanvas={offcanvas} />
57
+ <LogDirectoryTitleView log_dir={logs.log_dir} />
47
58
  <button
48
59
  onClick={handleToggle}
49
60
  className={clsx("btn", styles.toggle)}
@@ -58,7 +69,10 @@ export const Sidebar: FC<SidebarProps> = ({
58
69
  <ProgressBar animating={loading} />
59
70
  </div>
60
71
 
61
- <ul className={clsx("list-group", styles.list)}>
72
+ <ul
73
+ ref={sidebarContentsRef}
74
+ className={clsx("list-group", styles.list)}
75
+ >
62
76
  {logs.files.map((file, index) => {
63
77
  const logHeader = logHeaders[file.name];
64
78
  return (
@@ -70,7 +84,8 @@ export const Sidebar: FC<SidebarProps> = ({
70
84
  styles.item,
71
85
  selectedIndex === index ? styles.active : undefined,
72
86
  )}
73
- onClick={() => onSelectedIndexChanged(index)}
87
+ data-index={index}
88
+ onClick={handleClick}
74
89
  >
75
90
  <SidebarLogEntry
76
91
  logHeader={logHeader}
@@ -1,4 +1,4 @@
1
- import { FC, useEffect, useState } from "react";
1
+ import { FC } from "react";
2
2
  import { SampleSummary } from "../../api/types";
3
3
  import { MessageBand } from "../../components/MessageBand";
4
4
  import { PlanCard } from "../../plan/PlanCard";
@@ -20,6 +20,7 @@ interface PlanTabProps {
20
20
  samples?: SampleSummary[];
21
21
  evalStatus?: "started" | "error" | "cancelled" | "success";
22
22
  evalError?: EvalError;
23
+ sampleCount?: number;
23
24
  }
24
25
 
25
26
  export const InfoTab: FC<PlanTabProps> = ({
@@ -27,17 +28,12 @@ export const InfoTab: FC<PlanTabProps> = ({
27
28
  evalPlan,
28
29
  evalResults,
29
30
  evalStats,
30
- samples,
31
31
  evalStatus,
32
32
  evalError,
33
+ sampleCount,
33
34
  }) => {
34
- const [hidden, setHidden] = useState(false);
35
- useEffect(() => {
36
- setHidden(false);
37
- }, [evalSpec, evalPlan, evalResults, evalStats, samples]);
38
-
39
35
  const showWarning =
40
- (!samples || samples.length === 0) &&
36
+ sampleCount === 0 &&
41
37
  evalStatus === "success" &&
42
38
  evalSpec?.dataset.samples &&
43
39
  evalSpec.dataset.samples > 0;
@@ -46,9 +42,8 @@ export const InfoTab: FC<PlanTabProps> = ({
46
42
  <div style={{ width: "100%" }}>
47
43
  {showWarning ? (
48
44
  <MessageBand
45
+ id="sample-too-large"
49
46
  message="Unable to display samples (this evaluation log may be too large)."
50
- hidden={hidden}
51
- setHidden={setHidden}
52
47
  type="warning"
53
48
  />
54
49
  ) : (
@@ -1,16 +1,15 @@
1
1
  import { filename } from "../../utils/path";
2
2
 
3
3
  import { FC } from "react";
4
- import { Capabilities } from "../../api/types";
5
4
  import { DownloadPanel } from "../../components/DownloadPanel";
6
5
  import { JSONPanel } from "../../components/JsonPanel";
6
+ import { useStore } from "../../state/store";
7
7
  import styles from "./JsonTab.module.css";
8
8
 
9
9
  const kJsonMaxSize = 10000000;
10
10
 
11
11
  interface JsonTabProps {
12
12
  logFile?: string;
13
- capabilities: Capabilities;
14
13
  selected: boolean;
15
14
  json: string;
16
15
  }
@@ -18,8 +17,9 @@ interface JsonTabProps {
18
17
  /**
19
18
  * Renders JSON tab
20
19
  */
21
- export const JsonTab: FC<JsonTabProps> = ({ logFile, capabilities, json }) => {
22
- if (logFile && json.length > kJsonMaxSize && capabilities.downloadFiles) {
20
+ export const JsonTab: FC<JsonTabProps> = ({ logFile, json }) => {
21
+ const downloadFiles = useStore((state) => state.capabilities.downloadFiles);
22
+ if (logFile && json.length > kJsonMaxSize && downloadFiles) {
23
23
  // This JSON file is so large we can't really productively render it
24
24
  // we should instead just provide a DL link
25
25
  const file = `${filename(logFile)}.json`;
@@ -0,0 +1,22 @@
1
+ .panel {
2
+ width: 100%;
3
+ display: flex;
4
+ justify-content: center;
5
+ }
6
+
7
+ .container {
8
+ margin-top: 3em;
9
+ display: grid;
10
+ grid-template-columns: max-content max-content;
11
+ column-gap: 0.3em;
12
+ }
13
+
14
+ .spinner {
15
+ border-width: 1px;
16
+ height: 15px;
17
+ width: 15px;
18
+ }
19
+
20
+ .text {
21
+ margin-top: -2px;
22
+ }
@@ -0,0 +1,19 @@
1
+ import clsx from "clsx";
2
+ import { FC } from "react";
3
+
4
+ import styles from "./RunningNoSamples.module.css";
5
+
6
+ interface RunningNoSamplesProps {}
7
+
8
+ export const RunningNoSamples: FC<RunningNoSamplesProps> = () => {
9
+ return (
10
+ <div className={clsx(styles.panel)}>
11
+ <div className={clsx(styles.container, "text-size-smaller")}>
12
+ <div className={clsx(styles.spinner, "spinner-border")} role="status">
13
+ <span className={clsx("visually-hidden")}>starting...</span>
14
+ </div>
15
+ <div className={clsx(styles.text)}>starting....</div>
16
+ </div>
17
+ </div>
18
+ );
19
+ };