inspect-ai 0.3.107__py3-none-any.whl → 0.3.109__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 +1 -1
- 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/_anthropic_citations.py +1 -4
- 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.107.dist-info → inspect_ai-0.3.109.dist-info}/METADATA +2 -2
- {inspect_ai-0.3.107.dist-info → inspect_ai-0.3.109.dist-info}/RECORD +125 -95
- 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.107.dist-info → inspect_ai-0.3.109.dist-info}/WHEEL +0 -0
- {inspect_ai-0.3.107.dist-info → inspect_ai-0.3.109.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.107.dist-info → inspect_ai-0.3.109.dist-info}/licenses/LICENSE +0 -0
- {inspect_ai-0.3.107.dist-info → inspect_ai-0.3.109.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
|
-
};
|