inspect-ai 0.3.96__py3-none-any.whl → 0.3.98__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/eval.py +10 -2
- inspect_ai/_eval/run.py +6 -1
- inspect_ai/_eval/task/util.py +32 -3
- inspect_ai/_util/registry.py +7 -0
- inspect_ai/_util/timer.py +13 -0
- inspect_ai/_view/www/dist/assets/index.css +275 -195
- inspect_ai/_view/www/dist/assets/index.js +8568 -7376
- inspect_ai/_view/www/src/app/App.css +1 -0
- inspect_ai/_view/www/src/app/App.tsx +27 -10
- inspect_ai/_view/www/src/app/appearance/icons.ts +5 -0
- inspect_ai/_view/www/src/app/content/RecordTree.module.css +22 -0
- inspect_ai/_view/www/src/app/content/RecordTree.tsx +370 -0
- inspect_ai/_view/www/src/app/content/RenderedContent.module.css +5 -0
- inspect_ai/_view/www/src/app/content/RenderedContent.tsx +32 -19
- inspect_ai/_view/www/src/app/content/record_processors/store.ts +101 -0
- inspect_ai/_view/www/src/app/content/record_processors/types.ts +3 -0
- inspect_ai/_view/www/src/app/content/types.ts +5 -0
- inspect_ai/_view/www/src/app/log-view/LogView.tsx +1 -0
- inspect_ai/_view/www/src/app/log-view/LogViewContainer.tsx +35 -28
- inspect_ai/_view/www/src/app/log-view/LogViewLayout.tsx +1 -8
- inspect_ai/_view/www/src/app/log-view/navbar/PrimaryBar.tsx +2 -4
- inspect_ai/_view/www/src/app/log-view/navbar/ResultsPanel.tsx +13 -3
- inspect_ai/_view/www/src/app/log-view/navbar/ScoreGrid.module.css +15 -0
- inspect_ai/_view/www/src/app/log-view/navbar/ScoreGrid.tsx +14 -10
- inspect_ai/_view/www/src/app/log-view/tabs/InfoTab.tsx +9 -3
- inspect_ai/_view/www/src/app/log-view/tabs/JsonTab.tsx +1 -3
- inspect_ai/_view/www/src/app/log-view/tabs/SamplesTab.tsx +8 -2
- inspect_ai/_view/www/src/app/log-view/types.ts +1 -0
- inspect_ai/_view/www/src/app/plan/ModelCard.module.css +7 -0
- inspect_ai/_view/www/src/app/plan/ModelCard.tsx +5 -2
- inspect_ai/_view/www/src/app/plan/PlanCard.tsx +13 -8
- inspect_ai/_view/www/src/app/routing/navigationHooks.ts +63 -8
- inspect_ai/_view/www/src/app/routing/url.ts +45 -0
- inspect_ai/_view/www/src/app/samples/InlineSampleDisplay.module.css +2 -1
- inspect_ai/_view/www/src/app/samples/InlineSampleDisplay.tsx +15 -8
- inspect_ai/_view/www/src/app/samples/SampleDialog.module.css +3 -0
- inspect_ai/_view/www/src/app/samples/SampleDialog.tsx +16 -5
- inspect_ai/_view/www/src/app/samples/SampleDisplay.module.css +9 -1
- inspect_ai/_view/www/src/app/samples/SampleDisplay.tsx +68 -31
- inspect_ai/_view/www/src/app/samples/chat/ChatMessage.module.css +12 -7
- inspect_ai/_view/www/src/app/samples/chat/ChatMessage.tsx +17 -5
- inspect_ai/_view/www/src/app/samples/chat/ChatMessageRow.module.css +9 -0
- inspect_ai/_view/www/src/app/samples/chat/ChatMessageRow.tsx +48 -18
- inspect_ai/_view/www/src/app/samples/chat/ChatView.tsx +0 -1
- inspect_ai/_view/www/src/app/samples/chat/ChatViewVirtualList.module.css +4 -0
- inspect_ai/_view/www/src/app/samples/chat/ChatViewVirtualList.tsx +41 -1
- inspect_ai/_view/www/src/app/samples/chat/messages.ts +7 -0
- inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.module.css +0 -3
- inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/chat/tools/ToolInput.module.css +1 -1
- inspect_ai/_view/www/src/app/samples/chat/tools/ToolOutput.module.css +1 -1
- inspect_ai/_view/www/src/app/samples/descriptor/score/NumericScoreDescriptor.tsx +5 -1
- inspect_ai/_view/www/src/app/samples/descriptor/score/PassFailScoreDescriptor.tsx +11 -6
- inspect_ai/_view/www/src/app/samples/list/SampleList.tsx +7 -0
- inspect_ai/_view/www/src/app/samples/list/SampleRow.tsx +5 -18
- inspect_ai/_view/www/src/app/samples/sample-tools/SortFilter.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/scores/SampleScoresGrid.tsx +18 -5
- inspect_ai/_view/www/src/app/samples/scores/SampleScoresView.module.css +0 -6
- inspect_ai/_view/www/src/app/samples/scores/SampleScoresView.tsx +4 -1
- inspect_ai/_view/www/src/app/samples/transcript/ApprovalEventView.tsx +4 -2
- inspect_ai/_view/www/src/app/samples/transcript/ErrorEventView.tsx +6 -4
- inspect_ai/_view/www/src/app/samples/transcript/InfoEventView.module.css +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/InfoEventView.tsx +13 -6
- inspect_ai/_view/www/src/app/samples/transcript/InputEventView.tsx +6 -4
- inspect_ai/_view/www/src/app/samples/transcript/LoggerEventView.tsx +4 -2
- inspect_ai/_view/www/src/app/samples/transcript/ModelEventView.tsx +11 -8
- inspect_ai/_view/www/src/app/samples/transcript/SampleInitEventView.tsx +14 -8
- inspect_ai/_view/www/src/app/samples/transcript/SampleLimitEventView.tsx +13 -8
- inspect_ai/_view/www/src/app/samples/transcript/SandboxEventView.tsx +25 -16
- inspect_ai/_view/www/src/app/samples/transcript/ScoreEventView.tsx +7 -5
- inspect_ai/_view/www/src/app/samples/transcript/SpanEventView.tsx +11 -28
- inspect_ai/_view/www/src/app/samples/transcript/StepEventView.tsx +12 -20
- inspect_ai/_view/www/src/app/samples/transcript/SubtaskEventView.tsx +12 -31
- inspect_ai/_view/www/src/app/samples/transcript/ToolEventView.tsx +25 -29
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualList.tsx +297 -0
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.module.css +0 -8
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.tsx +43 -25
- inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.module.css +43 -0
- inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.tsx +109 -43
- inspect_ai/_view/www/src/app/samples/transcript/state/StateEventView.tsx +19 -8
- inspect_ai/_view/www/src/app/samples/transcript/transform/treeify.ts +128 -60
- inspect_ai/_view/www/src/app/samples/transcript/transform/utils.ts +14 -4
- inspect_ai/_view/www/src/app/samples/transcript/types.ts +6 -4
- inspect_ai/_view/www/src/app/types.ts +12 -1
- inspect_ai/_view/www/src/components/Card.css +6 -3
- inspect_ai/_view/www/src/components/Card.tsx +15 -2
- inspect_ai/_view/www/src/components/CopyButton.tsx +4 -6
- inspect_ai/_view/www/src/components/ExpandablePanel.module.css +20 -14
- inspect_ai/_view/www/src/components/ExpandablePanel.tsx +17 -22
- inspect_ai/_view/www/src/components/LargeModal.tsx +5 -1
- inspect_ai/_view/www/src/components/LiveVirtualList.tsx +25 -1
- inspect_ai/_view/www/src/components/MarkdownDiv.css +4 -0
- inspect_ai/_view/www/src/components/MarkdownDiv.tsx +2 -2
- inspect_ai/_view/www/src/components/TabSet.module.css +6 -1
- inspect_ai/_view/www/src/components/TabSet.tsx +8 -2
- inspect_ai/_view/www/src/state/hooks.ts +83 -13
- inspect_ai/_view/www/src/state/logPolling.ts +2 -2
- inspect_ai/_view/www/src/state/logSlice.ts +1 -2
- inspect_ai/_view/www/src/state/logsSlice.ts +9 -9
- inspect_ai/_view/www/src/state/samplePolling.ts +1 -1
- inspect_ai/_view/www/src/state/sampleSlice.ts +134 -7
- inspect_ai/_view/www/src/state/scoring.ts +1 -1
- inspect_ai/_view/www/src/state/scrolling.ts +39 -6
- inspect_ai/_view/www/src/state/store.ts +5 -0
- inspect_ai/_view/www/src/state/store_filter.ts +47 -44
- inspect_ai/_view/www/src/utils/debugging.ts +95 -0
- inspect_ai/_view/www/src/utils/format.ts +2 -2
- inspect_ai/_view/www/src/utils/json.ts +29 -0
- inspect_ai/agent/__init__.py +2 -1
- inspect_ai/agent/_agent.py +12 -0
- inspect_ai/agent/_react.py +184 -48
- inspect_ai/agent/_types.py +14 -1
- inspect_ai/analysis/beta/__init__.py +0 -2
- inspect_ai/analysis/beta/_dataframe/columns.py +11 -16
- inspect_ai/analysis/beta/_dataframe/evals/table.py +65 -40
- inspect_ai/analysis/beta/_dataframe/events/table.py +24 -36
- inspect_ai/analysis/beta/_dataframe/messages/table.py +24 -15
- inspect_ai/analysis/beta/_dataframe/progress.py +35 -5
- inspect_ai/analysis/beta/_dataframe/record.py +13 -9
- inspect_ai/analysis/beta/_dataframe/samples/columns.py +1 -1
- inspect_ai/analysis/beta/_dataframe/samples/table.py +156 -46
- inspect_ai/analysis/beta/_dataframe/util.py +14 -12
- inspect_ai/dataset/_dataset.py +0 -1
- inspect_ai/model/_call_tools.py +1 -1
- inspect_ai/model/_providers/anthropic.py +18 -5
- inspect_ai/model/_providers/azureai.py +7 -2
- inspect_ai/model/_providers/google.py +6 -0
- inspect_ai/model/_providers/util/llama31.py +3 -3
- {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.98.dist-info}/METADATA +2 -2
- {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.98.dist-info}/RECORD +134 -129
- {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.98.dist-info}/WHEEL +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptView.module.css +0 -48
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptView.tsx +0 -276
- {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.98.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.98.dist-info}/licenses/LICENSE +0 -0
- {inspect_ai-0.3.96.dist-info → inspect_ai-0.3.98.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@
|
|
5
5
|
padding: 0.5em 0.5em 0.5em 0.5em;
|
6
6
|
font-size: var(--inspect-font-size-small);
|
7
7
|
font-weight: 600;
|
8
|
+
border-bottom: solid 1px var(--bs-light-border-subtle);
|
8
9
|
}
|
9
10
|
|
10
11
|
.card-header-icon {
|
@@ -13,9 +14,7 @@
|
|
13
14
|
|
14
15
|
.card-body {
|
15
16
|
background-color: var(--bs-body-bg);
|
16
|
-
|
17
|
-
border-radius: var(--bs-border-radius);
|
18
|
-
margin: 0 8px 8px 8px;
|
17
|
+
|
19
18
|
padding: 0.5em;
|
20
19
|
}
|
21
20
|
|
@@ -57,3 +56,7 @@
|
|
57
56
|
padding: 0 0.5em 0.1em 0.5em;
|
58
57
|
font-size: var(--inspect-font-size-smaller);
|
59
58
|
}
|
59
|
+
|
60
|
+
.card-body.card-no-padding {
|
61
|
+
padding: 0;
|
62
|
+
}
|
@@ -15,6 +15,7 @@ interface CardBodyProps {
|
|
15
15
|
id?: string;
|
16
16
|
children?: ReactNode;
|
17
17
|
className?: string | string[];
|
18
|
+
padded?: boolean;
|
18
19
|
}
|
19
20
|
|
20
21
|
interface CardProps {
|
@@ -53,9 +54,21 @@ export const CardHeader: FC<CardHeaderProps> = ({
|
|
53
54
|
);
|
54
55
|
};
|
55
56
|
|
56
|
-
export const CardBody: FC<CardBodyProps> = ({
|
57
|
+
export const CardBody: FC<CardBodyProps> = ({
|
58
|
+
id,
|
59
|
+
children,
|
60
|
+
className,
|
61
|
+
padded = true,
|
62
|
+
}) => {
|
57
63
|
return (
|
58
|
-
<div
|
64
|
+
<div
|
65
|
+
className={clsx(
|
66
|
+
"card-body",
|
67
|
+
className,
|
68
|
+
!padded ? "card-no-padding" : undefined,
|
69
|
+
)}
|
70
|
+
id={id || ""}
|
71
|
+
>
|
59
72
|
{children}
|
60
73
|
</div>
|
61
74
|
);
|
@@ -4,6 +4,7 @@ import { ApplicationIcons } from "../app/appearance/icons";
|
|
4
4
|
import styles from "./CopyButton.module.css";
|
5
5
|
|
6
6
|
interface CopyButtonProps {
|
7
|
+
icon?: string;
|
7
8
|
value: string;
|
8
9
|
onCopySuccess?: () => void;
|
9
10
|
onCopyError?: (error: Error) => void;
|
@@ -12,6 +13,7 @@ interface CopyButtonProps {
|
|
12
13
|
}
|
13
14
|
|
14
15
|
export const CopyButton = ({
|
16
|
+
icon = ApplicationIcons.copy,
|
15
17
|
value,
|
16
18
|
onCopySuccess,
|
17
19
|
onCopyError,
|
@@ -40,17 +42,13 @@ export const CopyButton = ({
|
|
40
42
|
return (
|
41
43
|
<button
|
42
44
|
type="button"
|
43
|
-
className={clsx(styles.copyButton, className)}
|
45
|
+
className={clsx("copy-button", styles.copyButton, className)}
|
44
46
|
onClick={handleClick}
|
45
47
|
aria-label={ariaLabel}
|
46
48
|
disabled={isCopied}
|
47
49
|
>
|
48
50
|
<i
|
49
|
-
className={
|
50
|
-
isCopied
|
51
|
-
? `${ApplicationIcons.confirm} primary`
|
52
|
-
: ApplicationIcons.copy
|
53
|
-
}
|
51
|
+
className={isCopied ? `${ApplicationIcons.confirm} primary` : icon}
|
54
52
|
aria-hidden="true"
|
55
53
|
/>
|
56
54
|
</button>
|
@@ -1,5 +1,10 @@
|
|
1
|
+
.expandablePanel {
|
2
|
+
position: relative;
|
3
|
+
}
|
4
|
+
|
1
5
|
.expandableBordered {
|
2
6
|
border: solid var(--bs-light-border-subtle) 1px;
|
7
|
+
padding: 0.5em;
|
3
8
|
}
|
4
9
|
|
5
10
|
.expandableTogglable {
|
@@ -17,27 +22,28 @@
|
|
17
22
|
.moreToggle {
|
18
23
|
display: flex;
|
19
24
|
margin-top: 0;
|
20
|
-
position:
|
21
|
-
|
25
|
+
position: absolute;
|
26
|
+
bottom: 0.25em;
|
27
|
+
right: 0.25em;
|
28
|
+
height: 20px;
|
29
|
+
background-color: var(--bs-body-bg);
|
30
|
+
border-radius: 5px;
|
31
|
+
border: solid var(--bs-light-border-subtle) 1px;
|
32
|
+
color: var(--bs-link-color);
|
22
33
|
}
|
23
34
|
|
24
35
|
.moreToggle.bordered {
|
25
36
|
border-top: solid var(--bs-light-border-subtle) 1px;
|
26
37
|
}
|
27
38
|
|
28
|
-
.moreToggleContainer {
|
29
|
-
position: absolute;
|
30
|
-
top: -1px;
|
31
|
-
right: 0;
|
32
|
-
display: inline-block;
|
33
|
-
border: solid var(--bs-light-border-subtle) 1px;
|
34
|
-
border-top: none;
|
35
|
-
margin-left: auto;
|
36
|
-
margin-right: 0;
|
37
|
-
}
|
38
|
-
|
39
39
|
.moreToggleButton {
|
40
40
|
font-size: var(--inspect-font-size-smaller);
|
41
41
|
border: none;
|
42
|
-
padding:
|
42
|
+
padding: 0rem 0.5rem;
|
43
|
+
}
|
44
|
+
|
45
|
+
.separator {
|
46
|
+
height: 1px;
|
47
|
+
background-color: var(--bs-light-border-subtle);
|
48
|
+
margin-top: -1px;
|
43
49
|
}
|
@@ -8,7 +8,6 @@ import {
|
|
8
8
|
useRef,
|
9
9
|
useState,
|
10
10
|
} from "react";
|
11
|
-
import { ApplicationIcons } from "../app/appearance/icons";
|
12
11
|
import { useCollapsedState } from "../state/hooks";
|
13
12
|
import { useResizeObserver } from "../utils/dom";
|
14
13
|
import styles from "./ExpandablePanel.module.css";
|
@@ -64,18 +63,21 @@ export const ExpandablePanel: FC<ExpandablePanelProps> = memo(
|
|
64
63
|
styles.expandablePanel,
|
65
64
|
collapsed ? styles.expandableCollapsed : undefined,
|
66
65
|
border ? styles.expandableBordered : undefined,
|
66
|
+
showToggle ? styles.padBottom : undefined,
|
67
67
|
)}
|
68
68
|
>
|
69
69
|
{children}
|
70
|
+
{showToggle && (
|
71
|
+
<>
|
72
|
+
<MoreToggle
|
73
|
+
collapsed={collapsed}
|
74
|
+
setCollapsed={setCollapsed}
|
75
|
+
border={!border}
|
76
|
+
/>
|
77
|
+
</>
|
78
|
+
)}
|
70
79
|
</div>
|
71
|
-
|
72
|
-
{showToggle && (
|
73
|
-
<MoreToggle
|
74
|
-
collapsed={collapsed}
|
75
|
-
setCollapsed={setCollapsed}
|
76
|
-
border={!border}
|
77
|
-
/>
|
78
|
-
)}
|
80
|
+
{showToggle && <div className={clsx(styles.separator)}></div>}
|
79
81
|
</div>
|
80
82
|
);
|
81
83
|
},
|
@@ -95,10 +97,6 @@ const MoreToggle: FC<MoreToggleProps> = ({
|
|
95
97
|
style,
|
96
98
|
}) => {
|
97
99
|
const text = collapsed ? "more" : "less";
|
98
|
-
const icon = collapsed
|
99
|
-
? ApplicationIcons["expand-down"]
|
100
|
-
: ApplicationIcons.collapse.up;
|
101
|
-
|
102
100
|
const handleClick = useCallback(() => {
|
103
101
|
setCollapsed(!collapsed);
|
104
102
|
}, [setCollapsed, collapsed]);
|
@@ -108,15 +106,12 @@ const MoreToggle: FC<MoreToggleProps> = ({
|
|
108
106
|
className={clsx(styles.moreToggle, border ? styles.bordered : undefined)}
|
109
107
|
style={style}
|
110
108
|
>
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
{text}
|
118
|
-
</button>
|
119
|
-
</div>
|
109
|
+
<button
|
110
|
+
className={clsx("btn", styles.moreToggleButton, "text-size-smallest")}
|
111
|
+
onClick={handleClick}
|
112
|
+
>
|
113
|
+
{text}...
|
114
|
+
</button>
|
120
115
|
</div>
|
121
116
|
);
|
122
117
|
};
|
@@ -28,6 +28,9 @@ interface LargeModalProps {
|
|
28
28
|
onHide: () => void;
|
29
29
|
scrollRef: RefObject<HTMLDivElement | null>;
|
30
30
|
children: ReactNode;
|
31
|
+
classNames?: {
|
32
|
+
body?: string | string[];
|
33
|
+
};
|
31
34
|
}
|
32
35
|
|
33
36
|
export const LargeModal: FC<LargeModalProps> = ({
|
@@ -42,6 +45,7 @@ export const LargeModal: FC<LargeModalProps> = ({
|
|
42
45
|
onHide,
|
43
46
|
showProgress,
|
44
47
|
scrollRef,
|
48
|
+
classNames,
|
45
49
|
}) => {
|
46
50
|
// The footer
|
47
51
|
const modalFooter = footer ? (
|
@@ -127,7 +131,7 @@ export const LargeModal: FC<LargeModalProps> = ({
|
|
127
131
|
</button>
|
128
132
|
</div>
|
129
133
|
<ProgressBar animating={showProgress} />
|
130
|
-
<div className={"modal-body"} ref={scrollRef}>
|
134
|
+
<div className={clsx("modal-body", classNames?.body)} ref={scrollRef}>
|
131
135
|
{children}
|
132
136
|
</div>
|
133
137
|
{modalFooter}
|
@@ -7,7 +7,7 @@ import {
|
|
7
7
|
useRef,
|
8
8
|
useState,
|
9
9
|
} from "react";
|
10
|
-
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
10
|
+
import { Components, Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
11
11
|
import { usePrevious, useProperty } from "../state/hooks";
|
12
12
|
import { useRafThrottle, useVirtuosoState } from "../state/scrolling";
|
13
13
|
import { PulsingDots } from "./PulsingDots";
|
@@ -32,6 +32,11 @@ interface LiveVirtualListProps<T> {
|
|
32
32
|
// The progress message to show (if any)
|
33
33
|
// no message show if progress isn't provided
|
34
34
|
showProgress?: boolean;
|
35
|
+
|
36
|
+
// The initial index to scroll to when loading
|
37
|
+
initialTopMostItemIndex?: number;
|
38
|
+
|
39
|
+
components?: Components<T>;
|
35
40
|
}
|
36
41
|
|
37
42
|
/**
|
@@ -45,6 +50,8 @@ export const LiveVirtualList = <T,>({
|
|
45
50
|
scrollRef,
|
46
51
|
live,
|
47
52
|
showProgress,
|
53
|
+
initialTopMostItemIndex,
|
54
|
+
components,
|
48
55
|
}: LiveVirtualListProps<T>) => {
|
49
56
|
// The list handle and list state management
|
50
57
|
const listHandle = useRef<VirtuosoHandle>(null);
|
@@ -155,6 +162,22 @@ export const LiveVirtualList = <T,>({
|
|
155
162
|
}
|
156
163
|
}, [scrollRef, handleScroll]);
|
157
164
|
|
165
|
+
// Scroll to index when component mounts or targetIndex changes
|
166
|
+
useEffect(() => {
|
167
|
+
if (initialTopMostItemIndex !== undefined && listHandle.current) {
|
168
|
+
// If there is an initial index, scroll to it after a short delay
|
169
|
+
const timer = setTimeout(() => {
|
170
|
+
listHandle.current?.scrollToIndex({
|
171
|
+
index: initialTopMostItemIndex,
|
172
|
+
align: "start",
|
173
|
+
behavior: "auto",
|
174
|
+
});
|
175
|
+
}, 50);
|
176
|
+
|
177
|
+
return () => clearTimeout(timer);
|
178
|
+
}
|
179
|
+
}, [initialTopMostItemIndex]);
|
180
|
+
|
158
181
|
return (
|
159
182
|
<Virtuoso
|
160
183
|
ref={listHandle}
|
@@ -171,6 +194,7 @@ export const LiveVirtualList = <T,>({
|
|
171
194
|
totalListHeightChanged={heightChanged}
|
172
195
|
components={{
|
173
196
|
Footer,
|
197
|
+
...components,
|
174
198
|
}}
|
175
199
|
/>
|
176
200
|
);
|
@@ -59,13 +59,13 @@ export const MarkdownDiv = forwardRef<HTMLDivElement, MarkdownDivProps>(
|
|
59
59
|
ref={ref}
|
60
60
|
dangerouslySetInnerHTML={markup}
|
61
61
|
style={style}
|
62
|
-
className={clsx(className, "markdown-content")}
|
62
|
+
className={clsx(className, "markdown-content", "text-size-base")}
|
63
63
|
/>
|
64
64
|
);
|
65
65
|
},
|
66
66
|
);
|
67
67
|
|
68
|
-
const kLetterListPattern = /^([a-zA-
|
68
|
+
const kLetterListPattern = /^([a-zA-Z0-9][).]\s.*?)$/gm;
|
69
69
|
const kCommonmarkReferenceLinkPattern = /\[([^\]]*)\]: (?!http)(.*)/g;
|
70
70
|
|
71
71
|
const protectBackslashesInLatex = (content: string): string => {
|
@@ -56,7 +56,13 @@ export const TabSet: FC<TabSetProps> = ({
|
|
56
56
|
<Fragment>
|
57
57
|
<ul
|
58
58
|
id={id}
|
59
|
-
className={clsx(
|
59
|
+
className={clsx(
|
60
|
+
"nav",
|
61
|
+
`nav-${type}`,
|
62
|
+
type === "tabs" ? moduleStyles.tabStyle : undefined,
|
63
|
+
className,
|
64
|
+
moduleStyles.tabs,
|
65
|
+
)}
|
60
66
|
role="tablist"
|
61
67
|
aria-orientation="horizontal"
|
62
68
|
>
|
@@ -157,7 +163,7 @@ export const TabPanel: FC<TabPanelProps> = ({
|
|
157
163
|
)}
|
158
164
|
style={style}
|
159
165
|
>
|
160
|
-
{children}
|
166
|
+
{selected ? children : null}
|
161
167
|
</div>
|
162
168
|
);
|
163
169
|
};
|
@@ -226,25 +226,38 @@ export const useSelectedSampleSummary = (): SampleSummary | undefined => {
|
|
226
226
|
export const useSampleData = () => {
|
227
227
|
const sampleStatus = useStore((state) => state.sample.sampleStatus);
|
228
228
|
const sampleError = useStore((state) => state.sample.sampleError);
|
229
|
-
const
|
229
|
+
const getSelectedSample = useStore(
|
230
|
+
(state) => state.sampleActions.getSelectedSample,
|
231
|
+
);
|
232
|
+
const selectedSampleIdentifier = useStore(
|
233
|
+
(state) => state.sample.sample_identifier,
|
234
|
+
);
|
235
|
+
const sampleNeedsReload = useStore((state) => state.sample.sampleNeedsReload);
|
230
236
|
const runningEvents = useStore(
|
231
237
|
(state) => state.sample.runningEvents,
|
232
238
|
) as Events;
|
233
239
|
return useMemo(() => {
|
234
240
|
return {
|
241
|
+
selectedSampleIdentifier,
|
235
242
|
status: sampleStatus,
|
243
|
+
sampleNeedsReload,
|
236
244
|
error: sampleError,
|
237
|
-
|
245
|
+
getSelectedSample,
|
238
246
|
running: runningEvents,
|
239
247
|
};
|
240
|
-
}, [
|
248
|
+
}, [
|
249
|
+
sampleStatus,
|
250
|
+
sampleError,
|
251
|
+
getSelectedSample,
|
252
|
+
selectedSampleIdentifier,
|
253
|
+
sampleNeedsReload,
|
254
|
+
runningEvents,
|
255
|
+
]);
|
241
256
|
};
|
242
257
|
|
243
258
|
export const useLogSelection = () => {
|
244
259
|
const selectedSampleSummary = useSelectedSampleSummary();
|
245
|
-
const selectedLogFile = useStore((state) =>
|
246
|
-
state.logsActions.getSelectedLogFile(),
|
247
|
-
);
|
260
|
+
const selectedLogFile = useStore((state) => state.logs.selectedLogFile);
|
248
261
|
const loadedLog = useStore((state) => state.log.loadedLog);
|
249
262
|
|
250
263
|
return useMemo(() => {
|
@@ -256,18 +269,68 @@ export const useLogSelection = () => {
|
|
256
269
|
}, [selectedLogFile, selectedSampleSummary]);
|
257
270
|
};
|
258
271
|
|
272
|
+
export const useCollapseSampleEvent = (
|
273
|
+
id: string,
|
274
|
+
): [boolean, (collapsed: boolean) => void] => {
|
275
|
+
const collapsed = useStore((state) => state.sample.collapsedEvents);
|
276
|
+
const collapseEvent = useStore((state) => state.sampleActions.collapseEvent);
|
277
|
+
|
278
|
+
return useMemo(() => {
|
279
|
+
const isCollapsed = collapsed !== null && collapsed[id] === true;
|
280
|
+
const set = (value: boolean) => {
|
281
|
+
log.debug("Set collapsed", id, value);
|
282
|
+
collapseEvent(id, value);
|
283
|
+
};
|
284
|
+
return [isCollapsed, set];
|
285
|
+
}, [collapsed, collapseEvent, id]);
|
286
|
+
};
|
287
|
+
|
288
|
+
export const useCollapsibleIds = (
|
289
|
+
key: string,
|
290
|
+
): [
|
291
|
+
Record<string, boolean>,
|
292
|
+
(id: string, value: boolean) => void,
|
293
|
+
() => void,
|
294
|
+
] => {
|
295
|
+
const collapsedIds = useStore(
|
296
|
+
(state) => state.sample.collapsedIdBuckets[key],
|
297
|
+
);
|
298
|
+
|
299
|
+
const setCollapsed = useStore((state) => state.sampleActions.collapseId);
|
300
|
+
const collapseId = useCallback(
|
301
|
+
(id: string, value: boolean) => {
|
302
|
+
setCollapsed(key, id, value);
|
303
|
+
},
|
304
|
+
[setCollapsed],
|
305
|
+
);
|
306
|
+
|
307
|
+
const clearCollapsedIds = useStore(
|
308
|
+
(state) => state.sampleActions.clearCollapsedIds,
|
309
|
+
);
|
310
|
+
const clearIds = useCallback(() => {
|
311
|
+
clearCollapsedIds(key);
|
312
|
+
}, [clearCollapsedIds, key]);
|
313
|
+
|
314
|
+
return useMemo(() => {
|
315
|
+
return [collapsedIds, collapseId, clearIds];
|
316
|
+
}, [collapsedIds, collapseId, clearIds]);
|
317
|
+
};
|
318
|
+
|
259
319
|
export const useCollapsedState = (
|
260
320
|
id: string,
|
261
321
|
defaultValue?: boolean,
|
322
|
+
scope?: string,
|
262
323
|
): [boolean, (value: boolean) => void] => {
|
324
|
+
const stateId = scope ? `${scope}-${id}` : id;
|
325
|
+
|
263
326
|
const collapsed = useStore((state) =>
|
264
|
-
state.appActions.getCollapsed(
|
327
|
+
state.appActions.getCollapsed(stateId, defaultValue),
|
265
328
|
);
|
266
329
|
const setCollapsed = useStore((state) => state.appActions.setCollapsed);
|
267
330
|
return useMemo(() => {
|
268
331
|
const set = (value: boolean) => {
|
269
|
-
log.debug("Set collapsed", id, value);
|
270
|
-
setCollapsed(
|
332
|
+
log.debug("Set collapsed", id, scope, value);
|
333
|
+
setCollapsed(stateId, value);
|
271
334
|
};
|
272
335
|
return [collapsed, set];
|
273
336
|
}, [collapsed, setCollapsed]);
|
@@ -289,9 +352,7 @@ export const useMessageVisibility = (
|
|
289
352
|
const isFirstRender = useRef(true);
|
290
353
|
|
291
354
|
// Reset state if the eval changes, but not during initialization
|
292
|
-
const selectedLogFile = useStore((state) =>
|
293
|
-
state.logsActions.getSelectedLogFile(),
|
294
|
-
);
|
355
|
+
const selectedLogFile = useStore((state) => state.logs.selectedLogFile);
|
295
356
|
useEffect(() => {
|
296
357
|
// Skip the first effect run
|
297
358
|
if (isFirstRender.current) {
|
@@ -426,13 +487,22 @@ export const useSetSelectedLogIndex = () => {
|
|
426
487
|
const clearSelectedLogSummary = useStore(
|
427
488
|
(state) => state.logActions.clearSelectedLogSummary,
|
428
489
|
);
|
490
|
+
const clearCollapsedEvents = useStore(
|
491
|
+
(state) => state.sampleActions.clearCollapsedEvents,
|
492
|
+
);
|
429
493
|
|
430
494
|
return useCallback(
|
431
495
|
(index: number) => {
|
496
|
+
clearCollapsedEvents();
|
432
497
|
clearSelectedSample();
|
433
498
|
clearSelectedLogSummary();
|
434
499
|
setSelectedLogIndex(index);
|
435
500
|
},
|
436
|
-
[
|
501
|
+
[
|
502
|
+
setSelectedLogIndex,
|
503
|
+
clearSelectedLogSummary,
|
504
|
+
clearSelectedSample,
|
505
|
+
clearCollapsedEvents,
|
506
|
+
],
|
437
507
|
);
|
438
508
|
};
|
@@ -26,7 +26,7 @@ export function createLogPolling(
|
|
26
26
|
|
27
27
|
const state = get();
|
28
28
|
const api = state.api;
|
29
|
-
const selectedLogFile = state.
|
29
|
+
const selectedLogFile = state.logs.selectedLogFile;
|
30
30
|
|
31
31
|
if (!api || !selectedLogFile) {
|
32
32
|
return false;
|
@@ -195,6 +195,6 @@ export function createLogPolling(
|
|
195
195
|
cleanup,
|
196
196
|
// Expose the refresh function so components can use it directly
|
197
197
|
refreshLog: (clearPending = false) =>
|
198
|
-
refreshLog(get().
|
198
|
+
refreshLog(get().logs.selectedLogFile || "", clearPending),
|
199
199
|
};
|
200
200
|
}
|
@@ -169,7 +169,6 @@ export const createLogSlice = (
|
|
169
169
|
try {
|
170
170
|
const logContents = await api.get_log_summary(logFileName);
|
171
171
|
state.logActions.setSelectedLogSummary(logContents);
|
172
|
-
state.logActions.setEpoch;
|
173
172
|
|
174
173
|
// Push the updated header information up
|
175
174
|
const header = {
|
@@ -207,7 +206,7 @@ export const createLogSlice = (
|
|
207
206
|
refreshLog: async () => {
|
208
207
|
const state = get();
|
209
208
|
const api = state.api;
|
210
|
-
const selectedLogFile = state.
|
209
|
+
const selectedLogFile = state.logs.selectedLogFile;
|
211
210
|
|
212
211
|
if (!api || !selectedLogFile) {
|
213
212
|
return;
|
@@ -26,9 +26,6 @@ export interface LogsSlice {
|
|
26
26
|
refreshLogs: () => Promise<void>;
|
27
27
|
selectLogFile: (logUrl: string) => Promise<void>;
|
28
28
|
loadLogs: () => Promise<LogFiles>;
|
29
|
-
|
30
|
-
// Computed values
|
31
|
-
getSelectedLogFile: () => string | undefined;
|
32
29
|
};
|
33
30
|
}
|
34
31
|
|
@@ -37,6 +34,7 @@ const initialState: LogsState = {
|
|
37
34
|
logHeaders: {},
|
38
35
|
headersLoading: false,
|
39
36
|
selectedLogIndex: -1,
|
37
|
+
selectedLogFile: undefined as string | undefined,
|
40
38
|
};
|
41
39
|
|
42
40
|
export const createLogsSlice = (
|
@@ -55,6 +53,10 @@ export const createLogsSlice = (
|
|
55
53
|
setLogs: (logs: LogFiles) => {
|
56
54
|
set((state) => {
|
57
55
|
state.logs.logs = logs;
|
56
|
+
state.logs.selectedLogFile =
|
57
|
+
state.logs.selectedLogIndex > -1
|
58
|
+
? logs.files[state.logs.selectedLogIndex]?.name
|
59
|
+
: undefined;
|
58
60
|
});
|
59
61
|
|
60
62
|
// If we have files in the logs, load the headers
|
@@ -79,6 +81,8 @@ export const createLogsSlice = (
|
|
79
81
|
setSelectedLogIndex: (selectedLogIndex: number) => {
|
80
82
|
set((state) => {
|
81
83
|
state.logs.selectedLogIndex = selectedLogIndex;
|
84
|
+
const file = state.logs.logs.files[selectedLogIndex];
|
85
|
+
state.logs.selectedLogFile = file ? file.name : undefined;
|
82
86
|
});
|
83
87
|
},
|
84
88
|
updateLogHeaders: (headers: Record<string, EvalLogHeader>) =>
|
@@ -94,6 +98,8 @@ export const createLogsSlice = (
|
|
94
98
|
|
95
99
|
if (index > -1) {
|
96
100
|
state.logsActions.setSelectedLogIndex(index);
|
101
|
+
state.logs.selectedLogFile =
|
102
|
+
state.logs.logs.files[index]?.name ?? undefined;
|
97
103
|
}
|
98
104
|
},
|
99
105
|
|
@@ -161,12 +167,6 @@ export const createLogsSlice = (
|
|
161
167
|
);
|
162
168
|
}
|
163
169
|
},
|
164
|
-
|
165
|
-
getSelectedLogFile: () => {
|
166
|
-
const state = get();
|
167
|
-
const file = state.logs.logs.files[state.logs.selectedLogIndex];
|
168
|
-
return file !== undefined ? file.name : undefined;
|
169
|
-
},
|
170
170
|
},
|
171
171
|
} as const;
|
172
172
|
|
@@ -140,7 +140,7 @@ export function createSamplePolling(
|
|
140
140
|
|
141
141
|
// Update the store with the completed sample
|
142
142
|
set((state) => {
|
143
|
-
state.
|
143
|
+
state.sampleActions.setSelectedSample(migratedSample);
|
144
144
|
state.sampleActions.setSampleStatus("ok");
|
145
145
|
state.sample.runningEvents = [];
|
146
146
|
});
|