ref(seer-explorer): Replace useSeerExplorerRunId with chat state context#115631
Merged
Conversation
Replace the module-level useSyncExternalStore pattern with a React context using a reducer with split dispatch and state. The context stores Record<number, ChatState> for per-run polling state and manages the active runId with session storage persistence. useSeerExplorerPolling now dispatches polling state updates to the parent context, centralizing chat state management. Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
📊 Type Coverage Diff✅ No new type safety issues introduced. Coverage: 93.53% |
The override was redundant — mutations already set optimistic status to 'processing' with a fresh updated_at, so getPollingState computes 'polling' without it. Polling now runs exclusively in SeerExplorerChatStateProvider via a child component that dispatches to the reducer. Consumers read isPolling/isTimedOut from chatStates instead of calling useSeerExplorerPolling directly. Co-Authored-By: Claude <noreply@anthropic.com>
Move SeerExplorerResponse and PendingUserInput types to types.tsx to break circular dependency (useSeerExplorer → seerExplorerChatStateContext → useSeerExplorerPolling → useSeerExplorer). Update all external consumers to import from the new location. Switch test mocks from jest.mock with jest.requireActual (which fails due to module initialization ordering) to jest.spyOn for utils and llmContext hooks. Un-export ChatState and ChatStateAction types that have no external consumers. Co-Authored-By: Claude <noreply@anthropic.com>
When runId is null (new session), pollingState was undefined and isPolling was always false, causing the processedSessionData memo to skip optimistic block construction. Users saw nothing while the first mutation was in-flight. Gate the early return on an awaitingResponse signal that checks isSendingMessage, whether we're waiting for initial API data, or whether the session is still processing (excluding timeouts). This bridges the gap between mutation resolve and polling state propagation through the context. Co-Authored-By: Claude <noreply@anthropic.com>
Drop the dead 'remove' action variant and reducer case that had no dispatch site. Type the JSON.parse result as unknown instead of any. Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5c259e4. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Removes polling hook in favor of context and global state management