Skip to content

Commit 80f2f30

Browse files
Copilotalexr00
andauthored
Fix race condition in branch picker when creating PR (#8628)
* Initial plan * Initial plan for fixing branch picker race condition Agent-Logs-Url: https://github.com/microsoft/vscode-pull-request-github/sessions/f9f9a4fa-befb-4089-968f-721dfd44e120 Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * Fix race condition in branch picker when creating PR Register onDidAccept/onDidHide handlers before async updateItems to avoid missing early user interactions. Fall back to activeItems when selectedItems is empty due to items being replaced during debounced refresh. Agent-Logs-Url: https://github.com/microsoft/vscode-pull-request-github/sessions/f9f9a4fa-befb-4089-968f-721dfd44e120 Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 4dc91c1 commit 80f2f30

File tree

4 files changed

+35
-28
lines changed

4 files changed

+35
-28
lines changed

src/@types/vscode.proposed.chatParticipantAdditions.d.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -990,10 +990,6 @@ declare module 'vscode' {
990990
readonly toolReferences?: readonly ChatLanguageModelToolReference[];
991991
}
992992

993-
export interface ChatResultFeedback {
994-
readonly unhelpfulReason?: string;
995-
}
996-
997993
export namespace lm {
998994
export function fileIsIgnored(uri: Uri, token?: CancellationToken): Thenable<boolean>;
999995
}

src/@types/vscode.proposed.chatParticipantPrivate.d.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ declare module 'vscode' {
5050
constructor(cell: TextDocument);
5151
}
5252

53-
export interface ChatRequestSessionGrouping {
54-
readonly id: string;
55-
readonly order: number;
56-
readonly kind?: string;
57-
}
58-
5953
export interface ChatRequest {
6054
/**
6155
* The id of the chat request. Used to identity an interaction with any of the chat surfaces.
@@ -122,11 +116,6 @@ declare module 'vscode' {
122116
*/
123117
readonly parentRequestId?: string;
124118

125-
/**
126-
* Optional metadata used to group related requests together in the UI.
127-
*/
128-
readonly sessionGrouping?: ChatRequestSessionGrouping;
129-
130119
/**
131120
* The permission level for tool auto-approval in this request.
132121
* - `'autoApprove'`: Auto-approve all tool calls and retry on errors.
@@ -199,10 +188,15 @@ declare module 'vscode' {
199188
*/
200189
readonly modelId?: string;
201190

191+
/**
192+
* The mode instructions that were active for this request, if any.
193+
*/
194+
readonly modeInstructions2?: ChatRequestModeInstructions;
195+
202196
/**
203197
* @hidden
204198
*/
205-
constructor(prompt: string, command: string | undefined, references: ChatPromptReference[], participant: string, toolReferences: ChatLanguageModelToolReference[], editedFileEvents: ChatRequestEditedFileEvent[] | undefined, id: string | undefined, modelId: string | undefined);
199+
constructor(prompt: string, command: string | undefined, references: ChatPromptReference[], participant: string, toolReferences: ChatLanguageModelToolReference[], editedFileEvents: ChatRequestEditedFileEvent[] | undefined, id: string | undefined, modelId: string | undefined, modeInstructions2: ChatRequestModeInstructions | undefined);
206200
}
207201

208202
export class ChatResponseTurn2 {
@@ -421,4 +415,17 @@ declare module 'vscode' {
421415
}
422416

423417
// #endregion
418+
419+
export interface LanguageModelToolInformation {
420+
/**
421+
* The full reference name of this tool as used in agent definition files.
422+
*
423+
* For MCP tools, this is the canonical name in the format `serverShortName/toolReferenceName`
424+
* (e.g., `github/search_issues`). This can be used to map between the tool names specified
425+
* in agent `.md` files and the tool's internal {@link LanguageModelToolInformation.name id}.
426+
*
427+
* This property is only set for MCP tools. For other tool types, it is `undefined`.
428+
*/
429+
readonly fullReferenceName?: string;
430+
}
424431
}

src/github/createPRViewProvider.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,19 +1161,14 @@ Don't forget to commit your template file to the repository so that it can be us
11611161
const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined;
11621162
quickPick.activeItems = activeItem ? [activeItem] : [];
11631163
}
1164-
await updateItems(githubRepository, undefined);
1165-
} else {
1166-
quickPick.items = await this.remotePicks(isBase);
11671164
}
1168-
const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined;
1169-
quickPick.activeItems = activeItem ? [activeItem] : [];
1170-
quickPick.busy = false;
1165+
// Register event handlers before awaiting async operations to avoid missing early user interactions
11711166
const remoteAndBranch: Promise<{ remote: RemoteInfo, branch: string } | undefined> = new Promise((resolve) => {
11721167
quickPick.onDidAccept(async () => {
1173-
if (quickPick.selectedItems.length === 0) {
1168+
const selectedPick = quickPick.selectedItems[0] ?? quickPick.activeItems[0];
1169+
if (!selectedPick) {
11741170
return;
11751171
}
1176-
const selectedPick = quickPick.selectedItems[0];
11771172
if (selectedPick.label === chooseDifferentRemote) {
11781173
quickPick.busy = true;
11791174
quickPick.items = await this.remotePicks(isBase);
@@ -1194,6 +1189,14 @@ Don't forget to commit your template file to the repository so that it can be us
11941189
});
11951190
});
11961191
const hidePromise = new Promise<void>((resolve) => quickPick.onDidHide(() => resolve()));
1192+
if (githubRepository) {
1193+
await updateItems(githubRepository, undefined);
1194+
} else {
1195+
quickPick.items = await this.remotePicks(isBase);
1196+
}
1197+
const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined;
1198+
quickPick.activeItems = activeItem ? [activeItem] : [];
1199+
quickPick.busy = false;
11971200
const result = await Promise.race([remoteAndBranch, hidePromise]);
11981201
if (!result || !githubRepository) {
11991202
quickPick.hide();

src/github/pullRequestOverview.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,13 +1136,14 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel<PullRequestMode
11361136
quickPick.canSelectMany = false;
11371137
quickPick.placeholder = vscode.l10n.t('Select a new base branch');
11381138
quickPick.show();
1139-
await updateItems(undefined);
1140-
1141-
quickPick.busy = false;
1139+
// Register event handlers before awaiting async operations to avoid missing early user interactions
11421140
const acceptPromise = asPromise<void>(quickPick.onDidAccept).then(() => {
1143-
return quickPick.selectedItems[0]?.branch;
1141+
return (quickPick.selectedItems[0] ?? quickPick.activeItems[0])?.branch;
11441142
});
11451143
const hidePromise = asPromise<void>(quickPick.onDidHide);
1144+
await updateItems(undefined);
1145+
1146+
quickPick.busy = false;
11461147
const selectedBranch = await Promise.race<string | void>([acceptPromise, hidePromise]);
11471148
quickPick.busy = true;
11481149
quickPick.enabled = false;

0 commit comments

Comments
 (0)