inspect-ai 0.3.80__py3-none-any.whl → 0.3.82__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 (179) hide show
  1. inspect_ai/_cli/eval.py +35 -2
  2. inspect_ai/_cli/util.py +44 -1
  3. inspect_ai/_display/core/config.py +1 -1
  4. inspect_ai/_display/core/display.py +13 -4
  5. inspect_ai/_display/core/results.py +1 -1
  6. inspect_ai/_display/textual/widgets/task_detail.py +5 -4
  7. inspect_ai/_eval/eval.py +38 -1
  8. inspect_ai/_eval/evalset.py +5 -0
  9. inspect_ai/_eval/run.py +5 -2
  10. inspect_ai/_eval/task/log.py +53 -6
  11. inspect_ai/_eval/task/run.py +51 -10
  12. inspect_ai/_util/constants.py +2 -0
  13. inspect_ai/_util/file.py +17 -1
  14. inspect_ai/_util/json.py +36 -1
  15. inspect_ai/_view/server.py +113 -1
  16. inspect_ai/_view/www/App.css +1 -1
  17. inspect_ai/_view/www/dist/assets/index.css +518 -296
  18. inspect_ai/_view/www/dist/assets/index.js +38803 -36307
  19. inspect_ai/_view/www/eslint.config.mjs +1 -1
  20. inspect_ai/_view/www/log-schema.json +13 -0
  21. inspect_ai/_view/www/node_modules/flatted/python/flatted.py +149 -0
  22. inspect_ai/_view/www/package.json +8 -2
  23. inspect_ai/_view/www/src/App.tsx +151 -855
  24. inspect_ai/_view/www/src/api/api-browser.ts +176 -5
  25. inspect_ai/_view/www/src/api/api-vscode.ts +75 -1
  26. inspect_ai/_view/www/src/api/client-api.ts +66 -10
  27. inspect_ai/_view/www/src/api/jsonrpc.ts +2 -0
  28. inspect_ai/_view/www/src/api/types.ts +107 -2
  29. inspect_ai/_view/www/src/appearance/icons.ts +1 -0
  30. inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +3 -3
  31. inspect_ai/_view/www/src/components/DownloadPanel.tsx +2 -2
  32. inspect_ai/_view/www/src/components/ExpandablePanel.tsx +56 -61
  33. inspect_ai/_view/www/src/components/FindBand.tsx +17 -9
  34. inspect_ai/_view/www/src/components/HumanBaselineView.tsx +1 -1
  35. inspect_ai/_view/www/src/components/JsonPanel.tsx +14 -24
  36. inspect_ai/_view/www/src/components/LargeModal.tsx +2 -35
  37. inspect_ai/_view/www/src/components/LightboxCarousel.tsx +27 -11
  38. inspect_ai/_view/www/src/components/LiveVirtualList.module.css +11 -0
  39. inspect_ai/_view/www/src/components/LiveVirtualList.tsx +177 -0
  40. inspect_ai/_view/www/src/components/MarkdownDiv.tsx +3 -3
  41. inspect_ai/_view/www/src/components/MessageBand.tsx +14 -9
  42. inspect_ai/_view/www/src/components/MorePopOver.tsx +3 -3
  43. inspect_ai/_view/www/src/components/NavPills.tsx +20 -8
  44. inspect_ai/_view/www/src/components/NoContentsPanel.module.css +12 -0
  45. inspect_ai/_view/www/src/components/NoContentsPanel.tsx +20 -0
  46. inspect_ai/_view/www/src/components/ProgressBar.module.css +5 -4
  47. inspect_ai/_view/www/src/components/ProgressBar.tsx +3 -2
  48. inspect_ai/_view/www/src/components/PulsingDots.module.css +81 -0
  49. inspect_ai/_view/www/src/components/PulsingDots.tsx +45 -0
  50. inspect_ai/_view/www/src/components/TabSet.tsx +4 -37
  51. inspect_ai/_view/www/src/components/ToolButton.tsx +3 -4
  52. inspect_ai/_view/www/src/index.tsx +26 -94
  53. inspect_ai/_view/www/src/logfile/remoteLogFile.ts +9 -1
  54. inspect_ai/_view/www/src/logfile/remoteZipFile.ts +30 -4
  55. inspect_ai/_view/www/src/metadata/RenderedContent.tsx +4 -6
  56. inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +1 -1
  57. inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +9 -1
  58. inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +67 -28
  59. inspect_ai/_view/www/src/samples/SampleDialog.tsx +51 -22
  60. inspect_ai/_view/www/src/samples/SampleDisplay.module.css +4 -0
  61. inspect_ai/_view/www/src/samples/SampleDisplay.tsx +144 -90
  62. inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +4 -0
  63. inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +82 -35
  64. inspect_ai/_view/www/src/samples/SamplesTools.tsx +23 -30
  65. inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +2 -1
  66. inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +1 -1
  67. inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +45 -53
  68. inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +4 -1
  69. inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +3 -0
  70. inspect_ai/_view/www/src/samples/chat/messages.ts +34 -0
  71. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.module.css +3 -0
  72. inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +10 -1
  73. inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +22 -46
  74. inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +25 -17
  75. inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +2 -1
  76. inspect_ai/_view/www/src/samples/descriptor/types.ts +6 -5
  77. inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +21 -3
  78. inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +20 -1
  79. inspect_ai/_view/www/src/samples/list/SampleList.tsx +105 -85
  80. inspect_ai/_view/www/src/samples/list/SampleRow.module.css +6 -0
  81. inspect_ai/_view/www/src/samples/list/SampleRow.tsx +27 -14
  82. inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +29 -18
  83. inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +28 -28
  84. inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +19 -9
  85. inspect_ai/_view/www/src/samples/sampleDataAdapter.ts +33 -0
  86. inspect_ai/_view/www/src/samples/sampleLimit.ts +2 -2
  87. inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +7 -9
  88. inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +7 -11
  89. inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +0 -13
  90. inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +0 -13
  91. inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +0 -13
  92. inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +4 -0
  93. inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +10 -24
  94. inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +0 -13
  95. inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +4 -22
  96. inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +15 -24
  97. inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +0 -13
  98. inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +6 -28
  99. inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +24 -34
  100. inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +4 -0
  101. inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +8 -13
  102. inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +197 -338
  103. inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.module.css +16 -0
  104. inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.tsx +44 -0
  105. inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +7 -4
  106. inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +52 -58
  107. inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.module.css +23 -0
  108. inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.tsx +27 -0
  109. inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +30 -1
  110. inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +102 -72
  111. inspect_ai/_view/www/src/scoring/utils.ts +87 -0
  112. inspect_ai/_view/www/src/state/appSlice.ts +244 -0
  113. inspect_ai/_view/www/src/state/hooks.ts +397 -0
  114. inspect_ai/_view/www/src/state/logPolling.ts +196 -0
  115. inspect_ai/_view/www/src/state/logSlice.ts +214 -0
  116. inspect_ai/_view/www/src/state/logsPolling.ts +118 -0
  117. inspect_ai/_view/www/src/state/logsSlice.ts +181 -0
  118. inspect_ai/_view/www/src/state/samplePolling.ts +311 -0
  119. inspect_ai/_view/www/src/state/sampleSlice.ts +127 -0
  120. inspect_ai/_view/www/src/state/sampleUtils.ts +21 -0
  121. inspect_ai/_view/www/src/state/scrolling.ts +206 -0
  122. inspect_ai/_view/www/src/state/store.ts +168 -0
  123. inspect_ai/_view/www/src/state/store_filter.ts +84 -0
  124. inspect_ai/_view/www/src/state/utils.ts +23 -0
  125. inspect_ai/_view/www/src/storage/index.ts +26 -0
  126. inspect_ai/_view/www/src/types/log.d.ts +2 -0
  127. inspect_ai/_view/www/src/types.ts +94 -32
  128. inspect_ai/_view/www/src/utils/attachments.ts +58 -23
  129. inspect_ai/_view/www/src/utils/logger.ts +52 -0
  130. inspect_ai/_view/www/src/utils/polling.ts +100 -0
  131. inspect_ai/_view/www/src/utils/react.ts +30 -0
  132. inspect_ai/_view/www/src/utils/vscode.ts +1 -1
  133. inspect_ai/_view/www/src/workspace/WorkSpace.tsx +181 -216
  134. inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +11 -53
  135. inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +8 -18
  136. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +1 -0
  137. inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +40 -22
  138. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +0 -1
  139. inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +98 -39
  140. inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.module.css +32 -0
  141. inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.tsx +32 -0
  142. inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +11 -13
  143. inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +6 -2
  144. inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +4 -4
  145. inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +28 -13
  146. inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +5 -10
  147. inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +4 -4
  148. inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.module.css +22 -0
  149. inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.tsx +19 -0
  150. inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +110 -115
  151. inspect_ai/_view/www/src/workspace/tabs/grouping.ts +37 -5
  152. inspect_ai/_view/www/src/workspace/tabs/types.ts +4 -0
  153. inspect_ai/_view/www/src/workspace/types.ts +4 -3
  154. inspect_ai/_view/www/src/workspace/utils.ts +4 -4
  155. inspect_ai/_view/www/vite.config.js +6 -0
  156. inspect_ai/_view/www/yarn.lock +370 -354
  157. inspect_ai/log/_condense.py +26 -0
  158. inspect_ai/log/_log.py +6 -3
  159. inspect_ai/log/_recorders/buffer/__init__.py +14 -0
  160. inspect_ai/log/_recorders/buffer/buffer.py +30 -0
  161. inspect_ai/log/_recorders/buffer/database.py +685 -0
  162. inspect_ai/log/_recorders/buffer/filestore.py +259 -0
  163. inspect_ai/log/_recorders/buffer/types.py +84 -0
  164. inspect_ai/log/_recorders/eval.py +2 -11
  165. inspect_ai/log/_recorders/types.py +30 -0
  166. inspect_ai/log/_transcript.py +27 -1
  167. inspect_ai/model/_call_tools.py +1 -0
  168. inspect_ai/model/_generate_config.py +2 -2
  169. inspect_ai/model/_model.py +1 -0
  170. inspect_ai/tool/_tool_support_helpers.py +4 -4
  171. inspect_ai/tool/_tools/_web_browser/_web_browser.py +3 -1
  172. inspect_ai/util/_subtask.py +1 -0
  173. {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/METADATA +2 -2
  174. {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/RECORD +178 -138
  175. inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +0 -22
  176. {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/WHEEL +0 -0
  177. {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/entry_points.txt +0 -0
  178. {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/licenses/LICENSE +0 -0
  179. {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  import clsx from "clsx";
2
2
  import { ScoreLabel } from "../../types";
3
3
 
4
- import { FC } from "react";
4
+ import { ChangeEvent, FC, useCallback } from "react";
5
5
  import styles from "./SelectScorer.module.css";
6
6
 
7
7
  interface SelectScorerProps {
@@ -26,6 +26,13 @@ export const SelectScorer: FC<SelectScorerProps> = ({
26
26
  return accum;
27
27
  }, [] as ScoreLabel[]);
28
28
 
29
+ const handleSelectScore = useCallback(
30
+ (index: number) => {
31
+ setScore(scores[index]);
32
+ },
33
+ [setScore, scores],
34
+ );
35
+
29
36
  if (scorers.length === 1) {
30
37
  // There is only a single scorer in play, just show the list of available scores
31
38
  return (
@@ -44,9 +51,7 @@ export const SelectScorer: FC<SelectScorerProps> = ({
44
51
  <ScoreSelector
45
52
  scores={scores}
46
53
  selectedIndex={scoreIndex(scores, score)}
47
- setSelectedIndex={(index: number) => {
48
- setScore(scores[index]);
49
- }}
54
+ setSelectedIndex={handleSelectScore}
50
55
  />
51
56
  </div>
52
57
  );
@@ -75,18 +80,14 @@ export const SelectScorer: FC<SelectScorerProps> = ({
75
80
  <ScorerSelector
76
81
  scorers={scorers}
77
82
  selectedIndex={scorerIndex(scorers, score)}
78
- setSelectedIndex={(index: number) => {
79
- setScore(scorers[index]);
80
- }}
83
+ setSelectedIndex={handleSelectScore}
81
84
  />
82
85
  {scorerScores.length > 1 ? (
83
86
  <ScoreSelector
84
87
  className={clsx(styles.secondSel)}
85
88
  scores={scorerScores}
86
89
  selectedIndex={scoreIndex(scorerScores, score)}
87
- setSelectedIndex={(index: number) => {
88
- setScore(scorerScores[index]);
89
- }}
90
+ setSelectedIndex={handleSelectScore}
90
91
  />
91
92
  ) : undefined}
92
93
  </div>
@@ -107,6 +108,14 @@ const ScoreSelector: FC<ScoreSelectorProps> = ({
107
108
  setSelectedIndex,
108
109
  className,
109
110
  }) => {
111
+ const handleChange = useCallback(
112
+ (e: ChangeEvent<HTMLSelectElement>) => {
113
+ const sel = e.target as HTMLSelectElement;
114
+ setSelectedIndex(sel.selectedIndex);
115
+ },
116
+ [setSelectedIndex],
117
+ );
118
+
110
119
  return (
111
120
  <select
112
121
  className={clsx(
@@ -117,10 +126,7 @@ const ScoreSelector: FC<ScoreSelectorProps> = ({
117
126
  )}
118
127
  aria-label=".select-scorer-label"
119
128
  value={scores[selectedIndex].name}
120
- onChange={(e) => {
121
- const sel = e.target as HTMLSelectElement;
122
- setSelectedIndex(sel.selectedIndex);
123
- }}
129
+ onChange={handleChange}
124
130
  >
125
131
  {scores.map((score) => {
126
132
  return (
@@ -144,15 +150,20 @@ const ScorerSelector: FC<ScorerSelectorProps> = ({
144
150
  selectedIndex,
145
151
  setSelectedIndex,
146
152
  }) => {
153
+ const handleChange = useCallback(
154
+ (e: ChangeEvent<HTMLSelectElement>) => {
155
+ const sel = e.target as HTMLSelectElement;
156
+ setSelectedIndex(sel.selectedIndex);
157
+ },
158
+ [setSelectedIndex],
159
+ );
160
+
147
161
  return (
148
162
  <select
149
163
  className={clsx("form-select", "form-select-sm", "text-size-smaller")}
150
164
  aria-label=".epoch-filter-label"
151
165
  value={scorers[selectedIndex].scorer}
152
- onChange={(e) => {
153
- const sel = e.target as HTMLSelectElement;
154
- setSelectedIndex(sel.selectedIndex);
155
- }}
166
+ onChange={handleChange}
156
167
  >
157
168
  {scorers.map((scorer) => {
158
169
  return (
@@ -1,5 +1,5 @@
1
1
  import clsx from "clsx";
2
- import { FC } from "react";
2
+ import { ChangeEvent, FC, useCallback } from "react";
3
3
  import { SampleSummary } from "../../api/types";
4
4
  import {
5
5
  kEpochAscVal,
@@ -9,6 +9,7 @@ import {
9
9
  kScoreAscVal,
10
10
  kScoreDescVal,
11
11
  } from "../../constants";
12
+ import { ScoreLabel } from "../../types";
12
13
  import { isNumeric } from "../../utils/type";
13
14
  import { SamplesDescriptor } from "../descriptor/samplesDescriptor";
14
15
  import styles from "./SortFilter.module.css";
@@ -42,6 +43,15 @@ export const SortFilter: FC<SortFilterProps> = ({ sort, setSort, epochs }) => {
42
43
  label: "score desc",
43
44
  val: kScoreDescVal,
44
45
  });
46
+
47
+ const handleChange = useCallback(
48
+ (e: ChangeEvent<HTMLSelectElement>) => {
49
+ const sel = e.target as HTMLSelectElement;
50
+ setSort(sel.value);
51
+ },
52
+ [setSort],
53
+ );
54
+
45
55
  return (
46
56
  <div className={styles.flex}>
47
57
  <span
@@ -59,10 +69,7 @@ export const SortFilter: FC<SortFilterProps> = ({ sort, setSort, epochs }) => {
59
69
  className={clsx("form-select", "form-select-sm", "text-size-smaller")}
60
70
  aria-label=".sort-filter-label"
61
71
  value={sort}
62
- onChange={(e) => {
63
- const sel = e.target as HTMLSelectElement;
64
- setSort(sel.value);
65
- }}
72
+ onChange={handleChange}
66
73
  >
67
74
  {options.map((option) => {
68
75
  return (
@@ -102,8 +109,13 @@ export const sortSamples = (
102
109
  sort: string,
103
110
  samples: SampleSummary[],
104
111
  samplesDescriptor: SamplesDescriptor,
105
- ): { sorted: SampleSummary[]; order: "asc" | "desc" } => {
112
+ score?: ScoreLabel,
113
+ ): SampleSummary[] => {
106
114
  const sortedSamples = samples.sort((a: SampleSummary, b: SampleSummary) => {
115
+ const scoreDescriptor = score
116
+ ? samplesDescriptor.evalDescriptor.scoreDescriptor(score)
117
+ : undefined;
118
+
107
119
  switch (sort) {
108
120
  case kSampleAscVal: {
109
121
  const result = sortId(a, b);
@@ -134,50 +146,38 @@ export const sortSamples = (
134
146
  if (result !== 0) {
135
147
  return result;
136
148
  } else {
137
- return sortId(a, b);
149
+ return sortId(b, a);
138
150
  }
139
151
  }
140
152
 
141
153
  case kScoreAscVal: {
142
- const aScore = samplesDescriptor.selectedScore(a);
143
- const bScore = samplesDescriptor.selectedScore(b);
154
+ const aScore = samplesDescriptor.evalDescriptor.score(a, score);
155
+ const bScore = samplesDescriptor.evalDescriptor.score(b, score);
144
156
  if (
145
157
  aScore === undefined ||
146
158
  bScore === undefined ||
147
- samplesDescriptor.selectedScoreDescriptor == undefined
159
+ scoreDescriptor === undefined
148
160
  ) {
149
161
  return 0;
150
162
  }
151
- return samplesDescriptor.selectedScoreDescriptor.compare(
152
- aScore,
153
- bScore,
154
- );
163
+ return scoreDescriptor?.compare(aScore, bScore);
155
164
  }
156
165
  case kScoreDescVal: {
157
- const aScore = samplesDescriptor.selectedScore(a);
158
- const bScore = samplesDescriptor.selectedScore(b);
166
+ const aScore = samplesDescriptor.evalDescriptor.score(a, score);
167
+ const bScore = samplesDescriptor.evalDescriptor.score(b, score);
159
168
  if (
160
169
  aScore === undefined ||
161
170
  bScore === undefined ||
162
- samplesDescriptor.selectedScoreDescriptor == undefined
171
+ scoreDescriptor == undefined
163
172
  ) {
164
173
  return 0;
165
174
  }
166
175
 
167
- return samplesDescriptor.selectedScoreDescriptor.compare(
168
- bScore,
169
- aScore,
170
- );
176
+ return scoreDescriptor?.compare(bScore, aScore);
171
177
  }
172
178
  default:
173
179
  return 0;
174
180
  }
175
181
  });
176
- return {
177
- sorted: sortedSamples,
178
- order:
179
- sort === kSampleAscVal || sort === kEpochAscVal || sort === kScoreAscVal
180
- ? "asc"
181
- : "desc",
182
- };
182
+ return sortedSamples;
183
183
  };
@@ -16,6 +16,8 @@ import clsx from "clsx";
16
16
  import { EditorView, minimalSetup } from "codemirror";
17
17
  import { FC, useEffect, useMemo, useRef, useState } from "react";
18
18
 
19
+ import { SampleSummary } from "../../../api/types";
20
+ import { useEvalDescriptor } from "../../../state/hooks";
19
21
  import { ScoreFilter } from "../../../types";
20
22
  import { EvalDescriptor } from "../../descriptor/types";
21
23
  import { FilterError, filterSamples, scoreFilterItems } from "../filters";
@@ -30,7 +32,7 @@ interface FilteringResult {
30
32
  }
31
33
 
32
34
  interface SampleFilterProps {
33
- evalDescriptor: EvalDescriptor;
35
+ samples: SampleSummary[];
34
36
  scoreFilter: ScoreFilter;
35
37
  setScoreFilter: (filter: ScoreFilter) => void;
36
38
  }
@@ -105,11 +107,12 @@ const editorTheme = EditorView.theme({
105
107
  // Helper functions
106
108
  const getFilteringResult = (
107
109
  evalDescriptor: EvalDescriptor,
110
+ sampleSummaries: SampleSummary[],
108
111
  filterValue: string,
109
112
  ): FilteringResult => {
110
113
  const { result, error } = filterSamples(
111
114
  evalDescriptor,
112
- evalDescriptor.samples,
115
+ sampleSummaries,
113
116
  filterValue,
114
117
  );
115
118
  return { numSamples: result.length, error };
@@ -151,7 +154,7 @@ const getLints = (
151
154
 
152
155
  // Main component
153
156
  export const SampleFilter: FC<SampleFilterProps> = ({
154
- evalDescriptor,
157
+ samples,
155
158
  scoreFilter,
156
159
  setScoreFilter,
157
160
  }) => {
@@ -160,9 +163,10 @@ export const SampleFilter: FC<SampleFilterProps> = ({
160
163
  const linterCompartment = useRef<Compartment>(new Compartment());
161
164
  const autocompletionCompartment = useRef<Compartment>(new Compartment());
162
165
  const updateListenerCompartment = useRef<Compartment>(new Compartment());
166
+ const evalDescriptor = useEvalDescriptor();
163
167
 
164
168
  const filterItems = useMemo(
165
- () => scoreFilterItems(evalDescriptor),
169
+ () => (evalDescriptor ? scoreFilterItems(evalDescriptor) : []),
166
170
  [evalDescriptor],
167
171
  );
168
172
 
@@ -186,9 +190,13 @@ export const SampleFilter: FC<SampleFilterProps> = ({
186
190
 
187
191
  const makeUpdateListener = () =>
188
192
  EditorView.updateListener.of((update) => {
189
- if (update.docChanged) {
193
+ if (update.docChanged && evalDescriptor) {
190
194
  const newValue = update.state.doc.toString();
191
- const filteringResult = getFilteringResult(evalDescriptor, newValue);
195
+ const filteringResult = getFilteringResult(
196
+ evalDescriptor,
197
+ samples,
198
+ newValue,
199
+ );
192
200
  if (!filteringResult.error) {
193
201
  setScoreFilter({ value: newValue });
194
202
  }
@@ -229,9 +237,11 @@ export const SampleFilter: FC<SampleFilterProps> = ({
229
237
  const currentValue = editorViewRef.current.state.doc.toString();
230
238
  if (scoreFilter.value === currentValue) return;
231
239
 
232
- setFilteringResultInstant(
233
- getFilteringResult(evalDescriptor, scoreFilter.value || ""),
234
- );
240
+ if (evalDescriptor) {
241
+ setFilteringResultInstant(
242
+ getFilteringResult(evalDescriptor, samples, scoreFilter.value || ""),
243
+ );
244
+ }
235
245
  editorViewRef.current.dispatch({
236
246
  changes: {
237
247
  from: 0,
@@ -0,0 +1,33 @@
1
+ import { EventData, SampleData } from "../api/types";
2
+ import { Events } from "../types/log";
3
+ import { resolveAttachments } from "../utils/attachments";
4
+
5
+ export const sampleDataAdapter = () => {
6
+ const attachments: Record<string, string> = {};
7
+ const events: Record<string, EventData> = {};
8
+
9
+ return {
10
+ addData: (data: SampleData) => {
11
+ data.attachments.forEach((a) => {
12
+ if (attachments[a.hash] === undefined) {
13
+ attachments[a.hash] = a.content;
14
+ }
15
+ });
16
+
17
+ data.events.forEach((e) => {
18
+ if (events[e.event_id] === undefined) {
19
+ events[e.event_id] = e;
20
+ }
21
+ });
22
+ },
23
+ resolvedEvents: (): Events => {
24
+ const eventDatas = Object.values(events);
25
+
26
+ const resolvedEvents = eventDatas.map((ed: EventData) => {
27
+ return ed.event;
28
+ }) as Events;
29
+
30
+ return resolveAttachments<Events>(resolvedEvents, attachments);
31
+ },
32
+ };
33
+ };
@@ -1,9 +1,9 @@
1
- import { Type11 } from "../types/log";
1
+ import { Type14 } from "../types/log";
2
2
 
3
3
  /**
4
4
  * Formats a limit message
5
5
  */
6
- export const sampleLimitMessage = (type: Type11): string => {
6
+ export const sampleLimitMessage = (type: Type14): string => {
7
7
  switch (type) {
8
8
  case "operator":
9
9
  return "Sample terminated due to operator limit.";
@@ -4,27 +4,26 @@ import { MarkdownDiv } from "../../components/MarkdownDiv";
4
4
  import { MetaDataGrid } from "../../metadata/MetaDataGrid";
5
5
  import { EvalSample } from "../../types/log";
6
6
  import { arrayToString, inputString } from "../../utils/format";
7
- import { SamplesDescriptor } from "../descriptor/samplesDescriptor";
8
7
  import { SampleScores } from "./SampleScores";
9
8
 
10
9
  import { FC } from "react";
11
10
  import { SampleSummary } from "../../api/types";
11
+ import { useEvalDescriptor } from "../../state/hooks";
12
12
  import styles from "./SampleScoreView.module.css";
13
13
 
14
14
  interface SampleScoreViewProps {
15
15
  sample: EvalSample;
16
- sampleDescriptor: SamplesDescriptor;
17
16
  scorer: string;
18
17
  className?: string | string[];
19
18
  }
20
19
 
21
20
  export const SampleScoreView: FC<SampleScoreViewProps> = ({
22
21
  sample,
23
- sampleDescriptor,
24
22
  className,
25
23
  scorer,
26
24
  }) => {
27
- if (!sampleDescriptor) {
25
+ const evalDescriptor = useEvalDescriptor();
26
+ if (!evalDescriptor) {
28
27
  return null;
29
28
  }
30
29
 
@@ -38,10 +37,10 @@ export const SampleScoreView: FC<SampleScoreViewProps> = ({
38
37
  );
39
38
  }
40
39
 
41
- const scorerDescriptor = sampleDescriptor.evalDescriptor.scorerDescriptor(
42
- sample,
43
- { scorer, name: scorer },
44
- );
40
+ const scorerDescriptor = evalDescriptor.scorerDescriptor(sample, {
41
+ scorer,
42
+ name: scorer,
43
+ });
45
44
  const explanation = scorerDescriptor.explanation() || "(No Explanation)";
46
45
  const answer = scorerDescriptor.answer();
47
46
  const metadata = scorerDescriptor.metadata();
@@ -128,7 +127,6 @@ export const SampleScoreView: FC<SampleScoreViewProps> = ({
128
127
  <td className={clsx(styles.scoreValue)}>
129
128
  <SampleScores
130
129
  sample={sample as any as SampleSummary}
131
- sampleDescriptor={sampleDescriptor}
132
130
  scorer={scorer}
133
131
  />
134
132
  </td>
@@ -1,30 +1,26 @@
1
1
  import { FC, Fragment } from "react";
2
2
  import { SampleSummary } from "../../api/types";
3
- import { SamplesDescriptor } from "../descriptor/samplesDescriptor";
4
3
 
4
+ import { useSampleDescriptor } from "../../state/hooks";
5
5
  import styles from "./SampleScores.module.css";
6
6
 
7
7
  interface SampleScoresProps {
8
8
  sample: SampleSummary;
9
- sampleDescriptor: SamplesDescriptor;
10
9
  scorer: string;
11
10
  }
12
11
 
13
- export const SampleScores: FC<SampleScoresProps> = ({
14
- sample,
15
- sampleDescriptor,
16
- scorer,
17
- }) => {
12
+ export const SampleScores: FC<SampleScoresProps> = ({ sample, scorer }) => {
13
+ const samplesDescriptor = useSampleDescriptor();
18
14
  const scores = scorer
19
- ? sampleDescriptor.evalDescriptor
15
+ ? samplesDescriptor?.evalDescriptor
20
16
  .scorerDescriptor(sample, { scorer, name: scorer })
21
17
  .scores()
22
- : sampleDescriptor.selectedScorerDescriptor(sample).scores();
18
+ : samplesDescriptor?.selectedScorerDescriptor(sample)?.scores();
23
19
 
24
- if (scores.length === 1) {
20
+ if (scores?.length === 1) {
25
21
  return scores[0].rendered();
26
22
  } else {
27
- const rows = scores.map((score) => {
23
+ const rows = scores?.map((score) => {
28
24
  return (
29
25
  <Fragment>
30
26
  <div style={{ opacity: "0.7" }}>{score.name}</div>
@@ -4,13 +4,10 @@ import { ANSIDisplay } from "../../components/AnsiDisplay";
4
4
  import { ErrorEvent } from "../../types/log";
5
5
  import { formatDateTime } from "../../utils/format";
6
6
  import { EventPanel } from "./event/EventPanel";
7
- import { TranscriptEventState } from "./types";
8
7
 
9
8
  interface ErrorEventViewProps {
10
9
  id: string;
11
10
  event: ErrorEvent;
12
- eventState: TranscriptEventState;
13
- setEventState: (state: TranscriptEventState) => void;
14
11
  className?: string | string[];
15
12
  }
16
13
 
@@ -20,8 +17,6 @@ interface ErrorEventViewProps {
20
17
  export const ErrorEventView: FC<ErrorEventViewProps> = ({
21
18
  id,
22
19
  event,
23
- eventState,
24
- setEventState,
25
20
  className,
26
21
  }) => {
27
22
  return (
@@ -31,14 +26,6 @@ export const ErrorEventView: FC<ErrorEventViewProps> = ({
31
26
  className={className}
32
27
  subTitle={formatDateTime(new Date(event.timestamp))}
33
28
  icon={ApplicationIcons.error}
34
- selectedNav={eventState.selectedNav || ""}
35
- setSelectedNav={(selectedNav: string) => {
36
- setEventState({ ...eventState, selectedNav });
37
- }}
38
- collapsed={eventState.collapsed}
39
- setCollapsed={(collapsed: boolean) => {
40
- setEventState({ ...eventState, collapsed });
41
- }}
42
29
  >
43
30
  <ANSIDisplay
44
31
  output={event.error.traceback_ansi}
@@ -6,13 +6,10 @@ import { InfoEvent } from "../../types/log";
6
6
  import { formatDateTime } from "../../utils/format";
7
7
  import { EventPanel } from "./event/EventPanel";
8
8
  import styles from "./InfoEventView.module.css";
9
- import { TranscriptEventState } from "./types";
10
9
 
11
10
  interface InfoEventViewProps {
12
11
  id: string;
13
12
  event: InfoEvent;
14
- eventState: TranscriptEventState;
15
- setEventState: (state: TranscriptEventState) => void;
16
13
  className?: string | string[];
17
14
  }
18
15
 
@@ -22,8 +19,6 @@ interface InfoEventViewProps {
22
19
  export const InfoEventView: FC<InfoEventViewProps> = ({
23
20
  id,
24
21
  event,
25
- eventState,
26
- setEventState,
27
22
  className,
28
23
  }) => {
29
24
  const panels = [];
@@ -40,14 +35,6 @@ export const InfoEventView: FC<InfoEventViewProps> = ({
40
35
  className={className}
41
36
  subTitle={formatDateTime(new Date(event.timestamp))}
42
37
  icon={ApplicationIcons.info}
43
- selectedNav={eventState.selectedNav || ""}
44
- setSelectedNav={(selectedNav) => {
45
- setEventState({ ...eventState, selectedNav });
46
- }}
47
- collapsed={eventState.collapsed}
48
- setCollapsed={(collapsed) => {
49
- setEventState({ ...eventState, collapsed });
50
- }}
51
38
  >
52
39
  {panels}
53
40
  </EventPanel>
@@ -4,13 +4,10 @@ import { ANSIDisplay } from "../../components/AnsiDisplay";
4
4
  import { InputEvent } from "../../types/log";
5
5
  import { formatDateTime } from "../../utils/format";
6
6
  import { EventPanel } from "./event/EventPanel";
7
- import { TranscriptEventState } from "./types";
8
7
 
9
8
  interface InputEventViewProps {
10
9
  id: string;
11
10
  event: InputEvent;
12
- eventState: TranscriptEventState;
13
- setEventState: (state: TranscriptEventState) => void;
14
11
  className?: string | string[];
15
12
  }
16
13
 
@@ -20,8 +17,6 @@ interface InputEventViewProps {
20
17
  export const InputEventView: FC<InputEventViewProps> = ({
21
18
  id,
22
19
  event,
23
- eventState,
24
- setEventState,
25
20
  className,
26
21
  }) => {
27
22
  return (
@@ -31,14 +26,6 @@ export const InputEventView: FC<InputEventViewProps> = ({
31
26
  className={className}
32
27
  subTitle={formatDateTime(new Date(event.timestamp))}
33
28
  icon={ApplicationIcons.input}
34
- selectedNav={eventState.selectedNav || ""}
35
- setSelectedNav={(selectedNav) => {
36
- setEventState({ ...eventState, selectedNav });
37
- }}
38
- collapsed={eventState.collapsed}
39
- setCollapsed={(collapsed) => {
40
- setEventState({ ...eventState, collapsed });
41
- }}
42
29
  >
43
30
  <ANSIDisplay
44
31
  output={event.input_ansi}
@@ -41,3 +41,7 @@
41
41
  column-gap: 1em;
42
42
  row-gap: 0.5em;
43
43
  }
44
+
45
+ .progress {
46
+ margin-left: 2em;
47
+ }
@@ -3,7 +3,7 @@ import "prismjs/components/prism-json";
3
3
  import "prismjs/components/prism-python";
4
4
 
5
5
  import clsx from "clsx";
6
- import { FC, Fragment, useEffect, useMemo, useRef } from "react";
6
+ import { FC, Fragment, useMemo } from "react";
7
7
  import { ApplicationIcons } from "../../appearance/icons";
8
8
  import { MetaDataGrid } from "../../metadata/MetaDataGrid";
9
9
  import {
@@ -17,9 +17,9 @@ import { ModelUsagePanel } from "../../usage/ModelUsagePanel";
17
17
  import { ChatView } from "../chat/ChatView";
18
18
  import { EventPanel } from "./event/EventPanel";
19
19
  import { EventSection } from "./event/EventSection";
20
- import { TranscriptEventState } from "./types";
21
20
 
22
- import { highlightElement } from "prismjs";
21
+ import { PulsingDots } from "../../components/PulsingDots";
22
+ import { usePrismHighlight } from "../../state/hooks";
23
23
  import styles from "./ModelEventView.module.css";
24
24
  import { EventTimingPanel } from "./event/EventTimingPanel";
25
25
  import { formatTiming, formatTitle } from "./event/utils";
@@ -27,8 +27,6 @@ import { formatTiming, formatTitle } from "./event/utils";
27
27
  interface ModelEventViewProps {
28
28
  id: string;
29
29
  event: ModelEvent;
30
- eventState: TranscriptEventState;
31
- setEventState: (state: TranscriptEventState) => void;
32
30
  className?: string | string[];
33
31
  }
34
32
 
@@ -38,8 +36,6 @@ interface ModelEventViewProps {
38
36
  export const ModelEventView: FC<ModelEventViewProps> = ({
39
37
  id,
40
38
  event,
41
- eventState,
42
- setEventState,
43
39
  className,
44
40
  }) => {
45
41
  const totalUsage = event.output.usage?.total_tokens;
@@ -74,14 +70,6 @@ export const ModelEventView: FC<ModelEventViewProps> = ({
74
70
  title={formatTitle(`Model Call: ${event.model}`, totalUsage, callTime)}
75
71
  subTitle={formatTiming(event.timestamp, event.working_start)}
76
72
  icon={ApplicationIcons.model}
77
- selectedNav={eventState.selectedNav || ""}
78
- setSelectedNav={(selectedNav) => {
79
- setEventState({ ...eventState, selectedNav });
80
- }}
81
- collapsed={eventState.collapsed}
82
- setCollapsed={(collapsed) => {
83
- setEventState({ ...eventState, collapsed });
84
- }}
85
73
  >
86
74
  <div data-name="Summary" className={styles.container}>
87
75
  <ChatView
@@ -91,6 +79,11 @@ export const ModelEventView: FC<ModelEventViewProps> = ({
91
79
  numbered={false}
92
80
  toolCallStyle="compact"
93
81
  />
82
+ {event.pending ? (
83
+ <div className={clsx(styles.progress)}>
84
+ <PulsingDots subtle={false} size="medium" />
85
+ </div>
86
+ ) : undefined}
94
87
  </div>
95
88
  <div data-name="All" className={styles.container}>
96
89
  <div className={styles.all}>
@@ -170,27 +163,20 @@ interface APICodeCellProps {
170
163
  }
171
164
 
172
165
  export const APICodeCell: FC<APICodeCellProps> = ({ id, contents }) => {
173
- const codeRef = useRef<HTMLElement>(null);
174
166
  const sourceCode = useMemo(() => {
175
167
  return JSON.stringify(contents, undefined, 2);
176
168
  }, [contents]);
177
-
178
- useEffect(() => {
179
- if (codeRef.current) {
180
- highlightElement(codeRef.current);
181
- }
182
- }, [contents]);
169
+ const prismParentRef = usePrismHighlight(sourceCode);
183
170
 
184
171
  if (!contents) {
185
172
  return null;
186
173
  }
187
174
 
188
175
  return (
189
- <div className={clsx("model-call")}>
176
+ <div ref={prismParentRef} className={clsx("model-call")}>
190
177
  <pre className={clsx(styles.codePre)}>
191
178
  <code
192
179
  id={id}
193
- ref={codeRef}
194
180
  className={clsx("language-json", styles.code, "text-size-small")}
195
181
  >
196
182
  {sourceCode}