Skip to content

Commit

Permalink
tools: allow followup message with implicit cancel on tool confirmati…
Browse files Browse the repository at this point in the history
…on (#238712)

- Make 'requestInProgress' false while waiting for a tool confirmation
- Cancel pending requests when sending a new request via the chat input
  • Loading branch information
connor4312 authored Jan 24, 2025
1 parent dcb91f8 commit eb0da63
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,10 @@ export class CancelAction extends Action2 {
icon: Codicon.stopCircle,
menu: {
id: MenuId.ChatExecute,
when: ContextKeyExpr.or(ChatContextKeys.requestInProgress, ContextKeyExpr.and(ChatContextKeys.location.isEqualTo(ChatAgentLocation.EditingSession), applyingChatEditsContextKey)),
when: ContextKeyExpr.or(
ChatContextKeys.requestInProgress,
ContextKeyExpr.and(ChatContextKeys.location.isEqualTo(ChatAgentLocation.EditingSession), applyingChatEditsContextKey)
),
order: 4,
group: 'navigation',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ class ChatToolInvocationSubPart extends Disposable {
toolInvocation.confirmed.complete(button.data);
}));
this._onDidChangeHeight.input = confirmWidget.onDidChangeHeight;
toolInvocation.confirmed.p.then(() => this._onNeedsRerender.fire());
toolInvocation.confirmed.p.then(() => {
this._onNeedsRerender.fire();
});
} else {
let content: IMarkdownString;
if (toolInvocation.isComplete && toolInvocation.isConfirmed !== false && toolInvocation.pastTenseMessage) {
Expand Down
2 changes: 2 additions & 0 deletions src/vs/workbench/contrib/chat/browser/chatWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,8 @@ export class ChatWidget extends Disposable implements IChatWidget {
currentEditingSession?.remove(WorkingSetEntryRemovalReason.User, ...unconfirmedSuggestions);
}

this.chatService.cancelCurrentRequestForSession(this.viewModel.sessionId);

const result = await this.chatService.sendRequest(this.viewModel.sessionId, input, {
userSelectedModelId: this.inputPart.currentLanguageModel,
location: this.location,
Expand Down
25 changes: 24 additions & 1 deletion src/vs/workbench/contrib/chat/common/chatModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export interface IChatResponseModel {
readonly response: IResponse;
readonly isComplete: boolean;
readonly isCanceled: boolean;
readonly isPendingConfirmation: boolean;
readonly shouldBeRemovedOnSend: boolean;
readonly isCompleteAddedRequest: boolean;
/** A stale response is one that has been persisted and rehydrated, so e.g. Commands that have their arguments stored in the EH are gone. */
Expand Down Expand Up @@ -399,6 +400,14 @@ export class Response extends Disposable implements IResponse {
this._updateRepr(false);
});

} else if (progress.kind === 'toolInvocation') {
if (progress.confirmationMessages) {
progress.confirmed.p.then(() => {
this._updateRepr(false);
});
}
this._responseParts.push(progress);
this._updateRepr(quiet);
} else {
this._responseParts.push(progress);
this._updateRepr(quiet);
Expand Down Expand Up @@ -595,6 +604,12 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel
return this._isStale;
}

public get isPendingConfirmation() {
return this._response.value.some(part =>
part.kind === 'toolInvocation' && part.isConfirmed === undefined
|| part.kind === 'confirmation' && part.isUsed === false);
}

constructor(
_response: IMarkdownString | ReadonlyArray<IMarkdownString | IChatResponseProgressFileTreeData | IChatContentInlineReference | IChatAgentMarkdownContentWithVulnerability | IChatResponseCodeblockUriPart>,
private _session: ChatModel,
Expand Down Expand Up @@ -979,7 +994,15 @@ export class ChatModel extends Disposable implements IChatModel {

get requestInProgress(): boolean {
const lastRequest = this.lastRequest;
return !!lastRequest?.response && !lastRequest.response.isComplete;
if (!lastRequest?.response) {
return false;
}

if (lastRequest.response.isPendingConfirmation) {
return false;
}

return !lastRequest.response.isComplete;
}

get hasRequests(): boolean {
Expand Down

0 comments on commit eb0da63

Please sign in to comment.