fix: stop completed workbench diagnostics polling
This commit is contained in:
@@ -421,6 +421,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
const response = await api.workbench.sessionMessages(id, { limit: 100 });
|
||||
if (!response.ok || !response.data) {
|
||||
if (shouldSuppressTransientWorkbenchReadFailure(response)) return;
|
||||
if (traceHasCompletedFinalResponse(traceId, messages.value)) return;
|
||||
applyProjectionDiagnostic(traceId, projectionDiagnosticFromApiFailure(response, { code: "message_projection_refresh_failed", message: response.error ?? "消息投影刷新失败,主消息正文保持上一份 canonical projection。", health: response.status === 0 ? "unavailable" : "degraded" }));
|
||||
return;
|
||||
}
|
||||
@@ -498,6 +499,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
return;
|
||||
}
|
||||
if (shouldSuppressTransientWorkbenchReadFailure(response)) return;
|
||||
if (traceHasCompletedFinalResponse(id, messages.value)) return;
|
||||
applyProjectionDiagnostic(id, projectionDiagnosticFromApiFailure(response, { code: "turn_status_poll_failed", message: response.error ?? "状态更新失败,当前 turn 状态暂不可见。", health: response.status === 0 ? "unavailable" : "degraded" }));
|
||||
}
|
||||
|
||||
@@ -663,6 +665,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
const result = await fetchTraceHydrationPage(traceId, afterProjectedSeq);
|
||||
if (!result.ok || !result.data) {
|
||||
if (shouldSuppressTransientWorkbenchReadFailure(result)) return;
|
||||
if (messageHasCompletedFinalResponse(message)) return;
|
||||
applyProjectionDiagnostic(traceId, projectionDiagnosticFromApiFailure(result, { code: "trace_hydration_failed", message: result.error ?? "Trace 更新超时,运行记录暂不可见。", health: result.status === 0 ? "unavailable" : "degraded" }));
|
||||
return;
|
||||
}
|
||||
@@ -1702,6 +1705,7 @@ function agentErrorFromProjection(projection: ProjectionDiagnostic): ChatMessage
|
||||
function messageNeedsTerminalDiagnostics(message: ChatMessage): boolean {
|
||||
if (message.role !== "agent") return false;
|
||||
if (!isTerminalMessageStatus(message.status)) return false;
|
||||
if (messageHasCompletedFinalResponse(message)) return false;
|
||||
const traceId = firstNonEmptyString(message.traceId, message.runnerTrace?.traceId);
|
||||
if (!traceId) return false;
|
||||
const agentRun = agentRunFromMessage(message);
|
||||
@@ -1711,6 +1715,7 @@ function messageNeedsTerminalDiagnostics(message: ChatMessage): boolean {
|
||||
|
||||
function messageNeedsTraceHydration(message: ChatMessage): boolean {
|
||||
if (message.role !== "agent") return false;
|
||||
if (messageHasCompletedFinalResponse(message)) return false;
|
||||
const traceId = firstNonEmptyString(message.traceId, message.runnerTrace?.traceId);
|
||||
if (!traceId) return false;
|
||||
const trace = message.runnerTrace;
|
||||
@@ -1720,6 +1725,18 @@ function messageNeedsTraceHydration(message: ChatMessage): boolean {
|
||||
return events.length === 0 || trace?.eventsCompacted === true || trace?.fullTraceLoaded !== true;
|
||||
}
|
||||
|
||||
function traceHasCompletedFinalResponse(traceId: string | null | undefined, source: ChatMessage[]): boolean {
|
||||
const id = firstNonEmptyString(traceId);
|
||||
if (!id) return false;
|
||||
return source.some((message) => firstNonEmptyString(message.traceId, message.runnerTrace?.traceId) === id && messageHasCompletedFinalResponse(message));
|
||||
}
|
||||
|
||||
function messageHasCompletedFinalResponse(message: ChatMessage | null | undefined): boolean {
|
||||
if (!message || message.role !== "agent") return false;
|
||||
if (normalizedStatusText(message.status) !== "completed" && normalizedStatusText(message.runnerTrace?.status) !== "completed") return false;
|
||||
return Boolean(firstNonEmptyString(message.text, finalResponseText((message as Record<string, unknown>).finalResponse)));
|
||||
}
|
||||
|
||||
function traceHasEvents(trace: ChatMessage["runnerTrace"]): boolean {
|
||||
return Array.isArray(trace?.events) && trace.events.length > 0;
|
||||
}
|
||||
|
||||
@@ -75,19 +75,13 @@ test.describe("REST gap hydration errors", () => {
|
||||
test.describe("sealed final response diagnostics separation", () => {
|
||||
test.use({ scenarioId: "sealed-final-response-diagnostics" });
|
||||
|
||||
test("keeps completed final response visible while showing diagnostics separately", async ({ page }, testInfo) => {
|
||||
test("keeps completed final response visible without surfacing transient hydration diagnostics", async ({ page }, testInfo) => {
|
||||
await gotoWorkbench(page, "/workbench/sessions/ses_sealed_final_diag");
|
||||
const card = page.locator(`${selectors.messageCard}[data-role="agent"][data-status="completed"]`).last();
|
||||
const diagnostic = card.locator(".projection-diagnostic");
|
||||
await expectCompactDiagnostic(diagnostic, card, "55555555555555555555555555555555");
|
||||
await expect(diagnostic).not.toContainText("req_e2e_sealed_final_trace_timeout");
|
||||
await expandDiagnostic(diagnostic);
|
||||
await expect(diagnostic).toContainText("Trace 更新超时");
|
||||
await expect(diagnostic).toContainText("req_e2e_sealed_final_trace_timeout");
|
||||
await expect(diagnostic).toContainText("/v1/workbench/traces/trc_sealed_final_diag/events");
|
||||
const finalResponse = card.locator(".message-text").filter({ hasText: "已完成的 sealed final response 不应被诊断覆盖。" });
|
||||
await expect(finalResponse).toBeVisible();
|
||||
await expect(finalResponse).not.toContainText("Trace 更新超时");
|
||||
await expect(card.locator(".projection-diagnostic")).toHaveCount(0);
|
||||
await saveScreenshot(page, testInfo, "sealed-final-response-diagnostic-separate");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user