diff --git a/resources/profiles/agent-sessions.code-profile b/resources/profiles/agent-sessions.code-profile index 815ec6a3bcb..dddbce4731f 100644 --- a/resources/profiles/agent-sessions.code-profile +++ b/resources/profiles/agent-sessions.code-profile @@ -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 } } diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.contribution.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.contribution.ts index dea75ac79ba..c46384cfa6a 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.contribution.ts @@ -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); diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts index f578da5d57a..69332b54c77 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsActions.ts @@ -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) ), }] }); diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts index 2951294e88e..94653334478 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts @@ -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; diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts index 53ff681b106..1cc3a238f4a 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts @@ -17,7 +17,7 @@ import { IAgentSessionsFilter, IAgentSessionsFilterExcludes } from './agentSessi export enum AgentSessionsGrouping { Default = 'default', - Pending = 'pending', + Active = 'active', } export interface IAgentSessionsFilterOptions extends Partial { diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts index 19bd713d2df..c1887af81f4 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts @@ -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 { diff --git a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts index 39a5873424b..5177c71603f 100644 --- a/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts +++ b/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts @@ -655,8 +655,8 @@ export class AgentSessionsDataSource implements IAsyncDataSource { @@ -728,9 +727,9 @@ export function groupAgentSessionsByDefault(sessions: IAgentSession[]): Map { - const pendingSessions = new Set(); - const doneSessions = new Set(); +export function groupAgentSessionsByActive(sessions: IAgentSession[]): Map { + const activeSessions = new Set(); + const historySessions = new Set(); const now = Date.now(); const startOfToday = new Date(now).setHours(0, 0, 0, 0); @@ -744,17 +743,17 @@ export function groupAgentSessionsByPending(sessions: IAgentSession[]): Map= 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= 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.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] }], ]); } diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 14b7a21e707..642268a2d75 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -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', diff --git a/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.ts b/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.ts index 1c67d25dd54..a520cc59bdc 100644 --- a/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.ts +++ b/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatViewPane.ts @@ -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(ChatConfiguration.ChatViewSessionsShowPendingOnly) ?? true; + this.sessionsViewerShowActiveOnly = this.configurationService.getValue(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(ChatConfiguration.ChatViewSessionsShowPendingOnly) ?? true; + this.sessionsViewerShowActiveOnly = this.configurationService.getValue(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(ChatConfiguration.ChatViewSessionsShowPendingOnly) ?? true; + this.sessionsViewerShowActiveOnly = this.configurationService.getValue(ChatConfiguration.ChatViewSessionsShowActiveOnly) ?? true; } const updatePromise = this.sessionsControl.update(); diff --git a/src/vs/workbench/contrib/chat/common/constants.ts b/src/vs/workbench/contrib/chat/common/constants.ts index eff0d1c4641..fb071fdd45d 100644 --- a/src/vs/workbench/contrib/chat/common/constants.ts +++ b/src/vs/workbench/contrib/chat/common/constants.ts @@ -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', diff --git a/src/vs/workbench/contrib/chat/test/browser/agentSessions/agentSessionsDataSource.test.ts b/src/vs/workbench/contrib/chat/test/browser/agentSessions/agentSessionsDataSource.test.ts index ae3a95de5da..6f44c148ebf 100644 --- a/src/vs/workbench/contrib/chat/test/browser/agentSessions/agentSessionsDataSource.test.ts +++ b/src/vs/workbench/contrib/chat/test/browser/agentSessions/agentSessionsDataSource.test.ts @@ -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); }); }); });