Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@
<applicationListeners>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUIChangeListener"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupStateChangeListener"/>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUIChangeListenerNew"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupStateChangeListener"/>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.toolwindow.CodeWhispererCodeReferenceActionListener"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUserActionListener"/>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.toolwindow.CodeWhispererCodeReferenceActionListenerNew"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUserActionListener"/>
</applicationListeners>

<projectListeners>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService
import software.aws.toolkits.resources.message

open class CodeWhispererAcceptAction(title: String = message("codewhisperer.inline.accept")) : AnAction(title), DumbAware {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT

override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project != null && e.getData(CommonDataKeys.EDITOR) != null &&
CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()
CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()
}

override fun actionPerformed(e: AnActionEvent) {
val sessionContext = e.project?.getUserData(CodeWhispererServiceNew.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return
val sessionContext = e.project?.getUserData(CodeWhispererService.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()) return
ApplicationManager.getApplication().messageBus.syncPublisher(
CodeWhispererPopupManager.CODEWHISPERER_USER_ACTION_PERFORMED
).beforeAccept(sessionContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,77 +7,45 @@ import com.intellij.codeInsight.lookup.impl.actions.ChooseItemAction
import com.intellij.openapi.actionSystem.ActionPromoter
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.actionSystem.EditorAction
import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.handlers.CodeWhispererPopupLeftArrowHandler
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.handlers.CodeWhispererPopupRightArrowHandler
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.handlers.CodeWhispererPopupTabHandler
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus

class CodeWhispererActionPromoter : ActionPromoter {
override fun promote(actions: MutableList<out AnAction>, context: DataContext): MutableList<AnAction> {
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
val results = actions.toMutableList()
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return results

results.sortWith { a, b ->
if (isCodeWhispererForceAction(a)) {
return@sortWith -1
} else if (isCodeWhispererForceAction(b)) {
return@sortWith 1
}

if (a is ChooseItemAction) {
return@sortWith -1
} else if (b is ChooseItemAction) {
return@sortWith 1
}
val results = actions.toMutableList()
if (!CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()) return results

if (isCodeWhispererAcceptAction(a)) {
return@sortWith -1
} else if (isCodeWhispererAcceptAction(b)) {
return@sortWith 1
}
results.sortWith { a, b ->
if (isCodeWhispererForceAction(a)) {
return@sortWith -1
} else if (isCodeWhispererForceAction(b)) {
return@sortWith 1
}

0
if (a is ChooseItemAction) {
return@sortWith -1
} else if (b is ChooseItemAction) {
return@sortWith 1
}
return results
}
val results = actions.toMutableList()
results.sortWith { a, b ->
if (isCodeWhispererPopupAction(a)) {

if (isCodeWhispererAcceptAction(a)) {
return@sortWith -1
} else if (isCodeWhispererPopupAction(b)) {
} else if (isCodeWhispererAcceptAction(b)) {
return@sortWith 1
} else {
0
}

0
}
return results
}

private fun isCodeWhispererAcceptAction(action: AnAction): Boolean =
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
action is CodeWhispererAcceptAction
} else {
action is EditorAction && action.handler is CodeWhispererPopupTabHandler
}
action is CodeWhispererAcceptAction

private fun isCodeWhispererForceAcceptAction(action: AnAction): Boolean =
action is CodeWhispererForceAcceptAction

private fun isCodeWhispererNavigateAction(action: AnAction): Boolean =
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
action is CodeWhispererNavigateNextAction || action is CodeWhispererNavigatePrevAction
} else {
action is EditorAction && (
action.handler is CodeWhispererPopupRightArrowHandler ||
action.handler is CodeWhispererPopupLeftArrowHandler
)
}

private fun isCodeWhispererPopupAction(action: AnAction): Boolean =
isCodeWhispererAcceptAction(action) || isCodeWhispererNavigateAction(action)
action is CodeWhispererNavigateNextAction || action is CodeWhispererNavigatePrevAction

private fun isCodeWhispererForceAction(action: AnAction): Boolean =
isCodeWhispererForceAcceptAction(action) || isCodeWhispererNavigateAction(action)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService
import software.aws.toolkits.resources.message

class CodeWhispererNavigateNextAction : AnAction(message("codewhisperer.inline.navigate.next")), DumbAware {
Expand All @@ -20,12 +20,12 @@ class CodeWhispererNavigateNextAction : AnAction(message("codewhisperer.inline.n
override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project != null &&
e.getData(CommonDataKeys.EDITOR) != null &&
CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()
CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()
}

override fun actionPerformed(e: AnActionEvent) {
val sessionContext = e.project?.getUserData(CodeWhispererServiceNew.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return
val sessionContext = e.project?.getUserData(CodeWhispererService.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()) return
ApplicationManager.getApplication().messageBus.syncPublisher(
CodeWhispererPopupManager.CODEWHISPERER_USER_ACTION_PERFORMED
).navigateNext(sessionContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService
import software.aws.toolkits.resources.message

class CodeWhispererNavigatePrevAction : AnAction(message("codewhisperer.inline.navigate.previous")), DumbAware {
Expand All @@ -20,12 +20,12 @@ class CodeWhispererNavigatePrevAction : AnAction(message("codewhisperer.inline.n
override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project != null &&
e.getData(CommonDataKeys.EDITOR) != null &&
CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()
CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()
}

override fun actionPerformed(e: AnActionEvent) {
val sessionContext = e.project?.getUserData(CodeWhispererServiceNew.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return
val sessionContext = e.project?.getUserData(CodeWhispererService.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatus.getInstance().isDisplaySessionActive()) return
ApplicationManager.getApplication().messageBus.syncPublisher(
CodeWhispererPopupManager.CODEWHISPERER_USER_ACTION_PERFORMED
).navigatePrevious(sessionContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.util.Key
import kotlinx.coroutines.Job
import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService
import software.aws.toolkits.jetbrains.services.codewhisperer.model.LatencyContext
import software.aws.toolkits.jetbrains.services.codewhisperer.model.TriggerTypeInfo
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererAutomatedTriggerType
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.resources.message
import software.aws.toolkits.telemetry.CodewhispererTriggerType
import java.util.concurrent.atomic.AtomicReference
Expand All @@ -32,23 +30,12 @@ class CodeWhispererRecommendationAction : AnAction(message("codewhisperer.trigge
latencyContext.codewhispererPreprocessingStart = System.nanoTime()
latencyContext.codewhispererEndToEndStart = System.nanoTime()
val editor = e.getRequiredData(CommonDataKeys.EDITOR)
if (!(
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
CodeWhispererServiceNew.getInstance().canDoInvocation(editor, CodewhispererTriggerType.OnDemand)
} else {
CodeWhispererService.getInstance().canDoInvocation(editor, CodewhispererTriggerType.OnDemand)
}
)
) {
if (!CodeWhispererService.getInstance().canDoInvocation(editor, CodewhispererTriggerType.OnDemand)) {
return
}

val triggerType = TriggerTypeInfo(CodewhispererTriggerType.OnDemand, CodeWhispererAutomatedTriggerType.Unknown())
val job = if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
CodeWhispererServiceNew.getInstance().showRecommendationsInPopup(editor, triggerType, latencyContext)
} else {
CodeWhispererService.getInstance().showRecommendationsInPopup(editor, triggerType, latencyContext)
}
val job = CodeWhispererService.getInstance().showRecommendationsInPopup(editor, triggerType, latencyContext)

e.getData(CommonDataKeys.EDITOR)?.getUserData(ACTION_JOB_KEY)?.set(job)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@ import software.aws.toolkits.jetbrains.services.amazonq.codeWhispererUserContext
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager
import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
import software.aws.toolkits.jetbrains.services.codewhisperer.model.SessionContextNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.RequestContext
import software.aws.toolkits.jetbrains.services.codewhisperer.service.RequestContextNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.ResponseContext
import software.aws.toolkits.jetbrains.services.codewhisperer.model.RequestContext
import software.aws.toolkits.jetbrains.services.codewhisperer.model.ResponseContext
import software.aws.toolkits.jetbrains.services.codewhisperer.model.SessionContext
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getTelemetryOptOutPreference
import software.aws.toolkits.jetbrains.services.codewhisperer.util.transform
Expand Down Expand Up @@ -90,6 +89,7 @@ interface CodeWhispererClientAdaptor : Disposable {
fun listAvailableCustomizations(): List<CodeWhispererCustomization>

fun sendUserTriggerDecisionTelemetry(
sessionContext: SessionContext,
requestContext: RequestContext,
responseContext: ResponseContext,
completionType: CodewhispererCompletionType,
Expand All @@ -100,18 +100,6 @@ interface CodeWhispererClientAdaptor : Disposable {
acceptedCharCount: Int,
): SendTelemetryEventResponse

fun sendUserTriggerDecisionTelemetry(
sessionContext: SessionContextNew,
requestContext: RequestContextNew,
responseContext: ResponseContext,
completionType: CodewhispererCompletionType,
suggestionState: CodewhispererSuggestionState,
suggestionReferenceCount: Int,
lineCount: Int,
numberOfRecommendations: Int,
acceptedCharCount: Int,
): SendTelemetryEventResponse

fun sendCodePercentageTelemetry(
language: CodeWhispererProgrammingLanguage,
customizationArn: String?,
Expand Down Expand Up @@ -302,6 +290,7 @@ open class CodeWhispererClientAdaptorImpl(override val project: Project) : CodeW
}

override fun sendUserTriggerDecisionTelemetry(
sessionContext: SessionContext,
requestContext: RequestContext,
responseContext: ResponseContext,
completionType: CodewhispererCompletionType,
Expand All @@ -310,53 +299,6 @@ open class CodeWhispererClientAdaptorImpl(override val project: Project) : CodeW
lineCount: Int,
numberOfRecommendations: Int,
acceptedCharCount: Int,
): SendTelemetryEventResponse {
val fileContext = requestContext.fileContextInfo
val programmingLanguage = fileContext.programmingLanguage
var e2eLatency = requestContext.latencyContext.getCodeWhispererEndToEndLatency()

// When we send a userTriggerDecision for neither Accept nor Reject, service side should not use this value
// and client side will set this value to 0.0.
if (suggestionState != CodewhispererSuggestionState.Accept &&
suggestionState != CodewhispererSuggestionState.Reject
) {
e2eLatency = 0.0
}

return bearerClient().sendTelemetryEvent { requestBuilder ->
requestBuilder.telemetryEvent { telemetryEventBuilder ->
telemetryEventBuilder.userTriggerDecisionEvent {
it.requestId(requestContext.latencyContext.firstRequestId)
it.completionType(completionType.toCodeWhispererSdkType())
it.programmingLanguage { builder -> builder.languageName(programmingLanguage.toCodeWhispererRuntimeLanguage().languageId) }
it.sessionId(responseContext.sessionId)
it.recommendationLatencyMilliseconds(e2eLatency)
it.triggerToResponseLatencyMilliseconds(requestContext.latencyContext.paginationFirstCompletionTime)
it.perceivedLatencyMilliseconds(requestContext.latencyContext.perceivedLatency)
it.suggestionState(suggestionState.toCodeWhispererSdkType())
it.timestamp(Instant.now())
it.suggestionReferenceCount(suggestionReferenceCount)
it.generatedLine(lineCount)
it.customizationArn(requestContext.customizationArn)
it.numberOfRecommendations(numberOfRecommendations)
it.acceptedCharacterCount(acceptedCharCount)
}
}
requestBuilder.optOutPreference(getTelemetryOptOutPreference())
requestBuilder.userContext(codeWhispererUserContext())
}
}

override fun sendUserTriggerDecisionTelemetry(
sessionContext: SessionContextNew,
requestContext: RequestContextNew,
responseContext: ResponseContext,
completionType: CodewhispererCompletionType,
suggestionState: CodewhispererSuggestionState,
suggestionReferenceCount: Int,
lineCount: Int,
numberOfRecommendations: Int,
acceptedCharCount: Int,
): SendTelemetryEventResponse {
val fileContext = requestContext.fileContextInfo
val programmingLanguage = fileContext.programmingLanguage
Expand Down Expand Up @@ -686,6 +628,8 @@ private fun CodewhispererSuggestionState.toCodeWhispererSdkType() = when {
this == CodewhispererSuggestionState.Reject -> SuggestionState.REJECT
this == CodewhispererSuggestionState.Empty -> SuggestionState.EMPTY
this == CodewhispererSuggestionState.Discard -> SuggestionState.DISCARD
this == CodewhispererSuggestionState.Ignore -> SuggestionState.MERGE
this == CodewhispererSuggestionState.Unseen -> SuggestionState.MERGE
else -> SuggestionState.UNKNOWN_TO_SDK_VERSION
}

Expand Down
Loading
Loading