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
@@ -0,0 +1,100 @@
|
|
1
|
+
import { Timeout } from "../types/log";
|
2
|
+
import { createLogger } from "./logger";
|
3
|
+
|
4
|
+
export interface PollingOptions {
|
5
|
+
maxRetries: number;
|
6
|
+
interval: number;
|
7
|
+
}
|
8
|
+
|
9
|
+
export interface Polling {
|
10
|
+
name: string;
|
11
|
+
start: () => void;
|
12
|
+
stop: () => void;
|
13
|
+
}
|
14
|
+
|
15
|
+
export const createPolling = (
|
16
|
+
name: string,
|
17
|
+
callback: () => Promise<boolean>,
|
18
|
+
options: PollingOptions,
|
19
|
+
): Polling => {
|
20
|
+
const log = createLogger(`Polling ${name}`);
|
21
|
+
|
22
|
+
const { maxRetries, interval } = options;
|
23
|
+
let timeoutId: Timeout = null;
|
24
|
+
let retryCount = 0;
|
25
|
+
// Are we currently polling
|
26
|
+
let isPolling = false;
|
27
|
+
|
28
|
+
// Are we stopped (e.g. cleaning up)
|
29
|
+
let isStopped = false;
|
30
|
+
|
31
|
+
const calculateBackoff = (retryCount: number) => {
|
32
|
+
return Math.min(interval * Math.pow(2, retryCount) * 1000, 60000);
|
33
|
+
};
|
34
|
+
|
35
|
+
const stop = () => {
|
36
|
+
if (timeoutId) {
|
37
|
+
clearTimeout(timeoutId);
|
38
|
+
timeoutId = null;
|
39
|
+
}
|
40
|
+
log.debug("Stop Polling");
|
41
|
+
isPolling = false;
|
42
|
+
isStopped = true;
|
43
|
+
};
|
44
|
+
|
45
|
+
const poll = async () => {
|
46
|
+
try {
|
47
|
+
log.debug("Poll");
|
48
|
+
// Don't proceed if polling has been stopped
|
49
|
+
if (!isPolling || isStopped) {
|
50
|
+
return;
|
51
|
+
}
|
52
|
+
|
53
|
+
const shouldContinue = await callback();
|
54
|
+
if (shouldContinue === false) {
|
55
|
+
stop();
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
// Reset retry count on success
|
60
|
+
retryCount = 0;
|
61
|
+
if (!isPolling || isStopped) {
|
62
|
+
return;
|
63
|
+
}
|
64
|
+
timeoutId = setTimeout(poll, interval * 1000);
|
65
|
+
} catch (e) {
|
66
|
+
// Don't retry if polling has been stopped
|
67
|
+
if (!isPolling || isStopped) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
log.debug("Polling error occurred", e);
|
71
|
+
|
72
|
+
retryCount += 1;
|
73
|
+
|
74
|
+
if (retryCount >= maxRetries) {
|
75
|
+
stop();
|
76
|
+
throw new Error(
|
77
|
+
`Gave up polling ${name} after ${maxRetries} attempts.`,
|
78
|
+
);
|
79
|
+
}
|
80
|
+
|
81
|
+
const backoffTime = calculateBackoff(retryCount);
|
82
|
+
log.debug(
|
83
|
+
`Retry ${retryCount}/${maxRetries}, backoff: ${backoffTime / 1000}s`,
|
84
|
+
);
|
85
|
+
timeoutId = setTimeout(poll, backoffTime);
|
86
|
+
}
|
87
|
+
};
|
88
|
+
|
89
|
+
const start = () => {
|
90
|
+
if (isPolling) {
|
91
|
+
return;
|
92
|
+
}
|
93
|
+
log.debug("Start Polling");
|
94
|
+
isPolling = true;
|
95
|
+
isStopped = false;
|
96
|
+
poll();
|
97
|
+
};
|
98
|
+
|
99
|
+
return { name, start, stop };
|
100
|
+
};
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { useEffect, useRef } from "react";
|
2
|
+
|
3
|
+
export const useWhyDidYouUpdate = (componentName: string, props: any) => {
|
4
|
+
const previousProps = useRef(props);
|
5
|
+
|
6
|
+
useEffect(() => {
|
7
|
+
if (previousProps.current !== props) {
|
8
|
+
const changedProps = Object.entries(props).reduce(
|
9
|
+
(diff, [key, value]) => {
|
10
|
+
if (previousProps.current[key] !== value) {
|
11
|
+
diff[key] = {
|
12
|
+
before: previousProps.current[key],
|
13
|
+
after: value,
|
14
|
+
};
|
15
|
+
}
|
16
|
+
return diff;
|
17
|
+
},
|
18
|
+
{} as Record<string, unknown>,
|
19
|
+
);
|
20
|
+
|
21
|
+
if (Object.keys(changedProps).length > 0) {
|
22
|
+
console.log(`[${componentName}] props changed:`, changedProps);
|
23
|
+
} else {
|
24
|
+
console.log(`[${componentName}] no props changed`);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
previousProps.current = props;
|
29
|
+
}, [props, componentName]);
|
30
|
+
};
|
@@ -2,7 +2,7 @@
|
|
2
2
|
* Type definition for the VS Code API object
|
3
3
|
* Note: This is a minimal definition - expand based on your needs
|
4
4
|
*/
|
5
|
-
interface VSCodeApi {
|
5
|
+
export interface VSCodeApi {
|
6
6
|
postMessage(message: unknown): void;
|
7
7
|
getState(): unknown;
|
8
8
|
setState(state: unknown): void;
|
@@ -5,27 +5,24 @@ import { JsonTab } from "./tabs/JsonTab";
|
|
5
5
|
import { SamplesTab } from "./tabs/SamplesTab";
|
6
6
|
|
7
7
|
import clsx from "clsx";
|
8
|
-
import { FC, MouseEvent,
|
9
|
-
import {
|
8
|
+
import { FC, MouseEvent, useEffect, useMemo, useRef } from "react";
|
9
|
+
import { RunningMetric } from "../api/types.ts";
|
10
10
|
import {
|
11
11
|
kEvalWorkspaceTabId,
|
12
12
|
kInfoWorkspaceTabId,
|
13
13
|
kJsonWorkspaceTabId,
|
14
14
|
} from "../constants";
|
15
|
-
import { SamplesDescriptor } from "../samples/descriptor/samplesDescriptor";
|
16
15
|
import {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
} from "../types.ts";
|
16
|
+
useFilteredSamples,
|
17
|
+
useSampleDescriptor,
|
18
|
+
useTotalSampleCount,
|
19
|
+
} from "../state/hooks.ts";
|
20
|
+
import { useStore } from "../state/store.ts";
|
21
|
+
import { CurrentLog } from "../types.ts";
|
23
22
|
import {
|
24
|
-
Epochs,
|
25
23
|
EvalError,
|
26
24
|
EvalPlan,
|
27
25
|
EvalResults,
|
28
|
-
EvalSample,
|
29
26
|
EvalSpec,
|
30
27
|
EvalStats,
|
31
28
|
Status,
|
@@ -35,7 +32,6 @@ import { WorkSpaceView } from "./WorkSpaceView.tsx";
|
|
35
32
|
|
36
33
|
interface WorkSpaceProps {
|
37
34
|
task_id?: string;
|
38
|
-
logFileName?: string;
|
39
35
|
evalError?: EvalError;
|
40
36
|
evalStatus?: Status;
|
41
37
|
evalVersion?: number;
|
@@ -43,42 +39,10 @@ interface WorkSpaceProps {
|
|
43
39
|
evalPlan?: EvalPlan;
|
44
40
|
evalStats?: EvalStats;
|
45
41
|
evalResults?: EvalResults;
|
42
|
+
runningMetrics?: RunningMetric[];
|
46
43
|
log?: CurrentLog;
|
47
|
-
samples?: SampleSummary[];
|
48
|
-
sampleMode: SampleMode;
|
49
|
-
groupBy: "none" | "epoch" | "sample";
|
50
|
-
groupByOrder: "asc" | "desc";
|
51
|
-
selectedSample?: EvalSample;
|
52
|
-
sampleStatus: string;
|
53
|
-
sampleError?: Error;
|
54
44
|
showToggle: boolean;
|
55
|
-
refreshLog: () =>
|
56
|
-
capabilities: Capabilities;
|
57
|
-
selectedSampleIndex: number;
|
58
|
-
samplesDescriptor?: SamplesDescriptor;
|
59
|
-
setSelectedSampleIndex: (index: number) => void;
|
60
|
-
selectedSampleTab?: string;
|
61
|
-
setSelectedSampleTab: (tab: string) => void;
|
62
|
-
sort: string;
|
63
|
-
setSort: (sort: string) => void;
|
64
|
-
epochs?: Epochs;
|
65
|
-
epoch: string;
|
66
|
-
showingSampleDialog: boolean;
|
67
|
-
setShowingSampleDialog: (showing: boolean) => void;
|
68
|
-
setEpoch: (epoch: string) => void;
|
69
|
-
filter: ScoreFilter;
|
70
|
-
setFilter: (filter: ScoreFilter) => void;
|
71
|
-
score?: ScoreLabel;
|
72
|
-
setScore: (score: ScoreLabel) => void;
|
73
|
-
scores: ScoreLabel[];
|
74
|
-
offcanvas: boolean;
|
75
|
-
setOffcanvas: (offcanvas: boolean) => void;
|
76
|
-
selectedTab: string;
|
77
|
-
setSelectedTab: (id: string) => void;
|
78
|
-
sampleScrollPositionRef: RefObject<number>;
|
79
|
-
setSampleScrollPosition: (position: number) => void;
|
80
|
-
workspaceTabScrollPositionRef: RefObject<Record<string, number>>;
|
81
|
-
setWorkspaceTabScrollPosition: (tab: string, position: number) => void;
|
45
|
+
refreshLog: () => void;
|
82
46
|
}
|
83
47
|
|
84
48
|
/**
|
@@ -88,20 +52,12 @@ export const WorkSpace: FC<WorkSpaceProps> = (props) => {
|
|
88
52
|
const {
|
89
53
|
task_id,
|
90
54
|
evalStatus,
|
91
|
-
logFileName,
|
92
55
|
evalSpec,
|
93
56
|
evalPlan,
|
94
57
|
evalStats,
|
95
58
|
evalResults,
|
96
|
-
|
59
|
+
runningMetrics,
|
97
60
|
showToggle,
|
98
|
-
offcanvas,
|
99
|
-
setOffcanvas,
|
100
|
-
samplesDescriptor,
|
101
|
-
selectedTab,
|
102
|
-
setSelectedTab,
|
103
|
-
workspaceTabScrollPositionRef,
|
104
|
-
setWorkspaceTabScrollPosition,
|
105
61
|
} = props;
|
106
62
|
|
107
63
|
const divRef = useRef<HTMLDivElement>(null);
|
@@ -121,27 +77,20 @@ export const WorkSpace: FC<WorkSpaceProps> = (props) => {
|
|
121
77
|
|
122
78
|
return (
|
123
79
|
<WorkSpaceView
|
124
|
-
logFileName={logFileName}
|
125
80
|
divRef={divRef}
|
126
81
|
evalSpec={evalSpec}
|
127
82
|
evalPlan={evalPlan}
|
128
83
|
evalResults={evalResults}
|
84
|
+
runningMetrics={runningMetrics}
|
129
85
|
evalStats={evalStats}
|
130
|
-
samples={samples}
|
131
|
-
evalDescriptor={samplesDescriptor?.evalDescriptor}
|
132
86
|
status={evalStatus}
|
133
87
|
tabs={resolvedTabs}
|
134
|
-
selectedTab={selectedTab}
|
135
88
|
showToggle={showToggle}
|
136
|
-
offcanvas={offcanvas}
|
137
|
-
setSelectedTab={setSelectedTab}
|
138
|
-
workspaceTabScrollPositionRef={workspaceTabScrollPositionRef}
|
139
|
-
setWorkspaceTabScrollPosition={setWorkspaceTabScrollPosition}
|
140
|
-
setOffcanvas={setOffcanvas}
|
141
89
|
/>
|
142
90
|
);
|
143
91
|
};
|
144
92
|
|
93
|
+
// Helper function for copy feedback
|
145
94
|
const copyFeedback = (e: MouseEvent<HTMLElement>) => {
|
146
95
|
const textEl = e.currentTarget.querySelector(".task-btn-copy-content");
|
147
96
|
const iconEl = e.currentTarget.querySelector("i.bi");
|
@@ -162,164 +111,180 @@ const copyFeedback = (e: MouseEvent<HTMLElement>) => {
|
|
162
111
|
}
|
163
112
|
};
|
164
113
|
|
165
|
-
|
166
|
-
|
167
|
-
evalStatus,
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
114
|
+
// Individual hook for Samples tab
|
115
|
+
export const useSamplesTabConfig = (
|
116
|
+
evalStatus: Status | undefined,
|
117
|
+
refreshLog: () => void,
|
118
|
+
) => {
|
119
|
+
const totalSampleCount = useTotalSampleCount();
|
120
|
+
const samplesDescriptor = useSampleDescriptor();
|
121
|
+
const sampleSummaries = useFilteredSamples();
|
122
|
+
const streamSamples = useStore((state) => state.capabilities.streamSamples);
|
123
|
+
|
124
|
+
return useMemo(() => {
|
125
|
+
return {
|
126
|
+
id: kEvalWorkspaceTabId,
|
127
|
+
scrollable: false,
|
128
|
+
label: totalSampleCount > 1 ? "Samples" : "Sample",
|
129
|
+
component: SamplesTab,
|
130
|
+
componentProps: {
|
131
|
+
running: evalStatus === "started",
|
132
|
+
},
|
133
|
+
tools: () =>
|
134
|
+
totalSampleCount === 1 || !samplesDescriptor
|
135
|
+
? undefined
|
136
|
+
: [
|
137
|
+
<SampleTools
|
138
|
+
samples={sampleSummaries || []}
|
139
|
+
key="sample-tools"
|
140
|
+
/>,
|
141
|
+
evalStatus === "started" && !streamSamples && (
|
142
|
+
<ToolButton
|
143
|
+
key="refresh"
|
144
|
+
label="Refresh"
|
145
|
+
icon={ApplicationIcons.refresh}
|
146
|
+
onClick={refreshLog}
|
147
|
+
/>
|
148
|
+
),
|
149
|
+
].filter(Boolean),
|
150
|
+
};
|
151
|
+
}, [
|
152
|
+
evalStatus,
|
153
|
+
refreshLog,
|
154
|
+
sampleSummaries,
|
155
|
+
samplesDescriptor,
|
156
|
+
totalSampleCount,
|
157
|
+
]);
|
158
|
+
};
|
159
|
+
|
160
|
+
// Individual hook for Info tab
|
161
|
+
export const useInfoTabConfig = (
|
162
|
+
evalSpec: EvalSpec | undefined,
|
163
|
+
evalPlan: EvalPlan | undefined,
|
164
|
+
evalError: EvalError | undefined,
|
165
|
+
evalResults: EvalResults | undefined,
|
166
|
+
evalStats: EvalStats | undefined,
|
167
|
+
) => {
|
168
|
+
const totalSampleCount = useTotalSampleCount();
|
169
|
+
return useMemo(() => {
|
170
|
+
return {
|
171
|
+
id: kInfoWorkspaceTabId,
|
172
|
+
label: "Info",
|
173
|
+
scrollable: true,
|
174
|
+
component: InfoTab,
|
175
|
+
componentProps: {
|
176
|
+
evalSpec,
|
177
|
+
evalPlan,
|
178
|
+
evalError,
|
179
|
+
evalResults,
|
180
|
+
evalStats,
|
181
|
+
sampleCount: totalSampleCount,
|
182
|
+
},
|
183
|
+
};
|
184
|
+
}, [evalSpec, evalPlan, evalError, evalResults, evalStats, totalSampleCount]);
|
185
|
+
};
|
186
|
+
|
187
|
+
// Individual hook for JSON tab
|
188
|
+
export const useJsonTabConfig = (
|
189
|
+
evalVersion: number | undefined,
|
190
|
+
evalStatus: Status | undefined,
|
191
|
+
evalSpec: EvalSpec | undefined,
|
192
|
+
evalPlan: EvalPlan | undefined,
|
193
|
+
evalError: EvalError | undefined,
|
194
|
+
evalResults: EvalResults | undefined,
|
195
|
+
evalStats: EvalStats | undefined,
|
196
|
+
) => {
|
197
|
+
const selectedLogFile = useStore((state) =>
|
198
|
+
state.logsActions.getSelectedLogFile(),
|
199
|
+
);
|
200
|
+
const selectedTab = useStore((state) => state.app.tabs.workspace);
|
201
|
+
|
202
|
+
return useMemo(() => {
|
203
|
+
const evalHeader = {
|
204
|
+
version: evalVersion,
|
205
|
+
status: evalStatus,
|
206
|
+
eval: evalSpec,
|
207
|
+
plan: evalPlan,
|
208
|
+
error: evalError,
|
209
|
+
results: evalResults,
|
210
|
+
stats: evalStats,
|
211
|
+
};
|
212
|
+
|
213
|
+
return {
|
214
|
+
id: kJsonWorkspaceTabId,
|
215
|
+
label: "JSON",
|
216
|
+
scrollable: true,
|
217
|
+
component: JsonTab,
|
218
|
+
componentProps: {
|
219
|
+
logFile: selectedLogFile,
|
220
|
+
json: JSON.stringify(evalHeader, null, 2),
|
221
|
+
selected: selectedTab === kJsonWorkspaceTabId,
|
222
|
+
},
|
223
|
+
tools: () => [
|
224
|
+
<ToolButton
|
225
|
+
key="copy-json"
|
226
|
+
label="Copy JSON"
|
227
|
+
icon={ApplicationIcons.copy}
|
228
|
+
className={clsx("task-btn-json-copy", "clipboard-button")}
|
229
|
+
data-clipboard-target="#task-json-contents"
|
230
|
+
onClick={copyFeedback}
|
231
|
+
/>,
|
232
|
+
],
|
233
|
+
};
|
234
|
+
}, [
|
235
|
+
selectedLogFile,
|
236
|
+
evalVersion,
|
237
|
+
evalStatus,
|
238
|
+
evalSpec,
|
239
|
+
evalPlan,
|
240
|
+
evalError,
|
241
|
+
evalResults,
|
242
|
+
evalStats,
|
243
|
+
selectedTab,
|
244
|
+
]);
|
245
|
+
};
|
246
|
+
|
247
|
+
// Main hook combining all tab configs
|
248
|
+
export const useResolvedTabs = (props: WorkSpaceProps) => {
|
249
|
+
const {
|
250
|
+
evalVersion,
|
251
|
+
evalStatus,
|
252
|
+
evalSpec,
|
253
|
+
evalPlan,
|
254
|
+
evalResults,
|
255
|
+
evalStats,
|
256
|
+
evalError,
|
257
|
+
refreshLog,
|
258
|
+
} = props;
|
205
259
|
|
206
|
-
|
207
|
-
|
208
|
-
? {
|
209
|
-
id: kEvalWorkspaceTabId,
|
210
|
-
scrollable: samples?.length === 1,
|
211
|
-
scrollRef: sampleTabScrollRef,
|
212
|
-
label: (samples || []).length > 1 ? "Samples" : "Sample",
|
213
|
-
content: () => (
|
214
|
-
<SamplesTab
|
215
|
-
sample={selectedSample}
|
216
|
-
sampleStatus={sampleStatus}
|
217
|
-
sampleError={sampleError}
|
218
|
-
showingSampleDialog={showingSampleDialog}
|
219
|
-
setShowingSampleDialog={setShowingSampleDialog}
|
220
|
-
samples={samples}
|
221
|
-
sampleMode={sampleMode}
|
222
|
-
groupBy={groupBy}
|
223
|
-
groupByOrder={groupByOrder}
|
224
|
-
selectedSampleIndex={selectedSampleIndex}
|
225
|
-
setSelectedSampleIndex={setSelectedSampleIndex}
|
226
|
-
sampleDescriptor={samplesDescriptor}
|
227
|
-
selectedSampleTab={selectedSampleTab}
|
228
|
-
setSelectedSampleTab={setSelectedSampleTab}
|
229
|
-
filter={filter}
|
230
|
-
epoch={epoch}
|
231
|
-
sampleScrollPositionRef={sampleScrollPositionRef}
|
232
|
-
setSampleScrollPosition={setSampleScrollPosition}
|
233
|
-
sampleTabScrollRef={sampleTabScrollRef}
|
234
|
-
/>
|
235
|
-
),
|
236
|
-
tools: () =>
|
237
|
-
sampleMode === "single" || !samplesDescriptor
|
238
|
-
? undefined
|
239
|
-
: [
|
240
|
-
<SampleTools
|
241
|
-
key="sample-tools"
|
242
|
-
epoch={epoch}
|
243
|
-
epochs={epochs || 1}
|
244
|
-
setEpoch={setEpoch}
|
245
|
-
scoreFilter={filter}
|
246
|
-
setScoreFilter={setFilter}
|
247
|
-
sort={sort}
|
248
|
-
setSort={setSort}
|
249
|
-
score={score}
|
250
|
-
setScore={setScore}
|
251
|
-
scores={scores}
|
252
|
-
sampleDescriptor={samplesDescriptor}
|
253
|
-
/>,
|
254
|
-
evalStatus === "started" && (
|
255
|
-
<ToolButton
|
256
|
-
key="refresh"
|
257
|
-
label="Refresh"
|
258
|
-
icon={ApplicationIcons.refresh}
|
259
|
-
onClick={refreshLog}
|
260
|
-
/>
|
261
|
-
),
|
262
|
-
].filter(Boolean),
|
263
|
-
}
|
264
|
-
: null;
|
260
|
+
// Use individual tab config hooks
|
261
|
+
const samplesTabConfig = useSamplesTabConfig(evalStatus, refreshLog);
|
265
262
|
|
266
|
-
const
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
evalPlan={evalPlan}
|
274
|
-
evalError={evalError}
|
275
|
-
evalResults={evalResults}
|
276
|
-
evalStats={evalStats}
|
277
|
-
samples={samples}
|
278
|
-
/>
|
279
|
-
),
|
280
|
-
};
|
263
|
+
const configTabConfig = useInfoTabConfig(
|
264
|
+
evalSpec,
|
265
|
+
evalPlan,
|
266
|
+
evalError,
|
267
|
+
evalResults,
|
268
|
+
evalStats,
|
269
|
+
);
|
281
270
|
|
282
|
-
const
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
plan: evalPlan,
|
292
|
-
error: evalError,
|
293
|
-
results: evalResults,
|
294
|
-
stats: evalStats,
|
295
|
-
};
|
296
|
-
return (
|
297
|
-
<JsonTab
|
298
|
-
logFile={logFileName}
|
299
|
-
json={JSON.stringify(evalHeader, null, 2)}
|
300
|
-
capabilities={capabilities}
|
301
|
-
selected={selectedTab === kJsonWorkspaceTabId}
|
302
|
-
/>
|
303
|
-
);
|
304
|
-
},
|
305
|
-
tools: () => [
|
306
|
-
<ToolButton
|
307
|
-
key="copy-json"
|
308
|
-
label="Copy JSON"
|
309
|
-
icon={ApplicationIcons.copy}
|
310
|
-
className={clsx("task-btn-json-copy", "clipboard-button")}
|
311
|
-
data-clipboard-target="#task-json-contents"
|
312
|
-
onClick={copyFeedback}
|
313
|
-
/>,
|
314
|
-
],
|
315
|
-
};
|
271
|
+
const jsonTabConfig = useJsonTabConfig(
|
272
|
+
evalVersion,
|
273
|
+
evalStatus,
|
274
|
+
evalSpec,
|
275
|
+
evalPlan,
|
276
|
+
evalError,
|
277
|
+
evalResults,
|
278
|
+
evalStats,
|
279
|
+
);
|
316
280
|
|
281
|
+
// Combine all tab configs
|
317
282
|
return useMemo(
|
318
283
|
() => ({
|
319
|
-
...(
|
320
|
-
config:
|
321
|
-
json:
|
284
|
+
...(samplesTabConfig ? { samples: samplesTabConfig } : {}),
|
285
|
+
config: configTabConfig,
|
286
|
+
json: jsonTabConfig,
|
322
287
|
}),
|
323
|
-
[
|
288
|
+
[samplesTabConfig, configTabConfig, jsonTabConfig],
|
324
289
|
);
|
325
290
|
};
|