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
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING, Callable, Literal, TypeAlias
|
3
|
+
from typing import TYPE_CHECKING, Callable, Literal, Sequence, TypeAlias
|
4
4
|
|
5
5
|
from inspect_ai.analysis.beta._dataframe.events.columns import EventInfo
|
6
6
|
from inspect_ai.log._file import list_eval_logs
|
@@ -11,61 +11,44 @@ if TYPE_CHECKING:
|
|
11
11
|
|
12
12
|
from typing_extensions import overload
|
13
13
|
|
14
|
-
from ..columns import Column,
|
14
|
+
from ..columns import Column, ColumnError
|
15
15
|
from ..samples.table import EventsDetail, _read_samples_df
|
16
16
|
from ..util import LogPaths, verify_prerequisites
|
17
17
|
|
18
|
-
EventFilter: TypeAlias =
|
19
|
-
list[
|
20
|
-
Literal[
|
21
|
-
"sample_init",
|
22
|
-
"sample_limit",
|
23
|
-
"sandbox",
|
24
|
-
"state",
|
25
|
-
"store",
|
26
|
-
"model",
|
27
|
-
"tool",
|
28
|
-
"sandbox",
|
29
|
-
"approval",
|
30
|
-
"input",
|
31
|
-
"score",
|
32
|
-
"error",
|
33
|
-
"logger",
|
34
|
-
"info",
|
35
|
-
"span_begin",
|
36
|
-
"span_end",
|
37
|
-
"subtask",
|
38
|
-
]
|
39
|
-
]
|
40
|
-
| Callable[[Event], bool]
|
41
|
-
)
|
18
|
+
EventFilter: TypeAlias = Callable[[Event], bool]
|
42
19
|
"""Filter for `events_df()` rows."""
|
43
20
|
|
44
21
|
|
45
22
|
@overload
|
46
23
|
def events_df(
|
47
24
|
logs: LogPaths = list_eval_logs(),
|
48
|
-
columns:
|
25
|
+
columns: Sequence[Column] = EventInfo,
|
49
26
|
filter: EventFilter | None = None,
|
50
27
|
strict: Literal[True] = True,
|
28
|
+
parallel: bool | int = False,
|
29
|
+
quiet: bool = False,
|
51
30
|
) -> "pd.DataFrame": ...
|
52
31
|
|
53
32
|
|
54
33
|
@overload
|
55
34
|
def events_df(
|
56
35
|
logs: LogPaths = list_eval_logs(),
|
57
|
-
columns:
|
36
|
+
columns: Sequence[Column] = EventInfo,
|
58
37
|
filter: EventFilter | None = None,
|
59
38
|
strict: Literal[False] = False,
|
60
|
-
|
39
|
+
parallel: bool | int = False,
|
40
|
+
quiet: bool = False,
|
41
|
+
) -> tuple["pd.DataFrame", list[ColumnError]]: ...
|
61
42
|
|
62
43
|
|
63
44
|
def events_df(
|
64
45
|
logs: LogPaths = list_eval_logs(),
|
65
|
-
columns:
|
46
|
+
columns: Sequence[Column] = EventInfo,
|
66
47
|
filter: EventFilter | None = None,
|
67
48
|
strict: bool = True,
|
68
|
-
|
49
|
+
parallel: bool | int = False,
|
50
|
+
quiet: bool = False,
|
51
|
+
) -> "pd.DataFrame" | tuple["pd.DataFrame", list[ColumnError]]:
|
69
52
|
"""Read a dataframe containing events from a set of evals.
|
70
53
|
|
71
54
|
Args:
|
@@ -73,9 +56,14 @@ def events_df(
|
|
73
56
|
Defaults to the contents of the currently active log directory
|
74
57
|
(e.g. ./logs or INSPECT_LOG_DIR).
|
75
58
|
columns: Specification for what columns to read from log files.
|
76
|
-
filter:
|
59
|
+
filter: Callable that filters event types.
|
77
60
|
strict: Raise import errors immediately. Defaults to `True`.
|
78
61
|
If `False` then a tuple of `DataFrame` and errors is returned.
|
62
|
+
parallel: If `True`, use `ProcessPoolExecutor` to read logs in parallel
|
63
|
+
(with workers based on `mp.cpu_count()`, capped at 8). If `int`, read
|
64
|
+
in parallel with the specified number of workers. If `False` (the default)
|
65
|
+
do not read in parallel.
|
66
|
+
quiet: If `True` do not print any output or progress (defaults to `False`).
|
79
67
|
|
80
68
|
Returns:
|
81
69
|
For `strict`, a Pandas `DataFrame` with information for the specified logs.
|
@@ -85,16 +73,16 @@ def events_df(
|
|
85
73
|
verify_prerequisites()
|
86
74
|
|
87
75
|
# resolve filter/detail
|
88
|
-
if filter
|
89
|
-
detail = EventsDetail(filter=lambda e: True)
|
90
|
-
elif callable(filter):
|
76
|
+
if callable(filter):
|
91
77
|
detail = EventsDetail(filter=filter)
|
92
78
|
else:
|
93
|
-
detail = EventsDetail(
|
79
|
+
detail = EventsDetail()
|
94
80
|
|
95
81
|
return _read_samples_df(
|
96
82
|
logs=logs,
|
97
83
|
columns=columns,
|
98
84
|
strict=strict,
|
99
85
|
detail=detail,
|
86
|
+
progress=not quiet,
|
87
|
+
parallel=parallel,
|
100
88
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING, Callable, Literal, TypeAlias
|
3
|
+
from typing import TYPE_CHECKING, Callable, Literal, Sequence, TypeAlias
|
4
4
|
|
5
5
|
from inspect_ai.log._file import list_eval_logs
|
6
6
|
from inspect_ai.model._chat_message import ChatMessage
|
@@ -10,41 +10,45 @@ if TYPE_CHECKING:
|
|
10
10
|
|
11
11
|
from typing_extensions import overload
|
12
12
|
|
13
|
-
from ..columns import Column,
|
13
|
+
from ..columns import Column, ColumnError
|
14
14
|
from ..samples.table import MessagesDetail, _read_samples_df
|
15
15
|
from ..util import LogPaths, verify_prerequisites
|
16
16
|
from .columns import MessageColumns
|
17
17
|
|
18
|
-
MessageFilter: TypeAlias =
|
19
|
-
list[Literal["system", "user", "assistant", "tool"]] | Callable[[ChatMessage], bool]
|
20
|
-
)
|
18
|
+
MessageFilter: TypeAlias = Callable[[ChatMessage], bool]
|
21
19
|
"""Filter for `messages_df()` rows."""
|
22
20
|
|
23
21
|
|
24
22
|
@overload
|
25
23
|
def messages_df(
|
26
24
|
logs: LogPaths = list_eval_logs(),
|
27
|
-
columns:
|
25
|
+
columns: Sequence[Column] = MessageColumns,
|
28
26
|
filter: MessageFilter | None = None,
|
29
27
|
strict: Literal[True] = True,
|
28
|
+
parallel: bool | int = False,
|
29
|
+
quiet: bool = False,
|
30
30
|
) -> "pd.DataFrame": ...
|
31
31
|
|
32
32
|
|
33
33
|
@overload
|
34
34
|
def messages_df(
|
35
35
|
logs: LogPaths = list_eval_logs(),
|
36
|
-
columns:
|
36
|
+
columns: Sequence[Column] = MessageColumns,
|
37
37
|
filter: MessageFilter | None = None,
|
38
38
|
strict: Literal[False] = False,
|
39
|
-
|
39
|
+
parallel: bool | int = False,
|
40
|
+
quiet: bool = False,
|
41
|
+
) -> tuple["pd.DataFrame", list[ColumnError]]: ...
|
40
42
|
|
41
43
|
|
42
44
|
def messages_df(
|
43
45
|
logs: LogPaths = list_eval_logs(),
|
44
|
-
columns:
|
46
|
+
columns: Sequence[Column] = MessageColumns,
|
45
47
|
filter: MessageFilter | None = None,
|
46
48
|
strict: bool = True,
|
47
|
-
|
49
|
+
parallel: bool | int = False,
|
50
|
+
quiet: bool = False,
|
51
|
+
) -> "pd.DataFrame" | tuple["pd.DataFrame", list[ColumnError]]:
|
48
52
|
"""Read a dataframe containing messages from a set of evals.
|
49
53
|
|
50
54
|
Args:
|
@@ -52,9 +56,14 @@ def messages_df(
|
|
52
56
|
Defaults to the contents of the currently active log directory
|
53
57
|
(e.g. ./logs or INSPECT_LOG_DIR).
|
54
58
|
columns: Specification for what columns to read from log files.
|
55
|
-
filter:
|
59
|
+
filter: Callable that filters messages
|
56
60
|
strict: Raise import errors immediately. Defaults to `True`.
|
57
61
|
If `False` then a tuple of `DataFrame` and errors is returned.
|
62
|
+
parallel: If `True`, use `ProcessPoolExecutor` to read logs in parallel
|
63
|
+
(with workers based on `mp.cpu_count()`, capped at 8). If `int`, read
|
64
|
+
in parallel with the specified number of workers. If `False` (the default)
|
65
|
+
do not read in parallel.
|
66
|
+
quiet: If `True` do not print any output or progress (defaults to `False`).
|
58
67
|
|
59
68
|
Returns:
|
60
69
|
For `strict`, a Pandas `DataFrame` with information for the specified logs.
|
@@ -64,16 +73,16 @@ def messages_df(
|
|
64
73
|
verify_prerequisites()
|
65
74
|
|
66
75
|
# resolve filter/detail
|
67
|
-
if filter
|
68
|
-
detail = MessagesDetail(filter=lambda m: True)
|
69
|
-
elif callable(filter):
|
76
|
+
if callable(filter):
|
70
77
|
detail = MessagesDetail(filter=filter)
|
71
78
|
else:
|
72
|
-
detail = MessagesDetail(
|
79
|
+
detail = MessagesDetail()
|
73
80
|
|
74
81
|
return _read_samples_df(
|
75
82
|
logs=logs,
|
76
83
|
columns=columns,
|
77
84
|
strict=strict,
|
78
85
|
detail=detail,
|
86
|
+
parallel=parallel,
|
87
|
+
progress=not quiet,
|
79
88
|
)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from contextlib import contextmanager
|
2
|
-
from typing import Iterator
|
2
|
+
from typing import Iterator, Protocol
|
3
3
|
|
4
4
|
from rich.progress import (
|
5
5
|
BarColumn,
|
@@ -11,10 +11,40 @@ from rich.progress import (
|
|
11
11
|
)
|
12
12
|
|
13
13
|
|
14
|
+
class ImportProgress(Protocol):
|
15
|
+
def update(self) -> None: ...
|
16
|
+
def reset(self, description: str, completed: int, total: int) -> None: ...
|
17
|
+
|
18
|
+
|
19
|
+
class NoProgress(ImportProgress):
|
20
|
+
def update(self) -> None:
|
21
|
+
pass
|
22
|
+
|
23
|
+
def reset(self, description: str, completed: int, total: int) -> None:
|
24
|
+
pass
|
25
|
+
|
26
|
+
|
27
|
+
class RichImportProgress(ImportProgress):
|
28
|
+
def __init__(self, progress: Progress, task_id: TaskID) -> None:
|
29
|
+
self._progress = progress
|
30
|
+
self._task_id = task_id
|
31
|
+
|
32
|
+
def update(self) -> None:
|
33
|
+
self._progress.update(self._task_id, advance=1)
|
34
|
+
|
35
|
+
def reset(self, description: str, completed: int, total: int) -> None:
|
36
|
+
self._progress.reset(
|
37
|
+
self._task_id, description=description, completed=completed, total=total
|
38
|
+
)
|
39
|
+
|
40
|
+
|
41
|
+
@contextmanager
|
42
|
+
def no_progress() -> Iterator[ImportProgress]:
|
43
|
+
yield NoProgress()
|
44
|
+
|
45
|
+
|
14
46
|
@contextmanager
|
15
|
-
def import_progress(
|
16
|
-
description: str, total: float | None
|
17
|
-
) -> Iterator[tuple[Progress, TaskID]]:
|
47
|
+
def import_progress(description: str, total: float | None) -> Iterator[ImportProgress]:
|
18
48
|
with Progress(
|
19
49
|
TextColumn("[progress.description]{task.description:<18}"),
|
20
50
|
BarColumn(),
|
@@ -23,4 +53,4 @@ def import_progress(
|
|
23
53
|
transient=True,
|
24
54
|
) as progress:
|
25
55
|
task_id = progress.add_task(description, total=total)
|
26
|
-
yield progress, task_id
|
56
|
+
yield RichImportProgress(progress, task_id)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
from datetime import date, datetime, time, timezone
|
3
|
-
from typing import Any, Callable, Literal, Type, cast, overload
|
3
|
+
from typing import Any, Callable, Literal, Sequence, Type, cast, overload
|
4
4
|
|
5
5
|
import yaml
|
6
6
|
from jsonpath_ng import JSONPath # type: ignore
|
@@ -20,38 +20,41 @@ from .extract import model_to_record
|
|
20
20
|
|
21
21
|
@overload
|
22
22
|
def import_record(
|
23
|
+
log: EvalLog,
|
23
24
|
record: EvalLog
|
24
25
|
| EvalSampleSummary
|
25
26
|
| EvalSample
|
26
27
|
| ChatMessage
|
27
28
|
| Event
|
28
29
|
| dict[str, JsonValue],
|
29
|
-
columns:
|
30
|
+
columns: Sequence[Column],
|
30
31
|
strict: Literal[True] = True,
|
31
32
|
) -> dict[str, ColumnType]: ...
|
32
33
|
|
33
34
|
|
34
35
|
@overload
|
35
36
|
def import_record(
|
37
|
+
log: EvalLog,
|
36
38
|
record: EvalLog
|
37
39
|
| EvalSampleSummary
|
38
40
|
| EvalSample
|
39
41
|
| ChatMessage
|
40
42
|
| Event
|
41
43
|
| dict[str, JsonValue],
|
42
|
-
columns:
|
44
|
+
columns: Sequence[Column],
|
43
45
|
strict: Literal[False],
|
44
46
|
) -> tuple[dict[str, ColumnType], list[ColumnError]]: ...
|
45
47
|
|
46
48
|
|
47
49
|
def import_record(
|
50
|
+
log: EvalLog,
|
48
51
|
record: EvalLog
|
49
52
|
| EvalSampleSummary
|
50
53
|
| EvalSample
|
51
54
|
| ChatMessage
|
52
55
|
| Event
|
53
56
|
| dict[str, JsonValue],
|
54
|
-
columns:
|
57
|
+
columns: Sequence[Column],
|
55
58
|
strict: bool = True,
|
56
59
|
) -> dict[str, ColumnType] | tuple[dict[str, ColumnType], list[ColumnError]]:
|
57
60
|
# resolve the record BaseModel into a dict (and optionally a summary dict).
|
@@ -80,7 +83,7 @@ def import_record(
|
|
80
83
|
try:
|
81
84
|
result[name] = _resolve_value(value, column.type)
|
82
85
|
except ValueError as ex:
|
83
|
-
error = ColumnError(name, path=column.path,
|
86
|
+
error = ColumnError(name, path=column.path, error=ex, log=log)
|
84
87
|
if strict:
|
85
88
|
raise ValueError(str(error))
|
86
89
|
else:
|
@@ -90,10 +93,10 @@ def import_record(
|
|
90
93
|
def field_not_found(
|
91
94
|
name: str, path: JSONPath | None, required_type: str | None = None
|
92
95
|
) -> None:
|
93
|
-
|
96
|
+
ex = ValueError(
|
94
97
|
f"field not of type {required_type}" if required_type else "field not found"
|
95
98
|
)
|
96
|
-
error = ColumnError(name, path=path,
|
99
|
+
error = ColumnError(name, path=path, error=ex, log=log)
|
97
100
|
if strict:
|
98
101
|
raise ValueError(str(error))
|
99
102
|
else:
|
@@ -157,7 +160,8 @@ def import_record(
|
|
157
160
|
error = ColumnError(
|
158
161
|
column.name,
|
159
162
|
path=str(column.path) if column.path else None,
|
160
|
-
|
163
|
+
error=ex,
|
164
|
+
log=log,
|
161
165
|
)
|
162
166
|
if strict:
|
163
167
|
raise ValueError(str(error))
|
@@ -190,7 +194,7 @@ def import_record(
|
|
190
194
|
return result, errors
|
191
195
|
|
192
196
|
|
193
|
-
def resolve_duplicate_columns(columns:
|
197
|
+
def resolve_duplicate_columns(columns: Sequence[Column]) -> list[Column]:
|
194
198
|
"""Remove duplicate columns (with the later columns winning)"""
|
195
199
|
seen = set[str]()
|
196
200
|
deduped: list[Column] = []
|
@@ -65,7 +65,7 @@ SampleSummary: list[Column] = [
|
|
65
65
|
SampleColumn("model_usage", path="model_usage"),
|
66
66
|
SampleColumn("total_time", path="total_time"),
|
67
67
|
SampleColumn("working_time", path="total_time"),
|
68
|
-
SampleColumn("error", path="error"),
|
68
|
+
SampleColumn("error", path="error", default=""),
|
69
69
|
SampleColumn("limit", path="limit"),
|
70
70
|
SampleColumn("retries", path="retries"),
|
71
71
|
]
|