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.
- inspect_ai/_cli/eval.py +35 -2
- inspect_ai/_cli/util.py +44 -1
- inspect_ai/_display/core/config.py +1 -1
- inspect_ai/_display/core/display.py +13 -4
- inspect_ai/_display/core/results.py +1 -1
- inspect_ai/_display/textual/widgets/task_detail.py +5 -4
- inspect_ai/_eval/eval.py +38 -1
- inspect_ai/_eval/evalset.py +5 -0
- inspect_ai/_eval/run.py +5 -2
- inspect_ai/_eval/task/log.py +53 -6
- inspect_ai/_eval/task/run.py +51 -10
- inspect_ai/_util/constants.py +2 -0
- inspect_ai/_util/file.py +17 -1
- inspect_ai/_util/json.py +36 -1
- inspect_ai/_view/server.py +113 -1
- inspect_ai/_view/www/App.css +1 -1
- inspect_ai/_view/www/dist/assets/index.css +518 -296
- inspect_ai/_view/www/dist/assets/index.js +38803 -36307
- inspect_ai/_view/www/eslint.config.mjs +1 -1
- inspect_ai/_view/www/log-schema.json +13 -0
- inspect_ai/_view/www/node_modules/flatted/python/flatted.py +149 -0
- inspect_ai/_view/www/package.json +8 -2
- inspect_ai/_view/www/src/App.tsx +151 -855
- inspect_ai/_view/www/src/api/api-browser.ts +176 -5
- inspect_ai/_view/www/src/api/api-vscode.ts +75 -1
- inspect_ai/_view/www/src/api/client-api.ts +66 -10
- inspect_ai/_view/www/src/api/jsonrpc.ts +2 -0
- inspect_ai/_view/www/src/api/types.ts +107 -2
- inspect_ai/_view/www/src/appearance/icons.ts +1 -0
- inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +3 -3
- inspect_ai/_view/www/src/components/DownloadPanel.tsx +2 -2
- inspect_ai/_view/www/src/components/ExpandablePanel.tsx +56 -61
- inspect_ai/_view/www/src/components/FindBand.tsx +17 -9
- inspect_ai/_view/www/src/components/HumanBaselineView.tsx +1 -1
- inspect_ai/_view/www/src/components/JsonPanel.tsx +14 -24
- inspect_ai/_view/www/src/components/LargeModal.tsx +2 -35
- inspect_ai/_view/www/src/components/LightboxCarousel.tsx +27 -11
- inspect_ai/_view/www/src/components/LiveVirtualList.module.css +11 -0
- inspect_ai/_view/www/src/components/LiveVirtualList.tsx +177 -0
- inspect_ai/_view/www/src/components/MarkdownDiv.tsx +3 -3
- inspect_ai/_view/www/src/components/MessageBand.tsx +14 -9
- inspect_ai/_view/www/src/components/MorePopOver.tsx +3 -3
- inspect_ai/_view/www/src/components/NavPills.tsx +20 -8
- inspect_ai/_view/www/src/components/NoContentsPanel.module.css +12 -0
- inspect_ai/_view/www/src/components/NoContentsPanel.tsx +20 -0
- inspect_ai/_view/www/src/components/ProgressBar.module.css +5 -4
- inspect_ai/_view/www/src/components/ProgressBar.tsx +3 -2
- inspect_ai/_view/www/src/components/PulsingDots.module.css +81 -0
- inspect_ai/_view/www/src/components/PulsingDots.tsx +45 -0
- inspect_ai/_view/www/src/components/TabSet.tsx +4 -37
- inspect_ai/_view/www/src/components/ToolButton.tsx +3 -4
- inspect_ai/_view/www/src/index.tsx +26 -94
- inspect_ai/_view/www/src/logfile/remoteLogFile.ts +9 -1
- inspect_ai/_view/www/src/logfile/remoteZipFile.ts +30 -4
- inspect_ai/_view/www/src/metadata/RenderedContent.tsx +4 -6
- inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +1 -1
- inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +9 -1
- inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +67 -28
- inspect_ai/_view/www/src/samples/SampleDialog.tsx +51 -22
- inspect_ai/_view/www/src/samples/SampleDisplay.module.css +4 -0
- inspect_ai/_view/www/src/samples/SampleDisplay.tsx +144 -90
- inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +4 -0
- inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +82 -35
- inspect_ai/_view/www/src/samples/SamplesTools.tsx +23 -30
- inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +2 -1
- inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +1 -1
- inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +45 -53
- inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +4 -1
- inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +3 -0
- inspect_ai/_view/www/src/samples/chat/messages.ts +34 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.module.css +3 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +10 -1
- inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +22 -46
- inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +25 -17
- inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +2 -1
- inspect_ai/_view/www/src/samples/descriptor/types.ts +6 -5
- inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +21 -3
- inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +20 -1
- inspect_ai/_view/www/src/samples/list/SampleList.tsx +105 -85
- inspect_ai/_view/www/src/samples/list/SampleRow.module.css +6 -0
- inspect_ai/_view/www/src/samples/list/SampleRow.tsx +27 -14
- inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +29 -18
- inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +28 -28
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +19 -9
- inspect_ai/_view/www/src/samples/sampleDataAdapter.ts +33 -0
- inspect_ai/_view/www/src/samples/sampleLimit.ts +2 -2
- inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +7 -9
- inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +7 -11
- inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +4 -0
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +10 -24
- inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +4 -22
- inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +15 -24
- inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +6 -28
- inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +24 -34
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +4 -0
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +8 -13
- inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +197 -338
- inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.module.css +16 -0
- inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.tsx +44 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +7 -4
- inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +52 -58
- inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.module.css +23 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.tsx +27 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +30 -1
- inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +102 -72
- inspect_ai/_view/www/src/scoring/utils.ts +87 -0
- inspect_ai/_view/www/src/state/appSlice.ts +244 -0
- inspect_ai/_view/www/src/state/hooks.ts +397 -0
- inspect_ai/_view/www/src/state/logPolling.ts +196 -0
- inspect_ai/_view/www/src/state/logSlice.ts +214 -0
- inspect_ai/_view/www/src/state/logsPolling.ts +118 -0
- inspect_ai/_view/www/src/state/logsSlice.ts +181 -0
- inspect_ai/_view/www/src/state/samplePolling.ts +311 -0
- inspect_ai/_view/www/src/state/sampleSlice.ts +127 -0
- inspect_ai/_view/www/src/state/sampleUtils.ts +21 -0
- inspect_ai/_view/www/src/state/scrolling.ts +206 -0
- inspect_ai/_view/www/src/state/store.ts +168 -0
- inspect_ai/_view/www/src/state/store_filter.ts +84 -0
- inspect_ai/_view/www/src/state/utils.ts +23 -0
- inspect_ai/_view/www/src/storage/index.ts +26 -0
- inspect_ai/_view/www/src/types/log.d.ts +2 -0
- inspect_ai/_view/www/src/types.ts +94 -32
- inspect_ai/_view/www/src/utils/attachments.ts +58 -23
- inspect_ai/_view/www/src/utils/logger.ts +52 -0
- inspect_ai/_view/www/src/utils/polling.ts +100 -0
- inspect_ai/_view/www/src/utils/react.ts +30 -0
- inspect_ai/_view/www/src/utils/vscode.ts +1 -1
- inspect_ai/_view/www/src/workspace/WorkSpace.tsx +181 -216
- inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +11 -53
- inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +8 -18
- inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +1 -0
- inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +40 -22
- inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +0 -1
- inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +98 -39
- inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.module.css +32 -0
- inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.tsx +32 -0
- inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +11 -13
- inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +6 -2
- inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +4 -4
- inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +28 -13
- inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +5 -10
- inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +4 -4
- inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.module.css +22 -0
- inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.tsx +19 -0
- inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +110 -115
- inspect_ai/_view/www/src/workspace/tabs/grouping.ts +37 -5
- inspect_ai/_view/www/src/workspace/tabs/types.ts +4 -0
- inspect_ai/_view/www/src/workspace/types.ts +4 -3
- inspect_ai/_view/www/src/workspace/utils.ts +4 -4
- inspect_ai/_view/www/vite.config.js +6 -0
- inspect_ai/_view/www/yarn.lock +370 -354
- inspect_ai/log/_condense.py +26 -0
- inspect_ai/log/_log.py +6 -3
- inspect_ai/log/_recorders/buffer/__init__.py +14 -0
- inspect_ai/log/_recorders/buffer/buffer.py +30 -0
- inspect_ai/log/_recorders/buffer/database.py +685 -0
- inspect_ai/log/_recorders/buffer/filestore.py +259 -0
- inspect_ai/log/_recorders/buffer/types.py +84 -0
- inspect_ai/log/_recorders/eval.py +2 -11
- inspect_ai/log/_recorders/types.py +30 -0
- inspect_ai/log/_transcript.py +27 -1
- inspect_ai/model/_call_tools.py +1 -0
- inspect_ai/model/_generate_config.py +2 -2
- inspect_ai/model/_model.py +1 -0
- inspect_ai/tool/_tool_support_helpers.py +4 -4
- inspect_ai/tool/_tools/_web_browser/_web_browser.py +3 -1
- inspect_ai/util/_subtask.py +1 -0
- {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/METADATA +2 -2
- {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/RECORD +178 -138
- inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +0 -22
- {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/WHEEL +0 -0
- {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/licenses/LICENSE +0 -0
- {inspect_ai-0.3.80.dist-info → inspect_ai-0.3.82.dist-info}/top_level.txt +0 -0
@@ -15,14 +15,14 @@ import {
|
|
15
15
|
export interface SamplesDescriptor {
|
16
16
|
evalDescriptor: EvalDescriptor;
|
17
17
|
messageShape: MessageShape;
|
18
|
-
selectedScoreDescriptor?: ScoreDescriptor;
|
19
18
|
selectedScore: (sample: BasicSampleData) => SelectedScore | undefined;
|
20
|
-
selectedScorerDescriptor: (
|
19
|
+
selectedScorerDescriptor: (
|
20
|
+
sample: BasicSampleData,
|
21
|
+
) => ScorerDescriptor | undefined;
|
21
22
|
}
|
22
23
|
|
23
24
|
export const createEvalDescriptor = (
|
24
25
|
scores: ScoreLabel[],
|
25
|
-
epochs: number,
|
26
26
|
samples?: SampleSummary[],
|
27
27
|
): EvalDescriptor | undefined => {
|
28
28
|
if (!samples) {
|
@@ -57,10 +57,10 @@ export const createEvalDescriptor = (
|
|
57
57
|
|
58
58
|
const scoreAnswer = (
|
59
59
|
sample: BasicSampleData,
|
60
|
-
scorer:
|
60
|
+
scorer: ScoreLabel,
|
61
61
|
): string | undefined => {
|
62
62
|
if (sample && sample.scores) {
|
63
|
-
const sampleScore = sample.scores[scorer];
|
63
|
+
const sampleScore = sample.scores[scorer.name];
|
64
64
|
if (sampleScore && sampleScore.answer) {
|
65
65
|
return sampleScore.answer;
|
66
66
|
}
|
@@ -181,7 +181,7 @@ export const createEvalDescriptor = (
|
|
181
181
|
return scoreExplanation(sample, scoreLabel.scorer) || "";
|
182
182
|
},
|
183
183
|
answer: () => {
|
184
|
-
return scoreAnswer(sample, scoreLabel
|
184
|
+
return scoreAnswer(sample, scoreLabel) || "";
|
185
185
|
},
|
186
186
|
scores: () => {
|
187
187
|
if (!sample || !sample.scores) {
|
@@ -252,8 +252,11 @@ export const createEvalDescriptor = (
|
|
252
252
|
|
253
253
|
const score = (
|
254
254
|
sample: BasicSampleData,
|
255
|
-
scoreLabel
|
256
|
-
): SelectedScore => {
|
255
|
+
scoreLabel?: ScoreLabel,
|
256
|
+
): SelectedScore | undefined => {
|
257
|
+
if (!scoreLabel) {
|
258
|
+
return undefined;
|
259
|
+
}
|
257
260
|
return {
|
258
261
|
value: scoreValue(sample, scoreLabel),
|
259
262
|
render: () => {
|
@@ -263,8 +266,6 @@ export const createEvalDescriptor = (
|
|
263
266
|
};
|
264
267
|
|
265
268
|
return {
|
266
|
-
epochs,
|
267
|
-
samples,
|
268
269
|
scores,
|
269
270
|
scorerDescriptor,
|
270
271
|
scoreDescriptor,
|
@@ -274,14 +275,17 @@ export const createEvalDescriptor = (
|
|
274
275
|
};
|
275
276
|
|
276
277
|
export const createSamplesDescriptor = (
|
278
|
+
samples: SampleSummary[],
|
277
279
|
evalDescriptor: EvalDescriptor,
|
278
|
-
selectedScore
|
280
|
+
selectedScore?: ScoreLabel,
|
279
281
|
): SamplesDescriptor | undefined => {
|
280
282
|
// Find the total length of the value so we can compute an average
|
281
|
-
const sizes =
|
283
|
+
const sizes = samples.reduce(
|
282
284
|
(previous, current) => {
|
283
285
|
const text = inputString(current.input).join(" ");
|
284
|
-
const score =
|
286
|
+
const score = selectedScore
|
287
|
+
? evalDescriptor.score(current, selectedScore)
|
288
|
+
: undefined;
|
285
289
|
const scoreValue = score?.value;
|
286
290
|
const scoreText = scoreValue
|
287
291
|
? String(scoreValue)
|
@@ -296,7 +300,9 @@ export const createSamplesDescriptor = (
|
|
296
300
|
previous[2] = Math.min(
|
297
301
|
Math.max(
|
298
302
|
previous[2],
|
299
|
-
|
303
|
+
selectedScore
|
304
|
+
? evalDescriptor.scoreAnswer(current, selectedScore)?.length || 0
|
305
|
+
: 0,
|
300
306
|
),
|
301
307
|
300,
|
302
308
|
);
|
@@ -353,10 +359,12 @@ export const createSamplesDescriptor = (
|
|
353
359
|
return {
|
354
360
|
evalDescriptor,
|
355
361
|
messageShape,
|
356
|
-
|
357
|
-
|
362
|
+
selectedScore: (sample) =>
|
363
|
+
selectedScore ? evalDescriptor.score(sample, selectedScore) : undefined,
|
358
364
|
selectedScorerDescriptor: (sample) =>
|
359
|
-
|
365
|
+
selectedScore
|
366
|
+
? evalDescriptor.scorerDescriptor(sample, selectedScore)
|
367
|
+
: undefined,
|
360
368
|
};
|
361
369
|
};
|
362
370
|
|
@@ -52,13 +52,14 @@ export const objectScoreDescriptor = (values: Value2[]): ScoreDescriptor => {
|
|
52
52
|
: String(value);
|
53
53
|
scores.push(
|
54
54
|
<div
|
55
|
+
key={`score-value-${index}`}
|
55
56
|
className={clsx(
|
56
57
|
styles.container,
|
57
58
|
index + 1 < keys.length ? styles.padded : undefined,
|
58
59
|
)}
|
59
60
|
>
|
60
61
|
<div className={clsx(styles.key, "text-size-smaller")}>{key}</div>
|
61
|
-
<div className={clsx(styles.value, "text-size-
|
62
|
+
<div className={clsx(styles.value, "text-size-large")}>
|
62
63
|
{formattedValue}
|
63
64
|
</div>
|
64
65
|
</div>,
|
@@ -1,11 +1,9 @@
|
|
1
1
|
import { ReactNode } from "react";
|
2
|
-
import { BasicSampleData
|
2
|
+
import { BasicSampleData } from "../../api/types";
|
3
3
|
import { ScoreLabel } from "../../types";
|
4
4
|
import { Value2 } from "../../types/log";
|
5
5
|
|
6
6
|
export interface EvalDescriptor {
|
7
|
-
epochs: number;
|
8
|
-
samples: SampleSummary[];
|
9
7
|
scores: ScoreLabel[];
|
10
8
|
scoreDescriptor: (scoreLabel: ScoreLabel) => ScoreDescriptor;
|
11
9
|
scorerDescriptor: (
|
@@ -14,9 +12,12 @@ export interface EvalDescriptor {
|
|
14
12
|
) => ScorerDescriptor;
|
15
13
|
score: (
|
16
14
|
sample: BasicSampleData,
|
17
|
-
scoreLabel
|
15
|
+
scoreLabel?: ScoreLabel,
|
18
16
|
) => SelectedScore | undefined;
|
19
|
-
scoreAnswer: (
|
17
|
+
scoreAnswer: (
|
18
|
+
sample: BasicSampleData,
|
19
|
+
scorer: ScoreLabel,
|
20
|
+
) => string | undefined;
|
20
21
|
}
|
21
22
|
|
22
23
|
export interface ScorerDescriptor {
|
@@ -2,8 +2,26 @@
|
|
2
2
|
border-top: solid var(--bs-light-border-subtle) 1px;
|
3
3
|
background: var(--bs-light-bg-subtle);
|
4
4
|
display: grid;
|
5
|
-
grid-template-columns: max-content;
|
6
|
-
justify-content:
|
7
|
-
|
5
|
+
grid-template-columns: max-content max-content;
|
6
|
+
justify-content: space-between;
|
7
|
+
|
8
8
|
padding: 0.2em 1em;
|
9
9
|
}
|
10
|
+
|
11
|
+
.spinnerContainer {
|
12
|
+
display: grid;
|
13
|
+
grid-template-columns: max-content max-content;
|
14
|
+
column-gap: 0.3em;
|
15
|
+
padding-top: 0.2em;
|
16
|
+
}
|
17
|
+
|
18
|
+
.spinner {
|
19
|
+
height: 11px;
|
20
|
+
width: 11px;
|
21
|
+
color: var(--bs-secondary);
|
22
|
+
border-width: 1px;
|
23
|
+
}
|
24
|
+
|
25
|
+
.label {
|
26
|
+
margin-top: -4px;
|
27
|
+
}
|
@@ -1,14 +1,33 @@
|
|
1
1
|
interface SampleFooterProps {
|
2
2
|
sampleCount: number;
|
3
|
+
running: boolean;
|
3
4
|
}
|
4
5
|
|
5
6
|
import clsx from "clsx";
|
6
7
|
import { FC } from "react";
|
7
8
|
import styles from "./SampleFooter.module.css";
|
8
9
|
|
9
|
-
export const SampleFooter: FC<SampleFooterProps> = ({
|
10
|
+
export const SampleFooter: FC<SampleFooterProps> = ({
|
11
|
+
sampleCount,
|
12
|
+
running,
|
13
|
+
}) => {
|
10
14
|
return (
|
11
15
|
<div className={clsx("text-size-smaller", styles.footer)}>
|
16
|
+
<div>
|
17
|
+
{running ? (
|
18
|
+
<div className={clsx(styles.spinnerContainer)}>
|
19
|
+
<div
|
20
|
+
className={clsx("spinner-border", styles.spinner)}
|
21
|
+
role="status"
|
22
|
+
>
|
23
|
+
<span className={clsx("visually-hidden")}>Running...</span>
|
24
|
+
</div>
|
25
|
+
<div className={clsx("text-style-secondary", styles.label)}>
|
26
|
+
running...
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
) : undefined}
|
30
|
+
</div>
|
12
31
|
<div>{sampleCount} Samples</div>
|
13
32
|
</div>
|
14
33
|
);
|
@@ -1,15 +1,14 @@
|
|
1
1
|
import {
|
2
2
|
FC,
|
3
3
|
KeyboardEvent,
|
4
|
+
memo,
|
4
5
|
RefObject,
|
5
6
|
useCallback,
|
6
7
|
useEffect,
|
7
8
|
useMemo,
|
8
9
|
useRef,
|
9
|
-
useState,
|
10
10
|
} from "react";
|
11
11
|
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
12
|
-
import { EmptyPanel } from "../../components/EmptyPanel";
|
13
12
|
import { MessageBand } from "../../components/MessageBand";
|
14
13
|
import { formatNoDecimal } from "../../utils/format";
|
15
14
|
import { ListItem } from "../../workspace/tabs/types";
|
@@ -18,6 +17,9 @@ import { SampleRow } from "./SampleRow";
|
|
18
17
|
import { SampleSeparator } from "./SampleSeparator";
|
19
18
|
|
20
19
|
import clsx from "clsx";
|
20
|
+
import { useProperty, useSampleDescriptor } from "../../state/hooks";
|
21
|
+
import { useVirtuosoState } from "../../state/scrolling";
|
22
|
+
import { useStore } from "../../state/store";
|
21
23
|
import { SampleFooter } from "./SampleFooter";
|
22
24
|
import { SampleHeader } from "./SampleHeader";
|
23
25
|
import styles from "./SampleList.module.css";
|
@@ -27,8 +29,7 @@ const kSeparatorHeight = 24;
|
|
27
29
|
|
28
30
|
interface SampleListProps {
|
29
31
|
items: ListItem[];
|
30
|
-
|
31
|
-
selectedIndex: number;
|
32
|
+
running: boolean;
|
32
33
|
nextSample: () => void;
|
33
34
|
prevSample: () => void;
|
34
35
|
showSample: (index: number) => void;
|
@@ -36,11 +37,10 @@ interface SampleListProps {
|
|
36
37
|
listHandle: RefObject<VirtuosoHandle | null>;
|
37
38
|
}
|
38
39
|
|
39
|
-
export const SampleList: FC<SampleListProps> = (props) => {
|
40
|
+
export const SampleList: FC<SampleListProps> = memo((props) => {
|
40
41
|
const {
|
41
42
|
items,
|
42
|
-
|
43
|
-
selectedIndex,
|
43
|
+
running,
|
44
44
|
nextSample,
|
45
45
|
prevSample,
|
46
46
|
showSample,
|
@@ -48,37 +48,50 @@ export const SampleList: FC<SampleListProps> = (props) => {
|
|
48
48
|
listHandle,
|
49
49
|
} = props;
|
50
50
|
|
51
|
-
const
|
51
|
+
const { getRestoreState, isScrolling } = useVirtuosoState(
|
52
|
+
listHandle,
|
53
|
+
"sample-list",
|
54
|
+
);
|
52
55
|
|
53
|
-
const
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
const selectedSampleIndex = useStore(
|
57
|
+
(state) => state.log.selectedSampleIndex,
|
58
|
+
);
|
59
|
+
const samplesDescriptor = useSampleDescriptor();
|
60
|
+
const [followOutput, setFollowOutput] = useProperty("sample-list", "follow", {
|
61
|
+
defaultValue: false,
|
62
|
+
});
|
57
63
|
|
58
|
-
//
|
59
|
-
|
60
|
-
|
61
|
-
items.forEach((item, index) => {
|
62
|
-
if (item.type === "sample") {
|
63
|
-
rowIndexes.push(index);
|
64
|
-
}
|
65
|
-
});
|
66
|
-
return rowIndexes;
|
67
|
-
}, [items]);
|
64
|
+
// Track whether we were previously running so we can
|
65
|
+
// decide whether to pop up to the top
|
66
|
+
const prevRunningRef = useRef(running);
|
68
67
|
|
69
|
-
const prevSelectedIndexRef = useRef<number>(null);
|
70
68
|
useEffect(() => {
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
69
|
+
// When we finish running, if we are following output
|
70
|
+
// then scroll up to the top
|
71
|
+
if (
|
72
|
+
!running &&
|
73
|
+
prevRunningRef.current &&
|
74
|
+
followOutput &&
|
75
|
+
listHandle.current
|
76
|
+
) {
|
77
|
+
setFollowOutput(false);
|
78
|
+
setTimeout(() => {
|
79
|
+
if (listHandle.current) {
|
80
|
+
listHandle.current.scrollTo({ top: 0, behavior: "instant" });
|
81
|
+
}
|
82
|
+
}, 100);
|
80
83
|
}
|
81
|
-
|
84
|
+
prevRunningRef.current = running;
|
85
|
+
}, [running, followOutput, listHandle]);
|
86
|
+
|
87
|
+
const handleAtBottomStateChange = useCallback(
|
88
|
+
(atBottom: boolean) => {
|
89
|
+
if (running) {
|
90
|
+
setFollowOutput(atBottom);
|
91
|
+
}
|
92
|
+
},
|
93
|
+
[running, setFollowOutput],
|
94
|
+
);
|
82
95
|
|
83
96
|
const onkeydown = useCallback(
|
84
97
|
(e: KeyboardEvent<HTMLDivElement>) => {
|
@@ -94,48 +107,51 @@ export const SampleList: FC<SampleListProps> = (props) => {
|
|
94
107
|
e.stopPropagation();
|
95
108
|
break;
|
96
109
|
case "Enter":
|
97
|
-
showSample(
|
110
|
+
showSample(selectedSampleIndex);
|
98
111
|
e.preventDefault();
|
99
112
|
e.stopPropagation();
|
100
113
|
break;
|
101
114
|
}
|
102
115
|
},
|
103
|
-
[
|
116
|
+
[selectedSampleIndex, nextSample, prevSample, showSample],
|
104
117
|
);
|
105
118
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
}
|
119
|
+
const gridColumnsTemplate = useMemo(() => {
|
120
|
+
return gridColumnsValue(samplesDescriptor);
|
121
|
+
}, [samplesDescriptor]);
|
110
122
|
|
111
|
-
const renderRow = (
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
123
|
+
const renderRow = useCallback(
|
124
|
+
(_index: number, item: ListItem) => {
|
125
|
+
if (item.type === "sample") {
|
126
|
+
return (
|
127
|
+
<SampleRow
|
128
|
+
id={`${item.number}`}
|
129
|
+
index={item.index}
|
130
|
+
sample={item.data}
|
131
|
+
height={kSampleHeight}
|
132
|
+
answer={item.answer}
|
133
|
+
completed={item.completed}
|
134
|
+
scoreRendered={item.scoreRendered}
|
135
|
+
gridColumnsTemplate={gridColumnsTemplate}
|
136
|
+
showSample={showSample}
|
137
|
+
/>
|
138
|
+
);
|
139
|
+
} else if (item.type === "separator") {
|
140
|
+
return (
|
141
|
+
<SampleSeparator
|
142
|
+
id={`sample-group${item.number}`}
|
143
|
+
title={item.data}
|
144
|
+
height={kSeparatorHeight}
|
145
|
+
/>
|
146
|
+
);
|
147
|
+
} else {
|
148
|
+
return null;
|
149
|
+
}
|
150
|
+
},
|
151
|
+
[showSample],
|
152
|
+
);
|
137
153
|
|
138
|
-
const { input, limit, answer, target } = gridColumns(
|
154
|
+
const { input, limit, answer, target } = gridColumns(samplesDescriptor);
|
139
155
|
|
140
156
|
const sampleCount = items?.reduce((prev, current) => {
|
141
157
|
if (current.type === "sample") {
|
@@ -176,68 +192,72 @@ export const SampleList: FC<SampleListProps> = (props) => {
|
|
176
192
|
<div className={styles.mainLayout}>
|
177
193
|
{warningMessage ? (
|
178
194
|
<MessageBand
|
195
|
+
id={"sample-warning-message"}
|
179
196
|
message={warningMessage}
|
180
|
-
hidden={hidden}
|
181
|
-
setHidden={setHidden}
|
182
197
|
type="info"
|
183
198
|
/>
|
184
199
|
) : undefined}
|
185
|
-
|
186
200
|
<SampleHeader
|
187
201
|
input={input !== "0"}
|
188
202
|
target={target !== "0"}
|
189
203
|
answer={answer !== "0"}
|
190
204
|
limit={limit !== "0"}
|
191
|
-
gridColumnsTemplate={
|
205
|
+
gridColumnsTemplate={gridColumnsTemplate}
|
192
206
|
/>
|
193
207
|
<Virtuoso
|
194
208
|
ref={listHandle}
|
195
209
|
style={{ height: "100%" }}
|
196
210
|
data={items}
|
197
211
|
defaultItemHeight={50}
|
198
|
-
itemContent={
|
199
|
-
return renderRow(data);
|
200
|
-
}}
|
212
|
+
itemContent={renderRow}
|
201
213
|
followOutput={followOutput}
|
202
|
-
atBottomStateChange={
|
203
|
-
|
214
|
+
atBottomStateChange={handleAtBottomStateChange}
|
215
|
+
increaseViewportBy={{ top: 300, bottom: 300 }}
|
216
|
+
overscan={{
|
217
|
+
main: 10,
|
218
|
+
reverse: 10,
|
204
219
|
}}
|
205
220
|
className={clsx(className)}
|
206
221
|
onKeyDown={onkeydown}
|
207
222
|
skipAnimationFrameInResizeObserver={true}
|
223
|
+
isScrolling={isScrolling}
|
224
|
+
restoreStateFrom={getRestoreState()}
|
208
225
|
/>
|
209
|
-
<SampleFooter sampleCount={sampleCount} />
|
226
|
+
<SampleFooter sampleCount={sampleCount} running={running} />
|
210
227
|
</div>
|
211
228
|
);
|
212
|
-
};
|
229
|
+
});
|
213
230
|
|
214
|
-
const gridColumnsValue = (sampleDescriptor
|
231
|
+
const gridColumnsValue = (sampleDescriptor?: SamplesDescriptor) => {
|
215
232
|
const { input, target, answer, limit, id, score } =
|
216
233
|
gridColumns(sampleDescriptor);
|
217
234
|
return `${id} ${input} ${target} ${answer} ${limit} ${score}`;
|
218
235
|
};
|
219
236
|
|
220
|
-
const gridColumns = (sampleDescriptor
|
237
|
+
const gridColumns = (sampleDescriptor?: SamplesDescriptor) => {
|
221
238
|
const input =
|
222
|
-
sampleDescriptor
|
239
|
+
sampleDescriptor && sampleDescriptor.messageShape.normalized.input > 0
|
223
240
|
? Math.max(0.15, sampleDescriptor.messageShape.normalized.input)
|
224
241
|
: 0;
|
225
242
|
const target =
|
226
|
-
sampleDescriptor
|
243
|
+
sampleDescriptor && sampleDescriptor.messageShape.normalized.target > 0
|
227
244
|
? Math.max(0.15, sampleDescriptor.messageShape.normalized.target)
|
228
245
|
: 0;
|
229
246
|
const answer =
|
230
|
-
sampleDescriptor
|
247
|
+
sampleDescriptor && sampleDescriptor.messageShape.normalized.answer > 0
|
231
248
|
? Math.max(0.15, sampleDescriptor.messageShape.normalized.answer)
|
232
249
|
: 0;
|
233
250
|
const limit =
|
234
|
-
sampleDescriptor
|
251
|
+
sampleDescriptor && sampleDescriptor.messageShape.normalized.limit > 0
|
235
252
|
? Math.max(0.15, sampleDescriptor.messageShape.normalized.limit)
|
236
253
|
: 0;
|
237
|
-
const id = Math.max(
|
254
|
+
const id = Math.max(
|
255
|
+
2,
|
256
|
+
Math.min(10, sampleDescriptor?.messageShape.raw.id || 0),
|
257
|
+
);
|
238
258
|
const score = Math.max(
|
239
259
|
3,
|
240
|
-
Math.min(10, sampleDescriptor?.messageShape.raw.score),
|
260
|
+
Math.min(10, sampleDescriptor?.messageShape.raw.score || 0),
|
241
261
|
);
|
242
262
|
|
243
263
|
const frSize = (val: number) => {
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import clsx from "clsx";
|
2
|
-
import { FC } from "react";
|
2
|
+
import { FC, ReactNode, useCallback } from "react";
|
3
3
|
import { SampleSummary } from "../../api/types";
|
4
4
|
import { MarkdownDiv } from "../../components/MarkdownDiv";
|
5
|
+
import { PulsingDots } from "../../components/PulsingDots";
|
6
|
+
import { useStore } from "../../state/store";
|
5
7
|
import { arrayToString, inputString } from "../../utils/format";
|
6
|
-
import { SamplesDescriptor } from "../descriptor/samplesDescriptor";
|
7
8
|
import { SampleErrorView } from "../error/SampleErrorView";
|
8
9
|
import styles from "./SampleRow.module.css";
|
9
10
|
|
@@ -11,10 +12,11 @@ interface SampleRowProps {
|
|
11
12
|
id: string;
|
12
13
|
index: number;
|
13
14
|
sample: SampleSummary;
|
14
|
-
|
15
|
+
answer: string;
|
16
|
+
completed: boolean;
|
17
|
+
scoreRendered: ReactNode;
|
15
18
|
gridColumnsTemplate: string;
|
16
19
|
height: number;
|
17
|
-
selected: boolean;
|
18
20
|
showSample: (index: number) => void;
|
19
21
|
}
|
20
22
|
|
@@ -22,22 +24,33 @@ export const SampleRow: FC<SampleRowProps> = ({
|
|
22
24
|
id,
|
23
25
|
index,
|
24
26
|
sample,
|
25
|
-
|
27
|
+
answer,
|
28
|
+
completed,
|
29
|
+
scoreRendered,
|
26
30
|
gridColumnsTemplate,
|
27
31
|
height,
|
28
|
-
selected,
|
29
32
|
showSample,
|
30
33
|
}) => {
|
34
|
+
const streamSampleData = useStore(
|
35
|
+
(state) => state.capabilities.streamSampleData,
|
36
|
+
);
|
37
|
+
const selectedSampleIndex = useStore(
|
38
|
+
(state) => state.log.selectedSampleIndex,
|
39
|
+
);
|
40
|
+
const handleClick = useCallback(() => {
|
41
|
+
if (completed || streamSampleData) {
|
42
|
+
showSample(index);
|
43
|
+
}
|
44
|
+
}, [index, showSample, completed]);
|
45
|
+
|
31
46
|
return (
|
32
47
|
<div
|
33
48
|
id={`sample-${id}`}
|
34
|
-
onClick={
|
35
|
-
showSample(index);
|
36
|
-
}}
|
49
|
+
onClick={handleClick}
|
37
50
|
className={clsx(
|
38
51
|
styles.grid,
|
39
52
|
"text-size-base",
|
40
|
-
|
53
|
+
selectedSampleIndex === index ? styles.selected : undefined,
|
41
54
|
)}
|
42
55
|
style={{
|
43
56
|
height: `${height}px`,
|
@@ -67,9 +80,7 @@ export const SampleRow: FC<SampleRowProps> = ({
|
|
67
80
|
<div className={clsx("sample-answer", "three-line-clamp", styles.cell)}>
|
68
81
|
{sample ? (
|
69
82
|
<MarkdownDiv
|
70
|
-
markdown={
|
71
|
-
?.selectedScorerDescriptor(sample)
|
72
|
-
.answer()}
|
83
|
+
markdown={answer || ""}
|
73
84
|
className={clsx("no-last-para-padding", styles.noLeft)}
|
74
85
|
/>
|
75
86
|
) : (
|
@@ -90,8 +101,10 @@ export const SampleRow: FC<SampleRowProps> = ({
|
|
90
101
|
<div className={clsx("text-size-small", styles.cell, styles.score)}>
|
91
102
|
{sample.error ? (
|
92
103
|
<SampleErrorView message={sample.error} />
|
104
|
+
) : completed ? (
|
105
|
+
scoreRendered
|
93
106
|
) : (
|
94
|
-
|
107
|
+
<PulsingDots />
|
95
108
|
)}
|
96
109
|
</div>
|
97
110
|
</div>
|