Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/test/common/mockChatSessionsService.ts
4780 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { CancellationToken } from '../../../../../base/common/cancellation.js';
7
import { Emitter } from '../../../../../base/common/event.js';
8
import { IDisposable } from '../../../../../base/common/lifecycle.js';
9
import { ResourceMap } from '../../../../../base/common/map.js';
10
import { ThemeIcon } from '../../../../../base/common/themables.js';
11
import { URI } from '../../../../../base/common/uri.js';
12
import { IChatAgentAttachmentCapabilities } from '../../common/participants/chatAgents.js';
13
import { IChatModel } from '../../common/model/chatModel.js';
14
import { IChatService } from '../../common/chatService/chatService.js';
15
import { IChatSession, IChatSessionContentProvider, IChatSessionItem, IChatSessionItemProvider, IChatSessionProviderOptionGroup, IChatSessionsExtensionPoint, IChatSessionsService, SessionOptionsChangedCallback } from '../../common/chatSessionsService.js';
16
17
export class MockChatSessionsService implements IChatSessionsService {
18
_serviceBrand: undefined;
19
20
private readonly _onDidChangeSessionOptions = new Emitter<URI>();
21
readonly onDidChangeSessionOptions = this._onDidChangeSessionOptions.event;
22
private readonly _onDidChangeItemsProviders = new Emitter<IChatSessionItemProvider>();
23
readonly onDidChangeItemsProviders = this._onDidChangeItemsProviders.event;
24
25
private readonly _onDidChangeSessionItems = new Emitter<string>();
26
readonly onDidChangeSessionItems = this._onDidChangeSessionItems.event;
27
28
private readonly _onDidChangeAvailability = new Emitter<void>();
29
readonly onDidChangeAvailability = this._onDidChangeAvailability.event;
30
31
private readonly _onDidChangeInProgress = new Emitter<void>();
32
readonly onDidChangeInProgress = this._onDidChangeInProgress.event;
33
34
private readonly _onDidChangeContentProviderSchemes = new Emitter<{ readonly added: string[]; readonly removed: string[] }>();
35
readonly onDidChangeContentProviderSchemes = this._onDidChangeContentProviderSchemes.event;
36
37
private readonly _onDidChangeOptionGroups = new Emitter<string>();
38
readonly onDidChangeOptionGroups = this._onDidChangeOptionGroups.event;
39
40
private sessionItemProviders = new Map<string, IChatSessionItemProvider>();
41
private contentProviders = new Map<string, IChatSessionContentProvider>();
42
private contributions: IChatSessionsExtensionPoint[] = [];
43
private optionGroups = new Map<string, IChatSessionProviderOptionGroup[]>();
44
private sessionOptions = new ResourceMap<Map<string, string>>();
45
private inProgress = new Map<string, number>();
46
private onChange = () => { };
47
48
// For testing: allow triggering events
49
fireDidChangeItemsProviders(provider: IChatSessionItemProvider): void {
50
this._onDidChangeItemsProviders.fire(provider);
51
}
52
53
fireDidChangeSessionItems(chatSessionType: string): void {
54
this._onDidChangeSessionItems.fire(chatSessionType);
55
}
56
57
fireDidChangeAvailability(): void {
58
this._onDidChangeAvailability.fire();
59
}
60
61
fireDidChangeInProgress(): void {
62
this._onDidChangeInProgress.fire();
63
}
64
65
registerChatSessionItemProvider(provider: IChatSessionItemProvider): IDisposable {
66
this.sessionItemProviders.set(provider.chatSessionType, provider);
67
return {
68
dispose: () => {
69
this.sessionItemProviders.delete(provider.chatSessionType);
70
}
71
};
72
}
73
74
getAllChatSessionContributions(): IChatSessionsExtensionPoint[] {
75
return this.contributions;
76
}
77
78
getChatSessionContribution(chatSessionType: string): IChatSessionsExtensionPoint | undefined {
79
return this.contributions.find(contrib => contrib.type === chatSessionType);
80
}
81
82
setContributions(contributions: IChatSessionsExtensionPoint[]): void {
83
this.contributions = contributions;
84
}
85
86
async activateChatSessionItemProvider(chatSessionType: string): Promise<IChatSessionItemProvider | undefined> {
87
return this.sessionItemProviders.get(chatSessionType);
88
}
89
90
getAllChatSessionItemProviders(): IChatSessionItemProvider[] {
91
return Array.from(this.sessionItemProviders.values());
92
}
93
94
getIconForSessionType(chatSessionType: string): ThemeIcon | URI | undefined {
95
const contribution = this.contributions.find(c => c.type === chatSessionType);
96
return contribution?.icon && typeof contribution.icon === 'string' ? ThemeIcon.fromId(contribution.icon) : undefined;
97
}
98
99
getWelcomeTitleForSessionType(chatSessionType: string): string | undefined {
100
return this.contributions.find(c => c.type === chatSessionType)?.welcomeTitle;
101
}
102
103
getWelcomeMessageForSessionType(chatSessionType: string): string | undefined {
104
return this.contributions.find(c => c.type === chatSessionType)?.welcomeMessage;
105
}
106
107
getInputPlaceholderForSessionType(chatSessionType: string): string | undefined {
108
return this.contributions.find(c => c.type === chatSessionType)?.inputPlaceholder;
109
}
110
111
getAllChatSessionItems(token: CancellationToken): Promise<Array<{ readonly chatSessionType: string; readonly items: IChatSessionItem[] }>> {
112
return Promise.all(Array.from(this.sessionItemProviders.values(), async provider => {
113
return {
114
chatSessionType: provider.chatSessionType,
115
items: await provider.provideChatSessionItems(token),
116
};
117
}));
118
}
119
120
reportInProgress(chatSessionType: string, count: number): void {
121
this.inProgress.set(chatSessionType, count);
122
this._onDidChangeInProgress.fire();
123
}
124
125
getInProgress(): { displayName: string; count: number }[] {
126
return Array.from(this.inProgress.entries()).map(([displayName, count]) => ({ displayName, count }));
127
}
128
129
registerChatSessionContentProvider(chatSessionType: string, provider: IChatSessionContentProvider): IDisposable {
130
this.contentProviders.set(chatSessionType, provider);
131
this._onDidChangeContentProviderSchemes.fire({ added: [chatSessionType], removed: [] });
132
return {
133
dispose: () => {
134
this.contentProviders.delete(chatSessionType);
135
}
136
};
137
}
138
139
async canResolveContentProvider(chatSessionType: string): Promise<boolean> {
140
return this.contentProviders.has(chatSessionType);
141
}
142
143
async getOrCreateChatSession(sessionResource: URI, token: CancellationToken): Promise<IChatSession> {
144
const provider = this.contentProviders.get(sessionResource.scheme);
145
if (!provider) {
146
throw new Error(`No content provider for ${sessionResource.scheme}`);
147
}
148
return provider.provideChatSessionContent(sessionResource, token);
149
}
150
151
async canResolveChatSession(chatSessionResource: URI): Promise<boolean> {
152
return this.contentProviders.has(chatSessionResource.scheme);
153
}
154
155
getOptionGroupsForSessionType(chatSessionType: string): IChatSessionProviderOptionGroup[] | undefined {
156
return this.optionGroups.get(chatSessionType);
157
}
158
159
setOptionGroupsForSessionType(chatSessionType: string, handle: number, optionGroups?: IChatSessionProviderOptionGroup[]): void {
160
if (optionGroups) {
161
this.optionGroups.set(chatSessionType, optionGroups);
162
} else {
163
this.optionGroups.delete(chatSessionType);
164
}
165
}
166
167
private optionsChangeCallback?: SessionOptionsChangedCallback;
168
169
setOptionsChangeCallback(callback: SessionOptionsChangedCallback): void {
170
this.optionsChangeCallback = callback;
171
}
172
173
async notifySessionOptionsChange(sessionResource: URI, updates: ReadonlyArray<{ optionId: string; value: string }>): Promise<void> {
174
await this.optionsChangeCallback?.(sessionResource, updates);
175
}
176
177
notifySessionItemsChanged(chatSessionType: string): void {
178
this._onDidChangeSessionItems.fire(chatSessionType);
179
}
180
181
getSessionOption(sessionResource: URI, optionId: string): string | undefined {
182
return this.sessionOptions.get(sessionResource)?.get(optionId);
183
}
184
185
setSessionOption(sessionResource: URI, optionId: string, value: string): boolean {
186
if (!this.sessionOptions.has(sessionResource)) {
187
this.sessionOptions.set(sessionResource, new Map());
188
}
189
this.sessionOptions.get(sessionResource)!.set(optionId, value);
190
return true;
191
}
192
193
hasAnySessionOptions(resource: URI): boolean {
194
return this.sessionOptions.has(resource) && this.sessionOptions.get(resource)!.size > 0;
195
}
196
197
getCapabilitiesForSessionType(chatSessionType: string): IChatAgentAttachmentCapabilities | undefined {
198
return this.contributions.find(c => c.type === chatSessionType)?.capabilities;
199
}
200
201
getContentProviderSchemes(): string[] {
202
return Array.from(this.contentProviders.keys());
203
}
204
205
getInProgressSessionDescription(chatModel: IChatModel): string | undefined {
206
return undefined;
207
}
208
209
registerChatModelChangeListeners(chatService: IChatService, chatSessionType: string, onChange: () => void): IDisposable {
210
// Store the emitter so tests can trigger it
211
this.onChange = onChange;
212
return {
213
dispose: () => {
214
}
215
};
216
}
217
218
// Helper method for tests to trigger progress events
219
triggerProgressEvent(): void {
220
if (this.onChange) {
221
this.onChange();
222
}
223
}
224
}
225
226