fix(desktop): replay pending approval/ask prompts on (re)connect#3857
Merged
Conversation
A session blocked awaiting a tool approval or ask question keeps its "waiting" status server-side (tabs.go derives it from the event stream), but the frontend approval modal is driven only by the live ApprovalRequest/AskRequest event with no restore path. A frontend that reloaded, reconnected, or raced the original event was left showing the "waiting" badge with no modal and no working stop — a deadlock only a new message could break (#3844). Add Controller.ReplayPendingPrompts to re-emit the event for any prompt still blocking the run loop, expose it on App, and call it from the frontend once its event subscription is live. asks now retains its questions so an AskRequest can be replayed faithfully. Closes #3844
The hand-written AppBindings contract and the dev-mock bridge must carry every bound Go method. ReplayPendingPrompts was missing from both, so the generated-binding drift check and tsc failed the frontend build.
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.
Problem
A session blocked awaiting a tool approval or
askquestion can deadlock with no way out: the project tree shows the topic as待确认/ waiting but no approval modal appears, the Stop button does nothing, and only typing a new message unblocks it (#3844).Root cause
The "waiting" status and the approval modal come from two independent channels:
desktop/tabs.go,topicActivityStatusFromEvent) derives a tab's activity status from the event stream and keeps it server-side, so it survives a WebView reload/reconnect.ApprovalRequest/AskRequestevent in the in-memory frontend reducer (useController.ts), with no restore path:MetaForTabcarries no pending prompt, and nothing re-emits it.So if the live event is ever missed — app restart while blocked, WebView reload, event-stream reconnect, or a subscribe-after-emit race — the controller's
requestApproval/Askgoroutine stays blocked, the badge still says waiting, but the modal never rebuilds. (Same class as the dashboard fix in #1770.)Fix
Controller.ReplayPendingPrompts()re-emits theApprovalRequest/AskRequestevent for any prompt still blocking the run loop.promptMuserialises the two, so at most one is outstanding; the loops stay general regardless.asksnow retains itsquestions(newpendingAsk) so anAskRequestreplays faithfully.App.ReplayPendingPrompts()fans it across all tabs.tabIdexactly like the originals.Tests
internal/control: newreplay_pending_test.go— a blocked approval and a blocked ask are both re-emitted identically onReplayPendingPrompts; an idle controller emits nothing.go test ./internal/control/...,go build ./...,cd desktop && go build ./... && go vet ./...all pass.Closes #3844