From 87351278b52a894c4d6a84abc260bae93d3cbddc Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 2 Jul 2026 09:13:41 +0000 Subject: [PATCH] fix: bound web-probe observe analyze output --- scripts/src/hwlab-node/web-observe-render.ts | 140 +++++++++++++++++++ scripts/src/hwlab-node/web-probe-observe.ts | 116 ++++++++++++--- 2 files changed, 239 insertions(+), 17 deletions(-) diff --git a/scripts/src/hwlab-node/web-observe-render.ts b/scripts/src/hwlab-node/web-observe-render.ts index f6f52b85..3433e85b 100644 --- a/scripts/src/hwlab-node/web-observe-render.ts +++ b/scripts/src/hwlab-node/web-observe-render.ts @@ -330,6 +330,146 @@ export function renderWebObserveAnalyzeTable(value: Record): st webObserveText(item.overBudgetCount ?? item.overFiveSecondCount), webObserveShort(webObserveArray(item.slowSamples).map((sample) => webObserveText(record(sample)?.otelTraceId)).filter((text) => text !== "-").join(",") || "-", 36), ]); + const frontendPerformance = record(analysis?.frontendPerformance); + const frontendPerformanceSummary = nonEmptyRecord(frontendPerformance?.summary) ?? frontendPerformance; + const frontendPerformanceHotspots = record(analysis?.frontendPerformanceHotspots); + const frontendProfileFunctions = webObserveArray(frontendPerformanceHotspots?.profileFunctions ?? frontendPerformance?.profileFunctions ?? frontendPerformance?.profileHotspots).map(record).filter((item): item is Record => item !== null).slice(0, 4); + const frontendProfileStacks = webObserveArray(frontendPerformanceHotspots?.profileStacks ?? frontendPerformance?.profileStacks).map(record).filter((item): item is Record => item !== null).slice(0, 3); + const frontendScriptHotspots = webObserveArray(frontendPerformanceHotspots?.scripts ?? frontendPerformance?.scripts ?? frontendPerformance?.scriptHotspots).map(record).filter((item): item is Record => item !== null).slice(0, 4); + const highSignalFindings = dedupeWebObserveRecords( + [...toolFindings, ...findings, ...archiveRedFindings], + (item) => String(item.kind ?? item.id ?? item.code ?? ""), + ).slice(0, 6); + const id = webObserveText(value.id); + const statusLine = value.ok === false + ? `blocked reason=${webObserveText(record(value.failure)?.reason)} exit=${webObserveText(result.exitCode)} timeout=${webObserveText(result.timedOut)} recovered=${webObserveText(record(value.failure)?.recoveredFromArtifacts)}` + : `ok=${webObserveText(value.ok !== false)} exit=${webObserveText(result.exitCode)} timeout=${webObserveText(result.timedOut)}`; + const compactLines = [ + `web-probe observe analyze (${webObserveText(value.status)})`, + "", + webObserveTable(["ID", "NODE", "LANE", "STATUS", "SCOPE", "STATE_DIR"], [[ + id, + value.node, + value.lane, + statusLine, + webObserveShort([webObserveText(jsonlScope?.mode ?? "current"), webObserveText(record(jsonlScope?.focus)?.mode), jsonlScope?.archivePrefix ? webObserveText(jsonlScope.archivePrefix) : ""].filter((part) => part && part !== "-").join(":"), 36), + webObserveShort(webObserveText(analysis?.stateDir), 72), + ]]), + "", + "Artifacts:", + webObserveTable(["KIND", "PATH", "SHA256"], [ + ["report.json", webObserveShort(webObserveText(analysis?.reportJsonPath), 72), webObserveShort(webObserveText(analysis?.reportJsonSha256), 24)], + ["report.md", webObserveShort(webObserveText(analysis?.reportMdPath), 72), webObserveShort(webObserveText(analysis?.reportMdSha256), 24)], + ]), + "", + "Counts:", + webObserveTable(["SAMPLES", "CONTROL", "NETWORK", "CONSOLE", "ARTIFACTS", "ARCHIVE_SAMPLES", "ARCHIVE_RED"], [[ + webObserveText(counts?.samples), + webObserveText(counts?.control), + webObserveText(counts?.network), + webObserveText(counts?.console), + webObserveText(counts?.artifacts), + webObserveText(record(archiveSummary?.sampleMetrics)?.sampleCount), + webObserveText(archiveSummary?.redFindingCount), + ]]), + "", + "Tool state:", + webObserveTable(["PENDING", "PROCESSING", "ABANDONED", "FAILED", "RUNNER_ERRORS", "COMMAND_FAILURES"], [[ + webObserveText(commandState?.pendingCount), + webObserveText(commandState?.processingCount), + webObserveText(commandState?.abandonedCount), + webObserveText(commandState?.failedCount), + webObserveText(runnerErrors.length), + webObserveText(commandFailures.length), + ]]), + "", + "Findings:", + webObserveTable(["KIND", "SEVERITY", "COUNT", "ROOT_CAUSE", "SUMMARY"], highSignalFindings.length > 0 ? highSignalFindings.map((item) => [ + webObserveShort(webObserveText(item.kind ?? item.id ?? item.code), 38), + webObserveText(item.severity ?? item.level), + webObserveText(item.count ?? item.sampleCount), + webObserveShort(webObserveText(item.rootCause ?? item.rootCauseStatus), 38), + webObserveShort(webObserveText(item.summary ?? item.message), 104), + ]) : [["-", "-", "-", "-", "-"]]), + "", + "Turn/loading:", + webObserveTable(["ROUNDS", "TURNS", "ROWS", "ELAPSED_JUMP", "RECENT_JUMP", "LOADING_SAMPLES", "MAX_LOADING", `OVER_${loadingBudgetLabel}`], [[ + webObserveText(roundCount), + webObserveText(turnColumnCount), + webObserveText(sampleMetrics?.turnTimingRows), + webObserveText(sampleMetrics?.turnTimingTotalElapsedForwardJumpCount ?? elapsedForwardJumps.length), + webObserveText(sampleMetrics?.turnTimingRecentUpdateJumpCount ?? sampleMetrics?.turnTimingRecentUpdateSawtoothJumpCount), + webObserveText(loadingSummary?.loadingSampleCount ?? sampleMetrics?.loadingSampleCount), + webObserveText(loadingSummary?.maxSimultaneousCount ?? sampleMetrics?.loadingMaxCount), + webObserveText(loadingSummary?.overBudgetSegmentCount ?? loadingSummary?.overFiveSecondSegmentCount ?? sampleMetrics?.loadingOverFiveSecondSegmentCount), + ]]), + "", + "Request/performance:", + webObserveTable(["REQUESTS", "TOTAL_PEAK", "PAGE_PEAK", "API_PEAK", "SLOW_API", "ARCHIVE_SLOW", "SSE_SLOW"], [[ + webObserveText(requestRateSummary?.requestCount), + webObserveText(requestRateSummary?.totalPeakPerMinute), + webObserveText(requestRateSummary?.pagePeakPerMinute), + webObserveText(requestRateSummary?.apiPathPeakPerMinute), + webObserveText(slowApis.length), + webObserveText(archiveSlowApis.length), + webObserveText(sseStreams.length), + ]]), + webObserveTable(["PATH", "SAMPLES", "P95", "MAX", "OVER"], (slowApis.length > 0 ? slowApis : archiveSlowApis).slice(0, 4).map((item) => [ + webObserveShort(webObserveText(item.path ?? item.route), 56), + webObserveText(item.sampleCount), + webObserveText(item.p95Ms ?? item.p95), + webObserveText(item.maxMs ?? item.max), + webObserveText(item.overBudgetCount ?? item.overFiveSecondCount), + ]).concat((slowApis.length > 0 || archiveSlowApis.length > 0) ? [] : [["-", "-", "-", "-", "-"]])), + "", + "Frontend performance:", + webObserveTable(["EVENTS", "LONGTASK", "LOAF", "GAP", "CAPTURES", "MAX_LONGTASK", "MAX_LOAF", "MAX_GAP"], [[ + webObserveText(frontendPerformanceSummary?.eventCount), + webObserveText(frontendPerformanceSummary?.longTaskCount), + webObserveText(frontendPerformanceSummary?.longAnimationFrameCount), + webObserveText(frontendPerformanceSummary?.eventLoopGapCount), + webObserveText(frontendPerformanceSummary?.captureCount), + webObserveText(frontendPerformanceSummary?.maxLongTaskMs), + webObserveText(frontendPerformanceSummary?.maxLongAnimationFrameMs), + webObserveText(frontendPerformanceSummary?.maxEventLoopGapMs), + ]]), + webObserveTable(["CPU_SELF_MS", "TOTAL_MS", "HITS", "FUNCTION", "URL"], frontendProfileFunctions.length > 0 ? frontendProfileFunctions.map((item) => [ + webObserveText(item.selfTimeMs), + webObserveText(item.totalTimeMs), + webObserveText(item.hitCount), + webObserveShort(webObserveText(item.functionName ?? item.name), 42), + webObserveShort(webObserveText(item.url ?? item.sourceURL ?? item.scriptUrl), 64), + ]) : [["-", "-", "-", "-", "-"]]), + webObserveTable(["STACK_SELF_MS", "FRAMES", "FUNCTION", "TOP_FRAME"], frontendProfileStacks.length > 0 ? frontendProfileStacks.map((item) => { + const frames = webObserveArray(item.frames).map(record).filter((frame): frame is Record => frame !== null); + const topFrame = frames[0] ?? {}; + return [ + webObserveText(item.selfTimeMs), + webObserveText(item.frameCount ?? frames.length), + webObserveShort(webObserveText(item.functionName ?? item.name), 38), + webObserveShort(`${webObserveText(topFrame.functionName ?? "(anonymous)")}@${webObserveText(topFrame.url ?? topFrame.scriptId)}`, 68), + ]; + }) : [["-", "-", "-", "-"]]), + webObserveTable(["LOAF_MS", "COUNT", "FUNCTION", "URL"], frontendScriptHotspots.length > 0 ? frontendScriptHotspots.map((item) => [ + webObserveText(item.totalDurationMs ?? item.durationMs), + webObserveText(item.count ?? item.hitCount), + webObserveShort(webObserveText(item.sourceFunctionName ?? item.functionName ?? item.invoker), 42), + webObserveShort(webObserveText(item.sourceURL ?? item.url), 64), + ]) : [["-", "-", "-", "-"]]), + "", + "Next:", + ` bun scripts/cli.ts web-probe observe collect ${id} --view turn-summary`, + ` bun scripts/cli.ts web-probe observe collect ${id} --view timeline --command-id `, + ` bun scripts/cli.ts web-probe observe collect ${id} --view trace-frame --trace-id --sample-seq `, + ` bun scripts/cli.ts web-probe observe collect ${id} --view workbench-triad --trace-id `, + ` bun scripts/cli.ts web-probe observe collect ${id} --view performance-summary`, + ` bun scripts/cli.ts web-probe observe collect ${id} --view files --file analysis/report.json --finding `, + "", + "Disclosure:", + " default analyze output is a bounded index; full offline report stays in report.md/report.json artifacts.", + ]; + if (value.full !== true) return compactLines.join("\n"); + const lines = [ `web-probe observe analyze (${webObserveText(value.status)})`, "", diff --git a/scripts/src/hwlab-node/web-probe-observe.ts b/scripts/src/hwlab-node/web-probe-observe.ts index 8852dd45..5e635ddb 100644 --- a/scripts/src/hwlab-node/web-probe-observe.ts +++ b/scripts/src/hwlab-node/web-probe-observe.ts @@ -2453,6 +2453,30 @@ export function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOption " }", " }", "}", + "if (Buffer.byteLength(output, 'utf8') > 7500) {", + " const frontend = objectOrNull(compact.frontendPerformance) || {};", + " const frontendHotspots = objectOrNull(compact.frontendPerformanceHotspots) || {};", + " output = compactOutput({", + " ok: compact.ok,", + " counts: compact.counts ? { samples: compact.counts.samples ?? null, control: compact.counts.control ?? null, network: compact.counts.network ?? null, console: compact.counts.console ?? null, artifacts: compact.counts.artifacts ?? null } : null,", + " jsonlScope: compact.jsonlScope ? { mode: compact.jsonlScope.mode ?? null, focus: objectOrNull(compact.jsonlScope.focus)?.mode ?? null, archivePrefix: compact.jsonlScope.archivePrefix ?? null } : null,", + " analysisWindow: compact.analysisWindow ? { name: compact.analysisWindow.name ?? null, fromAt: compact.analysisWindow.fromAt ?? null, toAt: compact.analysisWindow.toAt ?? null, samples: compact.analysisWindow.samples ?? null, network: compact.analysisWindow.network ?? null, console: compact.analysisWindow.console ?? null } : null,", + " archiveSummary: compact.archiveSummary ? { redFindingCount: compact.archiveSummary.redFindingCount ?? null, findingCount: compact.archiveSummary.findingCount ?? null, sampleCount: compact.archiveSummary.sampleMetrics?.sampleCount ?? null, slowPathCount: compact.archiveSummary.pagePerformance?.slowPathCount ?? null } : null,", + " sampleMetrics: compact.sampleMetrics ? { sampleCount: compact.sampleMetrics.sampleCount ?? null, roundCount: Array.isArray(compact.sampleMetrics.rounds) ? compact.sampleMetrics.rounds.length : null, turnColumnCount: Array.isArray(compact.sampleMetrics.turnColumns) ? compact.sampleMetrics.turnColumns.length : null, turnTimingRows: compact.sampleMetrics.turnTimingRows ?? null, turnTimingTotalElapsedForwardJumpCount: compact.sampleMetrics.turnTimingTotalElapsedForwardJumpCount ?? null, turnTimingRecentUpdateJumpCount: compact.sampleMetrics.turnTimingRecentUpdateJumpCount ?? compact.sampleMetrics.turnTimingRecentUpdateSawtoothJumpCount ?? null, loadingSampleCount: compact.sampleMetrics.loadingSampleCount ?? null, loadingMaxCount: compact.sampleMetrics.loadingMaxCount ?? null, loadingOverFiveSecondSegmentCount: compact.sampleMetrics.loadingOverFiveSecondSegmentCount ?? null } : null,", + " requestRate: compact.requestRate ? { requestCount: compact.requestRate.requestCount ?? null, totalPeakPerMinute: compact.requestRate.totalPeakPerMinute ?? null, pagePeakPerMinute: compact.requestRate.pagePeakPerMinute ?? null, apiPathPeakPerMinute: compact.requestRate.apiPathPeakPerMinute ?? null, overThresholdPeakCount: compact.requestRate.overThresholdPeakCount ?? null } : null,", + " frontendPerformance: frontend ? { eventCount: frontend.eventCount ?? null, longTaskCount: frontend.longTaskCount ?? null, longAnimationFrameCount: frontend.longAnimationFrameCount ?? null, eventLoopGapCount: frontend.eventLoopGapCount ?? null, captureCount: frontend.captureCount ?? null, maxLongTaskMs: frontend.maxLongTaskMs ?? null, maxLongAnimationFrameMs: frontend.maxLongAnimationFrameMs ?? null, maxEventLoopGapMs: frontend.maxEventLoopGapMs ?? null, profileHotspotCount: frontend.profileHotspotCount ?? null, scriptHotspotCount: frontend.scriptHotspotCount ?? null, profileFunctions: takeHead(frontendHotspots.profileFunctions, 3).map((item) => ({ functionName: clip(item?.functionName ?? item?.name, 64), url: clip(item?.url ?? item?.sourceURL, 96), selfTimeMs: item?.selfTimeMs ?? null, totalTimeMs: item?.totalTimeMs ?? null, hitCount: item?.hitCount ?? null })), profileStacks: takeHead(frontendHotspots.profileStacks, 2).map((item) => ({ functionName: clip(item?.functionName ?? item?.name, 64), selfTimeMs: item?.selfTimeMs ?? null, frameCount: item?.frameCount ?? (Array.isArray(item?.frames) ? item.frames.length : null) })), scripts: takeHead(frontendHotspots.scripts, 3).map((item) => ({ functionName: clip(item?.sourceFunctionName ?? item?.functionName ?? item?.invoker, 64), url: clip(item?.sourceURL ?? item?.url, 96), totalDurationMs: item?.totalDurationMs ?? null, count: item?.count ?? null })) } : null,", + " commandState: compact.commandState ? { pendingCount: compact.commandState.pendingCount ?? null, processingCount: compact.commandState.processingCount ?? null, abandonedCount: compact.commandState.abandonedCount ?? null, failedCount: compact.commandState.failedCount ?? null } : null,", + " findings: Array.isArray(compact.findings) ? compact.findings.slice(0, 4).map((item) => ({ kind: item.kind ?? item.code ?? null, severity: item.severity ?? item.level ?? null, count: item.count ?? item.sampleCount ?? null, summary: clip(item.summary ?? item.message, 100) })) : [],", + " archiveRedFindings: Array.isArray(compact.archiveRedFindings) ? compact.archiveRedFindings.slice(0, 3).map((item) => ({ kind: item.kind ?? item.code ?? null, severity: item.severity ?? item.level ?? null, count: item.count ?? item.sampleCount ?? null, summary: clip(item.summary ?? item.message, 100) })) : [],", + " pagePerformanceSlowApi: Array.isArray(compact.pagePerformanceSlowApi) ? compact.pagePerformanceSlowApi.slice(0, 2).map((item) => ({ path: item.path ?? item.route ?? null, sampleCount: item.sampleCount ?? null, p95Ms: item.p95Ms ?? null, maxMs: item.maxMs ?? null, overBudgetCount: item.overBudgetCount ?? null })) : [],", + " reportJsonPath: compact.reportJsonPath ?? reportJsonPath,", + " reportJsonSha256: compact.reportJsonSha256 ?? sha256(reportJsonPath),", + " reportMdPath: compact.reportMdPath ?? reportMdPath,", + " reportMdSha256: compact.reportMdSha256 ?? sha256(reportMdPath),", + " analyzer: { exitCode: compact.analyzer?.exitCode ?? null, recoveredFrom: compact.analyzer?.recoveredFrom ?? null, stdoutBytes: compact.analyzer?.stdoutBytes ?? null, stderrBytes: compact.analyzer?.stderrBytes ?? null, compactStdoutLimited: true, hardFallback: true, byteClamp: 7500 },", + " valuesRedacted: true", + " });", + "}", "console.log(output);", "UNIDESK_WEB_OBSERVE_ANALYZE_COMPACT", "exit \"$analyzer_exit\"", @@ -2528,6 +2552,7 @@ export function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOption browserFreezePolicy, wrapper: buildWebObserveWrapperForObserveOptions("analyze", options, spec.workspace), result: analysis === null ? compactCommandResultWithStdoutTail(result) : compactCommandResult(result), + full: options.full, valuesRedacted: true, }; return options.raw ? compactWebObserveAnalyzePayloadForRaw(payload, options.compactRaw) : withWebObserveAnalyzeRendered(payload); @@ -2558,8 +2583,10 @@ function compactWebObserveAnalyzeAnalysisForRaw(analysis: Record 0 ? requestRate : recordValue(requestRateCurve.summary), requestRateCurve: compactWebObserveAnalyzeRequestRateCurveForRaw(requestRateCurve), - requestRatePeaks: arrayRecordsValue(analysis.requestRatePeaks ?? requestRateCurve.peaks ?? requestRate.peaks).slice(0, 8), - pagePerformanceSlowApi: arrayRecordsValue(analysis.pagePerformanceSlowApi ?? analysis.archivePagePerformanceSlowApi).slice(0, 8).map((item) => ({ + requestRatePeaks: arrayRecordsValue(analysis.requestRatePeaks ?? requestRateCurve.peaks ?? requestRate.peaks).slice(0, 4), + frontendPerformance: compactWebObserveAnalyzeFrontendPerformanceForRaw(frontendPerformance, frontendHotspots), + pagePerformanceSlowApi: arrayRecordsValue(analysis.pagePerformanceSlowApi ?? analysis.archivePagePerformanceSlowApi).slice(0, 4).map((item) => ({ path: stringOrNullValue(item.path ?? item.route), route: stringOrNullValue(item.route ?? item.path), sampleCount: numberOrNullValue(item.sampleCount), @@ -2611,13 +2639,74 @@ function compactWebObserveAnalyzeRequestRateCurveForRaw(value: Record, hotspots: Record): Record | null { + const summary = recordValue(performance.summary); + const hasPerformance = Object.keys(summary).length > 0 + || arrayRecordsValue(performance.profileHotspots).length > 0 + || arrayRecordsValue(performance.profileStacks).length > 0 + || arrayRecordsValue(performance.scriptHotspots).length > 0 + || arrayRecordsValue(hotspots.profileFunctions).length > 0 + || arrayRecordsValue(hotspots.profileStacks).length > 0 + || arrayRecordsValue(hotspots.scripts).length > 0; + if (!hasPerformance) return null; + const performanceSummary = Object.keys(summary).length > 0 ? summary : performance; + return { + summary: { + eventCount: numberOrNullValue(performanceSummary.eventCount), + longTaskCount: numberOrNullValue(performanceSummary.longTaskCount), + longAnimationFrameCount: numberOrNullValue(performanceSummary.longAnimationFrameCount), + eventLoopGapCount: numberOrNullValue(performanceSummary.eventLoopGapCount), + captureCount: numberOrNullValue(performanceSummary.captureCount), + maxLongTaskMs: numberOrNullValue(performanceSummary.maxLongTaskMs), + maxLongAnimationFrameMs: numberOrNullValue(performanceSummary.maxLongAnimationFrameMs), + maxEventLoopGapMs: numberOrNullValue(performanceSummary.maxEventLoopGapMs), + profileHotspotCount: numberOrNullValue(performanceSummary.profileHotspotCount), + scriptHotspotCount: numberOrNullValue(performanceSummary.scriptHotspotCount), + valuesRedacted: true, + }, + profileFunctions: arrayRecordsValue(hotspots.profileFunctions ?? performance.profileHotspots).slice(0, 4).map(compactWebObserveAnalyzeFrontendHotspotForRaw), + profileStacks: arrayRecordsValue(hotspots.profileStacks ?? performance.profileStacks).slice(0, 3).map(compactWebObserveAnalyzeFrontendStackForRaw), + scriptHotspots: arrayRecordsValue(hotspots.scripts ?? performance.scriptHotspots).slice(0, 4).map(compactWebObserveAnalyzeFrontendHotspotForRaw), + valuesRedacted: true, + }; +} + +function compactWebObserveAnalyzeFrontendHotspotForRaw(value: Record): Record { + return { + functionName: stringOrNullValue(value.functionName ?? value.name ?? value.sourceFunctionName ?? value.invoker)?.slice(0, 80) ?? null, + url: stringOrNullValue(value.url ?? value.sourceURL ?? value.scriptUrl)?.slice(0, 120) ?? null, + lineNumber: numberOrNullValue(value.lineNumber ?? value.line), + columnNumber: numberOrNullValue(value.columnNumber ?? value.column), + selfTimeMs: numberOrNullValue(value.selfTimeMs ?? value.selfMs), + totalTimeMs: numberOrNullValue(value.totalTimeMs ?? value.totalMs), + totalDurationMs: numberOrNullValue(value.totalDurationMs ?? value.durationMs), + hitCount: numberOrNullValue(value.hitCount ?? value.sampleCount ?? value.count), + captureCount: numberOrNullValue(value.captureCount), + valuesRedacted: true, + }; +} + +function compactWebObserveAnalyzeFrontendStackForRaw(value: Record): Record { + return { + ...compactWebObserveAnalyzeFrontendHotspotForRaw(value), + frameCount: numberOrNullValue(value.frameCount), + frames: arrayRecordsValue(value.frames).slice(0, 2).map((frame) => ({ + functionName: stringOrNullValue(frame.functionName ?? frame.name)?.slice(0, 64) ?? null, + url: stringOrNullValue(frame.url ?? frame.sourceURL ?? frame.scriptUrl)?.slice(0, 96) ?? null, + lineNumber: numberOrNullValue(frame.lineNumber ?? frame.line), + columnNumber: numberOrNullValue(frame.columnNumber ?? frame.column), + valuesRedacted: true, + })), + }; +} + function compactWebObserveAnalyzeRequestRateBucketForRaw(value: Record): Record { return { t: stringOrNullValue(value.startAt ?? value.t), @@ -2633,7 +2722,7 @@ function compactWebObserveAnalyzeRequestRateSeriesForRaw(value: Record): Record { return { kind: stringOrNullValue(value.kind ?? value.id ?? value.code), - id: stringOrNullValue(value.id ?? value.kind ?? value.code), - code: stringOrNullValue(value.code ?? value.id ?? value.kind), severity: stringOrNullValue(value.severity ?? value.level), - level: stringOrNullValue(value.level ?? value.severity), count: numberOrNullValue(value.count ?? value.sampleCount), - sampleCount: numberOrNullValue(value.sampleCount ?? value.count), timingSourceOfTruth: stringOrNullValue(value.timingSourceOfTruth ?? value.expectedElapsedSource ?? value.evidenceKind), timingStatus: stringOrNullValue(value.timingStatus), timingAlert: value.timingAlert === true, - summary: stringOrNullValue(value.summary ?? value.message)?.slice(0, 220) ?? null, - message: stringOrNullValue(value.message ?? value.summary)?.slice(0, 220) ?? null, - rootCause: stringOrNullValue(value.rootCause)?.slice(0, 140) ?? null, + summary: stringOrNullValue(value.summary ?? value.message)?.slice(0, 140) ?? null, + rootCause: stringOrNullValue(value.rootCause)?.slice(0, 90) ?? null, rootCauseStatus: stringOrNullValue(value.rootCauseStatus)?.slice(0, 90) ?? null, rootCauseConfidence: stringOrNullValue(value.rootCauseConfidence)?.slice(0, 40) ?? null, - nextAction: stringOrNullValue(value.nextAction)?.slice(0, 240) ?? null, - evidenceSummary: stringOrNullValue(value.evidenceSummary)?.slice(0, 220) ?? null, valuesRedacted: true, }; }