From da86d56821201a6def556c23d7d220eece021dfa Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Wed, 24 Jun 2026 03:11:16 +0800 Subject: [PATCH] fix(workbench): dedupe final assistant trace rows (#2009) --- tools/src/hwlab-cli/trace-renderer.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/src/hwlab-cli/trace-renderer.ts b/tools/src/hwlab-cli/trace-renderer.ts index 9571eb4e..ce92154e 100644 --- a/tools/src/hwlab-cli/trace-renderer.ts +++ b/tools/src/hwlab-cli/trace-renderer.ts @@ -20,6 +20,7 @@ export function traceDisplayRows(trace: Record = {}, events: Tr const orderedEvents = traceEventsForDisplay(events); const effectiveTrace = traceWithInferredStart(trace, orderedEvents); const finalResponseText = traceFinalResponseText(effectiveTrace); + const finalResponseFingerprint = traceMessageFingerprint(finalResponseText); const hasCompletionEvent = orderedEvents.some(isCompletionTraceEvent); const rows: TraceEventRow[] = []; const renderedSourceEvents = new Set(); @@ -58,6 +59,7 @@ export function traceDisplayRows(trace: Record = {}, events: Tr continue; } if (isAssistantTraceEvent(event)) { + if (finalResponseFingerprint && traceAssistantEventFingerprint(effectiveTrace, event) === finalResponseFingerprint) continue; rows.push(traceAssistantMessageRow(effectiveTrace, event, { terminal: false }, options)); continue; } @@ -214,7 +216,7 @@ export function traceNoiseEventCount(events: TraceEvent[] = []): number { } function traceAssistantMessageRow(trace: Record, event: TraceEvent, { terminal }: { terminal: boolean }, options: TraceDisplayRowsOptions): TraceEventRow { - const text = cleanTraceDetailText(event.message ?? event.outputSummary ?? assistantStreamText(trace, event) ?? ""); + const text = traceAssistantEventText(trace, event); const index = Number.isInteger(event.messageIndex) ? Number(event.messageIndex) : null; const count = Number.isInteger(event.messageCount) ? Number(event.messageCount) : null; const eventKey = traceEventIdentityToken(event); @@ -229,6 +231,19 @@ function traceAssistantMessageRow(trace: Record, event: TraceEv }; } +function traceAssistantEventText(trace: Record, event: TraceEvent): string { + return cleanTraceDetailText(event.message ?? event.outputSummary ?? assistantStreamText(trace, event) ?? ""); +} + +function traceAssistantEventFingerprint(trace: Record, event: TraceEvent): string | null { + return traceMessageFingerprint(traceAssistantEventText(trace, event)); +} + +function traceMessageFingerprint(value: unknown): string | null { + const text = cleanTraceDetailText(value ?? "").replace(/\s+/gu, " ").trim(); + return text || null; +} + function traceFinalResponseRow(event: TraceEvent, finalText: string, options: TraceDisplayRowsOptions): TraceEventRow { const eventKey = traceEventIdentityToken(event); return {