inspect-ai 0.3.81__py3-none-any.whl → 0.3.83__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. inspect_ai/__init__.py +2 -1
  2. inspect_ai/_cli/eval.py +35 -2
  3. inspect_ai/_cli/util.py +44 -1
  4. inspect_ai/_display/core/config.py +1 -1
  5. inspect_ai/_display/core/display.py +13 -4
  6. inspect_ai/_display/core/results.py +1 -1
  7. inspect_ai/_display/textual/app.py +14 -3
  8. inspect_ai/_display/textual/display.py +4 -0
  9. inspect_ai/_display/textual/widgets/samples.py +9 -3
  10. inspect_ai/_display/textual/widgets/task_detail.py +8 -8
  11. inspect_ai/_display/textual/widgets/tasks.py +17 -1
  12. inspect_ai/_display/textual/widgets/vscode.py +44 -0
  13. inspect_ai/_eval/eval.py +74 -25
  14. inspect_ai/_eval/evalset.py +22 -18
  15. inspect_ai/_eval/loader.py +34 -11
  16. inspect_ai/_eval/run.py +13 -15
  17. inspect_ai/_eval/score.py +13 -3
  18. inspect_ai/_eval/task/generate.py +8 -9
  19. inspect_ai/_eval/task/log.py +55 -6
  20. inspect_ai/_eval/task/run.py +51 -10
  21. inspect_ai/_eval/task/task.py +23 -9
  22. inspect_ai/_util/constants.py +2 -0
  23. inspect_ai/_util/file.py +30 -1
  24. inspect_ai/_util/json.py +37 -1
  25. inspect_ai/_util/registry.py +1 -0
  26. inspect_ai/_util/vscode.py +37 -0
  27. inspect_ai/_view/server.py +113 -1
  28. inspect_ai/_view/www/App.css +7 -1
  29. inspect_ai/_view/www/dist/assets/index.css +813 -415
  30. inspect_ai/_view/www/dist/assets/index.js +54475 -32003
  31. inspect_ai/_view/www/eslint.config.mjs +1 -1
  32. inspect_ai/_view/www/log-schema.json +137 -31
  33. inspect_ai/_view/www/node_modules/flatted/python/flatted.py +149 -0
  34. inspect_ai/_view/www/package.json +11 -2
  35. inspect_ai/_view/www/src/App.tsx +161 -853
  36. inspect_ai/_view/www/src/api/api-browser.ts +176 -5
  37. inspect_ai/_view/www/src/api/api-vscode.ts +75 -1
  38. inspect_ai/_view/www/src/api/client-api.ts +66 -10
  39. inspect_ai/_view/www/src/api/jsonrpc.ts +2 -0
  40. inspect_ai/_view/www/src/api/types.ts +107 -2
  41. inspect_ai/_view/www/src/appearance/icons.ts +2 -0
  42. inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +3 -3
  43. inspect_ai/_view/www/src/components/Card.tsx +6 -4
  44. inspect_ai/_view/www/src/components/DownloadPanel.tsx +2 -2
  45. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +56 -61
  46. inspect_ai/_view/www/src/components/FindBand.tsx +17 -9
  47. inspect_ai/_view/www/src/components/HumanBaselineView.tsx +1 -1
  48. inspect_ai/_view/www/src/components/JsonPanel.tsx +14 -24
  49. inspect_ai/_view/www/src/components/LargeModal.tsx +2 -35
  50. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +27 -11
  51. inspect_ai/_view/www/src/components/LinkButton.module.css +16 -0
  52. inspect_ai/_view/www/src/components/LinkButton.tsx +33 -0
  53. inspect_ai/_view/www/src/components/LiveVirtualList.module.css +11 -0
  54. inspect_ai/_view/www/src/components/LiveVirtualList.tsx +177 -0
  55. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +116 -26
  56. inspect_ai/_view/www/src/components/MessageBand.tsx +14 -9
  57. inspect_ai/_view/www/src/components/Modal.module.css +38 -0
  58. inspect_ai/_view/www/src/components/Modal.tsx +77 -0
  59. inspect_ai/_view/www/src/components/MorePopOver.tsx +3 -3
  60. inspect_ai/_view/www/src/components/NavPills.tsx +20 -8
  61. inspect_ai/_view/www/src/components/NoContentsPanel.module.css +12 -0
  62. inspect_ai/_view/www/src/components/NoContentsPanel.tsx +20 -0
  63. inspect_ai/_view/www/src/components/ProgressBar.module.css +5 -4
  64. inspect_ai/_view/www/src/components/ProgressBar.tsx +3 -2
  65. inspect_ai/_view/www/src/components/PulsingDots.module.css +81 -0
  66. inspect_ai/_view/www/src/components/PulsingDots.tsx +45 -0
  67. inspect_ai/_view/www/src/components/TabSet.tsx +4 -37
  68. inspect_ai/_view/www/src/components/ToolButton.tsx +3 -4
  69. inspect_ai/_view/www/src/index.tsx +26 -94
  70. inspect_ai/_view/www/src/logfile/remoteLogFile.ts +9 -1
  71. inspect_ai/_view/www/src/logfile/remoteZipFile.ts +30 -4
  72. inspect_ai/_view/www/src/metadata/RenderedContent.tsx +4 -6
  73. inspect_ai/_view/www/src/plan/DetailStep.module.css +4 -0
  74. inspect_ai/_view/www/src/plan/DetailStep.tsx +6 -3
  75. inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +1 -1
  76. inspect_ai/_view/www/src/plan/SolverDetailView.module.css +2 -1
  77. inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +9 -1
  78. inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +74 -28
  79. inspect_ai/_view/www/src/samples/SampleDialog.tsx +58 -22
  80. inspect_ai/_view/www/src/samples/SampleDisplay.module.css +4 -0
  81. inspect_ai/_view/www/src/samples/SampleDisplay.tsx +135 -104
  82. inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +10 -0
  83. inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +83 -36
  84. inspect_ai/_view/www/src/samples/SamplesTools.tsx +35 -30
  85. inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +2 -1
  86. inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +1 -1
  87. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +45 -53
  88. inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +6 -1
  89. inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +5 -0
  90. inspect_ai/_view/www/src/samples/chat/messages.ts +36 -0
  91. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.module.css +3 -0
  92. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +11 -1
  93. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +22 -46
  94. inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +34 -20
  95. inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.module.css +3 -3
  96. inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.tsx +1 -1
  97. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.module.css +4 -4
  98. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +10 -10
  99. inspect_ai/_view/www/src/samples/descriptor/types.ts +6 -5
  100. inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +22 -3
  101. inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +27 -2
  102. inspect_ai/_view/www/src/samples/list/SampleList.tsx +122 -85
  103. inspect_ai/_view/www/src/samples/list/SampleRow.module.css +6 -0
  104. inspect_ai/_view/www/src/samples/list/SampleRow.tsx +28 -15
  105. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +29 -18
  106. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +28 -28
  107. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +19 -9
  108. inspect_ai/_view/www/src/samples/sampleDataAdapter.ts +33 -0
  109. inspect_ai/_view/www/src/samples/sampleLimit.ts +2 -2
  110. inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +12 -27
  111. inspect_ai/_view/www/src/samples/scores/SampleScoresGrid.module.css +38 -0
  112. inspect_ai/_view/www/src/samples/scores/SampleScoresGrid.tsx +118 -0
  113. inspect_ai/_view/www/src/samples/scores/{SampleScoreView.module.css → SampleScoresView.module.css} +10 -1
  114. inspect_ai/_view/www/src/samples/scores/SampleScoresView.tsx +78 -0
  115. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +0 -13
  116. inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +0 -13
  117. inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +0 -13
  118. inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +4 -0
  119. inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +10 -24
  120. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +0 -13
  121. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +4 -22
  122. inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +15 -24
  123. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +0 -13
  124. inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +6 -28
  125. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +24 -34
  126. inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +4 -0
  127. inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +33 -17
  128. inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +197 -338
  129. inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.module.css +16 -0
  130. inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.tsx +44 -0
  131. inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +7 -4
  132. inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +81 -60
  133. inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.module.css +23 -0
  134. inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.tsx +27 -0
  135. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +29 -1
  136. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +102 -72
  137. inspect_ai/_view/www/src/scoring/utils.ts +87 -0
  138. inspect_ai/_view/www/src/state/appSlice.ts +244 -0
  139. inspect_ai/_view/www/src/state/hooks.ts +399 -0
  140. inspect_ai/_view/www/src/state/logPolling.ts +200 -0
  141. inspect_ai/_view/www/src/state/logSlice.ts +224 -0
  142. inspect_ai/_view/www/src/state/logsPolling.ts +118 -0
  143. inspect_ai/_view/www/src/state/logsSlice.ts +181 -0
  144. inspect_ai/_view/www/src/state/samplePolling.ts +314 -0
  145. inspect_ai/_view/www/src/state/sampleSlice.ts +140 -0
  146. inspect_ai/_view/www/src/state/sampleUtils.ts +21 -0
  147. inspect_ai/_view/www/src/state/scrolling.ts +206 -0
  148. inspect_ai/_view/www/src/state/store.ts +168 -0
  149. inspect_ai/_view/www/src/state/store_filter.ts +84 -0
  150. inspect_ai/_view/www/src/state/utils.ts +23 -0
  151. inspect_ai/_view/www/src/storage/index.ts +26 -0
  152. inspect_ai/_view/www/src/types/log.d.ts +36 -26
  153. inspect_ai/_view/www/src/types/markdown-it-katex.d.ts +21 -0
  154. inspect_ai/_view/www/src/types.ts +94 -32
  155. inspect_ai/_view/www/src/utils/attachments.ts +58 -23
  156. inspect_ai/_view/www/src/utils/json-worker.ts +79 -12
  157. inspect_ai/_view/www/src/utils/logger.ts +52 -0
  158. inspect_ai/_view/www/src/utils/polling.ts +100 -0
  159. inspect_ai/_view/www/src/utils/react.ts +30 -0
  160. inspect_ai/_view/www/src/utils/vscode.ts +1 -1
  161. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +184 -217
  162. inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +11 -53
  163. inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +8 -18
  164. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +1 -0
  165. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +40 -22
  166. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +16 -1
  167. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +159 -103
  168. inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.module.css +32 -0
  169. inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.tsx +32 -0
  170. inspect_ai/_view/www/src/workspace/navbar/ScoreGrid.module.css +35 -0
  171. inspect_ai/_view/www/src/workspace/navbar/ScoreGrid.tsx +117 -0
  172. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +12 -14
  173. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +6 -2
  174. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +4 -4
  175. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.module.css +3 -2
  176. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +28 -13
  177. inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +5 -10
  178. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +4 -4
  179. inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.module.css +22 -0
  180. inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.tsx +19 -0
  181. inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +128 -115
  182. inspect_ai/_view/www/src/workspace/tabs/grouping.ts +37 -5
  183. inspect_ai/_view/www/src/workspace/tabs/types.ts +4 -0
  184. inspect_ai/_view/www/src/workspace/types.ts +4 -3
  185. inspect_ai/_view/www/src/workspace/utils.ts +4 -4
  186. inspect_ai/_view/www/vite.config.js +6 -0
  187. inspect_ai/_view/www/yarn.lock +464 -355
  188. inspect_ai/agent/__init__.py +36 -0
  189. inspect_ai/agent/_agent.py +268 -0
  190. inspect_ai/agent/_as_solver.py +72 -0
  191. inspect_ai/agent/_as_tool.py +122 -0
  192. inspect_ai/{solver → agent}/_bridge/bridge.py +23 -37
  193. inspect_ai/{solver → agent}/_bridge/patch.py +9 -8
  194. inspect_ai/agent/_filter.py +46 -0
  195. inspect_ai/agent/_handoff.py +93 -0
  196. inspect_ai/{solver/_human_agent → agent/_human}/agent.py +11 -12
  197. inspect_ai/{solver/_human_agent → agent/_human}/commands/__init__.py +2 -3
  198. inspect_ai/{solver/_human_agent → agent/_human}/commands/clock.py +3 -1
  199. inspect_ai/{solver/_human_agent → agent/_human}/commands/score.py +5 -5
  200. inspect_ai/{solver/_human_agent → agent/_human}/install.py +6 -3
  201. inspect_ai/{solver/_human_agent → agent/_human}/service.py +7 -3
  202. inspect_ai/{solver/_human_agent → agent/_human}/state.py +5 -5
  203. inspect_ai/agent/_react.py +241 -0
  204. inspect_ai/agent/_run.py +36 -0
  205. inspect_ai/agent/_types.py +81 -0
  206. inspect_ai/log/_condense.py +26 -0
  207. inspect_ai/log/_log.py +17 -5
  208. inspect_ai/log/_recorders/buffer/__init__.py +14 -0
  209. inspect_ai/log/_recorders/buffer/buffer.py +30 -0
  210. inspect_ai/log/_recorders/buffer/database.py +685 -0
  211. inspect_ai/log/_recorders/buffer/filestore.py +259 -0
  212. inspect_ai/log/_recorders/buffer/types.py +84 -0
  213. inspect_ai/log/_recorders/eval.py +2 -11
  214. inspect_ai/log/_recorders/types.py +30 -0
  215. inspect_ai/log/_transcript.py +32 -2
  216. inspect_ai/model/__init__.py +7 -1
  217. inspect_ai/model/_call_tools.py +257 -52
  218. inspect_ai/model/_chat_message.py +7 -4
  219. inspect_ai/model/_conversation.py +13 -62
  220. inspect_ai/model/_display.py +85 -0
  221. inspect_ai/model/_generate_config.py +2 -2
  222. inspect_ai/model/_model.py +114 -14
  223. inspect_ai/model/_model_output.py +14 -9
  224. inspect_ai/model/_openai.py +16 -4
  225. inspect_ai/model/_openai_computer_use.py +162 -0
  226. inspect_ai/model/_openai_responses.py +319 -165
  227. inspect_ai/model/_providers/anthropic.py +20 -21
  228. inspect_ai/model/_providers/azureai.py +24 -13
  229. inspect_ai/model/_providers/bedrock.py +1 -7
  230. inspect_ai/model/_providers/cloudflare.py +3 -3
  231. inspect_ai/model/_providers/goodfire.py +2 -6
  232. inspect_ai/model/_providers/google.py +11 -10
  233. inspect_ai/model/_providers/groq.py +6 -3
  234. inspect_ai/model/_providers/hf.py +7 -3
  235. inspect_ai/model/_providers/mistral.py +7 -10
  236. inspect_ai/model/_providers/openai.py +47 -17
  237. inspect_ai/model/_providers/openai_o1.py +11 -4
  238. inspect_ai/model/_providers/openai_responses.py +12 -14
  239. inspect_ai/model/_providers/providers.py +2 -2
  240. inspect_ai/model/_providers/together.py +12 -2
  241. inspect_ai/model/_providers/util/chatapi.py +7 -2
  242. inspect_ai/model/_providers/util/hf_handler.py +4 -2
  243. inspect_ai/model/_providers/util/llama31.py +4 -2
  244. inspect_ai/model/_providers/vertex.py +11 -9
  245. inspect_ai/model/_providers/vllm.py +4 -4
  246. inspect_ai/scorer/__init__.py +2 -0
  247. inspect_ai/scorer/_metrics/__init__.py +2 -0
  248. inspect_ai/scorer/_metrics/grouped.py +84 -0
  249. inspect_ai/scorer/_score.py +26 -6
  250. inspect_ai/solver/__init__.py +2 -2
  251. inspect_ai/solver/_basic_agent.py +22 -9
  252. inspect_ai/solver/_bridge.py +31 -0
  253. inspect_ai/solver/_chain.py +20 -12
  254. inspect_ai/solver/_fork.py +5 -1
  255. inspect_ai/solver/_human_agent.py +52 -0
  256. inspect_ai/solver/_prompt.py +3 -1
  257. inspect_ai/solver/_run.py +59 -0
  258. inspect_ai/solver/_solver.py +14 -4
  259. inspect_ai/solver/_task_state.py +5 -3
  260. inspect_ai/tool/_tool_call.py +15 -8
  261. inspect_ai/tool/_tool_def.py +17 -12
  262. inspect_ai/tool/_tool_support_helpers.py +4 -4
  263. inspect_ai/tool/_tool_with.py +14 -11
  264. inspect_ai/tool/_tools/_bash_session.py +11 -2
  265. inspect_ai/tool/_tools/_computer/_common.py +18 -2
  266. inspect_ai/tool/_tools/_computer/_computer.py +18 -2
  267. inspect_ai/tool/_tools/_computer/_resources/tool/_constants.py +2 -0
  268. inspect_ai/tool/_tools/_computer/_resources/tool/_x11_client.py +17 -0
  269. inspect_ai/tool/_tools/_think.py +1 -1
  270. inspect_ai/tool/_tools/_web_browser/_web_browser.py +103 -62
  271. inspect_ai/util/__init__.py +2 -0
  272. inspect_ai/util/_anyio.py +27 -0
  273. inspect_ai/util/_sandbox/__init__.py +2 -1
  274. inspect_ai/util/_sandbox/context.py +32 -7
  275. inspect_ai/util/_sandbox/docker/cleanup.py +4 -0
  276. inspect_ai/util/_sandbox/docker/compose.py +2 -2
  277. inspect_ai/util/_sandbox/docker/docker.py +12 -1
  278. inspect_ai/util/_store_model.py +30 -7
  279. inspect_ai/util/_subprocess.py +13 -3
  280. inspect_ai/util/_subtask.py +1 -0
  281. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/METADATA +1 -1
  282. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/RECORD +295 -229
  283. inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +0 -169
  284. inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +0 -22
  285. /inspect_ai/{solver → agent}/_bridge/__init__.py +0 -0
  286. /inspect_ai/{solver/_human_agent → agent/_human}/__init__.py +0 -0
  287. /inspect_ai/{solver/_human_agent → agent/_human}/commands/command.py +0 -0
  288. /inspect_ai/{solver/_human_agent → agent/_human}/commands/instructions.py +0 -0
  289. /inspect_ai/{solver/_human_agent → agent/_human}/commands/note.py +0 -0
  290. /inspect_ai/{solver/_human_agent → agent/_human}/commands/status.py +0 -0
  291. /inspect_ai/{solver/_human_agent → agent/_human}/commands/submit.py +0 -0
  292. /inspect_ai/{solver/_human_agent → agent/_human}/panel.py +0 -0
  293. /inspect_ai/{solver/_human_agent → agent/_human}/view.py +0 -0
  294. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/WHEEL +0 -0
  295. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/entry_points.txt +0 -0
  296. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/licenses/LICENSE +0 -0
  297. {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,52 @@
1
+ // This will be replaced at build time with a boolean value
2
+ declare const __DEV_WATCH__: boolean;
3
+ declare const __LOGGING_FILTER__: string;
4
+
5
+ const getEnabledNamespaces = () => {
6
+ // Split by comma and filter out empty strings
7
+ return __LOGGING_FILTER__
8
+ .split(",")
9
+ .map((ns) => ns.trim())
10
+ .filter(Boolean);
11
+ };
12
+
13
+ const ENABLED_NAMESPACES = new Set<string>(getEnabledNamespaces());
14
+ const filterNameSpace = (namespace: string) => {
15
+ if (ENABLED_NAMESPACES.has("*")) return true;
16
+
17
+ return ENABLED_NAMESPACES.has(namespace);
18
+ };
19
+
20
+ // Create a logger for a specific namespace
21
+ export const createLogger = (namespace: string) => {
22
+ // Logger functions that only activate in dev-watch mode
23
+ const logger = {
24
+ debug: (message: string, ...args: any[]) => {
25
+ if (__DEV_WATCH__ && filterNameSpace(namespace))
26
+ console.debug(`[${namespace}] ${message}`, ...args);
27
+ },
28
+
29
+ info: (message: string, ...args: any[]) => {
30
+ if (__DEV_WATCH__ && filterNameSpace(namespace))
31
+ console.info(`[${namespace}] ${message}`, ...args);
32
+ },
33
+
34
+ warn: (message: string, ...args: any[]) => {
35
+ if (__DEV_WATCH__ && filterNameSpace(namespace))
36
+ console.warn(`[${namespace}] ${message}`, ...args);
37
+ },
38
+
39
+ // Always log errors, even in production
40
+ error: (message: string, ...args: any[]) => {
41
+ console.error(`[${namespace}] ${message}`, ...args);
42
+ },
43
+
44
+ // Lazy evaluation for expensive logs
45
+ debugIf: (fn: () => string) => {
46
+ if (__DEV_WATCH__ && filterNameSpace(namespace))
47
+ console.debug(`[${namespace}] ${fn()}`);
48
+ },
49
+ };
50
+
51
+ return logger;
52
+ };
@@ -0,0 +1,100 @@
1
+ import { Timeout } from "../types/log";
2
+ import { createLogger } from "./logger";
3
+
4
+ export interface PollingOptions {
5
+ maxRetries: number;
6
+ interval: number;
7
+ }
8
+
9
+ export interface Polling {
10
+ name: string;
11
+ start: () => void;
12
+ stop: () => void;
13
+ }
14
+
15
+ export const createPolling = (
16
+ name: string,
17
+ callback: () => Promise<boolean>,
18
+ options: PollingOptions,
19
+ ): Polling => {
20
+ const log = createLogger(`Polling ${name}`);
21
+
22
+ const { maxRetries, interval } = options;
23
+ let timeoutId: Timeout = null;
24
+ let retryCount = 0;
25
+ // Are we currently polling
26
+ let isPolling = false;
27
+
28
+ // Are we stopped (e.g. cleaning up)
29
+ let isStopped = false;
30
+
31
+ const calculateBackoff = (retryCount: number) => {
32
+ return Math.min(interval * Math.pow(2, retryCount) * 1000, 60000);
33
+ };
34
+
35
+ const stop = () => {
36
+ if (timeoutId) {
37
+ clearTimeout(timeoutId);
38
+ timeoutId = null;
39
+ }
40
+ log.debug("Stop Polling");
41
+ isPolling = false;
42
+ isStopped = true;
43
+ };
44
+
45
+ const poll = async () => {
46
+ try {
47
+ log.debug("Poll");
48
+ // Don't proceed if polling has been stopped
49
+ if (!isPolling || isStopped) {
50
+ return;
51
+ }
52
+
53
+ const shouldContinue = await callback();
54
+ if (shouldContinue === false) {
55
+ stop();
56
+ return;
57
+ }
58
+
59
+ // Reset retry count on success
60
+ retryCount = 0;
61
+ if (!isPolling || isStopped) {
62
+ return;
63
+ }
64
+ timeoutId = setTimeout(poll, interval * 1000);
65
+ } catch (e) {
66
+ // Don't retry if polling has been stopped
67
+ if (!isPolling || isStopped) {
68
+ return;
69
+ }
70
+ log.debug("Polling error occurred", e);
71
+
72
+ retryCount += 1;
73
+
74
+ if (retryCount >= maxRetries) {
75
+ stop();
76
+ throw new Error(
77
+ `Gave up polling ${name} after ${maxRetries} attempts.`,
78
+ );
79
+ }
80
+
81
+ const backoffTime = calculateBackoff(retryCount);
82
+ log.debug(
83
+ `Retry ${retryCount}/${maxRetries}, backoff: ${backoffTime / 1000}s`,
84
+ );
85
+ timeoutId = setTimeout(poll, backoffTime);
86
+ }
87
+ };
88
+
89
+ const start = () => {
90
+ if (isPolling) {
91
+ return;
92
+ }
93
+ log.debug("Start Polling");
94
+ isPolling = true;
95
+ isStopped = false;
96
+ poll();
97
+ };
98
+
99
+ return { name, start, stop };
100
+ };
@@ -0,0 +1,30 @@
1
+ import { useEffect, useRef } from "react";
2
+
3
+ export const useWhyDidYouUpdate = (componentName: string, props: any) => {
4
+ const previousProps = useRef(props);
5
+
6
+ useEffect(() => {
7
+ if (previousProps.current !== props) {
8
+ const changedProps = Object.entries(props).reduce(
9
+ (diff, [key, value]) => {
10
+ if (previousProps.current[key] !== value) {
11
+ diff[key] = {
12
+ before: previousProps.current[key],
13
+ after: value,
14
+ };
15
+ }
16
+ return diff;
17
+ },
18
+ {} as Record<string, unknown>,
19
+ );
20
+
21
+ if (Object.keys(changedProps).length > 0) {
22
+ console.log(`[${componentName}] props changed:`, changedProps);
23
+ } else {
24
+ console.log(`[${componentName}] no props changed`);
25
+ }
26
+ }
27
+
28
+ previousProps.current = props;
29
+ }, [props, componentName]);
30
+ };
@@ -2,7 +2,7 @@
2
2
  * Type definition for the VS Code API object
3
3
  * Note: This is a minimal definition - expand based on your needs
4
4
  */
5
- interface VSCodeApi {
5
+ export interface VSCodeApi {
6
6
  postMessage(message: unknown): void;
7
7
  getState(): unknown;
8
8
  setState(state: unknown): void;
@@ -1,31 +1,28 @@
1
1
  import { ApplicationIcons } from "../appearance/icons";
2
2
  import { ToolButton } from "../components/ToolButton";
3
- import { SampleTools } from "../samples/SamplesTools";
3
+ import { SampleTools, ScoreFilterTools } from "../samples/SamplesTools";
4
4
  import { JsonTab } from "./tabs/JsonTab";
5
5
  import { SamplesTab } from "./tabs/SamplesTab";
6
6
 
7
7
  import clsx from "clsx";
8
- import { FC, MouseEvent, RefObject, useEffect, useMemo, useRef } from "react";
9
- import { SampleSummary } from "../api/types.ts";
8
+ import { FC, MouseEvent, useEffect, useMemo, useRef } from "react";
9
+ import { RunningMetric } from "../api/types.ts";
10
10
  import {
11
11
  kEvalWorkspaceTabId,
12
12
  kInfoWorkspaceTabId,
13
13
  kJsonWorkspaceTabId,
14
14
  } from "../constants";
15
- import { SamplesDescriptor } from "../samples/descriptor/samplesDescriptor";
16
15
  import {
17
- Capabilities,
18
- CurrentLog,
19
- SampleMode,
20
- ScoreFilter,
21
- ScoreLabel,
22
- } from "../types.ts";
16
+ useFilteredSamples,
17
+ useSampleDescriptor,
18
+ useTotalSampleCount,
19
+ } from "../state/hooks.ts";
20
+ import { useStore } from "../state/store.ts";
21
+ import { CurrentLog } from "../types.ts";
23
22
  import {
24
- Epochs,
25
23
  EvalError,
26
24
  EvalPlan,
27
25
  EvalResults,
28
- EvalSample,
29
26
  EvalSpec,
30
27
  EvalStats,
31
28
  Status,
@@ -35,7 +32,6 @@ import { WorkSpaceView } from "./WorkSpaceView.tsx";
35
32
 
36
33
  interface WorkSpaceProps {
37
34
  task_id?: string;
38
- logFileName?: string;
39
35
  evalError?: EvalError;
40
36
  evalStatus?: Status;
41
37
  evalVersion?: number;
@@ -43,42 +39,10 @@ interface WorkSpaceProps {
43
39
  evalPlan?: EvalPlan;
44
40
  evalStats?: EvalStats;
45
41
  evalResults?: EvalResults;
42
+ runningMetrics?: RunningMetric[];
46
43
  log?: CurrentLog;
47
- samples?: SampleSummary[];
48
- sampleMode: SampleMode;
49
- groupBy: "none" | "epoch" | "sample";
50
- groupByOrder: "asc" | "desc";
51
- selectedSample?: EvalSample;
52
- sampleStatus: string;
53
- sampleError?: Error;
54
44
  showToggle: boolean;
55
- refreshLog: () => Promise<void>;
56
- capabilities: Capabilities;
57
- selectedSampleIndex: number;
58
- samplesDescriptor?: SamplesDescriptor;
59
- setSelectedSampleIndex: (index: number) => void;
60
- selectedSampleTab?: string;
61
- setSelectedSampleTab: (tab: string) => void;
62
- sort: string;
63
- setSort: (sort: string) => void;
64
- epochs?: Epochs;
65
- epoch: string;
66
- showingSampleDialog: boolean;
67
- setShowingSampleDialog: (showing: boolean) => void;
68
- setEpoch: (epoch: string) => void;
69
- filter: ScoreFilter;
70
- setFilter: (filter: ScoreFilter) => void;
71
- score?: ScoreLabel;
72
- setScore: (score: ScoreLabel) => void;
73
- scores: ScoreLabel[];
74
- offcanvas: boolean;
75
- setOffcanvas: (offcanvas: boolean) => void;
76
- selectedTab: string;
77
- setSelectedTab: (id: string) => void;
78
- sampleScrollPositionRef: RefObject<number>;
79
- setSampleScrollPosition: (position: number) => void;
80
- workspaceTabScrollPositionRef: RefObject<Record<string, number>>;
81
- setWorkspaceTabScrollPosition: (tab: string, position: number) => void;
45
+ refreshLog: () => void;
82
46
  }
83
47
 
84
48
  /**
@@ -88,20 +52,12 @@ export const WorkSpace: FC<WorkSpaceProps> = (props) => {
88
52
  const {
89
53
  task_id,
90
54
  evalStatus,
91
- logFileName,
92
55
  evalSpec,
93
56
  evalPlan,
94
57
  evalStats,
95
58
  evalResults,
96
- samples,
59
+ runningMetrics,
97
60
  showToggle,
98
- offcanvas,
99
- setOffcanvas,
100
- samplesDescriptor,
101
- selectedTab,
102
- setSelectedTab,
103
- workspaceTabScrollPositionRef,
104
- setWorkspaceTabScrollPosition,
105
61
  } = props;
106
62
 
107
63
  const divRef = useRef<HTMLDivElement>(null);
@@ -121,27 +77,20 @@ export const WorkSpace: FC<WorkSpaceProps> = (props) => {
121
77
 
122
78
  return (
123
79
  <WorkSpaceView
124
- logFileName={logFileName}
125
80
  divRef={divRef}
126
81
  evalSpec={evalSpec}
127
82
  evalPlan={evalPlan}
128
83
  evalResults={evalResults}
84
+ runningMetrics={runningMetrics}
129
85
  evalStats={evalStats}
130
- samples={samples}
131
- evalDescriptor={samplesDescriptor?.evalDescriptor}
132
86
  status={evalStatus}
133
87
  tabs={resolvedTabs}
134
- selectedTab={selectedTab}
135
88
  showToggle={showToggle}
136
- offcanvas={offcanvas}
137
- setSelectedTab={setSelectedTab}
138
- workspaceTabScrollPositionRef={workspaceTabScrollPositionRef}
139
- setWorkspaceTabScrollPosition={setWorkspaceTabScrollPosition}
140
- setOffcanvas={setOffcanvas}
141
89
  />
142
90
  );
143
91
  };
144
92
 
93
+ // Helper function for copy feedback
145
94
  const copyFeedback = (e: MouseEvent<HTMLElement>) => {
146
95
  const textEl = e.currentTarget.querySelector(".task-btn-copy-content");
147
96
  const iconEl = e.currentTarget.querySelector("i.bi");
@@ -162,164 +111,182 @@ const copyFeedback = (e: MouseEvent<HTMLElement>) => {
162
111
  }
163
112
  };
164
113
 
165
- const useResolvedTabs = ({
166
- evalVersion,
167
- evalStatus,
168
- sampleMode,
169
- samples,
170
- selectedSample,
171
- sampleStatus,
172
- sampleError,
173
- showingSampleDialog,
174
- setShowingSampleDialog,
175
- groupBy,
176
- groupByOrder,
177
- selectedSampleIndex,
178
- setSelectedSampleIndex,
179
- samplesDescriptor,
180
- selectedSampleTab,
181
- setSelectedSampleTab,
182
- filter,
183
- sort,
184
- epoch,
185
- sampleScrollPositionRef,
186
- setSampleScrollPosition,
187
- epochs,
188
- setEpoch,
189
- setFilter,
190
- setSort,
191
- score,
192
- setScore,
193
- scores,
194
- evalSpec,
195
- evalPlan,
196
- evalResults,
197
- evalStats,
198
- evalError,
199
- logFileName,
200
- capabilities,
201
- selectedTab,
202
- refreshLog,
203
- }: WorkSpaceProps) => {
204
- const sampleTabScrollRef = useRef<HTMLDivElement>(null);
114
+ // Individual hook for Samples tab
115
+ export const useSamplesTabConfig = (
116
+ evalStatus: Status | undefined,
117
+ refreshLog: () => void,
118
+ ) => {
119
+ const totalSampleCount = useTotalSampleCount();
120
+ const samplesDescriptor = useSampleDescriptor();
121
+ const sampleSummaries = useFilteredSamples();
122
+ const streamSamples = useStore((state) => state.capabilities.streamSamples);
123
+
124
+ return useMemo(() => {
125
+ return {
126
+ id: kEvalWorkspaceTabId,
127
+ scrollable: false,
128
+ label: totalSampleCount > 1 ? "Samples" : "Sample",
129
+ component: SamplesTab,
130
+ componentProps: {
131
+ running: evalStatus === "started",
132
+ },
133
+ tools: () =>
134
+ !samplesDescriptor
135
+ ? undefined
136
+ : totalSampleCount === 1
137
+ ? [<ScoreFilterTools />]
138
+ : [
139
+ <SampleTools
140
+ samples={sampleSummaries || []}
141
+ key="sample-tools"
142
+ />,
143
+ evalStatus === "started" && !streamSamples && (
144
+ <ToolButton
145
+ key="refresh"
146
+ label="Refresh"
147
+ icon={ApplicationIcons.refresh}
148
+ onClick={refreshLog}
149
+ />
150
+ ),
151
+ ],
152
+ };
153
+ }, [
154
+ evalStatus,
155
+ refreshLog,
156
+ sampleSummaries,
157
+ samplesDescriptor,
158
+ totalSampleCount,
159
+ ]);
160
+ };
161
+
162
+ // Individual hook for Info tab
163
+ export const useInfoTabConfig = (
164
+ evalSpec: EvalSpec | undefined,
165
+ evalPlan: EvalPlan | undefined,
166
+ evalError: EvalError | undefined,
167
+ evalResults: EvalResults | undefined,
168
+ evalStats: EvalStats | undefined,
169
+ ) => {
170
+ const totalSampleCount = useTotalSampleCount();
171
+ return useMemo(() => {
172
+ return {
173
+ id: kInfoWorkspaceTabId,
174
+ label: "Info",
175
+ scrollable: true,
176
+ component: InfoTab,
177
+ componentProps: {
178
+ evalSpec,
179
+ evalPlan,
180
+ evalError,
181
+ evalResults,
182
+ evalStats,
183
+ sampleCount: totalSampleCount,
184
+ },
185
+ };
186
+ }, [evalSpec, evalPlan, evalError, evalResults, evalStats, totalSampleCount]);
187
+ };
188
+
189
+ // Individual hook for JSON tab
190
+ export const useJsonTabConfig = (
191
+ evalVersion: number | undefined,
192
+ evalStatus: Status | undefined,
193
+ evalSpec: EvalSpec | undefined,
194
+ evalPlan: EvalPlan | undefined,
195
+ evalError: EvalError | undefined,
196
+ evalResults: EvalResults | undefined,
197
+ evalStats: EvalStats | undefined,
198
+ ) => {
199
+ const selectedLogFile = useStore((state) =>
200
+ state.logsActions.getSelectedLogFile(),
201
+ );
202
+ const selectedTab = useStore((state) => state.app.tabs.workspace);
203
+
204
+ return useMemo(() => {
205
+ const evalHeader = {
206
+ version: evalVersion,
207
+ status: evalStatus,
208
+ eval: evalSpec,
209
+ plan: evalPlan,
210
+ error: evalError,
211
+ results: evalResults,
212
+ stats: evalStats,
213
+ };
214
+
215
+ return {
216
+ id: kJsonWorkspaceTabId,
217
+ label: "JSON",
218
+ scrollable: true,
219
+ component: JsonTab,
220
+ componentProps: {
221
+ logFile: selectedLogFile,
222
+ json: JSON.stringify(evalHeader, null, 2),
223
+ selected: selectedTab === kJsonWorkspaceTabId,
224
+ },
225
+ tools: () => [
226
+ <ToolButton
227
+ key="copy-json"
228
+ label="Copy JSON"
229
+ icon={ApplicationIcons.copy}
230
+ className={clsx("task-btn-json-copy", "clipboard-button")}
231
+ data-clipboard-target="#task-json-contents"
232
+ onClick={copyFeedback}
233
+ />,
234
+ ],
235
+ };
236
+ }, [
237
+ selectedLogFile,
238
+ evalVersion,
239
+ evalStatus,
240
+ evalSpec,
241
+ evalPlan,
242
+ evalError,
243
+ evalResults,
244
+ evalStats,
245
+ selectedTab,
246
+ ]);
247
+ };
248
+
249
+ // Main hook combining all tab configs
250
+ export const useResolvedTabs = (props: WorkSpaceProps) => {
251
+ const {
252
+ evalVersion,
253
+ evalStatus,
254
+ evalSpec,
255
+ evalPlan,
256
+ evalResults,
257
+ evalStats,
258
+ evalError,
259
+ refreshLog,
260
+ } = props;
205
261
 
206
- const samplesTab =
207
- sampleMode !== "none"
208
- ? {
209
- id: kEvalWorkspaceTabId,
210
- scrollable: samples?.length === 1,
211
- scrollRef: sampleTabScrollRef,
212
- label: (samples || []).length > 1 ? "Samples" : "Sample",
213
- content: () => (
214
- <SamplesTab
215
- sample={selectedSample}
216
- sampleStatus={sampleStatus}
217
- sampleError={sampleError}
218
- showingSampleDialog={showingSampleDialog}
219
- setShowingSampleDialog={setShowingSampleDialog}
220
- samples={samples}
221
- sampleMode={sampleMode}
222
- groupBy={groupBy}
223
- groupByOrder={groupByOrder}
224
- selectedSampleIndex={selectedSampleIndex}
225
- setSelectedSampleIndex={setSelectedSampleIndex}
226
- sampleDescriptor={samplesDescriptor}
227
- selectedSampleTab={selectedSampleTab}
228
- setSelectedSampleTab={setSelectedSampleTab}
229
- filter={filter}
230
- epoch={epoch}
231
- sampleScrollPositionRef={sampleScrollPositionRef}
232
- setSampleScrollPosition={setSampleScrollPosition}
233
- sampleTabScrollRef={sampleTabScrollRef}
234
- />
235
- ),
236
- tools: () =>
237
- sampleMode === "single" || !samplesDescriptor
238
- ? undefined
239
- : [
240
- <SampleTools
241
- key="sample-tools"
242
- epoch={epoch}
243
- epochs={epochs || 1}
244
- setEpoch={setEpoch}
245
- scoreFilter={filter}
246
- setScoreFilter={setFilter}
247
- sort={sort}
248
- setSort={setSort}
249
- score={score}
250
- setScore={setScore}
251
- scores={scores}
252
- sampleDescriptor={samplesDescriptor}
253
- />,
254
- evalStatus === "started" && (
255
- <ToolButton
256
- key="refresh"
257
- label="Refresh"
258
- icon={ApplicationIcons.refresh}
259
- onClick={refreshLog}
260
- />
261
- ),
262
- ].filter(Boolean),
263
- }
264
- : null;
262
+ // Use individual tab config hooks
263
+ const samplesTabConfig = useSamplesTabConfig(evalStatus, refreshLog);
265
264
 
266
- const configTab = {
267
- id: kInfoWorkspaceTabId,
268
- label: "Info",
269
- scrollable: true,
270
- content: () => (
271
- <InfoTab
272
- evalSpec={evalSpec}
273
- evalPlan={evalPlan}
274
- evalError={evalError}
275
- evalResults={evalResults}
276
- evalStats={evalStats}
277
- samples={samples}
278
- />
279
- ),
280
- };
265
+ const configTabConfig = useInfoTabConfig(
266
+ evalSpec,
267
+ evalPlan,
268
+ evalError,
269
+ evalResults,
270
+ evalStats,
271
+ );
281
272
 
282
- const jsonTab = {
283
- id: kJsonWorkspaceTabId,
284
- label: "JSON",
285
- scrollable: true,
286
- content: () => {
287
- const evalHeader = {
288
- version: evalVersion,
289
- status: evalStatus,
290
- eval: evalSpec,
291
- plan: evalPlan,
292
- error: evalError,
293
- results: evalResults,
294
- stats: evalStats,
295
- };
296
- return (
297
- <JsonTab
298
- logFile={logFileName}
299
- json={JSON.stringify(evalHeader, null, 2)}
300
- capabilities={capabilities}
301
- selected={selectedTab === kJsonWorkspaceTabId}
302
- />
303
- );
304
- },
305
- tools: () => [
306
- <ToolButton
307
- key="copy-json"
308
- label="Copy JSON"
309
- icon={ApplicationIcons.copy}
310
- className={clsx("task-btn-json-copy", "clipboard-button")}
311
- data-clipboard-target="#task-json-contents"
312
- onClick={copyFeedback}
313
- />,
314
- ],
315
- };
273
+ const jsonTabConfig = useJsonTabConfig(
274
+ evalVersion,
275
+ evalStatus,
276
+ evalSpec,
277
+ evalPlan,
278
+ evalError,
279
+ evalResults,
280
+ evalStats,
281
+ );
316
282
 
283
+ // Combine all tab configs
317
284
  return useMemo(
318
285
  () => ({
319
- ...(samplesTab ? { samples: samplesTab } : {}),
320
- config: configTab,
321
- json: jsonTab,
286
+ ...(samplesTabConfig ? { samples: samplesTabConfig } : {}),
287
+ config: configTabConfig,
288
+ json: jsonTabConfig,
322
289
  }),
323
- [samplesTab, configTab, jsonTab],
290
+ [samplesTabConfig, configTabConfig, jsonTabConfig],
324
291
  );
325
292
  };