Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { IAgentSessionsService, AgentSessionsService } from './agentSessionsServ
import { LocalAgentsSessionsProvider } from './localAgentSessionsProvider.js';
import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../../common/contributions.js';
import { ISubmenuItem, MenuId, MenuRegistry, registerAction2 } from '../../../../../platform/actions/common/actions.js';
import { ArchiveAgentSessionAction, ArchiveAgentSessionSectionAction, UnarchiveAgentSessionAction, OpenAgentSessionInEditorGroupAction, OpenAgentSessionInNewEditorGroupAction, OpenAgentSessionInNewWindowAction, ShowAgentSessionsSidebar, HideAgentSessionsSidebar, ToggleAgentSessionsSidebar, RefreshAgentSessionsViewerAction, FindAgentSessionInViewerAction, MarkAgentSessionUnreadAction, MarkAgentSessionReadAction, FocusAgentSessionsAction, SetAgentSessionsOrientationStackedAction, SetAgentSessionsOrientationSideBySideAction, PickAgentSessionAction, ArchiveAllAgentSessionsAction, RenameAgentSessionAction, DeleteAgentSessionAction, DeleteAllLocalSessionsAction, HideAgentSessionsAction, MarkAgentSessionSectionReadAction, ShowAllAgentSessionsAction, ShowRecentAgentSessionsAction, UnarchiveAgentSessionSectionAction } from './agentSessionsActions.js';
import { ArchiveAgentSessionAction, ArchiveAgentSessionSectionAction, UnarchiveAgentSessionAction, OpenAgentSessionInEditorGroupAction, OpenAgentSessionInNewEditorGroupAction, OpenAgentSessionInNewWindowAction, ShowAgentSessionsSidebar, HideAgentSessionsSidebar, ToggleAgentSessionsSidebar, RefreshAgentSessionsViewerAction, FindAgentSessionInViewerAction, MarkAgentSessionUnreadAction, MarkAgentSessionReadAction, FocusAgentSessionsAction, SetAgentSessionsOrientationStackedAction, SetAgentSessionsOrientationSideBySideAction, PickAgentSessionAction, ArchiveAllAgentSessionsAction, RenameAgentSessionAction, DeleteAgentSessionAction, DeleteAllLocalSessionsAction, MarkAgentSessionSectionReadAction, UnarchiveAgentSessionSectionAction, ToggleChatViewSessionsAction } from './agentSessionsActions.js';
import { AgentSessionsQuickAccessProvider, AGENT_SESSIONS_QUICK_ACCESS_PREFIX } from './agentSessionsQuickAccess.js';
import { AuxiliaryBarMaximizedContext } from '../../../../common/contextkeys.js';

Expand All @@ -43,9 +43,7 @@ registerAction2(FindAgentSessionInViewerAction);
registerAction2(ShowAgentSessionsSidebar);
registerAction2(HideAgentSessionsSidebar);
registerAction2(ToggleAgentSessionsSidebar);
registerAction2(ShowAllAgentSessionsAction);
registerAction2(ShowRecentAgentSessionsAction);
registerAction2(HideAgentSessionsAction);
registerAction2(ToggleChatViewSessionsAction);
registerAction2(SetAgentSessionsOrientationStackedAction);
registerAction2(SetAgentSessionsOrientationSideBySideAction);

Expand All @@ -57,7 +55,6 @@ MenuRegistry.appendMenuItem(MenuId.AgentSessionsToolbar, {
group: 'navigation',
order: 3,
icon: Codicon.filter,
when: ChatContextKeys.agentSessionsViewerLimited.negate()
} satisfies ISubmenuItem);

