Skip to content

Commit d1d3e55

Browse files
authored
Input type attribute to chat model (microsoft#265702)
* Adding a way to identify chat models originated from contributions * Rename to input type * Input type rename * Using model data got get inputtype * Review comments * Using initialModelProps * Clean up
1 parent 5024429 commit d1d3e55

File tree

5 files changed

+37
-43
lines changed

5 files changed

+37
-43
lines changed

src/vs/workbench/contrib/chat/browser/chatEditorInput.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,16 @@ export class ChatEditorInput extends EditorInput implements IEditorCloseHandler
172172
}
173173

174174
override async resolve(): Promise<ChatEditorModel | null> {
175+
const searchParams = new URLSearchParams(this.resource.query);
176+
const chatSessionType = searchParams.get('chatSessionType');
177+
const inputType = chatSessionType ?? this.resource.authority;
175178
if (this.resource.scheme === Schemas.vscodeChatSession) {
176179
this.model = await this.chatService.loadSessionForResource(this.resource, ChatAgentLocation.Editor, CancellationToken.None);
177180
} else if (typeof this.sessionId === 'string') {
178181
this.model = await this.chatService.getOrRestoreSession(this.sessionId)
179-
?? this.chatService.startSession(ChatAgentLocation.Panel, CancellationToken.None);
182+
?? this.chatService.startSession(ChatAgentLocation.Panel, CancellationToken.None, undefined, inputType);
180183
} else if (!this.options.target) {
181-
this.model = this.chatService.startSession(ChatAgentLocation.Panel, CancellationToken.None);
184+
this.model = this.chatService.startSession(ChatAgentLocation.Panel, CancellationToken.None, undefined, inputType);
182185
} else if ('data' in this.options.target) {
183186
this.model = this.chatService.loadSessionFromContent(this.options.target.data);
184187
}

src/vs/workbench/contrib/chat/common/chatModel.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,7 @@ export interface IExportableChatData {
11201120
responderUsername: string;
11211121
requesterAvatarIconUri: UriComponents | undefined;
11221122
responderAvatarIconUri: ThemeIcon | UriComponents | undefined; // Keeping Uri name for backcompat
1123+
inputType?: string;
11231124
}
11241125

11251126
/*
@@ -1144,11 +1145,12 @@ export interface ISerializableChatData2 extends ISerializableChatData1 {
11441145
export interface ISerializableChatData3 extends Omit<ISerializableChatData2, 'version' | 'computedTitle'> {
11451146
version: 3;
11461147
customTitle: string | undefined;
1148+
inputType?: string;
11471149
}
11481150

11491151
/**
1150-
* Chat data that has been parsed and normalized to the current format.
1151-
*/
1152+
* Chat data that has been parsed and normalized to the current format.
1153+
*/
11521154
export type ISerializableChatData = ISerializableChatData3;
11531155

11541156
/**
@@ -1404,10 +1406,6 @@ export class ChatModel extends Disposable implements IChatModel {
14041406
return this._customTitle || ChatModel.getDefaultTitle(this._requests);
14051407
}
14061408

1407-
get initialLocation() {
1408-
return this._initialLocation;
1409-
}
1410-
14111409
private _editingSession: ObservablePromise<IChatEditingSession> | undefined;
14121410
get editingSessionObs(): ObservablePromise<IChatEditingSession> | undefined {
14131411
return this._editingSession;
@@ -1417,9 +1415,19 @@ export class ChatModel extends Disposable implements IChatModel {
14171415
return this._editingSession?.promiseResult.get()?.data;
14181416
}
14191417

1418+
private readonly _inputType: string | undefined;
1419+
get inputType(): string | undefined {
1420+
return this._inputType;
1421+
}
1422+
1423+
private readonly _initialLocation: ChatAgentLocation;
1424+
get initialLocation(): ChatAgentLocation {
1425+
return this._initialLocation;
1426+
}
1427+
14201428
constructor(
14211429
private readonly initialData: ISerializableChatData | IExportableChatData | undefined,
1422-
private readonly _initialLocation: ChatAgentLocation,
1430+
initialModelProps: { initialLocation: ChatAgentLocation; inputType?: string },
14231431
@ILogService private readonly logService: ILogService,
14241432
@IChatAgentService private readonly chatAgentService: IChatAgentService,
14251433
@IChatEditingService private readonly chatEditingService: IChatEditingService,
@@ -1441,6 +1449,8 @@ export class ChatModel extends Disposable implements IChatModel {
14411449
this._initialRequesterAvatarIconUri = initialData?.requesterAvatarIconUri && URI.revive(initialData.requesterAvatarIconUri);
14421450
this._initialResponderAvatarIconUri = isUriComponents(initialData?.responderAvatarIconUri) ? URI.revive(initialData.responderAvatarIconUri) : initialData?.responderAvatarIconUri;
14431451

1452+
this._inputType = initialData?.inputType ?? initialModelProps.inputType;
1453+
this._initialLocation = initialData?.initialLocation ?? initialModelProps.initialLocation;
14441454

14451455
const lastResponse = observableFromEvent(this, this.onDidChange, () => this._requests.at(-1)?.response);
14461456

src/vs/workbench/contrib/chat/common/chatService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ export interface IChatService {
675675

676676
isEnabled(location: ChatAgentLocation): boolean;
677677
hasSessions(): boolean;
678-
startSession(location: ChatAgentLocation, token: CancellationToken, isGlobalEditingSession?: boolean): ChatModel;
678+
startSession(location: ChatAgentLocation, token: CancellationToken, isGlobalEditingSession?: boolean, inputType?: string): ChatModel;
679679
getSession(sessionId: string): IChatModel | undefined;
680680
getOrRestoreSession(sessionId: string): Promise<IChatModel | undefined>;
681681
getPersistedSessionTitle(sessionId: string): string | undefined;

src/vs/workbench/contrib/chat/common/chatServiceImpl.ts

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ export class ChatService extends Disposable implements IChatService {
180180
private saveState(): void {
181181
const liveChats = Array.from(this._sessionModels.values())
182182
.filter(session =>
183-
this.shouldSaveToHistory(session.sessionId) && (session.initialLocation === ChatAgentLocation.Panel || session.initialLocation === ChatAgentLocation.Editor));
183+
!session.inputType && (session.initialLocation === ChatAgentLocation.Panel || session.initialLocation === ChatAgentLocation.Editor));
184184

185185
if (this.useFileStorage) {
186186
this._chatSessionStore.storeSessions(liveChats);
@@ -415,7 +415,7 @@ export class ChatService extends Disposable implements IChatService {
415415
async getHistory(): Promise<IChatDetail[]> {
416416
if (this.useFileStorage) {
417417
const liveSessionItems = Array.from(this._sessionModels.values())
418-
.filter(session => !session.isImported)
418+
.filter(session => !session.isImported && !session.inputType)
419419
.map(session => {
420420
const title = session.title || localize('newChat', "New Chat");
421421
return {
@@ -489,13 +489,13 @@ export class ChatService extends Disposable implements IChatService {
489489
this.saveState();
490490
}
491491

492-
startSession(location: ChatAgentLocation, token: CancellationToken, isGlobalEditingSession: boolean = true): ChatModel {
492+
startSession(location: ChatAgentLocation, token: CancellationToken, isGlobalEditingSession: boolean = true, inputType?: string): ChatModel {
493493
this.trace('startSession');
494-
return this._startSession(undefined, location, isGlobalEditingSession, token);
494+
return this._startSession(undefined, location, isGlobalEditingSession, token, inputType);
495495
}
496496

497-
private _startSession(someSessionHistory: IExportableChatData | ISerializableChatData | undefined, location: ChatAgentLocation, isGlobalEditingSession: boolean, token: CancellationToken): ChatModel {
498-
const model = this.instantiationService.createInstance(ChatModel, someSessionHistory, location);
497+
private _startSession(someSessionHistory: IExportableChatData | ISerializableChatData | undefined, location: ChatAgentLocation, isGlobalEditingSession: boolean, token: CancellationToken, inputType?: string): ChatModel {
498+
const model = this.instantiationService.createInstance(ChatModel, someSessionHistory, { initialLocation: location, inputType });
499499
if (location === ChatAgentLocation.Panel) {
500500
model.startEditingSession(isGlobalEditingSession);
501501
}
@@ -632,7 +632,7 @@ export class ChatService extends Disposable implements IChatService {
632632
const chatSessionType = parsed.chatSessionType;
633633
const content = await this.chatSessionService.provideChatSessionContent(chatSessionType, parsed.sessionId, CancellationToken.None);
634634

635-
const model = this._startSession(undefined, location, true, CancellationToken.None);
635+
const model = this._startSession(undefined, location, true, CancellationToken.None, chatSessionType);
636636
if (!this._contentProviderSessionModels.has(chatSessionType)) {
637637
this._contentProviderSessionModels.set(chatSessionType, new Map());
638638
}
@@ -1238,14 +1238,13 @@ export class ChatService extends Disposable implements IChatService {
12381238
}
12391239

12401240
async clearSession(sessionId: string): Promise<void> {
1241-
const shouldSaveToHistory = this.shouldSaveToHistory(sessionId);
1242-
this.trace('clearSession', `sessionId: ${sessionId}, save to history: ${shouldSaveToHistory}`);
1241+
this.trace('clearSession', `sessionId: ${sessionId}`);
12431242
const model = this._sessionModels.get(sessionId);
12441243
if (!model) {
12451244
throw new Error(`Unknown session: ${sessionId}`);
12461245
}
1247-
1248-
if (shouldSaveToHistory && (model.initialLocation === ChatAgentLocation.Panel || model.initialLocation === ChatAgentLocation.Editor)) {
1246+
this.trace(`Model input type: ${model.inputType}`);
1247+
if (!model.inputType && (model.initialLocation === ChatAgentLocation.Panel || model.initialLocation === ChatAgentLocation.Editor)) {
12491248
if (this.useFileStorage) {
12501249
// Always preserve sessions that have custom titles, even if empty
12511250
if (model.getRequests().length === 0 && !model.customTitle) {
@@ -1310,22 +1309,4 @@ export class ChatService extends Disposable implements IChatService {
13101309
logChatIndex(): void {
13111310
this._chatSessionStore.logIndex();
13121311
}
1313-
1314-
private shouldSaveToHistory(sessionId: string): boolean {
1315-
// We shouldn't save contributed sessions from content providers
1316-
for (const [_, sessions] of this._contentProviderSessionModels) {
1317-
let session: { readonly model: IChatModel; readonly disposables: DisposableStore } | undefined;
1318-
for (const entry of sessions.values()) {
1319-
if (entry.model.sessionId === sessionId) {
1320-
session = entry;
1321-
break;
1322-
}
1323-
}
1324-
if (session) {
1325-
return false;
1326-
}
1327-
}
1328-
1329-
return true;
1330-
}
13311312
}

src/vs/workbench/contrib/chat/test/common/chatModel.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ suite('ChatModel', () => {
4040
});
4141

4242
test('removeRequest', async () => {
43-
const model = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, ChatAgentLocation.Panel));
43+
const model = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, { initialLocation: ChatAgentLocation.Panel, inputType: '' }));
4444

4545
const text = 'hello';
4646
model.addRequest({ text, parts: [new ChatRequestTextPart(new OffsetRange(0, text.length), new Range(1, text.length, 1, text.length), text)] }, { variables: [] }, 0);
@@ -52,8 +52,8 @@ suite('ChatModel', () => {
5252
});
5353

5454
test('adoptRequest', async function () {
55-
const model1 = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, ChatAgentLocation.Editor));
56-
const model2 = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, ChatAgentLocation.Panel));
55+
const model1 = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, { initialLocation: ChatAgentLocation.Editor }));
56+
const model2 = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, { initialLocation: ChatAgentLocation.Panel, inputType: '' }));
5757

5858
const text = 'hello';
5959
const request1 = model1.addRequest({ text, parts: [new ChatRequestTextPart(new OffsetRange(0, text.length), new Range(1, text.length, 1, text.length), text)] }, { variables: [] }, 0);
@@ -76,7 +76,7 @@ suite('ChatModel', () => {
7676
});
7777

7878
test('addCompleteRequest', async function () {
79-
const model1 = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, ChatAgentLocation.Panel));
79+
const model1 = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, { initialLocation: ChatAgentLocation.Panel, inputType: '' }));
8080

8181
const text = 'hello';
8282
const request1 = model1.addRequest({ text, parts: [new ChatRequestTextPart(new OffsetRange(0, text.length), new Range(1, text.length, 1, text.length), text)] }, { variables: [] }, 0, undefined, undefined, undefined, undefined, undefined, undefined, true);

0 commit comments

Comments
 (0)