239 lines
11 KiB
TypeScript
239 lines
11 KiB
TypeScript
// SPEC: PJ2026-01040111 长程观测 draft-2026-06-20-p0-passive-web-probe-observer.
|
|
// Responsibility: bounded raw payloads for web-probe observe collect views.
|
|
|
|
export function compactObserveCollectForRaw(collect: Record<string, unknown> | null): Record<string, unknown> | null {
|
|
if (collect === null) return null;
|
|
const rows = Array.isArray(collect.rows) ? collect.rows.map((item) => {
|
|
const row = observeRecord(item);
|
|
const finalResponse = observeRecord(row.finalResponse);
|
|
return {
|
|
round: row.round ?? null,
|
|
commandId: row.commandId ?? null,
|
|
controlExecutionStatus: row.controlExecutionStatus ?? null,
|
|
turnSubmissionStatus: row.turnSubmissionStatus ?? null,
|
|
turnStatus: row.turnStatus ?? row.status ?? null,
|
|
turnTerminalObserved: row.turnTerminalObserved === true,
|
|
userHash: row.userHash ?? null,
|
|
userBytes: row.userBytes ?? null,
|
|
traceId: row.traceId ?? null,
|
|
status: row.status ?? null,
|
|
elapsedSeconds: row.elapsedSeconds ?? null,
|
|
recentUpdateSeconds: row.recentUpdateSeconds ?? null,
|
|
marks: row.marks ?? null,
|
|
firstSeq: row.firstSeq ?? null,
|
|
lastSeq: row.lastSeq ?? null,
|
|
lastTs: row.lastTs ?? null,
|
|
finalResponse: {
|
|
preview: finalResponse.preview ?? null,
|
|
textHash: finalResponse.textHash ?? null,
|
|
textBytes: finalResponse.textBytes ?? null,
|
|
empty: finalResponse.empty === true,
|
|
},
|
|
valuesRedacted: true,
|
|
};
|
|
}) : undefined;
|
|
const timelineRows = Array.isArray(collect.timelineRows) ? collect.timelineRows.slice(0, 12).map((item) => {
|
|
const row = observeRecord(item);
|
|
return {
|
|
ts: row.ts ?? null,
|
|
seq: row.seq ?? null,
|
|
kind: row.kind ?? null,
|
|
phase: row.phase ?? null,
|
|
type: row.type ?? null,
|
|
commandId: row.commandId ?? null,
|
|
sessionId: row.sessionId ?? null,
|
|
traceId: row.traceId ?? null,
|
|
summary: row.summary ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
}) : undefined;
|
|
const collectView = typeof collect.view === "string" ? collect.view : null;
|
|
const slimNetworkEvidence = (value: unknown): Record<string, unknown> => {
|
|
const source = observeRecord(value);
|
|
const latestTurn = observeRecord(source.latestTurnResponse);
|
|
const latestTrace = observeRecord(source.latestTraceEventsResponse);
|
|
return {
|
|
requestCount: source.requestCount ?? null,
|
|
responseCount: source.responseCount ?? null,
|
|
failedCount: source.failedCount ?? null,
|
|
terminalResponseCount: source.terminalResponseCount ?? null,
|
|
turnResponseCount: source.turnResponseCount ?? null,
|
|
traceEventsResponseCount: source.traceEventsResponseCount ?? null,
|
|
latestTurnResponse: {
|
|
ts: latestTurn.ts ?? null,
|
|
sampleSeq: latestTurn.sampleSeq ?? null,
|
|
status: latestTurn.status ?? null,
|
|
bodySummary: observeRecord(latestTurn.bodySummary),
|
|
valuesRedacted: true,
|
|
},
|
|
latestTraceEventsResponse: {
|
|
ts: latestTrace.ts ?? null,
|
|
sampleSeq: latestTrace.sampleSeq ?? null,
|
|
status: latestTrace.status ?? null,
|
|
bodySummary: observeRecord(latestTrace.bodySummary),
|
|
valuesRedacted: true,
|
|
},
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimFreeze = (value: unknown): Record<string, unknown> => {
|
|
const source = observeRecord(value);
|
|
const blocker = observeRecord(source.latestBlocker);
|
|
return {
|
|
blockerCount: source.blockerCount ?? null,
|
|
responsivenessEventCount: source.responsivenessEventCount ?? null,
|
|
latestBlocker: {
|
|
ts: blocker.ts ?? null,
|
|
sampleSeq: blocker.sampleSeq ?? null,
|
|
rootCause: blocker.rootCause ?? null,
|
|
rootCauseStatus: blocker.rootCauseStatus ?? null,
|
|
fallbackAllowed: blocker.fallbackAllowed === true,
|
|
observed: observeRecord(blocker.observed),
|
|
page: observeRecord(blocker.page),
|
|
valuesRedacted: true,
|
|
},
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimFindings = Array.isArray(collect.findings) ? collect.findings.slice(0, 6).map((item) => {
|
|
const row = observeRecord(item);
|
|
return {
|
|
id: row.id ?? null,
|
|
severity: row.severity ?? null,
|
|
count: row.count ?? null,
|
|
rootCause: row.rootCause ?? row.rootCauseStatus ?? null,
|
|
summary: typeof row.summary === "string" ? row.summary.slice(0, 140) : row.summary ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
}) : undefined;
|
|
const slimPerfFrame = (value: unknown): Record<string, unknown> => {
|
|
const row = observeRecord(value);
|
|
return {
|
|
functionName: row.functionName ?? null,
|
|
url: row.url ?? null,
|
|
scriptId: row.scriptId ?? null,
|
|
lineNumber: row.lineNumber ?? null,
|
|
columnNumber: row.columnNumber ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimPerfStack = (value: unknown): Record<string, unknown> => {
|
|
const row = observeRecord(value);
|
|
return {
|
|
functionName: row.functionName ?? null,
|
|
url: row.url ?? null,
|
|
scriptId: row.scriptId ?? null,
|
|
lineNumber: row.lineNumber ?? null,
|
|
columnNumber: row.columnNumber ?? null,
|
|
selfTimeMs: row.selfTimeMs ?? null,
|
|
totalTimeMs: row.totalTimeMs ?? null,
|
|
hitCount: row.hitCount ?? null,
|
|
frameCount: row.frameCount ?? null,
|
|
frames: Array.isArray(row.frames) ? row.frames.slice(0, 3).map(slimPerfFrame) : [],
|
|
framesOmitted: row.framesOmitted ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimPerfHotspot = (value: unknown): Record<string, unknown> => {
|
|
const row = observeRecord(value);
|
|
return {
|
|
functionName: row.functionName ?? row.sourceFunctionName ?? null,
|
|
url: row.url ?? row.sourceURL ?? null,
|
|
scriptId: row.scriptId ?? null,
|
|
lineNumber: row.lineNumber ?? null,
|
|
columnNumber: row.columnNumber ?? null,
|
|
selfTimeMs: row.selfTimeMs ?? null,
|
|
totalTimeMs: row.totalTimeMs ?? null,
|
|
totalDurationMs: row.totalDurationMs ?? null,
|
|
count: row.count ?? null,
|
|
hitCount: row.hitCount ?? null,
|
|
captureCount: row.captureCount ?? null,
|
|
invoker: row.invoker ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimPerfEvent = (value: unknown): Record<string, unknown> => {
|
|
const row = observeRecord(value);
|
|
return {
|
|
ts: row.ts ?? null,
|
|
kind: row.kind ?? null,
|
|
durationMs: row.durationMs ?? null,
|
|
pageRole: row.pageRole ?? null,
|
|
pageId: row.pageId ?? null,
|
|
sampleSeq: row.sampleSeq ?? null,
|
|
scriptCount: row.scriptCount ?? null,
|
|
url: row.url ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimPerfCapture = (value: unknown): Record<string, unknown> => {
|
|
const row = observeRecord(value);
|
|
return {
|
|
ts: row.ts ?? null,
|
|
commandId: row.commandId ?? null,
|
|
status: row.status ?? null,
|
|
durationMs: row.durationMs ?? null,
|
|
sampleCount: row.sampleCount ?? null,
|
|
nodeCount: row.nodeCount ?? null,
|
|
file: row.file ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
};
|
|
const slimPerfFindings = Array.isArray(collect.findings) ? collect.findings.slice(0, 5).map((item) => {
|
|
const row = observeRecord(item);
|
|
return {
|
|
id: row.id ?? null,
|
|
severity: row.severity ?? null,
|
|
count: row.count ?? null,
|
|
rootCause: row.rootCause ?? row.rootCauseStatus ?? null,
|
|
summary: typeof row.summary === "string" ? row.summary.slice(0, 110) : row.summary ?? null,
|
|
valuesRedacted: true,
|
|
};
|
|
}) : undefined;
|
|
const isPerformanceSummary = collectView === "performance-summary";
|
|
return {
|
|
ok: collect.ok !== false,
|
|
command: collect.command,
|
|
view: collect.view,
|
|
status: collect.status,
|
|
stateDir: collect.stateDir,
|
|
turnCount: collect.turnCount,
|
|
availableTurnCount: collect.availableTurnCount,
|
|
filter: observeRecord(collect.filter),
|
|
error: observeRecord(collect.error),
|
|
artifactFileCount: collect.artifactFileCount ?? collect.fileCount,
|
|
skippedFileCount: collect.skippedFileCount,
|
|
skippedFiles: Array.isArray(collect.skippedFiles) ? collect.skippedFiles.slice(0, 8) : undefined,
|
|
anchor: observeRecord(collect.anchor),
|
|
window: observeRecord(collect.window),
|
|
counts: observeRecord(collect.counts),
|
|
summary: observeRecord(collect.summary),
|
|
...(rows === undefined ? {} : { rows }),
|
|
...(timelineRows === undefined ? {} : { timelineRows }),
|
|
renderedText: collectView === "timeline" || collectView === "workbench-triad" ? undefined : typeof collect.renderedText === "string" ? collect.renderedText : undefined,
|
|
sourceFiles: Array.isArray(collect.sourceFiles) ? collect.sourceFiles : undefined,
|
|
blocker: collect.blocker,
|
|
sampleSeq: collect.sampleSeq,
|
|
traceId: collect.traceId,
|
|
finalResponse: collect.finalResponse,
|
|
statusGap: observeRecord(collect.statusGap),
|
|
evidenceReconciliation: observeRecord(collect.evidenceReconciliation),
|
|
dom: observeRecord(collect.dom),
|
|
networkEvidence: collectView === "workbench-triad" ? slimNetworkEvidence(collect.networkEvidence) : observeRecord(collect.networkEvidence),
|
|
freeze: collectView === "workbench-triad" ? slimFreeze(collect.freeze) : observeRecord(collect.freeze),
|
|
profileHotspots: Array.isArray(collect.profileHotspots) ? (isPerformanceSummary ? collect.profileHotspots.slice(0, 5).map(slimPerfHotspot) : collect.profileHotspots.slice(0, 8)) : undefined,
|
|
profileStacks: Array.isArray(collect.profileStacks) ? (isPerformanceSummary ? collect.profileStacks.slice(0, 3).map(slimPerfStack) : collect.profileStacks.slice(0, 5)) : undefined,
|
|
scriptHotspots: Array.isArray(collect.scriptHotspots) ? (isPerformanceSummary ? collect.scriptHotspots.slice(0, 5).map(slimPerfHotspot) : collect.scriptHotspots.slice(0, 8)) : undefined,
|
|
longTasks: Array.isArray(collect.longTasks) ? (isPerformanceSummary ? collect.longTasks.slice(0, 3).map(slimPerfEvent) : collect.longTasks.slice(0, 8)) : undefined,
|
|
longAnimationFrames: Array.isArray(collect.longAnimationFrames) ? (isPerformanceSummary ? collect.longAnimationFrames.slice(0, 3).map(slimPerfEvent) : collect.longAnimationFrames.slice(0, 8)) : undefined,
|
|
eventLoopGaps: Array.isArray(collect.eventLoopGaps) ? (isPerformanceSummary ? collect.eventLoopGaps.slice(0, 3).map(slimPerfEvent) : collect.eventLoopGaps.slice(0, 8)) : undefined,
|
|
captures: Array.isArray(collect.captures) ? (isPerformanceSummary ? collect.captures.slice(0, 3).map(slimPerfCapture) : collect.captures.slice(0, 8)) : undefined,
|
|
findings: collectView === "workbench-triad" ? slimFindings : isPerformanceSummary ? slimPerfFindings : Array.isArray(collect.findings) ? collect.findings.slice(0, 8) : undefined,
|
|
valuesRedacted: true,
|
|
};
|
|
}
|
|
|
|
function observeRecord(value: unknown): Record<string, unknown> {
|
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
|
|
}
|