Merge pull request #294798 from mjbvz/dev/mjbvz/evident-tarsier

Slight chat session controller optimization
This commit is contained in:
Matt Bierner
2026-02-12 01:20:27 -08:00
committed by GitHub
3 changed files with 52 additions and 36 deletions

View File

@@ -354,13 +354,9 @@ class MainThreadChatSessionItemController extends Disposable implements IChatSes
this._onDidChangeChatSessionItems.fire();
}
updateItem(item: IChatSessionItem): void {
if (this._items.has(item.resource)) {
this._items.set(item.resource, item);
this._onDidChangeChatSessionItems.fire();
} else {
console.warn(`Item with resource ${item.resource.toString()} does not exist. Skipping update.`);
}
addOrUpdateItem(item: IChatSessionItem): void {
this._items.set(item.resource, item);
this._onDidChangeChatSessionItems.fire();
}
fireOnDidChangeChatSessionItems(): void {
@@ -440,8 +436,17 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
));
}
private getController(handle: number): MainThreadChatSessionItemController {
const registration = this._itemControllerRegistrations.get(handle);
if (!registration) {
throw new Error(`No chat session controller registered for handle ${handle}`);
}
return registration.controller;
}
$onDidChangeChatSessionItems(handle: number): void {
this._itemControllerRegistrations.get(handle)?.controller.fireOnDidChangeChatSessionItems();
const controller = this.getController(handle);
controller.fireOnDidChangeChatSessionItems();
}
private async _resolveSessionItem(item: Dto<IChatSessionItem>): Promise<IChatSessionItem> {
@@ -474,31 +479,20 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
};
}
async $setChatSessionItems(handle: number, items: Dto<IChatSessionItem>[]): Promise<void> {
const registration = this._itemControllerRegistrations.get(handle);
if (!registration) {
this._logService.warn(`No chat session controller registered for handle ${handle}`);
return;
}
async $setChatSessionItems(controllerHandle: number, items: Dto<IChatSessionItem>[]): Promise<void> {
const controller = this.getController(controllerHandle);
const resolvedItems = await Promise.all(items.map(item => this._resolveSessionItem(item)));
registration.controller.setItems(resolvedItems);
controller.setItems(resolvedItems);
}
async $updateChatSessionItem(controllerHandle: number, item: Dto<IChatSessionItem>): Promise<void> {
const registration = this._itemControllerRegistrations.get(controllerHandle);
if (!registration) {
this._logService.warn(`No chat session controller registered for handle ${controllerHandle}`);
return;
}
async $addOrUpdateChatSessionItem(controllerHandle: number, item: Dto<IChatSessionItem>): Promise<void> {
const controller = this.getController(controllerHandle);
const resolvedItem = await this._resolveSessionItem(item);
registration.controller.updateItem(resolvedItem);
controller.addOrUpdateItem(resolvedItem);
}
$onDidChangeChatSessionOptions(handle: number, sessionResourceComponents: UriComponents, updates: ReadonlyArray<{ optionId: string; value: string }>): void {
const sessionResource = URI.revive(sessionResourceComponents);
this._chatSessionsService.notifySessionOptionsChange(sessionResource, updates);
}

View File

@@ -3418,7 +3418,7 @@ export interface MainThreadChatSessionsShape extends IDisposable {
$registerChatSessionItemController(handle: number, chatSessionType: string): void;
$unregisterChatSessionItemController(handle: number): void;
$setChatSessionItems(handle: number, items: Dto<IChatSessionItem>[]): Promise<void>;
$updateChatSessionItem(handle: number, item: Dto<IChatSessionItem>): Promise<void>;
$addOrUpdateChatSessionItem(handle: number, item: Dto<IChatSessionItem>): Promise<void>;
$onDidChangeChatSessionItems(handle: number): void;
$onDidCommitChatSessionItem(handle: number, original: UriComponents, modified: UriComponents): void;
$registerChatSessionContentProvider(handle: number, chatSessionScheme: string): void;

View File

@@ -176,12 +176,17 @@ class ChatSessionItemImpl implements vscode.ChatSessionItem {
}
}
interface SessionCollectionListeners {
onItemsChanged(): void;
onItemAddedOrUpdated(item: vscode.ChatSessionItem): void;
}
class ChatSessionItemCollectionImpl implements vscode.ChatSessionItemCollection {
readonly #items = new ResourceMap<vscode.ChatSessionItem>();
#onItemsChanged: () => void;
readonly #callbacks: SessionCollectionListeners;
constructor(onItemsChanged: () => void) {
this.#onItemsChanged = onItemsChanged;
constructor(callbacks: SessionCollectionListeners) {
this.#callbacks = callbacks;
}
get size(): number {
@@ -197,7 +202,7 @@ class ChatSessionItemCollectionImpl implements vscode.ChatSessionItemCollection
for (const item of items) {
this.#items.set(item.resource, item);
}
this.#onItemsChanged();
this.#callbacks.onItemsChanged();
}
forEach(callback: (item: vscode.ChatSessionItem, collection: vscode.ChatSessionItemCollection) => unknown, thisArg?: any): void {
@@ -207,13 +212,20 @@ class ChatSessionItemCollectionImpl implements vscode.ChatSessionItemCollection
}
add(item: vscode.ChatSessionItem): void {
const existing = this.#items.get(item.resource);
if (existing && existing === item) {
// We're adding the same item again
return;
}
this.#items.set(item.resource, item);
this.#onItemsChanged();
this.#callbacks.onItemAddedOrUpdated(item);
}
delete(resource: vscode.Uri): void {
this.#items.delete(resource);
this.#onItemsChanged();
if (this.#items.delete(resource)) {
this.#callbacks.onItemsChanged();
}
}
get(resource: vscode.Uri): vscode.ChatSessionItem | undefined {
@@ -324,8 +336,10 @@ export class ExtHostChatSessions extends Disposable implements ExtHostChatSessio
const onDidChangeChatSessionItemStateEmitter = disposables.add(new Emitter<vscode.ChatSessionItem>());
const collection = new ChatSessionItemCollectionImpl(() => {
const collection = new ChatSessionItemCollectionImpl({
// Noop for providers
onItemsChanged: () => { },
onItemAddedOrUpdated: () => { }
});
// Helper to push items to main thread
@@ -400,7 +414,12 @@ export class ExtHostChatSessions extends Disposable implements ExtHostChatSessio
void this._proxy.$setChatSessionItems(controllerHandle, items);
};
const collection = new ChatSessionItemCollectionImpl(onItemsChanged);
const collection = new ChatSessionItemCollectionImpl({
onItemsChanged,
onItemAddedOrUpdated: (item: vscode.ChatSessionItem) => {
void this._proxy.$addOrUpdateChatSessionItem(controllerHandle, typeConvert.ChatSessionItem.from(item));
}
});
const controller = Object.freeze<vscode.ChatSessionItemController>({
id,
@@ -420,7 +439,10 @@ export class ExtHostChatSessions extends Disposable implements ExtHostChatSessio
}
const item = new ChatSessionItemImpl(resource, label, () => {
void this._proxy.$updateChatSessionItem(controllerHandle, typeConvert.ChatSessionItem.from(item));
// Make sure the item really is in the collection. If not we don't need to transmit it to the main thread yet
if (collection.get(resource) === item) {
void this._proxy.$addOrUpdateChatSessionItem(controllerHandle, typeConvert.ChatSessionItem.from(item));
}
});
return item;
},