inspect-ai 0.3.108__py3-none-any.whl → 0.3.110__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/_eval/task/log.py +1 -1
- inspect_ai/_eval/task/run.py +7 -3
- inspect_ai/_util/dateutil.py +40 -0
- inspect_ai/_view/schema.py +11 -0
- inspect_ai/_view/www/CLAUDE.md +1 -1
- inspect_ai/_view/www/dist/assets/index.css +2068 -1796
- inspect_ai/_view/www/dist/assets/index.js +7951 -3643
- inspect_ai/_view/www/package.json +3 -2
- inspect_ai/_view/www/src/@types/log.d.ts +5 -5
- inspect_ai/_view/www/src/app/App.css +71 -4
- inspect_ai/_view/www/src/app/App.tsx +7 -0
- inspect_ai/_view/www/src/app/appearance/icons.ts +18 -2
- inspect_ai/_view/www/src/app/content/RenderedContent.tsx +7 -9
- inspect_ai/_view/www/src/app/log-list/LogItem.ts +18 -0
- inspect_ai/_view/www/src/app/log-list/LogListFooter.module.css +55 -0
- inspect_ai/_view/www/src/app/log-list/LogListFooter.tsx +67 -0
- inspect_ai/_view/www/src/app/log-list/LogPager.module.css +29 -0
- inspect_ai/_view/www/src/app/log-list/LogPager.tsx +134 -0
- inspect_ai/_view/www/src/app/log-list/LogsFilterInput.module.css +5 -0
- inspect_ai/_view/www/src/app/log-list/LogsFilterInput.tsx +31 -0
- inspect_ai/_view/www/src/app/log-list/LogsPanel.module.css +12 -0
- inspect_ai/_view/www/src/app/log-list/LogsPanel.tsx +178 -0
- inspect_ai/_view/www/src/app/log-list/grid/LogListGrid.module.css +115 -0
- inspect_ai/_view/www/src/app/log-list/grid/LogListGrid.tsx +304 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/CompletedDate.module.css +6 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/CompletedDate.tsx +64 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/EmptyCell.module.css +3 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/EmptyCell.tsx +7 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/FileName.module.css +20 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/FileName.tsx +52 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Icon.module.css +11 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Icon.tsx +35 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Model.module.css +6 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Model.tsx +34 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Score.module.css +6 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Score.tsx +61 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Status.module.css +15 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Status.tsx +95 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Task.module.css +20 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/Task.tsx +50 -0
- inspect_ai/_view/www/src/app/log-list/grid/columns/columns.ts +27 -0
- inspect_ai/_view/www/src/app/log-view/LogView.tsx +2 -5
- inspect_ai/_view/www/src/app/log-view/LogViewContainer.tsx +4 -30
- inspect_ai/_view/www/src/app/log-view/LogViewLayout.tsx +5 -30
- inspect_ai/_view/www/src/app/log-view/tabs/TaskTab.tsx +4 -7
- inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/PrimaryBar.module.css +2 -0
- inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/PrimaryBar.tsx +3 -31
- inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/ResultsPanel.tsx +7 -57
- inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/ScoreGrid.tsx +2 -2
- inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/SecondaryBar.tsx +7 -1
- inspect_ai/_view/www/src/app/log-view/{navbar/Navbar.tsx → title-view/TitleView.tsx} +3 -6
- inspect_ai/_view/www/src/app/navbar/Navbar.module.css +57 -0
- inspect_ai/_view/www/src/app/navbar/Navbar.tsx +117 -0
- inspect_ai/_view/www/src/app/navbar/useBreadcrumbTruncation.ts +128 -0
- inspect_ai/_view/www/src/app/plan/DatasetDetailView.tsx +3 -3
- inspect_ai/_view/www/src/app/plan/DetailStep.tsx +6 -6
- inspect_ai/_view/www/src/app/plan/PlanDetailView.module.css +1 -0
- inspect_ai/_view/www/src/app/plan/ScorerDetailView.tsx +1 -1
- inspect_ai/_view/www/src/app/routing/AppRouter.tsx +28 -4
- inspect_ai/_view/www/src/app/routing/RouteDispatcher.tsx +28 -0
- inspect_ai/_view/www/src/app/routing/sampleNavigation.ts +76 -7
- inspect_ai/_view/www/src/app/routing/url.ts +193 -20
- inspect_ai/_view/www/src/app/samples/SampleDisplay.tsx +3 -17
- inspect_ai/_view/www/src/app/samples/descriptor/score/ScoreDescriptor.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/SubtaskEventView.tsx +2 -2
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptPanel.tsx +2 -2
- inspect_ai/_view/www/src/app/samples/transcript/outline/tree-visitors.ts +5 -0
- inspect_ai/_view/www/src/app/samples/transcript/transform/treeify.ts +26 -10
- inspect_ai/_view/www/src/app/types.ts +21 -1
- inspect_ai/_view/www/src/client/api/api-http.ts +2 -1
- inspect_ai/_view/www/src/client/api/api-shared.ts +0 -32
- inspect_ai/_view/www/src/client/api/client-api.ts +1 -1
- inspect_ai/_view/www/src/client/remote/remoteLogFile.ts +38 -6
- inspect_ai/_view/www/src/components/TextInput.module.css +45 -0
- inspect_ai/_view/www/src/components/TextInput.tsx +52 -0
- inspect_ai/_view/www/src/constants.ts +18 -0
- inspect_ai/_view/www/src/img/inspect-16.svg +10 -0
- inspect_ai/_view/www/src/img/inspect-back.svg +5 -0
- inspect_ai/_view/www/src/img/inspect-file.svg +26 -0
- inspect_ai/_view/www/src/img/inspect-forward.svg +7 -0
- inspect_ai/_view/www/src/img/inspect-home.svg +18 -0
- inspect_ai/_view/www/src/scoring/metrics.ts +75 -0
- inspect_ai/_view/www/src/scoring/scores.ts +19 -0
- inspect_ai/_view/www/src/scoring/types.ts +11 -0
- inspect_ai/_view/www/src/state/appSlice.ts +27 -7
- inspect_ai/_view/www/src/state/clientEvents.ts +73 -0
- inspect_ai/_view/www/src/state/clientEventsService.ts +105 -0
- inspect_ai/_view/www/src/state/hooks.ts +118 -1
- inspect_ai/_view/www/src/state/log.ts +19 -0
- inspect_ai/_view/www/src/state/logPolling.ts +3 -1
- inspect_ai/_view/www/src/state/logSlice.ts +9 -0
- inspect_ai/_view/www/src/state/logsSlice.ts +157 -15
- inspect_ai/_view/www/src/state/samplePolling.ts +4 -2
- inspect_ai/_view/www/src/tests/utils/path.test.ts +3 -3
- inspect_ai/_view/www/src/utils/evallog.ts +31 -0
- inspect_ai/_view/www/src/utils/path.ts +28 -0
- inspect_ai/_view/www/src/utils/uri.ts +49 -0
- inspect_ai/_view/www/yarn.lock +54 -17
- inspect_ai/analysis/beta/_dataframe/util.py +106 -10
- inspect_ai/log/_recorders/buffer/database.py +55 -16
- inspect_ai/model/_model.py +1 -1
- inspect_ai/model/_providers/providers.py +2 -2
- inspect_ai/model/_providers/vertex.py +3 -0
- inspect_ai/tool/_mcp/_mcp.py +6 -1
- inspect_ai/tool/_mcp/sampling.py +8 -1
- inspect_ai/tool/_tools/_bash_session.py +3 -6
- inspect_ai/tool/_tools/_web_browser/_web_browser.py +3 -8
- inspect_ai/util/_anyio.py +12 -3
- {inspect_ai-0.3.108.dist-info → inspect_ai-0.3.110.dist-info}/METADATA +2 -2
- {inspect_ai-0.3.108.dist-info → inspect_ai-0.3.110.dist-info}/RECORD +124 -94
- inspect_ai/_util/datetime.py +0 -10
- inspect_ai/_view/www/src/app/content/MetaDataView.module.css +0 -35
- inspect_ai/_view/www/src/app/content/MetaDataView.tsx +0 -101
- inspect_ai/_view/www/src/app/log-view/utils.ts +0 -34
- inspect_ai/_view/www/src/app/sidebar/EvalStatus.module.css +0 -15
- inspect_ai/_view/www/src/app/sidebar/EvalStatus.tsx +0 -72
- inspect_ai/_view/www/src/app/sidebar/LogDirectoryTitleView.module.css +0 -16
- inspect_ai/_view/www/src/app/sidebar/LogDirectoryTitleView.tsx +0 -70
- inspect_ai/_view/www/src/app/sidebar/Sidebar.module.css +0 -77
- inspect_ai/_view/www/src/app/sidebar/Sidebar.tsx +0 -119
- inspect_ai/_view/www/src/app/sidebar/SidebarLogEntry.module.css +0 -29
- inspect_ai/_view/www/src/app/sidebar/SidebarLogEntry.tsx +0 -96
- inspect_ai/_view/www/src/app/sidebar/SidebarScoreView.module.css +0 -23
- inspect_ai/_view/www/src/app/sidebar/SidebarScoreView.tsx +0 -44
- inspect_ai/_view/www/src/app/sidebar/SidebarScoresView.module.css +0 -35
- inspect_ai/_view/www/src/app/sidebar/SidebarScoresView.tsx +0 -63
- inspect_ai/_view/www/src/state/logsPolling.ts +0 -118
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/ModelRolesView.module.css +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/ModelRolesView.tsx +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/ResultsPanel.module.css +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/RunningStatusPanel.module.css +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/RunningStatusPanel.tsx +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/ScoreGrid.module.css +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/SecondaryBar.module.css +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/StatusPanel.module.css +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar → title-view}/StatusPanel.tsx +0 -0
- /inspect_ai/_view/www/src/app/log-view/{navbar/Navbar.module.css → title-view/TitleView.module.css} +0 -0
- {inspect_ai-0.3.108.dist-info → inspect_ai-0.3.110.dist-info}/WHEEL +0 -0
- {inspect_ai-0.3.108.dist-info → inspect_ai-0.3.110.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.108.dist-info → inspect_ai-0.3.110.dist-info}/licenses/LICENSE +0 -0
- {inspect_ai-0.3.108.dist-info → inspect_ai-0.3.110.dist-info}/top_level.txt +0 -0
@@ -1,101 +0,0 @@
|
|
1
|
-
import clsx from "clsx";
|
2
|
-
import { CSSProperties, FC } from "react";
|
3
|
-
import styles from "./MetaDataView.module.css";
|
4
|
-
import { RenderedContent } from "./RenderedContent";
|
5
|
-
|
6
|
-
interface MetadataViewProps {
|
7
|
-
id?: string;
|
8
|
-
style?: CSSProperties;
|
9
|
-
entries: Record<string, unknown> | Array<{ name: string; value: unknown }>;
|
10
|
-
tableOptions?: string;
|
11
|
-
compact?: boolean;
|
12
|
-
className?: string | string[];
|
13
|
-
}
|
14
|
-
|
15
|
-
/**
|
16
|
-
* Renders the MetaDataView component.
|
17
|
-
*/
|
18
|
-
export const MetaDataView: FC<MetadataViewProps> = ({
|
19
|
-
id,
|
20
|
-
style,
|
21
|
-
entries,
|
22
|
-
tableOptions,
|
23
|
-
compact,
|
24
|
-
className,
|
25
|
-
}) => {
|
26
|
-
const baseId = "metadataview";
|
27
|
-
|
28
|
-
// Configure options for
|
29
|
-
tableOptions = tableOptions || "sm";
|
30
|
-
const tblClz = (tableOptions || "").split(",").map((option) => {
|
31
|
-
return `table-${option}`;
|
32
|
-
});
|
33
|
-
|
34
|
-
const coercedEntries = toNameValues(entries);
|
35
|
-
|
36
|
-
const entryEls = (coercedEntries || []).map((entry, index) => {
|
37
|
-
const id = `${baseId}-value-${index}`;
|
38
|
-
return (
|
39
|
-
<tr key={id}>
|
40
|
-
<td
|
41
|
-
className={clsx(
|
42
|
-
styles.cell,
|
43
|
-
styles.cellKey,
|
44
|
-
"text-size-small",
|
45
|
-
"text-style-label",
|
46
|
-
)}
|
47
|
-
>
|
48
|
-
{entry.name}
|
49
|
-
</td>
|
50
|
-
<td className={clsx(styles.cell, styles.cellValue, "text-size-small")}>
|
51
|
-
<RenderedContent id={id} entry={entry} />
|
52
|
-
</td>
|
53
|
-
</tr>
|
54
|
-
);
|
55
|
-
});
|
56
|
-
|
57
|
-
return (
|
58
|
-
<table
|
59
|
-
id={id}
|
60
|
-
className={clsx(
|
61
|
-
"table",
|
62
|
-
tblClz,
|
63
|
-
styles.table,
|
64
|
-
compact ? styles.compact : undefined,
|
65
|
-
className,
|
66
|
-
)}
|
67
|
-
style={style}
|
68
|
-
>
|
69
|
-
<tbody>{entryEls}</tbody>
|
70
|
-
</table>
|
71
|
-
);
|
72
|
-
};
|
73
|
-
|
74
|
-
// entries can be either a Record<string, stringable>
|
75
|
-
// or an array of record with name/value on way in
|
76
|
-
// but coerce to array of records for order
|
77
|
-
const toNameValues = (
|
78
|
-
entries?:
|
79
|
-
| Array<{ name: string; value: unknown }>
|
80
|
-
| Record<string, unknown>
|
81
|
-
| Array<unknown>,
|
82
|
-
): Array<{ name: string; value: unknown }> | undefined => {
|
83
|
-
if (entries) {
|
84
|
-
if (Array.isArray(entries)) {
|
85
|
-
// filter arrays that don't contain the expected name value pairs
|
86
|
-
const filtered = entries.filter((entry) => {
|
87
|
-
if (entry && typeof entry === "object") {
|
88
|
-
return "name" in entry && "value" in entry;
|
89
|
-
}
|
90
|
-
return false;
|
91
|
-
});
|
92
|
-
return filtered as Array<{ name: string; value: unknown }>;
|
93
|
-
} else {
|
94
|
-
return Object.entries(entries || {}).map(([key, value]) => {
|
95
|
-
return { name: key, value };
|
96
|
-
});
|
97
|
-
}
|
98
|
-
} else {
|
99
|
-
return entries;
|
100
|
-
}
|
101
|
-
};
|
@@ -1,34 +0,0 @@
|
|
1
|
-
import { ResultsMetric } from "./navbar/ResultsPanel";
|
2
|
-
|
3
|
-
export const metricDisplayName = (metric: ResultsMetric): string => {
|
4
|
-
let modifier = undefined;
|
5
|
-
for (const metricModifier of metricModifiers) {
|
6
|
-
modifier = metricModifier(metric);
|
7
|
-
if (modifier) {
|
8
|
-
break;
|
9
|
-
}
|
10
|
-
}
|
11
|
-
const metricName = !modifier ? metric.name : `${metric.name}[${modifier}]`;
|
12
|
-
|
13
|
-
return metricName;
|
14
|
-
};
|
15
|
-
|
16
|
-
type MetricModifier = (metric: ResultsMetric) => string | undefined;
|
17
|
-
|
18
|
-
const clusterMetricModifier: MetricModifier = (
|
19
|
-
metric: ResultsMetric,
|
20
|
-
): string | undefined => {
|
21
|
-
if (metric.name !== "stderr") {
|
22
|
-
return undefined;
|
23
|
-
}
|
24
|
-
|
25
|
-
const clusterValue = ((metric.params || {}) as Record<string, unknown>)[
|
26
|
-
"cluster"
|
27
|
-
];
|
28
|
-
if (clusterValue === undefined || typeof clusterValue !== "string") {
|
29
|
-
return undefined;
|
30
|
-
}
|
31
|
-
return clusterValue;
|
32
|
-
};
|
33
|
-
|
34
|
-
const metricModifiers: MetricModifier[] = [clusterMetricModifier];
|
@@ -1,72 +0,0 @@
|
|
1
|
-
import clsx from "clsx";
|
2
|
-
import { FC } from "react";
|
3
|
-
import { EvalLogHeader } from "../../client/api/types";
|
4
|
-
import styles from "./EvalStatus.module.css";
|
5
|
-
import { SidebarScoreView } from "./SidebarScoreView";
|
6
|
-
import { SidebarScoresView } from "./SidebarScoresView";
|
7
|
-
|
8
|
-
interface EvalStatusProps {
|
9
|
-
logHeader?: EvalLogHeader;
|
10
|
-
}
|
11
|
-
|
12
|
-
export const EvalStatus: FC<EvalStatusProps> = ({ logHeader }) => {
|
13
|
-
switch (logHeader?.status) {
|
14
|
-
case "error":
|
15
|
-
return <StatusError message="Error" />;
|
16
|
-
|
17
|
-
case "cancelled":
|
18
|
-
return <StatusCancelled message="Cancelled" />;
|
19
|
-
|
20
|
-
case "started":
|
21
|
-
return <StatusRunning message="Running" />;
|
22
|
-
|
23
|
-
default:
|
24
|
-
if (logHeader?.results?.scores && logHeader.results?.scores.length > 0) {
|
25
|
-
if (logHeader.results.scores.length === 1) {
|
26
|
-
return <SidebarScoreView scorer={logHeader.results.scores[0]} />;
|
27
|
-
} else {
|
28
|
-
return <SidebarScoresView scores={logHeader.results.scores} />;
|
29
|
-
}
|
30
|
-
} else {
|
31
|
-
return null;
|
32
|
-
}
|
33
|
-
}
|
34
|
-
};
|
35
|
-
|
36
|
-
interface StatusProps {
|
37
|
-
message: string;
|
38
|
-
}
|
39
|
-
|
40
|
-
const StatusCancelled: FC<StatusProps> = ({ message }) => {
|
41
|
-
return (
|
42
|
-
<div
|
43
|
-
className={clsx(
|
44
|
-
"text-style-secondary",
|
45
|
-
"text-style-label",
|
46
|
-
"text-size-small",
|
47
|
-
styles.cancelled,
|
48
|
-
)}
|
49
|
-
>
|
50
|
-
{message}
|
51
|
-
</div>
|
52
|
-
);
|
53
|
-
};
|
54
|
-
|
55
|
-
const StatusRunning: FC<StatusProps> = ({ message }) => {
|
56
|
-
return (
|
57
|
-
<div
|
58
|
-
className={clsx(
|
59
|
-
"text-style-secondary",
|
60
|
-
"text-style-label",
|
61
|
-
"text-size-small",
|
62
|
-
styles.running,
|
63
|
-
)}
|
64
|
-
>
|
65
|
-
<div>{message}</div>
|
66
|
-
</div>
|
67
|
-
);
|
68
|
-
};
|
69
|
-
|
70
|
-
const StatusError: FC<StatusProps> = ({ message }) => {
|
71
|
-
return <div className={clsx(styles.error, "text-size-small")}>{message}</div>;
|
72
|
-
};
|
@@ -1,16 +0,0 @@
|
|
1
|
-
.dirname {
|
2
|
-
overflow: hidden;
|
3
|
-
white-space: nowrap;
|
4
|
-
text-overflow: ellipsis;
|
5
|
-
}
|
6
|
-
|
7
|
-
.directoryLink {
|
8
|
-
color: inherit;
|
9
|
-
text-decoration: none;
|
10
|
-
cursor: pointer;
|
11
|
-
}
|
12
|
-
|
13
|
-
.directoryLink:hover {
|
14
|
-
color: var(--bs-primary);
|
15
|
-
text-decoration: none;
|
16
|
-
}
|
@@ -1,70 +0,0 @@
|
|
1
|
-
import clsx from "clsx";
|
2
|
-
import { FC, useCallback } from "react";
|
3
|
-
import { Link } from "react-router-dom";
|
4
|
-
import { useStore } from "../../state/store";
|
5
|
-
import styles from "./LogDirectoryTitleView.module.css";
|
6
|
-
|
7
|
-
interface LogDirectoryTitleViewProps {
|
8
|
-
log_dir?: string;
|
9
|
-
}
|
10
|
-
|
11
|
-
export const LogDirectoryTitleView: FC<LogDirectoryTitleViewProps> = ({
|
12
|
-
log_dir,
|
13
|
-
}) => {
|
14
|
-
const offCanvas = useStore((state) => state.app.offcanvas);
|
15
|
-
const setOffCanvas = useStore((state) => state.appActions.setOffcanvas);
|
16
|
-
|
17
|
-
const handleClick = useCallback(() => {
|
18
|
-
// Close the sidebar when clicking the directory link on mobile
|
19
|
-
if (offCanvas) {
|
20
|
-
setOffCanvas(false);
|
21
|
-
}
|
22
|
-
}, [offCanvas, setOffCanvas]);
|
23
|
-
if (log_dir) {
|
24
|
-
const displayDir = prettyDir(log_dir);
|
25
|
-
return (
|
26
|
-
<Link to="/logs" className={styles.directoryLink} onClick={handleClick}>
|
27
|
-
<div style={{ display: "flex", flexDirection: "column" }}>
|
28
|
-
<span
|
29
|
-
className={clsx(
|
30
|
-
"text-style-secondary",
|
31
|
-
"text-style-label",
|
32
|
-
"text-size-small",
|
33
|
-
)}
|
34
|
-
>
|
35
|
-
Log Directory
|
36
|
-
</span>
|
37
|
-
<span
|
38
|
-
title={displayDir}
|
39
|
-
className={clsx("text-size-base", styles.dirname)}
|
40
|
-
>
|
41
|
-
{offCanvas ? displayDir : ""}
|
42
|
-
</span>
|
43
|
-
</div>
|
44
|
-
</Link>
|
45
|
-
);
|
46
|
-
} else {
|
47
|
-
return (
|
48
|
-
<Link to="/logs" className={styles.directoryLink} onClick={handleClick}>
|
49
|
-
<span className={clsx("text-size-title")}>
|
50
|
-
{offCanvas ? "Log History" : ""}
|
51
|
-
</span>
|
52
|
-
</Link>
|
53
|
-
);
|
54
|
-
}
|
55
|
-
};
|
56
|
-
|
57
|
-
const prettyDir = (path: string): string => {
|
58
|
-
try {
|
59
|
-
// Try to create a new URL object
|
60
|
-
let url = new URL(path);
|
61
|
-
|
62
|
-
if (url.protocol === "file:") {
|
63
|
-
return url.pathname;
|
64
|
-
} else {
|
65
|
-
return path;
|
66
|
-
}
|
67
|
-
} catch {
|
68
|
-
return path;
|
69
|
-
}
|
70
|
-
};
|
@@ -1,77 +0,0 @@
|
|
1
|
-
.sidebar {
|
2
|
-
position: fixed;
|
3
|
-
left: 0;
|
4
|
-
top: 0;
|
5
|
-
width: var(--sidebar-width);
|
6
|
-
height: 100%;
|
7
|
-
background-color: #fff;
|
8
|
-
border-right: 1px solid var(--bs-light-border-subtle);
|
9
|
-
display: flex;
|
10
|
-
flex-direction: column;
|
11
|
-
z-index: 9999; /* Sit above main content */
|
12
|
-
transition: transform 0.3s ease-in-out;
|
13
|
-
}
|
14
|
-
|
15
|
-
.sidebarClosed {
|
16
|
-
transform: translateX(-100%);
|
17
|
-
}
|
18
|
-
|
19
|
-
.sidebarOpen {
|
20
|
-
transform: translateX(0);
|
21
|
-
}
|
22
|
-
|
23
|
-
.header {
|
24
|
-
display: grid;
|
25
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
26
|
-
column-gap: 0.2rem;
|
27
|
-
align-items: center;
|
28
|
-
opacity: 0.7;
|
29
|
-
position: sticky;
|
30
|
-
top: 0;
|
31
|
-
width: var(--sidebar-width);
|
32
|
-
border-bottom: 1px solid var(--bs-light-border-subtle);
|
33
|
-
padding: 0.5rem 0 0.5rem 1rem;
|
34
|
-
height: 3.6em;
|
35
|
-
background-color: #fff;
|
36
|
-
z-index: 10;
|
37
|
-
}
|
38
|
-
|
39
|
-
.toggle {
|
40
|
-
padding: 0.1rem;
|
41
|
-
align-self: end;
|
42
|
-
width: 40px;
|
43
|
-
flex: 0 0 auto;
|
44
|
-
}
|
45
|
-
|
46
|
-
.progress {
|
47
|
-
z-index: 3;
|
48
|
-
}
|
49
|
-
|
50
|
-
.list {
|
51
|
-
flex-grow: 1;
|
52
|
-
overflow-y: auto;
|
53
|
-
}
|
54
|
-
|
55
|
-
.backdrop {
|
56
|
-
position: fixed;
|
57
|
-
inset: 0;
|
58
|
-
background-color: var(--inspect-glass-color);
|
59
|
-
opacity: var(--inspect-glass-opacity);
|
60
|
-
z-index: 9998;
|
61
|
-
}
|
62
|
-
|
63
|
-
.active {
|
64
|
-
background-color: var(--bs-secondary-bg-subtle);
|
65
|
-
}
|
66
|
-
|
67
|
-
.item {
|
68
|
-
cursor: pointer;
|
69
|
-
padding: 0;
|
70
|
-
}
|
71
|
-
|
72
|
-
.logLink {
|
73
|
-
display: block;
|
74
|
-
padding: 0.5rem 1rem;
|
75
|
-
color: inherit;
|
76
|
-
text-decoration: none;
|
77
|
-
}
|
@@ -1,119 +0,0 @@
|
|
1
|
-
import clsx from "clsx";
|
2
|
-
import { FC, useCallback, useEffect, useRef } from "react";
|
3
|
-
import { Link } from "react-router-dom";
|
4
|
-
import { Fragment } from "react/jsx-runtime";
|
5
|
-
import { EvalLogHeader } from "../../client/api/types";
|
6
|
-
import { ProgressBar } from "../../components/ProgressBar";
|
7
|
-
import { useStatefulScrollPosition } from "../../state/scrolling";
|
8
|
-
import { useStore } from "../../state/store";
|
9
|
-
import { ApplicationIcons } from "../appearance/icons";
|
10
|
-
import { logUrl } from "../routing/url";
|
11
|
-
import { LogDirectoryTitleView } from "./LogDirectoryTitleView";
|
12
|
-
import styles from "./Sidebar.module.css";
|
13
|
-
import { SidebarLogEntry } from "./SidebarLogEntry";
|
14
|
-
|
15
|
-
interface SidebarProps {
|
16
|
-
logHeaders: Record<string, EvalLogHeader>;
|
17
|
-
loading: boolean;
|
18
|
-
selectedIndex: number;
|
19
|
-
onSelectedIndexChanged: (index: number) => void;
|
20
|
-
}
|
21
|
-
|
22
|
-
export const Sidebar: FC<SidebarProps> = ({
|
23
|
-
logHeaders,
|
24
|
-
loading,
|
25
|
-
selectedIndex,
|
26
|
-
onSelectedIndexChanged,
|
27
|
-
}) => {
|
28
|
-
const logs = useStore((state) => state.logs.logs);
|
29
|
-
const setOffCanvas = useStore((state) => state.appActions.setOffcanvas);
|
30
|
-
const offCanvas = useStore((state) => state.app.offcanvas);
|
31
|
-
const handleToggle = useCallback(() => {
|
32
|
-
setOffCanvas(!offCanvas);
|
33
|
-
}, [offCanvas, setOffCanvas]);
|
34
|
-
|
35
|
-
const sidebarContentsRef = useRef(null);
|
36
|
-
useStatefulScrollPosition(sidebarContentsRef, "sidebar-contents", 1000);
|
37
|
-
|
38
|
-
// Scroll the selected log into view when it changes
|
39
|
-
const itemRefs = useRef<{ [index: number]: HTMLLIElement | null }>({});
|
40
|
-
|
41
|
-
useEffect(() => {
|
42
|
-
if (itemRefs.current[selectedIndex]) {
|
43
|
-
itemRefs.current[selectedIndex]?.scrollIntoView({
|
44
|
-
behavior: "smooth",
|
45
|
-
block: "nearest",
|
46
|
-
});
|
47
|
-
}
|
48
|
-
}, [selectedIndex]);
|
49
|
-
|
50
|
-
// No longer need the click handler as we're using Links now
|
51
|
-
|
52
|
-
return (
|
53
|
-
<Fragment>
|
54
|
-
{/* Optional backdrop for small screens, appears only when offcanvas is open */}
|
55
|
-
{offCanvas && <div className={styles.backdrop} onClick={handleToggle} />}
|
56
|
-
|
57
|
-
<div
|
58
|
-
className={clsx(
|
59
|
-
styles.sidebar,
|
60
|
-
offCanvas ? styles.sidebarOpen : styles.sidebarClosed,
|
61
|
-
)}
|
62
|
-
>
|
63
|
-
<div className={styles.header}>
|
64
|
-
<LogDirectoryTitleView log_dir={logs.log_dir} />
|
65
|
-
<button
|
66
|
-
onClick={handleToggle}
|
67
|
-
className={clsx("btn", styles.toggle)}
|
68
|
-
type="button"
|
69
|
-
aria-label="Close sidebar"
|
70
|
-
>
|
71
|
-
<i className={ApplicationIcons.close}></i>
|
72
|
-
</button>
|
73
|
-
</div>
|
74
|
-
|
75
|
-
<div className={styles.progress}>
|
76
|
-
<ProgressBar animating={loading} />
|
77
|
-
</div>
|
78
|
-
|
79
|
-
<ul
|
80
|
-
ref={sidebarContentsRef}
|
81
|
-
className={clsx("list-group", styles.list)}
|
82
|
-
>
|
83
|
-
{logs.files.map((file, index) => {
|
84
|
-
const logHeader = logHeaders[file.name];
|
85
|
-
return (
|
86
|
-
<li
|
87
|
-
key={file.name}
|
88
|
-
ref={(el) => {
|
89
|
-
itemRefs.current[index] = el;
|
90
|
-
}}
|
91
|
-
className={clsx(
|
92
|
-
"list-group-item",
|
93
|
-
"list-group-item-action",
|
94
|
-
styles.item,
|
95
|
-
selectedIndex === index ? styles.active : undefined,
|
96
|
-
)}
|
97
|
-
data-index={index}
|
98
|
-
>
|
99
|
-
<Link
|
100
|
-
to={logUrl(file.name, logs.log_dir)}
|
101
|
-
className={styles.logLink}
|
102
|
-
onClick={() => {
|
103
|
-
// Also update the current index in state
|
104
|
-
onSelectedIndexChanged(index);
|
105
|
-
}}
|
106
|
-
>
|
107
|
-
<SidebarLogEntry
|
108
|
-
logHeader={logHeader}
|
109
|
-
task={file.task || "unknown task"}
|
110
|
-
/>
|
111
|
-
</Link>
|
112
|
-
</li>
|
113
|
-
);
|
114
|
-
})}
|
115
|
-
</ul>
|
116
|
-
</div>
|
117
|
-
</Fragment>
|
118
|
-
);
|
119
|
-
};
|
@@ -1,29 +0,0 @@
|
|
1
|
-
.entry {
|
2
|
-
display: flex;
|
3
|
-
flex-direction: row;
|
4
|
-
justify-content: space-between;
|
5
|
-
}
|
6
|
-
|
7
|
-
.title {
|
8
|
-
overflow: hidden;
|
9
|
-
min-width: 33%;
|
10
|
-
}
|
11
|
-
|
12
|
-
.task {
|
13
|
-
white-space: nowrap;
|
14
|
-
overflow: hidden;
|
15
|
-
text-overflow: ellipsis;
|
16
|
-
}
|
17
|
-
|
18
|
-
.params {
|
19
|
-
margin-top: 1em;
|
20
|
-
}
|
21
|
-
|
22
|
-
.scores {
|
23
|
-
width: 100%;
|
24
|
-
display: grid;
|
25
|
-
grid-template-columns: minmax(auto, 1fr) minmax(1fr, 1fr);
|
26
|
-
column-gap: 1rem;
|
27
|
-
justify-content: space-between;
|
28
|
-
margin-top: 0em;
|
29
|
-
}
|
@@ -1,96 +0,0 @@
|
|
1
|
-
import clsx from "clsx";
|
2
|
-
import { FC, Fragment } from "react";
|
3
|
-
import { EvalLogHeader } from "../../client/api/types";
|
4
|
-
import { kModelNone } from "../../constants";
|
5
|
-
import { EvalStatus } from "./EvalStatus";
|
6
|
-
import styles from "./SidebarLogEntry.module.css";
|
7
|
-
|
8
|
-
interface SidebarLogEntryProps {
|
9
|
-
logHeader?: EvalLogHeader;
|
10
|
-
task: string;
|
11
|
-
}
|
12
|
-
|
13
|
-
export const SidebarLogEntry: FC<SidebarLogEntryProps> = ({
|
14
|
-
logHeader,
|
15
|
-
task,
|
16
|
-
}) => {
|
17
|
-
const hyperparameters: Record<string, unknown> = {
|
18
|
-
...(logHeader?.plan?.config || {}),
|
19
|
-
...(logHeader?.eval?.task_args || {}),
|
20
|
-
};
|
21
|
-
|
22
|
-
const model = logHeader?.eval?.model;
|
23
|
-
const datasetName = logHeader?.eval?.dataset.name;
|
24
|
-
|
25
|
-
const uniqScorers = new Set();
|
26
|
-
logHeader?.results?.scores?.forEach((scorer) => {
|
27
|
-
uniqScorers.add(scorer.name);
|
28
|
-
});
|
29
|
-
const scorerNames = Array.from(uniqScorers).join(",");
|
30
|
-
|
31
|
-
const scorerLabel =
|
32
|
-
Object.keys(logHeader?.results?.scores || {}).length === 1
|
33
|
-
? "scorer"
|
34
|
-
: "scorers";
|
35
|
-
|
36
|
-
const completed = logHeader?.stats?.completed_at;
|
37
|
-
const time = completed ? new Date(completed) : undefined;
|
38
|
-
const timeStr = time
|
39
|
-
? `${time.toDateString()}
|
40
|
-
${time.toLocaleTimeString([], {
|
41
|
-
hour: "2-digit",
|
42
|
-
minute: "2-digit",
|
43
|
-
})}`
|
44
|
-
: "";
|
45
|
-
|
46
|
-
return (
|
47
|
-
<Fragment>
|
48
|
-
<div className={styles.entry}>
|
49
|
-
<div className={styles.title}>
|
50
|
-
<div className={clsx(styles.task, "text-size-title-secondary")}>
|
51
|
-
{logHeader?.eval?.task || task}
|
52
|
-
</div>
|
53
|
-
<small className={clsx("mb-1", "text-size-small")}>{timeStr}</small>
|
54
|
-
|
55
|
-
{model && model !== kModelNone ? (
|
56
|
-
<div>
|
57
|
-
<small className={clsx("mb-1", "text-size-small")}>{model}</small>
|
58
|
-
</div>
|
59
|
-
) : (
|
60
|
-
""
|
61
|
-
)}
|
62
|
-
</div>
|
63
|
-
<EvalStatus logHeader={logHeader} />
|
64
|
-
</div>
|
65
|
-
<div className={clsx(styles.params, "three-line-clamp")}>
|
66
|
-
<small className={"mb-1"}>
|
67
|
-
{hyperparameters
|
68
|
-
? Object.keys(hyperparameters)
|
69
|
-
.map((key) => {
|
70
|
-
const val = hyperparameters[key];
|
71
|
-
if (Array.isArray(val) || typeof val === "object") {
|
72
|
-
return `${key}: ${JSON.stringify(val)}`;
|
73
|
-
} else {
|
74
|
-
return `${key}: ${val}`;
|
75
|
-
}
|
76
|
-
})
|
77
|
-
.join(", ")
|
78
|
-
: ""}
|
79
|
-
</small>
|
80
|
-
</div>
|
81
|
-
{(logHeader?.eval?.dataset || logHeader?.results?.scores) &&
|
82
|
-
logHeader?.status === "success" ? (
|
83
|
-
<div
|
84
|
-
className={clsx("text-truncate", "text-size-small", styles.scores)}
|
85
|
-
>
|
86
|
-
<div>dataset: {datasetName || "(samples)"}</div>
|
87
|
-
<div className={clsx("text-truncate", styles.scoreInfo)}>
|
88
|
-
{scorerLabel}: {scorerNames || "(none)"}
|
89
|
-
</div>
|
90
|
-
</div>
|
91
|
-
) : (
|
92
|
-
""
|
93
|
-
)}
|
94
|
-
</Fragment>
|
95
|
-
);
|
96
|
-
};
|
@@ -1,23 +0,0 @@
|
|
1
|
-
.container {
|
2
|
-
display: flex;
|
3
|
-
flex-direction: row;
|
4
|
-
flex-wrap: wrap;
|
5
|
-
justify-content: flex-end;
|
6
|
-
}
|
7
|
-
|
8
|
-
.metric {
|
9
|
-
display: flex;
|
10
|
-
flex-direction: column;
|
11
|
-
align-items: flex-end;
|
12
|
-
margin-left: 1em;
|
13
|
-
margin-bottom: 0.4em;
|
14
|
-
margin-top: 0.5rem;
|
15
|
-
}
|
16
|
-
|
17
|
-
.metricName {
|
18
|
-
margin-bottom: -0.3em;
|
19
|
-
}
|
20
|
-
|
21
|
-
.metricReducer {
|
22
|
-
margin-bottom: -0.2rem;
|
23
|
-
}
|
@@ -1,44 +0,0 @@
|
|
1
|
-
import clsx from "clsx";
|
2
|
-
import { EvalScore } from "../../@types/log";
|
3
|
-
import { formatPrettyDecimal } from "../../utils/format";
|
4
|
-
|
5
|
-
import { FC } from "react";
|
6
|
-
import { metricDisplayName } from "../log-view/utils";
|
7
|
-
import styles from "./SidebarScoreView.module.css";
|
8
|
-
interface SidebarScoreProps {
|
9
|
-
scorer: EvalScore;
|
10
|
-
}
|
11
|
-
|
12
|
-
export const SidebarScoreView: FC<SidebarScoreProps> = ({ scorer }) => {
|
13
|
-
const showReducer = !!scorer.reducer;
|
14
|
-
return (
|
15
|
-
<div className={styles.container}>
|
16
|
-
{Object.keys(scorer.metrics).map((metric) => {
|
17
|
-
return (
|
18
|
-
<div className={styles.metric} key={metric}>
|
19
|
-
<div
|
20
|
-
className={clsx(
|
21
|
-
"text-style-secondary",
|
22
|
-
"text-style-label",
|
23
|
-
"text-size-small",
|
24
|
-
styles.metricName,
|
25
|
-
)}
|
26
|
-
>
|
27
|
-
{metricDisplayName(scorer.metrics[metric])}
|
28
|
-
</div>
|
29
|
-
{showReducer ? (
|
30
|
-
<div className={clsx("text-size-small", styles.metricReducer)}>
|
31
|
-
{scorer.reducer || "default"}
|
32
|
-
</div>
|
33
|
-
) : (
|
34
|
-
""
|
35
|
-
)}
|
36
|
-
<div className={"text-size-title-secondary"}>
|
37
|
-
{formatPrettyDecimal(scorer.metrics[metric].value)}
|
38
|
-
</div>
|
39
|
-
</div>
|
40
|
-
);
|
41
|
-
})}
|
42
|
-
</div>
|
43
|
-
);
|
44
|
-
};
|