@@ -22,8 +22,7 @@ import { FileService } from '../../../../../../../platform/files/common/fileServ
2222import { InMemoryFileSystemProvider } from '../../../../../../../platform/files/common/inMemoryFilesystemProvider.js' ;
2323import { TestInstantiationService } from '../../../../../../../platform/instantiation/test/common/instantiationServiceMock.js' ;
2424import { 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' ;
2726import { INSTRUCTIONS_LANGUAGE_ID , PROMPT_LANGUAGE_ID , PromptsType } from '../../../../common/promptSyntax/promptTypes.js' ;
2827import { TextModelPromptParser } from '../../../../common/promptSyntax/parsers/textModelPromptParser.js' ;
2928import { IPromptFileReference } from '../../../../common/promptSyntax/parsers/types.js' ;
@@ -35,7 +34,12 @@ import { ComputeAutomaticInstructions } from '../../../../common/promptSyntax/co
3534import { CancellationToken } from '../../../../../../../base/common/cancellation.js' ;
3635import { ResourceSet } from '../../../../../../../base/common/map.js' ;
3736import { 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} ) ;
0 commit comments