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
@@ -1,16 +1,15 @@
|
|
1
1
|
import clsx from "clsx";
|
2
2
|
import {
|
3
|
+
createElement,
|
3
4
|
FC,
|
4
5
|
Fragment,
|
5
6
|
MouseEvent,
|
6
7
|
RefObject,
|
7
8
|
useCallback,
|
8
|
-
useMemo,
|
9
9
|
} from "react";
|
10
|
-
import {
|
10
|
+
import { RunningMetric } from "../api/types";
|
11
11
|
import { EmptyPanel } from "../components/EmptyPanel";
|
12
12
|
import { TabPanel, TabSet } from "../components/TabSet";
|
13
|
-
import { EvalDescriptor } from "../samples/descriptor/types";
|
14
13
|
import {
|
15
14
|
EvalPlan,
|
16
15
|
EvalResults,
|
@@ -18,63 +17,37 @@ import {
|
|
18
17
|
EvalStats,
|
19
18
|
Status,
|
20
19
|
} from "../types/log";
|
21
|
-
import { debounce } from "../utils/sync";
|
22
20
|
import { Navbar } from "./navbar/Navbar";
|
23
21
|
import { TabDescriptor } from "./types";
|
24
22
|
|
23
|
+
import { useStore } from "../state/store";
|
25
24
|
import styles from "./WorkSpaceView.module.css";
|
26
25
|
|
27
26
|
interface WorkSpaceViewProps {
|
28
|
-
logFileName?: string;
|
29
27
|
evalSpec: EvalSpec;
|
30
28
|
evalPlan?: EvalPlan;
|
31
29
|
evalResults?: EvalResults;
|
30
|
+
runningMetrics?: RunningMetric[];
|
32
31
|
evalStats?: EvalStats;
|
33
|
-
samples?: SampleSummary[];
|
34
|
-
evalDescriptor?: EvalDescriptor;
|
35
32
|
status?: Status;
|
36
33
|
showToggle: boolean;
|
37
|
-
tabs: Record<string, TabDescriptor
|
38
|
-
selectedTab: string;
|
39
|
-
setSelectedTab: (tab: string) => void;
|
34
|
+
tabs: Record<string, TabDescriptor<any>>;
|
40
35
|
divRef: RefObject<HTMLDivElement | null>;
|
41
|
-
offcanvas: boolean;
|
42
|
-
setOffcanvas: (offcanvas: boolean) => void;
|
43
|
-
workspaceTabScrollPositionRef: RefObject<Record<string, number>>;
|
44
|
-
setWorkspaceTabScrollPosition: (tab: string, pos: number) => void;
|
45
36
|
}
|
46
37
|
|
47
38
|
export const WorkSpaceView: FC<WorkSpaceViewProps> = ({
|
48
|
-
logFileName,
|
49
39
|
evalSpec,
|
50
40
|
evalPlan,
|
51
41
|
evalResults,
|
42
|
+
runningMetrics,
|
52
43
|
evalStats,
|
53
|
-
samples,
|
54
|
-
evalDescriptor,
|
55
44
|
status,
|
56
45
|
showToggle,
|
57
|
-
selectedTab,
|
58
46
|
tabs,
|
59
|
-
setSelectedTab,
|
60
47
|
divRef,
|
61
|
-
offcanvas,
|
62
|
-
setOffcanvas,
|
63
|
-
workspaceTabScrollPositionRef,
|
64
|
-
setWorkspaceTabScrollPosition,
|
65
48
|
}) => {
|
66
|
-
const
|
67
|
-
|
68
|
-
setWorkspaceTabScrollPosition(id, position);
|
69
|
-
}, 100);
|
70
|
-
}, [setWorkspaceTabScrollPosition]);
|
71
|
-
|
72
|
-
const onScroll = useCallback(
|
73
|
-
(id: string, position: number) => {
|
74
|
-
debouncedScroll(id, position);
|
75
|
-
},
|
76
|
-
[debouncedScroll],
|
77
|
-
);
|
49
|
+
const selectedTab = useStore((state) => state.app.tabs.workspace);
|
50
|
+
const setSelectedTab = useStore((state) => state.appActions.setWorkspaceTab);
|
78
51
|
|
79
52
|
const onSelected = useCallback(
|
80
53
|
(e: MouseEvent<HTMLElement>) => {
|
@@ -85,12 +58,6 @@ export const WorkSpaceView: FC<WorkSpaceViewProps> = ({
|
|
85
58
|
},
|
86
59
|
[setSelectedTab],
|
87
60
|
);
|
88
|
-
const handleScroll = useCallback(
|
89
|
-
(tabid: string, position: number) => {
|
90
|
-
onScroll(tabid, position);
|
91
|
-
},
|
92
|
-
[onScroll],
|
93
|
-
);
|
94
61
|
|
95
62
|
if (evalSpec === undefined) {
|
96
63
|
return <EmptyPanel />;
|
@@ -118,14 +85,10 @@ export const WorkSpaceView: FC<WorkSpaceViewProps> = ({
|
|
118
85
|
evalSpec={evalSpec}
|
119
86
|
evalPlan={evalPlan}
|
120
87
|
evalResults={evalResults}
|
88
|
+
runningMetrics={runningMetrics}
|
121
89
|
evalStats={evalStats}
|
122
|
-
samples={samples}
|
123
|
-
evalDescriptor={evalDescriptor}
|
124
90
|
status={status}
|
125
|
-
file={logFileName}
|
126
91
|
showToggle={showToggle}
|
127
|
-
offcanvas={offcanvas}
|
128
|
-
setOffcanvas={setOffcanvas}
|
129
92
|
/>
|
130
93
|
<div ref={divRef} className={clsx("workspace", styles.workspace)}>
|
131
94
|
<div className={clsx("log-detail", styles.tabContainer)}>
|
@@ -148,14 +111,9 @@ export const WorkSpaceView: FC<WorkSpaceViewProps> = ({
|
|
148
111
|
selected={selectedTab === tab.id}
|
149
112
|
scrollable={!!tab.scrollable}
|
150
113
|
scrollRef={tab.scrollRef}
|
151
|
-
|
152
|
-
workspaceTabScrollPositionRef.current?.[tab.id]
|
153
|
-
}
|
154
|
-
setScrollPosition={(position: number) => {
|
155
|
-
handleScroll(tab.id, position);
|
156
|
-
}}
|
114
|
+
style={{ height: tab.scrollable ? "100%" : undefined }}
|
157
115
|
>
|
158
|
-
{tab.
|
116
|
+
{createElement(tab.component, tab.componentProps)}
|
159
117
|
</TabPanel>
|
160
118
|
);
|
161
119
|
})}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import clsx from "clsx";
|
2
2
|
import { FC } from "react";
|
3
|
-
import {
|
4
|
-
import {
|
3
|
+
import { RunningMetric } from "../../api/types";
|
4
|
+
import { useTotalSampleCount } from "../../state/hooks";
|
5
5
|
import {
|
6
6
|
EvalPlan,
|
7
7
|
EvalResults,
|
@@ -14,16 +14,12 @@ import { PrimaryBar } from "./PrimaryBar";
|
|
14
14
|
import { SecondaryBar } from "./SecondaryBar";
|
15
15
|
|
16
16
|
interface NavBarProps {
|
17
|
-
file?: string;
|
18
17
|
evalSpec?: EvalSpec;
|
19
18
|
evalResults?: EvalResults;
|
19
|
+
runningMetrics?: RunningMetric[];
|
20
20
|
evalPlan?: EvalPlan;
|
21
21
|
evalStats?: EvalStats;
|
22
|
-
evalDescriptor?: EvalDescriptor;
|
23
|
-
samples?: SampleSummary[];
|
24
22
|
status?: Status;
|
25
|
-
offcanvas: boolean;
|
26
|
-
setOffcanvas: (offcanvas: boolean) => void;
|
27
23
|
showToggle: boolean;
|
28
24
|
}
|
29
25
|
|
@@ -31,38 +27,32 @@ interface NavBarProps {
|
|
31
27
|
* Renders the Navbar
|
32
28
|
*/
|
33
29
|
export const Navbar: FC<NavBarProps> = ({
|
34
|
-
file,
|
35
30
|
evalSpec,
|
36
31
|
evalPlan,
|
37
32
|
evalResults,
|
38
33
|
evalStats,
|
39
|
-
samples,
|
40
|
-
evalDescriptor,
|
41
34
|
showToggle,
|
42
|
-
offcanvas,
|
43
|
-
setOffcanvas,
|
44
35
|
status,
|
36
|
+
runningMetrics,
|
45
37
|
}) => {
|
38
|
+
const totalSampleCount = useTotalSampleCount();
|
46
39
|
return (
|
47
40
|
<nav className={clsx("navbar", "sticky-top", styles.navbarWrapper)}>
|
48
41
|
<PrimaryBar
|
49
|
-
file={file}
|
50
42
|
evalSpec={evalSpec}
|
51
43
|
evalResults={evalResults}
|
52
|
-
samples={samples}
|
53
44
|
showToggle={showToggle}
|
54
|
-
offcanvas={offcanvas}
|
55
|
-
setOffcanvas={setOffcanvas}
|
56
45
|
status={status}
|
46
|
+
runningMetrics={runningMetrics}
|
47
|
+
sampleCount={totalSampleCount}
|
57
48
|
/>
|
58
49
|
<SecondaryBar
|
59
50
|
evalSpec={evalSpec}
|
60
51
|
evalPlan={evalPlan}
|
61
52
|
evalResults={evalResults}
|
62
53
|
evalStats={evalStats}
|
63
|
-
samples={samples}
|
64
|
-
evalDescriptor={evalDescriptor}
|
65
54
|
status={status}
|
55
|
+
sampleCount={totalSampleCount}
|
66
56
|
/>
|
67
57
|
</nav>
|
68
58
|
);
|
@@ -1,41 +1,52 @@
|
|
1
1
|
import clsx from "clsx";
|
2
2
|
import { FC, useCallback } from "react";
|
3
|
-
import {
|
3
|
+
import { RunningMetric } from "../../api/types";
|
4
4
|
import { ApplicationIcons } from "../../appearance/icons";
|
5
5
|
import { CopyButton } from "../../components/CopyButton";
|
6
6
|
import { kModelNone } from "../../constants";
|
7
|
+
import { useStore } from "../../state/store";
|
7
8
|
import { EvalResults, EvalSpec, Status } from "../../types/log";
|
8
9
|
import { filename } from "../../utils/path";
|
9
10
|
import styles from "./PrimaryBar.module.css";
|
10
|
-
import {
|
11
|
-
|
11
|
+
import {
|
12
|
+
displayScorersFromRunningMetrics,
|
13
|
+
ResultsPanel,
|
14
|
+
toDisplayScorers,
|
15
|
+
} from "./ResultsPanel";
|
16
|
+
import { RunningStatusPanel } from "./RunningStatusPanel";
|
17
|
+
import { CancelledPanel, ErroredPanel } from "./StatusPanel";
|
12
18
|
|
13
19
|
interface PrimaryBarProps {
|
14
20
|
showToggle: boolean;
|
15
|
-
offcanvas: boolean;
|
16
|
-
setOffcanvas: (offcanvas: boolean) => void;
|
17
21
|
status?: Status;
|
18
22
|
evalResults?: EvalResults;
|
19
|
-
|
20
|
-
file?: string;
|
23
|
+
runningMetrics?: RunningMetric[];
|
21
24
|
evalSpec?: EvalSpec;
|
25
|
+
sampleCount?: number;
|
22
26
|
}
|
23
27
|
|
24
28
|
export const PrimaryBar: FC<PrimaryBarProps> = ({
|
25
29
|
showToggle,
|
26
|
-
offcanvas,
|
27
30
|
status,
|
28
31
|
evalResults,
|
29
|
-
|
30
|
-
file,
|
32
|
+
runningMetrics,
|
31
33
|
evalSpec,
|
32
|
-
|
34
|
+
sampleCount,
|
33
35
|
}) => {
|
34
|
-
const
|
36
|
+
const offCanvas = useStore((state) => state.app.offcanvas);
|
37
|
+
const setOffCanvas = useStore((state) => state.appActions.setOffcanvas);
|
38
|
+
const streamSamples = useStore((state) => state.capabilities.streamSamples);
|
39
|
+
const selectedLogFile = useStore((state) =>
|
40
|
+
state.logsActions.getSelectedLogFile(),
|
41
|
+
);
|
42
|
+
|
43
|
+
const logFileName = selectedLogFile ? filename(selectedLogFile) : "";
|
35
44
|
|
36
45
|
const handleToggle = useCallback(() => {
|
37
|
-
|
38
|
-
}, [
|
46
|
+
setOffCanvas(!offCanvas);
|
47
|
+
}, [offCanvas, setOffCanvas]);
|
48
|
+
|
49
|
+
const hasRunningMetrics = runningMetrics && runningMetrics.length > 0;
|
39
50
|
|
40
51
|
return (
|
41
52
|
<div className={clsx(styles.wrapper)}>
|
@@ -53,7 +64,7 @@ export const PrimaryBar: FC<PrimaryBarProps> = ({
|
|
53
64
|
onClick={handleToggle}
|
54
65
|
className={clsx(
|
55
66
|
"btn",
|
56
|
-
|
67
|
+
offCanvas ? "d-md-none" : undefined,
|
57
68
|
styles.toggle,
|
58
69
|
)}
|
59
70
|
type="button"
|
@@ -93,22 +104,29 @@ export const PrimaryBar: FC<PrimaryBarProps> = ({
|
|
93
104
|
<div className={clsx("navbar-secondary-text", "text-truncate")}>
|
94
105
|
{logFileName}
|
95
106
|
</div>
|
96
|
-
{
|
107
|
+
{selectedLogFile ? <CopyButton value={selectedLogFile} /> : ""}
|
97
108
|
</div>
|
98
109
|
</div>
|
99
110
|
</div>
|
100
111
|
<div className={clsx(styles.taskStatus, "navbar-text")}>
|
101
|
-
{status === "success"
|
102
|
-
|
112
|
+
{status === "success" ||
|
113
|
+
(status === "started" && streamSamples && hasRunningMetrics) ? (
|
114
|
+
<ResultsPanel
|
115
|
+
scorers={
|
116
|
+
runningMetrics
|
117
|
+
? displayScorersFromRunningMetrics(runningMetrics)
|
118
|
+
: toDisplayScorers(evalResults?.scores)
|
119
|
+
}
|
120
|
+
/>
|
103
121
|
) : undefined}
|
104
122
|
{status === "cancelled" ? (
|
105
|
-
<CancelledPanel sampleCount={
|
123
|
+
<CancelledPanel sampleCount={sampleCount || 0} />
|
106
124
|
) : undefined}
|
107
|
-
{status === "started" ? (
|
108
|
-
<
|
125
|
+
{status === "started" && (!streamSamples || !hasRunningMetrics) ? (
|
126
|
+
<RunningStatusPanel sampleCount={sampleCount || 0} />
|
109
127
|
) : undefined}
|
110
128
|
{status === "error" ? (
|
111
|
-
<ErroredPanel sampleCount={
|
129
|
+
<ErroredPanel sampleCount={sampleCount || 0} />
|
112
130
|
) : undefined}
|
113
131
|
</div>
|
114
132
|
<div id="task-created" style={{ display: "none" }}>
|
@@ -1,46 +1,103 @@
|
|
1
1
|
import clsx from "clsx";
|
2
2
|
import { FC } from "react";
|
3
|
-
import {
|
3
|
+
import { RunningMetric } from "../../api/types";
|
4
|
+
import { Scores } from "../../types/log";
|
4
5
|
import { formatPrettyDecimal } from "../../utils/format";
|
5
6
|
import { metricDisplayName } from "../utils";
|
6
7
|
import styles from "./ResultsPanel.module.css";
|
7
8
|
|
8
|
-
interface
|
9
|
-
|
9
|
+
export interface ResultsMetric {
|
10
|
+
name: string;
|
11
|
+
params?: {};
|
12
|
+
value: number;
|
10
13
|
}
|
11
14
|
|
12
|
-
interface
|
13
|
-
|
14
|
-
|
15
|
+
export interface ResultsScorer {
|
16
|
+
scorer: string;
|
17
|
+
reducer?: string;
|
18
|
+
metrics: ResultsMetric[];
|
15
19
|
}
|
16
20
|
|
17
|
-
export const
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
export const displayScorersFromRunningMetrics = (metrics?: RunningMetric[]) => {
|
22
|
+
if (!metrics) {
|
23
|
+
return [];
|
24
|
+
}
|
25
|
+
|
26
|
+
const getKey = (metric: RunningMetric) => {
|
27
|
+
return metric.reducer
|
28
|
+
? `${metric.scorer}-${metric.reducer}`
|
29
|
+
: metric.scorer;
|
30
|
+
};
|
31
|
+
|
32
|
+
const scorers: Record<string, ResultsScorer> = {};
|
33
|
+
metrics.forEach((metric) => {
|
34
|
+
if (metric.value !== undefined) {
|
35
|
+
const key = getKey(metric);
|
36
|
+
if (scorers[key]) {
|
37
|
+
scorers[key].metrics.push({
|
38
|
+
name: metric.name,
|
39
|
+
value: metric.value,
|
40
|
+
});
|
41
|
+
} else {
|
42
|
+
scorers[key] = {
|
43
|
+
scorer: metric.scorer,
|
44
|
+
reducer: metric.reducer,
|
45
|
+
metrics: [
|
46
|
+
{
|
47
|
+
name: metric.name,
|
48
|
+
value: metric.value,
|
49
|
+
},
|
50
|
+
],
|
51
|
+
};
|
52
|
+
}
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
return Object.values(scorers);
|
57
|
+
};
|
58
|
+
|
59
|
+
export const toDisplayScorers = (scores?: Scores): ResultsScorer[] => {
|
60
|
+
if (!scores) {
|
61
|
+
return [];
|
62
|
+
}
|
63
|
+
|
64
|
+
return scores.map((score) => {
|
65
|
+
return {
|
66
|
+
scorer: score.name,
|
67
|
+
reducer: score.reducer === null ? undefined : score.reducer,
|
68
|
+
metrics: Object.keys(score.metrics).map((key) => {
|
69
|
+
const metric = score.metrics[key];
|
23
70
|
return {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
value: score.metrics[key].value,
|
28
|
-
params: score.metrics[key].params,
|
29
|
-
metadata: {},
|
30
|
-
},
|
71
|
+
name: metric.name,
|
72
|
+
value: metric.value,
|
73
|
+
params: metric.params,
|
31
74
|
};
|
32
|
-
})
|
33
|
-
}
|
75
|
+
}),
|
76
|
+
};
|
77
|
+
});
|
78
|
+
};
|
79
|
+
|
80
|
+
interface ResultsPanelProps {
|
81
|
+
scorers?: ResultsScorer[];
|
82
|
+
}
|
83
|
+
|
84
|
+
export const ResultsPanel: FC<ResultsPanelProps> = ({ scorers }) => {
|
85
|
+
if (!scorers || scorers.length === 0) {
|
86
|
+
return undefined;
|
87
|
+
}
|
34
88
|
|
35
|
-
|
36
|
-
|
89
|
+
// Get the display scorers
|
90
|
+
if (scorers.length === 1) {
|
91
|
+
const showReducer = !!scorers[0].reducer;
|
92
|
+
const metrics = scorers[0].metrics;
|
37
93
|
return (
|
38
94
|
<div className={styles.simpleMetricsRows}>
|
39
95
|
{metrics.map((metric, i) => {
|
40
96
|
return (
|
41
97
|
<VerticalMetric
|
42
98
|
key={`simple-metric-${i}`}
|
43
|
-
|
99
|
+
reducer={scorers[0].reducer}
|
100
|
+
metric={metric}
|
44
101
|
isFirst={i === 0}
|
45
102
|
showReducer={showReducer}
|
46
103
|
/>
|
@@ -49,15 +106,14 @@ export const ResultsPanel: FC<ResultsPanelProps> = ({ results }) => {
|
|
49
106
|
</div>
|
50
107
|
);
|
51
108
|
} else {
|
52
|
-
const showReducer =
|
53
|
-
results?.scores.findIndex((score) => !!score.reducer) !== -1;
|
109
|
+
const showReducer = scorers.findIndex((score) => !!score.reducer) !== -1;
|
54
110
|
return (
|
55
111
|
<div className={styles.multiMetricsRows}>
|
56
|
-
{
|
112
|
+
{scorers.map((scorer, index) => {
|
57
113
|
return (
|
58
114
|
<MultiScorerMetric
|
59
115
|
key={`multi-metric-${index}`}
|
60
|
-
scorer={
|
116
|
+
scorer={scorer}
|
61
117
|
isFirst={index === 0}
|
62
118
|
showReducer={showReducer}
|
63
119
|
/>
|
@@ -69,7 +125,8 @@ export const ResultsPanel: FC<ResultsPanelProps> = ({ results }) => {
|
|
69
125
|
};
|
70
126
|
|
71
127
|
interface VerticalMetricProps {
|
72
|
-
|
128
|
+
metric: ResultsMetric;
|
129
|
+
reducer?: string;
|
73
130
|
isFirst: boolean;
|
74
131
|
showReducer: boolean;
|
75
132
|
}
|
@@ -77,7 +134,8 @@ interface VerticalMetricProps {
|
|
77
134
|
/** Renders a Vertical Metric
|
78
135
|
*/
|
79
136
|
const VerticalMetric: FC<VerticalMetricProps> = ({
|
80
|
-
|
137
|
+
metric,
|
138
|
+
reducer,
|
81
139
|
isFirst,
|
82
140
|
showReducer,
|
83
141
|
}) => {
|
@@ -91,7 +149,7 @@ const VerticalMetric: FC<VerticalMetricProps> = ({
|
|
91
149
|
styles.verticalMetricName,
|
92
150
|
)}
|
93
151
|
>
|
94
|
-
{metricDisplayName(
|
152
|
+
{metricDisplayName(metric)}
|
95
153
|
</div>
|
96
154
|
{showReducer ? (
|
97
155
|
<div
|
@@ -101,7 +159,7 @@ const VerticalMetric: FC<VerticalMetricProps> = ({
|
|
101
159
|
styles.verticalMetricReducer,
|
102
160
|
)}
|
103
161
|
>
|
104
|
-
{
|
162
|
+
{reducer || "default"}
|
105
163
|
</div>
|
106
164
|
) : undefined}
|
107
165
|
|
@@ -112,14 +170,16 @@ const VerticalMetric: FC<VerticalMetricProps> = ({
|
|
112
170
|
styles.verticalMetricValue,
|
113
171
|
)}
|
114
172
|
>
|
115
|
-
{
|
173
|
+
{metric.value !== undefined && metric.value !== null
|
174
|
+
? formatPrettyDecimal(metric.value)
|
175
|
+
: "n/a"}
|
116
176
|
</div>
|
117
177
|
</div>
|
118
178
|
);
|
119
179
|
};
|
120
180
|
|
121
181
|
interface MultiScorerMetricProps {
|
122
|
-
scorer:
|
182
|
+
scorer: ResultsScorer;
|
123
183
|
isFirst: boolean;
|
124
184
|
showReducer: boolean;
|
125
185
|
}
|
@@ -149,7 +209,7 @@ const MultiScorerMetric: FC<MultiScorerMetricProps> = ({
|
|
149
209
|
styles.multiScorerLabel,
|
150
210
|
)}
|
151
211
|
>
|
152
|
-
{scorer.
|
212
|
+
{scorer.scorer}
|
153
213
|
</div>
|
154
214
|
{showReducer ? (
|
155
215
|
<div
|
@@ -164,13 +224,12 @@ const MultiScorerMetric: FC<MultiScorerMetricProps> = ({
|
|
164
224
|
</div>
|
165
225
|
) : undefined}
|
166
226
|
<div className={clsx(valueFontClz, styles.multiScorerValue)}>
|
167
|
-
{
|
168
|
-
const metric = scorer.metrics[key];
|
227
|
+
{scorer.metrics.map((metric) => {
|
169
228
|
return (
|
170
|
-
<div className={styles.multiScoreMetricGrid} key={
|
229
|
+
<div className={styles.multiScoreMetricGrid} key={metric.name}>
|
171
230
|
<div>{metricDisplayName(metric)}</div>
|
172
231
|
<div className={styles.multiScorerValueContent}>
|
173
|
-
{formatPrettyDecimal(metric.value)}
|
232
|
+
{metric.value ? formatPrettyDecimal(metric.value) : undefined}
|
174
233
|
</div>
|
175
234
|
</div>
|
176
235
|
);
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.statusContainer {
|
2
|
+
display: inline-block;
|
3
|
+
margin-top: 0.3em;
|
4
|
+
}
|
5
|
+
|
6
|
+
.status {
|
7
|
+
display: grid;
|
8
|
+
grid-template-columns: auto auto;
|
9
|
+
}
|
10
|
+
|
11
|
+
.statusText {
|
12
|
+
margin-top: 0.2em;
|
13
|
+
}
|
14
|
+
|
15
|
+
.metricsRows {
|
16
|
+
margin-top: 0.3em;
|
17
|
+
margin-left: 1.25em;
|
18
|
+
display: grid;
|
19
|
+
grid-template-columns: auto auto;
|
20
|
+
grid-template-rows: auto;
|
21
|
+
column-gap: 0.5em;
|
22
|
+
}
|
23
|
+
|
24
|
+
.icon {
|
25
|
+
font-size: var(--inspect-font-size-large);
|
26
|
+
margin-right: 0.3em;
|
27
|
+
margin-top: -0.1em;
|
28
|
+
}
|
29
|
+
|
30
|
+
.value {
|
31
|
+
font-weight: 600;
|
32
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import clsx from "clsx";
|
2
|
+
import { RunningMetric } from "../../api/types";
|
3
|
+
import { ApplicationIcons } from "../../appearance/icons";
|
4
|
+
|
5
|
+
import { FC } from "react";
|
6
|
+
import styles from "./RunningStatusPanel.module.css";
|
7
|
+
|
8
|
+
export interface RunningPanelProps {
|
9
|
+
sampleCount: number;
|
10
|
+
displayMetrics?: RunningMetric[];
|
11
|
+
}
|
12
|
+
|
13
|
+
export const RunningStatusPanel: FC<RunningPanelProps> = ({ sampleCount }) => {
|
14
|
+
return (
|
15
|
+
<div>
|
16
|
+
<div className={clsx(styles.statusContainer)}>
|
17
|
+
<div className={clsx(styles.status)}>
|
18
|
+
<i className={clsx(ApplicationIcons.running, styles.icon)} />
|
19
|
+
<div
|
20
|
+
className={clsx(
|
21
|
+
styles.statusText,
|
22
|
+
"text-style-label",
|
23
|
+
"text-size-smaller",
|
24
|
+
)}
|
25
|
+
>
|
26
|
+
Running ({sampleCount} samples)
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
);
|
32
|
+
};
|