Skip to content

Commit f932a59

Browse files
authored
mcp: add support completions, files, and commands for prompt arguments (microsoft#249673)
* mcp: add support completions, files, and commands for prompt arguments - Support MCP completions for prompts - Support attaching files to prompts - Support attaching terminal command output to prompts - Some general quickpick flow improvements * fix step counting not working with back button
1 parent 7ab0d0a commit f932a59

File tree

4 files changed

+339
-41
lines changed

4 files changed

+339
-41
lines changed

src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ import { Action2, registerAction2 } from '../../../../../platform/actions/common
2828
import { CommandsRegistry } from '../../../../../platform/commands/common/commands.js';
2929
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
3030
import { FileKind, IFileService } from '../../../../../platform/files/common/files.js';
31-
import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
31+
import { IInstantiationService, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
3232
import { ILabelService } from '../../../../../platform/label/common/label.js';
3333
import { INotificationService } from '../../../../../platform/notification/common/notification.js';
34-
import { IQuickInputService } from '../../../../../platform/quickinput/common/quickInput.js';
3534
import { Registry } from '../../../../../platform/registry/common/platform.js';
3635
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js';
3736
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from '../../../../common/contributions.js';
@@ -40,6 +39,7 @@ import { IEditorService } from '../../../../services/editor/common/editorService
4039
import { IHistoryService } from '../../../../services/history/common/history.js';
4140
import { LifecyclePhase } from '../../../../services/lifecycle/common/lifecycle.js';
4241
import { ISearchService } from '../../../../services/search/common/search.js';
42+
import { McpPromptArgumentPick } from '../../../mcp/browser/mcpPromptArgumentPick.js';
4343
import { IMcpPrompt, IMcpPromptMessage, IMcpServer, IMcpService, McpResourceURI } from '../../../mcp/common/mcpTypes.js';
4444
import { searchFilesAndFolders } from '../../../search/browser/chatContributions.js';
4545
import { IChatAgentData, IChatAgentNameService, IChatAgentService, getFullyQualifiedId } from '../../common/chatAgents.js';
@@ -545,7 +545,7 @@ class StartParameterizedPromptAction extends Action2 {
545545
return;
546546
}
547547

548-
const quickInputService = accessor.get(IQuickInputService);
548+
const instantiationService = accessor.get(IInstantiationService);
549549
const notificationService = accessor.get(INotificationService);
550550
const widgetService = accessor.get(IChatWidgetService);
551551
const fileService = accessor.get(IFileService);
@@ -564,51 +564,21 @@ class StartParameterizedPromptAction extends Action2 {
564564
};
565565

566566
const store = new DisposableStore();
567-
const quickInput = store.add(quickInputService.createInputBox());
567+
const pick = store.add(instantiationService.createInstance(McpPromptArgumentPick, prompt));
568568

569569
try {
570-
// remove fake /command if hidden before accepting
571-
store.add(quickInput.onDidHide(() => replaceTextWith('')));
572-
573-
quickInput.totalSteps = prompt.arguments.length;
574-
quickInput.step = 0;
575-
quickInput.ignoreFocusOut = true;
576-
577-
const args: Record<string, string> = {};
578-
for (const arg of prompt.arguments) {
579-
quickInput.step++;
580-
quickInput.placeholder = arg.name;
581-
quickInput.description = arg.required ? arg.description : `${arg.description || ''} (${localize('optional', 'Optional')})`;
582-
quickInput.value = '';
583-
584-
const value = await new Promise<string | undefined>(resolve => {
585-
store.add(quickInput.onDidAccept(() => {
586-
resolve(quickInput.value);
587-
}));
588-
store.add(quickInput.onDidHide(() => {
589-
resolve(undefined);
590-
store.dispose();
591-
}));
592-
quickInput.show();
593-
});
594-
595-
if (value === undefined || (value === '' && arg.required)) {
596-
store.dispose();
597-
return;
598-
}
599-
600-
args[arg.name] = value;
570+
const args = await pick.createArgs();
571+
if (!args) {
572+
replaceTextWith('');
573+
return;
601574
}
602575

603-
quickInput.value = '';
604-
quickInput.placeholder = localize('loading', 'Loading...');
605-
quickInput.busy = true;
606-
607576
let messages: IMcpPromptMessage[];
608577
try {
609578
messages = await prompt.resolve(args);
610579
} catch (e) {
611580
notificationService.error(localize('mcp.prompt.error', "Error resolving prompt: {0}", String(e)));
581+
replaceTextWith('');
612582
return;
613583
}
614584

0 commit comments

Comments
 (0)