Skip to content

Commit ed4f003

Browse files
authored
feat - add retry and report issue commands in SetupAgent on timeout (microsoft#288645)
1 parent 40552e3 commit ed4f003

4 files changed

Lines changed: 49 additions & 8 deletions

File tree

src/vs/workbench/contrib/chat/browser/chatSetup/chatSetupProviders.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ export class SetupAgent extends Disposable implements IChatAgentImplementation {
167167
private static readonly SETUP_NEEDED_MESSAGE = new MarkdownString(localize('settingUpCopilotNeeded', "You need to set up GitHub Copilot and be signed in to use Chat."));
168168
private static readonly TRUST_NEEDED_MESSAGE = new MarkdownString(localize('trustNeeded', "You need to trust this workspace to use Chat."));
169169

170-
private static CHAT_REPORT_ISSUE_WITH_OUTPUT_ID = 'workbench.action.chat.reportIssueWithOutput';
170+
private static readonly CHAT_RETRY_COMMAND_ID = 'workbench.action.chat.retrySetup';
171+
private static readonly CHAT_REPORT_ISSUE_WITH_OUTPUT_COMMAND_ID = 'workbench.action.chat.reportIssueWithOutput';
171172

172173
private readonly _onUnresolvableError = this._register(new Emitter<void>());
173174
readonly onUnresolvableError = this._onUnresolvableError.event;
@@ -192,7 +193,9 @@ export class SetupAgent extends Disposable implements IChatAgentImplementation {
192193
}
193194

194195
private registerCommands(): void {
195-
this._register(CommandsRegistry.registerCommand(SetupAgent.CHAT_REPORT_ISSUE_WITH_OUTPUT_ID, async accessor => {
196+
197+
// Report issue with output command
198+
this._register(CommandsRegistry.registerCommand(SetupAgent.CHAT_REPORT_ISSUE_WITH_OUTPUT_COMMAND_ID, async accessor => {
196199
const outputService = accessor.get(IOutputService);
197200
const textModelService = accessor.get(ITextModelService);
198201
const issueService = accessor.get(IWorkbenchIssueService);
@@ -234,6 +237,22 @@ export class SetupAgent extends Disposable implements IChatAgentImplementation {
234237
data: outputData || localize('chatOutputChannelUnavailable', "GitHub Copilot Chat output channel not available. Please ensure the GitHub Copilot Chat extension is active and try again. If the issue persists, you can manually include relevant information from the Output panel (View > Output > GitHub Copilot Chat).")
235238
});
236239
}));
240+
241+
// Retry chat command
242+
this._register(CommandsRegistry.registerCommand(SetupAgent.CHAT_RETRY_COMMAND_ID, async (accessor, sessionResource: URI) => {
243+
const chatService = accessor.get(IChatService);
244+
const chatWidgetService = accessor.get(IChatWidgetService);
245+
246+
const widget = chatWidgetService.getWidgetBySessionResource(sessionResource);
247+
const lastRequest = widget?.viewModel?.model.getRequests().at(-1);
248+
if (lastRequest) {
249+
await chatService.resendRequest(lastRequest, {
250+
...widget?.getModeRequestOptions(),
251+
modeInfo: widget?.input.currentModeInfo,
252+
userSelectedModelId: widget?.input.currentLanguageModel
253+
});
254+
}
255+
}));
237256
}
238257

239258
async invoke(request: IChatAgentRequest, progress: (parts: IChatProgress[]) => void): Promise<IChatAgentResult> {
@@ -397,9 +416,14 @@ export class SetupAgent extends Disposable implements IChatAgentImplementation {
397416
progress({
398417
kind: 'command',
399418
command: {
400-
id: SetupAgent.CHAT_REPORT_ISSUE_WITH_OUTPUT_ID,
419+
id: SetupAgent.CHAT_RETRY_COMMAND_ID,
420+
title: localize('retryChat', "Retry"),
421+
arguments: [requestModel.session.sessionResource]
422+
},
423+
additionalCommands: [{
424+
id: SetupAgent.CHAT_REPORT_ISSUE_WITH_OUTPUT_COMMAND_ID,
401425
title: localize('reportChatIssue', "Report Issue"),
402-
}
426+
}]
403427
});
404428

405429
// This means Chat is unhealthy and we cannot retry the

src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { IChatContentPart, IChatContentPartRenderContext } from './chatContentPa
1313
import { IChatProgressRenderableResponseContent } from '../../../common/model/chatModel.js';
1414
import { IChatCommandButton } from '../../../common/chatService/chatService.js';
1515
import { isResponseVM } from '../../../common/model/chatViewModel.js';
16+
import { Command } from '../../../../../../editor/common/languages.js';
1617

1718
const $ = dom.$;
1819

@@ -28,15 +29,28 @@ export class ChatCommandButtonContentPart extends Disposable implements IChatCon
2829

2930
this.domNode = $('.chat-command-button');
3031
const enabled = !isResponseVM(context.element) || !context.element.isStale;
32+
33+
// Render the primary button
34+
this.renderButton(this.domNode, commandButton.command, enabled);
35+
36+
// Render additional buttons if any
37+
if (commandButton.additionalCommands) {
38+
for (const command of commandButton.additionalCommands) {
39+
this.renderButton(this.domNode, command, enabled, true);
40+
}
41+
}
42+
}
43+
44+
private renderButton(container: HTMLElement, command: Command, enabled: boolean, secondary?: boolean): void {
3145
const tooltip = enabled ?
32-
commandButton.command.tooltip :
46+
command.tooltip :
3347
localize('commandButtonDisabled', "Button not available in restored chat");
34-
const button = this._register(new Button(this.domNode, { ...defaultButtonStyles, supportIcons: true, title: tooltip }));
35-
button.label = commandButton.command.title;
48+
const button = this._register(new Button(container, { ...defaultButtonStyles, supportIcons: true, title: tooltip, secondary }));
49+
button.label = command.title;
3650
button.enabled = enabled;
3751

3852
// TODO still need telemetry for command buttons
39-
this._register(button.onDidClick(() => this.commandService.executeCommand(commandButton.command.id, ...(commandButton.command.arguments ?? []))));
53+
this._register(button.onDidClick(() => this.commandService.executeCommand(command.id, ...(command.arguments ?? []))));
4054
}
4155

4256
hasSameContent(other: IChatProgressRenderableResponseContent): boolean {

src/vs/workbench/contrib/chat/browser/widget/media/chat.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,6 +2239,8 @@ have to be updated for changes to the rules above, or to support more deeply nes
22392239

22402240
.interactive-item-container .chat-command-button {
22412241
display: flex;
2242+
flex-wrap: wrap;
2243+
gap: 8px;
22422244
margin-bottom: 16px;
22432245
}
22442246

src/vs/workbench/contrib/chat/common/chatService/chatService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ export interface IChatAgentMarkdownContentWithVulnerability {
282282
export interface IChatCommandButton {
283283
command: Command;
284284
kind: 'command';
285+
additionalCommands?: Command[]; // rendered as secondary buttons
285286
}
286287

287288
export interface IChatMoveMessage {

0 commit comments

Comments
 (0)