diff --git a/packages/amazonq/.changes/next-release/Removal-319fc7c8-22e0-44f1-a636-2f4040689b32.json b/packages/amazonq/.changes/next-release/Removal-319fc7c8-22e0-44f1-a636-2f4040689b32.json new file mode 100644 index 00000000000..4f179108afa --- /dev/null +++ b/packages/amazonq/.changes/next-release/Removal-319fc7c8-22e0-44f1-a636-2f4040689b32.json @@ -0,0 +1,4 @@ +{ + "type": "Removal", + "description": "Reverted prefetch logic to enable more stable inline completion" +} diff --git a/packages/amazonq/test/unit/codewhisperer/commands/onAcceptance.test.ts b/packages/amazonq/test/unit/codewhisperer/commands/onAcceptance.test.ts index a94bbd5a3fe..5af3252ec82 100644 --- a/packages/amazonq/test/unit/codewhisperer/commands/onAcceptance.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/commands/onAcceptance.test.ts @@ -9,21 +9,19 @@ import * as sinon from 'sinon' import { onAcceptance, AcceptedSuggestionEntry, - CodeWhispererSessionState, + session, CodeWhispererTracker, RecommendationHandler, AuthUtil, - CodeWhispererSession, } from 'aws-core-vscode/codewhisperer' import { resetCodeWhispererGlobalVariables, createMockTextEditor } from 'aws-core-vscode/test' import { assertTelemetryCurried } from 'aws-core-vscode/test' describe('onAcceptance', function () { - let session: CodeWhispererSession describe('onAcceptance', function () { beforeEach(async function () { - session = CodeWhispererSessionState.instance.getSession() await resetCodeWhispererGlobalVariables() + session.reset() }) afterEach(function () { diff --git a/packages/amazonq/test/unit/codewhisperer/commands/onInlineAcceptance.test.ts b/packages/amazonq/test/unit/codewhisperer/commands/onInlineAcceptance.test.ts index 6cff08c2ded..ae02e7bd7c3 100644 --- a/packages/amazonq/test/unit/codewhisperer/commands/onInlineAcceptance.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/commands/onInlineAcceptance.test.ts @@ -8,22 +8,15 @@ import * as vscode from 'vscode' import * as sinon from 'sinon' import { resetCodeWhispererGlobalVariables, createMockTextEditor } from 'aws-core-vscode/test' import { assertTelemetryCurried } from 'aws-core-vscode/test' -import { - onInlineAcceptance, - RecommendationHandler, - AuthUtil, - CodeWhispererSessionState, - CodeWhispererSession, -} from 'aws-core-vscode/codewhisperer' +import { onInlineAcceptance, RecommendationHandler, AuthUtil, session } from 'aws-core-vscode/codewhisperer' import { globals } from 'aws-core-vscode/shared' import { extensionVersion } from 'aws-core-vscode/shared' describe('onInlineAcceptance', function () { - let session: CodeWhispererSession describe('onInlineAcceptance', function () { beforeEach(async function () { - session = CodeWhispererSessionState.instance.getSession() await resetCodeWhispererGlobalVariables() + session.reset() }) afterEach(function () { diff --git a/packages/amazonq/test/unit/codewhisperer/service/completionProvider.test.ts b/packages/amazonq/test/unit/codewhisperer/service/completionProvider.test.ts index a7f87a346ad..956999d64ad 100644 --- a/packages/amazonq/test/unit/codewhisperer/service/completionProvider.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/service/completionProvider.test.ts @@ -12,7 +12,7 @@ import { getLabel, Recommendation, RecommendationHandler, - CodeWhispererSessionState, + session, } from 'aws-core-vscode/codewhisperer' import { createMockDocument, resetCodeWhispererGlobalVariables } from 'aws-core-vscode/test' @@ -39,7 +39,6 @@ describe('completionProviderService', function () { describe('getCompletionItem', function () { it('should return targetCompletionItem given input', function () { - const session = CodeWhispererSessionState.instance.getSession() session.startPos = new vscode.Position(0, 0) RecommendationHandler.instance.requestId = 'mock_requestId_getCompletionItem' session.sessionId = 'mock_sessionId_getCompletionItem' @@ -96,7 +95,6 @@ describe('completionProviderService', function () { describe('getCompletionItems', function () { it('should return completion items for each non-empty recommendation', async function () { - const session = CodeWhispererSessionState.instance.getSession() session.recommendations = [ { content: "\n\t\tconsole.log('Hello world!');\n\t}" }, { content: '\nvar a = 10' }, @@ -108,7 +106,6 @@ describe('completionProviderService', function () { }) it('should return empty completion items when recommendation is empty', async function () { - const session = CodeWhispererSessionState.instance.getSession() session.recommendations = [] const mockPosition = new vscode.Position(14, 83) const mockDocument = createMockDocument() diff --git a/packages/amazonq/test/unit/codewhisperer/service/inlineCompletionService.test.ts b/packages/amazonq/test/unit/codewhisperer/service/inlineCompletionService.test.ts index f1618c83dac..18fd7d2f21b 100644 --- a/packages/amazonq/test/unit/codewhisperer/service/inlineCompletionService.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/service/inlineCompletionService.test.ts @@ -14,7 +14,7 @@ import { CodeSuggestionsState, ConfigurationEntry, CWInlineCompletionItemProvider, - CodeWhispererSessionState, + session, AuthUtil, listCodeWhispererCommandsId, DefaultCodeWhispererClient, @@ -46,7 +46,6 @@ describe('inlineCompletionService', function () { }) it('should call checkAndResetCancellationTokens before showing inline and next token to be null', async function () { - const session = CodeWhispererSessionState.instance.getSession() const mockEditor = createMockTextEditor() sinon.stub(RecommendationHandler.instance, 'getRecommendations').resolves({ result: 'Succeeded', @@ -71,7 +70,6 @@ describe('inlineCompletionService', function () { describe('clearInlineCompletionStates', function () { it('should remove inline reference and recommendations', async function () { - const session = CodeWhispererSessionState.instance.getSession() const fakeReferences = [ { message: '', diff --git a/packages/amazonq/test/unit/codewhisperer/service/recommendationHandler.test.ts b/packages/amazonq/test/unit/codewhisperer/service/recommendationHandler.test.ts index 9668fa4c5a4..d8855796df0 100644 --- a/packages/amazonq/test/unit/codewhisperer/service/recommendationHandler.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/service/recommendationHandler.test.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode' import * as sinon from 'sinon' import { ReferenceInlineProvider, - CodeWhispererSessionState, + session, AuthUtil, DefaultCodeWhispererClient, RecommendationsList, @@ -55,7 +55,6 @@ describe('recommendationHandler', function () { }) it('should assign correct recommendations given input', async function () { - const session = CodeWhispererSessionState.instance.getSession() assert.strictEqual(CodeWhispererCodeCoverageTracker.instances.size, 0) assert.strictEqual( CodeWhispererCodeCoverageTracker.getTracker(mockEditor.document.languageId)?.serviceInvocationCount, @@ -75,7 +74,7 @@ describe('recommendationHandler', function () { } const handler = new RecommendationHandler() sinon.stub(handler, 'getServerResponse').resolves(mockServerResult) - await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, session, 'Enter', false) + await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, 'Enter', false) const actual = session.recommendations const expected: RecommendationsList = [{ content: "print('Hello World!')" }, { content: '' }] assert.deepStrictEqual(actual, expected) @@ -86,7 +85,6 @@ describe('recommendationHandler', function () { }) it('should assign request id correctly', async function () { - const session = CodeWhispererSessionState.instance.getSession() const mockServerResult = { recommendations: [{ content: "print('Hello World!')" }, { content: '' }], $response: { @@ -101,7 +99,7 @@ describe('recommendationHandler', function () { const handler = new RecommendationHandler() sinon.stub(handler, 'getServerResponse').resolves(mockServerResult) sinon.stub(handler, 'isCancellationRequested').returns(false) - await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, session, 'Enter', false) + await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, 'Enter', false) assert.strictEqual(handler.requestId, 'test_request') assert.strictEqual(session.sessionId, 'test_request') assert.strictEqual(session.triggerType, 'AutoTrigger') @@ -130,10 +128,9 @@ describe('recommendationHandler', function () { strategy: 'empty', }) sinon.stub(performance, 'now').returns(0.0) - const session = CodeWhispererSessionState.instance.getSession() session.startPos = new vscode.Position(1, 0) session.startCursorOffset = 2 - await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, session, 'Enter') + await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, 'Enter') const assertTelemetry = assertTelemetryCurried('codewhisperer_serviceInvocation') assertTelemetry({ codewhispererRequestId: 'test_request', @@ -170,11 +167,10 @@ describe('recommendationHandler', function () { const handler = new RecommendationHandler() sinon.stub(handler, 'getServerResponse').resolves(mockServerResult) sinon.stub(performance, 'now').returns(0.0) - const session = CodeWhispererSessionState.instance.getSession() session.startPos = new vscode.Position(1, 0) session.requestIdList = ['test_request_empty'] session.startCursorOffset = 2 - await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, session, 'Enter') + await handler.getRecommendations(mockClient, mockEditor, 'AutoTrigger', config, 'Enter') const assertTelemetry = assertTelemetryCurried('codewhisperer_userDecision') assertTelemetry({ codewhispererRequestId: 'test_request_empty', @@ -196,7 +192,6 @@ describe('recommendationHandler', function () { sinon.restore() }) it('should return true if any response is not empty', function () { - const session = CodeWhispererSessionState.instance.getSession() const handler = new RecommendationHandler() session.recommendations = [ { @@ -209,14 +204,12 @@ describe('recommendationHandler', function () { }) it('should return false if response is empty', function () { - const session = CodeWhispererSessionState.instance.getSession() const handler = new RecommendationHandler() session.recommendations = [] assert.ok(!handler.isValidResponse()) }) it('should return false if all response has no string length', function () { - const session = CodeWhispererSessionState.instance.getSession() const handler = new RecommendationHandler() session.recommendations = [{ content: '' }, { content: '' }] assert.ok(!handler.isValidResponse()) @@ -229,7 +222,6 @@ describe('recommendationHandler', function () { }) it('should set the completion type to block given a multi-line suggestion', function () { - const session = CodeWhispererSessionState.instance.getSession() session.setCompletionType(0, { content: 'test\n\n \t\r\nanother test' }) assert.strictEqual(session.getCompletionType(0), 'Block') @@ -241,7 +233,6 @@ describe('recommendationHandler', function () { }) it('should set the completion type to line given a single-line suggestion', function () { - const session = CodeWhispererSessionState.instance.getSession() session.setCompletionType(0, { content: 'test' }) assert.strictEqual(session.getCompletionType(0), 'Line') @@ -250,7 +241,6 @@ describe('recommendationHandler', function () { }) it('should set the completion type to line given a multi-line completion but only one-lien of non-blank sequence', function () { - const session = CodeWhispererSessionState.instance.getSession() session.setCompletionType(0, { content: 'test\n\t' }) assert.strictEqual(session.getCompletionType(0), 'Line') @@ -267,7 +257,6 @@ describe('recommendationHandler', function () { describe('on event change', async function () { beforeEach(function () { - const session = CodeWhispererSessionState.instance.getSession() const fakeReferences = [ { message: '', @@ -285,14 +274,12 @@ describe('recommendationHandler', function () { }) it('should remove inline reference onEditorChange', async function () { - const session = CodeWhispererSessionState.instance.getSession() session.sessionId = 'aSessionId' RecommendationHandler.instance.requestId = 'aRequestId' await RecommendationHandler.instance.onEditorChange() assert.strictEqual(ReferenceInlineProvider.instance.refs.length, 0) }) it('should remove inline reference onFocusChange', async function () { - const session = CodeWhispererSessionState.instance.getSession() session.sessionId = 'aSessionId' RecommendationHandler.instance.requestId = 'aRequestId' await RecommendationHandler.instance.onFocusChange() diff --git a/packages/amazonq/test/unit/codewhisperer/service/telemetry.test.ts b/packages/amazonq/test/unit/codewhisperer/service/telemetry.test.ts index 797de801428..0f1429f130b 100644 --- a/packages/amazonq/test/unit/codewhisperer/service/telemetry.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/service/telemetry.test.ts @@ -22,7 +22,7 @@ import { invokeRecommendation, ConfigurationEntry, RecommendationHandler, - CodeWhispererSessionState, + session, vsCodeCursorUpdateDelay, AuthUtil, } from 'aws-core-vscode/codewhisperer' @@ -36,7 +36,6 @@ type CodeWhispererResponse = ListRecommendationsResponse & { let tempFolder: string describe.skip('CodeWhisperer telemetry', async function () { - const session = CodeWhispererSessionState.instance.getSession() let sandbox: sinon.SinonSandbox let client: DefaultCodeWhispererClient @@ -520,7 +519,6 @@ async function manualTrigger( // Note: RecommendationHandler.isSuggestionVisible seems not to work well, hence not using it async function waitUntilSuggestionSeen(index: number = 0) { - const session = CodeWhispererSessionState.instance.getSession() const state = await waitUntil( async () => { const r = session.getSuggestionState(index) diff --git a/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts b/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts index 99f2585a285..e042b1d43a2 100644 --- a/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts @@ -5,7 +5,7 @@ import assert from 'assert' import { assertTelemetryCurried, resetCodeWhispererGlobalVariables } from 'aws-core-vscode/test' -import { TelemetryHelper, Completion, CodeWhispererSessionState } from 'aws-core-vscode/codewhisperer' +import { TelemetryHelper, Completion, session } from 'aws-core-vscode/codewhisperer' import { CodewhispererCompletionType, CodewhispererSuggestionState, @@ -39,7 +39,6 @@ function aCompletion(): Completion { } describe('telemetryHelper', function () { - const session = CodeWhispererSessionState.instance.getSession() describe('clientComponentLatency', function () { let sut: TelemetryHelper @@ -49,7 +48,6 @@ describe('telemetryHelper', function () { afterEach(function () { sinon.restore() - session.reset() }) it('resetClientComponentLatencyTime should reset state variables', function () { diff --git a/packages/core/src/codewhisperer/client/codewhisperer.ts b/packages/core/src/codewhisperer/client/codewhisperer.ts index 68331c53ef4..1fad505cea3 100644 --- a/packages/core/src/codewhisperer/client/codewhisperer.ts +++ b/packages/core/src/codewhisperer/client/codewhisperer.ts @@ -17,7 +17,7 @@ import { isSsoConnection } from '../../auth/connection' import { pageableToCollection } from '../../shared/utilities/collectionUtils' import apiConfig = require('./service-2.json') import userApiConfig = require('./user-service-2.json') -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import { getLogger } from '../../shared/logger/logger' import { indent } from '../../shared/utilities/textUtilities' import { keepAliveHeader } from './agent' @@ -133,7 +133,6 @@ export class DefaultCodeWhispererClient { } async createUserSdkClient(maxRetries?: number): Promise { - const session = CodeWhispererSessionState.instance.getSession() const isOptedOut = CodeWhispererSettings.instance.isOptoutEnabled() session.setFetchCredentialStart() const bearerToken = await AuthUtil.instance.getBearerToken() diff --git a/packages/core/src/codewhisperer/commands/invokeRecommendation.ts b/packages/core/src/codewhisperer/commands/invokeRecommendation.ts index e1f17e8a909..37fcb965774 100644 --- a/packages/core/src/codewhisperer/commands/invokeRecommendation.ts +++ b/packages/core/src/codewhisperer/commands/invokeRecommendation.ts @@ -8,7 +8,7 @@ import { vsCodeState, ConfigurationEntry } from '../models/model' import { resetIntelliSenseState } from '../util/globalStateUtil' import { DefaultCodeWhispererClient } from '../client/codewhisperer' import { RecommendationHandler } from '../service/recommendationHandler' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import { RecommendationService } from '../service/recommendationService' /** @@ -33,7 +33,6 @@ export async function invokeRecommendation( /** * When using intelliSense, if invocation position changed, reject previous active recommendations */ - const session = CodeWhispererSessionState.instance.getSession() if (vsCodeState.isIntelliSenseActive && editor.selection.active !== session.startPos) { resetIntelliSenseState( config.isManualTriggerEnabled, diff --git a/packages/core/src/codewhisperer/commands/onInlineAcceptance.ts b/packages/core/src/codewhisperer/commands/onInlineAcceptance.ts index a0845892dbe..50af478ba57 100644 --- a/packages/core/src/codewhisperer/commands/onInlineAcceptance.ts +++ b/packages/core/src/codewhisperer/commands/onInlineAcceptance.ts @@ -26,7 +26,7 @@ import { import { ReferenceLogViewProvider } from '../service/referenceLogViewProvider' import { ReferenceHoverProvider } from '../service/referenceHoverProvider' import { ImportAdderProvider } from '../service/importAdderProvider' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import path from 'path' import { RecommendationService } from '../service/recommendationService' import { Container } from '../service/serviceContainer' @@ -89,7 +89,6 @@ export async function onInlineAcceptance(acceptanceEntry: OnRecommendationAccept const end = acceptanceEntry.editor.selection.active vsCodeState.isCodeWhispererEditing = true - const session = CodeWhispererSessionState.instance.getSession() /** * Mitigation to right context handling mainly for auto closing bracket use case */ @@ -143,17 +142,5 @@ export async function onInlineAcceptance(acceptanceEntry: OnRecommendationAccept } RecommendationHandler.instance.reportUserDecisions(acceptanceEntry.acceptIndex) - await promoteNextSessionIfAvailable(acceptanceEntry) - } -} - -async function promoteNextSessionIfAvailable(acceptanceEntry: OnRecommendationAcceptanceEntry) { - if (acceptanceEntry.acceptIndex === 0 && acceptanceEntry.editor) { - const nextSession = CodeWhispererSessionState.instance.getNextSession() - nextSession.startPos = acceptanceEntry.editor.selection.active - CodeWhispererSessionState.instance.setSession(nextSession) - if (nextSession.recommendations.length) { - await RecommendationHandler.instance.tryShowRecommendation() - } } } diff --git a/packages/core/src/codewhisperer/index.ts b/packages/core/src/codewhisperer/index.ts index 3b20e66a3db..565e9e3c238 100644 --- a/packages/core/src/codewhisperer/index.ts +++ b/packages/core/src/codewhisperer/index.ts @@ -58,7 +58,7 @@ export { onAcceptance } from './commands/onAcceptance' export { CodeWhispererTracker } from './tracker/codewhispererTracker' export { RecommendationHandler } from './service/recommendationHandler' export { CodeWhispererUserGroupSettings } from './util/userGroupUtil' -export { CodeWhispererSessionState, CodeWhispererSession } from './util/codeWhispererSession' +export { session } from './util/codeWhispererSession' export { onInlineAcceptance } from './commands/onInlineAcceptance' export { stopTransformByQ } from './commands/startTransformByQ' export { getCompletionItems, getCompletionItem, getLabel } from './service/completionProvider' diff --git a/packages/core/src/codewhisperer/service/completionProvider.ts b/packages/core/src/codewhisperer/service/completionProvider.ts index df4f2f98466..226d04dec2b 100644 --- a/packages/core/src/codewhisperer/service/completionProvider.ts +++ b/packages/core/src/codewhisperer/service/completionProvider.ts @@ -9,13 +9,12 @@ import { runtimeLanguageContext } from '../util/runtimeLanguageContext' import { Recommendation } from '../client/codewhisperer' import { LicenseUtil } from '../util/licenseUtil' import { RecommendationHandler } from './recommendationHandler' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import path from 'path' /** * completion provider for intelliSense popup */ export function getCompletionItems(document: vscode.TextDocument, position: vscode.Position) { - const session = CodeWhispererSessionState.instance.getSession() const completionItems: vscode.CompletionItem[] = [] for (const [index, recommendation] of session.recommendations.entries()) { completionItems.push(getCompletionItem(document, position, recommendation, index)) @@ -30,7 +29,6 @@ export function getCompletionItem( recommendationDetail: Recommendation, recommendationIndex: number ) { - const session = CodeWhispererSessionState.instance.getSession() const start = session.startPos const range = new vscode.Range(start, start) const recommendation = recommendationDetail.content diff --git a/packages/core/src/codewhisperer/service/inlineCompletionItemProvider.ts b/packages/core/src/codewhisperer/service/inlineCompletionItemProvider.ts index dedd2531901..a6c424c321d 100644 --- a/packages/core/src/codewhisperer/service/inlineCompletionItemProvider.ts +++ b/packages/core/src/codewhisperer/service/inlineCompletionItemProvider.ts @@ -5,7 +5,7 @@ import vscode, { Position } from 'vscode' import { getPrefixSuffixOverlap } from '../util/commonUtil' import { Recommendation } from '../client/codewhisperer' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import { TelemetryHelper } from '../util/telemetryHelper' import { runtimeLanguageContext } from '../util/runtimeLanguageContext' import { ReferenceInlineProvider } from './referenceInlineProvider' @@ -21,7 +21,6 @@ export class CWInlineCompletionItemProvider implements vscode.InlineCompletionIt private requestId: string private startPos: Position private nextToken: string - private session = CodeWhispererSessionState.instance.getSession() private _onDidShow: vscode.EventEmitter = new vscode.EventEmitter() public readonly onDidShow: vscode.Event = this._onDidShow.event @@ -101,8 +100,8 @@ export class CWInlineCompletionItemProvider implements vscode.InlineCompletionIt const effectiveStart = document.positionAt(document.offsetAt(start) + prefix.length) const truncatedSuggestion = this.truncateOverlapWithRightContext(document, r.content, end) if (truncatedSuggestion.length === 0) { - if (this.session.getSuggestionState(index) !== 'Showed') { - this.session.setSuggestionState(index, 'Discard') + if (session.getSuggestionState(index) !== 'Showed') { + session.setSuggestionState(index, 'Discard') } return undefined } @@ -119,9 +118,9 @@ export class CWInlineCompletionItemProvider implements vscode.InlineCompletionIt index, truncatedSuggestion, this.requestId, - this.session.sessionId, - this.session.triggerType, - this.session.getCompletionType(index), + session.sessionId, + session.triggerType, + session.getCompletionType(index), runtimeLanguageContext.getLanguageContext(document.languageId, path.extname(document.fileName)) .language, r.references, @@ -156,22 +155,22 @@ export class CWInlineCompletionItemProvider implements vscode.InlineCompletionIt const end = position const iteratingIndexes = this.getIteratingIndexes() const prefix = document.getText(new vscode.Range(start, end)).replace(/\r\n/g, '\n') - const matchedCount = this.session.recommendations.filter( + const matchedCount = session.recommendations.filter( (r) => r.content.length > 0 && r.content.startsWith(prefix) && r.content !== prefix ).length for (const i of iteratingIndexes) { - const r = this.recommendations[i] + const r = session.recommendations[i] const item = this.getInlineCompletionItem(document, r, start, end, i, prefix) if (item === undefined) { continue } this.activeItemIndex = i - this.session.setSuggestionState(i, 'Showed') + session.setSuggestionState(i, 'Showed') ReferenceInlineProvider.instance.setInlineReference(this.startPos.line, r.content, r.references) ImportAdderProvider.instance.onShowRecommendation(document, this.startPos.line, r) this.nextMove = 0 TelemetryHelper.instance.setFirstSuggestionShowTime() - this.session.setPerceivedLatency() + session.setPerceivedLatency() UserWrittenCodeTracker.instance.onQStartsMakingEdits() this._onDidShow.fire() if (matchedCount >= 2 || this.nextToken !== '') { diff --git a/packages/core/src/codewhisperer/service/inlineCompletionService.ts b/packages/core/src/codewhisperer/service/inlineCompletionService.ts index 9cd0dda781d..715fd93ad2d 100644 --- a/packages/core/src/codewhisperer/service/inlineCompletionService.ts +++ b/packages/core/src/codewhisperer/service/inlineCompletionService.ts @@ -16,7 +16,7 @@ import { shared } from '../../shared/utilities/functionUtils' import { ClassifierTrigger } from './classifierTrigger' import { getSelectedCustomization } from '../util/customizationUtil' import { codicon, getIcon } from '../../shared/icons' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import { noSuggestions } from '../models/constants' import { Commands } from '../../shared/vscode/commands2' import { listCodeWhispererCommandsId } from '../ui/statusBarMenu' @@ -119,7 +119,6 @@ export class InlineCompletionService { errorMessage: undefined, recommendationCount: 0, } - const session = CodeWhispererSessionState.instance.getSession() try { let page = 0 while (page < this.maxPage) { @@ -128,7 +127,6 @@ export class InlineCompletionService { editor, triggerType, config, - session, autoTriggerType, true, page diff --git a/packages/core/src/codewhisperer/service/recommendationHandler.ts b/packages/core/src/codewhisperer/service/recommendationHandler.ts index bdbf21074bd..99baf680d0a 100644 --- a/packages/core/src/codewhisperer/service/recommendationHandler.ts +++ b/packages/core/src/codewhisperer/service/recommendationHandler.ts @@ -5,15 +5,10 @@ import * as vscode from 'vscode' import { extensionVersion } from '../../shared/vscode/env' -import { - RecommendationsList, - DefaultCodeWhispererClient, - CognitoCredentialsError, - ListRecommendationsRequest, -} from '../client/codewhisperer' +import { RecommendationsList, DefaultCodeWhispererClient, CognitoCredentialsError } from '../client/codewhisperer' import * as EditorContext from '../util/editorContext' import * as CodeWhispererConstants from '../models/constants' -import { CodeSuggestionsState, ConfigurationEntry, GetRecommendationsResponse, vsCodeState } from '../models/model' +import { ConfigurationEntry, GetRecommendationsResponse, vsCodeState } from '../models/model' import { runtimeLanguageContext } from '../util/runtimeLanguageContext' import { AWSError } from 'aws-sdk' import { isAwsError } from '../../shared/errors' @@ -36,7 +31,7 @@ import { import { CodeWhispererCodeCoverageTracker } from '../tracker/codewhispererCodeCoverageTracker' import { invalidCustomizationMessage } from '../models/constants' import { getSelectedCustomization, switchToBaseCustomizationAndNotify } from '../util/customizationUtil' -import { CodeWhispererSessionState, CodeWhispererSession } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import { Commands } from '../../shared/vscode/commands2' import globals from '../../shared/extensionGlobals' import { noSuggestions, updateInlineLockKey } from '../models/constants' @@ -49,8 +44,6 @@ import { indent } from '../../shared/utilities/textUtilities' import path from 'path' import { isIamConnection } from '../../auth/connection' import { UserWrittenCodeTracker } from '../tracker/userWrittenCodeTracker' -import * as codewhispererClient from '../client/codewhisperer' -import { CodeWhispererSettings } from '../util/codewhispererSettings' /** * This class is for getRecommendation/listRecommendation API calls and its states @@ -110,7 +103,6 @@ export class RecommendationHandler { } isValidResponse(): boolean { - const session = CodeWhispererSessionState.instance.getSession() return session.recommendations.some((r) => r.content.trim() !== '') } @@ -162,22 +154,14 @@ export class RecommendationHandler { editor: vscode.TextEditor, triggerType: CodewhispererTriggerType, config: ConfigurationEntry, - session: CodeWhispererSession, autoTriggerType?: CodewhispererAutomatedTriggerType, pagination: boolean = true, page: number = 0, - generate: boolean = isIamConnection(AuthUtil.instance.conn), - isNextSession: boolean = false + generate: boolean = isIamConnection(AuthUtil.instance.conn) ): Promise { let invocationResult: 'Succeeded' | 'Failed' = 'Failed' let errorMessage: string | undefined = undefined let errorCode: string | undefined = undefined - let currentSession = session - if (isNextSession) { - getLogger().debug('pre-fetching next recommendation for model routing') - currentSession = new CodeWhispererSession() - CodeWhispererSessionState.instance.setNextSession(currentSession) - } if (!editor) { return Promise.resolve({ @@ -194,60 +178,43 @@ export class RecommendationHandler { let latency = 0 let nextToken = '' let shouldRecordServiceInvocation = true - currentSession.language = runtimeLanguageContext.getLanguageContext( + session.language = runtimeLanguageContext.getLanguageContext( editor.document.languageId, path.extname(editor.document.fileName) ).language - currentSession.taskType = await this.getTaskTypeFromEditorFileName(editor.document.fileName) + session.taskType = await this.getTaskTypeFromEditorFileName(editor.document.fileName) if (pagination && !generate) { if (page === 0) { - if (isNextSession) { - const request = session.requestContext.request as ListRecommendationsRequest - currentSession.requestContext = { - request: { - ...request, - fileContext: { - ...request.fileContext, - leftFileContent: `${request.fileContext.leftFileContent}${session.recommendations[0].content}`, - }, - nextToken: undefined, - }, - supplementalMetadata: currentSession.requestContext.supplementalMetadata, - } - } else { - currentSession.requestContext = await EditorContext.buildListRecommendationRequest( - editor as vscode.TextEditor, - this.nextToken, - config.isSuggestionsWithCodeReferencesEnabled - ) - } + session.requestContext = await EditorContext.buildListRecommendationRequest( + editor as vscode.TextEditor, + this.nextToken, + config.isSuggestionsWithCodeReferencesEnabled + ) } else { - currentSession.requestContext = { + session.requestContext = { request: { - ...currentSession.requestContext.request, + ...session.requestContext.request, // Putting nextToken assignment in the end so it overwrites the existing nextToken nextToken: this.nextToken, }, - supplementalMetadata: currentSession.requestContext.supplementalMetadata, + supplementalMetadata: session.requestContext.supplementalMetadata, } } - // } } else { - currentSession.requestContext = await EditorContext.buildGenerateRecommendationRequest( - editor as vscode.TextEditor - ) + session.requestContext = await EditorContext.buildGenerateRecommendationRequest(editor as vscode.TextEditor) } - const request = currentSession.requestContext.request + const request = session.requestContext.request + // record preprocessing end time TelemetryHelper.instance.setPreprocessEndTime() // set start pos for non pagination call or first pagination call if (!pagination || (pagination && page === 0)) { - currentSession.startPos = editor.selection.active - currentSession.startCursorOffset = editor.document.offsetAt(currentSession.startPos) - currentSession.leftContextOfCurrentLine = EditorContext.getLeftContext(editor, currentSession.startPos.line) - currentSession.triggerType = triggerType - currentSession.autoTriggerType = autoTriggerType + session.startPos = editor.selection.active + session.startCursorOffset = editor.document.offsetAt(session.startPos) + session.leftContextOfCurrentLine = EditorContext.getLeftContext(editor, session.startPos.line) + session.triggerType = triggerType + session.autoTriggerType = autoTriggerType /** * Validate request @@ -288,7 +255,7 @@ export class RecommendationHandler { sessionId = resp?.$response?.httpResponse?.headers['x-amzn-sessionid'] TelemetryHelper.instance.setFirstResponseRequestId(requestId) if (page === 0) { - currentSession.setTimeToFirstRecommendation(performance.now()) + session.setTimeToFirstRecommendation(performance.now()) } if (nextToken === '') { TelemetryHelper.instance.setAllPaginationEndTime() @@ -334,9 +301,9 @@ export class RecommendationHandler { vscode version: '${vscode.version}', extension version: '${extensionVersion}', filename: '${EditorContext.getFileName(editor)}', - left context of line: '${currentSession.leftContextOfCurrentLine}', - line number: ${currentSession.startPos.line}, - character location: ${currentSession.startPos.character}, + left context of line: '${session.leftContextOfCurrentLine}', + line number: ${session.startPos.line}, + character location: ${session.startPos.character}, latency: ${latency} ms. Recommendations:`, 4, @@ -344,11 +311,11 @@ export class RecommendationHandler { ).trimStart() for (const [index, item] of recommendations.entries()) { msg += `\n ${index.toString().padStart(2, '0')}: ${indent(item.content, 8, true).trim()}` - currentSession.requestIdList.push(requestId) + session.requestIdList.push(requestId) } getLogger().debug(msg) if (invocationResult === 'Succeeded') { - CodeWhispererCodeCoverageTracker.getTracker(currentSession.language)?.incrementServiceInvocationCount() + CodeWhispererCodeCoverageTracker.getTracker(session.language)?.incrementServiceInvocationCount() UserWrittenCodeTracker.instance.onQFeatureInvoked() } else { if ( @@ -364,7 +331,6 @@ export class RecommendationHandler { editor, triggerType, config, - currentSession, autoTriggerType, pagination, page, @@ -377,86 +343,82 @@ export class RecommendationHandler { TelemetryHelper.instance.recordServiceInvocationTelemetry( requestId, sessionId, - currentSession.recommendations.length + recommendations.length - 1, + session.recommendations.length + recommendations.length - 1, invocationResult, latency, - currentSession.language, - currentSession.taskType, + session.language, + session.taskType, reason, - currentSession.requestContext.supplementalMetadata + session.requestContext.supplementalMetadata ) } } - if (!isNextSession && this.isCancellationRequested()) { + if (this.isCancellationRequested()) { return Promise.resolve({ result: invocationResult, errorMessage: errorMessage, - recommendationCount: currentSession.recommendations.length, + recommendationCount: session.recommendations.length, }) } const typedPrefix = editor.document - .getText(new vscode.Range(currentSession.startPos, editor.selection.active)) + .getText(new vscode.Range(session.startPos, editor.selection.active)) .replace('\r\n', '\n') if (recommendations.length > 0) { TelemetryHelper.instance.setTypeAheadLength(typedPrefix.length) // mark suggestions that does not match typeahead when arrival as Discard // these suggestions can be marked as Showed if typeahead can be removed with new inline API for (const [i, r] of recommendations.entries()) { - const recommendationIndex = i + currentSession.recommendations.length + const recommendationIndex = i + session.recommendations.length if ( !r.content.startsWith(typedPrefix) && - currentSession.getSuggestionState(recommendationIndex) === undefined + session.getSuggestionState(recommendationIndex) === undefined ) { - currentSession.setSuggestionState(recommendationIndex, 'Discard') + session.setSuggestionState(recommendationIndex, 'Discard') } - currentSession.setCompletionType(recommendationIndex, r) + session.setCompletionType(recommendationIndex, r) } - currentSession.recommendations = pagination - ? currentSession.recommendations.concat(recommendations) - : recommendations - if (isInlineCompletionEnabled() && this.hasAtLeastOneValidSuggestion(typedPrefix, currentSession)) { + session.recommendations = pagination ? session.recommendations.concat(recommendations) : recommendations + if (isInlineCompletionEnabled() && this.hasAtLeastOneValidSuggestion(typedPrefix)) { this._onDidReceiveRecommendation.fire() } } this.requestId = requestId - currentSession.sessionId = sessionId - if (!isNextSession) { - this.nextToken = nextToken - } + session.sessionId = sessionId + this.nextToken = nextToken // send Empty userDecision event if user receives no recommendations in this session at all. if (invocationResult === 'Succeeded' && nextToken === '') { // case 1: empty list of suggestion [] - if (currentSession.recommendations.length === 0) { - currentSession.requestIdList.push(requestId) + if (session.recommendations.length === 0) { + session.requestIdList.push(requestId) // Received an empty list of recommendations TelemetryHelper.instance.recordUserDecisionTelemetryForEmptyList( - currentSession.requestIdList, + session.requestIdList, sessionId, page, runtimeLanguageContext.getLanguageContext( editor.document.languageId, path.extname(editor.document.fileName) ).language, - currentSession.requestContext.supplementalMetadata + session.requestContext.supplementalMetadata ) } // case 2: non empty list of suggestion but with (a) empty content or (b) non-matching typeahead - else if (!this.hasAtLeastOneValidSuggestion(typedPrefix, currentSession)) { + else if (!this.hasAtLeastOneValidSuggestion(typedPrefix)) { this.reportUserDecisions(-1) } } return Promise.resolve({ result: invocationResult, errorMessage: errorMessage, - recommendationCount: currentSession.recommendations.length, + recommendationCount: session.recommendations.length, }) } - hasAtLeastOneValidSuggestion(typedPrefix: string, session: CodeWhispererSession): boolean { + hasAtLeastOneValidSuggestion(typedPrefix: string): boolean { return session.recommendations.some((r) => r.content.trim() !== '' && r.content.startsWith(typedPrefix)) } @@ -482,7 +444,6 @@ export class RecommendationHandler { * Clear recommendation state */ clearRecommendations() { - const session = CodeWhispererSessionState.instance.getSession() session.requestIdList = [] session.recommendations = [] session.suggestionStates = new Map() @@ -512,7 +473,6 @@ export class RecommendationHandler { } reportDiscardedUserDecisions() { - const session = CodeWhispererSessionState.instance.getSession() for (const [i, _] of session.recommendations.entries()) { session.setSuggestionState(i, 'Discard') } @@ -523,7 +483,6 @@ export class RecommendationHandler { * Emits telemetry reflecting user decision for current recommendation. */ reportUserDecisions(acceptIndex: number) { - const session = CodeWhispererSessionState.instance.getSession() if (session.sessionId === '' || this.requestId === '') { return } @@ -553,7 +512,6 @@ export class RecommendationHandler { showPrompt: boolean = false, response: GetRecommendationsResponse ): boolean { - const session = CodeWhispererSessionState.instance.getSession() const reject = () => { this.reportUserDecisions(-1) } @@ -635,11 +593,6 @@ export class RecommendationHandler { } async showRecommendation(indexShift: number, noSuggestionVisible: boolean = false) { - const session = CodeWhispererSessionState.instance.getSession() - - if (!indexShift && session.recommendations.length) { - await this.fetchNextRecommendations() - } await lock.acquire(updateInlineLockKey, async () => { if (!vscode.window.state.focused) { this.reportDiscardedUserDecisions() @@ -670,7 +623,7 @@ export class RecommendationHandler { } if (noSuggestionVisible) { await vscode.commands.executeCommand(`editor.action.inlineSuggest.trigger`) - this.sendPerceivedLatencyTelemetry(session) + this.sendPerceivedLatencyTelemetry() } }) } @@ -701,46 +654,7 @@ export class RecommendationHandler { return this.inlineCompletionProvider?.getActiveItemIndex !== undefined } - async getConfigEntry(): Promise { - const codewhispererSettings = CodeWhispererSettings.instance - const isShowMethodsEnabled: boolean = - vscode.workspace.getConfiguration('editor').get('suggest.showMethods') || false - const isAutomatedTriggerEnabled: boolean = CodeSuggestionsState.instance.isSuggestionsEnabled() - const isManualTriggerEnabled: boolean = true - const isSuggestionsWithCodeReferencesEnabled = codewhispererSettings.isSuggestionsWithCodeReferencesEnabled() - - return { - isShowMethodsEnabled, - isManualTriggerEnabled, - isAutomatedTriggerEnabled, - isSuggestionsWithCodeReferencesEnabled, - } - } - - async fetchNextRecommendations() { - const session = CodeWhispererSessionState.instance.getSession() - const client = new codewhispererClient.DefaultCodeWhispererClient() - const editor = vscode.window.activeTextEditor - if (!editor) { - return - } - - await this.getRecommendations( - client, - editor, - session.triggerType, - await this.getConfigEntry(), - session, - session.autoTriggerType, - true, - 0, - false, - true - ) - } - async tryShowRecommendation() { - const session = CodeWhispererSessionState.instance.getSession() const editor = vscode.window.activeTextEditor if (editor === undefined) { return @@ -769,7 +683,7 @@ export class RecommendationHandler { } } - private sendPerceivedLatencyTelemetry(session: CodeWhispererSession) { + private sendPerceivedLatencyTelemetry() { if (vscode.window.activeTextEditor) { const languageContext = runtimeLanguageContext.getLanguageContext( vscode.window.activeTextEditor.document.languageId, diff --git a/packages/core/src/codewhisperer/service/referenceLogViewProvider.ts b/packages/core/src/codewhisperer/service/referenceLogViewProvider.ts index 02055f0aded..9ec20b8cb44 100644 --- a/packages/core/src/codewhisperer/service/referenceLogViewProvider.ts +++ b/packages/core/src/codewhisperer/service/referenceLogViewProvider.ts @@ -10,7 +10,7 @@ import * as CodeWhispererConstants from '../models/constants' import { CodeWhispererSettings } from '../util/codewhispererSettings' import globals from '../../shared/extensionGlobals' import { AuthUtil } from '../util/authUtil' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' export class ReferenceLogViewProvider implements vscode.WebviewViewProvider { public static readonly viewType = 'aws.codeWhisperer.referenceLog' @@ -68,7 +68,6 @@ export class ReferenceLogViewProvider implements vscode.WebviewViewProvider { reference.recommendationContentSpan.start, reference.recommendationContentSpan.end ) - const session = CodeWhispererSessionState.instance.getSession() const firstCharLineNumber = editor.document.positionAt(session.startCursorOffset + reference.recommendationContentSpan.start).line + 1 diff --git a/packages/core/src/codewhisperer/util/codeWhispererSession.ts b/packages/core/src/codewhisperer/util/codeWhispererSession.ts index 12222903568..042cd947124 100644 --- a/packages/core/src/codewhisperer/util/codeWhispererSession.ts +++ b/packages/core/src/codewhisperer/util/codeWhispererSession.ts @@ -14,62 +14,41 @@ import { GenerateRecommendationsRequest, ListRecommendationsRequest, Recommendat import { Position } from 'vscode' import { CodeWhispererSupplementalContext, vsCodeState } from '../models/model' -export class CodeWhispererSessionState { - static #instance: CodeWhispererSessionState - session: CodeWhispererSession - nextSession: CodeWhispererSession - - constructor() { - this.session = new CodeWhispererSession() - this.nextSession = new CodeWhispererSession() - } - public static get instance() { - return (this.#instance ??= new CodeWhispererSessionState()) - } - - getSession() { - return this.session - } - - setSession(session: CodeWhispererSession) { - this.session = session - } - - getNextSession() { - return this.nextSession - } +class CodeWhispererSession { + static #instance: CodeWhispererSession - setNextSession(session: CodeWhispererSession) { - this.nextSession = session - } -} - -export class CodeWhispererSession { - sessionId: string = '' + // Per-session states + sessionId = '' requestIdList: string[] = [] - startPos: Position = new Position(0, 0) - startCursorOffset: number = 0 - leftContextOfCurrentLine: string = '' + startPos = new Position(0, 0) + startCursorOffset = 0 + leftContextOfCurrentLine = '' requestContext: { request: ListRecommendationsRequest | GenerateRecommendationsRequest supplementalMetadata: CodeWhispererSupplementalContext | undefined - } = { request: {} as any, supplementalMetadata: undefined } + } = { request: {} as any, supplementalMetadata: {} as any } language: CodewhispererLanguage = 'python' - taskType: CodewhispererGettingStartedTask | undefined = undefined + taskType: CodewhispererGettingStartedTask | undefined triggerType: CodewhispererTriggerType = 'OnDemand' - autoTriggerType: CodewhispererAutomatedTriggerType | undefined = undefined + autoTriggerType: CodewhispererAutomatedTriggerType | undefined + // Various states of recommendations recommendations: Recommendation[] = [] - suggestionStates: Map = new Map() - completionTypes: Map = new Map() + suggestionStates = new Map() + completionTypes = new Map() + // Some other variables for client component latency - fetchCredentialStartTime: number = 0 - sdkApiCallStartTime: number = 0 - invokeSuggestionStartTime: number = 0 - preprocessEndTime: number = 0 - timeToFirstRecommendation: number = 0 - firstSuggestionShowTime: number = 0 - perceivedLatency: number = 0 + fetchCredentialStartTime = 0 + sdkApiCallStartTime = 0 + invokeSuggestionStartTime = 0 + preprocessEndTime = 0 + timeToFirstRecommendation = 0 + firstSuggestionShowTime = 0 + perceivedLatency = 0 + + public static get instance() { + return (this.#instance ??= new CodeWhispererSession()) + } setFetchCredentialStart() { if (this.fetchCredentialStartTime === 0 && this.invokeSuggestionStartTime !== 0) { @@ -110,7 +89,7 @@ export class CodeWhispererSession { if (triggerType === 'OnDemand') { return this.timeToFirstRecommendation } else { - return this.firstSuggestionShowTime - vsCodeState.lastUserModificationTime + return session.firstSuggestionShowTime - vsCodeState.lastUserModificationTime } } @@ -139,3 +118,6 @@ export class CodeWhispererSession { this.completionTypes.clear() } } + +// TODO: convert this to a function call +export const session = CodeWhispererSession.instance diff --git a/packages/core/src/codewhisperer/util/telemetryHelper.ts b/packages/core/src/codewhisperer/util/telemetryHelper.ts index 22ece4400d2..2612718f1ef 100644 --- a/packages/core/src/codewhisperer/util/telemetryHelper.ts +++ b/packages/core/src/codewhisperer/util/telemetryHelper.ts @@ -22,7 +22,7 @@ import { getSelectedCustomization } from './customizationUtil' import { AuthUtil } from './authUtil' import { isAwsError } from '../../shared/errors' import { getLogger } from '../../shared/logger/logger' -import { CodeWhispererSessionState } from './codeWhispererSession' +import { session } from './codeWhispererSession' import { CodeWhispererSupplementalContext } from '../models/model' import { FeatureConfigProvider } from '../../shared/featureConfig' import { CodeScanRemediationsEventType } from '../client/codewhispereruserclient' @@ -124,7 +124,6 @@ export class TelemetryHelper { reason: string, supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined ) { - const session = CodeWhispererSessionState.instance.getSession() const event = { codewhispererAutomatedTriggerType: session.autoTriggerType, codewhispererCursorOffset: session.startCursorOffset, @@ -158,7 +157,6 @@ export class TelemetryHelper { supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined ) { const selectedCustomization = getSelectedCustomization() - const session = CodeWhispererSessionState.instance.getSession() telemetry.codewhisperer_userDecision.emit({ codewhispererCompletionType: 'Line', @@ -279,7 +277,6 @@ export class TelemetryHelper { if (_elem.content.length === 0) { recommendationSuggestionState?.set(i, 'Empty') } - const session = CodeWhispererSessionState.instance.getSession() const event: CodewhispererUserDecision = { // TODO: maintain a list of RecommendationContexts with both recommendation and requestId in it, instead of two separate list items. codewhispererCompletionType: this.getCompletionType(i, completionTypes), @@ -341,7 +338,6 @@ export class TelemetryHelper { if (!events.length) { return } - const session = CodeWhispererSessionState.instance.getSession() const aggregated: CodewhispererUserTriggerDecision = { codewhispererAutomatedTriggerType: session.autoTriggerType, codewhispererCompletionType: events[0].codewhispererCompletionType, @@ -391,7 +387,6 @@ export class TelemetryHelper { .map((e) => e.codewhispererSuggestionCount) .reduce((a, b) => a + b, 0) - const session = CodeWhispererSessionState.instance.getSession() const aggregated: CodewhispererUserTriggerDecision = { codewhispererAutomatedTriggerType: autoTriggerType, codewhispererCharactersAccepted: acceptedRecommendationContent.length, @@ -513,7 +508,6 @@ export class TelemetryHelper { } private resetUserTriggerDecisionTelemetry() { - const session = CodeWhispererSessionState.instance.getSession() this.sessionDecisions = [] this.triggerChar = '' this.typeAheadLength = 0 @@ -598,7 +592,6 @@ export class TelemetryHelper { } public resetClientComponentLatencyTime() { - const session = CodeWhispererSessionState.instance.getSession() session.invokeSuggestionStartTime = 0 session.preprocessEndTime = 0 session.sdkApiCallStartTime = 0 @@ -610,7 +603,6 @@ export class TelemetryHelper { } public setPreprocessEndTime() { - const session = CodeWhispererSessionState.instance.getSession() if (session.preprocessEndTime !== 0) { getLogger().warn(`inline completion preprocessEndTime has been set and not reset correctly`) } @@ -619,13 +611,11 @@ export class TelemetryHelper { /** This method is assumed to be invoked first at the start of execution **/ public setInvokeSuggestionStartTime() { - const session = CodeWhispererSessionState.instance.getSession() this.resetClientComponentLatencyTime() session.invokeSuggestionStartTime = performance.now() } public setSdkApiCallEndTime() { - const session = CodeWhispererSessionState.instance.getSession() if (this._sdkApiCallEndTime === 0 && session.sdkApiCallStartTime !== 0) { this._sdkApiCallEndTime = performance.now() } @@ -638,7 +628,6 @@ export class TelemetryHelper { } public setFirstSuggestionShowTime() { - const session = CodeWhispererSessionState.instance.getSession() if (session.firstSuggestionShowTime === 0 && this._sdkApiCallEndTime !== 0) { session.firstSuggestionShowTime = performance.now() } @@ -653,7 +642,6 @@ export class TelemetryHelper { // report client component latency after all pagination call finish // and at least one suggestion is shown to the user public tryRecordClientComponentLatency() { - const session = CodeWhispererSessionState.instance.getSession() if (session.firstSuggestionShowTime === 0 || this._allPaginationEndTime === 0) { return } diff --git a/packages/core/src/codewhisperer/views/lineAnnotationController.ts b/packages/core/src/codewhisperer/views/lineAnnotationController.ts index 7cf51a39f9c..8b1d38ed7ae 100644 --- a/packages/core/src/codewhisperer/views/lineAnnotationController.ts +++ b/packages/core/src/codewhisperer/views/lineAnnotationController.ts @@ -16,7 +16,7 @@ import { Container } from '../service/serviceContainer' import { telemetry } from '../../shared/telemetry/telemetry' import { getLogger } from '../../shared/logger/logger' import { Commands } from '../../shared/vscode/commands2' -import { CodeWhispererSessionState } from '../util/codeWhispererSession' +import { session } from '../util/codeWhispererSession' import { RecommendationHandler } from '../service/recommendationHandler' import { runtimeLanguageContext } from '../util/runtimeLanguageContext' import { setContext } from '../../shared/vscode/setContext' @@ -75,7 +75,6 @@ export class AutotriggerState implements AnnotationState { static acceptedCount = 0 updateState(changeSource: AnnotationChangeSource, force: boolean): AnnotationState | undefined { - const session = CodeWhispererSessionState.instance.getSession() if (AutotriggerState.acceptedCount < RecommendationService.instance.acceptedSuggestionCount) { return new ManualtriggerState() } else if (session.recommendations.length > 0 && RecommendationHandler.instance.isSuggestionVisible()) { diff --git a/packages/core/src/test/codewhisperer/testUtil.ts b/packages/core/src/test/codewhisperer/testUtil.ts index ce2b0e51aa8..dfa6c932878 100644 --- a/packages/core/src/test/codewhisperer/testUtil.ts +++ b/packages/core/src/test/codewhisperer/testUtil.ts @@ -16,7 +16,7 @@ import { MockDocument } from '../fake/fakeDocument' import { getLogger } from '../../shared/logger' import { CodeWhispererCodeCoverageTracker } from '../../codewhisperer/tracker/codewhispererCodeCoverageTracker' import globals from '../../shared/extensionGlobals' -import { CodeWhispererSessionState } from '../../codewhisperer/util/codeWhispererSession' +import { session } from '../../codewhisperer/util/codeWhispererSession' import { DefaultAWSClientBuilder, ServiceOptions } from '../../shared/awsClientBuilder' import { FakeAwsContext } from '../utilities/fakeAwsContext' import { HttpResponse, Service } from 'aws-sdk' @@ -33,7 +33,6 @@ export async function resetCodeWhispererGlobalVariables(clearGlobalState: boolea vsCodeState.isCodeWhispererEditing = false CodeWhispererCodeCoverageTracker.instances.clear() globals.telemetry.logger.clear() - const session = CodeWhispererSessionState.instance.getSession() session.reset() if (clearGlobalState) { await globals.globalState.clear() diff --git a/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts b/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts index 6511c628eb9..0038795ad89 100644 --- a/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts +++ b/packages/core/src/testE2E/codewhisperer/referenceTracker.test.ts @@ -10,7 +10,7 @@ import { setValidConnection, skipTestIfNoValidConn } from '../util/connection' import { RecommendationHandler } from '../../codewhisperer/service/recommendationHandler' import { createMockTextEditor, resetCodeWhispererGlobalVariables } from '../../test/codewhisperer/testUtil' import { invokeRecommendation } from '../../codewhisperer/commands/invokeRecommendation' -import { CodeWhispererSessionState } from '../../codewhisperer/util/codeWhispererSession' +import { session } from '../../codewhisperer/util/codeWhispererSession' /* New model deployment may impact references returned. @@ -47,7 +47,6 @@ describe('CodeWhisperer service invocation', async function () { isAutomatedTriggerEnabled: true, isSuggestionsWithCodeReferencesEnabled: false, } - const session = CodeWhispererSessionState.instance.getSession() before(async function () { validConnection = await setValidConnection() diff --git a/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts b/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts index 6770373489b..d4265d13982 100644 --- a/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts +++ b/packages/core/src/testE2E/codewhisperer/serviceInvocations.test.ts @@ -19,10 +19,9 @@ import { KeyStrokeHandler } from '../../codewhisperer/service/keyStrokeHandler' import { sleep } from '../../shared/utilities/timeoutUtils' import { invokeRecommendation } from '../../codewhisperer/commands/invokeRecommendation' import { getTestWorkspaceFolder } from '../../testInteg/integrationTestsUtilities' -import { CodeWhispererSessionState } from '../../codewhisperer/util/codeWhispererSession' +import { session } from '../../codewhisperer/util/codeWhispererSession' describe('CodeWhisperer service invocation', async function () { - const session = CodeWhispererSessionState.instance.getSession() let validConnection: boolean const client = new codewhispererClient.DefaultCodeWhispererClient() const config: ConfigurationEntry = {