inspect-ai 0.3.62__py3-none-any.whl → 0.3.64__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 (518) hide show
  1. inspect_ai/_cli/cache.py +8 -7
  2. inspect_ai/_cli/common.py +0 -12
  3. inspect_ai/_cli/eval.py +32 -4
  4. inspect_ai/_cli/info.py +1 -0
  5. inspect_ai/_cli/list.py +1 -1
  6. inspect_ai/_cli/log.py +2 -0
  7. inspect_ai/_cli/main.py +1 -1
  8. inspect_ai/_cli/sandbox.py +4 -1
  9. inspect_ai/_cli/score.py +181 -32
  10. inspect_ai/_cli/trace.py +10 -0
  11. inspect_ai/_cli/view.py +4 -2
  12. inspect_ai/_display/core/active.py +2 -3
  13. inspect_ai/_display/core/config.py +7 -1
  14. inspect_ai/_display/textual/widgets/samples.py +4 -3
  15. inspect_ai/_display/textual/widgets/sandbox.py +6 -0
  16. inspect_ai/_eval/eval.py +104 -101
  17. inspect_ai/_eval/evalset.py +75 -75
  18. inspect_ai/_eval/loader.py +122 -12
  19. inspect_ai/_eval/registry.py +1 -1
  20. inspect_ai/_eval/run.py +14 -0
  21. inspect_ai/_eval/score.py +125 -36
  22. inspect_ai/_eval/task/log.py +105 -4
  23. inspect_ai/_eval/task/results.py +92 -38
  24. inspect_ai/_eval/task/run.py +9 -2
  25. inspect_ai/_eval/task/sandbox.py +35 -2
  26. inspect_ai/_eval/task/task.py +49 -46
  27. inspect_ai/_util/constants.py +1 -1
  28. inspect_ai/_util/content.py +8 -0
  29. inspect_ai/_util/error.py +2 -0
  30. inspect_ai/_util/file.py +15 -1
  31. inspect_ai/_util/hash.py +1 -1
  32. inspect_ai/_util/logger.py +4 -2
  33. inspect_ai/_util/registry.py +7 -1
  34. inspect_ai/_view/view.py +1 -2
  35. inspect_ai/_view/www/.vscode/extensions.json +3 -0
  36. inspect_ai/_view/www/.vscode/settings.json +8 -0
  37. inspect_ai/_view/www/App.css +97 -29
  38. inspect_ai/_view/www/README.md +1 -1
  39. inspect_ai/_view/www/dist/assets/index.css +16663 -14674
  40. inspect_ai/_view/www/dist/assets/index.js +58808 -51348
  41. inspect_ai/_view/www/dist/index.html +1 -1
  42. inspect_ai/_view/www/index.html +2 -2
  43. inspect_ai/_view/www/log-schema.json +87 -73
  44. inspect_ai/_view/www/package.json +22 -4
  45. inspect_ai/_view/www/postcss.config.cjs +8 -9
  46. inspect_ai/_view/www/src/{App.mjs → App.tsx} +356 -365
  47. inspect_ai/_view/www/src/AppErrorBoundary.tsx +47 -0
  48. inspect_ai/_view/www/src/api/api-browser.ts +2 -2
  49. inspect_ai/_view/www/src/api/api-http.ts +3 -5
  50. inspect_ai/_view/www/src/api/api-vscode.ts +6 -6
  51. inspect_ai/_view/www/src/api/client-api.ts +4 -4
  52. inspect_ai/_view/www/src/api/index.ts +4 -4
  53. inspect_ai/_view/www/src/api/{Types.ts → types.ts} +25 -9
  54. inspect_ai/_view/www/src/appearance/colors.ts +9 -0
  55. inspect_ai/_view/www/src/appearance/fonts.ts +39 -0
  56. inspect_ai/_view/www/src/appearance/icons.ts +100 -0
  57. inspect_ai/_view/www/src/appearance/{Styles.mjs → styles.ts} +2 -32
  58. inspect_ai/_view/www/src/components/AnsiDisplay.tsx +198 -0
  59. inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +86 -0
  60. inspect_ai/_view/www/src/components/Card.css +60 -0
  61. inspect_ai/_view/www/src/components/Card.tsx +109 -0
  62. inspect_ai/_view/www/src/components/CopyButton.module.css +11 -0
  63. inspect_ai/_view/www/src/components/CopyButton.tsx +58 -0
  64. inspect_ai/_view/www/src/components/DownloadButton.css +4 -0
  65. inspect_ai/_view/www/src/components/DownloadButton.tsx +25 -0
  66. inspect_ai/_view/www/src/components/DownloadPanel.css +10 -0
  67. inspect_ai/_view/www/src/components/DownloadPanel.tsx +30 -0
  68. inspect_ai/_view/www/src/components/EmptyPanel.css +12 -0
  69. inspect_ai/_view/www/src/components/EmptyPanel.tsx +15 -0
  70. inspect_ai/_view/www/src/components/ErrorPanel.css +37 -0
  71. inspect_ai/_view/www/src/components/ErrorPanel.tsx +39 -0
  72. inspect_ai/_view/www/src/components/ExpandablePanel.css +40 -0
  73. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +115 -0
  74. inspect_ai/_view/www/src/components/FindBand.css +49 -0
  75. inspect_ai/_view/www/src/components/FindBand.tsx +130 -0
  76. inspect_ai/_view/www/src/components/HumanBaselineView.css +41 -0
  77. inspect_ai/_view/www/src/components/HumanBaselineView.tsx +162 -0
  78. inspect_ai/_view/www/src/components/JsonPanel.css +20 -0
  79. inspect_ai/_view/www/src/components/JsonPanel.tsx +82 -0
  80. inspect_ai/_view/www/src/components/LabeledValue.css +20 -0
  81. inspect_ai/_view/www/src/components/LabeledValue.tsx +41 -0
  82. inspect_ai/_view/www/src/components/LargeModal.module.css +54 -0
  83. inspect_ai/_view/www/src/components/LargeModal.tsx +189 -0
  84. inspect_ai/_view/www/src/components/LightboxCarousel.css +95 -0
  85. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +132 -0
  86. inspect_ai/_view/www/src/components/MarkdownDiv.css +3 -0
  87. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +133 -0
  88. inspect_ai/_view/www/src/components/MessageBand.css +43 -0
  89. inspect_ai/_view/www/src/components/MessageBand.tsx +39 -0
  90. inspect_ai/_view/www/src/components/MorePopOver.css +0 -0
  91. inspect_ai/_view/www/src/components/MorePopOver.tsx +67 -0
  92. inspect_ai/_view/www/src/components/NavPills.module.css +18 -0
  93. inspect_ai/_view/www/src/components/NavPills.tsx +101 -0
  94. inspect_ai/_view/www/src/components/ProgressBar.module.css +37 -0
  95. inspect_ai/_view/www/src/components/ProgressBar.tsx +22 -0
  96. inspect_ai/_view/www/src/components/TabSet.module.css +40 -0
  97. inspect_ai/_view/www/src/components/TabSet.tsx +215 -0
  98. inspect_ai/_view/www/src/components/ToolButton.css +3 -0
  99. inspect_ai/_view/www/src/components/ToolButton.tsx +27 -0
  100. inspect_ai/_view/www/src/components/VirtualList.module.css +19 -0
  101. inspect_ai/_view/www/src/components/VirtualList.tsx +292 -0
  102. inspect_ai/_view/www/src/{index.js → index.tsx} +45 -19
  103. inspect_ai/_view/www/src/{log → logfile}/remoteLogFile.ts +3 -8
  104. inspect_ai/_view/www/src/{utils/remoteZipFile.mjs → logfile/remoteZipFile.ts} +86 -80
  105. inspect_ai/_view/www/src/metadata/MetaDataGrid.tsx +83 -0
  106. inspect_ai/_view/www/src/metadata/MetaDataView.module.css +35 -0
  107. inspect_ai/_view/www/src/metadata/MetaDataView.tsx +95 -0
  108. inspect_ai/_view/www/src/metadata/MetadataGrid.module.css +15 -0
  109. inspect_ai/_view/www/src/metadata/RenderedContent.module.css +12 -0
  110. inspect_ai/_view/www/src/{components/RenderedContent/RenderedContent.mjs → metadata/RenderedContent.tsx} +92 -73
  111. inspect_ai/_view/www/src/metadata/types.ts +18 -0
  112. inspect_ai/_view/www/src/plan/DatasetDetailView.module.css +3 -0
  113. inspect_ai/_view/www/src/plan/DatasetDetailView.tsx +37 -0
  114. inspect_ai/_view/www/src/plan/DetailStep.module.css +9 -0
  115. inspect_ai/_view/www/src/plan/DetailStep.tsx +31 -0
  116. inspect_ai/_view/www/src/plan/PlanCard.tsx +28 -0
  117. inspect_ai/_view/www/src/plan/PlanDetailView.module.css +48 -0
  118. inspect_ai/_view/www/src/plan/PlanDetailView.tsx +324 -0
  119. inspect_ai/_view/www/src/plan/ScorerDetailView.module.css +3 -0
  120. inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +30 -0
  121. inspect_ai/_view/www/src/plan/SolverDetailView.module.css +15 -0
  122. inspect_ai/_view/www/src/plan/SolverDetailView.tsx +32 -0
  123. inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +8 -0
  124. inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +53 -0
  125. inspect_ai/_view/www/src/samples/SampleDialog.tsx +122 -0
  126. inspect_ai/_view/www/src/samples/SampleDisplay.module.css +29 -0
  127. inspect_ai/_view/www/src/samples/SampleDisplay.tsx +331 -0
  128. inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +24 -0
  129. inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +177 -0
  130. inspect_ai/_view/www/src/samples/SamplesTools.tsx +52 -0
  131. inspect_ai/_view/www/src/samples/chat/ChatMessage.module.css +29 -0
  132. inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +76 -0
  133. inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +60 -0
  134. inspect_ai/_view/www/src/samples/chat/ChatMessageRow.module.css +9 -0
  135. inspect_ai/_view/www/src/samples/chat/ChatMessageRow.tsx +57 -0
  136. inspect_ai/_view/www/src/samples/chat/ChatView.tsx +47 -0
  137. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.module.css +4 -0
  138. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +58 -0
  139. inspect_ai/_view/www/src/samples/chat/MessageContent.module.css +4 -0
  140. inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +157 -0
  141. inspect_ai/_view/www/src/samples/chat/MessageContents.module.css +3 -0
  142. inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +133 -0
  143. inspect_ai/_view/www/src/samples/chat/messages.ts +112 -0
  144. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +147 -0
  145. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.module.css +14 -0
  146. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +76 -0
  147. inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.module.css +19 -0
  148. inspect_ai/_view/www/src/samples/chat/tools/ToolOutput.tsx +60 -0
  149. inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.module.css +4 -0
  150. inspect_ai/_view/www/src/samples/chat/tools/ToolTitle.tsx +18 -0
  151. inspect_ai/_view/www/src/samples/chat/tools/tool.ts +92 -0
  152. inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +365 -0
  153. inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.module.css +22 -0
  154. inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.tsx +26 -0
  155. inspect_ai/_view/www/src/samples/descriptor/score/CategoricalScoreDescriptor.tsx +18 -0
  156. inspect_ai/_view/www/src/samples/descriptor/score/NumericScoreDescriptor.tsx +27 -0
  157. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.module.css +18 -0
  158. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +71 -0
  159. inspect_ai/_view/www/src/samples/descriptor/score/OtherScoreDescriptor.tsx +20 -0
  160. inspect_ai/_view/www/src/samples/descriptor/score/PassFailScoreDescriptor.module.css +28 -0
  161. inspect_ai/_view/www/src/samples/descriptor/score/PassFailScoreDescriptor.tsx +81 -0
  162. inspect_ai/_view/www/src/samples/descriptor/score/ScoreDescriptor.tsx +99 -0
  163. inspect_ai/_view/www/src/samples/descriptor/types.ts +55 -0
  164. inspect_ai/_view/www/src/samples/error/FlatSampleErrorView.module.css +19 -0
  165. inspect_ai/_view/www/src/samples/error/FlatSampleErrorView.tsx +22 -0
  166. inspect_ai/_view/www/src/samples/error/SampleErrorView.module.css +17 -0
  167. inspect_ai/_view/www/src/samples/error/SampleErrorView.tsx +31 -0
  168. inspect_ai/_view/www/src/samples/error/error.ts +15 -0
  169. inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +9 -0
  170. inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +14 -0
  171. inspect_ai/_view/www/src/samples/list/SampleHeader.module.css +13 -0
  172. inspect_ai/_view/www/src/samples/list/SampleHeader.tsx +36 -0
  173. inspect_ai/_view/www/src/samples/list/SampleList.module.css +11 -0
  174. inspect_ai/_view/www/src/samples/list/SampleList.tsx +247 -0
  175. inspect_ai/_view/www/src/samples/list/SampleRow.module.css +33 -0
  176. inspect_ai/_view/www/src/samples/list/SampleRow.tsx +98 -0
  177. inspect_ai/_view/www/src/samples/list/SampleSeparator.module.css +6 -0
  178. inspect_ai/_view/www/src/samples/list/SampleSeparator.tsx +24 -0
  179. inspect_ai/_view/www/src/samples/sample-tools/EpochFilter.module.css +9 -0
  180. inspect_ai/_view/www/src/samples/sample-tools/EpochFilter.tsx +51 -0
  181. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.module.css +16 -0
  182. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +175 -0
  183. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.module.css +9 -0
  184. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +186 -0
  185. inspect_ai/_view/www/src/samples/{tools/filters.mjs → sample-tools/filters.ts} +86 -81
  186. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.module.css +16 -0
  187. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +288 -0
  188. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/completions.ts +346 -0
  189. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/language.ts +19 -0
  190. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/tokenize.ts +97 -0
  191. inspect_ai/_view/www/src/samples/{SampleLimit.mjs → sampleLimit.ts} +3 -6
  192. inspect_ai/_view/www/src/samples/scores/SampleScoreView.module.css +53 -0
  193. inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +168 -0
  194. inspect_ai/_view/www/src/samples/scores/SampleScores.module.css +5 -0
  195. inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +37 -0
  196. inspect_ai/_view/www/src/samples/transcript/ApprovalEventView.tsx +66 -0
  197. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +51 -0
  198. inspect_ai/_view/www/src/samples/transcript/InfoEventView.module.css +3 -0
  199. inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +54 -0
  200. inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +48 -0
  201. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.module.css +6 -0
  202. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.tsx +36 -0
  203. inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +43 -0
  204. inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +223 -0
  205. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.module.css +23 -0
  206. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +112 -0
  207. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +75 -0
  208. inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +22 -0
  209. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.module.css +15 -0
  210. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +100 -0
  211. inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +171 -0
  212. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.module.css +19 -0
  213. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +133 -0
  214. inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +10 -0
  215. inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +92 -0
  216. inspect_ai/_view/www/src/samples/transcript/TranscriptView.module.css +49 -0
  217. inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +449 -0
  218. inspect_ai/_view/www/src/samples/transcript/event/EventNav.module.css +5 -0
  219. inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +43 -0
  220. inspect_ai/_view/www/src/samples/transcript/event/EventNavs.module.css +3 -0
  221. inspect_ai/_view/www/src/samples/transcript/event/EventNavs.tsx +39 -0
  222. inspect_ai/_view/www/src/samples/transcript/event/EventPanel.module.css +25 -0
  223. inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +191 -0
  224. inspect_ai/_view/www/src/samples/transcript/event/EventRow.module.css +13 -0
  225. inspect_ai/_view/www/src/samples/transcript/event/EventRow.tsx +32 -0
  226. inspect_ai/_view/www/src/samples/transcript/event/EventSection.module.css +8 -0
  227. inspect_ai/_view/www/src/samples/transcript/event/EventSection.tsx +29 -0
  228. inspect_ai/_view/www/src/samples/transcript/state/StateDiffView.tsx +67 -0
  229. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +285 -0
  230. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenders.module.css +10 -0
  231. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.module.css +9 -0
  232. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +346 -0
  233. inspect_ai/_view/www/src/samples/transcript/types.ts +58 -0
  234. inspect_ai/_view/www/src/types/log.d.ts +108 -19
  235. inspect_ai/_view/www/src/types/prism.d.ts +11 -0
  236. inspect_ai/_view/www/src/types.ts +71 -0
  237. inspect_ai/_view/www/src/usage/ModelTokenTable.tsx +28 -0
  238. inspect_ai/_view/www/src/usage/ModelUsagePanel.module.css +24 -0
  239. inspect_ai/_view/www/src/usage/ModelUsagePanel.tsx +97 -0
  240. inspect_ai/_view/www/src/usage/TokenTable.module.css +17 -0
  241. inspect_ai/_view/www/src/usage/TokenTable.tsx +91 -0
  242. inspect_ai/_view/www/src/usage/UsageCard.module.css +15 -0
  243. inspect_ai/_view/www/src/usage/UsageCard.tsx +67 -0
  244. inspect_ai/_view/www/src/utils/attachments.ts +42 -0
  245. inspect_ai/_view/www/src/utils/{Base64.mjs → base64.ts} +1 -6
  246. inspect_ai/_view/www/src/{components/Browser.mjs → utils/browser.ts} +0 -1
  247. inspect_ai/_view/www/src/utils/debugging.ts +28 -0
  248. inspect_ai/_view/www/src/utils/dom.ts +30 -0
  249. inspect_ai/_view/www/src/utils/format.ts +194 -0
  250. inspect_ai/_view/www/src/utils/git.ts +7 -0
  251. inspect_ai/_view/www/src/utils/html.ts +6 -0
  252. inspect_ai/_view/www/src/utils/http.ts +14 -0
  253. inspect_ai/_view/www/src/utils/{Path.mjs → path.ts} +2 -9
  254. inspect_ai/_view/www/src/utils/{Print.mjs → print.ts} +34 -26
  255. inspect_ai/_view/www/src/utils/queue.ts +51 -0
  256. inspect_ai/_view/www/src/utils/sync.ts +114 -0
  257. inspect_ai/_view/www/src/utils/{Type.mjs → type.ts} +3 -6
  258. inspect_ai/_view/www/src/utils/vscode.ts +13 -0
  259. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +324 -0
  260. inspect_ai/_view/www/src/workspace/WorkSpaceView.module.css +33 -0
  261. inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +158 -0
  262. inspect_ai/_view/www/src/workspace/error/TaskErrorPanel.module.css +3 -0
  263. inspect_ai/_view/www/src/workspace/error/TaskErrorPanel.tsx +28 -0
  264. inspect_ai/_view/www/src/workspace/navbar/Navbar.module.css +54 -0
  265. inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +68 -0
  266. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +52 -0
  267. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +114 -0
  268. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +90 -0
  269. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +180 -0
  270. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.module.css +28 -0
  271. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +226 -0
  272. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.module.css +14 -0
  273. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +61 -0
  274. inspect_ai/_view/www/src/workspace/sidebar/EvalStatus.module.css +15 -0
  275. inspect_ai/_view/www/src/workspace/sidebar/EvalStatus.tsx +71 -0
  276. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.module.css +5 -0
  277. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +56 -0
  278. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.module.css +68 -0
  279. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +85 -0
  280. inspect_ai/_view/www/src/workspace/sidebar/SidebarLogEntry.module.css +29 -0
  281. inspect_ai/_view/www/src/workspace/sidebar/SidebarLogEntry.tsx +95 -0
  282. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoreView.module.css +23 -0
  283. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoreView.tsx +43 -0
  284. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoresView.module.css +35 -0
  285. inspect_ai/_view/www/src/workspace/sidebar/SidebarScoresView.tsx +63 -0
  286. inspect_ai/_view/www/src/workspace/tabs/InfoTab.module.css +0 -0
  287. inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +70 -0
  288. inspect_ai/_view/www/src/workspace/tabs/JsonTab.module.css +5 -0
  289. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +46 -0
  290. inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +204 -0
  291. inspect_ai/_view/www/src/workspace/tabs/grouping.ts +195 -0
  292. inspect_ai/_view/www/src/workspace/tabs/types.ts +19 -0
  293. inspect_ai/_view/www/src/workspace/types.ts +10 -0
  294. inspect_ai/_view/www/src/workspace/utils.ts +34 -0
  295. inspect_ai/_view/www/tsconfig.json +23 -9
  296. inspect_ai/_view/www/vite.config.js +8 -17
  297. inspect_ai/_view/www/yarn.lock +627 -556
  298. inspect_ai/approval/_approval.py +2 -0
  299. inspect_ai/approval/_approver.py +4 -4
  300. inspect_ai/approval/_auto.py +1 -1
  301. inspect_ai/approval/_human/approver.py +3 -0
  302. inspect_ai/approval/_policy.py +5 -0
  303. inspect_ai/approval/_registry.py +2 -2
  304. inspect_ai/dataset/_dataset.py +64 -37
  305. inspect_ai/dataset/_sources/__init__.py +0 -0
  306. inspect_ai/dataset/_sources/csv.py +20 -12
  307. inspect_ai/dataset/_sources/file.py +4 -0
  308. inspect_ai/dataset/_sources/hf.py +39 -29
  309. inspect_ai/dataset/_sources/json.py +17 -9
  310. inspect_ai/log/__init__.py +2 -0
  311. inspect_ai/log/_convert.py +3 -3
  312. inspect_ai/log/_file.py +24 -9
  313. inspect_ai/log/_log.py +101 -13
  314. inspect_ai/log/_message.py +4 -2
  315. inspect_ai/log/_recorders/file.py +4 -0
  316. inspect_ai/log/_recorders/json.py +5 -7
  317. inspect_ai/log/_recorders/recorder.py +3 -0
  318. inspect_ai/log/_transcript.py +19 -8
  319. inspect_ai/model/__init__.py +2 -0
  320. inspect_ai/model/_cache.py +39 -21
  321. inspect_ai/model/_call_tools.py +4 -3
  322. inspect_ai/model/_chat_message.py +14 -4
  323. inspect_ai/model/_generate_config.py +1 -1
  324. inspect_ai/model/_model.py +31 -24
  325. inspect_ai/model/_model_output.py +14 -1
  326. inspect_ai/model/_openai.py +10 -18
  327. inspect_ai/model/_providers/anthropic.py +3 -3
  328. inspect_ai/model/_providers/google.py +9 -5
  329. inspect_ai/model/_providers/openai.py +5 -9
  330. inspect_ai/model/_providers/openai_o1.py +3 -5
  331. inspect_ai/model/_providers/openrouter.py +86 -0
  332. inspect_ai/model/_providers/providers.py +11 -0
  333. inspect_ai/scorer/__init__.py +6 -1
  334. inspect_ai/scorer/_answer.py +7 -7
  335. inspect_ai/scorer/_classification.py +38 -18
  336. inspect_ai/scorer/_common.py +2 -8
  337. inspect_ai/scorer/_match.py +4 -5
  338. inspect_ai/scorer/_metric.py +87 -28
  339. inspect_ai/scorer/_metrics/__init__.py +3 -3
  340. inspect_ai/scorer/_metrics/accuracy.py +8 -10
  341. inspect_ai/scorer/_metrics/mean.py +3 -17
  342. inspect_ai/scorer/_metrics/std.py +111 -30
  343. inspect_ai/scorer/_model.py +12 -12
  344. inspect_ai/scorer/_pattern.py +3 -3
  345. inspect_ai/scorer/_reducer/reducer.py +36 -21
  346. inspect_ai/scorer/_reducer/registry.py +2 -2
  347. inspect_ai/scorer/_reducer/types.py +7 -1
  348. inspect_ai/scorer/_score.py +11 -1
  349. inspect_ai/scorer/_scorer.py +110 -16
  350. inspect_ai/solver/__init__.py +1 -1
  351. inspect_ai/solver/_basic_agent.py +19 -22
  352. inspect_ai/solver/_bridge/__init__.py +0 -3
  353. inspect_ai/solver/_bridge/bridge.py +3 -3
  354. inspect_ai/solver/_chain.py +1 -2
  355. inspect_ai/solver/_critique.py +3 -3
  356. inspect_ai/solver/_fork.py +2 -2
  357. inspect_ai/solver/_human_agent/__init__.py +0 -0
  358. inspect_ai/solver/_human_agent/agent.py +5 -8
  359. inspect_ai/solver/_human_agent/commands/clock.py +14 -10
  360. inspect_ai/solver/_human_agent/commands/note.py +1 -1
  361. inspect_ai/solver/_human_agent/commands/score.py +0 -11
  362. inspect_ai/solver/_multiple_choice.py +38 -26
  363. inspect_ai/solver/_prompt.py +7 -7
  364. inspect_ai/solver/_solver.py +53 -52
  365. inspect_ai/solver/_task_state.py +80 -69
  366. inspect_ai/solver/_use_tools.py +9 -9
  367. inspect_ai/tool/__init__.py +4 -1
  368. inspect_ai/tool/_tool.py +43 -14
  369. inspect_ai/tool/_tool_call.py +6 -2
  370. inspect_ai/tool/_tool_choice.py +3 -1
  371. inspect_ai/tool/_tool_def.py +10 -8
  372. inspect_ai/tool/_tool_params.py +24 -0
  373. inspect_ai/tool/_tool_with.py +7 -7
  374. inspect_ai/tool/_tools/__init__.py +0 -0
  375. inspect_ai/tool/{beta → _tools}/_computer/_common.py +2 -2
  376. inspect_ai/tool/{beta → _tools}/_computer/_computer.py +13 -5
  377. inspect_ai/tool/_tools/_computer/_resources/tool/__init__.py +0 -0
  378. inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_x11_client.py +1 -1
  379. inspect_ai/tool/_tools/_computer/_resources/tool/requirements.txt +0 -0
  380. inspect_ai/tool/_tools/_execute.py +23 -11
  381. inspect_ai/tool/_tools/_web_browser/_resources/README.md +2 -2
  382. inspect_ai/tool/_tools/_web_browser/_web_browser.py +5 -3
  383. inspect_ai/tool/_tools/_web_search.py +7 -5
  384. inspect_ai/tool/beta.py +3 -0
  385. inspect_ai/util/_concurrency.py +3 -3
  386. inspect_ai/util/_panel.py +2 -0
  387. inspect_ai/util/_resource.py +12 -12
  388. inspect_ai/util/_sandbox/docker/compose.py +23 -20
  389. inspect_ai/util/_sandbox/docker/config.py +2 -1
  390. inspect_ai/util/_sandbox/docker/docker.py +42 -86
  391. inspect_ai/util/_sandbox/docker/service.py +100 -0
  392. inspect_ai/util/_sandbox/environment.py +99 -96
  393. inspect_ai/util/_sandbox/self_check.py +124 -16
  394. inspect_ai/util/_subprocess.py +5 -3
  395. inspect_ai/util/_subtask.py +15 -16
  396. {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/LICENSE +1 -1
  397. {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/METADATA +11 -6
  398. inspect_ai-0.3.64.dist-info/RECORD +625 -0
  399. inspect_ai/_view/www/src/Register.mjs +0 -3
  400. inspect_ai/_view/www/src/Types.mjs +0 -38
  401. inspect_ai/_view/www/src/appearance/Colors.mjs +0 -27
  402. inspect_ai/_view/www/src/appearance/Fonts.mjs +0 -66
  403. inspect_ai/_view/www/src/appearance/Icons.mjs +0 -240
  404. inspect_ai/_view/www/src/components/AnsiDisplay.mjs +0 -184
  405. inspect_ai/_view/www/src/components/AppErrorBoundary.mjs +0 -34
  406. inspect_ai/_view/www/src/components/AsciiCinemaPlayer.mjs +0 -74
  407. inspect_ai/_view/www/src/components/Card.mjs +0 -126
  408. inspect_ai/_view/www/src/components/ChatView.mjs +0 -441
  409. inspect_ai/_view/www/src/components/CopyButton.mjs +0 -48
  410. inspect_ai/_view/www/src/components/Dialog.mjs +0 -61
  411. inspect_ai/_view/www/src/components/DownloadButton.mjs +0 -15
  412. inspect_ai/_view/www/src/components/DownloadPanel.mjs +0 -29
  413. inspect_ai/_view/www/src/components/EmptyPanel.mjs +0 -23
  414. inspect_ai/_view/www/src/components/ErrorPanel.mjs +0 -66
  415. inspect_ai/_view/www/src/components/ExpandablePanel.mjs +0 -136
  416. inspect_ai/_view/www/src/components/FindBand.mjs +0 -157
  417. inspect_ai/_view/www/src/components/HumanBaselineView.mjs +0 -168
  418. inspect_ai/_view/www/src/components/JsonPanel.mjs +0 -61
  419. inspect_ai/_view/www/src/components/LabeledValue.mjs +0 -32
  420. inspect_ai/_view/www/src/components/LargeModal.mjs +0 -190
  421. inspect_ai/_view/www/src/components/LightboxCarousel.mjs +0 -217
  422. inspect_ai/_view/www/src/components/MarkdownDiv.mjs +0 -118
  423. inspect_ai/_view/www/src/components/MessageBand.mjs +0 -48
  424. inspect_ai/_view/www/src/components/MessageContent.mjs +0 -111
  425. inspect_ai/_view/www/src/components/MetaDataGrid.mjs +0 -92
  426. inspect_ai/_view/www/src/components/MetaDataView.mjs +0 -109
  427. inspect_ai/_view/www/src/components/MorePopOver.mjs +0 -50
  428. inspect_ai/_view/www/src/components/NavPills.mjs +0 -63
  429. inspect_ai/_view/www/src/components/ProgressBar.mjs +0 -51
  430. inspect_ai/_view/www/src/components/RenderedContent/ChatMessageRenderer.mjs +0 -54
  431. inspect_ai/_view/www/src/components/RenderedContent/Types.mjs +0 -19
  432. inspect_ai/_view/www/src/components/TabSet.mjs +0 -184
  433. inspect_ai/_view/www/src/components/ToolButton.mjs +0 -16
  434. inspect_ai/_view/www/src/components/Tools.mjs +0 -376
  435. inspect_ai/_view/www/src/components/VirtualList.mjs +0 -280
  436. inspect_ai/_view/www/src/components/ansi-output.js +0 -932
  437. inspect_ai/_view/www/src/json/JsonTab.mjs +0 -48
  438. inspect_ai/_view/www/src/log-reader/Log-Reader.mjs +0 -25
  439. inspect_ai/_view/www/src/log-reader/Native-Log-Reader.mjs +0 -13
  440. inspect_ai/_view/www/src/log-reader/Open-AI-Log-Reader.mjs +0 -263
  441. inspect_ai/_view/www/src/navbar/Navbar.mjs +0 -418
  442. inspect_ai/_view/www/src/navbar/SecondaryBar.mjs +0 -175
  443. inspect_ai/_view/www/src/plan/PlanCard.mjs +0 -418
  444. inspect_ai/_view/www/src/samples/SampleDialog.mjs +0 -123
  445. inspect_ai/_view/www/src/samples/SampleDisplay.mjs +0 -516
  446. inspect_ai/_view/www/src/samples/SampleError.mjs +0 -99
  447. inspect_ai/_view/www/src/samples/SampleList.mjs +0 -427
  448. inspect_ai/_view/www/src/samples/SampleScoreView.mjs +0 -172
  449. inspect_ai/_view/www/src/samples/SampleScores.mjs +0 -34
  450. inspect_ai/_view/www/src/samples/SampleTranscript.mjs +0 -20
  451. inspect_ai/_view/www/src/samples/SamplesDescriptor.mjs +0 -771
  452. inspect_ai/_view/www/src/samples/SamplesTab.mjs +0 -399
  453. inspect_ai/_view/www/src/samples/SamplesTools.mjs +0 -64
  454. inspect_ai/_view/www/src/samples/tools/EpochFilter.mjs +0 -38
  455. inspect_ai/_view/www/src/samples/tools/SampleFilter.mjs +0 -756
  456. inspect_ai/_view/www/src/samples/tools/SelectScorer.mjs +0 -141
  457. inspect_ai/_view/www/src/samples/tools/SortFilter.mjs +0 -151
  458. inspect_ai/_view/www/src/samples/transcript/ApprovalEventView.mjs +0 -71
  459. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.mjs +0 -44
  460. inspect_ai/_view/www/src/samples/transcript/EventPanel.mjs +0 -271
  461. inspect_ai/_view/www/src/samples/transcript/EventRow.mjs +0 -46
  462. inspect_ai/_view/www/src/samples/transcript/EventSection.mjs +0 -33
  463. inspect_ai/_view/www/src/samples/transcript/InfoEventView.mjs +0 -59
  464. inspect_ai/_view/www/src/samples/transcript/InputEventView.mjs +0 -44
  465. inspect_ai/_view/www/src/samples/transcript/LoggerEventView.mjs +0 -32
  466. inspect_ai/_view/www/src/samples/transcript/ModelEventView.mjs +0 -216
  467. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.mjs +0 -107
  468. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.mjs +0 -74
  469. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.mjs +0 -100
  470. inspect_ai/_view/www/src/samples/transcript/StepEventView.mjs +0 -187
  471. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.mjs +0 -133
  472. inspect_ai/_view/www/src/samples/transcript/ToolEventView.mjs +0 -88
  473. inspect_ai/_view/www/src/samples/transcript/TranscriptView.mjs +0 -459
  474. inspect_ai/_view/www/src/samples/transcript/Types.mjs +0 -44
  475. inspect_ai/_view/www/src/samples/transcript/state/StateDiffView.mjs +0 -53
  476. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.mjs +0 -254
  477. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.mjs +0 -313
  478. inspect_ai/_view/www/src/sidebar/Sidebar.mjs +0 -418
  479. inspect_ai/_view/www/src/usage/ModelTokenTable.mjs +0 -72
  480. inspect_ai/_view/www/src/usage/UsageCard.mjs +0 -159
  481. inspect_ai/_view/www/src/utils/Format.mjs +0 -260
  482. inspect_ai/_view/www/src/utils/Git.mjs +0 -12
  483. inspect_ai/_view/www/src/utils/Html.mjs +0 -21
  484. inspect_ai/_view/www/src/utils/attachments.mjs +0 -31
  485. inspect_ai/_view/www/src/utils/debugging.mjs +0 -23
  486. inspect_ai/_view/www/src/utils/http.mjs +0 -18
  487. inspect_ai/_view/www/src/utils/queue.mjs +0 -67
  488. inspect_ai/_view/www/src/utils/sync.mjs +0 -101
  489. inspect_ai/_view/www/src/workspace/TaskErrorPanel.mjs +0 -17
  490. inspect_ai/_view/www/src/workspace/WorkSpace.mjs +0 -516
  491. inspect_ai/tool/beta/__init__.py +0 -5
  492. inspect_ai-0.3.62.dist-info/RECORD +0 -481
  493. /inspect_ai/{tool/beta/_computer/_resources/tool → _eval}/__init__.py +0 -0
  494. /inspect_ai/{tool/beta/_computer/_resources/tool/requirements.txt → _util/__init__.py} +0 -0
  495. /inspect_ai/_view/www/src/{constants.mjs → constants.ts} +0 -0
  496. /inspect_ai/tool/{beta → _tools}/_computer/__init__.py +0 -0
  497. /inspect_ai/tool/{beta → _tools}/_computer/_computer_split.py +0 -0
  498. /inspect_ai/tool/{beta → _tools}/_computer/_resources/Dockerfile +0 -0
  499. /inspect_ai/tool/{beta → _tools}/_computer/_resources/README.md +0 -0
  500. /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/entrypoint.sh +0 -0
  501. /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/novnc_startup.sh +0 -0
  502. /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/x11vnc_startup.sh +0 -0
  503. /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/xfce_startup.sh +0 -0
  504. /inspect_ai/tool/{beta → _tools}/_computer/_resources/entrypoint/xvfb_startup.sh +0 -0
  505. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/Code/User/globalStorage/state.vscdb +0 -0
  506. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/Code/User/settings.json +0 -0
  507. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml +0 -0
  508. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-screensaver.xml +0 -0
  509. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/Desktop/Firefox Web Browser.desktop +0 -0
  510. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/Desktop/Terminal.desktop +0 -0
  511. /inspect_ai/tool/{beta → _tools}/_computer/_resources/image_home_dir/Desktop/Visual Studio Code.desktop +0 -0
  512. /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_logger.py +0 -0
  513. /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_run.py +0 -0
  514. /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/_tool_result.py +0 -0
  515. /inspect_ai/tool/{beta → _tools}/_computer/_resources/tool/computer_tool.py +0 -0
  516. {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/WHEEL +0 -0
  517. {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/entry_points.txt +0 -0
  518. {inspect_ai-0.3.62.dist-info → inspect_ai-0.3.64.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,292 @@
1
+ import clsx from "clsx";
2
+ import React, {
3
+ forwardRef,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useMemo,
7
+ useRef,
8
+ useState,
9
+ } from "react";
10
+ import styles from "./VirtualList.module.css";
11
+
12
+ export interface VirtualListRef {
13
+ focus: () => void;
14
+ scrollToIndex: (index: number, direction?: "up" | "down") => void;
15
+ }
16
+
17
+ interface VirtualListProps<T> {
18
+ data: T[];
19
+ renderRow: (item: T, index: number) => React.ReactNode;
20
+ overscanCount?: number;
21
+ initialEstimatedRowHeight?: number;
22
+ sync?: boolean;
23
+ scrollRef?: React.RefObject<HTMLElement | null>;
24
+ className?: string;
25
+ style?: React.CSSProperties;
26
+ tabIndex?: number;
27
+ onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
28
+ }
29
+
30
+ interface ListMetrics {
31
+ rowHeights: Map<number, number>;
32
+ totalHeight: number;
33
+ estimatedRowHeight: number;
34
+ }
35
+
36
+ export const VirtualList = forwardRef(function VirtualList<T>(
37
+ {
38
+ data,
39
+ renderRow,
40
+ overscanCount = 15,
41
+ initialEstimatedRowHeight = 50,
42
+ sync = false,
43
+ scrollRef,
44
+ onKeyDown,
45
+ ...props
46
+ }: VirtualListProps<T>,
47
+ ref: React.Ref<VirtualListRef>,
48
+ ) {
49
+ const [height, setHeight] = useState(0);
50
+ const [offset, setOffset] = useState(0);
51
+ const [listMetrics, setListMetrics] = useState<ListMetrics>({
52
+ rowHeights: new Map(),
53
+ totalHeight: data.length * initialEstimatedRowHeight,
54
+ estimatedRowHeight: initialEstimatedRowHeight,
55
+ });
56
+
57
+ const baseRef = useRef<HTMLDivElement>(null);
58
+ const containerRef = useRef<HTMLDivElement>(null);
59
+ const rowRefs = useRef<Map<number, HTMLElement>>(new Map());
60
+
61
+ const getRowHeight = (index: number): number => {
62
+ return listMetrics.rowHeights.get(index) || listMetrics.estimatedRowHeight;
63
+ };
64
+
65
+ // Calculate new estimated height based on measured rows
66
+ const calculateEstimatedHeight = (heights: Map<number, number>): number => {
67
+ if (heights.size === 0) return listMetrics.estimatedRowHeight;
68
+
69
+ // Calculate average of measured heights
70
+ let sum = 0;
71
+ heights.forEach((height) => {
72
+ sum += height;
73
+ });
74
+
75
+ // Use exponential moving average to smooth transitions
76
+ const alpha = 0.2; // Smoothing factor
77
+ const newEstimate = sum / heights.size;
78
+ return Math.round(
79
+ alpha * newEstimate + (1 - alpha) * listMetrics.estimatedRowHeight,
80
+ );
81
+ };
82
+
83
+ const rowPositions = useMemo(() => {
84
+ let currentPosition = 0;
85
+ const positions = new Map<number, number>();
86
+
87
+ for (let i = 0; i < data.length; i++) {
88
+ positions.set(i, currentPosition);
89
+ currentPosition += getRowHeight(i);
90
+ }
91
+
92
+ return positions;
93
+ }, [listMetrics.rowHeights, listMetrics.estimatedRowHeight, data.length]);
94
+
95
+ // Measure rendered rows and update heights if needed
96
+ const measureRows = () => {
97
+ let updates: [number, number][] = [];
98
+
99
+ rowRefs.current.forEach((element, index) => {
100
+ if (element) {
101
+ const measuredHeight = element.offsetHeight;
102
+ if (
103
+ measuredHeight &&
104
+ measuredHeight !== listMetrics.rowHeights.get(index)
105
+ ) {
106
+ updates.push([index, measuredHeight]);
107
+ }
108
+ }
109
+ });
110
+
111
+ if (updates.length === 0) return;
112
+
113
+ const newHeights = new Map(listMetrics.rowHeights);
114
+ updates.forEach(([index, height]) => {
115
+ newHeights.set(index, height);
116
+ });
117
+
118
+ // Calculate new estimated height
119
+ const newEstimatedHeight = calculateEstimatedHeight(newHeights);
120
+
121
+ let newTotalHeight = 0;
122
+ for (let i = 0; i < data.length; i++) {
123
+ newTotalHeight += newHeights.get(i) || newEstimatedHeight;
124
+ }
125
+
126
+ setListMetrics({
127
+ rowHeights: newHeights,
128
+ totalHeight: newTotalHeight,
129
+ estimatedRowHeight: newEstimatedHeight,
130
+ });
131
+ };
132
+
133
+ useImperativeHandle(
134
+ ref,
135
+ () => ({
136
+ focus: () => {
137
+ baseRef.current?.focus();
138
+ },
139
+ scrollToIndex: (index: number, direction?: "up" | "down") => {
140
+ const scrollElement = scrollRef?.current || baseRef.current;
141
+ if (!scrollElement || index < 0 || index >= data.length) return;
142
+
143
+ const currentScrollTop = scrollElement.scrollTop;
144
+ const viewportHeight = scrollElement.offsetHeight;
145
+
146
+ const rowTop = rowPositions.get(index) || 0;
147
+ const rowHeight = getRowHeight(index);
148
+ const rowBottom = rowTop + rowHeight;
149
+
150
+ const isVisible =
151
+ rowTop >= currentScrollTop &&
152
+ rowBottom <= currentScrollTop + viewportHeight;
153
+ if (isVisible) return;
154
+
155
+ let newScrollTop: number;
156
+ if (direction === "up") {
157
+ newScrollTop = rowTop;
158
+ } else {
159
+ newScrollTop = rowBottom - viewportHeight;
160
+ }
161
+
162
+ newScrollTop = Math.max(
163
+ 0,
164
+ Math.min(newScrollTop, listMetrics.totalHeight - viewportHeight),
165
+ );
166
+ scrollElement.scrollTop = newScrollTop;
167
+ },
168
+ }),
169
+ [rowPositions, data.length],
170
+ );
171
+
172
+ const resize = () => {
173
+ const scrollElement = scrollRef?.current || baseRef.current;
174
+ if (scrollElement && height !== scrollElement.offsetHeight) {
175
+ setHeight(scrollElement.offsetHeight);
176
+ }
177
+ };
178
+
179
+ const handleScroll = throttle(() => {
180
+ const scrollElement = scrollRef?.current || baseRef.current;
181
+ if (scrollElement) {
182
+ setOffset(scrollElement.scrollTop);
183
+ }
184
+ if (sync) {
185
+ setOffset((prev) => prev);
186
+ }
187
+ }, 100);
188
+
189
+ useEffect(() => {
190
+ resize();
191
+ const scrollElement = scrollRef?.current || baseRef.current;
192
+
193
+ if (scrollElement) {
194
+ scrollElement.addEventListener("scroll", handleScroll);
195
+ window.addEventListener("resize", resize);
196
+
197
+ return () => {
198
+ scrollElement.removeEventListener("scroll", handleScroll);
199
+ window.removeEventListener("resize", resize);
200
+ };
201
+ }
202
+ }, [scrollRef?.current]);
203
+
204
+ useEffect(() => {
205
+ measureRows();
206
+ });
207
+
208
+ const findRowAtOffset = (targetOffset: number): number => {
209
+ if (targetOffset <= 0) return 0;
210
+ if (targetOffset >= listMetrics.totalHeight) return data.length - 1;
211
+
212
+ let low = 0;
213
+ let high = data.length - 1;
214
+ let lastValid = 0;
215
+
216
+ while (low <= high) {
217
+ const mid = Math.floor((low + high) / 2);
218
+ const rowStart = rowPositions.get(mid) || 0;
219
+
220
+ if (rowStart <= targetOffset) {
221
+ lastValid = mid;
222
+ low = mid + 1;
223
+ } else {
224
+ high = mid - 1;
225
+ }
226
+ }
227
+ return lastValid;
228
+ };
229
+
230
+ const firstVisibleIdx = findRowAtOffset(offset);
231
+ const lastVisibleIdx = findRowAtOffset(offset + height);
232
+
233
+ const start = Math.max(0, firstVisibleIdx - overscanCount);
234
+ const end = Math.min(data.length, lastVisibleIdx + overscanCount);
235
+
236
+ const renderedRows = useMemo(() => {
237
+ const selection = data.slice(start, end);
238
+ return selection.map((item, index) => {
239
+ const actualIndex = start + index;
240
+ return (
241
+ <div
242
+ key={`list-item-${actualIndex}`}
243
+ ref={(el) => {
244
+ if (el) {
245
+ rowRefs.current.set(actualIndex, el);
246
+ } else {
247
+ rowRefs.current.delete(actualIndex);
248
+ }
249
+ }}
250
+ >
251
+ {renderRow(item, actualIndex)}
252
+ </div>
253
+ );
254
+ });
255
+ }, [data, start, end, renderRow]);
256
+
257
+ const top = rowPositions.get(start) || 0;
258
+ const scrollProps = scrollRef ? {} : { onScroll: handleScroll };
259
+
260
+ return (
261
+ <div ref={baseRef} {...props} {...scrollProps} onKeyDown={onKeyDown}>
262
+ <div
263
+ className={clsx(
264
+ styles.container,
265
+ !scrollRef?.current ? styles.hidden : undefined,
266
+ )}
267
+ style={{ height: `${listMetrics.totalHeight}px` }}
268
+ >
269
+ <div
270
+ className={styles.content}
271
+ style={{ transform: `translateY(${top}px)` }}
272
+ ref={containerRef}
273
+ >
274
+ {renderedRows}
275
+ </div>
276
+ </div>
277
+ </div>
278
+ );
279
+ }) as <T>(
280
+ props: VirtualListProps<T> & { ref?: React.Ref<VirtualListRef> },
281
+ ) => React.ReactElement;
282
+
283
+ const throttle = (func: (...args: any[]) => void, limit: number) => {
284
+ let inThrottle: boolean;
285
+ return function (this: any, ...args: any[]) {
286
+ if (!inThrottle) {
287
+ func.apply(this, args);
288
+ inThrottle = true;
289
+ setTimeout(() => (inThrottle = false), limit);
290
+ }
291
+ };
292
+ };
@@ -1,33 +1,59 @@
1
- import { render } from "preact";
2
- import { html } from "htm/preact";
3
-
4
- import { App } from "./App.mjs";
1
+ import { createRoot } from "react-dom/client";
2
+ import { App } from "./App";
5
3
  import api from "./api/index";
4
+ import { ApplicationState, Capabilities } from "./types";
5
+ import { throttle } from "./utils/sync";
6
6
  import { getVscodeApi } from "./utils/vscode";
7
- import { throttle } from "./utils/sync.mjs";
8
7
 
9
8
  // Read any state from the page itself
10
9
  const vscode = getVscodeApi();
11
10
  let initialState = undefined;
11
+ let capabilities: Capabilities = {
12
+ downloadFiles: true,
13
+ webWorkers: true,
14
+ };
12
15
  if (vscode) {
13
- initialState = filterState(vscode.getState());
16
+ initialState = filterState(vscode.getState() as ApplicationState);
17
+
18
+ // Determine the capabilities
19
+ const extensionVersionEl = document.querySelector(
20
+ 'meta[name="inspect-extension:version"]',
21
+ );
22
+ const extensionVersion = extensionVersionEl
23
+ ? extensionVersionEl.getAttribute("content")
24
+ : undefined;
25
+
26
+ if (!extensionVersion) {
27
+ capabilities = { downloadFiles: false, webWorkers: false };
28
+ }
29
+ }
30
+
31
+ const containerId = "app";
32
+ const container = document.getElementById(containerId);
33
+ if (!container) {
34
+ console.error("Root container not found");
35
+ throw new Error(
36
+ `Expected a container element with Id '${containerId}' but no such container element was present.`,
37
+ );
14
38
  }
15
39
 
16
- render(
17
- html`<${App}
18
- api=${api}
19
- initialState=${initialState}
20
- saveInitialState=${throttle((state) => {
40
+ const root = createRoot(container as HTMLElement);
41
+ root.render(
42
+ <App
43
+ api={api}
44
+ applicationState={initialState}
45
+ saveApplicationState={throttle((state) => {
21
46
  const vscode = getVscodeApi();
22
47
  if (vscode) {
23
48
  vscode.setState(filterState(state));
24
49
  }
25
50
  }, 1000)}
26
- />`,
27
- document.getElementById("app"),
51
+ capabilities={capabilities}
52
+ pollForLogs={false}
53
+ />,
28
54
  );
29
55
 
30
- function filterState(state) {
56
+ function filterState(state: ApplicationState) {
31
57
  if (!state) {
32
58
  return state;
33
59
  }
@@ -41,7 +67,7 @@ function filterState(state) {
41
67
  }
42
68
 
43
69
  // Filters the selected Sample if it is large
44
- function filterLargeSample(state) {
70
+ function filterLargeSample(state: ApplicationState) {
45
71
  if (!state || !state.selectedSample) {
46
72
  return state;
47
73
  }
@@ -56,7 +82,7 @@ function filterLargeSample(state) {
56
82
  }
57
83
 
58
84
  // Filters the selectedlog if it is too large
59
- function filterLargeSelectedLog(state) {
85
+ function filterLargeSelectedLog(state: ApplicationState) {
60
86
  if (!state || !state.selectedLog?.contents) {
61
87
  return state;
62
88
  }
@@ -72,8 +98,8 @@ function filterLargeSelectedLog(state) {
72
98
  }
73
99
  }
74
100
 
75
- function estimateSize(list, frequency = 0.2) {
76
- if (!list || list.len === 0) {
101
+ function estimateSize(list: unknown[], frequency = 0.2) {
102
+ if (!list || list.length === 0) {
77
103
  return 0;
78
104
  }
79
105
 
@@ -81,7 +107,7 @@ function estimateSize(list, frequency = 0.2) {
81
107
  const sampleSize = Math.ceil(list.length * frequency);
82
108
 
83
109
  // Get a proper random sample without duplicates
84
- const messageIndices = new Set();
110
+ const messageIndices = new Set<number>();
85
111
  while (
86
112
  messageIndices.size < sampleSize &&
87
113
  messageIndices.size < list.length
@@ -1,17 +1,13 @@
1
- //@ts-check
2
1
  import {
3
2
  EvalHeader,
4
3
  EvalSummary,
5
4
  LogViewAPI,
6
5
  SampleSummary,
7
- } from "../api/Types";
6
+ } from "../api/types";
8
7
  import { EvalLog, EvalPlan, EvalSample, EvalSpec } from "../types/log";
9
8
  import { asyncJsonParse } from "../utils/json-worker";
10
- import { AsyncQueue } from "../utils/queue.mjs";
11
- import {
12
- FileSizeLimitError,
13
- openRemoteZipFile,
14
- } from "../utils/remoteZipFile.mjs";
9
+ import { AsyncQueue } from "../utils/queue";
10
+ import { FileSizeLimitError, openRemoteZipFile } from "./remoteZipFile";
15
11
 
16
12
  // don't try to load samples greater than 50mb
17
13
  const MAX_BYTES = 50 * 1024 * 1024;
@@ -105,7 +101,6 @@ export const openRemoteLogFile = async (
105
101
  if (remoteZipFile.centralDirectory.has(sampleFile)) {
106
102
  return (await readJSONFile(sampleFile, MAX_BYTES)) as EvalSample;
107
103
  } else {
108
- console.log({ dir: remoteZipFile.centralDirectory });
109
104
  throw new Error(
110
105
  `Unable to read sample file ${sampleFile} - it is not present in the manifest.`,
111
106
  );
@@ -1,72 +1,60 @@
1
- //@ts-check
2
- import { decompress } from "fflate";
1
+ import { AsyncInflateOptions, decompress } from "fflate";
3
2
 
4
- /**
5
- * @typedef {Object} ZipFileEntry
6
- * @property {number} versionNeeded - The minimum version needed to extract the ZIP entry.
7
- * @property {number} bitFlag - The general purpose bit flag of the ZIP entry.
8
- * @property {number} compressionMethod - The compression method used for the ZIP entry.
9
- * @property {number} crc32 - The CRC-32 checksum of the uncompressed data.
10
- * @property {number} compressedSize - The size of the compressed data in bytes.
11
- * @property {number} uncompressedSize - The size of the uncompressed data in bytes.
12
- * @property {number} filenameLength - The length of the filename in bytes.
13
- * @property {number} extraFieldLength - The length of the extra field in bytes.
14
- * @property {Uint8Array} data - The compressed data for the ZIP entry.
15
- */
3
+ export interface ZipFileEntry {
4
+ versionNeeded: number;
5
+ bitFlag: number;
6
+ compressionMethod: number;
7
+ crc32: number;
8
+ compressedSize: number;
9
+ uncompressedSize: number;
10
+ filenameLength: number;
11
+ extraFieldLength: number;
12
+ data: Uint8Array;
13
+ }
16
14
 
17
- /**
18
- * @typedef {Object} CentralDirectoryEntry
19
- * @property {string} filename - The name of the file in the ZIP archive.
20
- * @property {number} compressionMethod - The compression method used for the file.
21
- * @property {number} compressedSize - The size of the compressed file in bytes.
22
- * @property {number} uncompressedSize - The size of the uncompressed file in bytes.
23
- * @property {number} fileOffset - The offset of the file's data in the ZIP archive.
24
- */
15
+ export interface CentralDirectoryEntry {
16
+ filename: string;
17
+ compressionMethod: number;
18
+ compressedSize: number;
19
+ uncompressedSize: number;
20
+ fileOffset: number;
21
+ }
25
22
 
26
23
  /**
27
24
  * Represents an error thrown when a file exceeds the maximum allowed size.
28
- *
29
- * @class
30
- * @extends {Error}
31
25
  */
32
26
  export class FileSizeLimitError extends Error {
33
- /**
34
- * Creates a new FileSizeLimitError.
35
- *
36
- * @param {string} file - The name of the file that caused the error.
37
- * @param {number} maxBytes - The maximum allowed size for the file, in bytes.
38
- */
39
- constructor(file, maxBytes) {
27
+ public readonly file: string;
28
+ public readonly maxBytes: number;
29
+
30
+ constructor(file: string, maxBytes: number) {
40
31
  super(
41
32
  `File "${file}" exceeds the maximum size (${maxBytes} bytes) and cannot be loaded.`,
42
33
  );
43
34
  this.name = "FileSizeLimitError";
44
35
  this.file = file;
45
36
  this.maxBytes = maxBytes;
37
+
38
+ Object.setPrototypeOf(this, FileSizeLimitError.prototype);
46
39
  }
47
40
  }
48
41
 
49
42
  /**
50
43
  * Opens a remote ZIP file from the specified URL, fetches and parses the central directory,
51
44
  * and provides a method to read files within the ZIP.
52
- *
53
- * @param {string} url - The URL of the remote ZIP file.
54
- * @param {(url: string) => Promise<number>} [fetchContentLength] - Optional function to compute the content length of the remote file.
55
- * @param {(url: string, start: number, end: number) => Promise<Uint8Array>} [fetchBytes] - Optional function to fetch a range of bytes from the remote file.
56
- * @returns {Promise<{
57
- * centralDirectory: Map<string, CentralDirectoryEntry>,
58
- * readFile: (file: string, maxBytes?: number) => Promise<Uint8Array>
59
- * }>} A promise that resolves with an object containing:
60
- * - `centralDirectory`: A map where keys are filenames and values are their corresponding central directory entries.
61
- * - `readFile`: A function to read a specific file from the ZIP archive by name.
62
- * Takes the filename and an optional maximum byte length to read.
63
- * @throws {Error} If the file is not found or if an unsupported compression method is encountered.
64
45
  */
65
46
  export const openRemoteZipFile = async (
66
- url,
67
- fetchContentLength = fetchSize,
68
- fetchBytes = fetchRange,
69
- ) => {
47
+ url: string,
48
+ fetchContentLength: (url: string) => Promise<number> = fetchSize,
49
+ fetchBytes: (
50
+ url: string,
51
+ start: number,
52
+ end: number,
53
+ ) => Promise<Uint8Array> = fetchRange,
54
+ ): Promise<{
55
+ centralDirectory: Map<string, CentralDirectoryEntry>;
56
+ readFile: (file: string, maxBytes?: number) => Promise<Uint8Array>;
57
+ }> => {
70
58
  const contentLength = await fetchContentLength(url);
71
59
 
72
60
  // Read the end of central directory record
@@ -89,7 +77,7 @@ export const openRemoteZipFile = async (
89
77
  const centralDirectory = parseCentralDirectory(centralDirBuffer);
90
78
  return {
91
79
  centralDirectory: centralDirectory,
92
- readFile: async (file, maxBytes) => {
80
+ readFile: async (file, maxBytes): Promise<Uint8Array> => {
93
81
  const entry = centralDirectory.get(file);
94
82
  if (!entry) {
95
83
  throw new Error(`File not found: ${file}`);
@@ -142,7 +130,7 @@ export const openRemoteZipFile = async (
142
130
  };
143
131
  };
144
132
 
145
- export const fetchSize = async (url) => {
133
+ export const fetchSize = async (url: string): Promise<number> => {
146
134
  const response = await fetch(`${url}`, { method: "HEAD" });
147
135
  const contentLength = Number(response.headers.get("Content-Length"));
148
136
  return contentLength;
@@ -150,14 +138,12 @@ export const fetchSize = async (url) => {
150
138
 
151
139
  /**
152
140
  * Fetches a range of bytes from a remote resource and returns it as a `Uint8Array`.
153
- *
154
- * @param {string} url - The URL of the remote resource to fetch.
155
- * @param {number} start - The starting byte position of the range to fetch.
156
- * @param {number} end - The ending byte position of the range to fetch.
157
- * @returns {Promise<Uint8Array>} A promise that resolves to a `Uint8Array` containing the fetched byte range.
158
- * @throws {Error} If there is an issue with the network request.
159
141
  */
160
- export const fetchRange = async (url, start, end) => {
142
+ export const fetchRange = async (
143
+ url: string,
144
+ start: number,
145
+ end: number,
146
+ ): Promise<Uint8Array> => {
161
147
  const response = await fetch(`${url}`, {
162
148
  headers: { Range: `bytes=${start}-${end}` },
163
149
  });
@@ -167,13 +153,11 @@ export const fetchRange = async (url, start, end) => {
167
153
 
168
154
  /**
169
155
  * Asynchronously decompresses the provided data using the specified options.
170
- *
171
- * @param {Uint8Array} data - The compressed data to be decompressed.
172
- * @param {Object} opts - Options to configure the decompression process.
173
- * @returns {Promise<Uint8Array>} A promise that resolves with the decompressed data.
174
- * @throws {Error} If an error occurs during decompression, the promise is rejected with the error.
175
156
  */
176
- const decompressAsync = async (data, opts) => {
157
+ const decompressAsync = async (
158
+ data: Uint8Array,
159
+ opts: AsyncInflateOptions,
160
+ ): Promise<Uint8Array> => {
177
161
  return new Promise((resolve, reject) => {
178
162
  decompress(data, opts, (err, result) => {
179
163
  if (err) {
@@ -187,13 +171,11 @@ const decompressAsync = async (data, opts) => {
187
171
 
188
172
  /**
189
173
  * Extracts and parses the header and data of a compressed ZIP entry from raw binary data.
190
- *
191
- * @param {string} file - The name of the file stream to be parsed
192
- * @param {Uint8Array} rawData - The raw binary data containing the ZIP entry.
193
- * @returns {Promise<ZipFileEntry>} A promise that resolves to an object containing the ZIP entry's header information and compressed data.
194
- * @throws {Error} If the ZIP entry signature is invalid.
195
174
  */
196
- const parseZipFileEntry = async (file, rawData) => {
175
+ const parseZipFileEntry = async (
176
+ file: string,
177
+ rawData: Uint8Array,
178
+ ): Promise<ZipFileEntry> => {
197
179
  // Parse ZIP entry header
198
180
  const view = new DataView(rawData.buffer);
199
181
  let offset = 0;
@@ -237,20 +219,17 @@ const parseZipFileEntry = async (file, rawData) => {
237
219
  };
238
220
  };
239
221
 
222
+ const kFileHeaderSize = 46;
240
223
  /**
241
224
  * Parses the central directory of a ZIP file from the provided buffer and returns a map of entries.
242
- *
243
- * @param {Uint8Array} buffer - The raw binary data containing the central directory of the ZIP archive.
244
- * @returns {Map<string, CentralDirectoryEntry>} A map where the key is the filename and the value is the corresponding central directory entry.
245
- * @throws {Error} If the buffer does not contain a valid central directory signature.
246
225
  */
247
- const parseCentralDirectory = (buffer) => {
226
+ const parseCentralDirectory = (buffer: Uint8Array<ArrayBufferLike>) => {
248
227
  let offset = 0;
249
228
  const view = new DataView(buffer.buffer);
250
-
251
229
  const entries = new Map();
230
+
252
231
  while (offset < buffer.length) {
253
- // Make sure there is a central directory signature
232
+ // Central Directory signature
254
233
  if (view.getUint32(offset, true) !== 0x02014b50) break;
255
234
 
256
235
  const filenameLength = view.getUint16(offset + 28, true);
@@ -258,20 +237,47 @@ const parseCentralDirectory = (buffer) => {
258
237
  const fileCommentLength = view.getUint16(offset + 32, true);
259
238
 
260
239
  const filename = new TextDecoder().decode(
261
- buffer.subarray(offset + 46, offset + 46 + filenameLength),
240
+ buffer.subarray(
241
+ offset + kFileHeaderSize,
242
+ offset + kFileHeaderSize + filenameLength,
243
+ ),
262
244
  );
263
245
 
246
+ // Read 32-bit file offset
247
+ let fileOffset = view.getUint32(offset + 42, true);
248
+
249
+ // If fileOffset is 0xFFFFFFFF, use the ZIP64 extended offset instead
250
+ if (fileOffset === 0xffffffff) {
251
+ // Move to extra field
252
+ let extraOffset = offset + kFileHeaderSize + filenameLength;
253
+ // Look through extra fields until we find zip64 extra field
254
+ while (
255
+ extraOffset <
256
+ offset + kFileHeaderSize + filenameLength + extraFieldLength
257
+ ) {
258
+ const tag = view.getUint16(extraOffset, true);
259
+ const size = view.getUint16(extraOffset + 2, true);
260
+ if (tag === 0x0001) {
261
+ // ZIP64 Extra Field - Read 64-bit offset
262
+ fileOffset = Number(view.getBigUint64(extraOffset + 4, true));
263
+ break;
264
+ }
265
+ extraOffset += 4 + size; // Move to next extra field
266
+ }
267
+ }
268
+
264
269
  const entry = {
265
270
  filename,
266
271
  compressionMethod: view.getUint16(offset + 10, true),
267
272
  compressedSize: view.getUint32(offset + 20, true),
268
273
  uncompressedSize: view.getUint32(offset + 24, true),
269
- fileOffset: view.getUint32(offset + 42, true),
274
+ fileOffset,
270
275
  };
271
276
 
272
277
  entries.set(filename, entry);
273
-
274
- offset += 46 + filenameLength + extraFieldLength + fileCommentLength;
278
+ offset +=
279
+ kFileHeaderSize + filenameLength + extraFieldLength + fileCommentLength;
275
280
  }
281
+
276
282
  return entries;
277
283
  };