Add 'default agent' concept (#195599)

So that every request can be routed through an agent
This commit is contained in:
Rob Lourens
2023-10-13 14:47:14 -07:00
committed by GitHub
parent ab51ad15e3
commit 2ac11b37d2
6 changed files with 40 additions and 7 deletions

View File

@@ -185,6 +185,7 @@ class ExtHostChatAgent {
private _description: string | undefined;
private _fullName: string | undefined;
private _iconPath: URI | undefined;
private _isDefault: boolean | undefined;
private _onDidReceiveFeedback = new Emitter<vscode.ChatAgentResult2Feedback>();
private _onDidPerformAction = new Emitter<vscode.ChatAgentUserActionEvent>();
@@ -258,6 +259,7 @@ class ExtHostChatAgent {
icon: this._iconPath,
hasSlashCommands: this._slashCommandProvider !== undefined,
hasFollowup: this._followupProvider !== undefined,
isDefault: this._isDefault
});
updateScheduled = false;
});
@@ -304,6 +306,13 @@ class ExtHostChatAgent {
that._followupProvider = v;
updateMetadataSoon();
},
get isDefault() {
return that._isDefault;
},
set isDefault(v) {
that._isDefault = v;
updateMetadataSoon();
},
get onDidReceiveFeedback() {
return that._onDidReceiveFeedback.event;
},

View File

@@ -329,7 +329,8 @@ class AgentCompletions extends Disposable {
return null;
}
const agents = this.chatAgentService.getAgents();
const agents = this.chatAgentService.getAgents()
.filter(a => !a.metadata.isDefault);
return <CompletionList>{
suggestions: agents.map((c, i) => {
const withAt = `@${c.id}`;

View File

@@ -5,6 +5,7 @@
import { CancellationToken } from 'vs/base/common/cancellation';
import { Emitter, Event } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
@@ -36,7 +37,7 @@ export interface IChatAgentMetadata {
description?: string;
// subCommands: IChatAgentCommand[];
requireCommand?: boolean; // Do some agents not have a default action?
isImplicit?: boolean; // Only @workspace. slash commands get promoted to the top-level and this agent is invoked when those are used
isDefault?: boolean; // The agent invoked when no agent is specified
fullName?: string;
icon?: URI;
}
@@ -69,6 +70,7 @@ export interface IChatAgentService {
getFollowups(id: string, sessionId: string, token: CancellationToken): Promise<IChatFollowup[]>;
getAgents(): Array<IChatAgent>;
getAgent(id: string): IChatAgent | undefined;
getDefaultAgent(): IChatAgent | undefined;
hasAgent(id: string): boolean;
updateAgent(id: string, updateMetadata: IChatAgentMetadata): void;
}
@@ -112,6 +114,10 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
this._onDidChangeAgents.fire();
}
getDefaultAgent(): IChatAgent | undefined {
return Iterable.find(this._agents.values(), a => !!a.agent.metadata.isDefault)?.agent;
}
getAgents(): Array<IChatAgent> {
return Array.from(this._agents.values(), v => v.agent);
}

View File

@@ -507,7 +507,9 @@ export class ChatService extends Disposable implements IChatService {
let rawResponse: IChatResponse | null | undefined;
let agentOrCommandFollowups: Promise<IChatFollowup[] | undefined> | undefined = undefined;
if (typeof message === 'string' && agentPart) {
const defaultAgent = this.chatAgentService.getDefaultAgent();
if (typeof message === 'string' && (agentPart || defaultAgent)) {
const agent = (agentPart?.agent ?? defaultAgent)!;
const history: IChatMessage[] = [];
for (const request of model.getRequests()) {
if (!request.response) {
@@ -518,11 +520,11 @@ export class ChatService extends Disposable implements IChatService {
history.push({ role: ChatMessageRole.Assistant, content: request.response.response.asString() });
}
request = model.addRequest(parsedRequest, agentPart.agent);
request = model.addRequest(parsedRequest, agent);
const requestProps: IChatAgentRequest = {
sessionId,
requestId: generateUuid(),
message: message,
message,
variables: {},
command: agentSlashCommandPart?.command.name ?? '',
};
@@ -532,7 +534,7 @@ export class ChatService extends Disposable implements IChatService {
requestProps.message = varResult.prompt;
}
const agentResult = await this.chatAgentService.invokeAgent(agentPart.agent.id, requestProps, new Progress<IChatProgress>(p => {
const agentResult = await this.chatAgentService.invokeAgent(agent.id, requestProps, new Progress<IChatProgress>(p => {
progressCallback(p);
}), history, token);
rawResponse = {
@@ -541,7 +543,7 @@ export class ChatService extends Disposable implements IChatService {
timings: agentResult.timings
};
agentOrCommandFollowups = agentResult?.followUp ? Promise.resolve(agentResult.followUp) :
this.chatAgentService.getFollowups(agentPart.agent.id, sessionId, CancellationToken.None);
this.chatAgentService.getFollowups(agent.id, sessionId, CancellationToken.None);
} else if (commandPart && typeof message === 'string' && this.chatSlashCommandService.hasCommand(commandPart.slashCommand.command)) {
request = model.addRequest(parsedRequest);
// contributed slash commands

View File

@@ -38,6 +38,7 @@ export const allApiProposals = Object.freeze({
createFileSystemWatcher: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.createFileSystemWatcher.d.ts',
customEditorMove: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.customEditorMove.d.ts',
debugFocus: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.debugFocus.d.ts',
defaultChatAgent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.defaultChatAgent.d.ts',
diffCommand: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffCommand.d.ts',
diffContentOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts',
documentFiltersExclusive: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts',

View File

@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
export interface ChatAgent2 {
/**
* When true, this agent is invoked by default when no other agent is being invoked
*/
isDefault?: boolean;
}
}