mcp: fix resource templates trying to resolve twice (#280629)

Also some other minor bugs:
- Picker was not busy while the server was starting
- Old completion items could be shown when working quickly (or on slow plane wifi)
This commit is contained in:
Connor Peet
2025-12-02 09:17:06 -08:00
committed by GitHub
parent f6949883f5
commit a4c38488fe

View File

@@ -32,7 +32,7 @@ import { ChatContextPickAttachment } from '../../chat/browser/chatContextPickSer
import { asArray } from '../../../../base/common/arrays.js';
export class McpResourcePickHelper extends Disposable {
private _resources = observableValue<{ picks: Map<IMcpServer, (IMcpResourceTemplate | IMcpResource)[]>; isBusy: boolean }>(this, { picks: new Map(), isBusy: false });
private _resources = observableValue<{ picks: Map<IMcpServer, (IMcpResourceTemplate | IMcpResource)[]>; isBusy: boolean }>(this, { picks: new Map(), isBusy: true });
private _pickItemsStack: LinkedList<{ server: IMcpServer; resources: (IMcpResource | IMcpResourceTemplate)[] }> = new LinkedList();
private _inDirectory = observableValue<undefined | { server: IMcpServer; resources: (IMcpResource | IMcpResourceTemplate)[] }>(this, undefined);
public static sep(server: IMcpServer): IQuickPickSeparator {
@@ -125,10 +125,11 @@ export class McpResourcePickHelper extends Disposable {
* When returning true, statefully updates the picker state to display directory contents.
*/
public async navigate(resource: IMcpResource | IMcpResourceTemplate, server: IMcpServer): Promise<boolean> {
const uri = await this.toURI(resource);
if (!uri) {
if (isMcpResourceTemplate(resource)) {
return false;
}
const uri = resource.uri;
let stat: IFileStat | undefined = undefined;
try {
stat = await this._fileService.resolve(uri, { resolveMetadata: false });
@@ -297,7 +298,9 @@ export class McpResourcePickHelper extends Disposable {
input.items = items;
};
let changeCancellation = store.add(new CancellationTokenSource());
let changeCancellation = new CancellationTokenSource();
store.add(toDisposable(() => changeCancellation.dispose(true)));
const getCompletionItems = () => {
const inputValue = input.value;
let promise = completions.get(inputValue);
@@ -337,8 +340,7 @@ export class McpResourcePickHelper extends Disposable {
store.add(input.onDidChangeValue(value => {
input.busy = true;
changeCancellation.dispose(true);
store.delete(changeCancellation);
changeCancellation = store.add(new CancellationTokenSource());
changeCancellation = new CancellationTokenSource();
getCompletionItemsScheduler.cancel();
setItems(value);