Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't pass the followup object in with the request #195610

Merged
merged 1 commit into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ export interface IChatDto {
}

export interface IChatRequestDto {
message: string | IChatReplyFollowup;
message: string;
variables?: Record<string, IChatRequestVariableValue[]>;
}

Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHostChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class ExtHostChat implements ExtHostChatShape {

const requestObj: vscode.InteractiveRequest = {
session: realSession,
message: typeof request.message === 'string' ? request.message : typeConvert.ChatReplyFollowup.to(request.message),
message: request.message,
variables: {}
};

Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/chat/browser/chatInputPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
return this._inputEditor.hasWidgetFocus();
}

async acceptInput(query?: string | IChatReplyFollowup): Promise<void> {
async acceptInput(query?: string): Promise<void> {
const editorValue = this._inputEditor.getValue();
if (!query && editorValue) {
// Followups and programmatic messages don't go to history
Expand Down
12 changes: 8 additions & 4 deletions src/vs/workbench/contrib/chat/browser/chatWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ export class ChatWidget extends Disposable implements IChatWidget {
rendererDelegate
));
this._register(this.renderer.onDidClickFollowup(item => {
this.acceptInput(item);
// is this used anymore?
this.acceptInput(item.message);
}));

this.tree = <WorkbenchObjectTree<ChatTreeItem>>scopedInstantiationService.createInstance(
Expand Down Expand Up @@ -408,7 +409,10 @@ export class ChatWidget extends Disposable implements IChatWidget {
this.inputPart.render(container, '', this);

this._register(this.inputPart.onDidFocus(() => this._onDidFocus.fire()));
this._register(this.inputPart.onDidAcceptFollowup(followup => this.acceptInput(followup)));
this._register(this.inputPart.onDidAcceptFollowup(followup => {
// this.chatService.notifyUserAction
this.acceptInput(followup.message);
}));
this._register(this.inputPart.onDidChangeHeight(() => this.bodyDimension && this.layout(this.bodyDimension.height, this.bodyDimension.width)));
}

Expand Down Expand Up @@ -469,14 +473,14 @@ export class ChatWidget extends Disposable implements IChatWidget {
this.inputPart.setValue(value);
}

async acceptInput(query?: string | IChatReplyFollowup): Promise<void> {
async acceptInput(query?: string): Promise<void> {
if (this.viewModel) {
this._onDidAcceptInput.fire();

const editorValue = this.inputPart.inputEditor.getValue();
this._chatAccessibilityService.acceptRequest();
const input = query ?? editorValue;
const usedSlashCommand = this.lookupSlashCommand(typeof input === 'string' ? input : input.message);
const usedSlashCommand = this.lookupSlashCommand(input);
const result = await this.chatService.sendRequest(this.viewModel.sessionId, input, usedSlashCommand);

if (result) {
Expand Down
8 changes: 4 additions & 4 deletions src/vs/workbench/contrib/chat/common/chatModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class ChatRequestModel implements IChatRequestModel {

constructor(
public readonly session: ChatModel,
public readonly message: IParsedChatRequest | IChatReplyFollowup,
public readonly message: IParsedChatRequest,
private _providerRequestId?: string) {
this._id = 'request_' + ChatRequestModel.nextId++;
}
Expand Down Expand Up @@ -521,7 +521,7 @@ export class ChatModel extends Disposable implements IChatModel {

get title(): string {
const firstRequestMessage = firstOrDefault(this._requests)?.message;
const message = (firstRequestMessage && 'text' in firstRequestMessage) ? firstRequestMessage.text : firstRequestMessage?.message ?? '';
const message = firstRequestMessage?.text ?? '';
return message.split('\n')[0].substring(0, 50);
}

Expand Down Expand Up @@ -645,7 +645,7 @@ export class ChatModel extends Disposable implements IChatModel {
return this._requests;
}

addRequest(message: IParsedChatRequest | IChatReplyFollowup, chatAgent?: IChatAgent): ChatRequestModel {
addRequest(message: IParsedChatRequest, chatAgent?: IChatAgent): ChatRequestModel {
if (!this._session) {
throw new Error('addRequest: No session');
}
Expand Down Expand Up @@ -753,7 +753,7 @@ export class ChatModel extends Disposable implements IChatModel {
requests: this._requests.map((r): ISerializableChatRequestData => {
return {
providerRequestId: r.providerRequestId,
message: 'text' in r.message ? r.message : r.message.message,
message: r.message,
response: r.response ? r.response.response.value : undefined,
responseErrorDetails: r.response?.errorDetails,
followups: r.response?.followups,
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/contrib/chat/common/chatService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface IChat {

export interface IChatRequest {
session: IChat;
message: string | IChatReplyFollowup;
message: string;
variables: Record<string, IChatRequestVariableValue[]>;
}

Expand Down Expand Up @@ -270,7 +270,7 @@ export interface IChatService {
/**
* Returns whether the request was accepted.
*/
sendRequest(sessionId: string, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise<{ responseCompletePromise: Promise<void> } | undefined>;
sendRequest(sessionId: string, message: string, usedSlashCommand?: ISlashCommand): Promise<{ responseCompletePromise: Promise<void> } | undefined>;
removeRequest(sessionid: string, requestId: string): Promise<void>;
cancelCurrentRequestForSession(sessionId: string): void;
getSlashCommands(sessionId: string, token: CancellationToken): Promise<ISlashCommand[]>;
Expand Down
31 changes: 13 additions & 18 deletions src/vs/workbench/contrib/chat/common/chatServiceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { IChatAgentRequest, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { ChatModel, ChatModelInitState, ChatRequestModel, ChatWelcomeMessageModel, IChatModel, ISerializableChatData, ISerializableChatsData, isCompleteInteractiveProgressTreeData } from 'vs/workbench/contrib/chat/common/chatModel';
import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, IParsedChatRequest } from 'vs/workbench/contrib/chat/common/chatParserTypes';
import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart } from 'vs/workbench/contrib/chat/common/chatParserTypes';
import { ChatMessageRole, IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider';
import { ChatRequestParser } from 'vs/workbench/contrib/chat/common/chatRequestParser';
import { IChat, IChatCompleteResponse, IChatDetail, IChatDynamicRequest, IChatFollowup, IChatProgress, IChatProvider, IChatProviderInfo, IChatReplyFollowup, IChatRequest, IChatResponse, IChatService, IChatTransferredSessionData, IChatUserActionEvent, ISlashCommand, InteractiveSessionCopyKind, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
Expand Down Expand Up @@ -412,10 +412,9 @@ export class ChatService extends Disposable implements IChatService {
return this._startSession(data.providerId, data, CancellationToken.None);
}

async sendRequest(sessionId: string, request: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise<{ responseCompletePromise: Promise<void> } | undefined> {
const messageText = typeof request === 'string' ? request : request.message;
this.trace('sendRequest', `sessionId: ${sessionId}, message: ${messageText.substring(0, 20)}${messageText.length > 20 ? '[...]' : ''}}`);
if (!messageText.trim()) {
async sendRequest(sessionId: string, request: string, usedSlashCommand?: ISlashCommand): Promise<{ responseCompletePromise: Promise<void> } | undefined> {
this.trace('sendRequest', `sessionId: ${sessionId}, message: ${request.substring(0, 20)}${request.length > 20 ? '[...]' : ''}}`);
if (!request.trim()) {
this.trace('sendRequest', 'Rejected empty message');
return;
}
Expand All @@ -440,20 +439,16 @@ export class ChatService extends Disposable implements IChatService {
return { responseCompletePromise: this._sendRequestAsync(model, sessionId, provider, request, usedSlashCommand) };
}

private async _sendRequestAsync(model: ChatModel, sessionId: string, provider: IChatProvider, message: string | IChatReplyFollowup, usedSlashCommand?: ISlashCommand): Promise<void> {
const parsedRequest = typeof message === 'string' ?
await this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message) :
message; // Handle the followup type along with the response
private async _sendRequestAsync(model: ChatModel, sessionId: string, provider: IChatProvider, message: string, usedSlashCommand?: ISlashCommand): Promise<void> {
const parsedRequest = await this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message);

let request: ChatRequestModel;
const agentPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r): r is ChatRequestAgentPart => r instanceof ChatRequestAgentPart);
const agentSlashCommandPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r): r is ChatRequestAgentSubcommandPart => r instanceof ChatRequestAgentSubcommandPart);
const commandPart = 'kind' in parsedRequest ? undefined : parsedRequest.parts.find((r): r is ChatRequestSlashCommandPart => r instanceof ChatRequestSlashCommandPart);

let gotProgress = false;
const requestType = typeof message === 'string' ?
commandPart ? 'slashCommand' : 'string' :
'followup';
const requestType = commandPart ? 'slashCommand' : 'string';

const rawResponsePromise = createCancelablePromise<void>(async token => {
const progressCallback = (progress: IChatProgress) => {
Expand Down Expand Up @@ -508,15 +503,15 @@ export class ChatService extends Disposable implements IChatService {
let agentOrCommandFollowups: Promise<IChatFollowup[] | undefined> | undefined = undefined;

const defaultAgent = this.chatAgentService.getDefaultAgent();
if (typeof message === 'string' && (agentPart || defaultAgent)) {
if (agentPart || defaultAgent) {
const agent = (agentPart?.agent ?? defaultAgent)!;
const history: IChatMessage[] = [];
for (const request of model.getRequests()) {
if (!request.response) {
continue;
}

history.push({ role: ChatMessageRole.User, content: 'text' in request.message ? request.message.text : request.message.message });
history.push({ role: ChatMessageRole.User, content: request.message.text });
history.push({ role: ChatMessageRole.Assistant, content: request.response.response.asString() });
}

Expand Down Expand Up @@ -544,7 +539,7 @@ export class ChatService extends Disposable implements IChatService {
};
agentOrCommandFollowups = agentResult?.followUp ? Promise.resolve(agentResult.followUp) :
this.chatAgentService.getFollowups(agent.id, sessionId, CancellationToken.None);
} else if (commandPart && typeof message === 'string' && this.chatSlashCommandService.hasCommand(commandPart.slashCommand.command)) {
} else if (commandPart && this.chatSlashCommandService.hasCommand(commandPart.slashCommand.command)) {
request = model.addRequest(parsedRequest);
// contributed slash commands
// TODO: spell this out in the UI
Expand All @@ -553,7 +548,7 @@ export class ChatService extends Disposable implements IChatService {
if (!request.response) {
continue;
}
history.push({ role: ChatMessageRole.User, content: 'text' in request.message ? request.message.text : request.message.message });
history.push({ role: ChatMessageRole.User, content: request.message.text });
history.push({ role: ChatMessageRole.Assistant, content: request.response.response.asString() });
}
const commandResult = await this.chatSlashCommandService.executeCommand(commandPart.slashCommand.command, message.substring(commandPart.slashCommand.command.length + 1).trimStart(), new Progress<IChatSlashFragment>(p => {
Expand Down Expand Up @@ -690,7 +685,7 @@ export class ChatService extends Disposable implements IChatService {
return Array.from(this._providers.keys());
}

async addCompleteRequest(sessionId: string, message: string | IParsedChatRequest, response: IChatCompleteResponse): Promise<void> {
async addCompleteRequest(sessionId: string, message: string, response: IChatCompleteResponse): Promise<void> {
this.trace('addCompleteRequest', `message: ${message}`);

const model = this._sessionModels.get(sessionId);
Expand All @@ -699,7 +694,7 @@ export class ChatService extends Disposable implements IChatService {
}

await model.waitForInitialization();
const parsedRequest = typeof message === 'string' ? await this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message) : message;
const parsedRequest = await this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(sessionId, message);
const request = model.addRequest(parsedRequest);
if (typeof response.message === 'string') {
model.acceptResponseProgress(request, { content: response.message });
Expand Down
4 changes: 1 addition & 3 deletions src/vscode-dts/vscode.proposed.interactive.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ declare module 'vscode' {

export interface InteractiveRequest {
session: InteractiveSession;
message: string | InteractiveSessionReplyFollowup;
// TODO@API move to agent
// slashCommand?: InteractiveSessionSlashCommand;
message: string;
}

export interface InteractiveResponseErrorDetails {
Expand Down