Skip to content

Commit 6cb3870

Browse files
authored
Merge pull request microsoft#264926 from microsoft/aeschli/expensive-guineafowl
copilot-instructions.md and agents.md are not picked up
2 parents bc3101e + 14246b7 commit 6cb3870

6 files changed

Lines changed: 117 additions & 15 deletions

File tree

src/vs/workbench/contrib/chat/common/promptSyntax/computeAutomaticInstructions.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ export class ComputeAutomaticInstructions {
162162
}
163163
}
164164
}
165+
for (const entry of entries.asArray()) {
166+
variables.add(entry);
167+
}
165168
}
166169

167170
private _matches(files: ResourceSet, applyToPattern: string): { pattern: string; file?: URI } | undefined {

src/vs/workbench/contrib/chat/test/common/promptSyntax/service/promptsService.test.ts

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ import { FileService } from '../../../../../../../platform/files/common/fileServ
2222
import { InMemoryFileSystemProvider } from '../../../../../../../platform/files/common/inMemoryFilesystemProvider.js';
2323
import { TestInstantiationService } from '../../../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
2424
import { ILogService, NullLogService } from '../../../../../../../platform/log/common/log.js';
25-
import { IWorkspacesService } from '../../../../../../../platform/workspaces/common/workspaces.js';
26-
import { INSTRUCTION_FILE_EXTENSION, PROMPT_FILE_EXTENSION } from '../../../../common/promptSyntax/config/promptFileLocations.js';
25+
import { INSTRUCTION_FILE_EXTENSION, INSTRUCTIONS_DEFAULT_SOURCE_FOLDER, MODE_DEFAULT_SOURCE_FOLDER, PROMPT_DEFAULT_SOURCE_FOLDER, PROMPT_FILE_EXTENSION } from '../../../../common/promptSyntax/config/promptFileLocations.js';
2726
import { INSTRUCTIONS_LANGUAGE_ID, PROMPT_LANGUAGE_ID, PromptsType } from '../../../../common/promptSyntax/promptTypes.js';
2827
import { TextModelPromptParser } from '../../../../common/promptSyntax/parsers/textModelPromptParser.js';
2928
import { IPromptFileReference } from '../../../../common/promptSyntax/parsers/types.js';
@@ -35,7 +34,12 @@ import { ComputeAutomaticInstructions } from '../../../../common/promptSyntax/co
3534
import { CancellationToken } from '../../../../../../../base/common/cancellation.js';
3635
import { ResourceSet } from '../../../../../../../base/common/map.js';
3736
import { IWorkbenchEnvironmentService } from '../../../../../../services/environment/common/environmentService.js';
38-
import { ChatRequestVariableSet, isPromptFileVariableEntry } from '../../../../common/chatVariableEntries.js';
37+
import { ChatRequestVariableSet, isPromptFileVariableEntry, toFileVariableEntry } from '../../../../common/chatVariableEntries.js';
38+
import { PromptsConfig } from '../../../../common/promptSyntax/config/config.js';
39+
import { IWorkspaceContextService } from '../../../../../../../platform/workspace/common/workspace.js';
40+
import { TestContextService, TestUserDataProfileService } from '../../../../../../test/common/workbenchTestServices.js';
41+
import { testWorkspace } from '../../../../../../../platform/workspace/test/common/testWorkspace.js';
42+
import { IUserDataProfileService } from '../../../../../../services/userDataProfile/common/userDataProfile.js';
3943

4044
/**
4145
* Helper class to assert the properties of a link.
@@ -109,13 +113,26 @@ suite('PromptsService', () => {
109113

110114
let service: IPromptsService;
111115
let instaService: TestInstantiationService;
116+
let workspaceContextService: TestContextService;
112117

113118
setup(async () => {
114119
instaService = disposables.add(new TestInstantiationService());
115120
instaService.stub(ILogService, new NullLogService());
116-
instaService.stub(IWorkspacesService, {});
117-
instaService.stub(IConfigurationService, new TestConfigurationService());
121+
122+
workspaceContextService = new TestContextService();
123+
instaService.stub(IWorkspaceContextService, workspaceContextService);
124+
125+
const testConfigService = new TestConfigurationService();
126+
testConfigService.setUserConfiguration(PromptsConfig.KEY, true);
127+
testConfigService.setUserConfiguration(PromptsConfig.USE_COPILOT_INSTRUCTION_FILES, true);
128+
testConfigService.setUserConfiguration(PromptsConfig.USE_AGENT_MD, true);
129+
testConfigService.setUserConfiguration(PromptsConfig.INSTRUCTIONS_LOCATION_KEY, { [INSTRUCTIONS_DEFAULT_SOURCE_FOLDER]: true });
130+
testConfigService.setUserConfiguration(PromptsConfig.PROMPT_LOCATIONS_KEY, { [PROMPT_DEFAULT_SOURCE_FOLDER]: true });
131+
testConfigService.setUserConfiguration(PromptsConfig.MODE_LOCATION_KEY, { [MODE_DEFAULT_SOURCE_FOLDER]: true });
132+
133+
instaService.stub(IConfigurationService, testConfigService);
118134
instaService.stub(IWorkbenchEnvironmentService, {});
135+
instaService.stub(IUserDataProfileService, new TestUserDataProfileService());
119136

120137
const fileService = disposables.add(instaService.createInstance(FileService));
121138
instaService.stub(IFileService, fileService);
@@ -561,6 +578,9 @@ suite('PromptsService', () => {
561578
const rootFileName = 'file2.prompt.md';
562579

563580
const rootFolderUri = URI.file(rootFolder);
581+
582+
workspaceContextService.setWorkspace(testWorkspace(rootFolderUri));
583+
564584
const rootFileUri = URI.joinPath(rootFolderUri, rootFileName);
565585

566586
await (instaService.createInstance(MockFilesystem,
@@ -733,6 +753,8 @@ suite('PromptsService', () => {
733753
const rootFolder = `/${rootFolderName}`;
734754
const rootFolderUri = URI.file(rootFolder);
735755

756+
workspaceContextService.setWorkspace(testWorkspace(rootFolderUri));
757+
736758
const userPromptsFolderName = '/tmp/user-data/prompts';
737759
const userPromptsFolderUri = URI.file(userPromptsFolderName);
738760

@@ -918,6 +940,8 @@ suite('PromptsService', () => {
918940
const rootFolder = `/${rootFolderName}`;
919941
const rootFolderUri = URI.file(rootFolder);
920942

943+
workspaceContextService.setWorkspace(testWorkspace(rootFolderUri));
944+
921945
const userPromptsFolderName = '/tmp/user-data/prompts';
922946
const userPromptsFolderUri = URI.file(userPromptsFolderName);
923947

@@ -1100,5 +1124,75 @@ suite('PromptsService', () => {
11001124
'Must find correct instruction files.',
11011125
);
11021126
});
1127+
1128+
test('copilot-instructions and AGENTS.md', async () => {
1129+
const rootFolderName = 'copilot-instructions-and-agents';
1130+
const rootFolder = `/${rootFolderName}`;
1131+
const rootFolderUri = URI.file(rootFolder);
1132+
1133+
workspaceContextService.setWorkspace(testWorkspace(rootFolderUri));
1134+
1135+
// mock current workspace file structure
1136+
await (instaService.createInstance(MockFilesystem,
1137+
[{
1138+
name: rootFolderName,
1139+
children: [
1140+
{
1141+
name: 'codestyle.md',
1142+
contents: [
1143+
'Can you see this?',
1144+
],
1145+
},
1146+
{
1147+
name: 'AGENTS.md',
1148+
contents: [
1149+
'What about this?',
1150+
],
1151+
},
1152+
{
1153+
name: 'README.md',
1154+
contents: [
1155+
'Thats my project?',
1156+
],
1157+
},
1158+
{
1159+
name: '.github',
1160+
children: [
1161+
{
1162+
name: 'copilot-instructions.md',
1163+
contents: [
1164+
'Be nice and friendly. Also look at instructions at #file:../codestyle.md and [more-codestyle.md](./more-codestyle.md).',
1165+
],
1166+
},
1167+
{
1168+
name: 'more-codestyle.md',
1169+
contents: [
1170+
'I like it clean.',
1171+
],
1172+
},
1173+
],
1174+
},
1175+
1176+
],
1177+
}])).mock();
1178+
1179+
1180+
const contextComputer = instaService.createInstance(ComputeAutomaticInstructions, undefined);
1181+
const context = new ChatRequestVariableSet();
1182+
context.add(toFileVariableEntry(URI.joinPath(rootFolderUri, 'README.md')));
1183+
1184+
await contextComputer.collect(context, CancellationToken.None);
1185+
1186+
assert.deepStrictEqual(
1187+
context.asArray().map(i => isPromptFileVariableEntry(i) ? i.value.path : undefined).filter(e => !!e).sort(),
1188+
[
1189+
URI.joinPath(rootFolderUri, '.github/copilot-instructions.md').path,
1190+
URI.joinPath(rootFolderUri, '.github/more-codestyle.md').path,
1191+
URI.joinPath(rootFolderUri, 'AGENTS.md').path,
1192+
URI.joinPath(rootFolderUri, 'codestyle.md').path,
1193+
].sort(),
1194+
'Must find correct instruction files.',
1195+
);
1196+
});
11031197
});
11041198
});

src/vs/workbench/contrib/chat/test/common/promptSyntax/utils/promptFilesLocator.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { PromptsType } from '../../../../common/promptSyntax/promptTypes.js';
2626
import { isValidGlob, PromptFilesLocator } from '../../../../common/promptSyntax/utils/promptFilesLocator.js';
2727
import { IMockFolder, MockFilesystem } from '../testUtils/mockFilesystem.js';
2828
import { mockService } from './mock.js';
29+
import { TestUserDataProfileService } from '../../../../../../test/common/workbenchTestServices.js';
2930

3031
/**
3132
* Mocked instance of {@link IConfigurationService}.
@@ -112,7 +113,7 @@ suite('PromptFilesLocator', () => {
112113
});
113114
instantiationService.stub(IWorkspaceContextService, mockWorkspaceService(workspaceFolders));
114115
instantiationService.stub(IWorkbenchEnvironmentService, {} as IWorkbenchEnvironmentService);
115-
instantiationService.stub(IUserDataProfileService, {} as IUserDataProfileService);
116+
instantiationService.stub(IUserDataProfileService, new TestUserDataProfileService());
116117
instantiationService.stub(ISearchService, {
117118
async fileSearch(query: IFileQuery) {
118119
// mock the search service

src/vs/workbench/services/extensions/test/browser/extensionService.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ import { ILifecycleService } from '../../../lifecycle/common/lifecycle.js';
4646
import { IRemoteAgentService } from '../../../remote/common/remoteAgentService.js';
4747
import { IUserDataProfileService } from '../../../userDataProfile/common/userDataProfile.js';
4848
import { WorkspaceTrustEnablementService } from '../../../workspaces/common/workspaceTrust.js';
49-
import { TestEnvironmentService, TestFileService, TestLifecycleService, TestRemoteAgentService, TestRemoteExtensionsScannerService, TestUserDataProfileService, TestWebExtensionsScannerService, TestWorkbenchExtensionEnablementService, TestWorkbenchExtensionManagementService } from '../../../../test/browser/workbenchTestServices.js';
50-
import { TestContextService } from '../../../../test/common/workbenchTestServices.js';
49+
import { TestEnvironmentService, TestFileService, TestLifecycleService, TestRemoteAgentService, TestRemoteExtensionsScannerService, TestWebExtensionsScannerService, TestWorkbenchExtensionEnablementService, TestWorkbenchExtensionManagementService } from '../../../../test/browser/workbenchTestServices.js';
50+
import { TestContextService, TestUserDataProfileService } from '../../../../test/common/workbenchTestServices.js';
5151

5252
suite('BrowserExtensionService', () => {
5353

src/vs/workbench/test/browser/workbenchTestServices.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ import { IDiagnosticInfoOptions, IDiagnosticInfo } from '../../../platform/diagn
157157
import { ExtensionType, IExtension, IExtensionDescription, IRelaxedExtensionManifest, TargetPlatform } from '../../../platform/extensions/common/extensions.js';
158158
import { IRemoteAgentEnvironment } from '../../../platform/remote/common/remoteAgentEnvironment.js';
159159
import { ILayoutOffsetInfo } from '../../../platform/layout/browser/layoutService.js';
160-
import { IUserDataProfile, IUserDataProfilesService, toUserDataProfile, UserDataProfilesService } from '../../../platform/userDataProfile/common/userDataProfile.js';
160+
import { IUserDataProfile, IUserDataProfilesService, UserDataProfilesService } from '../../../platform/userDataProfile/common/userDataProfile.js';
161161
import { UserDataProfileService } from '../../services/userDataProfile/common/userDataProfileService.js';
162162
import { IUserDataProfileService } from '../../services/userDataProfile/common/userDataProfile.js';
163163
import { EnablementState, IExtensionManagementServer, IResourceExtension, IScannedExtension, IWebExtensionsScannerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService } from '../../services/extensionManagement/common/extensionManagement.js';
@@ -2276,13 +2276,7 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens
22762276
async requestPublisherTrust(extensions: InstallExtensionInfo[]): Promise<void> { }
22772277
}
22782278

2279-
export class TestUserDataProfileService implements IUserDataProfileService {
22802279

2281-
readonly _serviceBrand: undefined;
2282-
readonly onDidChangeCurrentProfile = Event.None;
2283-
readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' }), URI.file('tests').with({ scheme: 'vscode-tests' }));
2284-
async updateCurrentProfile(): Promise<void> { }
2285-
}
22862280

22872281
export class TestWebExtensionsScannerService implements IWebExtensionsScannerService {
22882282
_serviceBrand: undefined;

src/vs/workbench/test/common/workbenchTestServices.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import { IAutoSaveConfiguration, IAutoSaveMode, IFilesConfigurationService } fro
3131
import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService, IWorkspaceTrustRequestService, IWorkspaceTrustTransitionParticipant, IWorkspaceTrustUriInfo, WorkspaceTrustRequestOptions, WorkspaceTrustUriResponse } from '../../../platform/workspace/common/workspaceTrust.js';
3232
import { IMarker, IMarkerData, IMarkerService, IResourceMarker, MarkerStatistics } from '../../../platform/markers/common/markers.js';
3333
import { IProgress, IProgressStep } from '../../../platform/progress/common/progress.js';
34+
import { IUserDataProfileService } from '../../services/userDataProfile/common/userDataProfile.js';
35+
import { toUserDataProfile } from '../../../platform/userDataProfile/common/userDataProfile.js';
3436

3537
export class TestLoggerService extends AbstractLoggerService {
3638
constructor(logsHome?: URI) {
@@ -57,6 +59,14 @@ export class TestTextResourcePropertiesService implements ITextResourcePropertie
5759
}
5860
}
5961

62+
export class TestUserDataProfileService implements IUserDataProfileService {
63+
64+
readonly _serviceBrand: undefined;
65+
readonly onDidChangeCurrentProfile = Event.None;
66+
readonly currentProfile = toUserDataProfile('test', 'test', URI.file('tests').with({ scheme: 'vscode-tests' }), URI.file('tests').with({ scheme: 'vscode-tests' }));
67+
async updateCurrentProfile(): Promise<void> { }
68+
}
69+
6070
export class TestContextService implements IWorkspaceContextService {
6171

6272
declare readonly _serviceBrand: undefined;

0 commit comments

Comments
 (0)