Path: blob/main/src/vs/workbench/contrib/chat/test/common/mockChatSessionsService.ts
4780 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CancellationToken } from '../../../../../base/common/cancellation.js';6import { Emitter } from '../../../../../base/common/event.js';7import { IDisposable } from '../../../../../base/common/lifecycle.js';8import { ResourceMap } from '../../../../../base/common/map.js';9import { ThemeIcon } from '../../../../../base/common/themables.js';10import { URI } from '../../../../../base/common/uri.js';11import { IChatAgentAttachmentCapabilities } from '../../common/participants/chatAgents.js';12import { IChatModel } from '../../common/model/chatModel.js';13import { IChatService } from '../../common/chatService/chatService.js';14import { IChatSession, IChatSessionContentProvider, IChatSessionItem, IChatSessionItemProvider, IChatSessionProviderOptionGroup, IChatSessionsExtensionPoint, IChatSessionsService, SessionOptionsChangedCallback } from '../../common/chatSessionsService.js';1516export class MockChatSessionsService implements IChatSessionsService {17_serviceBrand: undefined;1819private readonly _onDidChangeSessionOptions = new Emitter<URI>();20readonly onDidChangeSessionOptions = this._onDidChangeSessionOptions.event;21private readonly _onDidChangeItemsProviders = new Emitter<IChatSessionItemProvider>();22readonly onDidChangeItemsProviders = this._onDidChangeItemsProviders.event;2324private readonly _onDidChangeSessionItems = new Emitter<string>();25readonly onDidChangeSessionItems = this._onDidChangeSessionItems.event;2627private readonly _onDidChangeAvailability = new Emitter<void>();28readonly onDidChangeAvailability = this._onDidChangeAvailability.event;2930private readonly _onDidChangeInProgress = new Emitter<void>();31readonly onDidChangeInProgress = this._onDidChangeInProgress.event;3233private readonly _onDidChangeContentProviderSchemes = new Emitter<{ readonly added: string[]; readonly removed: string[] }>();34readonly onDidChangeContentProviderSchemes = this._onDidChangeContentProviderSchemes.event;3536private readonly _onDidChangeOptionGroups = new Emitter<string>();37readonly onDidChangeOptionGroups = this._onDidChangeOptionGroups.event;3839private sessionItemProviders = new Map<string, IChatSessionItemProvider>();40private contentProviders = new Map<string, IChatSessionContentProvider>();41private contributions: IChatSessionsExtensionPoint[] = [];42private optionGroups = new Map<string, IChatSessionProviderOptionGroup[]>();43private sessionOptions = new ResourceMap<Map<string, string>>();44private inProgress = new Map<string, number>();45private onChange = () => { };4647// For testing: allow triggering events48fireDidChangeItemsProviders(provider: IChatSessionItemProvider): void {49this._onDidChangeItemsProviders.fire(provider);50}5152fireDidChangeSessionItems(chatSessionType: string): void {53this._onDidChangeSessionItems.fire(chatSessionType);54}5556fireDidChangeAvailability(): void {57this._onDidChangeAvailability.fire();58}5960fireDidChangeInProgress(): void {61this._onDidChangeInProgress.fire();62}6364registerChatSessionItemProvider(provider: IChatSessionItemProvider): IDisposable {65this.sessionItemProviders.set(provider.chatSessionType, provider);66return {67dispose: () => {68this.sessionItemProviders.delete(provider.chatSessionType);69}70};71}7273getAllChatSessionContributions(): IChatSessionsExtensionPoint[] {74return this.contributions;75}7677getChatSessionContribution(chatSessionType: string): IChatSessionsExtensionPoint | undefined {78return this.contributions.find(contrib => contrib.type === chatSessionType);79}8081setContributions(contributions: IChatSessionsExtensionPoint[]): void {82this.contributions = contributions;83}8485async activateChatSessionItemProvider(chatSessionType: string): Promise<IChatSessionItemProvider | undefined> {86return this.sessionItemProviders.get(chatSessionType);87}8889getAllChatSessionItemProviders(): IChatSessionItemProvider[] {90return Array.from(this.sessionItemProviders.values());91}9293getIconForSessionType(chatSessionType: string): ThemeIcon | URI | undefined {94const contribution = this.contributions.find(c => c.type === chatSessionType);95return contribution?.icon && typeof contribution.icon === 'string' ? ThemeIcon.fromId(contribution.icon) : undefined;96}9798getWelcomeTitleForSessionType(chatSessionType: string): string | undefined {99return this.contributions.find(c => c.type === chatSessionType)?.welcomeTitle;100}101102getWelcomeMessageForSessionType(chatSessionType: string): string | undefined {103return this.contributions.find(c => c.type === chatSessionType)?.welcomeMessage;104}105106getInputPlaceholderForSessionType(chatSessionType: string): string | undefined {107return this.contributions.find(c => c.type === chatSessionType)?.inputPlaceholder;108}109110getAllChatSessionItems(token: CancellationToken): Promise<Array<{ readonly chatSessionType: string; readonly items: IChatSessionItem[] }>> {111return Promise.all(Array.from(this.sessionItemProviders.values(), async provider => {112return {113chatSessionType: provider.chatSessionType,114items: await provider.provideChatSessionItems(token),115};116}));117}118119reportInProgress(chatSessionType: string, count: number): void {120this.inProgress.set(chatSessionType, count);121this._onDidChangeInProgress.fire();122}123124getInProgress(): { displayName: string; count: number }[] {125return Array.from(this.inProgress.entries()).map(([displayName, count]) => ({ displayName, count }));126}127128registerChatSessionContentProvider(chatSessionType: string, provider: IChatSessionContentProvider): IDisposable {129this.contentProviders.set(chatSessionType, provider);130this._onDidChangeContentProviderSchemes.fire({ added: [chatSessionType], removed: [] });131return {132dispose: () => {133this.contentProviders.delete(chatSessionType);134}135};136}137138async canResolveContentProvider(chatSessionType: string): Promise<boolean> {139return this.contentProviders.has(chatSessionType);140}141142async getOrCreateChatSession(sessionResource: URI, token: CancellationToken): Promise<IChatSession> {143const provider = this.contentProviders.get(sessionResource.scheme);144if (!provider) {145throw new Error(`No content provider for ${sessionResource.scheme}`);146}147return provider.provideChatSessionContent(sessionResource, token);148}149150async canResolveChatSession(chatSessionResource: URI): Promise<boolean> {151return this.contentProviders.has(chatSessionResource.scheme);152}153154getOptionGroupsForSessionType(chatSessionType: string): IChatSessionProviderOptionGroup[] | undefined {155return this.optionGroups.get(chatSessionType);156}157158setOptionGroupsForSessionType(chatSessionType: string, handle: number, optionGroups?: IChatSessionProviderOptionGroup[]): void {159if (optionGroups) {160this.optionGroups.set(chatSessionType, optionGroups);161} else {162this.optionGroups.delete(chatSessionType);163}164}165166private optionsChangeCallback?: SessionOptionsChangedCallback;167168setOptionsChangeCallback(callback: SessionOptionsChangedCallback): void {169this.optionsChangeCallback = callback;170}171172async notifySessionOptionsChange(sessionResource: URI, updates: ReadonlyArray<{ optionId: string; value: string }>): Promise<void> {173await this.optionsChangeCallback?.(sessionResource, updates);174}175176notifySessionItemsChanged(chatSessionType: string): void {177this._onDidChangeSessionItems.fire(chatSessionType);178}179180getSessionOption(sessionResource: URI, optionId: string): string | undefined {181return this.sessionOptions.get(sessionResource)?.get(optionId);182}183184setSessionOption(sessionResource: URI, optionId: string, value: string): boolean {185if (!this.sessionOptions.has(sessionResource)) {186this.sessionOptions.set(sessionResource, new Map());187}188this.sessionOptions.get(sessionResource)!.set(optionId, value);189return true;190}191192hasAnySessionOptions(resource: URI): boolean {193return this.sessionOptions.has(resource) && this.sessionOptions.get(resource)!.size > 0;194}195196getCapabilitiesForSessionType(chatSessionType: string): IChatAgentAttachmentCapabilities | undefined {197return this.contributions.find(c => c.type === chatSessionType)?.capabilities;198}199200getContentProviderSchemes(): string[] {201return Array.from(this.contentProviders.keys());202}203204getInProgressSessionDescription(chatModel: IChatModel): string | undefined {205return undefined;206}207208registerChatModelChangeListeners(chatService: IChatService, chatSessionType: string, onChange: () => void): IDisposable {209// Store the emitter so tests can trigger it210this.onChange = onChange;211return {212dispose: () => {213}214};215}216217// Helper method for tests to trigger progress events218triggerProgressEvent(): void {219if (this.onChange) {220this.onChange();221}222}223}224225226