Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 10 additions & 6 deletions src/vs/platform/agentHost/node/agentHostStateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,16 @@ export class AgentHostStateManager extends Disposable {
const entry = this._sessionStates.get(session);
return entry ? this._toSummary(session, entry) : undefined;
},
(session, changes) => this._onDidEmitNotification.fire({
type: 'root/sessionSummaryChanged',
channel: ROOT_STATE_URI,
session,
changes,
}),
(session, changes) => {
if (this._publishedSessionSummaries.has(session)) {
this._onDidEmitNotification.fire({
type: 'root/sessionSummaryChanged',
channel: ROOT_STATE_URI,
session,
changes,
});
}
},
));
}
private readonly _log = (msg: string) => this._logService.warn(`[AgentHostStateManager] ${msg}`);
Expand Down
31 changes: 31 additions & 0 deletions src/vs/platform/agentHost/test/node/agentHostStateManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,37 @@ suite('AgentHostStateManager', () => {
assert.strictEqual(notifications.length, 0, 'should not emit notification for restored sessions');
});

test('restored unpublished sessions retain summary changes without notifying root clients', () => {
return runWithFakedTimers({ useFakeTimers: true }, async () => {
manager.restoreSession(makeSessionSummary(), []);
const notifications: INotification[] = [];
disposables.add(manager.onDidEmitNotification(notification => notifications.push(notification)));

manager.dispatchServerAction(sessionUri, { type: ActionType.SessionTitleChanged, title: 'Hidden Title' });
await new Promise(resolve => setTimeout(resolve, 150));
const hiddenChanges = notifications.filter(notification => notification.type === NotificationType.SessionSummaryChanged);
const retainedTitle = manager.getSessionSummary(sessionUri)?.title;

manager.setSessionSummaryPublished(sessionUri, true);
const added = notifications.find(notification => notification.type === NotificationType.SessionAdded);
manager.dispatchServerAction(sessionUri, { type: ActionType.SessionTitleChanged, title: 'Visible Title' });
await new Promise(resolve => setTimeout(resolve, 150));
const visibleChanges = notifications.filter(notification => notification.type === NotificationType.SessionSummaryChanged) as SessionSummaryChangedParams[];

assert.deepStrictEqual({
hiddenChangeCount: hiddenChanges.length,
retainedTitle,
addedTitle: added?.type === NotificationType.SessionAdded ? added.summary.title : undefined,
visibleChanges: visibleChanges.map(change => change.changes.title),
}, {
hiddenChangeCount: 0,
retainedTitle: 'Hidden Title',
addedTitle: 'Hidden Title',
visibleChanges: ['Visible Title'],
});
});
});

test('restoreSession emits sessionSummaryChanged clearing the adoptable marker for a previously surfaced session', () => {
// A surfaced adoptable-legacy session is announced with the marker; adopting
// it via restoreSession must notify clients the marker was cleared so they
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ The **only** per-provider difference is the storage key: local uses the fixed `l

### External session visibility

Provider-native sessions discovered outside the Agent Host carry `_meta.external`. `chat.agentSessions.showExternal` controls whether the catalog publishes none, all, the last 24 hours, or the last 7 days (the default). Configuration changes publish or unpublish matching summaries immediately, including restored sessions, while retaining live Agent Host state so a later settings change can surface them again. The state manager distinguishes a summary retained as the diff baseline from one actually published through `root/sessionAdded`; restoring a filtered session records the former without implying the latter.
Provider-native sessions discovered outside the Agent Host carry `_meta.external`. `chat.agentSessions.showExternal` controls whether the catalog publishes none, all, the last 24 hours, or the last 7 days (the default). Configuration changes publish or unpublish matching summaries immediately, including restored sessions, while retaining live Agent Host state so a later settings change can surface them again. The state manager distinguishes a summary retained as the diff baseline from one actually published through `root/sessionAdded`; restoring a filtered session records the former without implying the latter, and hidden summary changes advance that baseline without emitting root notifications.

Both the regular VS Code agent sessions list and the Agents Window Sessions list expose this setting as an `External` submenu directly below their provider filters. The checked option follows the effective configuration value, and selecting an option writes the user setting.

Expand Down
Loading