Skip to content

Commit aeb4725

Browse files
fix(seer-explorer): Ensure 30s safety timeout always fires for optimistic UI
The early return when the server data signature matches the baseline prevented the setTimeout from ever being scheduled. If the backend never persisted the new block, the optimistic "Thinking" block would persist indefinitely.
1 parent de0a4a6 commit aeb4725

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

static/app/views/seerExplorer/hooks/useSeerExplorer.tsx

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,14 @@ export const useSeerExplorer = () => {
466466
return undefined;
467467
}
468468

469+
const isTimedOut = Date.now() - optimistic.createdAt > 30_000;
470+
471+
if (isTimedOut) {
472+
setOptimistic(null);
473+
setDeletedFromIndex(null);
474+
return undefined;
475+
}
476+
469477
const currentSignature = JSON.stringify(
470478
(apiData?.session?.blocks || []).map(b => [
471479
b.id,
@@ -475,33 +483,27 @@ export const useSeerExplorer = () => {
475483
])
476484
);
477485

478-
if (currentSignature === optimistic.baselineSignature) {
479-
return undefined;
480-
}
481-
482-
const serverBlocks = apiData?.session?.blocks || [];
483-
const hasAssistantResponse = serverBlocks.some(
484-
(b, i) => i >= optimistic.insertIndex && b.message.role === 'assistant'
485-
);
486-
const isTimedOut = Date.now() - optimistic.createdAt > 30_000;
487-
488-
if (hasAssistantResponse || isTimedOut) {
489-
setOptimistic(null);
490-
setDeletedFromIndex(null);
491-
return undefined;
492-
}
486+
if (currentSignature !== optimistic.baselineSignature) {
487+
const serverBlocks = apiData?.session?.blocks || [];
488+
const hasAssistantResponse = serverBlocks.some(
489+
(b, i) => i >= optimistic.insertIndex && b.message.role === 'assistant'
490+
);
493491

494-
// Schedule a forced clear at the 30s mark in case no new poll data arrives
495-
const remaining = 30_000 - (Date.now() - optimistic.createdAt);
496-
if (remaining > 0) {
497-
const timer = setTimeout(() => {
492+
if (hasAssistantResponse) {
498493
setOptimistic(null);
499494
setDeletedFromIndex(null);
500-
}, remaining);
501-
return () => clearTimeout(timer);
495+
return undefined;
496+
}
502497
}
503498

504-
return undefined;
499+
// Always schedule the safety timeout so the optimistic UI cannot persist
500+
// indefinitely when the server data signature never diverges from baseline.
501+
const remaining = 30_000 - (Date.now() - optimistic.createdAt);
502+
const timer = setTimeout(() => {
503+
setOptimistic(null);
504+
setDeletedFromIndex(null);
505+
}, remaining);
506+
return () => clearTimeout(timer);
505507
}, [apiData?.session?.blocks, optimistic]);
506508

507509
// Detect PR creation errors and show error messages

0 commit comments

Comments
 (0)