MenuRegistry.appendMenuItem(MenuId.AgentSessionsToolbar, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,86 +38,26 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../../pla

//#region Chat View

const showSessionsSubmenu = new MenuId('chatShowSessionsSubmenu');
MenuRegistry.appendMenuItem(MenuId.ChatWelcomeContext, {
submenu: showSessionsSubmenu,
title: localize2('chat.showSessions', "Show Sessions"),
group: '0_sessions',
order: 1,
when: ChatContextKeys.inChatEditor.negate()
});

export class ShowAllAgentSessionsAction extends Action2 {

export class ToggleChatViewSessionsAction extends Action2 {
constructor() {
super({
id: 'workbench.action.chat.showAllAgentSessions',
title: localize2('chat.showSessions.all', "All"),
toggled: ContextKeyExpr.and(
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsEnabled}`, true),
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsShowRecentOnly}`, false)
),
id: 'workbench.action.chat.toggleChatViewSessions',
title: localize2('chat.toggleChatViewSessions.label', "Show Sessions"),
toggled: ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsEnabled}`, true),
menu: {
id: showSessionsSubmenu,
group: 'navigation',
order: 1
}
});
}

async run(accessor: ServicesAccessor): Promise<void> {
const configurationService = accessor.get(IConfigurationService);

await configurationService.updateValue(ChatConfiguration.ChatViewSessionsEnabled, true);
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsShowRecentOnly, false);
}
}

export class ShowRecentAgentSessionsAction extends Action2 {

constructor() {
super({
id: 'workbench.action.chat.showRecentAgentSessions',
title: localize2('chat.showSessions.recent', "Recent"),
toggled: ContextKeyExpr.and(
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsEnabled}`, true),
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsShowRecentOnly}`, true)
),
menu: {
id: showSessionsSubmenu,
group: 'navigation',
order: 2
}
});
}

async run(accessor: ServicesAccessor): Promise<void> {
const configurationService = accessor.get(IConfigurationService);

await configurationService.updateValue(ChatConfiguration.ChatViewSessionsEnabled, true);
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsShowRecentOnly, true);
}
}

export class HideAgentSessionsAction extends Action2 {

constructor() {
super({
id: 'workbench.action.chat.hideAgentSessions',
title: localize2('chat.showSessions.none', "None"),
toggled: ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsEnabled}`, false),
menu: {
id: showSessionsSubmenu,
group: 'navigation',
order: 3
id: MenuId.ChatWelcomeContext,
group: '0_sessions',
order: 1,
when: ChatContextKeys.inChatEditor.negate()
}
});
}

async run(accessor: ServicesAccessor): Promise<void> {
const configurationService = accessor.get(IConfigurationService);

await configurationService.updateValue(ChatConfiguration.ChatViewSessionsEnabled, false);
const chatViewSessionsEnabled = configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsEnabled);
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsEnabled, !chatViewSessionsEnabled);
}
}

Expand Down Expand Up @@ -845,7 +785,6 @@ export class RefreshAgentSessionsViewerAction extends Action2 {
id: MenuId.AgentSessionsToolbar,
group: 'navigation',
order: 1,
when: ChatContextKeys.agentSessionsViewerLimited.negate()
},
});
}
Expand All @@ -866,7 +805,6 @@ export class FindAgentSessionInViewerAction extends Action2 {
id: MenuId.AgentSessionsToolbar,
group: 'navigation',
order: 2,
when: ChatContextKeys.agentSessionsViewerLimited.negate()
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ export class AgentSessionRenderer extends Disposable implements ICompressibleTre
}

private renderHover(session: ITreeNode<IAgentSession, FuzzyScore>, template: IAgentSessionItemTemplate): void {
if (!isSessionInProgressStatus(session.element.status)) {
return; // the hover is complex and large, for now limit it to in-progress sessions only
}

template.elementDisposable.add(
this.hoverService.setupDelayedHover(template.element, () => this.buildHoverContent(session.element), { groupId: 'agent.sessions' })
);
Expand Down
5 changes: 0 additions & 5 deletions src/vs/workbench/contrib/chat/browser/chat.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,6 @@ configurationRegistry.registerConfiguration({
default: true,
description: nls.localize('chat.viewSessions.enabled', "Show chat agent sessions when chat is empty or to the side when chat view is wide enough."),
},
[ChatConfiguration.ChatViewSessionsShowRecentOnly]: {
type: 'boolean',
default: false,
description: nls.localize('chat.viewSessions.showRecentOnly', "When enabled, only show recent sessions in the stacked sessions view. When disabled, show all sessions."),
},
[ChatConfiguration.ChatViewSessionsOrientation]: {
type: 'string',
enum: ['stacked', 'sideBySide'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,11 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
) {
this.viewState.sessionId = undefined; // clear persisted session on fresh start
}
this.sessionsViewerLimited = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowRecentOnly) ?? false;
this.sessionsViewerVisible = false; // will be updated from layout code
this.sessionsViewerSidebarWidth = Math.max(ChatViewPane.SESSIONS_SIDEBAR_MIN_WIDTH, this.viewState.sessionsSidebarWidth ?? ChatViewPane.SESSIONS_SIDEBAR_DEFAULT_WIDTH);

// Contextkeys
this.chatViewLocationContext = ChatContextKeys.panelLocation.bindTo(contextKeyService);
this.sessionsViewerLimitedContext = ChatContextKeys.agentSessionsViewerLimited.bindTo(contextKeyService);
this.sessionsViewerOrientationContext = ChatContextKeys.agentSessionsViewerOrientation.bindTo(contextKeyService);
this.sessionsViewerPositionContext = ChatContextKeys.agentSessionsViewerPosition.bindTo(contextKeyService);
this.sessionsViewerVisibilityContext = ChatContextKeys.agentSessionsViewerVisible.bindTo(contextKeyService);
Expand All @@ -149,7 +147,6 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
private updateContextKeys(): void {
const { position, location } = this.getViewPositionAndLocation();

this.sessionsViewerLimitedContext.set(this.sessionsViewerLimited);
this.chatViewLocationContext.set(location ?? ViewContainerLocation.AuxiliaryBar);
this.sessionsViewerOrientationContext.set(this.sessionsViewerOrientation);
this.sessionsViewerPositionContext.set(position === Position.RIGHT ? AgentSessionsViewerPosition.Right : AgentSessionsViewerPosition.Left);
Expand Down Expand Up @@ -221,22 +218,6 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
return e.affectsConfiguration(LayoutSettings.ACTIVITY_BAR_LOCATION);
})(() => this.updateViewPaneClasses(true)));

