diff --git a/inspect-ui/src/panels/ActionList.css b/inspect-ui/src/panels/ActionList.css index c322f97..b9a1925 100644 --- a/inspect-ui/src/panels/ActionList.css +++ b/inspect-ui/src/panels/ActionList.css @@ -130,3 +130,54 @@ text-overflow: ellipsis; white-space: nowrap; } + +.action-list-extractor-changes { + grid-column: 2; + display: flex; + flex-direction: column; + gap: 2px; + margin-top: 4px; + padding-top: 4px; + border-top: 1px solid var(--surface-border); +} + +.action-list-extractor-changes-heading { + color: var(--text-muted); + text-transform: lowercase; + letter-spacing: 0.5px; +} + +.action-list-extractor-change-row { + display: grid; + grid-template-columns: minmax(80px, max-content) 1fr; + gap: 6px; + color: var(--text-primary); +} + +.action-list-extractor-change-name { + color: var(--text-muted); +} + +.action-list-extractor-change-diff { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.action-list-extractor-change-row-collapsed > summary { + display: grid; + grid-template-columns: minmax(80px, max-content) 1fr; + gap: 6px; + cursor: pointer; +} + +.action-list-extractor-change-full { + grid-column: 1 / -1; + margin: 4px 0 0; + white-space: pre-wrap; + word-break: break-word; + background: var(--surface-base); + padding: 4px 6px; + border-radius: 2px; + font-size: 10px; +} diff --git a/inspect-ui/src/panels/ActionList.tsx b/inspect-ui/src/panels/ActionList.tsx index 75b03bd..9e6bbc1 100644 --- a/inspect-ui/src/panels/ActionList.tsx +++ b/inspect-ui/src/panels/ActionList.tsx @@ -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 : `""`} + {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 ( +
+ {`prev: ${prev}\ncurr: ${curr}`}
+
+