Skip to content

feat(explorer): stop UI polling after a timeout#112897

Closed
aliu39 wants to merge 14 commits intomasterfrom
aliu/timeout-ui
Closed

feat(explorer): stop UI polling after a timeout#112897
aliu39 wants to merge 14 commits intomasterfrom
aliu/timeout-ui

Conversation

@aliu39
Copy link
Copy Markdown
Member

@aliu39 aliu39 commented Apr 14, 2026

Stop polling for state after a timeout. Subsequent queries will overwrite any agent responses processed after the timeout. If no queries are made, extra responses may be loaded only after reloading the page/switching away from the convo

The input bar is enabled after timeouts so the user can keep talking. An info msg is shown in the placeholder. Demo w/ timeout=2s:
https://github.com/user-attachments/assets/2601799a-8290-4364-bcc2-b48e7cfdf68b

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 14, 2026
@sentry
Copy link
Copy Markdown
Contributor

sentry bot commented Apr 15, 2026

Sentry Snapshot Testing

Name Added Removed Modified Renamed Unchanged Status
sentry-frontend
sentry-frontend
0 0 0 0 204 ✅ Unchanged

@aliu39 aliu39 changed the title timeout ui feat(explorer): stop UI polling after a timeout Apr 15, 2026
};

const POLL_INTERVAL = 500; // Poll every 500ms
const POLLING_TIMEOUT_MS = 420_000; // 7 minutes
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

= to the backend task timeout. We can lower this to have snappier behavior for the chat, but users will be completely locked out from responses that take longer than this timeout

@aliu39 aliu39 marked this pull request as ready for review April 15, 2026 23:06
@aliu39 aliu39 requested a review from a team as a code owner April 15, 2026 23:06
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx
};
},
[readOnly, inputValue, isPolling, sendMessage]
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backtick key handler accidentally removed during refactor

Medium Severity

When handleInputKeyDown was refactored to use useCallback, the backtick key guard was accidentally removed. The old code had an explicit if (e.key === '') { e.nativeEvent.stopImmediatePropagation(); }block to prevent the backtick from triggering the superuserViewAsHookMiddleware`. This protection is now missing, so typing a backtick in the input while focused will propagate the event and potentially toggle superuser mode for staff users.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit cc89ff3. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it didnt work

Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx Outdated
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx Outdated
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx Outdated
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx Outdated
Comment thread static/app/views/seerExplorer/inputSection.tsx
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx
Comment thread static/app/views/seerExplorer/hooks/useSeerExplorer.tsx
Comment thread static/app/views/seerExplorer/inputSection.tsx Outdated
Comment on lines 432 to 441
[api, orgSlug, runId, queryClient]
);

// Always filter messages based on optimistic state and deletedFromIndex before any other processing
const sessionData = apiData?.session ?? null;

// Apply deletedFromIndex and optimistic state before any other processing
const filteredSessionData = useMemo(() => {
const realBlocks = sessionData?.blocks || [];
const rawSessionData = apiData?.session ?? null;
const realBlocks = rawSessionData?.blocks || [];

// Respect rewound/deleted index first for the real blocks view
const baseBlocks =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The createPR function does not re-enable polling after a session has completed, preventing the UI from updating with the PR creation status.
Severity: HIGH

Suggested Fix

The createPR function should call _onNewRequest() or a similar mechanism to set the isPolling state to true. This will ensure that after a PR creation is initiated, the application resumes polling to fetch status updates.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: static/app/views/seerExplorer/hooks/useSeerExplorer.tsx#L432-L441

Potential issue: When a Seer Explorer session completes, the `isLoaded` flag becomes
true, which in turn sets the `isPolling` state to false, stopping further data fetching.
If the user then calls the `createPR` function to create a pull request, the function
invalidates the query cache to trigger a refetch but fails to set `isPolling` back to
true. Because the `refetchInterval` logic depends on `isPolling` being true, polling for
the status of the PR creation never starts. This results in the UI not updating to
reflect whether the PR was created successfully or encountered an error.

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4ada837. Configure here.

setWasJustInterrupted(false);
}, []);

const [isPolling, setIsPolling] = useState<boolean>(true); // true on mount, set to false when response loaded or timeout.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isPolling initial true blocks first message on fresh sessions

High Severity

isPolling is initialized to true, but when runId is null (fresh session with no prior conversation), the API query is disabled (enabled: !!runId), so no data ever loads, filteredSessionData stays null, isLoaded never becomes truthy, and nothing ever sets isPolling to false. This permanently blocks message sending via the !isPolling guard in handleInputKeyDown and incorrectly shows the stop/interrupt button in InputSection.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4ada837. Configure here.

// Always filter messages based on optimistic state and deletedFromIndex before any other processing
const sessionData = apiData?.session ?? null;

// Apply deletedFromIndex and optimistic state before any other processing
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createPR doesn't enable polling for status updates

Medium Severity

createPR never calls _onNewRequest() or setIsPolling(true). After a completed response sets isPolling to false, initiating PR creation only does a one-shot query invalidation. The refetchInterval closure returns false, so pr_creation_status transitions (e.g., 'creating''completed') are never polled. The old code handled this via the dynamic anyPRCreating check in the isPolling function.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4ada837. Configure here.

@aliu39 aliu39 closed this Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant