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
@@ -63,10 +63,11 @@
|
|
63
63
|
"@codemirror/state": "^6.5.2",
|
64
64
|
"@lezer/highlight": "^1.2.1",
|
65
65
|
"@mui/material": "^7.1.0",
|
66
|
-
"@mui/x-tree-view": "^8.3.
|
66
|
+
"@mui/x-tree-view": "^8.3.1",
|
67
67
|
"@popperjs/core": "^2.11.8",
|
68
|
+
"@tanstack/react-table": "^8.21.3",
|
68
69
|
"ansi-output": "^0.0.9",
|
69
|
-
"asciinema-player": "^3.
|
70
|
+
"asciinema-player": "^3.10.0",
|
70
71
|
"bootstrap": "^5.3.6",
|
71
72
|
"bootstrap-icons": "^1.12.1",
|
72
73
|
"clipboard": "^2.0.11",
|
@@ -1,8 +1,8 @@
|
|
1
|
-
/*
|
2
|
-
|
3
|
-
*
|
4
|
-
*
|
5
|
-
*
|
1
|
+
/*
|
2
|
+
* This file is automatically generated by schema.py
|
3
|
+
* DO NOT MODIFY IT BY HAND.
|
4
|
+
* To regenerate, run: python -m ../schema.py from within the
|
5
|
+
* src/inspect_ai/_view/www directory.
|
6
6
|
*/
|
7
7
|
|
8
8
|
export type Version = number;
|
@@ -53,7 +53,15 @@ body:not([class^="vscode-"]) button {
|
|
53
53
|
display: grid;
|
54
54
|
height: 100vh;
|
55
55
|
overflow-y: hidden;
|
56
|
-
grid-template-rows: max-content max-content 1fr;
|
56
|
+
grid-template-rows: max-content max-content max-content 1fr;
|
57
|
+
}
|
58
|
+
|
59
|
+
a {
|
60
|
+
color: var(--bs-link-color);
|
61
|
+
}
|
62
|
+
|
63
|
+
a:hover {
|
64
|
+
color: var(--bs-link-hover-color);
|
57
65
|
}
|
58
66
|
|
59
67
|
.modal {
|
@@ -64,7 +72,7 @@ body:not([class^="vscode-"]) button {
|
|
64
72
|
--bs-backdrop-opacity: 0.4;
|
65
73
|
}
|
66
74
|
|
67
|
-
|
75
|
+
.app-main-grid.single-file-mode {
|
68
76
|
grid-template-rows: max-content max-content 1fr;
|
69
77
|
}
|
70
78
|
|
@@ -135,6 +143,7 @@ body[class^="vscode-"] {
|
|
135
143
|
--bs-border-radius: 0;
|
136
144
|
--bs-border-radius-lg: 0;
|
137
145
|
--bs-body-bg: var(--vscode-editor-background);
|
146
|
+
--bs-secondary-bg-subtle: var(--vscode-editorHoverWidget-background);
|
138
147
|
--bs-card-bg: var(--vscode-editor-background);
|
139
148
|
--bs-table-bg: var(--vscode-editor-background);
|
140
149
|
--bs-light-bg-subtle: var(--vscode-sideBar-background);
|
@@ -150,12 +159,15 @@ body[class^="vscode-"] {
|
|
150
159
|
--bs-btn-bg: var(--vscode-peekViewTitle-background);
|
151
160
|
--bs-primary: var(--vscode-banner-iconForeground);
|
152
161
|
--bs-nav-pills-link-active-bg: var(--vscode-banner-iconForeground);
|
162
|
+
--bs-link-color: var(--vscode-textLink-foreground);
|
163
|
+
--bs-link-hover-color: var(--vscode-textLink-activeForeground);
|
153
164
|
--bs-secondary: var(--vscode-breadcrumb-foreground);
|
154
165
|
--bs-secondary-bg: var(--vscode-list-inactiveSelectionBackground);
|
155
166
|
--bs-border-color: var(--vscode-editorGroup-border);
|
156
167
|
--bs-card-border-color: var(--vscode-editorGroup-border);
|
157
168
|
--bs-warning-bg-subtle: var(--vscode-inputValidation-warningBackground);
|
158
169
|
--bs-warning-text-emphasis: var(--vscode-input-foreground);
|
170
|
+
--bs-breadcrumb-divider-color: var(--vscode-foreground);
|
159
171
|
--inspect-find-background: var(--vscode-editorWidget-background);
|
160
172
|
--inspect-find-foreground: var(--vscode-editorWidget-foreground);
|
161
173
|
--inspect-input-background: var(--vscode-input-background);
|
@@ -328,6 +340,10 @@ body[class^="vscode-"] .sidebar .list-group {
|
|
328
340
|
--bs-list-group-active-color: var(--vscode-sideBarSectionHeader-foreground);
|
329
341
|
}
|
330
342
|
|
343
|
+
body[class^="vscode-"] .breadcrumb-item {
|
344
|
+
--bs-breadcrumb-divider-color: var(--vscode-foreground);
|
345
|
+
}
|
346
|
+
|
331
347
|
body[class^="vscode-"] div.ap-control-bar .ap-fullscreen-button {
|
332
348
|
display: none;
|
333
349
|
}
|
@@ -1025,11 +1041,11 @@ ul.jsondiffpatch-textdiff {
|
|
1025
1041
|
/* prism-custom.css */
|
1026
1042
|
code[class*="language-"],
|
1027
1043
|
pre[class*="language-"] {
|
1028
|
-
font-size: 0.
|
1044
|
+
font-size: 0.7rem !important;
|
1029
1045
|
}
|
1030
1046
|
|
1031
1047
|
.token {
|
1032
|
-
font-size: 0.
|
1048
|
+
font-size: 0.7rem !important;
|
1033
1049
|
}
|
1034
1050
|
|
1035
1051
|
/* PrismJS 1.29.0 https://prismjs.com/download.html#themes=prism-dark&languages=markup+css+clike+javascript+bash+python */
|
@@ -1140,3 +1156,54 @@ pre[class*="language-"] {
|
|
1140
1156
|
color: red;
|
1141
1157
|
}
|
1142
1158
|
/* END PrismJS */
|
1159
|
+
|
1160
|
+
/* SVG Icon styles - following Bootstrap Icons pattern */
|
1161
|
+
.inspect-icon-16::before {
|
1162
|
+
content: "";
|
1163
|
+
width: 1em;
|
1164
|
+
height: 1em;
|
1165
|
+
display: inline-block;
|
1166
|
+
vertical-align: middle;
|
1167
|
+
mask: url("../img/inspect-16.svg") no-repeat center / contain;
|
1168
|
+
-webkit-mask: url("../img/inspect-16.svg") no-repeat center / contain;
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
.inspect-icon-back::before {
|
1172
|
+
content: "";
|
1173
|
+
width: 1em;
|
1174
|
+
height: 1em;
|
1175
|
+
display: inline-block;
|
1176
|
+
vertical-align: middle;
|
1177
|
+
mask: url("../img/inspect-back.svg") no-repeat center / contain;
|
1178
|
+
-webkit-mask: url("../img/inspect-back.svg") no-repeat center / contain;
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
.inspect-icon-forward::before {
|
1182
|
+
content: "";
|
1183
|
+
width: 1em;
|
1184
|
+
height: 1em;
|
1185
|
+
display: inline-block;
|
1186
|
+
vertical-align: middle;
|
1187
|
+
mask: url("../img/inspect-forward.svg") no-repeat center / contain;
|
1188
|
+
-webkit-mask: url("../img/inspect-forward.svg") no-repeat center / contain;
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
.inspect-icon-file::before {
|
1192
|
+
content: "";
|
1193
|
+
width: 1em;
|
1194
|
+
height: 1em;
|
1195
|
+
display: inline-block;
|
1196
|
+
vertical-align: middle;
|
1197
|
+
mask: url("../img/inspect-file.svg") no-repeat center / contain;
|
1198
|
+
-webkit-mask: url("../img/inspect-file.svg") no-repeat center / contain;
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
.inspect-icon-home::before {
|
1202
|
+
content: "";
|
1203
|
+
width: 1em;
|
1204
|
+
height: 1em;
|
1205
|
+
display: inline-block;
|
1206
|
+
vertical-align: middle;
|
1207
|
+
mask: url("../img/inspect-home.svg") no-repeat center / contain;
|
1208
|
+
-webkit-mask: url("../img/inspect-home.svg") no-repeat center / contain;
|
1209
|
+
}
|
@@ -45,6 +45,10 @@ export const App: FC<AppProps> = ({ api }) => {
|
|
45
45
|
const loadLog = useStore((state) => state.logActions.loadLog);
|
46
46
|
const pollLog = useStore((state) => state.logActions.pollLog);
|
47
47
|
|
48
|
+
const setSingleFileMode = useStore(
|
49
|
+
(state) => state.appActions.setSingleFileMode,
|
50
|
+
);
|
51
|
+
|
48
52
|
// Load a specific log
|
49
53
|
useEffect(() => {
|
50
54
|
const loadSpecificLog = async () => {
|
@@ -135,6 +139,7 @@ export const App: FC<AppProps> = ({ api }) => {
|
|
135
139
|
if (embeddedState && !rehydrated) {
|
136
140
|
const state = JSON5.parse(embeddedState.textContent || "");
|
137
141
|
onMessage({ data: state });
|
142
|
+
setSingleFileMode(true);
|
138
143
|
} else {
|
139
144
|
// For non-route URL params support (legacy)
|
140
145
|
const urlParams = new URLSearchParams(window.location.search);
|
@@ -151,11 +156,13 @@ export const App: FC<AppProps> = ({ api }) => {
|
|
151
156
|
log_dir: "",
|
152
157
|
files: [{ name: resolvedLogPath }],
|
153
158
|
});
|
159
|
+
setSingleFileMode(true);
|
154
160
|
} else {
|
155
161
|
// If a log file was passed, select it
|
156
162
|
const log_file = urlParams.get("log_file");
|
157
163
|
if (log_file) {
|
158
164
|
await selectLogFile(log_file);
|
165
|
+
setSingleFileMode(true);
|
159
166
|
}
|
160
167
|
// Else do nothing - RouteProvider will handle it
|
161
168
|
}
|
@@ -23,6 +23,7 @@ export const ApplicationIcons = {
|
|
23
23
|
down: "bi bi-arrow-down",
|
24
24
|
up: "bi bi-arrow-up",
|
25
25
|
},
|
26
|
+
cancelled: "bi bi-x-circle",
|
26
27
|
caret: {
|
27
28
|
right: "bi bi-caret-right",
|
28
29
|
down: "bi bi-caret-down",
|
@@ -36,11 +37,12 @@ export const ApplicationIcons = {
|
|
36
37
|
right: "bi bi-chevron-right",
|
37
38
|
down: "bi bi-chevron-down",
|
38
39
|
},
|
40
|
+
"clear-text": "bi bi-x-circle-fill",
|
41
|
+
close: "bi bi-x",
|
39
42
|
collapse: {
|
40
43
|
all: "bi bi-arrows-collapse",
|
41
44
|
up: "bi bi-chevron-up",
|
42
45
|
},
|
43
|
-
close: "bi bi-x",
|
44
46
|
config: "bi bi-gear",
|
45
47
|
confirm: "bi bi-check",
|
46
48
|
copy: "bi bi-copy",
|
@@ -48,12 +50,18 @@ export const ApplicationIcons = {
|
|
48
50
|
return `bi bi-${epoch}-circle`;
|
49
51
|
},
|
50
52
|
error: "bi bi-exclamation-circle",
|
53
|
+
eval: "bi bi-info-circle-fill",
|
51
54
|
"expand-all": "bi bi-arrows-expand",
|
52
55
|
"expand-down": "bi bi-chevron-down",
|
56
|
+
file: "bi bi-file-code",
|
57
|
+
filter: "bi bi-funnel",
|
58
|
+
folder: "bi bi-folder",
|
53
59
|
fork: "bi bi-signpost-split",
|
60
|
+
home: "bi bi-house",
|
54
61
|
info: "bi bi-info-circle",
|
55
62
|
input: "bi bi-terminal",
|
56
|
-
inspect: "
|
63
|
+
inspect: "ii inspect-icon-16",
|
64
|
+
inspectFile: "ii inspect-icon-file",
|
57
65
|
json: "bi bi-filetype-json",
|
58
66
|
limits: {
|
59
67
|
messages: "bi bi-chat-right-text",
|
@@ -73,6 +81,13 @@ export const ApplicationIcons = {
|
|
73
81
|
"toggle-right": "bi bi-chevron-right",
|
74
82
|
more: "bi bi-zoom-in",
|
75
83
|
"multiple-choice": "bi bi-card-list",
|
84
|
+
navbar: {
|
85
|
+
home: "ii inspect-icon-home",
|
86
|
+
back: "ii inspect-icon-back",
|
87
|
+
forward: "ii inspect-icon-forward",
|
88
|
+
inspectLogo: "ii inspect-icon-16",
|
89
|
+
},
|
90
|
+
|
76
91
|
next: "bi bi-chevron-right",
|
77
92
|
noSamples: "bi bi-ban",
|
78
93
|
play: "bi bi-play-fill",
|
@@ -103,6 +118,7 @@ export const ApplicationIcons = {
|
|
103
118
|
},
|
104
119
|
step: "bi bi-fast-forward-btn",
|
105
120
|
subtask: "bi bi-subtract",
|
121
|
+
success: "bi bi-check-circle",
|
106
122
|
transcript: "bi bi-list-columns-reverse",
|
107
123
|
tree: {
|
108
124
|
open: "bi bi-caret-down-fill",
|
@@ -8,7 +8,7 @@ import { formatNumber } from "../../utils/format";
|
|
8
8
|
import { isJson } from "../../utils/json";
|
9
9
|
import { ApplicationIcons } from "../appearance/icons";
|
10
10
|
import { ChatMessageRenderer } from "../samples/chat/ChatMessageRenderer";
|
11
|
-
import {
|
11
|
+
import { MetaDataGrid } from "./MetaDataGrid";
|
12
12
|
import styles from "./RenderedContent.module.css";
|
13
13
|
import { Buckets, ContentRenderer, RenderOptions } from "./types";
|
14
14
|
|
@@ -190,12 +190,11 @@ const contentRenderers: (
|
|
190
190
|
const arrayRendered = renderObject ? (
|
191
191
|
renderObject(arrayMap)
|
192
192
|
) : (
|
193
|
-
<
|
193
|
+
<MetaDataGrid
|
194
194
|
id={id}
|
195
195
|
className={"font-size-small"}
|
196
196
|
entries={arrayMap}
|
197
|
-
|
198
|
-
compact={true}
|
197
|
+
plain={true}
|
199
198
|
/>
|
200
199
|
);
|
201
200
|
return { rendered: arrayRendered };
|
@@ -283,12 +282,11 @@ const contentRenderers: (
|
|
283
282
|
} else {
|
284
283
|
return {
|
285
284
|
rendered: (
|
286
|
-
<
|
285
|
+
<MetaDataGrid
|
287
286
|
id={id}
|
288
|
-
className={"
|
289
|
-
entries={entry.value}
|
290
|
-
|
291
|
-
compact
|
287
|
+
className={"font-size-small"}
|
288
|
+
entries={entry.value as Record<string, unknown>}
|
289
|
+
plain={true}
|
292
290
|
/>
|
293
291
|
),
|
294
292
|
};
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { EvalLogHeader, LogFile } from "../../client/api/types";
|
2
|
+
|
3
|
+
export interface LogItem {
|
4
|
+
id: string;
|
5
|
+
name: string;
|
6
|
+
url: string;
|
7
|
+
}
|
8
|
+
|
9
|
+
export interface FolderLogItem extends LogItem {
|
10
|
+
type: "folder";
|
11
|
+
itemCount: number;
|
12
|
+
}
|
13
|
+
|
14
|
+
export interface FileLogItem extends LogItem {
|
15
|
+
type: "file";
|
16
|
+
logFile: LogFile;
|
17
|
+
header?: EvalLogHeader;
|
18
|
+
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
.footer {
|
2
|
+
border-top: solid var(--bs-light-border-subtle) 1px;
|
3
|
+
background: var(--bs-light-bg-subtle);
|
4
|
+
display: grid;
|
5
|
+
grid-template-columns: 0.5fr 1fr 0.5fr;
|
6
|
+
justify-content: space-between;
|
7
|
+
|
8
|
+
padding: 0.2em 1em;
|
9
|
+
}
|
10
|
+
|
11
|
+
.spinnerContainer {
|
12
|
+
display: grid;
|
13
|
+
grid-template-columns: max-content max-content;
|
14
|
+
column-gap: 0.3em;
|
15
|
+
padding-top: 0.2em;
|
16
|
+
}
|
17
|
+
|
18
|
+
.spinner {
|
19
|
+
height: 11px;
|
20
|
+
width: 11px;
|
21
|
+
color: var(--bs-secondary);
|
22
|
+
border-width: 1px;
|
23
|
+
}
|
24
|
+
|
25
|
+
.label {
|
26
|
+
margin-left: 0.1em;
|
27
|
+
margin-top: -3px;
|
28
|
+
}
|
29
|
+
|
30
|
+
.right {
|
31
|
+
display: grid;
|
32
|
+
grid-auto-columns: max-content;
|
33
|
+
grid-auto-flow: column;
|
34
|
+
justify-content: end;
|
35
|
+
align-items: center;
|
36
|
+
column-gap: 0.5em;
|
37
|
+
}
|
38
|
+
|
39
|
+
.left {
|
40
|
+
display: grid;
|
41
|
+
grid-auto-columns: max-content;
|
42
|
+
grid-auto-flow: column;
|
43
|
+
justify-content: start;
|
44
|
+
align-items: center;
|
45
|
+
column-gap: 0.5em;
|
46
|
+
}
|
47
|
+
|
48
|
+
.center {
|
49
|
+
display: grid;
|
50
|
+
grid-auto-columns: max-content;
|
51
|
+
grid-auto-flow: column;
|
52
|
+
justify-content: center;
|
53
|
+
align-items: center;
|
54
|
+
column-gap: 0.5em;
|
55
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
interface LogListFooterProps {
|
2
|
+
logDir: string;
|
3
|
+
itemCount: number;
|
4
|
+
progressText?: string;
|
5
|
+
}
|
6
|
+
|
7
|
+
import clsx from "clsx";
|
8
|
+
import { FC } from "react";
|
9
|
+
import { useLogsListing, usePagination } from "../../state/hooks";
|
10
|
+
import styles from "./LogListFooter.module.css";
|
11
|
+
import { LogPager } from "./LogPager";
|
12
|
+
import { kDefaultPageSize, kLogsPaginationId } from "./LogsPanel";
|
13
|
+
|
14
|
+
export const LogListFooter: FC<LogListFooterProps> = ({
|
15
|
+
itemCount,
|
16
|
+
progressText,
|
17
|
+
}) => {
|
18
|
+
// Get pagination info from the store
|
19
|
+
const { page, itemsPerPage } = usePagination(
|
20
|
+
kLogsPaginationId,
|
21
|
+
kDefaultPageSize,
|
22
|
+
);
|
23
|
+
|
24
|
+
// Get filtered count from the store
|
25
|
+
const { filteredCount } = useLogsListing();
|
26
|
+
const effectiveItemCount = filteredCount ?? itemCount;
|
27
|
+
|
28
|
+
const currentPage = page || 0;
|
29
|
+
const pageItemCount = Math.min(
|
30
|
+
itemsPerPage,
|
31
|
+
effectiveItemCount - currentPage * itemsPerPage,
|
32
|
+
);
|
33
|
+
const startItem = effectiveItemCount > 0 ? currentPage * itemsPerPage + 1 : 0;
|
34
|
+
const endItem = startItem + pageItemCount - 1;
|
35
|
+
|
36
|
+
return (
|
37
|
+
<div className={clsx("text-size-smaller", styles.footer)}>
|
38
|
+
<div className={clsx(styles.left)}>
|
39
|
+
{progressText ? (
|
40
|
+
<div className={clsx(styles.spinnerContainer)}>
|
41
|
+
<div
|
42
|
+
className={clsx("spinner-border", styles.spinner)}
|
43
|
+
role="status"
|
44
|
+
>
|
45
|
+
<span className={clsx("visually-hidden")}>{progressText}...</span>
|
46
|
+
</div>
|
47
|
+
<div className={clsx("text-style-secondary", styles.label)}>
|
48
|
+
{progressText}...
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
) : undefined}
|
52
|
+
</div>
|
53
|
+
<div className={clsx(styles.center)}>
|
54
|
+
<LogPager itemCount={effectiveItemCount} />
|
55
|
+
</div>
|
56
|
+
<div className={clsx(styles.right)}>
|
57
|
+
<div>
|
58
|
+
{effectiveItemCount === 0
|
59
|
+
? ""
|
60
|
+
: filteredCount !== undefined && filteredCount !== itemCount
|
61
|
+
? `${startItem} - ${endItem} / ${effectiveItemCount} (${itemCount} total)`
|
62
|
+
: `${startItem} - ${endItem} / ${effectiveItemCount}`}
|
63
|
+
</div>
|
64
|
+
</div>
|
65
|
+
</div>
|
66
|
+
);
|
67
|
+
};
|
@@ -0,0 +1,29 @@
|
|
1
|
+
.pager {
|
2
|
+
--bs-pagination-padding-x: 0.5em;
|
3
|
+
--bs-pagination-padding-y: 0.15em;
|
4
|
+
--bs-pagination-font-size: 0.8rem;
|
5
|
+
--bs-pagination-padding-x: 0.5em;
|
6
|
+
--bs-pagination-padding-y: 0;
|
7
|
+
--bs-pagination-border-radius: var(--bs-border-radius);
|
8
|
+
margin-bottom: 0;
|
9
|
+
}
|
10
|
+
|
11
|
+
.item:not(:global(.disabled)) {
|
12
|
+
cursor: pointer;
|
13
|
+
}
|
14
|
+
|
15
|
+
.item {
|
16
|
+
margin-left: 0.2em;
|
17
|
+
margin-right: 0.2em;
|
18
|
+
}
|
19
|
+
|
20
|
+
.item:first-child,
|
21
|
+
.item:last-child {
|
22
|
+
--bs-pagination-padding-x: 0.3em;
|
23
|
+
}
|
24
|
+
|
25
|
+
.item:first-child :global(.ii:before),
|
26
|
+
.item:last-child :global(.ii:before) {
|
27
|
+
margin-top: -2px;
|
28
|
+
font-size: 0.8em;
|
29
|
+
}
|
@@ -0,0 +1,134 @@
|
|
1
|
+
import clsx from "clsx";
|
2
|
+
import { FC } from "react";
|
3
|
+
|
4
|
+
import { usePagination } from "../../state/hooks";
|
5
|
+
import { ApplicationIcons } from "../appearance/icons";
|
6
|
+
import styles from "./LogPager.module.css";
|
7
|
+
import { kDefaultPageSize, kLogsPaginationId } from "./LogsPanel";
|
8
|
+
|
9
|
+
interface LogPagerProps {
|
10
|
+
itemCount: number;
|
11
|
+
}
|
12
|
+
|
13
|
+
export const LogPager: FC<LogPagerProps> = ({ itemCount }) => {
|
14
|
+
const { page, itemsPerPage, setPage } = usePagination(
|
15
|
+
kLogsPaginationId,
|
16
|
+
kDefaultPageSize,
|
17
|
+
);
|
18
|
+
const pageCount = Math.ceil(itemCount / itemsPerPage);
|
19
|
+
if (pageCount <= 1) {
|
20
|
+
return null;
|
21
|
+
}
|
22
|
+
|
23
|
+
const currentPage = page || 0;
|
24
|
+
|
25
|
+
const generatePaginationSegments = () => {
|
26
|
+
const segments: Array<{
|
27
|
+
type: "page" | "ellipsis";
|
28
|
+
page?: number;
|
29
|
+
key: string;
|
30
|
+
}> = [];
|
31
|
+
|
32
|
+
if (pageCount <= 5) {
|
33
|
+
// Show all pages if 5 or fewer
|
34
|
+
for (let i = 0; i < pageCount; i++) {
|
35
|
+
segments.push({ type: "page", page: i, key: `page-${i}` });
|
36
|
+
}
|
37
|
+
} else {
|
38
|
+
// There are more than 5 pages, use ellpsis to constrain the size
|
39
|
+
|
40
|
+
// first page
|
41
|
+
segments.push({ type: "page", page: 0, key: "page-0" });
|
42
|
+
|
43
|
+
// Determine the range around current page
|
44
|
+
const startPage = Math.max(1, currentPage - 1);
|
45
|
+
const endPage = Math.min(pageCount - 2, currentPage + 1);
|
46
|
+
|
47
|
+
// Add ellipsis before middle section if needed
|
48
|
+
if (startPage > 1) {
|
49
|
+
segments.push({ type: "ellipsis", key: "ellipsis-start" });
|
50
|
+
}
|
51
|
+
|
52
|
+
// Add middle section pages
|
53
|
+
for (let i = startPage; i <= endPage; i++) {
|
54
|
+
segments.push({ type: "page", page: i, key: `page-${i}` });
|
55
|
+
}
|
56
|
+
|
57
|
+
// Add ellipsis after middle section if needed
|
58
|
+
if (endPage < pageCount - 2) {
|
59
|
+
segments.push({ type: "ellipsis", key: "ellipsis-end" });
|
60
|
+
}
|
61
|
+
|
62
|
+
// last page
|
63
|
+
segments.push({
|
64
|
+
type: "page",
|
65
|
+
page: pageCount - 1,
|
66
|
+
key: `page-${pageCount - 1}`,
|
67
|
+
});
|
68
|
+
}
|
69
|
+
|
70
|
+
return segments;
|
71
|
+
};
|
72
|
+
|
73
|
+
const segments = generatePaginationSegments();
|
74
|
+
|
75
|
+
return (
|
76
|
+
<nav aria-label="Log Pagination">
|
77
|
+
<ul className={clsx("pagination", styles.pager)}>
|
78
|
+
<li className={clsx(currentPage === 0 ? "disabled" : "", styles.item)}>
|
79
|
+
<a
|
80
|
+
className={clsx("page-link")}
|
81
|
+
onClick={() => {
|
82
|
+
if (currentPage > 0) {
|
83
|
+
setPage(currentPage - 1);
|
84
|
+
}
|
85
|
+
}}
|
86
|
+
>
|
87
|
+
<i className={clsx(ApplicationIcons.navbar.back)} />
|
88
|
+
</a>
|
89
|
+
</li>
|
90
|
+
|
91
|
+
{segments.map((segment) => (
|
92
|
+
<li
|
93
|
+
key={segment.key}
|
94
|
+
className={clsx(
|
95
|
+
segment.type === "page" && segment.page === currentPage
|
96
|
+
? "active"
|
97
|
+
: undefined,
|
98
|
+
segment.type === "ellipsis" ? "disabled" : undefined,
|
99
|
+
styles.item,
|
100
|
+
)}
|
101
|
+
>
|
102
|
+
<a
|
103
|
+
className={clsx("page-link")}
|
104
|
+
onClick={() => {
|
105
|
+
if (segment.type === "page" && segment.page !== undefined) {
|
106
|
+
setPage(segment.page);
|
107
|
+
}
|
108
|
+
}}
|
109
|
+
>
|
110
|
+
{segment.type === "page" ? segment.page! + 1 : "..."}
|
111
|
+
</a>
|
112
|
+
</li>
|
113
|
+
))}
|
114
|
+
<li
|
115
|
+
className={clsx(
|
116
|
+
currentPage + 1 >= pageCount ? "disabled" : "",
|
117
|
+
styles.item,
|
118
|
+
)}
|
119
|
+
>
|
120
|
+
<a
|
121
|
+
className={clsx("page-link")}
|
122
|
+
onClick={() => {
|
123
|
+
if (currentPage < pageCount) {
|
124
|
+
setPage(currentPage + 1);
|
125
|
+
}
|
126
|
+
}}
|
127
|
+
>
|
128
|
+
<i className={clsx(ApplicationIcons.navbar.forward)} />
|
129
|
+
</a>
|
130
|
+
</li>
|
131
|
+
</ul>
|
132
|
+
</nav>
|
133
|
+
);
|
134
|
+
};
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { FC, useCallback } from "react";
|
2
|
+
|
3
|
+
import clsx from "clsx";
|
4
|
+
import { TextInput } from "../../components/TextInput";
|
5
|
+
import { useLogsListing } from "../../state/hooks";
|
6
|
+
import { ApplicationIcons } from "../appearance/icons";
|
7
|
+
import styles from "./LogsFilterInput.module.css";
|
8
|
+
|
9
|
+
export interface LogsToolbarProps {}
|
10
|
+
|
11
|
+
export const LogsFilterInput: FC<LogsToolbarProps> = () => {
|
12
|
+
const { globalFilter, setGlobalFilter } = useLogsListing();
|
13
|
+
const debouncedUpdate = useCallback(
|
14
|
+
async (value: string) => {
|
15
|
+
setGlobalFilter(value);
|
16
|
+
},
|
17
|
+
[setGlobalFilter],
|
18
|
+
);
|
19
|
+
|
20
|
+
return (
|
21
|
+
<TextInput
|
22
|
+
icon={ApplicationIcons.filter}
|
23
|
+
value={globalFilter || ""}
|
24
|
+
onChange={(e) => {
|
25
|
+
debouncedUpdate(e.target.value);
|
26
|
+
}}
|
27
|
+
placeholder="Filter..."
|
28
|
+
className={clsx(styles.filterInput)}
|
29
|
+
/>
|
30
|
+
);
|
31
|
+
};
|