@@ -53,54 +53,137 @@ interface Chunk {
5353 score ?: number
5454}
5555
56- type SupplementalContextConfig = 'none' | 'v1' | 'v2'
56+ /**
57+ * `none`: supplementalContext is not supported
58+ * `opentabs`: opentabs_BM25
59+ * `codemap`: repomap + opentabs BM25
60+ * `bm25`: global_BM25
61+ * `default`: repomap + global_BM25
62+ */
63+ type SupplementalContextConfig = 'none' | 'opentabs' | 'codemap' | 'bm25' | 'default'
5764
5865export async function fetchSupplementalContextForSrc (
5966 editor : vscode . TextEditor ,
6067 cancellationToken : vscode . CancellationToken
6168) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
6269 const supplementalContextConfig = getSupplementalContextConfig ( editor . document . languageId )
6370
71+ // not supported case
6472 if ( supplementalContextConfig === 'none' ) {
6573 return undefined
6674 }
67- if ( supplementalContextConfig === 'v1' ) {
68- return fetchSupplementalContextForSrcV1 ( editor , cancellationToken )
75+
76+ // opentabs context will use bm25 and users' open tabs to fetch supplemental context
77+ if ( supplementalContextConfig === 'opentabs' ) {
78+ return {
79+ supplementalContextItems : ( await fetchOpentabsContext ( editor , cancellationToken ) ) ?? [ ] ,
80+ strategy : 'opentabs' ,
81+ }
82+ }
83+
84+ // codemap will use opentabs context plus repomap if it's present
85+ if ( supplementalContextConfig === 'codemap' ) {
86+ const opentabsContextAndCodemap = await waitUntil (
87+ async function ( ) {
88+ const result : CodeWhispererSupplementalContextItem [ ] = [ ]
89+ const opentabsContext = await fetchOpentabsContext ( editor , cancellationToken )
90+ const codemap = await fetchProjectContext ( editor , 'codemap' )
91+
92+ if ( codemap && codemap . length > 0 ) {
93+ result . push ( ...codemap )
94+ }
95+
96+ if ( opentabsContext && opentabsContext . length > 0 ) {
97+ result . push ( ...opentabsContext )
98+ }
99+
100+ return result
101+ } ,
102+ { timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
103+ )
104+
105+ return {
106+ supplementalContextItems : opentabsContextAndCodemap ?? [ ] ,
107+ strategy : 'codemap' ,
108+ }
69109 }
70- const promiseV1 = waitUntil (
110+
111+ // fallback to opentabs if projectContext timeout for 'default' | 'bm25'
112+ const opentabsContextPromise = waitUntil (
71113 async function ( ) {
72- return await fetchSupplementalContextForSrcV1 ( editor , cancellationToken )
114+ return await fetchOpentabsContext ( editor , cancellationToken )
73115 } ,
74116 { timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
75117 )
76- const promiseV2 = waitUntil (
118+
119+ // global bm25 without repomap
120+ if ( supplementalContextConfig === 'bm25' ) {
121+ const projectBM25Promise = waitUntil (
122+ async function ( ) {
123+ return await fetchProjectContext ( editor , 'bm25' )
124+ } ,
125+ { timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
126+ )
127+
128+ const [ projectContext , opentabsContext ] = await Promise . all ( [ projectBM25Promise , opentabsContextPromise ] )
129+ if ( projectContext && projectContext . length > 0 ) {
130+ return {
131+ supplementalContextItems : projectContext ,
132+ strategy : 'bm25' ,
133+ }
134+ }
135+
136+ return {
137+ supplementalContextItems : opentabsContext ?? [ ] ,
138+ strategy : 'opentabs' ,
139+ }
140+ }
141+
142+ // global bm25 with repomap
143+ const projectContextAndCodemapPromise = waitUntil (
77144 async function ( ) {
78- return await fetchSupplementalContextForSrcV2 ( editor )
145+ return await fetchProjectContext ( editor , 'default' )
79146 } ,
80147 { timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
81148 )
82- const [ resultV1 , resultV2 ] = await Promise . all ( [ promiseV1 , promiseV2 ] )
83- return resultV2 ?? resultV1
149+
150+ const [ projectContext , opentabsContext ] = await Promise . all ( [
151+ projectContextAndCodemapPromise ,
152+ opentabsContextPromise ,
153+ ] )
154+ if ( projectContext && projectContext . length > 0 ) {
155+ return {
156+ supplementalContextItems : projectContext ,
157+ strategy : 'default' ,
158+ }
159+ }
160+
161+ return {
162+ supplementalContextItems : opentabsContext ?? [ ] ,
163+ strategy : 'opentabs' ,
164+ }
84165}
85166
86- export async function fetchSupplementalContextForSrcV2 (
87- editor : vscode . TextEditor
88- ) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
167+ export async function fetchProjectContext (
168+ editor : vscode . TextEditor ,
169+ target : 'default' | 'codemap' | 'bm25'
170+ ) : Promise < CodeWhispererSupplementalContextItem [ ] > {
89171 const inputChunkContent = getInputChunk ( editor )
90172
91173 const inlineProjectContext : { content : string ; score : number ; filePath : string } [ ] =
92- await LspController . instance . queryInlineProjectContext ( inputChunkContent . content , editor . document . uri . fsPath )
174+ await LspController . instance . queryInlineProjectContext (
175+ inputChunkContent . content ,
176+ editor . document . uri . fsPath ,
177+ target
178+ )
93179
94- return {
95- supplementalContextItems : [ ...inlineProjectContext ] ,
96- strategy : 'LSP' ,
97- }
180+ return inlineProjectContext
98181}
99182
100- export async function fetchSupplementalContextForSrcV1 (
183+ export async function fetchOpentabsContext (
101184 editor : vscode . TextEditor ,
102185 cancellationToken : vscode . CancellationToken
103- ) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
186+ ) : Promise < CodeWhispererSupplementalContextItem [ ] | undefined > {
104187 const codeChunksCalculated = crossFileContextConfig . numberOfChunkToFetch
105188
106189 // Step 1: Get relevant cross files to refer
@@ -151,10 +234,7 @@ export async function fetchSupplementalContextForSrcV1(
151234
152235 // DO NOT send code chunk with empty content
153236 getLogger ( ) . debug ( `CodeWhisperer finished fetching crossfile context out of ${ relevantCrossFilePaths . length } files` )
154- return {
155- supplementalContextItems : supplementalContexts ,
156- strategy : 'OpenTabs_BM25' ,
157- }
237+ return supplementalContexts
158238}
159239
160240function findBestKChunkMatches ( chunkInput : Chunk , chunkReferences : Chunk [ ] , k : number ) : Chunk [ ] {
@@ -201,10 +281,18 @@ function getSupplementalContextConfig(languageId: vscode.TextDocument['languageI
201281 if ( ! isCrossFileSupported ( languageId ) ) {
202282 return 'none'
203283 }
204- if ( FeatureConfigProvider . instance . isNewProjectContextGroup ( ) ) {
205- return 'v2'
284+
285+ const group = FeatureConfigProvider . instance . getProjectContextGroup ( )
286+ switch ( group ) {
287+ case 'control' :
288+ return 'opentabs'
289+
290+ case 't1' :
291+ return 'codemap'
292+
293+ case 't2' :
294+ return 'bm25'
206295 }
207- return 'v1'
208296}
209297
210298/**
0 commit comments