Merge pull request #245790 from microsoft/roblou/defensive-elephant

Remove EditingSession location
This commit is contained in:
Rob Lourens
2025-04-06 18:01:15 -07:00
committed by GitHub
36 changed files with 118 additions and 99 deletions
@@ -33,7 +33,7 @@ const _allApiProposals = {
},
chatParticipantPrivate: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts',
version: 6
version: 7
},
chatProvider: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatProvider.d.ts',
@@ -154,7 +154,7 @@ const _allApiProposals = {
},
defaultChatParticipant: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.defaultChatParticipant.d.ts',
version: 3
version: 4
},
diffCommand: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffCommand.d.ts',
@@ -29,7 +29,7 @@ import { IChatEditingService, IChatRelatedFileProviderMetadata } from '../../con
import { ChatRequestAgentPart } from '../../contrib/chat/common/chatParserTypes.js';
import { ChatRequestParser } from '../../contrib/chat/common/chatRequestParser.js';
import { IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatNotebookEdit, IChatProgress, IChatService, IChatTask, IChatWarningMessage } from '../../contrib/chat/common/chatService.js';
import { ChatAgentLocation } from '../../contrib/chat/common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../contrib/chat/common/constants.js';
import { IExtHostContext, extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js';
import { IExtensionService } from '../../services/extensions/common/extensions.js';
import { Dto } from '../../services/extensions/common/proxyIdentifier.js';
@@ -200,6 +200,7 @@ export class MainThreadChatAgents2 extends Disposable implements MainThreadChatA
slashCommands: [],
disambiguation: [],
locations: [ChatAgentLocation.Panel], // TODO all dynamic participants are panel only?
modes: [ChatMode.Ask]
},
impl);
} else {
@@ -2924,7 +2924,6 @@ export namespace ChatLocation {
case ChatAgentLocation.Terminal: return types.ChatLocation.Terminal;
case ChatAgentLocation.Panel: return types.ChatLocation.Panel;
case ChatAgentLocation.Editor: return types.ChatLocation.Editor;
case ChatAgentLocation.EditingSession: return types.ChatLocation.EditingSession;
}
}
@@ -2934,7 +2933,6 @@ export namespace ChatLocation {
case types.ChatLocation.Terminal: return ChatAgentLocation.Terminal;
case types.ChatLocation.Panel: return ChatAgentLocation.Panel;
case types.ChatLocation.Editor: return ChatAgentLocation.Editor;
case types.ChatLocation.EditingSession: return ChatAgentLocation.EditingSession;
}
}
}
@@ -4730,7 +4730,6 @@ export enum ChatLocation {
Terminal = 2,
Notebook = 3,
Editor = 4,
EditingSession = 5,
}
export enum ChatResponseReferencePartStatusKind {
@@ -29,7 +29,7 @@ import { IExtension, IExtensionsWorkbenchService } from '../../extensions/common
import { IChatAgentData, IChatAgentService } from '../common/chatAgents.js';
import { ChatContextKeys } from '../common/chatContextKeys.js';
import { IRawChatParticipantContribution } from '../common/chatParticipantContribTypes.js';
import { ChatAgentLocation } from '../common/constants.js';
import { ChatAgentLocation, ChatMode } from '../common/constants.js';
import { ChatViewId } from './chat.js';
import { CHAT_SIDEBAR_PANEL_ID, ChatViewPane } from './chatViewPane.js';
@@ -238,7 +238,7 @@ export class ChatExtensionPointHandler implements IWorkbenchContribution {
continue;
}
if ((providerDescriptor.isDefault || providerDescriptor.isAgent) && !isProposedApiEnabled(extension.description, 'defaultChatParticipant')) {
if ((providerDescriptor.isDefault || providerDescriptor.modes) && !isProposedApiEnabled(extension.description, 'defaultChatParticipant')) {
this.logService.error(`Extension '${extension.description.identifier.value}' CANNOT use API proposal: defaultChatParticipant.`);
continue;
}
@@ -284,10 +284,10 @@ export class ChatExtensionPointHandler implements IWorkbenchContribution {
name: providerDescriptor.name,
fullName: providerDescriptor.fullName,
isDefault: providerDescriptor.isDefault,
isToolsAgent: providerDescriptor.isAgent,
locations: isNonEmptyArray(providerDescriptor.locations) ?
providerDescriptor.locations.map(ChatAgentLocation.fromRaw) :
[ChatAgentLocation.Panel],
modes: providerDescriptor.modes ?? [ChatMode.Ask],
slashCommands: providerDescriptor.commands ?? [],
disambiguation: coalesce(participantsDisambiguation.flat()),
} satisfies IChatAgentData));
@@ -102,7 +102,7 @@ const ToolsAgentWhen = ContextKeyExpr.and(
class SetupChatAgentImplementation extends Disposable implements IChatAgentImplementation {
static register(instantiationService: IInstantiationService, location: ChatAgentLocation, isToolsAgent: boolean, context: ChatEntitlementContext, controller: Lazy<ChatSetupController>): { disposable: IDisposable; agent: SetupChatAgentImplementation } {
static register(instantiationService: IInstantiationService, location: ChatAgentLocation, mode: ChatMode | undefined, context: ChatEntitlementContext, controller: Lazy<ChatSetupController>): { disposable: IDisposable; agent: SetupChatAgentImplementation } {
return instantiationService.invokeFunction(accessor => {
const chatAgentService = accessor.get(IChatAgentService);
@@ -112,27 +112,30 @@ class SetupChatAgentImplementation extends Disposable implements IChatAgentImple
const baseMessage = localize('chatMessage', "Copilot is powered by AI, so mistakes are possible. Review output carefully before use.");
switch (location) {
case ChatAgentLocation.Panel:
id = 'setup.chat';
welcomeMessageContent = {
title: description,
message: new MarkdownString(baseMessage),
icon: Codicon.copilotLarge
};
break;
case ChatAgentLocation.EditingSession:
id = isToolsAgent ? 'setup.agent' : 'setup.edits';
description = isToolsAgent ? localize('agentDescription', "Edit files in your workspace in agent mode") : localize('editsDescription', "Edit files in your workspace");
welcomeMessageContent = isToolsAgent ?
{
title: localize('editsTitle', "Edit with Copilot"),
message: new MarkdownString(localize('agentMessage', "Ask Copilot to edit your files in [agent mode]({0}). Copilot will automatically use multiple requests to pick files to edit, run terminal commands, and iterate on errors.", 'https://aka.ms/vscode-copilot-agent') + `\n\n${baseMessage}`),
if (mode === ChatMode.Ask) {
id = 'setup.chat';
welcomeMessageContent = {
title: description,
message: new MarkdownString(baseMessage),
icon: Codicon.copilotLarge
} :
{
};
} else if (mode === ChatMode.Edit) {
id = 'setup.edits';
description = localize('editsDescription', "Edit files in your workspace");
welcomeMessageContent = {
title: localize('editsTitle', "Edit with Copilot"),
message: new MarkdownString(localize('editsMessage', "Start your editing session by defining a set of files that you want to work with. Then ask Copilot for the changes you want to make.") + `\n\n${baseMessage}`),
icon: Codicon.copilotLarge
};
} else {
id = 'setup.agent';
description = localize('agentDescription', "Edit files in your workspace in agent mode");
welcomeMessageContent = {
title: localize('editsTitle', "Edit with Copilot"),
message: new MarkdownString(localize('agentMessage', "Ask Copilot to edit your files in [agent mode]({0}). Copilot will automatically use multiple requests to pick files to edit, run terminal commands, and iterate on errors.", 'https://aka.ms/vscode-copilot-agent') + `\n\n${baseMessage}`),
icon: Codicon.copilotLarge
};
}
break;
case ChatAgentLocation.Terminal:
id = 'setup.terminal';
@@ -152,8 +155,8 @@ class SetupChatAgentImplementation extends Disposable implements IChatAgentImple
name: `${defaultChat.providerName} Copilot`,
isDefault: true,
isCore: true,
isToolsAgent,
when: isToolsAgent ? ToolsAgentWhen?.serialize() : undefined,
modes: mode ? [mode] : [ChatMode.Ask],
when: mode === ChatMode.Agent ? ToolsAgentWhen?.serialize() : undefined,
slashCommands: [],
disambiguation: [],
locations: [location],
@@ -579,14 +582,14 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
const updateRegistration = () => {
const disabled = context.state.hidden || !this.configurationService.getValue('chat.setupFromDialog');
if (!disabled && !registration.value) {
const { agent: panelAgent, disposable: panelDisposable } = SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Panel, false, context, controller);
const { agent: panelAgent, disposable: panelDisposable } = SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Panel, ChatMode.Ask, context, controller);
registration.value = combinedDisposable(
panelDisposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Terminal, false, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Notebook, false, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Editor, false, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.EditingSession, false, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.EditingSession, true, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Terminal, undefined, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Notebook, undefined, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Editor, undefined, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Panel, ChatMode.Edit, context, controller).disposable,
SetupChatAgentImplementation.register(this.instantiationService, ChatAgentLocation.Panel, ChatMode.Agent, context, controller).disposable,
panelAgent.onUnresolvableError(() => {
// An unresolvable error from our agent registrations means that
// Copilot is unhealthy for some reason. We clear our panel
@@ -621,22 +621,24 @@ export class ChatWidget extends Disposable implements IChatWidget {
}
const numItems = this.viewModel?.getItems().length ?? 0;
const defaultAgent = this.chatAgentService.getDefaultAgent(this.location, this.input.currentMode);
const welcomeContent = defaultAgent?.metadata.welcomeMessageContent ?? this.persistedWelcomeMessage;
if (welcomeContent && !numItems && this.welcomeMessageContainer.children.length === 0) {
dom.clearNode(this.welcomeMessageContainer);
const tips = this.viewOptions.supportsAdditionalParticipants
? new MarkdownString(localize('chatWidget.tips', "{0} or type {1} to attach context\n\n{2} to chat with extensions\n\nType {3} to use commands", '$(attach)', '#', '$(mention)', '/'), { supportThemeIcons: true })
: new MarkdownString(localize('chatWidget.tips.withoutParticipants', "{0} or type {1} to attach context", '$(attach)', '#'), { supportThemeIcons: true });
this.welcomePart.value = this.instantiationService.createInstance(
ChatViewWelcomePart,
{ ...welcomeContent, tips, },
{
location: this.location,
isWidgetAgentWelcomeViewContent: this.input?.currentMode === ChatMode.Agent
}
);
dom.append(this.welcomeMessageContainer, this.welcomePart.value.element);
if (!numItems) {
const defaultAgent = this.chatAgentService.getDefaultAgent(this.location, this.input.currentMode);
const welcomeContent = defaultAgent?.metadata.welcomeMessageContent ?? this.persistedWelcomeMessage;
if (welcomeContent) {
dom.clearNode(this.welcomeMessageContainer);
const tips = this.viewOptions.supportsAdditionalParticipants
? new MarkdownString(localize('chatWidget.tips', "{0} or type {1} to attach context\n\n{2} to chat with extensions\n\nType {3} to use commands", '$(attach)', '#', '$(mention)', '/'), { supportThemeIcons: true })
: new MarkdownString(localize('chatWidget.tips.withoutParticipants', "{0} or type {1} to attach context", '$(attach)', '#'), { supportThemeIcons: true });
this.welcomePart.value = this.instantiationService.createInstance(
ChatViewWelcomePart,
{ ...welcomeContent, tips, },
{
location: this.location,
isWidgetAgentWelcomeViewContent: this.input?.currentMode === ChatMode.Agent
}
);
dom.append(this.welcomeMessageContainer, this.welcomePart.value.element);
}
}
if (this.viewModel) {
@@ -51,8 +51,6 @@ export interface IChatAgentData {
extensionDisplayName: string;
/** The agent invoked when no agent is specified */
isDefault?: boolean;
/** The default agent when "agent-mode" is enabled */
isToolsAgent?: boolean;
/** This agent is not contributed in package.json, but is registered dynamically */
isDynamic?: boolean;
/** This agent is contributed from core and not from an extension */
@@ -60,6 +58,7 @@ export interface IChatAgentData {
metadata: IChatAgentMetadata;
slashCommands: IChatAgentCommand[];
locations: ChatAgentLocation[];
modes: ChatMode[];
disambiguation: { category: string; description: string; examples: string[] }[];
}
@@ -237,7 +236,7 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
private readonly _hasDefaultAgent: IContextKey<boolean>;
private readonly _defaultAgentRegistered: IContextKey<boolean>;
private readonly _editingAgentRegistered: IContextKey<boolean>;
private readonly _hasToolsAgentContextKey: IContextKey<boolean>;
private _hasToolsAgent = false;
private _chatParticipantDetectionProviders = new Map<number, IChatParticipantDetectionProvider>();
@@ -253,8 +252,6 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
this._updateContextKeys();
}
}));
this._hasToolsAgentContextKey = ChatContextKeys.Editing.hasToolsAgent.bindTo(contextKeyService);
}
registerAgent(id: string, data: IChatAgentData): IDisposable {
@@ -303,20 +300,21 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
let defaultAgentRegistered = false;
let toolsAgentRegistered = false;
for (const agent of this.getAgents()) {
if (agent.isDefault && agent.locations.includes(ChatAgentLocation.EditingSession)) {
editingAgentRegistered = true;
if (agent.isToolsAgent) {
if (agent.isDefault) {
if (agent.modes.includes(ChatMode.Agent)) {
toolsAgentRegistered = true;
} else if (agent.modes.includes(ChatMode.Edit)) {
editingAgentRegistered = true;
} else {
defaultAgentRegistered = true;
}
} else if (agent.isDefault) {
defaultAgentRegistered = true;
}
}
this._editingAgentRegistered.set(editingAgentRegistered);
this._defaultAgentRegistered.set(defaultAgentRegistered);
if (toolsAgentRegistered !== this._hasToolsAgentContextKey.get()) {
this._hasToolsAgentContextKey.set(toolsAgentRegistered);
this._onDidChangeAgents.fire(this.getDefaultAgent(ChatAgentLocation.EditingSession));
if (toolsAgentRegistered !== this._hasToolsAgent) {
this._hasToolsAgent = toolsAgentRegistered;
this._onDidChangeAgents.fire(this.getDefaultAgent(ChatAgentLocation.Panel, ChatMode.Agent));
}
}
@@ -381,13 +379,9 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
this._onDidChangeAgents.fire(new MergedChatAgent(agent.data, agent.impl));
}
getDefaultAgent(location: ChatAgentLocation, mode?: ChatMode): IChatAgent | undefined {
if (mode === ChatMode.Edit || mode === ChatMode.Agent) {
location = ChatAgentLocation.EditingSession;
}
getDefaultAgent(location: ChatAgentLocation, mode: ChatMode = ChatMode.Ask): IChatAgent | undefined {
return this._preferExtensionAgent(this.getActivatedAgents().filter(a => {
if ((mode === ChatMode.Agent) !== !!a.isToolsAgent) {
if (mode && !a.modes.includes(mode)) {
return false;
}
@@ -396,7 +390,7 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
}
public get hasToolsAgent(): boolean {
return !!this._hasToolsAgentContextKey.get();
return !!this._hasToolsAgent;
}
getContributedDefaultAgent(location: ChatAgentLocation): IChatAgentData | undefined {
@@ -587,11 +581,11 @@ export class MergedChatAgent implements IChatAgent {
get extensionPublisherDisplayName() { return this.data.publisherDisplayName; }
get extensionDisplayName(): string { return this.data.extensionDisplayName; }
get isDefault(): boolean | undefined { return this.data.isDefault; }
get isToolsAgent(): boolean | undefined { return this.data.isToolsAgent; }
get isCore(): boolean | undefined { return this.data.isCore; }
get metadata(): IChatAgentMetadata { return this.data.metadata; }
get slashCommands(): IChatAgentCommand[] { return this.data.slashCommands; }
get locations(): ChatAgentLocation[] { return this.data.locations; }
get modes(): ChatMode[] { return this.data.modes; }
get disambiguation(): { category: string; description: string; examples: string[] }[] { return this.data.disambiguation; }
async invoke(request: IChatAgentRequest, progress: (part: IChatProgress) => void, history: IChatAgentHistoryEntry[], token: CancellationToken): Promise<IChatAgentResult> {
@@ -84,7 +84,6 @@ export namespace ChatContextKeys {
export const completionsQuotaExceeded = new RawContextKey<boolean>('completionsQuotaExceeded', false, true);
export const Editing = {
hasToolsAgent: new RawContextKey<boolean>('chatHasToolsAgent', false, { type: 'boolean', description: localize('chatEditingHasToolsAgent', "True when a tools agent is registered.") }),
agentModeDisallowed: new RawContextKey<boolean>('chatAgentModeDisallowed', undefined, { type: 'boolean', description: localize('chatAgentModeDisallowed', "True when agent mode is not allowed.") }), // experiment-driven disablement
hasToolConfirmation: new RawContextKey<boolean>('chatHasToolConfirmation', false, { type: 'boolean', description: localize('chatEditingHasToolConfirmation', "True when a tool confirmation is present.") }),
};
@@ -29,7 +29,7 @@ import { IChatEditingService, IChatEditingSession } from './chatEditingService.j
import { ChatRequestTextPart, IParsedChatRequest, reviveParsedChatRequest } from './chatParserTypes.js';
import { ChatAgentVoteDirection, ChatAgentVoteDownReason, IChatAgentMarkdownContentWithVulnerability, IChatCodeCitation, IChatCommandButton, IChatConfirmation, IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatLocationData, IChatMarkdownContent, IChatNotebookEdit, IChatProgress, IChatProgressMessage, IChatResponseCodeblockUriPart, IChatResponseProgressFileTreeData, IChatTask, IChatTextEdit, IChatToolInvocation, IChatToolInvocationSerialized, IChatTreeData, IChatUndoStop, IChatUsedContext, IChatWarningMessage, isIUsedContext } from './chatService.js';
import { IChatRequestVariableValue } from './chatVariables.js';
import { ChatAgentLocation } from './constants.js';
import { ChatAgentLocation, ChatMode } from './constants.js';
export interface IBaseChatRequestVariableEntry {
id: string;
@@ -1303,7 +1303,7 @@ export class ChatModel extends Disposable implements IChatModel {
}
private get _defaultAgent() {
return this.chatAgentService.getDefaultAgent(ChatAgentLocation.Panel);
return this.chatAgentService.getDefaultAgent(ChatAgentLocation.Panel, ChatMode.Ask);
}
get requesterUsername(): string {
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RawChatParticipantLocation } from './constants.js';
import { ChatMode, RawChatParticipantLocation } from './constants.js';
export interface IRawChatCommandContribution {
name: string;
@@ -22,11 +22,14 @@ export interface IRawChatParticipantContribution {
when?: string;
description?: string;
isDefault?: boolean;
isAgent?: boolean;
isSticky?: boolean;
sampleRequest?: string;
commands?: IRawChatCommandContribution[];
locations?: RawChatParticipantLocation[];
/**
* Valid for default participants in 'panel' location
*/
modes?: ChatMode[];
disambiguation?: { category: string; categoryName?: string /** Deprecated */; description: string; examples: string[] }[];
}
@@ -920,7 +920,7 @@ export class ChatService extends Disposable implements IChatService {
}
private async checkAgentAllowed(agent: IChatAgentData): Promise<void> {
if (agent.isToolsAgent) {
if (agent.modes.includes(ChatMode.Agent)) {
const enabled = await this.experimentService.getTreatment<boolean>('chatAgentEnabled');
if (enabled === false) {
throw new Error('Agent is currently disabled');
@@ -34,8 +34,6 @@ export enum ChatAgentLocation {
Terminal = 'terminal',
Notebook = 'notebook',
Editor = 'editor',
// TODO@roblourens Delete
EditingSession = 'editing-session',
}
export namespace ChatAgentLocation {
@@ -45,7 +43,6 @@ export namespace ChatAgentLocation {
case 'terminal': return ChatAgentLocation.Terminal;
case 'notebook': return ChatAgentLocation.Notebook;
case 'editor': return ChatAgentLocation.Editor;
case 'editing-session': return ChatAgentLocation.EditingSession;
}
return ChatAgentLocation.Panel;
}
@@ -17,7 +17,7 @@ import { IChatEditingService } from '../../common/chatEditingService.js';
import { assertThrowsAsync, ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
import { IChatVariablesService } from '../../common/chatVariables.js';
import { MockChatVariablesService } from '../common/mockChatVariables.js';
import { ChatAgentService, IChatAgentImplementation, IChatAgentService } from '../../common/chatAgents.js';
import { ChatAgentService, IChatAgentData, IChatAgentImplementation, IChatAgentService } from '../../common/chatAgents.js';
import { IChatSlashCommandService } from '../../common/chatSlashCommands.js';
import { IWorkbenchAssignmentService } from '../../../../services/assignment/common/assignmentService.js';
import { NullWorkbenchAssignmentService } from '../../../../services/assignment/test/common/nullAssignmentService.js';
@@ -31,11 +31,11 @@ import { isEqual } from '../../../../../base/common/resources.js';
import { waitForState } from '../../../../../base/common/observable.js';
import { INotebookService } from '../../../notebook/common/notebookService.js';
import { Range } from '../../../../../editor/common/core/range.js';
import { ChatAgentLocation } from '../../common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../common/constants.js';
import { NotebookTextModel } from '../../../notebook/common/model/notebookTextModel.js';
import { ChatTransferService, IChatTransferService } from '../../common/chatTransferService.js';
function getAgentData(id: string) {
function getAgentData(id: string): IChatAgentData {
return {
name: id,
id: id,
@@ -44,6 +44,7 @@ function getAgentData(id: string) {
publisherDisplayName: '',
extensionDisplayName: '',
locations: [ChatAgentLocation.Panel],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -36,6 +36,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -36,6 +36,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -22,6 +22,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -22,6 +22,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -22,6 +22,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -22,6 +22,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -22,6 +22,7 @@
extensionDisplayName: "",
extensionPublisherId: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [
{
@@ -32,6 +32,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [ ],
disambiguation: [ ]
@@ -74,6 +75,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [ ],
disambiguation: [ ]
@@ -32,6 +32,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [ ],
disambiguation: [ ]
@@ -74,6 +75,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [ ],
disambiguation: [ ]
@@ -31,6 +31,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { requester: { name: "test" } },
slashCommands: [ ],
disambiguation: [ ]
@@ -81,6 +82,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { requester: { name: "test" } },
slashCommands: [ ],
disambiguation: [ ]
@@ -148,6 +150,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { requester: { name: "test" } },
slashCommands: [ ],
disambiguation: [ ],
@@ -31,6 +31,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [ ],
disambiguation: [ ]
@@ -74,6 +75,7 @@
publisherDisplayName: "",
extensionDisplayName: "",
locations: [ "panel" ],
modes: [ "ask" ],
metadata: { },
slashCommands: [ ],
disambiguation: [ ]
@@ -18,6 +18,7 @@ const testAgentData: IChatAgentData = {
extensionId: new ExtensionIdentifier(''),
extensionPublisherId: '',
locations: [],
modes: [],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -120,7 +120,7 @@ suite('ChatRequestParser', () => {
// });
const getAgentWithSlashCommands = (slashCommands: IChatAgentCommand[]) => {
return { id: 'agent', name: 'agent', extensionId: nullExtensionDescription.identifier, publisherDisplayName: '', extensionDisplayName: '', extensionPublisherId: '', locations: [ChatAgentLocation.Panel], metadata: {}, slashCommands, disambiguation: [] } satisfies IChatAgentData;
return { id: 'agent', name: 'agent', extensionId: nullExtensionDescription.identifier, publisherDisplayName: '', extensionDisplayName: '', extensionPublisherId: '', locations: [ChatAgentLocation.Panel], modes: [ChatMode.Ask], metadata: {}, slashCommands, disambiguation: [] } satisfies IChatAgentData;
};
test('agent with subcommand after text', async () => {
@@ -30,14 +30,14 @@ import { IExtensionService, nullExtensionDescription } from '../../../../service
import { ILifecycleService } from '../../../../services/lifecycle/common/lifecycle.js';
import { IViewsService } from '../../../../services/views/common/viewsService.js';
import { mock, TestContextService, TestExtensionService, TestStorageService } from '../../../../test/common/workbenchTestServices.js';
import { ChatAgentService, IChatAgent, IChatAgentImplementation, IChatAgentService } from '../../common/chatAgents.js';
import { ChatAgentService, IChatAgent, IChatAgentData, IChatAgentImplementation, IChatAgentService } from '../../common/chatAgents.js';
import { IChatEditingService, IChatEditingSession } from '../../common/chatEditingService.js';
import { IChatModel, ISerializableChatData } from '../../common/chatModel.js';
import { IChatFollowup, IChatService } from '../../common/chatService.js';
import { ChatService } from '../../common/chatServiceImpl.js';
import { ChatSlashCommandService, IChatSlashCommandService } from '../../common/chatSlashCommands.js';
import { IChatVariablesService } from '../../common/chatVariables.js';
import { ChatAgentLocation } from '../../common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../common/constants.js';
import { MockChatService } from './mockChatService.js';
import { MockChatVariablesService } from './mockChatVariables.js';
@@ -50,6 +50,7 @@ const chatAgentWithUsedContext: IChatAgent = {
extensionPublisherId: '',
extensionDisplayName: '',
locations: [ChatAgentLocation.Panel],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -83,6 +84,7 @@ const chatAgentWithMarkdown: IChatAgent = {
extensionPublisherId: '',
extensionDisplayName: '',
locations: [ChatAgentLocation.Panel],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -95,7 +97,7 @@ const chatAgentWithMarkdown: IChatAgent = {
},
};
function getAgentData(id: string) {
function getAgentData(id: string): IChatAgentData {
return {
name: id,
id: id,
@@ -104,6 +106,7 @@ function getAgentData(id: string) {
publisherDisplayName: '',
extensionDisplayName: '',
locations: [ChatAgentLocation.Panel],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -17,7 +17,7 @@ import { IChatAgent, IChatAgentCommand, IChatAgentCompletionItem, IChatAgentData
import { IChatModel } from '../../common/chatModel.js';
import { IChatFollowup, IChatProgress } from '../../common/chatService.js';
import { IVoiceChatSessionOptions, IVoiceChatTextEvent, VoiceChatService } from '../../common/voiceChatService.js';
import { ChatAgentLocation } from '../../common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../common/constants.js';
suite('VoiceChat', () => {
@@ -32,6 +32,7 @@ suite('VoiceChat', () => {
extensionDisplayName = '';
extensionPublisherId = '';
locations: ChatAgentLocation[] = [ChatAgentLocation.Panel];
modes = [ChatMode.Ask];
public readonly name: string;
constructor(readonly id: string, readonly slashCommands: IChatAgentCommand[]) {
this.name = id;
@@ -339,7 +339,7 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService {
this._onWillStartSession.fire(editor as IActiveCodeEditor);
const chatModel = this._chatService.startSession(ChatAgentLocation.EditingSession, token, false);
const chatModel = this._chatService.startSession(ChatAgentLocation.Panel, token, false);
const editingSession = await chatModel.editingSessionObs?.promise!;
const widget = this._chatWidgetService.getWidgetBySessionId(chatModel.sessionId);
@@ -71,7 +71,7 @@ import { ChatInputBoxContentProvider } from '../../../chat/browser/chatEdinputIn
import { constObservable, IObservable } from '../../../../../base/common/observable.js';
import { ILanguageModelToolsService } from '../../../chat/common/languageModelToolsService.js';
import { MockLanguageModelToolsService } from '../../../chat/test/common/mockLanguageModelToolsService.js';
import { ChatAgentLocation } from '../../../chat/common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../../chat/common/constants.js';
suite('InlineChatController', function () {
@@ -84,6 +84,7 @@ suite('InlineChatController', function () {
name: 'testEditorAgent',
isDefault: true,
locations: [ChatAgentLocation.Editor],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -62,7 +62,7 @@ import { IChatRequestModel } from '../../../chat/common/chatModel.js';
import { assertSnapshot } from '../../../../../base/test/common/snapshot.js';
import { IObservable, constObservable } from '../../../../../base/common/observable.js';
import { IChatEditingService, IChatEditingSession } from '../../../chat/common/chatEditingService.js';
import { ChatAgentLocation } from '../../../chat/common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../../chat/common/constants.js';
import { ChatTransferService, IChatTransferService } from '../../../chat/common/chatTransferService.js';
suite('InlineChatSession', function () {
@@ -141,6 +141,7 @@ suite('InlineChatSession', function () {
name: 'testAgent',
isDefault: true,
locations: [ChatAgentLocation.Editor],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -21,7 +21,7 @@ import { CellKind, NotebookSetting } from '../../../common/notebookCommon.js';
import { ICellExecutionStateChangedEvent, IExecutionStateChangedEvent, INotebookCellExecution, INotebookExecutionStateService, NotebookExecutionType } from '../../../common/notebookExecutionStateService.js';
import { setupInstantiationService, TestNotebookExecutionStateService, withTestNotebook } from '../testNotebookEditor.js';
import { nullExtensionDescription } from '../../../../../services/extensions/common/extensions.js';
import { ChatAgentLocation } from '../../../../chat/common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../../../chat/common/constants.js';
suite('notebookCellDiagnostics', () => {
@@ -73,6 +73,7 @@ suite('notebookCellDiagnostics', () => {
name: 'testEditorAgent',
isDefault: true,
locations: [ChatAgentLocation.Notebook],
modes: [ChatMode.Ask],
metadata: {},
slashCommands: [],
disambiguation: [],
@@ -15,7 +15,7 @@ import { strictEqual } from 'assert';
import { ExtensionIdentifier } from '../../../../../../platform/extensions/common/extensions.js';
import { IChatAgent } from '../../../../chat/common/chatAgents.js';
import { importAMDNodeModule } from '../../../../../../amdX.js';
import { ChatAgentLocation } from '../../../../chat/common/constants.js';
import { ChatAgentLocation, ChatMode } from '../../../../chat/common/constants.js';
suite('Terminal Initial Hint Addon', () => {
const store = ensureNoDisposablesAreLeakedInTestSuite();
@@ -34,6 +34,7 @@ suite('Terminal Initial Hint Addon', () => {
slashCommands: [{ name: 'test', description: 'test' }],
disambiguation: [],
locations: [ChatAgentLocation.fromRaw('terminal')],
modes: [ChatMode.Ask],
invoke: async () => { return {}; }
};
const editorAgent: IChatAgent = {
@@ -45,6 +46,7 @@ suite('Terminal Initial Hint Addon', () => {
metadata: {},
slashCommands: [{ name: 'test', description: 'test' }],
locations: [ChatAgentLocation.fromRaw('editor')],
modes: [ChatMode.Ask],
disambiguation: [],
invoke: async () => { return {}; }
};
+1 -5
View File
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 6
// version: 7
declare module 'vscode' {
@@ -27,10 +27,6 @@ declare module 'vscode' {
* Code editor inline chat
*/
Editor = 4,
/**
* Chat is happening in an editing session
*/
EditingSession = 5,
}
export class ChatRequestEditorData {
+1 -1
View File
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 3
// version: 4
declare module 'vscode' {