Skip to content

Commit bf596bf

Browse files
authored
chore(amazonq): nep cherrypick codewhispererService.ts (#1689)
1 parent 4272eec commit bf596bf

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

server/aws-lsp-codewhisperer/src/shared/codeWhispererService.ts

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ import {
2222
createCodeWhispererTokenClient,
2323
RequestExtras,
2424
} from '../client/token/codewhisperer'
25+
import CodeWhispererSigv4Client = require('../client/sigv4/codewhisperersigv4client')
26+
import CodeWhispererTokenClient = require('../client/token/codewhispererbearertokenclient')
27+
import { getErrorId } from './utils'
28+
import { GenerateCompletionsResponse } from '../client/token/codewhispererbearertokenclient'
2529

26-
// Define our own Suggestion interface to wrap the differences between Token and IAM Client
2730
export interface Suggestion extends CodeWhispererTokenClient.Completion, CodeWhispererSigv4Client.Recommendation {
2831
itemId: string
2932
}
@@ -42,16 +45,17 @@ export interface ResponseContext {
4245
nextToken?: string
4346
}
4447

48+
export enum SuggestionType {
49+
EDIT = 'EDIT',
50+
COMPLETION = 'COMPLETION',
51+
}
52+
4553
export interface GenerateSuggestionsResponse {
4654
suggestions: Suggestion[]
55+
suggestionType?: SuggestionType
4756
responseContext: ResponseContext
4857
}
4958

50-
import CodeWhispererSigv4Client = require('../client/sigv4/codewhisperersigv4client')
51-
import CodeWhispererTokenClient = require('../client/token/codewhispererbearertokenclient')
52-
import { getErrorId } from './utils'
53-
54-
// Right now the only difference between the token client and the IAM client for codewhsiperer is the difference in function name
5559
// This abstract class can grow in the future to account for any additional changes across the clients
5660
export abstract class CodeWhispererServiceBase {
5761
protected readonly codeWhispererRegion
@@ -134,7 +138,6 @@ export class CodeWhispererServiceIAM extends CodeWhispererServiceBase {
134138
// add cancellation check
135139
// add error check
136140
if (this.customizationArn) request = { ...request, customizationArn: this.customizationArn }
137-
138141
const response = await this.client.generateRecommendations(request).promise()
139142
const responseContext = {
140143
requestId: response?.$response?.requestId,
@@ -148,6 +151,7 @@ export class CodeWhispererServiceIAM extends CodeWhispererServiceBase {
148151

149152
return {
150153
suggestions: response.recommendations as Suggestion[],
154+
suggestionType: SuggestionType.COMPLETION,
151155
responseContext,
152156
}
153157
}
@@ -172,6 +176,7 @@ export class CodeWhispererServiceToken extends CodeWhispererServiceBase {
172176
sdkInitializator: SDKInitializator
173177
) {
174178
super(codeWhispererRegion, codeWhispererEndpoint)
179+
175180
const options: CodeWhispererTokenClientConfigurationOptions = {
176181
region: this.codeWhispererRegion,
177182
endpoint: this.codeWhispererEndpoint,
@@ -193,7 +198,23 @@ export class CodeWhispererServiceToken extends CodeWhispererServiceBase {
193198
throw err
194199
}
195200
})
196-
req.on('complete', () => {
201+
req.on('complete', response => {
202+
const requestStartTime = req.startTime?.getTime() || 0
203+
const requestEndTime = new Date().getTime()
204+
const latency = requestStartTime > 0 ? requestEndTime - requestStartTime : 0
205+
206+
const requestBody = req.httpRequest.body ? JSON.parse(String(req.httpRequest.body)) : {}
207+
this.completeRequest(req)
208+
})
209+
req.on('error', async (error, response) => {
210+
const requestStartTime = req.startTime?.getTime() || 0
211+
const requestEndTime = new Date().getTime()
212+
const latency = requestStartTime > 0 ? requestEndTime - requestStartTime : 0
213+
214+
const requestBody = req.httpRequest.body ? JSON.parse(String(req.httpRequest.body)) : {}
215+
this.completeRequest(req)
216+
})
217+
req.on('error', () => {
197218
this.completeRequest(req)
198219
})
199220
req.on('error', () => {
@@ -219,23 +240,40 @@ export class CodeWhispererServiceToken extends CodeWhispererServiceBase {
219240
// add cancellation check
220241
// add error check
221242
if (this.customizationArn) request.customizationArn = this.customizationArn
222-
223243
const response = await this.client.generateCompletions(this.withProfileArn(request)).promise()
224244
const responseContext = {
225245
requestId: response?.$response?.requestId,
226246
codewhispererSessionId: response?.$response?.httpResponse?.headers['x-amzn-sessionid'],
227247
nextToken: response.nextToken,
228248
}
249+
return this.mapCodeWhispererApiResponseToSuggestion(response, responseContext)
250+
}
229251

230-
for (const recommendation of response?.completions ?? []) {
231-
Object.assign(recommendation, { itemId: this.generateItemId() })
232-
}
252+
private mapCodeWhispererApiResponseToSuggestion(
253+
apiResponse: GenerateCompletionsResponse,
254+
responseContext: ResponseContext
255+
): GenerateSuggestionsResponse {
256+
if (apiResponse?.predictions && apiResponse.predictions.length > 0) {
257+
const suggestionType = apiResponse.predictions[0].edit ? SuggestionType.EDIT : SuggestionType.COMPLETION
258+
const predictionType = suggestionType === SuggestionType.COMPLETION ? 'completion' : 'edit'
233259

260+
return {
261+
suggestions: apiResponse.predictions.map(prediction => ({
262+
content: prediction[predictionType]?.content ?? '',
263+
references: prediction[predictionType]?.references ?? [],
264+
itemId: this.generateItemId(),
265+
})),
266+
suggestionType,
267+
responseContext,
268+
}
269+
}
234270
return {
235-
suggestions: response.completions as Suggestion[],
271+
suggestions: apiResponse.completions as Suggestion[],
272+
suggestionType: SuggestionType.COMPLETION,
236273
responseContext,
237274
}
238275
}
276+
239277
public async codeModernizerCreateUploadUrl(
240278
request: CodeWhispererTokenClient.CreateUploadUrlRequest
241279
): Promise<CodeWhispererTokenClient.CreateUploadUrlResponse> {

0 commit comments

Comments
 (0)