microsoft / microsoft/copilot-for-eclipse
Stale chat progress can finish a newer active turn
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 126
- Forks
- 60
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 5
Description
Context
Discovered while reviewing #378, which fixes the confirmed #99 path where rebuilding the action buttons renders a disabled Send button during an active turn.
This issue tracks a separate turn-lifecycle race that can produce a similar symptom. It is not currently established as a root cause of #99.
Related review thread: https://github.com/microsoft/copilot-for-eclipse/pull/378#discussion_r3681652089
Problem
Each chat request is sent with a unique workDoneToken, and ProgressParamsAdapter parses the token returned on $/progress. However, CopilotLanguageClient.notifyProgress() forwards only ChatProgressValue, so the request identity is unavailable to ChatView.
ChatView currently associates top-level progress primarily by conversationId. Consecutive turns in one conversation share that ID, and any accepted top-level end event calls actionBar.markTurnFinished(). Asynchronous request errors also finish the action bar without checking whether the failed request is still active.
A possible sequence is:
- Turn A is running.
- The user cancels A; the UI immediately allows another send.
- Turn B starts in the same conversation.
- A delayed
end(A)or error callback from A arrives. - B is incorrectly marked finished and its Cancel button becomes Send.
- Subsequent progress for B may be ignored because
onChatProgress()gates processing onactionBar.isTurnRunning().
A real log attached to #99 confirms that the language server can send a cancellation end after $/cancelRequest (about 15 ms later in that trace). That trace did not overlap the cancellation end with the next turn, so it demonstrates the event shape but not this race itself.
Expected behavior
A terminal progress event or asynchronous callback must only finish the top-level request to which it belongs. Events from an older request must not change the lifecycle or action-button state of a newer active turn.
Acceptance criteria
start A -> cancel A -> start B -> end Aleaves B running with Cancel available.- A delayed error callback from A cannot finish B.
- The matching
end Bstill finishes B normally. - Request identity is preserved sufficiently to distinguish consecutive turns in the same conversation.
- The lifecycle behavior is covered by automated tests.
- Detailed handling of stale events, persistence, conversation metadata, and subagent progress is decided during implementation design rather than assumed by this issue.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Trace request identity through ProgressParamsAdapter and CopilotLanguageClient.notifyProgress() into ChatView, including actionBar lifecycle handling and asynchronous errors. Define the stale-event behavior during implementation, then add automated coverage for start A, cancel A, start B, delayed end or error from A, and the matching end B; done means B remains cancellable until its own completion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100