inspect-ai 0.3.90__py3-none-any.whl → 0.3.91__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 (370) hide show
  1. inspect_ai/_cli/common.py +13 -0
  2. inspect_ai/_cli/eval.py +40 -0
  3. inspect_ai/_display/textual/widgets/samples.py +49 -4
  4. inspect_ai/_display/textual/widgets/vscode.py +4 -2
  5. inspect_ai/_eval/eval.py +41 -28
  6. inspect_ai/_eval/evalset.py +4 -0
  7. inspect_ai/_eval/loader.py +4 -5
  8. inspect_ai/_eval/registry.py +1 -1
  9. inspect_ai/_eval/run.py +6 -3
  10. inspect_ai/_eval/task/log.py +6 -0
  11. inspect_ai/_eval/task/run.py +108 -41
  12. inspect_ai/_eval/task/sandbox.py +19 -5
  13. inspect_ai/_util/_async.py +1 -1
  14. inspect_ai/_util/constants.py +1 -0
  15. inspect_ai/_util/environ.py +32 -0
  16. inspect_ai/_util/file.py +8 -1
  17. inspect_ai/_util/httpx.py +105 -22
  18. inspect_ai/_util/registry.py +83 -9
  19. inspect_ai/_util/text.py +81 -17
  20. inspect_ai/_util/transcript.py +9 -6
  21. inspect_ai/_util/vscode.py +7 -2
  22. inspect_ai/_view/schema.py +1 -1
  23. inspect_ai/_view/www/babel.config.js +11 -0
  24. inspect_ai/_view/www/dist/assets/index.css +3640 -3563
  25. inspect_ai/_view/www/dist/assets/index.js +59204 -52519
  26. inspect_ai/_view/www/eslint.config.mjs +10 -1
  27. inspect_ai/_view/www/jest.config.mjs +21 -0
  28. inspect_ai/_view/www/log-schema.json +111 -2
  29. inspect_ai/_view/www/package.json +19 -5
  30. inspect_ai/_view/www/src/{types → @types}/log.d.ts +95 -32
  31. inspect_ai/_view/www/{App.css → src/app/App.css} +22 -14
  32. inspect_ai/_view/www/src/app/App.tsx +168 -0
  33. inspect_ai/_view/www/src/{AppErrorBoundary.tsx → app/AppErrorBoundary.tsx} +1 -1
  34. inspect_ai/_view/www/src/{appearance → app/appearance}/icons.ts +1 -0
  35. inspect_ai/_view/www/src/{metadata → app/content}/RenderedContent.tsx +5 -5
  36. inspect_ai/_view/www/src/{workspace/WorkSpaceView.tsx → app/log-view/LogView.tsx} +59 -40
  37. inspect_ai/_view/www/src/app/log-view/LogViewContainer.tsx +159 -0
  38. inspect_ai/_view/www/src/app/log-view/LogViewLayout.tsx +109 -0
  39. inspect_ai/_view/www/src/{workspace → app/log-view}/error/TaskErrorPanel.tsx +3 -3
  40. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/ModelRolesView.tsx +1 -1
  41. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/Navbar.tsx +4 -4
  42. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/PrimaryBar.tsx +8 -8
  43. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/ResultsPanel.tsx +6 -6
  44. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/RunningStatusPanel.tsx +1 -1
  45. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/ScoreGrid.tsx +1 -1
  46. inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/SecondaryBar.tsx +8 -8
  47. inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/InfoTab.tsx +35 -6
  48. inspect_ai/_view/www/src/app/log-view/tabs/JsonTab.tsx +136 -0
  49. inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/SamplesTab.tsx +82 -73
  50. inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/grouping.ts +3 -3
  51. inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/types.ts +1 -1
  52. inspect_ai/_view/www/src/{plan → app/plan}/DatasetDetailView.tsx +2 -2
  53. inspect_ai/_view/www/src/{plan → app/plan}/DetailStep.tsx +1 -1
  54. inspect_ai/_view/www/src/{plan → app/plan}/ModelCard.tsx +4 -4
  55. inspect_ai/_view/www/src/{plan → app/plan}/PlanCard.tsx +2 -2
  56. inspect_ai/_view/www/src/{plan → app/plan}/PlanDetailView.tsx +5 -5
  57. inspect_ai/_view/www/src/{plan → app/plan}/SolverDetailView.tsx +1 -1
  58. inspect_ai/_view/www/src/app/routing/AppRouter.tsx +58 -0
  59. inspect_ai/_view/www/src/app/routing/navigationHooks.ts +182 -0
  60. inspect_ai/_view/www/src/app/routing/url.ts +43 -0
  61. inspect_ai/_view/www/src/{samples → app/samples}/InlineSampleDisplay.tsx +11 -27
  62. inspect_ai/_view/www/src/{samples → app/samples}/SampleDialog.tsx +36 -40
  63. inspect_ai/_view/www/src/{samples → app/samples}/SampleDisplay.module.css +4 -0
  64. inspect_ai/_view/www/src/{samples → app/samples}/SampleDisplay.tsx +116 -49
  65. inspect_ai/_view/www/src/{samples → app/samples}/SampleSummaryView.module.css +1 -1
  66. inspect_ai/_view/www/src/{samples → app/samples}/SampleSummaryView.tsx +29 -26
  67. inspect_ai/_view/www/src/{samples → app/samples}/SamplesTools.tsx +3 -3
  68. inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatMessage.module.css +5 -2
  69. inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatMessage.tsx +12 -4
  70. inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatMessageRenderer.tsx +3 -3
  71. inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatMessageRow.tsx +6 -1
  72. inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatView.tsx +4 -2
  73. inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatViewVirtualList.tsx +5 -3
  74. inspect_ai/_view/www/src/app/samples/chat/MessageContent.module.css +12 -0
  75. inspect_ai/_view/www/src/{samples → app/samples}/chat/MessageContent.tsx +11 -10
  76. inspect_ai/_view/www/src/app/samples/chat/MessageContents.module.css +7 -0
  77. inspect_ai/_view/www/src/{samples → app/samples}/chat/MessageContents.tsx +14 -8
  78. inspect_ai/_view/www/src/{samples → app/samples}/chat/messages.ts +2 -2
  79. inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.module.css +7 -0
  80. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/ToolCallView.tsx +26 -27
  81. inspect_ai/_view/www/src/app/samples/chat/tools/ToolInput.module.css +19 -0
  82. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/ToolInput.tsx +3 -3
  83. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/ToolOutput.module.css +1 -0
  84. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/ToolOutput.tsx +1 -1
  85. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/ToolTitle.module.css +4 -0
  86. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/ToolTitle.tsx +2 -2
  87. inspect_ai/_view/www/src/{samples → app/samples}/chat/tools/tool.ts +1 -1
  88. inspect_ai/_view/www/src/app/samples/chat/types.ts +1 -0
  89. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/samplesDescriptor.tsx +38 -15
  90. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/BooleanScoreDescriptor.tsx +1 -1
  91. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/CategoricalScoreDescriptor.tsx +2 -2
  92. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/NumericScoreDescriptor.tsx +3 -3
  93. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/ObjectScoreDescriptor.tsx +4 -4
  94. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/OtherScoreDescriptor.tsx +2 -2
  95. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/PassFailScoreDescriptor.tsx +2 -2
  96. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/ScoreDescriptor.tsx +1 -1
  97. inspect_ai/_view/www/src/{samples → app/samples}/descriptor/types.ts +4 -3
  98. inspect_ai/_view/www/src/{samples → app/samples}/error/SampleErrorView.module.css +2 -1
  99. inspect_ai/_view/www/src/{samples → app/samples}/list/SampleHeader.tsx +3 -0
  100. inspect_ai/_view/www/src/{samples → app/samples}/list/SampleList.tsx +47 -33
  101. inspect_ai/_view/www/src/{samples → app/samples}/list/SampleRow.module.css +16 -0
  102. inspect_ai/_view/www/src/{samples → app/samples}/list/SampleRow.tsx +47 -20
  103. inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/SelectScorer.tsx +1 -1
  104. inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/SortFilter.tsx +4 -4
  105. inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/filters.ts +8 -6
  106. inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/sample-filter/SampleFilter.tsx +4 -3
  107. inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/sample-filter/completions.ts +1 -1
  108. inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/sample-filter/language.ts +1 -0
  109. inspect_ai/_view/www/src/{samples → app/samples}/sampleDataAdapter.ts +3 -3
  110. inspect_ai/_view/www/src/{samples → app/samples}/sampleLimit.ts +1 -1
  111. inspect_ai/_view/www/src/{samples → app/samples}/scores/SampleScores.tsx +1 -1
  112. inspect_ai/_view/www/src/{samples → app/samples}/scores/SampleScoresGrid.tsx +12 -11
  113. inspect_ai/_view/www/src/{samples → app/samples}/scores/SampleScoresView.tsx +6 -6
  114. inspect_ai/_view/www/src/{samples → app/samples}/transcript/ApprovalEventView.tsx +1 -1
  115. inspect_ai/_view/www/src/{samples → app/samples}/transcript/ErrorEventView.tsx +3 -3
  116. inspect_ai/_view/www/src/{samples → app/samples}/transcript/InfoEventView.tsx +4 -4
  117. inspect_ai/_view/www/src/{samples → app/samples}/transcript/InputEventView.tsx +3 -3
  118. inspect_ai/_view/www/src/{samples → app/samples}/transcript/LoggerEventView.tsx +3 -3
  119. inspect_ai/_view/www/src/{samples → app/samples}/transcript/ModelEventView.module.css +13 -7
  120. inspect_ai/_view/www/src/{samples → app/samples}/transcript/ModelEventView.tsx +49 -21
  121. inspect_ai/_view/www/src/{samples → app/samples}/transcript/SampleInitEventView.tsx +11 -9
  122. inspect_ai/_view/www/src/{samples → app/samples}/transcript/SampleLimitEventView.tsx +1 -1
  123. inspect_ai/_view/www/src/{samples → app/samples}/transcript/SandboxEventView.tsx +8 -6
  124. inspect_ai/_view/www/src/{samples → app/samples}/transcript/ScoreEventView.tsx +4 -4
  125. inspect_ai/_view/www/src/{samples → app/samples}/transcript/StepEventView.tsx +11 -3
  126. inspect_ai/_view/www/src/{samples → app/samples}/transcript/SubtaskEventView.tsx +2 -2
  127. inspect_ai/_view/www/src/{samples → app/samples}/transcript/ToolEventView.tsx +2 -2
  128. inspect_ai/_view/www/src/{samples → app/samples}/transcript/TranscriptView.module.css +8 -7
  129. inspect_ai/_view/www/src/{samples → app/samples}/transcript/TranscriptView.tsx +32 -114
  130. inspect_ai/_view/www/src/{samples → app/samples}/transcript/TranscriptVirtualListComponent.module.css +6 -5
  131. inspect_ai/_view/www/src/{samples → app/samples}/transcript/TranscriptVirtualListComponent.tsx +14 -2
  132. inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventPanel.tsx +2 -2
  133. inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventTimingPanel.tsx +1 -1
  134. inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/utils.ts +1 -1
  135. inspect_ai/_view/www/src/{samples → app/samples}/transcript/state/StateEventRenderers.tsx +23 -21
  136. inspect_ai/_view/www/src/{samples → app/samples}/transcript/state/StateEventRenders.module.css +7 -0
  137. inspect_ai/_view/www/src/{samples → app/samples}/transcript/state/StateEventView.tsx +2 -2
  138. inspect_ai/_view/www/src/app/samples/transcript/transform/fixups.ts +142 -0
  139. inspect_ai/_view/www/src/app/samples/transcript/transform/treeify.ts +39 -0
  140. inspect_ai/_view/www/src/{samples → app/samples}/transcript/types.ts +1 -1
  141. inspect_ai/_view/www/src/{workspace → app}/sidebar/EvalStatus.tsx +1 -1
  142. inspect_ai/_view/www/src/app/sidebar/LogDirectoryTitleView.module.css +16 -0
  143. inspect_ai/_view/www/src/app/sidebar/LogDirectoryTitleView.tsx +70 -0
  144. inspect_ai/_view/www/src/{workspace → app}/sidebar/Sidebar.module.css +8 -0
  145. inspect_ai/_view/www/src/{workspace → app}/sidebar/Sidebar.tsx +35 -17
  146. inspect_ai/_view/www/src/{workspace → app}/sidebar/SidebarLogEntry.tsx +1 -1
  147. inspect_ai/_view/www/src/{workspace → app}/sidebar/SidebarScoreView.tsx +2 -2
  148. inspect_ai/_view/www/src/{workspace → app}/sidebar/SidebarScoresView.tsx +2 -2
  149. inspect_ai/_view/www/src/{types.ts → app/types.ts} +18 -11
  150. inspect_ai/_view/www/src/{usage → app/usage}/ModelTokenTable.tsx +1 -1
  151. inspect_ai/_view/www/src/{usage → app/usage}/ModelUsagePanel.tsx +2 -2
  152. inspect_ai/_view/www/src/{usage → app/usage}/TokenTable.tsx +1 -1
  153. inspect_ai/_view/www/src/{usage → app/usage}/UsageCard.tsx +6 -6
  154. inspect_ai/_view/www/src/{api → client/api}/api-browser.ts +2 -2
  155. inspect_ai/_view/www/src/{api → client/api}/api-http.ts +3 -3
  156. inspect_ai/_view/www/src/{api → client/api}/api-vscode.ts +2 -2
  157. inspect_ai/_view/www/src/{api → client/api}/client-api.ts +6 -5
  158. inspect_ai/_view/www/src/{api → client/api}/index.ts +2 -2
  159. inspect_ai/_view/www/src/{api → client/api}/types.ts +4 -1
  160. inspect_ai/_view/www/src/{logfile → client/remote}/remoteLogFile.ts +3 -3
  161. inspect_ai/_view/www/src/{storage → client/storage}/index.ts +11 -5
  162. inspect_ai/_view/www/src/components/Card.tsx +1 -1
  163. inspect_ai/_view/www/src/components/CopyButton.tsx +1 -1
  164. inspect_ai/_view/www/src/components/DownloadButton.tsx +1 -1
  165. inspect_ai/_view/www/src/components/ErrorPanel.tsx +1 -1
  166. inspect_ai/_view/www/src/components/{ExpandablePanel.css → ExpandablePanel.module.css} +14 -11
  167. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +16 -10
  168. inspect_ai/_view/www/src/components/FindBand.tsx +1 -1
  169. inspect_ai/_view/www/src/components/JsonPanel.css +2 -2
  170. inspect_ai/_view/www/src/components/LargeModal.tsx +12 -1
  171. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +1 -1
  172. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +3 -1
  173. inspect_ai/_view/www/src/components/MessageBand.tsx +1 -1
  174. inspect_ai/_view/www/src/components/NoContentsPanel.tsx +1 -1
  175. inspect_ai/_view/www/src/constants.ts +10 -9
  176. inspect_ai/_view/www/src/index.tsx +27 -11
  177. inspect_ai/_view/www/src/state/appSlice.ts +44 -5
  178. inspect_ai/_view/www/src/state/hooks.ts +30 -7
  179. inspect_ai/_view/www/src/state/logSlice.ts +7 -5
  180. inspect_ai/_view/www/src/state/logsPolling.ts +1 -1
  181. inspect_ai/_view/www/src/state/logsSlice.ts +18 -13
  182. inspect_ai/_view/www/src/state/samplePolling.ts +12 -12
  183. inspect_ai/_view/www/src/state/sampleSlice.ts +3 -5
  184. inspect_ai/_view/www/src/state/sampleUtils.ts +1 -1
  185. inspect_ai/_view/www/src/{scoring/utils.ts → state/scoring.ts} +2 -2
  186. inspect_ai/_view/www/src/state/store.ts +9 -7
  187. inspect_ai/_view/www/src/state/utils.ts +1 -1
  188. inspect_ai/_view/www/src/tests/README.md +49 -0
  189. inspect_ai/_view/www/src/tests/__mocks__/fileMock.js +1 -0
  190. inspect_ai/_view/www/src/tests/__mocks__/styleMock.js +1 -0
  191. inspect_ai/_view/www/src/tests/setupTests.mjs +1 -0
  192. inspect_ai/_view/www/src/tests/utils/base64.test.ts +23 -0
  193. inspect_ai/_view/www/src/tests/utils/format.test.ts +127 -0
  194. inspect_ai/_view/www/src/tests/utils/path.test.ts +54 -0
  195. inspect_ai/_view/www/src/utils/format.ts +8 -2
  196. inspect_ai/_view/www/src/utils/path.ts +14 -2
  197. inspect_ai/_view/www/src/utils/polling.ts +1 -2
  198. inspect_ai/_view/www/src/utils/uri.ts +32 -0
  199. inspect_ai/_view/www/yarn.lock +3310 -382
  200. inspect_ai/agent/_handoff.py +6 -3
  201. inspect_ai/agent/_human/agent.py +5 -3
  202. inspect_ai/agent/_human/install.py +16 -7
  203. inspect_ai/agent/_human/panel.py +14 -1
  204. inspect_ai/agent/_human/service.py +5 -1
  205. inspect_ai/agent/_react.py +161 -128
  206. inspect_ai/agent/_types.py +15 -4
  207. inspect_ai/approval/_policy.py +2 -2
  208. inspect_ai/log/_file.py +30 -11
  209. inspect_ai/log/_log.py +7 -1
  210. inspect_ai/log/_recorders/eval.py +3 -0
  211. inspect_ai/log/_recorders/types.py +1 -0
  212. inspect_ai/log/_samples.py +4 -0
  213. inspect_ai/model/_call_tools.py +33 -17
  214. inspect_ai/model/_generate_config.py +10 -2
  215. inspect_ai/model/_model.py +41 -21
  216. inspect_ai/model/_model_output.py +2 -1
  217. inspect_ai/model/_openai.py +10 -8
  218. inspect_ai/model/_openai_responses.py +83 -42
  219. inspect_ai/model/_providers/anthropic.py +14 -12
  220. inspect_ai/model/_providers/google.py +191 -95
  221. inspect_ai/model/_providers/hf.py +1 -1
  222. inspect_ai/model/_providers/mistral.py +2 -3
  223. inspect_ai/model/_providers/openai.py +54 -17
  224. inspect_ai/model/_providers/openai_o1.py +1 -1
  225. inspect_ai/model/_providers/openai_responses.py +28 -16
  226. inspect_ai/model/_providers/openrouter.py +14 -0
  227. inspect_ai/model/_providers/providers.py +2 -2
  228. inspect_ai/model/_providers/util/chatapi.py +17 -7
  229. inspect_ai/model/_providers/vllm.py +1 -1
  230. inspect_ai/scorer/_metric.py +17 -1
  231. inspect_ai/scorer/_model.py +51 -6
  232. inspect_ai/scorer/_scorer.py +1 -1
  233. inspect_ai/solver/_human_agent.py +3 -0
  234. inspect_ai/solver/_plan.py +1 -1
  235. inspect_ai/solver/_solver.py +1 -1
  236. inspect_ai/solver/_use_tools.py +14 -8
  237. inspect_ai/tool/__init__.py +16 -1
  238. inspect_ai/tool/_json_rpc_helpers.py +285 -0
  239. inspect_ai/tool/_mcp/__init__.py +13 -0
  240. inspect_ai/tool/_mcp/_context.py +14 -0
  241. inspect_ai/tool/_mcp/_mcp.py +293 -0
  242. inspect_ai/tool/_mcp/_sandbox.py +104 -0
  243. inspect_ai/tool/_mcp/_types.py +31 -0
  244. inspect_ai/tool/_mcp/connection.py +60 -0
  245. inspect_ai/tool/_mcp/sampling.py +118 -0
  246. inspect_ai/tool/_mcp/server.py +112 -0
  247. inspect_ai/tool/_mcp/tools.py +34 -0
  248. inspect_ai/tool/_tool.py +13 -0
  249. inspect_ai/tool/_tool_def.py +24 -7
  250. inspect_ai/tool/_tool_support_helpers.py +129 -153
  251. inspect_ai/tool/_tools/_bash_session.py +11 -11
  252. inspect_ai/tool/_tools/_text_editor.py +6 -6
  253. inspect_ai/tool/_tools/_web_browser/_web_browser.py +8 -8
  254. inspect_ai/util/_anyio.py +31 -20
  255. inspect_ai/util/_json.py +20 -2
  256. inspect_ai/util/_sandbox/context.py +18 -7
  257. inspect_ai/util/_sandbox/docker/compose.py +1 -1
  258. inspect_ai/util/_sandbox/docker/docker.py +92 -21
  259. inspect_ai/util/_sandbox/environment.py +33 -2
  260. inspect_ai/util/_sandbox/events.py +2 -2
  261. inspect_ai/util/_sandbox/service.py +13 -3
  262. {inspect_ai-0.3.90.dist-info → inspect_ai-0.3.91.dist-info}/METADATA +6 -2
  263. inspect_ai-0.3.91.dist-info/RECORD +732 -0
  264. {inspect_ai-0.3.90.dist-info → inspect_ai-0.3.91.dist-info}/WHEEL +1 -1
  265. inspect_ai/_view/www/src/App.tsx +0 -316
  266. inspect_ai/_view/www/src/samples/chat/MessageContent.module.css +0 -4
  267. inspect_ai/_view/www/src/samples/chat/MessageContents.module.css +0 -3
  268. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.module.css +0 -3
  269. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.module.css +0 -14
  270. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +0 -292
  271. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.module.css +0 -5
  272. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +0 -57
  273. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +0 -43
  274. inspect_ai-0.3.90.dist-info/RECORD +0 -705
  275. /inspect_ai/_view/www/src/{types → @types}/asciicinema-player.d.ts +0 -0
  276. /inspect_ai/_view/www/src/{types → @types}/jsondiffpatch.d.ts +0 -0
  277. /inspect_ai/_view/www/src/{types → @types}/markdown-it-katex.d.ts +0 -0
  278. /inspect_ai/_view/www/src/{types → @types}/prism.d.ts +0 -0
  279. /inspect_ai/_view/www/src/{appearance → app/appearance}/colors.ts +0 -0
  280. /inspect_ai/_view/www/src/{appearance → app/appearance}/fonts.ts +0 -0
  281. /inspect_ai/_view/www/src/{appearance → app/appearance}/styles.ts +0 -0
  282. /inspect_ai/_view/www/src/{metadata → app/content}/MetaDataGrid.tsx +0 -0
  283. /inspect_ai/_view/www/src/{metadata → app/content}/MetaDataView.module.css +0 -0
  284. /inspect_ai/_view/www/src/{metadata → app/content}/MetaDataView.tsx +0 -0
  285. /inspect_ai/_view/www/src/{metadata → app/content}/MetadataGrid.module.css +0 -0
  286. /inspect_ai/_view/www/src/{metadata → app/content}/RenderedContent.module.css +0 -0
  287. /inspect_ai/_view/www/src/{metadata → app/content}/types.ts +0 -0
  288. /inspect_ai/_view/www/src/{workspace/WorkSpaceView.module.css → app/log-view/LogView.module.css} +0 -0
  289. /inspect_ai/_view/www/src/{workspace → app/log-view}/error/TaskErrorPanel.module.css +0 -0
  290. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/ModelRolesView.module.css +0 -0
  291. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/Navbar.module.css +0 -0
  292. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/PrimaryBar.module.css +0 -0
  293. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/ResultsPanel.module.css +0 -0
  294. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/RunningStatusPanel.module.css +0 -0
  295. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/ScoreGrid.module.css +0 -0
  296. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/SecondaryBar.module.css +0 -0
  297. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/StatusPanel.module.css +0 -0
  298. /inspect_ai/_view/www/src/{workspace → app/log-view}/navbar/StatusPanel.tsx +0 -0
  299. /inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/InfoTab.module.css +0 -0
  300. /inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/JsonTab.module.css +0 -0
  301. /inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/RunningNoSamples.module.css +0 -0
  302. /inspect_ai/_view/www/src/{workspace → app/log-view}/tabs/RunningNoSamples.tsx +0 -0
  303. /inspect_ai/_view/www/src/{workspace → app/log-view}/types.ts +0 -0
  304. /inspect_ai/_view/www/src/{workspace → app/log-view}/utils.ts +0 -0
  305. /inspect_ai/_view/www/src/{plan → app/plan}/DatasetDetailView.module.css +0 -0
  306. /inspect_ai/_view/www/src/{plan → app/plan}/DetailStep.module.css +0 -0
  307. /inspect_ai/_view/www/src/{plan → app/plan}/ModelCard.module.css +0 -0
  308. /inspect_ai/_view/www/src/{plan → app/plan}/PlanDetailView.module.css +0 -0
  309. /inspect_ai/_view/www/src/{plan → app/plan}/ScorerDetailView.module.css +0 -0
  310. /inspect_ai/_view/www/src/{plan → app/plan}/ScorerDetailView.tsx +0 -0
  311. /inspect_ai/_view/www/src/{plan → app/plan}/SolverDetailView.module.css +0 -0
  312. /inspect_ai/_view/www/src/{samples → app/samples}/InlineSampleDisplay.module.css +0 -0
  313. /inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatMessageRow.module.css +0 -0
  314. /inspect_ai/_view/www/src/{samples → app/samples}/chat/ChatViewVirtualList.module.css +0 -0
  315. /inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/BooleanScoreDescriptor.module.css +0 -0
  316. /inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/ObjectScoreDescriptor.module.css +0 -0
  317. /inspect_ai/_view/www/src/{samples → app/samples}/descriptor/score/PassFailScoreDescriptor.module.css +0 -0
  318. /inspect_ai/_view/www/src/{samples → app/samples}/error/FlatSampleErrorView.module.css +0 -0
  319. /inspect_ai/_view/www/src/{samples → app/samples}/error/FlatSampleErrorView.tsx +0 -0
  320. /inspect_ai/_view/www/src/{samples → app/samples}/error/SampleErrorView.tsx +0 -0
  321. /inspect_ai/_view/www/src/{samples → app/samples}/error/error.ts +0 -0
  322. /inspect_ai/_view/www/src/{samples → app/samples}/list/SampleFooter.module.css +0 -0
  323. /inspect_ai/_view/www/src/{samples → app/samples}/list/SampleFooter.tsx +0 -0
  324. /inspect_ai/_view/www/src/{samples → app/samples}/list/SampleHeader.module.css +0 -0
  325. /inspect_ai/_view/www/src/{samples → app/samples}/list/SampleList.module.css +0 -0
  326. /inspect_ai/_view/www/src/{samples → app/samples}/list/SampleSeparator.module.css +0 -0
  327. /inspect_ai/_view/www/src/{samples → app/samples}/list/SampleSeparator.tsx +0 -0
  328. /inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/EpochFilter.module.css +0 -0
  329. /inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/EpochFilter.tsx +0 -0
  330. /inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/SelectScorer.module.css +0 -0
  331. /inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/SortFilter.module.css +0 -0
  332. /inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/sample-filter/SampleFilter.module.css +0 -0
  333. /inspect_ai/_view/www/src/{samples → app/samples}/sample-tools/sample-filter/tokenize.ts +0 -0
  334. /inspect_ai/_view/www/src/{samples → app/samples}/scores/SampleScores.module.css +0 -0
  335. /inspect_ai/_view/www/src/{samples → app/samples}/scores/SampleScoresGrid.module.css +0 -0
  336. /inspect_ai/_view/www/src/{samples → app/samples}/scores/SampleScoresView.module.css +0 -0
  337. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/InfoEventView.module.css +0 -0
  338. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/LoggerEventView.module.css +0 -0
  339. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/SampleInitEventView.module.css +0 -0
  340. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/SandboxEventView.module.css +0 -0
  341. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/ScoreEventView.module.css +0 -0
  342. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/SubtaskEventView.module.css +0 -0
  343. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/ToolEventView.module.css +0 -0
  344. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventNav.module.css +0 -0
  345. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventNav.tsx +0 -0
  346. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventNavs.module.css +0 -0
  347. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventNavs.tsx +0 -0
  348. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventPanel.module.css +0 -0
  349. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventProgressPanel.module.css +0 -0
  350. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventProgressPanel.tsx +0 -0
  351. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventRow.module.css +0 -0
  352. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventRow.tsx +0 -0
  353. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventSection.module.css +0 -0
  354. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventSection.tsx +0 -0
  355. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/event/EventTimingPanel.module.css +0 -0
  356. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/state/StateDiffView.tsx +0 -0
  357. /inspect_ai/_view/www/src/{samples → app/samples}/transcript/state/StateEventView.module.css +0 -0
  358. /inspect_ai/_view/www/src/{workspace → app}/sidebar/EvalStatus.module.css +0 -0
  359. /inspect_ai/_view/www/src/{workspace → app}/sidebar/SidebarLogEntry.module.css +0 -0
  360. /inspect_ai/_view/www/src/{workspace → app}/sidebar/SidebarScoreView.module.css +0 -0
  361. /inspect_ai/_view/www/src/{workspace → app}/sidebar/SidebarScoresView.module.css +0 -0
  362. /inspect_ai/_view/www/src/{usage → app/usage}/ModelUsagePanel.module.css +0 -0
  363. /inspect_ai/_view/www/src/{usage → app/usage}/TokenTable.module.css +0 -0
  364. /inspect_ai/_view/www/src/{usage → app/usage}/UsageCard.module.css +0 -0
  365. /inspect_ai/_view/www/src/{api → client/api}/api-shared.ts +0 -0
  366. /inspect_ai/_view/www/src/{api → client/api}/jsonrpc.ts +0 -0
  367. /inspect_ai/_view/www/src/{logfile → client/remote}/remoteZipFile.ts +0 -0
  368. {inspect_ai-0.3.90.dist-info → inspect_ai-0.3.91.dist-info}/entry_points.txt +0 -0
  369. {inspect_ai-0.3.90.dist-info → inspect_ai-0.3.91.dist-info}/licenses/LICENSE +0 -0
  370. {inspect_ai-0.3.90.dist-info → inspect_ai-0.3.91.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,182 @@
1
+ import { useCallback } from "react";
2
+ import { useNavigate, useParams } from "react-router-dom";
3
+ import { useFilteredSamples } from "../../state/hooks";
4
+ import { useStore } from "../../state/store";
5
+ import { directoryRelativeUrl } from "../../utils/uri";
6
+ import { logUrl, logUrlRaw, sampleUrl } from "./url";
7
+
8
+ export const useLogNavigation = () => {
9
+ const navigate = useNavigate();
10
+ const { logPath } = useParams<{ logPath: string }>();
11
+ const logs = useStore((state) => state.logs.logs);
12
+ const loadedLog = useStore((state) => state.log.loadedLog);
13
+
14
+ const selectTab = useCallback(
15
+ (tabId: string) => {
16
+ // Only update URL if we have a loaded log
17
+ if (loadedLog && logPath) {
18
+ // We already have the logPath from params, just navigate to the tab
19
+ const url = logUrlRaw(logPath, tabId);
20
+ navigate(url);
21
+ } else if (loadedLog) {
22
+ // Fallback to constructing the path if needed
23
+ const url = logUrl(loadedLog, logs.log_dir, tabId);
24
+ navigate(url);
25
+ }
26
+ },
27
+ [loadedLog, logPath, logs.log_dir, navigate],
28
+ );
29
+
30
+ return {
31
+ selectTab,
32
+ };
33
+ };
34
+
35
+ /**
36
+ * Hook that provides sample navigation utilities with proper URL handling
37
+ * for use across the application
38
+ */
39
+ export const useSampleNavigation = () => {
40
+ const navigate = useNavigate();
41
+
42
+ // The log directory
43
+ const logDirectory = useStore((state) => state.logs.logs.log_dir);
44
+
45
+ // The log
46
+ const { logPath, tabId, sampleTabId } = useParams<{
47
+ logPath?: string;
48
+ tabId?: string;
49
+ sampleTabId?: string;
50
+ }>();
51
+
52
+ // Get the store access values directly in the hook
53
+ const getSelectedLogFile = useStore(
54
+ (state) => state.logsActions.getSelectedLogFile,
55
+ );
56
+
57
+ // Helper function to resolve the log path for URLs
58
+ const resolveLogPath = useCallback(() => {
59
+ // If we have a logPath from URL params, use that
60
+ if (logPath) {
61
+ return logPath;
62
+ }
63
+
64
+ // Otherwise use the selected log file
65
+ const selectedLogFile = getSelectedLogFile();
66
+
67
+ if (selectedLogFile) {
68
+ return directoryRelativeUrl(selectedLogFile, logDirectory);
69
+ }
70
+
71
+ return undefined;
72
+ }, [logPath, getSelectedLogFile, logDirectory]);
73
+
74
+ // The samples
75
+ const sampleSummaries = useFilteredSamples();
76
+
77
+ // Sample hooks
78
+ const selectedSampleIndex = useStore(
79
+ (state) => state.log.selectedSampleIndex,
80
+ );
81
+ const selectSample = useStore((state) => state.logActions.selectSample);
82
+ const setShowingSampleDialog = useStore(
83
+ (state) => state.appActions.setShowingSampleDialog,
84
+ );
85
+
86
+ // Navigate to a specific sample with index
87
+ const showSample = useCallback(
88
+ (index: number, specifiedSampleTabId?: string) => {
89
+ if (sampleSummaries && index >= 0 && index < sampleSummaries.length) {
90
+ const sample = sampleSummaries[index];
91
+ const resolvedPath = resolveLogPath();
92
+
93
+ if (resolvedPath) {
94
+ // Update internal state
95
+ selectSample(index);
96
+ setShowingSampleDialog(true);
97
+
98
+ // Use specified sampleTabId if provided, otherwise use current sampleTabId from URL params
99
+ const currentSampleTabId = specifiedSampleTabId || sampleTabId;
100
+
101
+ const url = sampleUrl(
102
+ resolvedPath,
103
+ sample.id,
104
+ sample.epoch,
105
+ currentSampleTabId,
106
+ );
107
+
108
+ // Navigate to the sample URL
109
+ navigate(url);
110
+ }
111
+ }
112
+ },
113
+ [
114
+ sampleSummaries,
115
+ resolveLogPath,
116
+ selectSample,
117
+ setShowingSampleDialog,
118
+ navigate,
119
+ tabId,
120
+ sampleTabId,
121
+ ],
122
+ );
123
+
124
+ // Navigate to the next sample
125
+ const nextSample = useCallback(() => {
126
+ const itemsCount = sampleSummaries.length;
127
+ const next = Math.min(selectedSampleIndex + 1, itemsCount - 1);
128
+ if (next > -1) {
129
+ showSample(next, sampleTabId);
130
+ }
131
+ }, [selectedSampleIndex, showSample, sampleTabId]);
132
+
133
+ // Navigate to the previous sample
134
+ const previousSample = useCallback(() => {
135
+ const prev = selectedSampleIndex - 1;
136
+ if (prev > -1) {
137
+ showSample(prev, sampleTabId);
138
+ }
139
+ }, [selectedSampleIndex, showSample, sampleTabId]);
140
+
141
+ // Get a sample URL for a specific sample
142
+ const getSampleUrl = useCallback(
143
+ (
144
+ sampleId: string | number,
145
+ epoch: number,
146
+ specificSampleTabId?: string,
147
+ ) => {
148
+ const resolvedPath = resolveLogPath();
149
+ if (resolvedPath) {
150
+ const currentSampleTabId = specificSampleTabId || sampleTabId;
151
+ const url = sampleUrl(
152
+ resolvedPath,
153
+ sampleId,
154
+ epoch,
155
+ currentSampleTabId,
156
+ );
157
+ return url;
158
+ }
159
+ return undefined;
160
+ },
161
+ [resolveLogPath, tabId, sampleTabId],
162
+ );
163
+
164
+ // Navigate back from sample dialog
165
+ const clearSampleUrl = useCallback(() => {
166
+ const resolvedPath = resolveLogPath();
167
+ if (resolvedPath) {
168
+ const url = logUrlRaw(resolvedPath, tabId);
169
+ navigate(url);
170
+ }
171
+ }, [resolveLogPath, navigate, tabId]);
172
+
173
+ return {
174
+ showSample,
175
+ nextEnabled: selectedSampleIndex < sampleSummaries.length - 1,
176
+ nextSample,
177
+ previousEnabled: selectedSampleIndex > 0,
178
+ previousSample,
179
+ getSampleUrl,
180
+ clearSampleUrl,
181
+ };
182
+ };
@@ -0,0 +1,43 @@
1
+ import { directoryRelativeUrl } from "../../utils/uri";
2
+
3
+ export const kLogRouteUrlPattern = "/logs/:logPath/:tabId?/:sampleTabId?";
4
+ export const kSampleRouteUrlPattern =
5
+ "/logs/:logPath/samples/sample/:sampleId/:epoch?/:sampleTabId?";
6
+
7
+ export const baseUrl = (
8
+ logPath: string,
9
+ sampleId?: string | number,
10
+ sampleEpoch?: string | number,
11
+ ) => {
12
+ if (sampleId !== undefined && sampleEpoch !== undefined) {
13
+ return sampleUrl(logPath, sampleId, sampleEpoch);
14
+ } else {
15
+ return logUrl(logPath);
16
+ }
17
+ };
18
+
19
+ export const sampleUrl = (
20
+ logPath: string,
21
+ sampleId?: string | number,
22
+ sampleEpoch?: string | number,
23
+ sampleTabId?: string,
24
+ ) => {
25
+ if (sampleId !== undefined && sampleEpoch !== undefined) {
26
+ return `/logs/${encodeURIComponent(logPath)}/samples/sample/${encodeURIComponent(sampleId)}/${sampleEpoch}/${sampleTabId || ""}`;
27
+ } else {
28
+ return `/logs/${encodeURIComponent(logPath)}/samples/${sampleTabId || ""}`;
29
+ }
30
+ };
31
+
32
+ export const logUrl = (log_file: string, log_dir?: string, tabId?: string) => {
33
+ const pathSegment = directoryRelativeUrl(log_file, log_dir);
34
+ return logUrlRaw(pathSegment, tabId);
35
+ };
36
+
37
+ export const logUrlRaw = (log_segment: string, tabId?: string) => {
38
+ if (tabId) {
39
+ return `/logs/${encodeURIComponent(log_segment)}/${tabId}`;
40
+ } else {
41
+ return `/logs/${encodeURIComponent(log_segment)}`;
42
+ }
43
+ };
@@ -1,27 +1,17 @@
1
1
  import { FC, useEffect, useRef } from "react";
2
- import { ErrorPanel } from "../components/ErrorPanel";
2
+ import { ErrorPanel } from "../../components/ErrorPanel";
3
3
  import { SampleDisplay } from "./SampleDisplay";
4
4
 
5
5
  import clsx from "clsx";
6
- import { ProgressBar } from "../components/ProgressBar";
7
- import { useLogSelection, usePrevious, useSampleData } from "../state/hooks";
8
- import { useStore } from "../state/store";
6
+ import { ProgressBar } from "../../components/ProgressBar";
7
+ import { useLogSelection, usePrevious, useSampleData } from "../../state/hooks";
8
+ import { useStore } from "../../state/store";
9
9
  import styles from "./InlineSampleDisplay.module.css";
10
10
 
11
- interface InlineSampleDisplayProps {
12
- id: string;
13
- selectedTab?: string;
14
- setSelectedTab: (tab: string) => void;
15
- }
16
-
17
11
  /**
18
12
  * Inline Sample Display
19
13
  */
20
- export const InlineSampleDisplay: FC<InlineSampleDisplayProps> = ({
21
- id,
22
- selectedTab,
23
- setSelectedTab,
24
- }) => {
14
+ export const InlineSampleDisplay: FC = () => {
25
15
  // Sample hooks
26
16
  const sampleData = useSampleData();
27
17
  const loadSample = useStore((state) => state.sampleActions.loadSample);
@@ -40,7 +30,7 @@ export const InlineSampleDisplay: FC<InlineSampleDisplayProps> = ({
40
30
  ? logSelection.sample.completed
41
31
  : true,
42
32
  );
43
- const prevLogFile = usePrevious<string | undefined>(logSelection.logFile);
33
+ const prevLogFile = usePrevious<string | undefined>(logSelection.loadedLog);
44
34
  useEffect(() => {
45
35
  if (logSelection.logFile && logSelection.sample) {
46
36
  const currentSampleCompleted =
@@ -49,16 +39,17 @@ export const InlineSampleDisplay: FC<InlineSampleDisplayProps> = ({
49
39
  : true;
50
40
 
51
41
  if (
52
- prevLogFile !== logSelection.logFile ||
42
+ (prevLogFile !== undefined && prevLogFile !== logSelection.loadedLog) ||
53
43
  sampleData.sample?.id !== logSelection.sample.id ||
54
44
  sampleData.sample?.epoch !== logSelection.sample.epoch ||
55
- currentSampleCompleted !== prevCompleted
45
+ (prevCompleted !== undefined &&
46
+ currentSampleCompleted !== prevCompleted)
56
47
  ) {
57
48
  loadSample(logSelection.logFile, logSelection.sample);
58
49
  }
59
50
  }
60
51
  }, [
61
- logSelection.logFile,
52
+ logSelection.loadedLog,
62
53
  logSelection.sample?.id,
63
54
  logSelection.sample?.epoch,
64
55
  logSelection.sample?.completed,
@@ -83,14 +74,7 @@ export const InlineSampleDisplay: FC<InlineSampleDisplayProps> = ({
83
74
  error={sampleData.error}
84
75
  />
85
76
  ) : (
86
- <SampleDisplay
87
- id={id}
88
- sample={sampleData.sample}
89
- runningEvents={sampleData.running}
90
- selectedTab={selectedTab}
91
- setSelectedTab={setSelectedTab}
92
- scrollRef={scrollRef}
93
- />
77
+ <SampleDisplay id={"inline-sample-display"} scrollRef={scrollRef} />
94
78
  )}
95
79
  </div>
96
80
  </div>
@@ -1,22 +1,18 @@
1
+ import { LargeModal, ModalTool, ModalTools } from "../../components/LargeModal";
1
2
  import { ApplicationIcons } from "../appearance/icons";
2
- import { LargeModal, ModalTool, ModalTools } from "../components/LargeModal";
3
3
 
4
4
  import { FC, Ref, useCallback, useEffect, useMemo, useRef } from "react";
5
- import { ErrorPanel } from "../components/ErrorPanel";
6
- import { useLogSelection, usePrevious, useSampleData } from "../state/hooks";
7
- import { useStatefulScrollPosition } from "../state/scrolling";
8
- import { useStore } from "../state/store";
5
+ import { ErrorPanel } from "../../components/ErrorPanel";
6
+ import { useLogSelection, usePrevious, useSampleData } from "../../state/hooks";
7
+ import { useStatefulScrollPosition } from "../../state/scrolling";
8
+ import { useStore } from "../../state/store";
9
+ import { useSampleNavigation } from "../routing/navigationHooks";
9
10
  import { SampleDisplay } from "./SampleDisplay";
10
11
 
11
12
  interface SampleDialogProps {
12
13
  id: string;
13
14
  title: string;
14
- selectedTab?: string;
15
- setSelectedTab: (tab: string) => void;
16
15
  showingSampleDialog: boolean;
17
- setShowingSampleDialog: (showing: boolean) => void;
18
- nextSample: () => void;
19
- prevSample: () => void;
20
16
  }
21
17
 
22
18
  /**
@@ -25,12 +21,7 @@ interface SampleDialogProps {
25
21
  export const SampleDialog: FC<SampleDialogProps> = ({
26
22
  id,
27
23
  title,
28
- nextSample,
29
- prevSample,
30
24
  showingSampleDialog,
31
- setShowingSampleDialog,
32
- selectedTab,
33
- setSelectedTab,
34
25
  }) => {
35
26
  // Scroll referernce (attach stateful trackign)
36
27
  const scrollRef: Ref<HTMLDivElement> = useRef(null);
@@ -55,6 +46,7 @@ export const SampleDialog: FC<SampleDialogProps> = ({
55
46
  : true,
56
47
  );
57
48
  const prevLogFile = usePrevious<string | undefined>(logSelection.logFile);
49
+
58
50
  useEffect(() => {
59
51
  if (logSelection.logFile && logSelection.sample) {
60
52
  const currentSampleCompleted =
@@ -63,10 +55,11 @@ export const SampleDialog: FC<SampleDialogProps> = ({
63
55
  : true;
64
56
 
65
57
  if (
66
- prevLogFile !== logSelection.logFile ||
58
+ (prevLogFile !== undefined && prevLogFile !== logSelection.logFile) ||
67
59
  sampleData.sample?.id !== logSelection.sample.id ||
68
60
  sampleData.sample?.epoch !== logSelection.sample.epoch ||
69
- currentSampleCompleted !== prevCompleted
61
+ (prevCompleted !== undefined &&
62
+ currentSampleCompleted !== prevCompleted)
70
63
  ) {
71
64
  loadSample(logSelection.logFile, logSelection.sample);
72
65
  }
@@ -80,52 +73,62 @@ export const SampleDialog: FC<SampleDialogProps> = ({
80
73
  sampleData.sample?.epoch,
81
74
  ]);
82
75
 
76
+ // Get sample navigation utilities
77
+ const sampleNavigation = useSampleNavigation();
78
+
83
79
  // Tools
84
80
  const tools = useMemo<ModalTools>(() => {
85
81
  const nextTool: ModalTool = {
86
82
  label: "Next Sample",
87
83
  icon: ApplicationIcons.next,
88
- onClick: nextSample,
89
- enabled: !!nextSample,
84
+ onClick: sampleNavigation.nextSample,
85
+ enabled: sampleNavigation.nextEnabled,
90
86
  };
91
87
 
92
88
  const prevTool: ModalTool = {
93
89
  label: "Previous Sample",
94
90
  icon: ApplicationIcons.previous,
95
- onClick: prevSample,
96
- enabled: !!prevSample,
91
+ onClick: sampleNavigation.previousSample,
92
+ enabled: sampleNavigation.previousEnabled,
97
93
  };
98
94
 
99
95
  return {
100
96
  left: [prevTool],
101
97
  right: [nextTool],
102
98
  };
103
- }, [prevSample, nextSample]);
99
+ }, [
100
+ sampleNavigation.nextSample,
101
+ sampleNavigation.previousSample,
102
+ sampleNavigation.nextEnabled,
103
+ sampleNavigation.previousEnabled,
104
+ ]);
104
105
 
105
106
  const handleKeyUp = useCallback(
106
107
  (e: KeyboardEvent) => {
107
108
  switch (e.key) {
108
109
  case "ArrowRight":
109
- if (nextSample) {
110
- nextSample();
111
- }
110
+ sampleNavigation.nextSample();
112
111
  break;
113
112
  case "ArrowLeft":
114
- if (prevSample) {
115
- prevSample();
116
- }
113
+ sampleNavigation.previousSample();
117
114
  break;
118
115
  case "Escape":
119
- setShowingSampleDialog(false);
116
+ // Use the navigation hook to close the dialog
117
+ sampleNavigation.clearSampleUrl();
120
118
  break;
121
119
  }
122
120
  },
123
- [prevSample, nextSample, setShowingSampleDialog],
121
+ [
122
+ sampleNavigation.nextSample,
123
+ sampleNavigation.previousSample,
124
+ sampleNavigation.clearSampleUrl,
125
+ ],
124
126
  );
125
127
 
126
128
  const onHide = useCallback(() => {
127
- setShowingSampleDialog(false);
128
- }, [setShowingSampleDialog]);
129
+ // Use the navigation hook to close the dialog
130
+ sampleNavigation.clearSampleUrl();
131
+ }, [sampleNavigation]);
129
132
 
130
133
  // Provide the dialog
131
134
  return (
@@ -144,14 +147,7 @@ export const SampleDialog: FC<SampleDialogProps> = ({
144
147
  {sampleData.error ? (
145
148
  <ErrorPanel title="Sample Error" error={sampleData.error} />
146
149
  ) : (
147
- <SampleDisplay
148
- id={id}
149
- sample={sampleData.sample}
150
- runningEvents={sampleData.running}
151
- selectedTab={selectedTab}
152
- setSelectedTab={setSelectedTab}
153
- scrollRef={scrollRef}
154
- />
150
+ <SampleDisplay id={id} scrollRef={scrollRef} />
155
151
  )}
156
152
  </LargeModal>
157
153
  );
@@ -20,6 +20,10 @@
20
20
  margin-top: 0.4em;
21
21
  }
22
22
 
23
+ .error {
24
+ padding-top: 0.5em;
25
+ }
26
+
23
27
  .ansi {
24
28
  margin: 1em 0;
25
29
  }