Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.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 { renderAsPlaintext } from '../../../../../base/browser/markdownRenderer.js';
7
import { Codicon } from '../../../../../base/common/codicons.js';
8
import { fromNow } from '../../../../../base/common/date.js';
9
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
10
import { ThemeIcon } from '../../../../../base/common/themables.js';
11
import { localize } from '../../../../../nls.js';
12
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
13
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
14
import { IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickPickSeparator } from '../../../../../platform/quickinput/common/quickInput.js';
15
import { openSession } from './agentSessionsOpener.js';
16
import { IAgentSession, isLocalAgentSessionItem } from './agentSessionsModel.js';
17
import { IAgentSessionsService } from './agentSessionsService.js';
18
import { AgentSessionsSorter, groupAgentSessions } from './agentSessionsViewer.js';
19
import { AGENT_SESSION_DELETE_ACTION_ID, AGENT_SESSION_RENAME_ACTION_ID } from './agentSessions.js';
20
21
interface ISessionPickItem extends IQuickPickItem {
22
readonly session: IAgentSession;
23
}
24
25
export const archiveButton: IQuickInputButton = {
26
iconClass: ThemeIcon.asClassName(Codicon.archive),
27
tooltip: localize('archiveSession', "Archive")
28
};
29
30
export const unarchiveButton: IQuickInputButton = {
31
iconClass: ThemeIcon.asClassName(Codicon.inbox),
32
tooltip: localize('unarchiveSession', "Unarchive")
33
};
34
35
export const renameButton: IQuickInputButton = {
36
iconClass: ThemeIcon.asClassName(Codicon.edit),
37
tooltip: localize('renameSession', "Rename")
38
};
39
40
export const deleteButton: IQuickInputButton = {
41
iconClass: ThemeIcon.asClassName(Codicon.trash),
42
tooltip: localize('deleteSession', "Delete")
43
};
44
45
export function getSessionDescription(session: IAgentSession): string {
46
const descriptionText = typeof session.description === 'string' ? session.description : session.description ? renderAsPlaintext(session.description) : undefined;
47
const timeAgo = fromNow(session.timing.endTime || session.timing.startTime);
48
const descriptionParts = [descriptionText, session.providerLabel, timeAgo].filter(part => !!part);
49
50
return descriptionParts.join(' • ');
51
}
52
53
export function getSessionButtons(session: IAgentSession): IQuickInputButton[] {
54
const buttons: IQuickInputButton[] = [];
55
56
if (isLocalAgentSessionItem(session)) {
57
buttons.push(renameButton);
58
buttons.push(deleteButton);
59
}
60
buttons.push(session.isArchived() ? unarchiveButton : archiveButton);
61
62
return buttons;
63
}
64
65
export class AgentSessionsPicker {
66
67
private readonly sorter = new AgentSessionsSorter();
68
69
constructor(
70
@IAgentSessionsService private readonly agentSessionsService: IAgentSessionsService,
71
@IQuickInputService private readonly quickInputService: IQuickInputService,
72
@IInstantiationService private readonly instantiationService: IInstantiationService,
73
@ICommandService private readonly commandService: ICommandService,
74
) { }
75
76
async pickAgentSession(): Promise<void> {
77
const disposables = new DisposableStore();
78
const picker = disposables.add(this.quickInputService.createQuickPick<ISessionPickItem>({ useSeparators: true }));
79
80
picker.items = this.createPickerItems();
81
picker.canAcceptInBackground = true;
82
picker.placeholder = localize('chatAgentPickerPlaceholder', "Search agent sessions by name");
83
84
disposables.add(picker.onDidAccept(e => {
85
const pick = picker.selectedItems[0];
86
if (pick) {
87
this.instantiationService.invokeFunction(openSession, pick.session, {
88
sideBySide: e.inBackground,
89
editorOptions: {
90
preserveFocus: e.inBackground,
91
pinned: e.inBackground
92
}
93
});
94
}
95
96
if (!e.inBackground) {
97
picker.hide();
98
}
99
}));
100
101
disposables.add(picker.onDidTriggerItemButton(async e => {
102
const session = e.item.session;
103
104
let reopenResolved: boolean = false;
105
if (e.button === renameButton) {
106
reopenResolved = true;
107
await this.commandService.executeCommand(AGENT_SESSION_RENAME_ACTION_ID, session);
108
} else if (e.button === deleteButton) {
109
reopenResolved = true;
110
await this.commandService.executeCommand(AGENT_SESSION_DELETE_ACTION_ID, session);
111
} else {
112
const newArchivedState = !session.isArchived();
113
session.setArchived(newArchivedState);
114
}
115
116
if (reopenResolved) {
117
await this.agentSessionsService.model.resolve(session.providerType);
118
this.pickAgentSession();
119
} else {
120
picker.items = this.createPickerItems();
121
}
122
}));
123
124
disposables.add(picker.onDidHide(() => disposables.dispose()));
125
picker.show();
126
}
127
128
private createPickerItems(): (ISessionPickItem | IQuickPickSeparator)[] {
129
const sessions = this.agentSessionsService.model.sessions.sort(this.sorter.compare.bind(this.sorter));
130
const items: (ISessionPickItem | IQuickPickSeparator)[] = [];
131
132
const groupedSessions = groupAgentSessions(sessions);
133
134
for (const group of groupedSessions.values()) {
135
if (group.sessions.length > 0) {
136
items.push({ type: 'separator', label: group.label });
137
items.push(...group.sessions.map(session => this.toPickItem(session)));
138
}
139
}
140
141
return items;
142
}
143
144
private toPickItem(session: IAgentSession): ISessionPickItem {
145
const description = getSessionDescription(session);
146
const buttons = getSessionButtons(session);
147
148
return {
149
id: session.resource.toString(),
150
label: session.label,
151
tooltip: session.tooltip,
152
description,
153
iconClass: ThemeIcon.asClassName(session.icon),
154
buttons,
155
session
156
};
157
}
158
}
159
160