@@ -53,54 +53,137 @@ interface Chunk {
53
53
score ?: number
54
54
}
55
55
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'
57
64
58
65
export async function fetchSupplementalContextForSrc (
59
66
editor : vscode . TextEditor ,
60
67
cancellationToken : vscode . CancellationToken
61
68
) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
62
69
const supplementalContextConfig = getSupplementalContextConfig ( editor . document . languageId )
63
70
71
+ // not supported case
64
72
if ( supplementalContextConfig === 'none' ) {
65
73
return undefined
66
74
}
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
+ }
69
109
}
70
- const promiseV1 = waitUntil (
110
+
111
+ // fallback to opentabs if projectContext timeout for 'default' | 'bm25'
112
+ const opentabsContextPromise = waitUntil (
71
113
async function ( ) {
72
- return await fetchSupplementalContextForSrcV1 ( editor , cancellationToken )
114
+ return await fetchOpentabsContext ( editor , cancellationToken )
73
115
} ,
74
116
{ timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
75
117
)
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 (
77
144
async function ( ) {
78
- return await fetchSupplementalContextForSrcV2 ( editor )
145
+ return await fetchProjectContext ( editor , 'default' )
79
146
} ,
80
147
{ timeout : supplementalContextTimeoutInMs , interval : 5 , truthy : false }
81
148
)
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
+ }
84
165
}
85
166
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 [ ] > {
89
171
const inputChunkContent = getInputChunk ( editor )
90
172
91
173
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
+ )
93
179
94
- return {
95
- supplementalContextItems : [ ...inlineProjectContext ] ,
96
- strategy : 'LSP' ,
97
- }
180
+ return inlineProjectContext
98
181
}
99
182
100
- export async function fetchSupplementalContextForSrcV1 (
183
+ export async function fetchOpentabsContext (
101
184
editor : vscode . TextEditor ,
102
185
cancellationToken : vscode . CancellationToken
103
- ) : Promise < Pick < CodeWhispererSupplementalContext , 'supplementalContextItems' | 'strategy' > | undefined > {
186
+ ) : Promise < CodeWhispererSupplementalContextItem [ ] | undefined > {
104
187
const codeChunksCalculated = crossFileContextConfig . numberOfChunkToFetch
105
188
106
189
// Step 1: Get relevant cross files to refer
@@ -151,10 +234,7 @@ export async function fetchSupplementalContextForSrcV1(
151
234
152
235
// DO NOT send code chunk with empty content
153
236
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
158
238
}
159
239
160
240
function findBestKChunkMatches ( chunkInput : Chunk , chunkReferences : Chunk [ ] , k : number ) : Chunk [ ] {
@@ -201,10 +281,18 @@ function getSupplementalContextConfig(languageId: vscode.TextDocument['languageI
201
281
if ( ! isCrossFileSupported ( languageId ) ) {
202
282
return 'none'
203
283
}
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'
206
295
}
207
- return 'v1'
208
296
}
209
297
210
298
/**
0 commit comments