mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 20:17:09 +00:00
feat(inspect-ui): render extractor-change breadcrumbs at violations
Show prev -> curr for each extractor whose value changed on the selected step, anchored under the violation row in ActionList. Long values collapse into <details> so the inline diff stays readable while the full payload is one click away.
This commit is contained in:
1 parent
e44ad56749
commit
d0cf5a98c7
3 files changed
+125
No files matched your search
@@ -121,6 +121,24 @@ function contentTextForStep(step: Step): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
const MAX_INLINE_VALUE = 80;
|
||||
|
||||
function formatExtractorValue(value: unknown): string {
|
||||
if (value === null) return "null";
|
||||
if (value === undefined) return "undefined";
|
||||
if (typeof value === "string") return JSON.stringify(value);
|
||||
try {
|
||||
return JSON.stringify(value);
|
||||
} catch {
|
||||
return String(value);
|
||||
}
|
||||
}
|
||||
|
||||
function truncateForInline(text: string): string {
|
||||
if (text.length <= MAX_INLINE_VALUE) return text;
|
||||
return `${text.slice(0, MAX_INLINE_VALUE - 1)}...`;
|
||||
}
|
||||
|
||||
function positionTextForStep(step: Step): string | null {
|
||||
const action = step.action;
|
||||
if (!action) {
|
||||
@@ -289,6 +307,56 @@ export default function ActionList({
|
||||
{contentText ? contentText : `""`}
|
||||
</span>
|
||||
</div>
|
||||
{step.has_violations && selectedStep?.extractor_changes
|
||||
? (() => {
|
||||
const entries = Object.entries(selectedStep.extractor_changes);
|
||||
if (entries.length === 0) return null;
|
||||
entries.sort(([a], [b]) => a.localeCompare(b));
|
||||
return (
|
||||
<div className="action-list-extractor-changes">
|
||||
<div className="action-list-extractor-changes-heading">
|
||||
extractor changes
|
||||
</div>
|
||||
{entries.map(([name, change]) => {
|
||||
const prev = formatExtractorValue(change.prev);
|
||||
const curr = formatExtractorValue(change.curr);
|
||||
const inlineFits =
|
||||
prev.length + curr.length <= MAX_INLINE_VALUE * 2;
|
||||
if (inlineFits) {
|
||||
return (
|
||||
<div key={name} className="action-list-extractor-change-row">
|
||||
<span className="action-list-extractor-change-name">
|
||||
{name}
|
||||
</span>
|
||||
<span className="action-list-extractor-change-diff">
|
||||
{truncateForInline(prev)} → {truncateForInline(curr)}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<details
|
||||
key={name}
|
||||
className="action-list-extractor-change-row action-list-extractor-change-row-collapsed"
|
||||
>
|
||||
<summary>
|
||||
<span className="action-list-extractor-change-name">
|
||||
{name}
|
||||
</span>
|
||||
<span className="action-list-extractor-change-diff">
|
||||
{truncateForInline(prev)} → {truncateForInline(curr)}
|
||||
</span>
|
||||
</summary>
|
||||
<pre className="action-list-extractor-change-full">
|
||||
{`prev: ${prev}\ncurr: ${curr}`}
|
||||
</pre>
|
||||
</details>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
})()
|
||||
: null}
|
||||
</div>
|
||||
) : null}
|
||||
</li>
|
||||
|
||||
Reference in new issue
Block a user