mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-15 07:28:05 +00:00
agent sessions - split by "Active" and "History" (#290232)
* agent sessions - split by "Active" and "History" * comments * comments * . * .
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
"github.copilot.chat.claudeCode.enabled": true,
|
||||
"github.copilot.chat.languageContext.typescript.enabled": true,
|
||||
"diffEditor.renderSideBySide": false,
|
||||
"diffEditor.hideUnchangedRegions.enabled": true
|
||||
"diffEditor.hideUnchangedRegions.enabled": true,
|
||||
"chat.viewSessions.showPendingOnly": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, ShowPendingAgentSessionsAction, 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, HideAgentSessionsAction, MarkAgentSessionSectionReadAction, ShowAllAgentSessionsAction, ShowActiveAgentSessionsAction, UnarchiveAgentSessionSectionAction } from './agentSessionsActions.js';
|
||||
import { AgentSessionsQuickAccessProvider, AGENT_SESSIONS_QUICK_ACCESS_PREFIX } from './agentSessionsQuickAccess.js';
|
||||
import { AuxiliaryBarMaximizedContext } from '../../../../common/contextkeys.js';
|
||||
|
||||
@@ -44,7 +44,7 @@ registerAction2(ShowAgentSessionsSidebar);
|
||||
registerAction2(HideAgentSessionsSidebar);
|
||||
registerAction2(ToggleAgentSessionsSidebar);
|
||||
registerAction2(ShowAllAgentSessionsAction);
|
||||
registerAction2(ShowPendingAgentSessionsAction);
|
||||
registerAction2(ShowActiveAgentSessionsAction);
|
||||
registerAction2(HideAgentSessionsAction);
|
||||
registerAction2(SetAgentSessionsOrientationStackedAction);
|
||||
registerAction2(SetAgentSessionsOrientationSideBySideAction);
|
||||
|
||||
@@ -55,7 +55,15 @@ export class ShowAllAgentSessionsAction extends Action2 {
|
||||
title: localize2('chat.showSessions.all', "All"),
|
||||
toggled: ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsEnabled}`, true),
|
||||
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsShowPendingOnly}`, false)
|
||||
ContextKeyExpr.or(
|
||||
// Stacked: based on setting
|
||||
ContextKeyExpr.and(
|
||||
ChatContextKeys.agentSessionsViewerOrientation.isEqualTo(AgentSessionsViewerOrientation.Stacked),
|
||||
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsShowActiveOnly}`, false)
|
||||
),
|
||||
// Side by side: always checked (active not applicable)
|
||||
ChatContextKeys.agentSessionsViewerOrientation.isEqualTo(AgentSessionsViewerOrientation.SideBySide)
|
||||
)
|
||||
),
|
||||
menu: {
|
||||
id: showSessionsSubmenu,
|
||||
@@ -69,24 +77,25 @@ export class ShowAllAgentSessionsAction extends Action2 {
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
|
||||
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsEnabled, true);
|
||||
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsShowPendingOnly, false);
|
||||
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsShowActiveOnly, false);
|
||||
}
|
||||
}
|
||||
|
||||
export class ShowPendingAgentSessionsAction extends Action2 {
|
||||
export class ShowActiveAgentSessionsAction extends Action2 {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.action.chat.showPendingAgentSessions',
|
||||
title: localize2('chat.showSessions.pending', "Pending"),
|
||||
id: 'workbench.action.chat.showActiveAgentSessions',
|
||||
title: localize2('chat.showSessions.active', "Active"),
|
||||
toggled: ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsEnabled}`, true),
|
||||
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsShowPendingOnly}`, true)
|
||||
ContextKeyExpr.equals(`config.${ChatConfiguration.ChatViewSessionsShowActiveOnly}`, true)
|
||||
),
|
||||
menu: {
|
||||
id: showSessionsSubmenu,
|
||||
group: 'navigation',
|
||||
order: 2
|
||||
order: 2,
|
||||
when: ChatContextKeys.agentSessionsViewerOrientation.isEqualTo(AgentSessionsViewerOrientation.Stacked) // side-by-side does not support this mode
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -95,7 +104,7 @@ export class ShowPendingAgentSessionsAction extends Action2 {
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
|
||||
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsEnabled, true);
|
||||
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsShowPendingOnly, true);
|
||||
await configurationService.updateValue(ChatConfiguration.ChatViewSessionsShowActiveOnly, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +280,7 @@ export class ArchiveAgentSessionSectionAction extends Action2 {
|
||||
order: 1,
|
||||
when: ContextKeyExpr.and(
|
||||
ChatContextKeys.agentSessionSection.notEqualsTo(AgentSessionSection.Archived),
|
||||
ChatContextKeys.agentSessionSection.notEqualsTo(AgentSessionSection.Done)
|
||||
ChatContextKeys.agentSessionSection.notEqualsTo(AgentSessionSection.History)
|
||||
),
|
||||
}, {
|
||||
id: MenuId.AgentSessionSectionContext,
|
||||
@@ -279,7 +288,7 @@ export class ArchiveAgentSessionSectionAction extends Action2 {
|
||||
order: 2,
|
||||
when: ContextKeyExpr.and(
|
||||
ChatContextKeys.agentSessionSection.notEqualsTo(AgentSessionSection.Archived),
|
||||
ChatContextKeys.agentSessionSection.notEqualsTo(AgentSessionSection.Done)
|
||||
ChatContextKeys.agentSessionSection.notEqualsTo(AgentSessionSection.History)
|
||||
),
|
||||
}]
|
||||
});
|
||||
|
||||
@@ -133,8 +133,8 @@ export class AgentSessionsControl extends Disposable implements IAgentSessionsCo
|
||||
|
||||
const collapseByDefault = (element: unknown) => {
|
||||
if (isAgentSessionSection(element)) {
|
||||
if (element.section === AgentSessionSection.Done) {
|
||||
return true; // Done section is always collapsed
|
||||
if (element.section === AgentSessionSection.History) {
|
||||
return true; // History section is always collapsed
|
||||
}
|
||||
if (element.section === AgentSessionSection.Archived && this.options.filter.getExcludes().archived) {
|
||||
return true; // Archived section is collapsed when archived are excluded
|
||||
@@ -324,12 +324,12 @@ export class AgentSessionsControl extends Disposable implements IAgentSessionsCo
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AgentSessionSection.Done: {
|
||||
const shouldCollapseDone = !this.sessionsListFindIsOpen; // always expand when find is open
|
||||
case AgentSessionSection.History: {
|
||||
const shouldCollapseHistory = !this.sessionsListFindIsOpen; // always expand when find is open
|
||||
|
||||
if (shouldCollapseDone && !child.collapsed) {
|
||||
if (shouldCollapseHistory && !child.collapsed) {
|
||||
this.sessionsList.collapse(child.element);
|
||||
} else if (!shouldCollapseDone && child.collapsed) {
|
||||
} else if (!shouldCollapseHistory && child.collapsed) {
|
||||
this.sessionsList.expand(child.element);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -17,7 +17,7 @@ import { IAgentSessionsFilter, IAgentSessionsFilterExcludes } from './agentSessi
|
||||
|
||||
export enum AgentSessionsGrouping {
|
||||
Default = 'default',
|
||||
Pending = 'pending',
|
||||
Active = 'active',
|
||||
}
|
||||
|
||||
export interface IAgentSessionsFilterOptions extends Partial<IAgentSessionsFilter> {
|
||||
|
||||
@@ -155,9 +155,9 @@ export const enum AgentSessionSection {
|
||||
Older = 'older',
|
||||
Archived = 'archived',
|
||||
|
||||
// Pending/Done Grouping
|
||||
Pending = 'pending',
|
||||
Done = 'done',
|
||||
// Active/History Grouping
|
||||
Active = 'active',
|
||||
History = 'history',
|
||||
}
|
||||
|
||||
export interface IAgentSessionSection {
|
||||
|
||||
@@ -655,8 +655,8 @@ export class AgentSessionsDataSource implements IAsyncDataSource<IAgentSessionsM
|
||||
const result: AgentSessionListItem[] = [];
|
||||
|
||||
const sortedSessions = sessions.sort(this.sorter.compare.bind(this.sorter));
|
||||
const groupedSessions = this.filter?.groupResults?.() === AgentSessionsGrouping.Pending
|
||||
? groupAgentSessionsByPending(sortedSessions)
|
||||
const groupedSessions = this.filter?.groupResults?.() === AgentSessionsGrouping.Active
|
||||
? groupAgentSessionsByActive(sortedSessions)
|
||||
: groupAgentSessionsByDefault(sortedSessions);
|
||||
|
||||
for (const { sessions, section, label } of groupedSessions.values()) {
|
||||
@@ -673,7 +673,6 @@ export class AgentSessionsDataSource implements IAsyncDataSource<IAgentSessionsM
|
||||
|
||||
const DAY_THRESHOLD = 24 * 60 * 60 * 1000;
|
||||
const WEEK_THRESHOLD = 7 * DAY_THRESHOLD;
|
||||
export const WINDOW_SESSION_START_TIME = Date.now();
|
||||
|
||||
export const AgentSessionSectionLabels = {
|
||||
[AgentSessionSection.InProgress]: localize('agentSessions.inProgressSection', "In Progress"),
|
||||
@@ -682,8 +681,8 @@ export const AgentSessionSectionLabels = {
|
||||
[AgentSessionSection.Week]: localize('agentSessions.weekSection', "Last Week"),
|
||||
[AgentSessionSection.Older]: localize('agentSessions.olderSection', "Older"),
|
||||
[AgentSessionSection.Archived]: localize('agentSessions.archivedSection', "Archived"),
|
||||
[AgentSessionSection.Pending]: localize('agentSessions.pendingSection', "Pending"),
|
||||
[AgentSessionSection.Done]: localize('agentSessions.doneSection', "Done"),
|
||||
[AgentSessionSection.Active]: localize('agentSessions.activeSection', "Active"),
|
||||
[AgentSessionSection.History]: localize('agentSessions.historySection', "History"),
|
||||
};
|
||||
|
||||
export function groupAgentSessionsByDefault(sessions: IAgentSession[]): Map<AgentSessionSection, IAgentSessionSection> {
|
||||
@@ -728,9 +727,9 @@ export function groupAgentSessionsByDefault(sessions: IAgentSession[]): Map<Agen
|
||||
]);
|
||||
}
|
||||
|
||||
export function groupAgentSessionsByPending(sessions: IAgentSession[]): Map<AgentSessionSection, IAgentSessionSection> {
|
||||
const pendingSessions = new Set<IAgentSession>();
|
||||
const doneSessions = new Set<IAgentSession>();
|
||||
export function groupAgentSessionsByActive(sessions: IAgentSession[]): Map<AgentSessionSection, IAgentSessionSection> {
|
||||
const activeSessions = new Set<IAgentSession>();
|
||||
const historySessions = new Set<IAgentSession>();
|
||||
|
||||
const now = Date.now();
|
||||
const startOfToday = new Date(now).setHours(0, 0, 0, 0);
|
||||
@@ -744,17 +743,17 @@ export function groupAgentSessionsByPending(sessions: IAgentSession[]): Map<Agen
|
||||
}
|
||||
|
||||
if (session.isArchived()) {
|
||||
doneSessions.add(session);
|
||||
historySessions.add(session);
|
||||
} else {
|
||||
if (
|
||||
isSessionInProgressStatus(session.status) || // in-progress
|
||||
!session.isRead() || // unread
|
||||
(getAgentChangesSummary(session.changes) && hasValidDiff(session.changes)) || // has changes
|
||||
sessionTime >= WINDOW_SESSION_START_TIME // newer than this window session
|
||||
sessionTime >= startOfYesterday // from today or yesterday
|
||||
) {
|
||||
pendingSessions.add(session);
|
||||
activeSessions.add(session);
|
||||
} else {
|
||||
doneSessions.add(session);
|
||||
historySessions.add(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -764,15 +763,15 @@ export function groupAgentSessionsByPending(sessions: IAgentSession[]): Map<Agen
|
||||
if (
|
||||
mostRecentSession && !mostRecentSession.session.isArchived() &&
|
||||
mostRecentSession.time >= startOfYesterday &&
|
||||
!pendingSessions.has(mostRecentSession.session)
|
||||
!activeSessions.has(mostRecentSession.session)
|
||||
) {
|
||||
doneSessions.delete(mostRecentSession.session);
|
||||
pendingSessions.add(mostRecentSession.session);
|
||||
historySessions.delete(mostRecentSession.session);
|
||||
activeSessions.add(mostRecentSession.session);
|
||||
}
|
||||
|
||||
return new Map<AgentSessionSection, IAgentSessionSection>([
|
||||
[AgentSessionSection.Pending, { section: AgentSessionSection.Pending, label: AgentSessionSectionLabels[AgentSessionSection.Pending], sessions: [...pendingSessions] }],
|
||||
[AgentSessionSection.Done, { section: AgentSessionSection.Done, label: localize('agentSessions.doneSectionWithCount', "Done ({0})", doneSessions.size), sessions: [...doneSessions] }],
|
||||
[AgentSessionSection.Active, { section: AgentSessionSection.Active, label: AgentSessionSectionLabels[AgentSessionSection.Active], sessions: [...activeSessions] }],
|
||||
[AgentSessionSection.History, { section: AgentSessionSection.History, label: localize('agentSessions.historySectionWithCount', "History ({0})", historySessions.size), sessions: [...historySessions] }],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -412,10 +412,10 @@ 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.ChatViewSessionsShowPendingOnly]: {
|
||||
[ChatConfiguration.ChatViewSessionsShowActiveOnly]: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
markdownDescription: nls.localize('chat.viewSessions.showPendingOnly', "When enabled, only show pending sessions in the stacked sessions view. When disabled, show all sessions. This setting requires {0} to be enabled.", '`#chat.viewSessions.enabled#`'),
|
||||
markdownDescription: nls.localize('chat.viewSessions.showActiveOnly', "When enabled, only show active sessions in the stacked sessions view. When disabled, show all sessions. This setting requires {0} to be enabled.", '`#chat.viewSessions.enabled#`'),
|
||||
},
|
||||
[ChatConfiguration.ChatViewSessionsOrientation]: {
|
||||
type: 'string',
|
||||
|
||||
@@ -129,7 +129,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
|
||||
) {
|
||||
this.viewState.sessionId = undefined; // clear persisted session on fresh start
|
||||
}
|
||||
this.sessionsViewerShowPendingOnly = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowPendingOnly) ?? true;
|
||||
this.sessionsViewerShowActiveOnly = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowActiveOnly) ?? true;
|
||||
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);
|
||||
|
||||
@@ -234,18 +234,18 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
|
||||
return e.affectsConfiguration(LayoutSettings.ACTIVITY_BAR_LOCATION);
|
||||
})(() => this.updateViewPaneClasses(true)));
|
||||
|
||||
// Sessions viewer show pending only setting changes
|
||||
// Sessions viewer show active only setting changes
|
||||
this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => {
|
||||
return e.affectsConfiguration(ChatConfiguration.ChatViewSessionsShowPendingOnly);
|
||||
return e.affectsConfiguration(ChatConfiguration.ChatViewSessionsShowActiveOnly);
|
||||
})(() => {
|
||||
const oldSessionsViewerShowPendingOnly = this.sessionsViewerShowPendingOnly;
|
||||
const oldSessionsViewerShowActiveOnly = this.sessionsViewerShowActiveOnly;
|
||||
if (this.sessionsViewerOrientation === AgentSessionsViewerOrientation.SideBySide) {
|
||||
this.sessionsViewerShowPendingOnly = false; // side by side always shows all
|
||||
this.sessionsViewerShowActiveOnly = false; // side by side always shows all
|
||||
} else {
|
||||
this.sessionsViewerShowPendingOnly = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowPendingOnly) ?? true;
|
||||
this.sessionsViewerShowActiveOnly = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowActiveOnly) ?? true;
|
||||
}
|
||||
|
||||
if (oldSessionsViewerShowPendingOnly !== this.sessionsViewerShowPendingOnly) {
|
||||
if (oldSessionsViewerShowActiveOnly !== this.sessionsViewerShowActiveOnly) {
|
||||
this.sessionsControl?.update();
|
||||
}
|
||||
}));
|
||||
@@ -342,7 +342,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
|
||||
private sessionsNewButtonContainer: HTMLElement | undefined;
|
||||
private sessionsControlContainer: HTMLElement | undefined;
|
||||
private sessionsControl: AgentSessionsControl | undefined;
|
||||
private sessionsViewerShowPendingOnly: boolean;
|
||||
private sessionsViewerShowActiveOnly: boolean;
|
||||
private sessionsViewerVisible: boolean;
|
||||
private sessionsViewerOrientation = AgentSessionsViewerOrientation.Stacked;
|
||||
private sessionsViewerOrientationConfiguration: 'stacked' | 'sideBySide' = 'sideBySide';
|
||||
@@ -374,7 +374,7 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
|
||||
// Sessions Filter
|
||||
const sessionsFilter = this._register(this.instantiationService.createInstance(AgentSessionsFilter, {
|
||||
filterMenuId: MenuId.AgentSessionsViewerFilterSubMenu,
|
||||
groupResults: () => this.sessionsViewerShowPendingOnly ? AgentSessionsGrouping.Pending : AgentSessionsGrouping.Default,
|
||||
groupResults: () => this.sessionsViewerShowActiveOnly ? AgentSessionsGrouping.Active : AgentSessionsGrouping.Default,
|
||||
}));
|
||||
this._register(Event.runAndSubscribe(sessionsFilter.onDidChange, () => {
|
||||
sessionsToolbarContainer.classList.toggle('filtered', !sessionsFilter.isDefault());
|
||||
@@ -861,12 +861,12 @@ export class ChatViewPane extends ViewPane implements IViewWelcomeDelegate {
|
||||
this.sessionsViewerOrientationContext.set(AgentSessionsViewerOrientation.Stacked);
|
||||
}
|
||||
|
||||
// Update show pending only state based on orientation change
|
||||
// Update show active only state based on orientation change
|
||||
if (oldSessionsViewerOrientation !== this.sessionsViewerOrientation) {
|
||||
if (this.sessionsViewerOrientation === AgentSessionsViewerOrientation.SideBySide) {
|
||||
this.sessionsViewerShowPendingOnly = false; // side by side always shows all
|
||||
this.sessionsViewerShowActiveOnly = false; // side by side always shows all
|
||||
} else {
|
||||
this.sessionsViewerShowPendingOnly = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowPendingOnly) ?? true;
|
||||
this.sessionsViewerShowActiveOnly = this.configurationService.getValue<boolean>(ChatConfiguration.ChatViewSessionsShowActiveOnly) ?? true;
|
||||
}
|
||||
|
||||
const updatePromise = this.sessionsControl.update();
|
||||
|
||||
@@ -34,7 +34,7 @@ export enum ChatConfiguration {
|
||||
TodosShowWidget = 'chat.tools.todos.showWidget',
|
||||
NotifyWindowOnResponseReceived = 'chat.notifyWindowOnResponseReceived',
|
||||
ChatViewSessionsEnabled = 'chat.viewSessions.enabled',
|
||||
ChatViewSessionsShowPendingOnly = 'chat.viewSessions.showPendingOnly',
|
||||
ChatViewSessionsShowActiveOnly = 'chat.viewSessions.showActiveOnly',
|
||||
ChatViewSessionsOrientation = 'chat.viewSessions.orientation',
|
||||
ChatViewTitleEnabled = 'chat.viewTitle.enabled',
|
||||
SubagentToolCustomAgents = 'chat.customAgentInSubagent.enabled',
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import assert from 'assert';
|
||||
import { URI } from '../../../../../../base/common/uri.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../../base/test/common/utils.js';
|
||||
import { AgentSessionsDataSource, AgentSessionListItem, groupAgentSessionsByPending, IAgentSessionsFilter, WINDOW_SESSION_START_TIME } from '../../../browser/agentSessions/agentSessionsViewer.js';
|
||||
import { AgentSessionsDataSource, AgentSessionListItem, groupAgentSessionsByActive, IAgentSessionsFilter } from '../../../browser/agentSessions/agentSessionsViewer.js';
|
||||
import { AgentSessionSection, IAgentSession, IAgentSessionSection, IAgentSessionsModel, isAgentSessionSection } from '../../../browser/agentSessions/agentSessionsModel.js';
|
||||
import { ChatSessionStatus, isSessionInProgressStatus } from '../../../common/chatSessionsService.js';
|
||||
import { ITreeSorter } from '../../../../../../base/browser/ui/tree/tree.js';
|
||||
@@ -379,30 +379,30 @@ suite('AgentSessionsDataSource', () => {
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: now - ONE_DAY }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
|
||||
assert.strictEqual(result.size, 2);
|
||||
assert.ok(result.has(AgentSessionSection.Pending));
|
||||
assert.ok(result.has(AgentSessionSection.Done));
|
||||
assert.ok(result.has(AgentSessionSection.Active));
|
||||
assert.ok(result.has(AgentSessionSection.History));
|
||||
});
|
||||
|
||||
test('In-progress sessions appear in Pending', () => {
|
||||
// Use session times before WINDOW_SESSION_START_TIME to isolate the in-progress logic
|
||||
const beforeWindowSession = WINDOW_SESSION_START_TIME - ONE_DAY;
|
||||
// Use session times before start of yesterday to isolate the in-progress logic
|
||||
const beforeYesterday = Date.now() - 2 * ONE_DAY;
|
||||
const sessions = [
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.InProgress, startTime: beforeWindowSession }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.NeedsInput, startTime: beforeWindowSession - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 2000 }),
|
||||
createMockSession({ id: '4', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - ONE_DAY }),
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.InProgress, startTime: beforeYesterday }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.NeedsInput, startTime: beforeYesterday - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeYesterday - 2000 }),
|
||||
createMockSession({ id: '4', status: ChatSessionStatus.Completed, startTime: beforeYesterday - ONE_DAY }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Pending);
|
||||
const doneSection = result.get(AgentSessionSection.Done);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Active);
|
||||
const doneSection = result.get(AgentSessionSection.History);
|
||||
|
||||
assert.ok(pendingSection);
|
||||
assert.ok(doneSection);
|
||||
// In-progress sessions in Pending, plus session 1 is also the most recent non-archived
|
||||
// In-progress sessions in Pending
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 1'));
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 2'));
|
||||
assert.strictEqual(pendingSection.sessions.length, 2);
|
||||
@@ -412,93 +412,101 @@ suite('AgentSessionsDataSource', () => {
|
||||
});
|
||||
|
||||
test('Unread sessions appear in Pending', () => {
|
||||
// Use session times before WINDOW_SESSION_START_TIME to isolate the unread logic
|
||||
const beforeWindowSession = WINDOW_SESSION_START_TIME - ONE_DAY;
|
||||
// Use session times before start of yesterday to isolate the unread logic
|
||||
const beforeYesterday = Date.now() - 2 * ONE_DAY;
|
||||
const sessions = [
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: beforeWindowSession, isRead: false }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 2000 }),
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: beforeYesterday, isRead: false }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeYesterday - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeYesterday - 2000 }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Pending);
|
||||
const doneSection = result.get(AgentSessionSection.Done);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Active);
|
||||
const doneSection = result.get(AgentSessionSection.History);
|
||||
|
||||
assert.ok(pendingSection);
|
||||
assert.ok(doneSection);
|
||||
// Unread session 1 is in Pending (also most recent)
|
||||
// Unread session 1 is in Pending
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 1'));
|
||||
// Read sessions 2, 3 are in Done (session 2 not most recent since session 1 is)
|
||||
assert.strictEqual(pendingSection.sessions.length, 1);
|
||||
// Read sessions 2, 3 are in Done
|
||||
assert.ok(doneSection.sessions.some(s => s.label === 'Session 2'));
|
||||
assert.ok(doneSection.sessions.some(s => s.label === 'Session 3'));
|
||||
});
|
||||
|
||||
test('Sessions with changes appear in Pending', () => {
|
||||
// Use session times before WINDOW_SESSION_START_TIME to isolate the changes logic
|
||||
const beforeWindowSession = WINDOW_SESSION_START_TIME - ONE_DAY;
|
||||
// Use session times before start of yesterday to isolate the changes logic
|
||||
const beforeYesterday = Date.now() - 2 * ONE_DAY;
|
||||
const sessions = [
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: beforeWindowSession, hasChanges: true }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 2000, hasChanges: true }),
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: beforeYesterday, hasChanges: true }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeYesterday - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeYesterday - 2000, hasChanges: true }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Pending);
|
||||
const doneSection = result.get(AgentSessionSection.Done);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Active);
|
||||
const doneSection = result.get(AgentSessionSection.History);
|
||||
|
||||
assert.ok(pendingSection);
|
||||
assert.ok(doneSection);
|
||||
// Sessions with changes in Pending
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 1'));
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 3'));
|
||||
assert.strictEqual(pendingSection.sessions.length, 2);
|
||||
// Session 2 is in Done (no changes, read)
|
||||
assert.ok(doneSection.sessions.some(s => s.label === 'Session 2'));
|
||||
});
|
||||
|
||||
test('Most recent non-archived session always appears in Pending', () => {
|
||||
// Use session times clearly before WINDOW_SESSION_START_TIME to test only the "most recent" logic
|
||||
const beforeWindowSession = WINDOW_SESSION_START_TIME - ONE_DAY;
|
||||
test('Most recent non-archived session from today or yesterday appears in Pending', () => {
|
||||
// Use session times from yesterday to test the "most recent from today/yesterday" logic
|
||||
const yesterday = Date.now() - ONE_DAY;
|
||||
const beforeYesterday = Date.now() - 2 * ONE_DAY;
|
||||
const sessions = [
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: beforeWindowSession }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 2000 }),
|
||||
// Session from yesterday - should be in Pending as most recent from today/yesterday
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: yesterday }),
|
||||
// Sessions from before yesterday - should be in Done
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeYesterday }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeYesterday - 1000 }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Pending);
|
||||
const doneSection = result.get(AgentSessionSection.Done);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Active);
|
||||
const doneSection = result.get(AgentSessionSection.History);
|
||||
|
||||
assert.ok(pendingSection);
|
||||
assert.ok(doneSection);
|
||||
// Most recent non-archived (session 1) in Pending
|
||||
// Session from yesterday (session 1) in Pending
|
||||
assert.strictEqual(pendingSection.sessions.length, 1);
|
||||
assert.strictEqual(pendingSection.sessions[0].label, 'Session 1');
|
||||
// Other sessions in Done
|
||||
// Sessions from before yesterday in Done
|
||||
assert.strictEqual(doneSection.sessions.length, 2);
|
||||
});
|
||||
|
||||
test('Sessions created during current window session appear in Pending', () => {
|
||||
test('Sessions from today or yesterday appear in Pending', () => {
|
||||
const now = Date.now();
|
||||
const beforeWindowSession = WINDOW_SESSION_START_TIME - ONE_DAY;
|
||||
const yesterday = Date.now() - ONE_DAY;
|
||||
const beforeYesterday = Date.now() - 2 * ONE_DAY;
|
||||
const sessions = [
|
||||
// Session created during current window session should be in Pending
|
||||
// Sessions from today and yesterday should be in Pending
|
||||
createMockSession({ id: '1', status: ChatSessionStatus.Completed, startTime: now }),
|
||||
// Session created before window session should be in Done
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 1000 }),
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeWindowSession - 2000 }),
|
||||
createMockSession({ id: '2', status: ChatSessionStatus.Completed, startTime: yesterday }),
|
||||
// Sessions from before yesterday should be in Done
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: beforeYesterday }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Pending);
|
||||
const doneSection = result.get(AgentSessionSection.Done);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Active);
|
||||
const doneSection = result.get(AgentSessionSection.History);
|
||||
|
||||
assert.ok(pendingSection);
|
||||
assert.ok(doneSection);
|
||||
// Session 1 created during window session should be in Pending
|
||||
// Sessions from today and yesterday should be in Pending
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 1'));
|
||||
// Sessions 2 and 3 created before window session should be in Done
|
||||
// (Session 2 is also made pending by "most recent from today/yesterday" logic)
|
||||
assert.ok(pendingSection.sessions.some(s => s.label === 'Session 2'));
|
||||
assert.strictEqual(pendingSection.sessions.length, 2);
|
||||
// Sessions from before yesterday should be in Done
|
||||
assert.ok(doneSection.sessions.some(s => s.label === 'Session 3'));
|
||||
assert.strictEqual(doneSection.sessions.length, 1);
|
||||
});
|
||||
|
||||
test('Archived sessions go to Done even if unread or have changes', () => {
|
||||
@@ -509,9 +517,9 @@ suite('AgentSessionsDataSource', () => {
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: now - 2000, isArchived: true, hasChanges: true }),
|
||||
];
|
||||
|
||||
const result = groupAgentSessionsByPending(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Pending);
|
||||
const doneSection = result.get(AgentSessionSection.Done);
|
||||
const result = groupAgentSessionsByActive(sessions);
|
||||
const pendingSection = result.get(AgentSessionSection.Active);
|
||||
const doneSection = result.get(AgentSessionSection.History);
|
||||
|
||||
assert.ok(pendingSection);
|
||||
assert.ok(doneSection);
|
||||
@@ -532,7 +540,7 @@ suite('AgentSessionsDataSource', () => {
|
||||
createMockSession({ id: '3', status: ChatSessionStatus.Completed, startTime: now - 2 * ONE_DAY }),
|
||||
];
|
||||
|
||||
const filter = createMockFilter({ groupBy: AgentSessionsGrouping.Pending });
|
||||
const filter = createMockFilter({ groupBy: AgentSessionsGrouping.Active });
|
||||
const sorter = createMockSorter();
|
||||
const dataSource = new AgentSessionsDataSource(filter, sorter);
|
||||
|
||||
@@ -542,8 +550,8 @@ suite('AgentSessionsDataSource', () => {
|
||||
assert.strictEqual(result.length, 2);
|
||||
assert.ok(isAgentSessionSection(result[0]));
|
||||
assert.ok(isAgentSessionSection(result[1]));
|
||||
assert.strictEqual((result[0] as IAgentSessionSection).section, AgentSessionSection.Pending);
|
||||
assert.strictEqual((result[1] as IAgentSessionSection).section, AgentSessionSection.Done);
|
||||
assert.strictEqual((result[0] as IAgentSessionSection).section, AgentSessionSection.Active);
|
||||
assert.strictEqual((result[1] as IAgentSessionSection).section, AgentSessionSection.History);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user