// Sessions viewer limited setting changes
this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => {
return e.affectsConfiguration(ChatConfiguration.ChatViewSessionsShowRecentOnly);
})(() => {
const oldSessionsViewerLimited = this.sessionsViewerLimited;
if (this.sessionsViewerOrientation === AgentSessionsViewerOrientation.SideBySide) {
this.sessionsViewerLimited = false; // side by side always shows all
} else {
this.sessionsViewerLimited = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowRecentOnly) ?? false;
}

if (oldSessionsViewerLimited !== this.sessionsViewerLimited) {
this.notifySessionsControlLimitedChanged(true /* layout */, true /* update */);
}
}));

// Entitlement changes
this._register(this.chatEntitlementService.onDidChangeSentiment(() => {
this.updateViewPaneClasses(true);
Expand Down Expand Up @@ -317,7 +298,6 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {

//#region Sessions Control

private static readonly SESSIONS_LIMIT = 5;
private static readonly SESSIONS_SIDEBAR_MIN_WIDTH = 200;
private static readonly SESSIONS_SIDEBAR_DEFAULT_WIDTH = 300;
private static readonly CHAT_WIDGET_DEFAULT_WIDTH = 300;
Expand All @@ -330,12 +310,10 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
private sessionsControlContainer: HTMLElement | undefined;
private sessionsControl: AgentSessionsControl | undefined;
private sessionsCount = 0;
private sessionsViewerLimited: boolean;
private sessionsViewerVisible: boolean;
private sessionsViewerOrientation = AgentSessionsViewerOrientation.Stacked;
private sessionsViewerOrientationConfiguration: 'stacked' | 'sideBySide' = 'sideBySide';
private sessionsViewerOrientationContext: IContextKey<AgentSessionsViewerOrientation>;
private sessionsViewerLimitedContext: IContextKey<boolean>;
private sessionsViewerVisibilityContext: IContextKey<boolean>;
private sessionsViewerPositionContext: IContextKey<AgentSessionsViewerPosition>;
private sessionsViewerSidebarWidth: number;
Expand All @@ -349,7 +327,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
// Sessions Title
const sessionsTitleContainer = this.sessionsTitleContainer = append(sessionsContainer, $('.agent-sessions-title-container'));
const sessionsTitle = this.sessionsTitle = append(sessionsTitleContainer, $('span.agent-sessions-title'));
this.updateSessionsControlTitle();
sessionsTitle.textContent = localize('sessions', "Sessions");
this._register(addDisposableListener(sessionsTitle, EventType.CLICK, () => {
this.sessionsControl?.scrollToTop();
this.sessionsControl?.focus();
Expand All @@ -364,23 +342,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
// Sessions Filter
const sessionsFilter = this._register(this.instantiationService.createInstance(AgentSessionsFilter, {
filterMenuId: MenuId.AgentSessionsViewerFilterSubMenu,
limitResults: () => {
return that.sessionsViewerLimited ? ChatViewPane.SESSIONS_LIMIT : undefined;
},
groupResults: () => {
return !that.sessionsViewerLimited;
},
overrideExclude(session) {
if (that.sessionsViewerLimited) {
if (session.isArchived()) {
return true; // exclude archived sessions when limited
}

return false;
}

return undefined; // leave up to the filter settings
},
groupResults() { return true; },
notifyResults(count: number) {
that.notifySessionsControlCountChanged(count);
},
Expand Down Expand Up @@ -414,23 +376,6 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
}
return openEvent;
},
overrideCompare(sessionA: IAgentSession, sessionB: IAgentSession): number | undefined {

// When limited where only few sessions show, sort unread sessions to the top
if (that.sessionsViewerLimited) {
const aIsUnread = !sessionA.isRead();
const bIsUnread = !sessionB.isRead();

if (aIsUnread && !bIsUnread) {
return -1; // a (unread) comes before b (read)
}
if (!aIsUnread && bIsUnread) {
return 1; // a (read) comes after b (unread)
}
}

return undefined;
}
}));
this._register(this.onDidChangeBodyVisibility(visible => sessionsControl.setVisible(visible)));

Expand Down Expand Up @@ -477,20 +422,6 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
}
}

private notifySessionsControlLimitedChanged(triggerLayout: boolean, triggerUpdate: boolean): Promise<void> {
this.sessionsViewerLimitedContext.set(this.sessionsViewerLimited);

this.updateSessionsControlTitle();

const updatePromise = triggerUpdate ? this.sessionsControl?.update() : undefined;

if (triggerLayout) {
this.relayout();
}

return updatePromise ?? Promise.resolve();
}

private notifySessionsControlCountChanged(newSessionsCount?: number): void {
const countChanged = typeof newSessionsCount === 'number' && newSessionsCount !== this.sessionsCount;
this.sessionsCount = newSessionsCount ?? this.sessionsCount;
Expand All @@ -502,14 +433,6 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
}
}

private updateSessionsControlTitle(): void {
if (!this.sessionsTitle) {
return;
}

this.sessionsTitle.textContent = this.sessionsViewerLimited ? localize('recentSessions', "Recent Sessions") : localize('allSessions', "Sessions");
}

private updateSessionsControlVisibility(): { changed: boolean; visible: boolean } {
if (!this.sessionsContainer || !this.viewPaneContainer) {
return { changed: false, visible: false };
Expand All @@ -523,10 +446,9 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
// Sessions control: stacked
if (this.sessionsViewerOrientation === AgentSessionsViewerOrientation.Stacked) {
newSessionsContainerVisible =
!!this.chatEntitlementService.sentiment.installed && // chat is installed (otherwise make room for terms and welcome)
(!this._widget || this._widget?.isEmpty()) && // chat widget empty
!this.welcomeController?.isShowingWelcome.get() && // welcome not showing
(this.sessionsCount > 0 || !this.sessionsViewerLimited); // has sessions or is showing all sessions
!!this.chatEntitlementService.sentiment.installed && // chat is installed (otherwise make room for terms and welcome)
(!this._widget || this._widget?.isEmpty()) && // chat widget empty
!this.welcomeController?.isShowingWelcome.get(); // welcome not showing
}

// Sessions control: sidebar
Expand Down Expand Up @@ -920,30 +842,15 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
this.sessionsViewerOrientationContext.set(AgentSessionsViewerOrientation.Stacked);
}

// Update limited state based on orientation change
// Update based on orientation change
if (oldSessionsViewerOrientation !== this.sessionsViewerOrientation) {
const oldSessionsViewerLimited = this.sessionsViewerLimited;
if (this.sessionsViewerOrientation === AgentSessionsViewerOrientation.SideBySide) {
this.sessionsViewerLimited = false; // side by side always shows all
} else {
this.sessionsViewerLimited = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowRecentOnly) ?? false;
}

let updatePromise: Promise<void>;
if (oldSessionsViewerLimited !== this.sessionsViewerLimited) {
updatePromise = this.notifySessionsControlLimitedChanged(false /* already in layout */, true /* update */);
} else {
updatePromise = this.sessionsControl?.update(); // still need to update for section visibility
}

// Switching to side-by-side, reveal the current session after elements have loaded
if (this.sessionsViewerOrientation === AgentSessionsViewerOrientation.SideBySide) {
updatePromise.then(() => {
const sessionResource = this._widget?.viewModel?.sessionResource;
if (sessionResource) {
this.sessionsControl?.reveal(sessionResource);
}
});
const sessionResource = this._widget?.viewModel?.sessionResource;
if (sessionResource) {
this.sessionsControl?.reveal(sessionResource);
}
}
}

Expand Down Expand Up @@ -984,14 +891,9 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
widthReduction = this.sessionsContainer.offsetWidth;
}

// Show stacked (grows with the number of items displayed)
// Show stacked
else {
let sessionsHeight: number;
if (this.sessionsViewerLimited) {
sessionsHeight = this.sessionsCount * AgentSessionsListDelegate.ITEM_HEIGHT;
} else {
sessionsHeight = availableSessionsHeight;
}
let sessionsHeight = 5 * AgentSessionsListDelegate.ITEM_HEIGHT;

const borderBottom = 1;
sessionsHeight = Math.min(availableSessionsHeight, sessionsHeight) - borderBottom;
Expand Down
Loading
Loading