Path: blob/main/extensions/copilot/test/intent/intentTest.ts
13389 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import * as fs from 'fs';7import path from 'path';8import type { ChatParticipantDetectionResult, ChatParticipantMetadata } from 'vscode';9import '../../src/extension/intents/node/allIntents';10import { IIntentService } from '../../src/extension/intents/node/intentService';11import { ChatVariablesCollection } from '../../src/extension/prompt/common/chatVariablesCollection';12import { IntentDetector } from '../../src/extension/prompt/node/intentDetector';13import { createTelemetryWithId } from '../../src/extension/prompt/node/telemetry';14import { editingSessionAgentEditorName, editsAgentName } from '../../src/platform/chat/common/chatAgents';15import { ChatLocation } from '../../src/platform/chat/common/commonTypes';16import { ITabsAndEditorsService } from '../../src/platform/tabs/common/tabsAndEditorsService';17import { TestingServiceCollection } from '../../src/platform/test/node/services';18import { TestingTabsAndEditorsService } from '../../src/platform/test/node/simulationWorkspaceServices';19import { CancellationToken } from '../../src/util/vs/base/common/cancellation';20import { IInstantiationService } from '../../src/util/vs/platform/instantiation/common/instantiation';21import { stest } from '../base/stest';2223export interface IIntentScenario {24name: string;25location: ChatLocation;26query: string;27expectedIntent: string | string[];28}2930export function generateIntentTest(scenario: IIntentScenario) {31stest({ description: scenario.name }, async (testingServiceCollection) => {32await executeIntentTest(testingServiceCollection, scenario);33});34}3536export async function executeIntentTest(testingServiceCollection: TestingServiceCollection, scenario: IIntentScenario) {37testingServiceCollection.define(ITabsAndEditorsService, new TestingTabsAndEditorsService({38getActiveTextEditor: () => undefined,39getVisibleTextEditors: () => [],40getActiveNotebookEditor: () => undefined41}));42const accessor = testingServiceCollection.createTestingAccessor();43const intentService = accessor.get(IIntentService);44const instaService = accessor.get(IInstantiationService);45const intentDetector = instaService.createInstance(IntentDetector);46const query = scenario.query;47const builtinIntents = readBuiltinIntents(scenario.location);48const detectedIntent = await intentDetector.detectIntent(scenario.location, undefined, query, CancellationToken.None, createTelemetryWithId(), new ChatVariablesCollection([]), builtinIntents);49const intent = detectedIntent ?? intentService.unknownIntent;5051const expectedIntents = Array.isArray(scenario.expectedIntent) ? scenario.expectedIntent : [scenario.expectedIntent];52assert.ok(intent && expectedIntents.includes('participant' in intent ? detectedParticipantToIntentId(intent) : intent.id), `Expected intent [${expectedIntents.join(',')}] but got ${'participant' in intent ? intent.participant : intent.id}`);53}5455function detectedParticipantToIntentId(detected: ChatParticipantDetectionResult) {56switch (detected.participant) {57case 'github.copilot.default':58return 'unknown';59case `github.copilot.${editingSessionAgentEditorName}`:60if (detected.command) {61return detected.command;62}63return 'unknown';64case 'github.copilot.terminalPanel':65return 'terminalExplain';66case `github.copilot.${editsAgentName}`:67switch (detected.command) {68case 'new':69return 'new';70case 'newNotebook':71return 'newNotebook';72case 'tests':73return 'tests';74case 'setupTests':75return 'setupTests';76default:77return 'workspace';78}79case 'github.copilot.vscode':80return 'vscode';81case 'github.copilot-dynamic.platform':82return 'github.copilot-dynamic.platform';83}84throw new Error(`Unknown participant ${detected.participant} with command ${detected.command}`);85}8687export function readBuiltinIntents(location: ChatLocation) {88const packageJson = JSON.parse(fs.readFileSync(path.resolve(path.join(__dirname, '..', 'package.json'))).toString(), undefined);89const participantMetadata: ChatParticipantMetadata[] = [];90for (const participant of packageJson['contributes']['chatParticipants']) {91const locationName = location === ChatLocation.Panel ? 'panel' : location === ChatLocation.Editor ? 'editor' : undefined;92if (!locationName || !participant.locations || !participant.locations.includes(locationName)) {93continue;94}95if (participant.disambiguation?.length) {96participantMetadata.push({97participant: participant.id, disambiguation: participant.disambiguation98});99}100if (participant.commands) {101for (const command of participant.commands) {102if (command.disambiguation?.length) {103participantMetadata.push({104participant: participant.id, command: command.name, disambiguation: command.disambiguation105});106}107}108}109}110return participantMetadata;111}112113114