inspect-ai 0.3.81__py3-none-any.whl → 0.3.83__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/__init__.py +2 -1
- inspect_ai/_cli/eval.py +35 -2
- inspect_ai/_cli/util.py +44 -1
- inspect_ai/_display/core/config.py +1 -1
- inspect_ai/_display/core/display.py +13 -4
- inspect_ai/_display/core/results.py +1 -1
- inspect_ai/_display/textual/app.py +14 -3
- inspect_ai/_display/textual/display.py +4 -0
- inspect_ai/_display/textual/widgets/samples.py +9 -3
- inspect_ai/_display/textual/widgets/task_detail.py +8 -8
- inspect_ai/_display/textual/widgets/tasks.py +17 -1
- inspect_ai/_display/textual/widgets/vscode.py +44 -0
- inspect_ai/_eval/eval.py +74 -25
- inspect_ai/_eval/evalset.py +22 -18
- inspect_ai/_eval/loader.py +34 -11
- inspect_ai/_eval/run.py +13 -15
- inspect_ai/_eval/score.py +13 -3
- inspect_ai/_eval/task/generate.py +8 -9
- inspect_ai/_eval/task/log.py +55 -6
- inspect_ai/_eval/task/run.py +51 -10
- inspect_ai/_eval/task/task.py +23 -9
- inspect_ai/_util/constants.py +2 -0
- inspect_ai/_util/file.py +30 -1
- inspect_ai/_util/json.py +37 -1
- inspect_ai/_util/registry.py +1 -0
- inspect_ai/_util/vscode.py +37 -0
- inspect_ai/_view/server.py +113 -1
- inspect_ai/_view/www/App.css +7 -1
- inspect_ai/_view/www/dist/assets/index.css +813 -415
- inspect_ai/_view/www/dist/assets/index.js +54475 -32003
- inspect_ai/_view/www/eslint.config.mjs +1 -1
- inspect_ai/_view/www/log-schema.json +137 -31
- inspect_ai/_view/www/node_modules/flatted/python/flatted.py +149 -0
- inspect_ai/_view/www/package.json +11 -2
- inspect_ai/_view/www/src/App.tsx +161 -853
- inspect_ai/_view/www/src/api/api-browser.ts +176 -5
- inspect_ai/_view/www/src/api/api-vscode.ts +75 -1
- inspect_ai/_view/www/src/api/client-api.ts +66 -10
- inspect_ai/_view/www/src/api/jsonrpc.ts +2 -0
- inspect_ai/_view/www/src/api/types.ts +107 -2
- inspect_ai/_view/www/src/appearance/icons.ts +2 -0
- inspect_ai/_view/www/src/components/AsciinemaPlayer.tsx +3 -3
- inspect_ai/_view/www/src/components/Card.tsx +6 -4
- inspect_ai/_view/www/src/components/DownloadPanel.tsx +2 -2
- inspect_ai/_view/www/src/components/ExpandablePanel.tsx +56 -61
- inspect_ai/_view/www/src/components/FindBand.tsx +17 -9
- inspect_ai/_view/www/src/components/HumanBaselineView.tsx +1 -1
- inspect_ai/_view/www/src/components/JsonPanel.tsx +14 -24
- inspect_ai/_view/www/src/components/LargeModal.tsx +2 -35
- inspect_ai/_view/www/src/components/LightboxCarousel.tsx +27 -11
- inspect_ai/_view/www/src/components/LinkButton.module.css +16 -0
- inspect_ai/_view/www/src/components/LinkButton.tsx +33 -0
- inspect_ai/_view/www/src/components/LiveVirtualList.module.css +11 -0
- inspect_ai/_view/www/src/components/LiveVirtualList.tsx +177 -0
- inspect_ai/_view/www/src/components/MarkdownDiv.tsx +116 -26
- inspect_ai/_view/www/src/components/MessageBand.tsx +14 -9
- inspect_ai/_view/www/src/components/Modal.module.css +38 -0
- inspect_ai/_view/www/src/components/Modal.tsx +77 -0
- inspect_ai/_view/www/src/components/MorePopOver.tsx +3 -3
- inspect_ai/_view/www/src/components/NavPills.tsx +20 -8
- inspect_ai/_view/www/src/components/NoContentsPanel.module.css +12 -0
- inspect_ai/_view/www/src/components/NoContentsPanel.tsx +20 -0
- inspect_ai/_view/www/src/components/ProgressBar.module.css +5 -4
- inspect_ai/_view/www/src/components/ProgressBar.tsx +3 -2
- inspect_ai/_view/www/src/components/PulsingDots.module.css +81 -0
- inspect_ai/_view/www/src/components/PulsingDots.tsx +45 -0
- inspect_ai/_view/www/src/components/TabSet.tsx +4 -37
- inspect_ai/_view/www/src/components/ToolButton.tsx +3 -4
- inspect_ai/_view/www/src/index.tsx +26 -94
- inspect_ai/_view/www/src/logfile/remoteLogFile.ts +9 -1
- inspect_ai/_view/www/src/logfile/remoteZipFile.ts +30 -4
- inspect_ai/_view/www/src/metadata/RenderedContent.tsx +4 -6
- inspect_ai/_view/www/src/plan/DetailStep.module.css +4 -0
- inspect_ai/_view/www/src/plan/DetailStep.tsx +6 -3
- inspect_ai/_view/www/src/plan/ScorerDetailView.tsx +1 -1
- inspect_ai/_view/www/src/plan/SolverDetailView.module.css +2 -1
- inspect_ai/_view/www/src/samples/InlineSampleDisplay.module.css +9 -1
- inspect_ai/_view/www/src/samples/InlineSampleDisplay.tsx +74 -28
- inspect_ai/_view/www/src/samples/SampleDialog.tsx +58 -22
- inspect_ai/_view/www/src/samples/SampleDisplay.module.css +4 -0
- inspect_ai/_view/www/src/samples/SampleDisplay.tsx +135 -104
- inspect_ai/_view/www/src/samples/SampleSummaryView.module.css +10 -0
- inspect_ai/_view/www/src/samples/SampleSummaryView.tsx +83 -36
- inspect_ai/_view/www/src/samples/SamplesTools.tsx +35 -30
- inspect_ai/_view/www/src/samples/chat/ChatMessage.tsx +2 -1
- inspect_ai/_view/www/src/samples/chat/ChatMessageRenderer.tsx +1 -1
- inspect_ai/_view/www/src/samples/chat/ChatViewVirtualList.tsx +45 -53
- inspect_ai/_view/www/src/samples/chat/MessageContent.tsx +6 -1
- inspect_ai/_view/www/src/samples/chat/MessageContents.tsx +5 -0
- inspect_ai/_view/www/src/samples/chat/messages.ts +36 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.module.css +3 -0
- inspect_ai/_view/www/src/samples/chat/tools/ToolCallView.tsx +11 -1
- inspect_ai/_view/www/src/samples/chat/tools/ToolInput.tsx +22 -46
- inspect_ai/_view/www/src/samples/descriptor/samplesDescriptor.tsx +34 -20
- inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.module.css +3 -3
- inspect_ai/_view/www/src/samples/descriptor/score/BooleanScoreDescriptor.tsx +1 -1
- inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.module.css +4 -4
- inspect_ai/_view/www/src/samples/descriptor/score/ObjectScoreDescriptor.tsx +10 -10
- inspect_ai/_view/www/src/samples/descriptor/types.ts +6 -5
- inspect_ai/_view/www/src/samples/list/SampleFooter.module.css +22 -3
- inspect_ai/_view/www/src/samples/list/SampleFooter.tsx +27 -2
- inspect_ai/_view/www/src/samples/list/SampleList.tsx +122 -85
- inspect_ai/_view/www/src/samples/list/SampleRow.module.css +6 -0
- inspect_ai/_view/www/src/samples/list/SampleRow.tsx +28 -15
- inspect_ai/_view/www/src/samples/sample-tools/SelectScorer.tsx +29 -18
- inspect_ai/_view/www/src/samples/sample-tools/SortFilter.tsx +28 -28
- inspect_ai/_view/www/src/samples/sample-tools/sample-filter/SampleFilter.tsx +19 -9
- inspect_ai/_view/www/src/samples/sampleDataAdapter.ts +33 -0
- inspect_ai/_view/www/src/samples/sampleLimit.ts +2 -2
- inspect_ai/_view/www/src/samples/scores/SampleScores.tsx +12 -27
- inspect_ai/_view/www/src/samples/scores/SampleScoresGrid.module.css +38 -0
- inspect_ai/_view/www/src/samples/scores/SampleScoresGrid.tsx +118 -0
- inspect_ai/_view/www/src/samples/scores/{SampleScoreView.module.css → SampleScoresView.module.css} +10 -1
- inspect_ai/_view/www/src/samples/scores/SampleScoresView.tsx +78 -0
- inspect_ai/_view/www/src/samples/transcript/ErrorEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/InfoEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/InputEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.module.css +4 -0
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.tsx +10 -24
- inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.tsx +4 -22
- inspect_ai/_view/www/src/samples/transcript/SandboxEventView.tsx +15 -24
- inspect_ai/_view/www/src/samples/transcript/ScoreEventView.tsx +0 -13
- inspect_ai/_view/www/src/samples/transcript/StepEventView.tsx +6 -28
- inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.tsx +24 -34
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.module.css +4 -0
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.tsx +33 -17
- inspect_ai/_view/www/src/samples/transcript/TranscriptView.tsx +197 -338
- inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.module.css +16 -0
- inspect_ai/_view/www/src/samples/transcript/TranscriptVirtualListComponent.tsx +44 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventNav.tsx +7 -4
- inspect_ai/_view/www/src/samples/transcript/event/EventPanel.tsx +81 -60
- inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.module.css +23 -0
- inspect_ai/_view/www/src/samples/transcript/event/EventProgressPanel.tsx +27 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventRenderers.tsx +29 -1
- inspect_ai/_view/www/src/samples/transcript/state/StateEventView.tsx +102 -72
- inspect_ai/_view/www/src/scoring/utils.ts +87 -0
- inspect_ai/_view/www/src/state/appSlice.ts +244 -0
- inspect_ai/_view/www/src/state/hooks.ts +399 -0
- inspect_ai/_view/www/src/state/logPolling.ts +200 -0
- inspect_ai/_view/www/src/state/logSlice.ts +224 -0
- inspect_ai/_view/www/src/state/logsPolling.ts +118 -0
- inspect_ai/_view/www/src/state/logsSlice.ts +181 -0
- inspect_ai/_view/www/src/state/samplePolling.ts +314 -0
- inspect_ai/_view/www/src/state/sampleSlice.ts +140 -0
- inspect_ai/_view/www/src/state/sampleUtils.ts +21 -0
- inspect_ai/_view/www/src/state/scrolling.ts +206 -0
- inspect_ai/_view/www/src/state/store.ts +168 -0
- inspect_ai/_view/www/src/state/store_filter.ts +84 -0
- inspect_ai/_view/www/src/state/utils.ts +23 -0
- inspect_ai/_view/www/src/storage/index.ts +26 -0
- inspect_ai/_view/www/src/types/log.d.ts +36 -26
- inspect_ai/_view/www/src/types/markdown-it-katex.d.ts +21 -0
- inspect_ai/_view/www/src/types.ts +94 -32
- inspect_ai/_view/www/src/utils/attachments.ts +58 -23
- inspect_ai/_view/www/src/utils/json-worker.ts +79 -12
- inspect_ai/_view/www/src/utils/logger.ts +52 -0
- inspect_ai/_view/www/src/utils/polling.ts +100 -0
- inspect_ai/_view/www/src/utils/react.ts +30 -0
- inspect_ai/_view/www/src/utils/vscode.ts +1 -1
- inspect_ai/_view/www/src/workspace/WorkSpace.tsx +184 -217
- inspect_ai/_view/www/src/workspace/WorkSpaceView.tsx +11 -53
- inspect_ai/_view/www/src/workspace/navbar/Navbar.tsx +8 -18
- inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.module.css +1 -0
- inspect_ai/_view/www/src/workspace/navbar/PrimaryBar.tsx +40 -22
- inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.module.css +16 -1
- inspect_ai/_view/www/src/workspace/navbar/ResultsPanel.tsx +159 -103
- inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.module.css +32 -0
- inspect_ai/_view/www/src/workspace/navbar/RunningStatusPanel.tsx +32 -0
- inspect_ai/_view/www/src/workspace/navbar/ScoreGrid.module.css +35 -0
- inspect_ai/_view/www/src/workspace/navbar/ScoreGrid.tsx +117 -0
- inspect_ai/_view/www/src/workspace/navbar/SecondaryBar.tsx +12 -14
- inspect_ai/_view/www/src/workspace/navbar/StatusPanel.tsx +6 -2
- inspect_ai/_view/www/src/workspace/sidebar/LogDirectoryTitleView.tsx +4 -4
- inspect_ai/_view/www/src/workspace/sidebar/Sidebar.module.css +3 -2
- inspect_ai/_view/www/src/workspace/sidebar/Sidebar.tsx +28 -13
- inspect_ai/_view/www/src/workspace/tabs/InfoTab.tsx +5 -10
- inspect_ai/_view/www/src/workspace/tabs/JsonTab.tsx +4 -4
- inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.module.css +22 -0
- inspect_ai/_view/www/src/workspace/tabs/RunningNoSamples.tsx +19 -0
- inspect_ai/_view/www/src/workspace/tabs/SamplesTab.tsx +128 -115
- inspect_ai/_view/www/src/workspace/tabs/grouping.ts +37 -5
- inspect_ai/_view/www/src/workspace/tabs/types.ts +4 -0
- inspect_ai/_view/www/src/workspace/types.ts +4 -3
- inspect_ai/_view/www/src/workspace/utils.ts +4 -4
- inspect_ai/_view/www/vite.config.js +6 -0
- inspect_ai/_view/www/yarn.lock +464 -355
- inspect_ai/agent/__init__.py +36 -0
- inspect_ai/agent/_agent.py +268 -0
- inspect_ai/agent/_as_solver.py +72 -0
- inspect_ai/agent/_as_tool.py +122 -0
- inspect_ai/{solver → agent}/_bridge/bridge.py +23 -37
- inspect_ai/{solver → agent}/_bridge/patch.py +9 -8
- inspect_ai/agent/_filter.py +46 -0
- inspect_ai/agent/_handoff.py +93 -0
- inspect_ai/{solver/_human_agent → agent/_human}/agent.py +11 -12
- inspect_ai/{solver/_human_agent → agent/_human}/commands/__init__.py +2 -3
- inspect_ai/{solver/_human_agent → agent/_human}/commands/clock.py +3 -1
- inspect_ai/{solver/_human_agent → agent/_human}/commands/score.py +5 -5
- inspect_ai/{solver/_human_agent → agent/_human}/install.py +6 -3
- inspect_ai/{solver/_human_agent → agent/_human}/service.py +7 -3
- inspect_ai/{solver/_human_agent → agent/_human}/state.py +5 -5
- inspect_ai/agent/_react.py +241 -0
- inspect_ai/agent/_run.py +36 -0
- inspect_ai/agent/_types.py +81 -0
- inspect_ai/log/_condense.py +26 -0
- inspect_ai/log/_log.py +17 -5
- inspect_ai/log/_recorders/buffer/__init__.py +14 -0
- inspect_ai/log/_recorders/buffer/buffer.py +30 -0
- inspect_ai/log/_recorders/buffer/database.py +685 -0
- inspect_ai/log/_recorders/buffer/filestore.py +259 -0
- inspect_ai/log/_recorders/buffer/types.py +84 -0
- inspect_ai/log/_recorders/eval.py +2 -11
- inspect_ai/log/_recorders/types.py +30 -0
- inspect_ai/log/_transcript.py +32 -2
- inspect_ai/model/__init__.py +7 -1
- inspect_ai/model/_call_tools.py +257 -52
- inspect_ai/model/_chat_message.py +7 -4
- inspect_ai/model/_conversation.py +13 -62
- inspect_ai/model/_display.py +85 -0
- inspect_ai/model/_generate_config.py +2 -2
- inspect_ai/model/_model.py +114 -14
- inspect_ai/model/_model_output.py +14 -9
- inspect_ai/model/_openai.py +16 -4
- inspect_ai/model/_openai_computer_use.py +162 -0
- inspect_ai/model/_openai_responses.py +319 -165
- inspect_ai/model/_providers/anthropic.py +20 -21
- inspect_ai/model/_providers/azureai.py +24 -13
- inspect_ai/model/_providers/bedrock.py +1 -7
- inspect_ai/model/_providers/cloudflare.py +3 -3
- inspect_ai/model/_providers/goodfire.py +2 -6
- inspect_ai/model/_providers/google.py +11 -10
- inspect_ai/model/_providers/groq.py +6 -3
- inspect_ai/model/_providers/hf.py +7 -3
- inspect_ai/model/_providers/mistral.py +7 -10
- inspect_ai/model/_providers/openai.py +47 -17
- inspect_ai/model/_providers/openai_o1.py +11 -4
- inspect_ai/model/_providers/openai_responses.py +12 -14
- inspect_ai/model/_providers/providers.py +2 -2
- inspect_ai/model/_providers/together.py +12 -2
- inspect_ai/model/_providers/util/chatapi.py +7 -2
- inspect_ai/model/_providers/util/hf_handler.py +4 -2
- inspect_ai/model/_providers/util/llama31.py +4 -2
- inspect_ai/model/_providers/vertex.py +11 -9
- inspect_ai/model/_providers/vllm.py +4 -4
- inspect_ai/scorer/__init__.py +2 -0
- inspect_ai/scorer/_metrics/__init__.py +2 -0
- inspect_ai/scorer/_metrics/grouped.py +84 -0
- inspect_ai/scorer/_score.py +26 -6
- inspect_ai/solver/__init__.py +2 -2
- inspect_ai/solver/_basic_agent.py +22 -9
- inspect_ai/solver/_bridge.py +31 -0
- inspect_ai/solver/_chain.py +20 -12
- inspect_ai/solver/_fork.py +5 -1
- inspect_ai/solver/_human_agent.py +52 -0
- inspect_ai/solver/_prompt.py +3 -1
- inspect_ai/solver/_run.py +59 -0
- inspect_ai/solver/_solver.py +14 -4
- inspect_ai/solver/_task_state.py +5 -3
- inspect_ai/tool/_tool_call.py +15 -8
- inspect_ai/tool/_tool_def.py +17 -12
- inspect_ai/tool/_tool_support_helpers.py +4 -4
- inspect_ai/tool/_tool_with.py +14 -11
- inspect_ai/tool/_tools/_bash_session.py +11 -2
- inspect_ai/tool/_tools/_computer/_common.py +18 -2
- inspect_ai/tool/_tools/_computer/_computer.py +18 -2
- inspect_ai/tool/_tools/_computer/_resources/tool/_constants.py +2 -0
- inspect_ai/tool/_tools/_computer/_resources/tool/_x11_client.py +17 -0
- inspect_ai/tool/_tools/_think.py +1 -1
- inspect_ai/tool/_tools/_web_browser/_web_browser.py +103 -62
- inspect_ai/util/__init__.py +2 -0
- inspect_ai/util/_anyio.py +27 -0
- inspect_ai/util/_sandbox/__init__.py +2 -1
- inspect_ai/util/_sandbox/context.py +32 -7
- inspect_ai/util/_sandbox/docker/cleanup.py +4 -0
- inspect_ai/util/_sandbox/docker/compose.py +2 -2
- inspect_ai/util/_sandbox/docker/docker.py +12 -1
- inspect_ai/util/_store_model.py +30 -7
- inspect_ai/util/_subprocess.py +13 -3
- inspect_ai/util/_subtask.py +1 -0
- {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/METADATA +1 -1
- {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/RECORD +295 -229
- inspect_ai/_view/www/src/samples/scores/SampleScoreView.tsx +0 -169
- inspect_ai/_view/www/src/samples/transcript/SampleTranscript.tsx +0 -22
- /inspect_ai/{solver → agent}/_bridge/__init__.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/__init__.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/commands/command.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/commands/instructions.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/commands/note.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/commands/status.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/commands/submit.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/panel.py +0 -0
- /inspect_ai/{solver/_human_agent → agent/_human}/view.py +0 -0
- {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/WHEEL +0 -0
- {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/licenses/LICENSE +0 -0
- {inspect_ai-0.3.81.dist-info → inspect_ai-0.3.83.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
import clsx from "clsx";
|
2
2
|
|
3
|
-
import { FC } from "react";
|
3
|
+
import { FC, useCallback } from "react";
|
4
4
|
import styles from "./EventNav.module.css";
|
5
5
|
|
6
6
|
interface EventNavProps {
|
@@ -19,6 +19,11 @@ export const EventNav: FC<EventNavProps> = ({
|
|
19
19
|
setSelectedNav,
|
20
20
|
}) => {
|
21
21
|
const active = target === selectedNav;
|
22
|
+
|
23
|
+
const handleClick = useCallback(() => {
|
24
|
+
setSelectedNav(target);
|
25
|
+
}, [setSelectedNav, target]);
|
26
|
+
|
22
27
|
return (
|
23
28
|
<li className="nav-item">
|
24
29
|
<button
|
@@ -33,9 +38,7 @@ export const EventNav: FC<EventNavProps> = ({
|
|
33
38
|
"text-size-small",
|
34
39
|
styles.tab,
|
35
40
|
)}
|
36
|
-
onClick={
|
37
|
-
setSelectedNav(target);
|
38
|
-
}}
|
41
|
+
onClick={handleClick}
|
39
42
|
>
|
40
43
|
{title}
|
41
44
|
</button>
|
@@ -1,9 +1,16 @@
|
|
1
1
|
import clsx from "clsx";
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
FC,
|
4
|
+
isValidElement,
|
5
|
+
ReactElement,
|
6
|
+
ReactNode,
|
7
|
+
useCallback,
|
8
|
+
} from "react";
|
3
9
|
import { ApplicationIcons } from "../../../appearance/icons";
|
4
10
|
import { EventNavs } from "./EventNavs";
|
5
11
|
|
6
|
-
import
|
12
|
+
import { ProgressBar } from "../../../components/ProgressBar";
|
13
|
+
import { useProperty } from "../../../state/hooks";
|
7
14
|
import styles from "./EventPanel.module.css";
|
8
15
|
|
9
16
|
interface EventPanelProps {
|
@@ -14,11 +21,8 @@ interface EventPanelProps {
|
|
14
21
|
text?: string;
|
15
22
|
icon?: string;
|
16
23
|
collapse?: boolean;
|
17
|
-
collapsed?: boolean;
|
18
|
-
setCollapsed: (collapse: boolean) => void;
|
19
|
-
selectedNav: string;
|
20
|
-
setSelectedNav: (nav: string) => void;
|
21
24
|
children?: ReactNode | ReactNode[];
|
25
|
+
running?: boolean;
|
22
26
|
}
|
23
27
|
|
24
28
|
interface ChildProps {
|
@@ -28,7 +32,7 @@ interface ChildProps {
|
|
28
32
|
/**
|
29
33
|
* Renders the StateEventView component.
|
30
34
|
*/
|
31
|
-
export const EventPanel:
|
35
|
+
export const EventPanel: FC<EventPanelProps> = ({
|
32
36
|
id,
|
33
37
|
className,
|
34
38
|
title,
|
@@ -36,23 +40,30 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
36
40
|
text,
|
37
41
|
icon,
|
38
42
|
collapse,
|
39
|
-
collapsed,
|
40
|
-
setCollapsed,
|
41
43
|
children,
|
42
|
-
|
43
|
-
selectedNav,
|
44
|
+
running,
|
44
45
|
}) => {
|
46
|
+
const [isCollapsed, setCollapsed] = useProperty(id, "collapsed", {
|
47
|
+
defaultValue: !!collapse,
|
48
|
+
});
|
49
|
+
|
45
50
|
const hasCollapse = collapse !== undefined;
|
46
|
-
const isCollapsed = collapsed === undefined ? collapse : collapsed;
|
47
51
|
|
48
52
|
const pillId = (index: number) => {
|
49
53
|
return `${id}-nav-pill-${index}`;
|
50
54
|
};
|
51
|
-
|
52
55
|
const filteredArrChildren = (
|
53
56
|
Array.isArray(children) ? children : [children]
|
54
57
|
).filter((child) => !!child);
|
55
|
-
|
58
|
+
|
59
|
+
const defaultPill = filteredArrChildren.findIndex((node) => {
|
60
|
+
return hasDataDefault(node) && node.props["data-default"];
|
61
|
+
});
|
62
|
+
const defaultPillId = defaultPill !== -1 ? pillId(defaultPill) : pillId(0);
|
63
|
+
|
64
|
+
const [selectedNav, setSelectedNav] = useProperty(id, "selectedNav", {
|
65
|
+
defaultValue: defaultPillId,
|
66
|
+
});
|
56
67
|
|
57
68
|
const gridColumns = [];
|
58
69
|
|
@@ -72,6 +83,10 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
72
83
|
gridColumns.push("minmax(0, max-content)");
|
73
84
|
gridColumns.push("minmax(0, max-content)");
|
74
85
|
|
86
|
+
const toggleCollapse = useCallback(() => {
|
87
|
+
setCollapsed(!isCollapsed);
|
88
|
+
}, [setCollapsed, isCollapsed]);
|
89
|
+
|
75
90
|
const titleEl =
|
76
91
|
title || icon || filteredArrChildren.length > 1 ? (
|
77
92
|
<div
|
@@ -86,9 +101,7 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
86
101
|
>
|
87
102
|
{hasCollapse ? (
|
88
103
|
<i
|
89
|
-
onClick={
|
90
|
-
setCollapsed(!isCollapsed);
|
91
|
-
}}
|
104
|
+
onClick={toggleCollapse}
|
92
105
|
className={
|
93
106
|
isCollapsed
|
94
107
|
? ApplicationIcons.chevron.right
|
@@ -104,33 +117,23 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
104
117
|
icon || ApplicationIcons.metadata,
|
105
118
|
"text-style-secondary",
|
106
119
|
)}
|
107
|
-
onClick={
|
108
|
-
setCollapsed(!isCollapsed);
|
109
|
-
}}
|
120
|
+
onClick={toggleCollapse}
|
110
121
|
/>
|
111
122
|
) : (
|
112
123
|
""
|
113
124
|
)}
|
114
125
|
<div
|
115
126
|
className={clsx("text-style-secondary", "text-style-label")}
|
116
|
-
onClick={
|
117
|
-
setCollapsed(!isCollapsed);
|
118
|
-
}}
|
127
|
+
onClick={toggleCollapse}
|
119
128
|
>
|
120
129
|
{title}
|
121
130
|
</div>
|
122
|
-
<div
|
123
|
-
onClick={() => {
|
124
|
-
setCollapsed(!isCollapsed);
|
125
|
-
}}
|
126
|
-
></div>
|
131
|
+
<div onClick={toggleCollapse}></div>
|
127
132
|
<div
|
128
133
|
className={clsx("text-style-secondary", styles.label)}
|
129
|
-
onClick={
|
130
|
-
setCollapsed(!isCollapsed);
|
131
|
-
}}
|
134
|
+
onClick={toggleCollapse}
|
132
135
|
>
|
133
|
-
{
|
136
|
+
{isCollapsed ? text : ""}
|
134
137
|
</div>
|
135
138
|
<div className={styles.navs}>
|
136
139
|
{(!hasCollapse || !isCollapsed) &&
|
@@ -140,7 +143,7 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
140
143
|
navs={filteredArrChildren.map((child, index) => {
|
141
144
|
const defaultTitle = `Tab ${index}`;
|
142
145
|
const title =
|
143
|
-
child &&
|
146
|
+
child && isValidElement<ChildProps>(child)
|
144
147
|
? (child.props as ChildProps)["data-name"] || defaultTitle
|
145
148
|
: defaultTitle;
|
146
149
|
return {
|
@@ -149,7 +152,7 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
149
152
|
target: pillId(index),
|
150
153
|
};
|
151
154
|
})}
|
152
|
-
selectedNav={selectedNav
|
155
|
+
selectedNav={selectedNav}
|
153
156
|
setSelectedNav={setSelectedNav}
|
154
157
|
/>
|
155
158
|
) : (
|
@@ -162,33 +165,51 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|
162
165
|
);
|
163
166
|
|
164
167
|
const card = (
|
165
|
-
|
166
|
-
{
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
)
|
189
|
-
|
168
|
+
<>
|
169
|
+
<div id={id} className={clsx(className, styles.card)}>
|
170
|
+
{titleEl}
|
171
|
+
<div
|
172
|
+
className={clsx(
|
173
|
+
"tab-content",
|
174
|
+
styles.cardContent,
|
175
|
+
hasCollapse && isCollapsed ? styles.hidden : undefined,
|
176
|
+
)}
|
177
|
+
>
|
178
|
+
{filteredArrChildren?.map((child, index) => {
|
179
|
+
const id = pillId(index);
|
180
|
+
const isSelected = id === selectedNav;
|
181
|
+
|
182
|
+
return (
|
183
|
+
<div
|
184
|
+
key={`children-${id}-${index}`}
|
185
|
+
id={id}
|
186
|
+
className={clsx("tab-pane", "show", isSelected ? "active" : "")}
|
187
|
+
>
|
188
|
+
{child}
|
189
|
+
</div>
|
190
|
+
);
|
191
|
+
})}
|
192
|
+
</div>
|
190
193
|
</div>
|
191
|
-
|
194
|
+
<ProgressBar animating={!!running} />
|
195
|
+
</>
|
192
196
|
);
|
193
197
|
return card;
|
194
198
|
};
|
199
|
+
|
200
|
+
// Typeguard for reading default value from pills
|
201
|
+
interface DataDefaultProps {
|
202
|
+
"data-default"?: boolean;
|
203
|
+
[key: string]: any;
|
204
|
+
}
|
205
|
+
|
206
|
+
function hasDataDefault(
|
207
|
+
node: ReactNode,
|
208
|
+
): node is ReactElement<DataDefaultProps> {
|
209
|
+
return (
|
210
|
+
isValidElement(node) &&
|
211
|
+
node.props !== null &&
|
212
|
+
typeof node.props === "object" &&
|
213
|
+
"data-default" in node.props
|
214
|
+
);
|
215
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
.panel {
|
2
|
+
display: flex;
|
3
|
+
justify-content: center;
|
4
|
+
padding-top: 1em;
|
5
|
+
padding-bottom: 1em;
|
6
|
+
}
|
7
|
+
|
8
|
+
.container {
|
9
|
+
display: grid;
|
10
|
+
grid-template-columns: max-content max-content;
|
11
|
+
column-gap: 0.3em;
|
12
|
+
}
|
13
|
+
|
14
|
+
.spinner {
|
15
|
+
height: 15px;
|
16
|
+
width: 14px;
|
17
|
+
border-width: 2px;
|
18
|
+
color: var(--bs-secondary);
|
19
|
+
}
|
20
|
+
|
21
|
+
.text {
|
22
|
+
margin-top: -2px;
|
23
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import clsx from "clsx";
|
2
|
+
import { FC } from "react";
|
3
|
+
|
4
|
+
import styles from "./EventProgressPanel.module.css";
|
5
|
+
|
6
|
+
interface EventProgressPanelProps {
|
7
|
+
text: string;
|
8
|
+
}
|
9
|
+
|
10
|
+
export const EventProgressPanel: FC<EventProgressPanelProps> = ({ text }) => {
|
11
|
+
return (
|
12
|
+
<div className={clsx(styles.panel)}>
|
13
|
+
<div className={clsx(styles.container)}>
|
14
|
+
<Spinner />
|
15
|
+
<div className={clsx("text-size-smaller", styles.text)}>{text}</div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
);
|
19
|
+
};
|
20
|
+
|
21
|
+
const Spinner: FC = () => {
|
22
|
+
return (
|
23
|
+
<div className={clsx(styles.spinner, "spinner-border")} role="status">
|
24
|
+
<span className={clsx("visually-hidden")}>generating...</span>
|
25
|
+
</div>
|
26
|
+
);
|
27
|
+
};
|
@@ -17,7 +17,8 @@ interface Signature {
|
|
17
17
|
|
18
18
|
interface ChangeType {
|
19
19
|
type: string;
|
20
|
-
signature
|
20
|
+
signature?: Signature;
|
21
|
+
match?: (changes: JsonChange[]) => boolean;
|
21
22
|
render: (
|
22
23
|
changes: JsonChange[],
|
23
24
|
state: Record<string, unknown>,
|
@@ -211,8 +212,35 @@ const renderTools = (
|
|
211
212
|
);
|
212
213
|
};
|
213
214
|
|
215
|
+
const createMessageRenderer = (name: string, role: string): ChangeType => {
|
216
|
+
return {
|
217
|
+
type: name,
|
218
|
+
match: (changes: JsonChange[]) => {
|
219
|
+
if (changes.length === 1) {
|
220
|
+
const change = changes[0];
|
221
|
+
if (change.op === "add" && change.path.match(/\/messages\/\d+/)) {
|
222
|
+
return change.value["role"] === role;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
return false;
|
226
|
+
},
|
227
|
+
render: (changes) => {
|
228
|
+
const message = changes[0].value as unknown;
|
229
|
+
return (
|
230
|
+
<ChatView
|
231
|
+
key="system_msg_event_preview"
|
232
|
+
id="system_msg_event_preview"
|
233
|
+
messages={[message] as Messages}
|
234
|
+
/>
|
235
|
+
);
|
236
|
+
},
|
237
|
+
};
|
238
|
+
};
|
239
|
+
|
214
240
|
export const RenderableChangeTypes: ChangeType[] = [
|
215
241
|
system_msg_added_sig,
|
242
|
+
createMessageRenderer("assistant_msg", "assistant"),
|
243
|
+
createMessageRenderer("user_msg", "user"),
|
216
244
|
use_tools,
|
217
245
|
add_tools,
|
218
246
|
];
|
@@ -10,7 +10,6 @@ import {
|
|
10
10
|
} from "../../../types/log";
|
11
11
|
import { formatDateTime } from "../../../utils/format";
|
12
12
|
import { EventPanel } from "../event/EventPanel";
|
13
|
-
import { TranscriptEventState } from "../types";
|
14
13
|
import { StateDiffView } from "./StateDiffView";
|
15
14
|
import {
|
16
15
|
RenderableChangeTypes,
|
@@ -23,8 +22,6 @@ import styles from "./StateEventView.module.css";
|
|
23
22
|
interface StateEventViewProps {
|
24
23
|
id: string;
|
25
24
|
event: StateEvent | StoreEvent;
|
26
|
-
eventState: TranscriptEventState;
|
27
|
-
setEventState: (state: TranscriptEventState) => void;
|
28
25
|
isStore?: boolean;
|
29
26
|
className?: string | string[];
|
30
27
|
}
|
@@ -35,8 +32,6 @@ interface StateEventViewProps {
|
|
35
32
|
export const StateEventView: FC<StateEventViewProps> = ({
|
36
33
|
id,
|
37
34
|
event,
|
38
|
-
eventState,
|
39
|
-
setEventState,
|
40
35
|
isStore = false,
|
41
36
|
className,
|
42
37
|
}) => {
|
@@ -46,7 +41,15 @@ export const StateEventView: FC<StateEventViewProps> = ({
|
|
46
41
|
|
47
42
|
// Synthesize objects for comparison
|
48
43
|
const [before, after] = useMemo(() => {
|
49
|
-
|
44
|
+
try {
|
45
|
+
return synthesizeComparable(event.changes);
|
46
|
+
} catch (e) {
|
47
|
+
console.error(
|
48
|
+
"Unable to synthesize comparable object to display state diffs.",
|
49
|
+
e,
|
50
|
+
);
|
51
|
+
return [{}, {}];
|
52
|
+
}
|
50
53
|
}, [event.changes]);
|
51
54
|
|
52
55
|
// This clone is important since the state is used by react as potential values that are rendered
|
@@ -66,14 +69,6 @@ export const StateEventView: FC<StateEventViewProps> = ({
|
|
66
69
|
subTitle={formatDateTime(new Date(event.timestamp))}
|
67
70
|
text={!changePreview ? summary : undefined}
|
68
71
|
collapse={changePreview === undefined ? true : undefined}
|
69
|
-
selectedNav={eventState.selectedNav || ""}
|
70
|
-
setSelectedNav={(selectedNav) => {
|
71
|
-
setEventState({ ...eventState, selectedNav });
|
72
|
-
}}
|
73
|
-
collapsed={eventState.collapsed}
|
74
|
-
setCollapsed={(collapsed) => {
|
75
|
-
setEventState({ ...eventState, collapsed });
|
76
|
-
}}
|
77
72
|
>
|
78
73
|
{changePreview ? (
|
79
74
|
<div data-name="Summary" className={clsx(styles.summary)}>
|
@@ -103,59 +98,71 @@ const generatePreview = (
|
|
103
98
|
...RenderableChangeTypes,
|
104
99
|
...(isStore ? StoreSpecificRenderableTypes : []),
|
105
100
|
]) {
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
const
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
101
|
+
if (changeType.signature) {
|
102
|
+
// Note that we currently only have renderers that depend upon
|
103
|
+
// add, remove, replace, but we should likely add
|
104
|
+
// move, copy, test
|
105
|
+
const requiredMatchCount =
|
106
|
+
changeType.signature.remove.length +
|
107
|
+
changeType.signature.replace.length +
|
108
|
+
changeType.signature.add.length;
|
109
|
+
let matchingOps = 0;
|
110
|
+
for (const change of changes) {
|
111
|
+
const op = change.op;
|
112
|
+
switch (op) {
|
113
|
+
case "add":
|
114
|
+
if (
|
115
|
+
changeType.signature.add &&
|
116
|
+
changeType.signature.add.length > 0
|
117
|
+
) {
|
118
|
+
changeType.signature.add.forEach((signature) => {
|
119
|
+
if (change.path.match(signature)) {
|
120
|
+
matchingOps++;
|
121
|
+
}
|
122
|
+
});
|
123
|
+
}
|
124
|
+
break;
|
125
|
+
case "remove":
|
126
|
+
if (
|
127
|
+
changeType.signature.remove &&
|
128
|
+
changeType.signature.remove.length > 0
|
129
|
+
) {
|
130
|
+
changeType.signature.remove.forEach((signature) => {
|
131
|
+
if (change.path.match(signature)) {
|
132
|
+
matchingOps++;
|
133
|
+
}
|
134
|
+
});
|
135
|
+
}
|
136
|
+
break;
|
137
|
+
case "replace":
|
138
|
+
if (
|
139
|
+
changeType.signature.replace &&
|
140
|
+
changeType.signature.replace.length > 0
|
141
|
+
) {
|
142
|
+
changeType.signature.replace.forEach((signature) => {
|
143
|
+
if (change.path.match(signature)) {
|
144
|
+
matchingOps++;
|
145
|
+
}
|
146
|
+
});
|
147
|
+
}
|
148
|
+
break;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
if (matchingOps === requiredMatchCount) {
|
152
|
+
const el = changeType.render(changes, resolvedState);
|
153
|
+
results.push(el);
|
154
|
+
// Only one renderer can process a change
|
155
|
+
// TODO: consider changing this to allow many handlers to render (though then we sort of need
|
156
|
+
// to match the renderer to the key (e.g. a rendered for `tool_choice` a renderer for `tools` etc..))
|
157
|
+
break;
|
158
|
+
}
|
159
|
+
} else if (changeType.match) {
|
160
|
+
const matches = changeType.match(changes);
|
161
|
+
if (matches) {
|
162
|
+
const el = changeType.render(changes, resolvedState);
|
163
|
+
results.push(el);
|
164
|
+
break;
|
150
165
|
}
|
151
|
-
}
|
152
|
-
if (matchingOps === requiredMatchCount) {
|
153
|
-
const el = changeType.render(changes, resolvedState);
|
154
|
-
results.push(el);
|
155
|
-
// Only one renderer can process a change
|
156
|
-
// TODO: consider changing this to allow many handlers to render (though then we sort of need
|
157
|
-
// to match the renderer to the key (e.g. a rendered for `tool_choice` a renderer for `tools` etc..))
|
158
|
-
break;
|
159
166
|
}
|
160
167
|
}
|
161
168
|
return results.length > 0 ? results : undefined;
|
@@ -269,21 +276,44 @@ function setPath(
|
|
269
276
|
value: unknown,
|
270
277
|
): void {
|
271
278
|
const keys = parsePath(path);
|
272
|
-
let current: Record<string, unknown> = target;
|
279
|
+
let current: Record<string, unknown> | unknown[] = target;
|
273
280
|
|
274
281
|
for (let i = 0; i < keys.length - 1; i++) {
|
275
282
|
const key = keys[i];
|
276
|
-
|
277
|
-
|
278
|
-
|
283
|
+
|
284
|
+
if (Array.isArray(current)) {
|
285
|
+
const numericIndex = getIndex(key);
|
286
|
+
current[numericIndex] = isArrayIndex(keys[i + 1]) ? [] : {};
|
287
|
+
current = current[numericIndex] as
|
288
|
+
| Record<string, unknown>
|
289
|
+
| Array<unknown>;
|
290
|
+
} else {
|
291
|
+
if (!(key in current)) {
|
292
|
+
// If the next key is a number, create an array, otherwise an object
|
293
|
+
current[key] = isArrayIndex(keys[i + 1]) ? [] : {};
|
294
|
+
}
|
295
|
+
current = current[key] as Record<string, unknown> | Array<unknown>;
|
279
296
|
}
|
280
|
-
current = current[key] as Record<string, unknown>;
|
281
297
|
}
|
282
298
|
|
283
299
|
const lastKey = keys[keys.length - 1];
|
284
|
-
current
|
300
|
+
if (Array.isArray(current)) {
|
301
|
+
const numericIndex = getIndex(lastKey);
|
302
|
+
current[numericIndex] = value;
|
303
|
+
} else {
|
304
|
+
current[lastKey] = value;
|
305
|
+
}
|
285
306
|
}
|
286
307
|
|
308
|
+
const getIndex = (key: string): number => {
|
309
|
+
const numericIndex = isArrayIndex(key) ? parseInt(key) : undefined;
|
310
|
+
if (numericIndex === undefined) {
|
311
|
+
throw new Error(`The key ${key} isn't a valid Array index!`);
|
312
|
+
}
|
313
|
+
|
314
|
+
return numericIndex;
|
315
|
+
};
|
316
|
+
|
287
317
|
/**
|
288
318
|
* Places structure in an object (without placing values)
|
289
319
|
*/
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import { EvalSummary, SampleSummary } from "../api/types";
|
2
|
+
import { EvalResults } from "../types/log";
|
3
|
+
|
4
|
+
export interface ScorerInfo {
|
5
|
+
name: string;
|
6
|
+
scorer: string;
|
7
|
+
}
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Extracts scorer information from evaluation results
|
11
|
+
*/
|
12
|
+
const getScorersFromResults = (results?: EvalResults): ScorerInfo[] => {
|
13
|
+
if (!results?.scores) {
|
14
|
+
return [];
|
15
|
+
}
|
16
|
+
|
17
|
+
return results.scores.reduce((uniqueScorers, score) => {
|
18
|
+
const isDuplicate = uniqueScorers.some(
|
19
|
+
(existing) =>
|
20
|
+
existing.scorer === score.scorer && existing.name === score.name,
|
21
|
+
);
|
22
|
+
|
23
|
+
if (!isDuplicate) {
|
24
|
+
uniqueScorers.push({
|
25
|
+
name: score.name,
|
26
|
+
scorer: score.scorer,
|
27
|
+
});
|
28
|
+
}
|
29
|
+
|
30
|
+
return uniqueScorers;
|
31
|
+
}, [] as ScorerInfo[]);
|
32
|
+
};
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Extracts scorer information from sample summaries
|
36
|
+
*/
|
37
|
+
const getScorersFromSamples = (samples: SampleSummary[]): ScorerInfo[] => {
|
38
|
+
// Find a sample with scores
|
39
|
+
const scoredSample = samples.find((sample) => {
|
40
|
+
return !!sample.scores;
|
41
|
+
});
|
42
|
+
|
43
|
+
return Object.keys(scoredSample?.scores || {}).map((key) => ({
|
44
|
+
name: key,
|
45
|
+
scorer: key,
|
46
|
+
}));
|
47
|
+
};
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Gets all available scorers for a log, prioritizing results over samples
|
51
|
+
*/
|
52
|
+
export const getAvailableScorers = (
|
53
|
+
log: EvalSummary,
|
54
|
+
sampleSummaries: SampleSummary[],
|
55
|
+
): ScorerInfo[] | undefined => {
|
56
|
+
const resultScorers = log.results ? getScorersFromResults(log.results) : [];
|
57
|
+
if (resultScorers.length > 0) {
|
58
|
+
return resultScorers;
|
59
|
+
}
|
60
|
+
|
61
|
+
const sampleScorers = getScorersFromSamples(sampleSummaries);
|
62
|
+
if (sampleScorers.length > 0) {
|
63
|
+
return sampleScorers;
|
64
|
+
}
|
65
|
+
|
66
|
+
return undefined;
|
67
|
+
};
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Gets the default scorer to use, preferring the first scorer from results
|
71
|
+
* or falling back to the first scorer from samples
|
72
|
+
*/
|
73
|
+
export const getDefaultScorer = (
|
74
|
+
log: EvalSummary,
|
75
|
+
sampleSummaries: SampleSummary[],
|
76
|
+
): ScorerInfo | undefined => {
|
77
|
+
if (sampleSummaries.length === 0) {
|
78
|
+
return undefined;
|
79
|
+
}
|
80
|
+
|
81
|
+
const allScorers = getAvailableScorers(log, sampleSummaries);
|
82
|
+
if (allScorers) {
|
83
|
+
return allScorers[0];
|
84
|
+
} else {
|
85
|
+
return undefined;
|
86
|
+
}
|
87
|
+
};
|