Skip to content

Commit cca4746

Browse files
committed
a
1 parent c8bd2f8 commit cca4746

File tree

4 files changed

+122
-33
lines changed

4 files changed

+122
-33
lines changed

packages/core/src/amazonq/lsp/lspController.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface Manifest {
6464
targets: Target[]
6565
}[]
6666
}
67-
const manifestUrl = 'https://ducvaeoffl85c.cloudfront.net/manifest-0.1.28.json'
67+
const manifestUrl = 'https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json'
6868
// this LSP client in Q extension is only going to work with these LSP server versions
6969
const supportedLspServerVersions = ['0.1.28']
7070

@@ -308,7 +308,7 @@ export class LspController {
308308
return resp
309309
}
310310

311-
async queryInlineProjectContext(query: string, path: string) {
311+
async queryInlineProjectContext(query: string, path: string, target: 'bm25' | 'codemap' | 'default') {
312312
try {
313313
return await LspClient.instance.queryInlineProjectContext(query, path)
314314
} catch (e) {

packages/core/src/codewhisperer/models/model.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ export const vsCodeState: VsCodeState = {
4747

4848
export type UtgStrategy = 'ByName' | 'ByContent'
4949

50-
export type CrossFileStrategy = 'OpenTabs_BM25'
50+
export type CrossFileStrategy = 'OpenTabs_BM25' | 'Codemap' | 'Project_BM25' | 'Project'
5151

52-
export type SupplementalContextStrategy = CrossFileStrategy | UtgStrategy | 'Empty' | 'LSP'
52+
export type SupplementalContextStrategy = CrossFileStrategy | UtgStrategy | 'Empty'
5353

5454
export interface CodeWhispererSupplementalContext {
5555
isUtg: boolean

packages/core/src/codewhisperer/util/supplementalContext/crossFileContextUtil.ts

Lines changed: 102 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ interface Chunk {
5353
score?: number
5454
}
5555

56-
type SupplementalContextConfig = 'none' | 'v1' | 'v2'
56+
type SupplementalContextConfig = 'none' | 'openbtabs' | 'codemap' | 'bm25' | 'default'
5757

5858
export async function fetchSupplementalContextForSrc(
5959
editor: vscode.TextEditor,
@@ -64,43 +64,114 @@ export async function fetchSupplementalContextForSrc(
6464
if (supplementalContextConfig === 'none') {
6565
return undefined
6666
}
67-
if (supplementalContextConfig === 'v1') {
68-
return fetchSupplementalContextForSrcV1(editor, cancellationToken)
67+
68+
if (supplementalContextConfig === 'openbtabs') {
69+
return {
70+
supplementalContextItems: (await fetchOpentabsContext(editor, cancellationToken)) ?? [],
71+
strategy: 'OpenTabs_BM25',
72+
}
73+
}
74+
75+
if (supplementalContextConfig === 'codemap') {
76+
const opentabsContextAndCodemap = await waitUntil(
77+
async function () {
78+
const result: CodeWhispererSupplementalContextItem[] = []
79+
const opentabsContext = await fetchOpentabsContext(editor, cancellationToken)
80+
const codemap = await fetchProjectContext(editor, 'codemap')
81+
82+
if (codemap && codemap.length > 0) {
83+
result.push(...codemap)
84+
}
85+
86+
if (opentabsContext && opentabsContext.length > 0) {
87+
result.push(...opentabsContext)
88+
}
89+
90+
return result
91+
},
92+
{ timeout: supplementalContextTimeoutInMs, interval: 5, truthy: false }
93+
)
94+
95+
return {
96+
supplementalContextItems: opentabsContextAndCodemap ?? [],
97+
strategy: 'Codemap',
98+
}
6999
}
70-
const promiseV1 = waitUntil(
100+
101+
// fallback to opentabs if projectContext timeout for 'default' | 'bm25'
102+
const opentabsContextPromise = waitUntil(
71103
async function () {
72-
return await fetchSupplementalContextForSrcV1(editor, cancellationToken)
104+
return await fetchOpentabsContext(editor, cancellationToken)
73105
},
74106
{ timeout: supplementalContextTimeoutInMs, interval: 5, truthy: false }
75107
)
76-
const promiseV2 = waitUntil(
108+
109+
if (supplementalContextConfig === 'bm25') {
110+
const projectBM25Promise = waitUntil(
111+
async function () {
112+
return await fetchProjectContext(editor, 'bm25')
113+
},
114+
{ timeout: supplementalContextTimeoutInMs, interval: 5, truthy: false }
115+
)
116+
117+
const [projectContext, opentabsContext] = await Promise.all([projectBM25Promise, opentabsContextPromise])
118+
if (projectContext && projectContext.length > 0) {
119+
return {
120+
supplementalContextItems: projectContext,
121+
strategy: 'Project_BM25',
122+
}
123+
}
124+
125+
return {
126+
supplementalContextItems: opentabsContext ?? [],
127+
strategy: 'OpenTabs_BM25',
128+
}
129+
}
130+
131+
const projectContextAndCodemapPromise = waitUntil(
77132
async function () {
78-
return await fetchSupplementalContextForSrcV2(editor)
133+
return await fetchProjectContext(editor, 'default')
79134
},
80135
{ timeout: supplementalContextTimeoutInMs, interval: 5, truthy: false }
81136
)
82-
const [resultV1, resultV2] = await Promise.all([promiseV1, promiseV2])
83-
return resultV2 ?? resultV1
137+
138+
const [projectContext, opentabsContext] = await Promise.all([
139+
projectContextAndCodemapPromise,
140+
opentabsContextPromise,
141+
])
142+
if (projectContext && projectContext.length > 0) {
143+
return {
144+
supplementalContextItems: projectContext,
145+
strategy: 'Project',
146+
}
147+
}
148+
149+
return {
150+
supplementalContextItems: opentabsContext ?? [],
151+
strategy: 'OpenTabs_BM25',
152+
}
84153
}
85154

86-
export async function fetchSupplementalContextForSrcV2(
87-
editor: vscode.TextEditor
88-
): Promise<Pick<CodeWhispererSupplementalContext, 'supplementalContextItems' | 'strategy'> | undefined> {
155+
export async function fetchProjectContext(
156+
editor: vscode.TextEditor,
157+
target: 'default' | 'codemap' | 'bm25'
158+
): Promise<CodeWhispererSupplementalContextItem[] | undefined> {
89159
const inputChunkContent = getInputChunk(editor)
90160

91161
const inlineProjectContext: { content: string; score: number; filePath: string }[] =
92-
await LspController.instance.queryInlineProjectContext(inputChunkContent.content, editor.document.uri.fsPath)
162+
await LspController.instance.queryInlineProjectContext(
163+
inputChunkContent.content,
164+
editor.document.uri.fsPath,
165+
target
166+
)
93167

94-
return {
95-
supplementalContextItems: [...inlineProjectContext],
96-
strategy: 'LSP',
97-
}
168+
return inlineProjectContext
98169
}
99170

100-
export async function fetchSupplementalContextForSrcV1(
171+
export async function fetchOpentabsContext(
101172
editor: vscode.TextEditor,
102173
cancellationToken: vscode.CancellationToken
103-
): Promise<Pick<CodeWhispererSupplementalContext, 'supplementalContextItems' | 'strategy'> | undefined> {
174+
): Promise<CodeWhispererSupplementalContextItem[] | undefined> {
104175
const codeChunksCalculated = crossFileContextConfig.numberOfChunkToFetch
105176

106177
// Step 1: Get relevant cross files to refer
@@ -151,10 +222,7 @@ export async function fetchSupplementalContextForSrcV1(
151222

152223
// DO NOT send code chunk with empty content
153224
getLogger().debug(`CodeWhisperer finished fetching crossfile context out of ${relevantCrossFilePaths.length} files`)
154-
return {
155-
supplementalContextItems: supplementalContexts,
156-
strategy: 'OpenTabs_BM25',
157-
}
225+
return supplementalContexts
158226
}
159227

160228
function findBestKChunkMatches(chunkInput: Chunk, chunkReferences: Chunk[], k: number): Chunk[] {
@@ -201,10 +269,18 @@ function getSupplementalContextConfig(languageId: vscode.TextDocument['languageI
201269
if (!isCrossFileSupported(languageId)) {
202270
return 'none'
203271
}
204-
if (FeatureConfigProvider.instance.isNewProjectContextGroup()) {
205-
return 'v2'
272+
273+
const group = FeatureConfigProvider.instance.getProjectContextGroup()
274+
switch (group) {
275+
case 'control':
276+
return 'openbtabs'
277+
278+
case 't1':
279+
return 'codemap'
280+
281+
case 't2':
282+
return 'bm25'
206283
}
207-
return 'v1'
208284
}
209285

210286
/**

packages/core/src/shared/featureConfig.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,22 @@ export class FeatureConfigProvider {
6464
return (this.#instance ??= new this())
6565
}
6666

67-
isNewProjectContextGroup(): boolean {
68-
return true
69-
return this.featureConfigs.get(Features.projectContextFeature)?.variation === 'TREATMENT'
67+
getProjectContextGroup(): 'control' | 't1' | 't2' {
68+
const variation = this.featureConfigs.get(Features.projectContextFeature)?.variation
69+
70+
switch (variation) {
71+
case 'CONTROL':
72+
return 'control'
73+
74+
case 'TREATMENT_1':
75+
return 't1'
76+
77+
case 'TREATMENT_2':
78+
return 't2'
79+
80+
default:
81+
return 'control'
82+
}
7083
}
7184

7285
public async listFeatureEvaluations(): Promise<ListFeatureEvaluationsResponse> {

0 commit comments

Comments
 (0)