inspect-ai 0.3.98__py3-none-any.whl → 0.3.100__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 -0
- inspect_ai/_cli/log.py +1 -1
- inspect_ai/_display/core/config.py +11 -5
- inspect_ai/_display/core/panel.py +66 -2
- inspect_ai/_display/core/textual.py +5 -2
- inspect_ai/_display/plain/display.py +1 -0
- inspect_ai/_display/rich/display.py +2 -2
- inspect_ai/_display/textual/widgets/transcript.py +41 -1
- inspect_ai/_eval/run.py +12 -4
- inspect_ai/_eval/score.py +2 -4
- inspect_ai/_eval/task/log.py +1 -1
- inspect_ai/_eval/task/run.py +59 -81
- inspect_ai/_eval/task/task.py +1 -1
- inspect_ai/_util/_async.py +1 -1
- inspect_ai/_util/content.py +11 -6
- inspect_ai/_util/interrupt.py +2 -2
- inspect_ai/_util/text.py +7 -0
- inspect_ai/_util/working.py +8 -37
- inspect_ai/_view/__init__.py +0 -0
- inspect_ai/_view/schema.py +3 -1
- inspect_ai/_view/view.py +14 -0
- inspect_ai/_view/www/CLAUDE.md +15 -0
- inspect_ai/_view/www/dist/assets/index.css +273 -169
- inspect_ai/_view/www/dist/assets/index.js +20079 -17019
- inspect_ai/_view/www/log-schema.json +122 -8
- inspect_ai/_view/www/package.json +5 -1
- inspect_ai/_view/www/src/@types/log.d.ts +20 -2
- inspect_ai/_view/www/src/app/App.tsx +1 -15
- inspect_ai/_view/www/src/app/appearance/icons.ts +4 -1
- inspect_ai/_view/www/src/app/content/MetaDataGrid.tsx +24 -6
- inspect_ai/_view/www/src/app/content/MetadataGrid.module.css +0 -5
- inspect_ai/_view/www/src/app/content/RenderedContent.tsx +221 -205
- inspect_ai/_view/www/src/app/log-view/LogViewContainer.tsx +2 -1
- inspect_ai/_view/www/src/app/log-view/tabs/SamplesTab.tsx +5 -0
- inspect_ai/_view/www/src/app/routing/url.ts +84 -4
- inspect_ai/_view/www/src/app/samples/InlineSampleDisplay.module.css +0 -5
- inspect_ai/_view/www/src/app/samples/SampleDialog.module.css +1 -1
- inspect_ai/_view/www/src/app/samples/SampleDisplay.module.css +7 -0
- inspect_ai/_view/www/src/app/samples/SampleDisplay.tsx +26 -19
- inspect_ai/_view/www/src/app/samples/SampleSummaryView.module.css +1 -2
- inspect_ai/_view/www/src/app/samples/chat/ChatMessage.tsx +8 -6
- inspect_ai/_view/www/src/app/samples/chat/ChatMessageRow.tsx +0 -4
- inspect_ai/_view/www/src/app/samples/chat/ChatViewVirtualList.tsx +3 -2
- inspect_ai/_view/www/src/app/samples/chat/MessageContent.tsx +2 -0
- inspect_ai/_view/www/src/app/samples/chat/MessageContents.tsx +2 -0
- inspect_ai/_view/www/src/app/samples/chat/messages.ts +1 -0
- inspect_ai/_view/www/src/app/samples/chat/tools/ToolCallView.tsx +1 -0
- inspect_ai/_view/www/src/app/samples/list/SampleRow.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/scores/SampleScoresGrid.module.css +2 -2
- inspect_ai/_view/www/src/app/samples/transcript/ErrorEventView.tsx +2 -3
- inspect_ai/_view/www/src/app/samples/transcript/InfoEventView.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/InputEventView.tsx +1 -2
- inspect_ai/_view/www/src/app/samples/transcript/ModelEventView.module.css +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/ModelEventView.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/SampleInitEventView.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/SampleLimitEventView.tsx +3 -2
- inspect_ai/_view/www/src/app/samples/transcript/SandboxEventView.tsx +4 -5
- inspect_ai/_view/www/src/app/samples/transcript/ScoreEventView.tsx +1 -1
- inspect_ai/_view/www/src/app/samples/transcript/SpanEventView.tsx +1 -2
- inspect_ai/_view/www/src/app/samples/transcript/StepEventView.tsx +1 -3
- inspect_ai/_view/www/src/app/samples/transcript/SubtaskEventView.tsx +1 -2
- inspect_ai/_view/www/src/app/samples/transcript/ToolEventView.tsx +3 -4
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptPanel.module.css +42 -0
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptPanel.tsx +77 -0
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualList.tsx +27 -71
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.module.css +13 -3
- inspect_ai/_view/www/src/app/samples/transcript/TranscriptVirtualListComponent.tsx +27 -2
- inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.module.css +1 -0
- inspect_ai/_view/www/src/app/samples/transcript/event/EventPanel.tsx +21 -22
- inspect_ai/_view/www/src/app/samples/transcript/outline/OutlineRow.module.css +45 -0
- inspect_ai/_view/www/src/app/samples/transcript/outline/OutlineRow.tsx +223 -0
- inspect_ai/_view/www/src/app/samples/transcript/outline/TranscriptOutline.module.css +10 -0
- inspect_ai/_view/www/src/app/samples/transcript/outline/TranscriptOutline.tsx +258 -0
- inspect_ai/_view/www/src/app/samples/transcript/outline/tree-visitors.ts +187 -0
- inspect_ai/_view/www/src/app/samples/transcript/state/StateEventRenderers.tsx +8 -1
- inspect_ai/_view/www/src/app/samples/transcript/state/StateEventView.tsx +3 -4
- inspect_ai/_view/www/src/app/samples/transcript/transform/hooks.ts +78 -0
- inspect_ai/_view/www/src/app/samples/transcript/transform/treeify.ts +340 -135
- inspect_ai/_view/www/src/app/samples/transcript/transform/utils.ts +3 -0
- inspect_ai/_view/www/src/app/samples/transcript/types.ts +2 -0
- inspect_ai/_view/www/src/app/types.ts +5 -1
- inspect_ai/_view/www/src/client/api/api-browser.ts +2 -2
- inspect_ai/_view/www/src/components/LiveVirtualList.tsx +6 -1
- inspect_ai/_view/www/src/components/MarkdownDiv.tsx +1 -1
- inspect_ai/_view/www/src/components/PopOver.tsx +422 -0
- inspect_ai/_view/www/src/components/PulsingDots.module.css +9 -9
- inspect_ai/_view/www/src/components/PulsingDots.tsx +4 -1
- inspect_ai/_view/www/src/components/StickyScroll.tsx +183 -0
- inspect_ai/_view/www/src/components/TabSet.tsx +4 -0
- inspect_ai/_view/www/src/state/hooks.ts +52 -2
- inspect_ai/_view/www/src/state/logSlice.ts +4 -3
- inspect_ai/_view/www/src/state/samplePolling.ts +8 -0
- inspect_ai/_view/www/src/state/sampleSlice.ts +53 -9
- inspect_ai/_view/www/src/state/scrolling.ts +152 -0
- inspect_ai/_view/www/src/utils/attachments.ts +7 -0
- inspect_ai/_view/www/src/utils/python.ts +18 -0
- inspect_ai/_view/www/yarn.lock +269 -6
- inspect_ai/agent/_react.py +12 -7
- inspect_ai/agent/_run.py +46 -11
- inspect_ai/analysis/beta/_dataframe/samples/table.py +19 -18
- inspect_ai/log/_bundle.py +5 -3
- inspect_ai/log/_log.py +3 -3
- inspect_ai/log/_recorders/file.py +2 -9
- inspect_ai/log/_transcript.py +1 -1
- inspect_ai/model/_call_tools.py +6 -2
- inspect_ai/model/_openai.py +1 -1
- inspect_ai/model/_openai_responses.py +78 -39
- inspect_ai/model/_openai_web_search.py +31 -0
- inspect_ai/model/_providers/anthropic.py +3 -6
- inspect_ai/model/_providers/azureai.py +72 -3
- inspect_ai/model/_providers/openai.py +2 -1
- inspect_ai/model/_providers/providers.py +1 -1
- inspect_ai/scorer/_metric.py +1 -2
- inspect_ai/solver/_task_state.py +2 -2
- inspect_ai/tool/_tool.py +6 -2
- inspect_ai/tool/_tool_def.py +27 -4
- inspect_ai/tool/_tool_info.py +2 -0
- inspect_ai/tool/_tools/_web_search/_google.py +15 -4
- inspect_ai/tool/_tools/_web_search/_tavily.py +35 -12
- inspect_ai/tool/_tools/_web_search/_web_search.py +214 -45
- inspect_ai/util/__init__.py +6 -0
- inspect_ai/util/_json.py +3 -0
- inspect_ai/util/_limit.py +374 -141
- inspect_ai/util/_sandbox/docker/compose.py +20 -11
- inspect_ai/util/_span.py +1 -1
- {inspect_ai-0.3.98.dist-info → inspect_ai-0.3.100.dist-info}/METADATA +3 -3
- {inspect_ai-0.3.98.dist-info → inspect_ai-0.3.100.dist-info}/RECORD +131 -117
- {inspect_ai-0.3.98.dist-info → inspect_ai-0.3.100.dist-info}/WHEEL +1 -1
- {inspect_ai-0.3.98.dist-info → inspect_ai-0.3.100.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.98.dist-info → inspect_ai-0.3.100.dist-info}/licenses/LICENSE +0 -0
- {inspect_ai-0.3.98.dist-info → inspect_ai-0.3.100.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,14 @@
|
|
1
|
-
import JSON5 from "json5";
|
2
|
-
import { ApplicationIcons } from "../appearance/icons";
|
3
|
-
|
4
|
-
import { ChatMessageRenderer } from "../../app/samples/chat/ChatMessageRenderer";
|
5
|
-
import { ANSIDisplay } from "../../components/AnsiDisplay";
|
6
|
-
import { formatNumber } from "../../utils/format";
|
7
|
-
import { MetaDataView } from "./MetaDataView";
|
8
|
-
|
9
1
|
import clsx from "clsx";
|
2
|
+
import JSON5 from "json5";
|
10
3
|
import { FC, Fragment, isValidElement, JSX, ReactNode } from "react";
|
4
|
+
import { ANSIDisplay } from "../../components/AnsiDisplay";
|
11
5
|
import JSONPanel from "../../components/JsonPanel";
|
6
|
+
import { MarkdownDiv } from "../../components/MarkdownDiv";
|
7
|
+
import { formatNumber } from "../../utils/format";
|
12
8
|
import { isJson } from "../../utils/json";
|
9
|
+
import { ApplicationIcons } from "../appearance/icons";
|
10
|
+
import { ChatMessageRenderer } from "../samples/chat/ChatMessageRenderer";
|
11
|
+
import { MetaDataView } from "./MetaDataView";
|
13
12
|
import styles from "./RenderedContent.module.css";
|
14
13
|
import { Buckets, ContentRenderer, RenderOptions } from "./types";
|
15
14
|
|
@@ -17,6 +16,7 @@ interface RenderedContentProps {
|
|
17
16
|
id: string;
|
18
17
|
entry: { name: string; value: unknown };
|
19
18
|
renderOptions?: RenderOptions;
|
19
|
+
renderObject?(entry: any): ReactNode;
|
20
20
|
}
|
21
21
|
|
22
22
|
/**
|
@@ -26,15 +26,16 @@ export const RenderedContent: FC<RenderedContentProps> = ({
|
|
26
26
|
id,
|
27
27
|
entry,
|
28
28
|
renderOptions = { renderString: "markdown" },
|
29
|
+
renderObject,
|
29
30
|
}): JSX.Element => {
|
30
31
|
// Explicitly specify return type
|
31
32
|
if (entry.value === null) {
|
32
33
|
return <span>[null]</span>;
|
33
34
|
}
|
34
|
-
|
35
|
-
const renderer = Object.keys(
|
35
|
+
const renderers = contentRenderers(renderObject);
|
36
|
+
const renderer = Object.keys(renderers)
|
36
37
|
.map((key) => {
|
37
|
-
return
|
38
|
+
return renderers[key];
|
38
39
|
})
|
39
40
|
.sort((a, b) => {
|
40
41
|
return a.bucket - b.bucket;
|
@@ -69,216 +70,231 @@ export const RenderedContent: FC<RenderedContentProps> = ({
|
|
69
70
|
* Object containing different content renderers.
|
70
71
|
* Each renderer is responsible for rendering a specific type of content.
|
71
72
|
*/
|
72
|
-
const contentRenderers:
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
canRender: (entry) => {
|
89
|
-
if (typeof entry.value === "string") {
|
90
|
-
const trimmed = entry.value.trim();
|
91
|
-
return isJson(trimmed);
|
92
|
-
}
|
93
|
-
return false;
|
94
|
-
},
|
95
|
-
render: (_id, entry, _options) => {
|
96
|
-
const obj = JSON5.parse(entry.value);
|
97
|
-
return { rendered: <JSONPanel data={obj as Record<string, unknown>} /> };
|
98
|
-
},
|
99
|
-
},
|
100
|
-
|
101
|
-
Model: {
|
102
|
-
bucket: Buckets.intermediate,
|
103
|
-
canRender: (entry) => {
|
104
|
-
return typeof entry.value === "object" && entry.value._model;
|
105
|
-
},
|
106
|
-
render: (_id, entry, _options) => {
|
107
|
-
return {
|
108
|
-
rendered: (
|
109
|
-
<Fragment>
|
110
|
-
<i className={ApplicationIcons.model} /> {entry.value._model}
|
111
|
-
</Fragment>
|
112
|
-
),
|
113
|
-
};
|
114
|
-
},
|
115
|
-
},
|
116
|
-
Boolean: {
|
117
|
-
bucket: Buckets.intermediate,
|
118
|
-
canRender: (entry) => {
|
119
|
-
return typeof entry.value === "boolean";
|
120
|
-
},
|
121
|
-
render: (id, entry, options) => {
|
122
|
-
entry.value = entry.value.toString();
|
123
|
-
return contentRenderers.String.render(id, entry, options);
|
124
|
-
},
|
125
|
-
},
|
126
|
-
Number: {
|
127
|
-
bucket: Buckets.intermediate,
|
128
|
-
canRender: (entry) => {
|
129
|
-
return typeof entry.value === "number";
|
130
|
-
},
|
131
|
-
render: (id, entry, options) => {
|
132
|
-
entry.value = formatNumber(entry.value);
|
133
|
-
return contentRenderers.String.render(id, entry, options);
|
134
|
-
},
|
135
|
-
},
|
136
|
-
String: {
|
137
|
-
bucket: Buckets.final,
|
138
|
-
canRender: (entry) => {
|
139
|
-
return typeof entry.value === "string";
|
73
|
+
const contentRenderers: (
|
74
|
+
renderObject?: (object: any) => ReactNode,
|
75
|
+
) => Record<string, ContentRenderer> = (renderObject) => {
|
76
|
+
const contentRenderers: Record<string, ContentRenderer> = {
|
77
|
+
AnsiString: {
|
78
|
+
bucket: Buckets.first,
|
79
|
+
canRender: (entry) => {
|
80
|
+
return (
|
81
|
+
typeof entry.value === "string" && entry.value.indexOf("\u001b") > -1
|
82
|
+
);
|
83
|
+
},
|
84
|
+
render: (_id, entry, _options) => {
|
85
|
+
return {
|
86
|
+
rendered: <ANSIDisplay output={entry.value} />,
|
87
|
+
};
|
88
|
+
},
|
140
89
|
},
|
141
|
-
|
142
|
-
|
143
|
-
|
90
|
+
JsonString: {
|
91
|
+
bucket: Buckets.first,
|
92
|
+
canRender: (entry) => {
|
93
|
+
if (typeof entry.value === "string") {
|
94
|
+
const trimmed = entry.value.trim();
|
95
|
+
return isJson(trimmed);
|
96
|
+
}
|
97
|
+
return false;
|
98
|
+
},
|
99
|
+
render: (_id, entry, _options) => {
|
100
|
+
const obj = JSON5.parse(entry.value);
|
144
101
|
return {
|
145
|
-
rendered:
|
102
|
+
rendered: <JSONPanel data={obj as Record<string, unknown>} />,
|
146
103
|
};
|
147
|
-
}
|
104
|
+
},
|
105
|
+
},
|
106
|
+
|
107
|
+
Model: {
|
108
|
+
bucket: Buckets.intermediate,
|
109
|
+
canRender: (entry) => {
|
110
|
+
return typeof entry.value === "object" && entry.value._model;
|
111
|
+
},
|
112
|
+
render: (_id, entry, _options) => {
|
148
113
|
return {
|
149
114
|
rendered: (
|
150
|
-
<
|
151
|
-
{
|
152
|
-
</
|
115
|
+
<Fragment>
|
116
|
+
<i className={ApplicationIcons.model} /> {entry.value._model}
|
117
|
+
</Fragment>
|
153
118
|
),
|
154
119
|
};
|
155
|
-
}
|
120
|
+
},
|
156
121
|
},
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
const types = new Set(
|
167
|
-
entry.value
|
168
|
-
.filter((e: unknown) => e !== null)
|
169
|
-
.map((e: unknown) => {
|
170
|
-
return typeof e;
|
171
|
-
}),
|
172
|
-
);
|
173
|
-
return types.size === 1;
|
174
|
-
} else {
|
175
|
-
return false;
|
176
|
-
}
|
122
|
+
Boolean: {
|
123
|
+
bucket: Buckets.intermediate,
|
124
|
+
canRender: (entry) => {
|
125
|
+
return typeof entry.value === "boolean";
|
126
|
+
},
|
127
|
+
render: (id, entry, options) => {
|
128
|
+
entry.value = entry.value.toString();
|
129
|
+
return contentRenderers.String.render(id, entry, options);
|
130
|
+
},
|
177
131
|
},
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
}
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
className={"font-size-small"}
|
188
|
-
entries={arrayMap}
|
189
|
-
tableOptions="borderless,sm"
|
190
|
-
compact={true}
|
191
|
-
/>
|
192
|
-
);
|
193
|
-
return { rendered: arrayRendered };
|
132
|
+
Number: {
|
133
|
+
bucket: Buckets.intermediate,
|
134
|
+
canRender: (entry) => {
|
135
|
+
return typeof entry.value === "number";
|
136
|
+
},
|
137
|
+
render: (id, entry, options) => {
|
138
|
+
entry.value = formatNumber(entry.value);
|
139
|
+
return contentRenderers.String.render(id, entry, options);
|
140
|
+
},
|
194
141
|
},
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
142
|
+
String: {
|
143
|
+
bucket: Buckets.final,
|
144
|
+
canRender: (entry) => {
|
145
|
+
return typeof entry.value === "string";
|
146
|
+
},
|
147
|
+
render: (_id, entry, options) => {
|
148
|
+
const rendered = entry.value.trim();
|
149
|
+
if (options.renderString === "markdown") {
|
150
|
+
return {
|
151
|
+
rendered: <MarkdownDiv markdown={rendered} />,
|
152
|
+
};
|
153
|
+
} else {
|
154
|
+
return {
|
155
|
+
rendered: (
|
156
|
+
<pre className={clsx(styles.preWrap, styles.preCompact)}>
|
157
|
+
{rendered}
|
158
|
+
</pre>
|
159
|
+
),
|
160
|
+
};
|
161
|
+
}
|
162
|
+
},
|
201
163
|
},
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
164
|
+
Array: {
|
165
|
+
bucket: Buckets.intermediate,
|
166
|
+
canRender: (entry) => {
|
167
|
+
const isArray = Array.isArray(entry.value);
|
168
|
+
if (isArray) {
|
169
|
+
if (entry.value.length === 0 || entry.value.length === 1) {
|
170
|
+
return true;
|
171
|
+
}
|
172
|
+
const types = new Set(
|
173
|
+
entry.value
|
174
|
+
.filter((e: unknown) => e !== null)
|
175
|
+
.map((e: unknown) => {
|
176
|
+
return typeof e;
|
177
|
+
}),
|
215
178
|
);
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
},
|
241
|
-
Html: {
|
242
|
-
bucket: Buckets.intermediate,
|
243
|
-
canRender: (entry) => {
|
244
|
-
return typeof entry.value === "object" && entry.value._html;
|
179
|
+
return types.size === 1;
|
180
|
+
} else {
|
181
|
+
return false;
|
182
|
+
}
|
183
|
+
},
|
184
|
+
render: (id, entry, _options) => {
|
185
|
+
const arrayMap: Record<string, unknown> = {};
|
186
|
+
entry.value.forEach((e: unknown, index: number) => {
|
187
|
+
arrayMap[`[${index}]`] = e;
|
188
|
+
});
|
189
|
+
|
190
|
+
const arrayRendered = renderObject ? (
|
191
|
+
renderObject(arrayMap)
|
192
|
+
) : (
|
193
|
+
<MetaDataView
|
194
|
+
id={id}
|
195
|
+
className={"font-size-small"}
|
196
|
+
entries={arrayMap}
|
197
|
+
tableOptions="borderless,sm"
|
198
|
+
compact={true}
|
199
|
+
/>
|
200
|
+
);
|
201
|
+
return { rendered: arrayRendered };
|
202
|
+
},
|
245
203
|
},
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
204
|
+
ChatMessage: ChatMessageRenderer,
|
205
|
+
web_search: {
|
206
|
+
bucket: Buckets.intermediate,
|
207
|
+
canRender: (entry) => {
|
208
|
+
return typeof entry.value === "object" && entry.name === "web_search";
|
209
|
+
},
|
210
|
+
render: (_id, entry, _options) => {
|
211
|
+
const results: ReactNode[] = [];
|
212
|
+
results.push(
|
213
|
+
<div className={styles.query}>
|
214
|
+
<i className={ApplicationIcons.search}></i> {entry.value.query}
|
215
|
+
</div>,
|
216
|
+
);
|
217
|
+
entry.value.results.forEach(
|
218
|
+
(result: { url: string; summary: string }) => {
|
219
|
+
results.push(
|
220
|
+
<div>
|
221
|
+
<a href={result.url}>{result.url}</a>
|
222
|
+
</div>,
|
223
|
+
);
|
224
|
+
results.push(
|
225
|
+
<div className={clsx("text-size-smaller", styles.summary)}>
|
226
|
+
{result.summary}
|
227
|
+
</div>,
|
228
|
+
);
|
229
|
+
},
|
230
|
+
);
|
231
|
+
return {
|
232
|
+
rendered: results,
|
233
|
+
};
|
234
|
+
},
|
250
235
|
},
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
236
|
+
web_browser: {
|
237
|
+
bucket: Buckets.intermediate,
|
238
|
+
canRender: (entry) => {
|
239
|
+
return (
|
240
|
+
typeof entry.value === "string" &&
|
241
|
+
entry.name?.startsWith("web_browser")
|
242
|
+
);
|
243
|
+
},
|
244
|
+
render: (_id, entry, _options) => {
|
245
|
+
return {
|
246
|
+
rendered: <pre className={styles.preWrap}>{entry.value}</pre>,
|
247
|
+
};
|
248
|
+
},
|
258
249
|
},
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
250
|
+
Html: {
|
251
|
+
bucket: Buckets.intermediate,
|
252
|
+
canRender: (entry) => {
|
253
|
+
return typeof entry.value === "object" && entry.value._html;
|
254
|
+
},
|
255
|
+
render: (_id, entry, _options) => {
|
256
|
+
return {
|
257
|
+
rendered: entry.value._html,
|
258
|
+
};
|
259
|
+
},
|
263
260
|
},
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
261
|
+
Image: {
|
262
|
+
bucket: Buckets.intermediate,
|
263
|
+
canRender: (entry) => {
|
264
|
+
return (
|
265
|
+
typeof entry.value === "string" &&
|
266
|
+
entry.value.startsWith("data:image/")
|
267
|
+
);
|
268
|
+
},
|
269
|
+
render: (_id, entry, _options) => {
|
270
|
+
return {
|
271
|
+
rendered: <img src={entry.value} />,
|
272
|
+
};
|
273
|
+
},
|
269
274
|
},
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
275
|
+
Object: {
|
276
|
+
bucket: Buckets.intermediate,
|
277
|
+
canRender: (entry) => {
|
278
|
+
return typeof entry.value === "object";
|
279
|
+
},
|
280
|
+
render: (id, entry, _options) => {
|
281
|
+
if (renderObject) {
|
282
|
+
return { rendered: renderObject(entry.value) };
|
283
|
+
} else {
|
284
|
+
return {
|
285
|
+
rendered: (
|
286
|
+
<MetaDataView
|
287
|
+
id={id}
|
288
|
+
className={"text-size-smaller"}
|
289
|
+
entries={entry.value}
|
290
|
+
tableOptions="borderless,sm"
|
291
|
+
compact
|
292
|
+
/>
|
293
|
+
),
|
294
|
+
};
|
295
|
+
}
|
296
|
+
},
|
282
297
|
},
|
283
|
-
}
|
298
|
+
};
|
299
|
+
return contentRenderers;
|
284
300
|
};
|
@@ -21,6 +21,7 @@ export const LogViewContainer: FC = () => {
|
|
21
21
|
epoch?: string;
|
22
22
|
sampleTabId?: string;
|
23
23
|
}>();
|
24
|
+
|
24
25
|
const initialState = useStore((state) => state.app.initialState);
|
25
26
|
const clearInitialState = useStore(
|
26
27
|
(state) => state.appActions.clearInitialState,
|
@@ -80,7 +81,7 @@ export const LogViewContainer: FC = () => {
|
|
80
81
|
}
|
81
82
|
|
82
83
|
// Reset the sample
|
83
|
-
if (logPath !== prevLogPath) {
|
84
|
+
if (prevLogPath && logPath !== prevLogPath) {
|
84
85
|
clearSelectedSample();
|
85
86
|
|
86
87
|
clearSelectedLogSummary();
|
@@ -105,6 +105,7 @@ export const SamplesTab: FC<SamplesTabProps> = ({ running }) => {
|
|
105
105
|
const groupBy = useGroupBy();
|
106
106
|
const groupByOrder = useGroupByOrder();
|
107
107
|
const currentScore = useScore();
|
108
|
+
const selectSample = useStore((state) => state.logActions.selectSample);
|
108
109
|
|
109
110
|
const selectedSampleIdentifier = useStore(
|
110
111
|
(state) => state.sample.sample_identifier,
|
@@ -186,6 +187,10 @@ export const SamplesTab: FC<SamplesTabProps> = ({ running }) => {
|
|
186
187
|
})
|
187
188
|
: [],
|
188
189
|
);
|
190
|
+
|
191
|
+
if (sampleSummaries.length === 1) {
|
192
|
+
selectSample(0);
|
193
|
+
}
|
189
194
|
}, [sampleSummaries, sampleProcessor]);
|
190
195
|
|
191
196
|
const title =
|
@@ -1,4 +1,7 @@
|
|
1
|
+
import { useMemo } from "react";
|
2
|
+
import { useParams } from "react-router-dom";
|
1
3
|
import { kSampleMessagesTabId, kSampleTranscriptTabId } from "../../constants";
|
4
|
+
import { useStore } from "../../state/store";
|
2
5
|
import { directoryRelativeUrl } from "../../utils/uri";
|
3
6
|
|
4
7
|
export const kLogRouteUrlPattern = "/logs/:logPath/:tabId?/:sampleTabId?";
|
@@ -46,6 +49,80 @@ export const sampleEventUrl = (
|
|
46
49
|
return `${baseUrl}?event=${eventId}`;
|
47
50
|
};
|
48
51
|
|
52
|
+
export const useSampleMessageUrl = (
|
53
|
+
messageId: string | null,
|
54
|
+
sampleId?: string | number,
|
55
|
+
sampleEpoch?: string | number,
|
56
|
+
) => {
|
57
|
+
const {
|
58
|
+
logPath: urlLogPath,
|
59
|
+
sampleId: urlSampleId,
|
60
|
+
epoch: urlEpoch,
|
61
|
+
} = useParams<{
|
62
|
+
logPath?: string;
|
63
|
+
tabId?: string;
|
64
|
+
sampleId?: string;
|
65
|
+
epoch?: string;
|
66
|
+
}>();
|
67
|
+
|
68
|
+
const log_file = useStore((state) => state.logs.selectedLogFile);
|
69
|
+
const log_dir = useStore((state) => state.logs.logs.log_dir);
|
70
|
+
|
71
|
+
let targetLogPath = urlLogPath;
|
72
|
+
if (!targetLogPath && log_file) {
|
73
|
+
targetLogPath = makeLogPath(log_file, log_dir);
|
74
|
+
}
|
75
|
+
|
76
|
+
const eventUrl = useMemo(() => {
|
77
|
+
return messageId && targetLogPath
|
78
|
+
? sampleMessageUrl(
|
79
|
+
messageId,
|
80
|
+
targetLogPath,
|
81
|
+
sampleId || urlSampleId,
|
82
|
+
sampleEpoch || urlEpoch,
|
83
|
+
)
|
84
|
+
: undefined;
|
85
|
+
}, [targetLogPath, messageId, sampleId, urlSampleId, sampleEpoch, urlEpoch]);
|
86
|
+
return eventUrl;
|
87
|
+
};
|
88
|
+
|
89
|
+
export const useSampleEventUrl = (
|
90
|
+
eventId: string,
|
91
|
+
sampleId?: string | number,
|
92
|
+
sampleEpoch?: string | number,
|
93
|
+
) => {
|
94
|
+
const {
|
95
|
+
logPath: urlLogPath,
|
96
|
+
sampleId: urlSampleId,
|
97
|
+
epoch: urlEpoch,
|
98
|
+
} = useParams<{
|
99
|
+
logPath?: string;
|
100
|
+
tabId?: string;
|
101
|
+
sampleId?: string;
|
102
|
+
epoch?: string;
|
103
|
+
}>();
|
104
|
+
|
105
|
+
const log_file = useStore((state) => state.logs.selectedLogFile);
|
106
|
+
const log_dir = useStore((state) => state.logs.logs.log_dir);
|
107
|
+
|
108
|
+
let targetLogPath = urlLogPath;
|
109
|
+
if (!targetLogPath && log_file) {
|
110
|
+
targetLogPath = makeLogPath(log_file, log_dir);
|
111
|
+
}
|
112
|
+
|
113
|
+
const eventUrl = useMemo(() => {
|
114
|
+
return targetLogPath
|
115
|
+
? sampleEventUrl(
|
116
|
+
eventId,
|
117
|
+
targetLogPath,
|
118
|
+
sampleId || urlSampleId,
|
119
|
+
sampleEpoch || urlEpoch,
|
120
|
+
)
|
121
|
+
: undefined;
|
122
|
+
}, [targetLogPath, eventId, sampleId, urlSampleId, sampleEpoch, urlEpoch]);
|
123
|
+
return eventUrl;
|
124
|
+
};
|
125
|
+
|
49
126
|
export const sampleMessageUrl = (
|
50
127
|
messageId: string,
|
51
128
|
logPath: string,
|
@@ -63,8 +140,12 @@ export const sampleMessageUrl = (
|
|
63
140
|
};
|
64
141
|
|
65
142
|
export const logUrl = (log_file: string, log_dir?: string, tabId?: string) => {
|
143
|
+
return logUrlRaw(makeLogPath(log_file, log_dir), tabId);
|
144
|
+
};
|
145
|
+
|
146
|
+
export const makeLogPath = (log_file: string, log_dir?: string) => {
|
66
147
|
const pathSegment = directoryRelativeUrl(log_file, log_dir);
|
67
|
-
return
|
148
|
+
return pathSegment;
|
68
149
|
};
|
69
150
|
|
70
151
|
export const logUrlRaw = (log_segment: string, tabId?: string) => {
|
@@ -77,9 +158,8 @@ export const logUrlRaw = (log_segment: string, tabId?: string) => {
|
|
77
158
|
|
78
159
|
export const supportsLinking = () => {
|
79
160
|
return (
|
80
|
-
location.hostname !== "localhost" &&
|
81
|
-
location.hostname !== "127.0.0.1" &&
|
82
|
-
location.protocol !== "vscode-webview:"
|
161
|
+
//location.hostname !== "localhost" &&
|
162
|
+
location.hostname !== "127.0.0.1" && location.protocol !== "vscode-webview:"
|
83
163
|
);
|
84
164
|
};
|
85
165
|
|