From 62fa3afc4cfe5a41d2ae45af5b71b9ea01bf5008 Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Tue, 23 Jun 2026 03:01:42 +0800 Subject: [PATCH] fix(workbench): avoid idle aborts for read hydration (#1940) --- web/hwlab-cloud-web/src/stores/workbench.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/web/hwlab-cloud-web/src/stores/workbench.ts b/web/hwlab-cloud-web/src/stores/workbench.ts index f31e4b79..4671e305 100644 --- a/web/hwlab-cloud-web/src/stores/workbench.ts +++ b/web/hwlab-cloud-web/src/stores/workbench.ts @@ -553,22 +553,35 @@ export const useWorkbenchStore = defineStore("workbench", () => { return false; } - function fetchWorkbenchTurnStatus(traceId: string): Promise> { + function fetchWorkbenchTurnStatus(traceId: string, useActivityTimeout = shouldUseActivityTimeoutForTrace(traceId)): Promise> { + const activitySource = useActivityTimeout ? () => activityRef.value : null; return runWorkbenchReadHydration( - () => api.workbench.turn(traceId, 8000, () => activityRef.value), + () => api.workbench.turn(traceId, 8000, activitySource), workbenchReadCooldownKey("turn", traceId), { minIntervalMs: WORKBENCH_TURN_STATUS_MIN_REFRESH_MS }, ); } - function fetchWorkbenchTraceEvents(traceId: string, afterProjectedSeq: number): Promise> { + function fetchWorkbenchTraceEvents(traceId: string, afterProjectedSeq: number, useActivityTimeout = shouldUseActivityTimeoutForTrace(traceId)): Promise> { + const activitySource = useActivityTimeout ? () => activityRef.value : null; return runWorkbenchReadHydration( - () => api.workbench.traceEvents(traceId, WORKBENCH_TRACE_EVENTS_TIMEOUT_MS, () => activityRef.value, { afterProjectedSeq, limit: TRACE_HYDRATION_PAGE_LIMIT }), + () => api.workbench.traceEvents(traceId, WORKBENCH_TRACE_EVENTS_TIMEOUT_MS, activitySource, { afterProjectedSeq, limit: TRACE_HYDRATION_PAGE_LIMIT }), workbenchReadCooldownKey("trace-events", traceId), { minIntervalMs: WORKBENCH_TRACE_EVENTS_MIN_REFRESH_MS }, ); } + function shouldUseActivityTimeoutForTrace(traceId: string | null | undefined): boolean { + const id = firstNonEmptyString(traceId); + if (!id) return false; + if (currentRequest.value?.traceId === id) return true; + const turn = turnStatusAuthority.value[id]; + if (turn?.terminal === true || isTerminalMessageStatus(turn?.status)) return false; + const message = [...messages.value].reverse().find((item) => firstNonEmptyString(item.traceId, item.runnerTrace?.traceId) === id) ?? null; + if (isTerminalMessageStatus(message?.status) || isTerminalMessageStatus(message?.runnerTrace?.status)) return false; + return isTraceActiveStatus(turn?.status) || isTraceActiveStatus(message?.status) || isTraceActiveStatus(message?.runnerTrace?.status); + } + async function refreshSessionMessageProjectionPage(sessionId: string | null | undefined): Promise { const id = normalizeWorkbenchSessionId(sessionId); if (!id) return;