Skip to content

Commit cf4af82

Browse files
committed
fix(amazonq): Change JB's behavior back to blocking auto trigger
1 parent 3467e45 commit cf4af82

File tree

1 file changed

+41
-22
lines changed
  • plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/popup

1 file changed

+41
-22
lines changed

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/popup/QInlineCompletionProvider.kt

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import com.intellij.ui.util.preferredHeight
3838
import icons.AwsIcons
3939
import kotlinx.coroutines.CancellationException
4040
import kotlinx.coroutines.CoroutineScope
41+
import kotlinx.coroutines.NonCancellable
4142
import kotlinx.coroutines.channels.Channel
4243
import kotlinx.coroutines.flow.receiveAsFlow
4344
import kotlinx.coroutines.future.await
@@ -132,6 +133,7 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
132133

133134
// not needed for current implementation, will need this when we support concurrent triggers, so leave it here
134135
private val activeTriggerSessions = mutableMapOf<Int, InlineCompletionSessionContext>()
136+
private val previousTriggerSessions = mutableMapOf<Int, InlineCompletionSessionContext>()
135137

136138
fun qToolTip(
137139
title: String,
@@ -261,6 +263,7 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
261263
}
262264

263265
override fun onInvalidated(event: InlineCompletionEventType.Invalidated) {
266+
// CodeWhispererInvocationStatus.getInstance().setIsInvokingQInline(session, false)
264267
updateDisplayIndex(session)
265268
super.onInvalidated(event)
266269
}
@@ -401,9 +404,9 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
401404
return TriggerTypeInfo(triggerType, automatedTriggerType)
402405
}
403406

404-
override suspend fun getSuggestion(request: InlineCompletionRequest): InlineCompletionSuggestion {
407+
override suspend fun getSuggestion(request: InlineCompletionRequest): InlineCompletionSuggestion = withContext(NonCancellable) {
405408
val editor = request.editor
406-
val project = editor.project ?: return InlineCompletionSuggestion.Empty
409+
val project = editor.project ?: return@withContext InlineCompletionSuggestion.Empty
407410

408411
// try to refresh automatically if possible, otherwise ask user to login again
409412
if (isQExpired(project)) {
@@ -414,13 +417,13 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
414417
}
415418

416419
if (shouldReauth) {
417-
return InlineCompletionSuggestion.Empty
420+
return@withContext InlineCompletionSuggestion.Empty
418421
}
419422
}
420423

421424
val document = editor.document
422-
val handler = InlineCompletion.getHandlerOrNull(editor) ?: return InlineCompletionSuggestion.Empty
423-
val session = InlineCompletionSession.getOrNull(editor) ?: return InlineCompletionSuggestion.Empty
425+
val handler = InlineCompletion.getHandlerOrNull(editor) ?: return@withContext InlineCompletionSuggestion.Empty
426+
val session = InlineCompletionSession.getOrNull(editor) ?: return@withContext InlineCompletionSuggestion.Empty
424427
val triggerSessionId = triggerSessionId++
425428
val latencyContext = LatencyContext(codewhispererEndToEndStart = System.nanoTime())
426429
val triggerTypeInfo = getTriggerTypeInfo(request)
@@ -431,14 +434,6 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
431434
CodeWhispererInvocationStatus.getInstance().setIsInvokingQInline(session, false)
432435
}
433436

434-
// this is only available in 2024.3+
435-
if (request.event.isDeletion()) {
436-
logInline(triggerSessionId) {
437-
"Skip inline completion when deleting"
438-
}
439-
return InlineCompletionSuggestion.Empty
440-
}
441-
442437
val sessionContext = InlineCompletionSessionContext(triggerOffset = request.endOffset, diagnostics = diagnostics)
443438

444439
// Pagination workaround: Always return exactly 5 variants
@@ -490,17 +485,38 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
490485
it.channel.close()
491486
}
492487
if (session.context.isDisposed) {
488+
previousTriggerSessions[triggerSessionId] = sessionContext
493489
logInline(triggerSessionId) {
494490
"Current display session already disposed by a new trigger before pagination finishes, exiting"
495491
}
492+
return@withContext InlineCompletionSuggestion.Empty
496493
}
497494

498-
return object : InlineCompletionSuggestion {
499-
override suspend fun getVariants(): List<InlineCompletionVariant> =
500-
sessionContext.itemContexts.map { itemContext ->
501-
itemContext.data.putUserData(KEY_Q_INLINE_ITEM_CONTEXT, itemContext)
502-
InlineCompletionVariant.build(data = itemContext.data, elements = itemContext.channel.receiveAsFlow())
495+
return@withContext object : InlineCompletionSuggestion {
496+
override suspend fun getVariants(): List<InlineCompletionVariant> {
497+
// also need to build valid elements from last session
498+
val result = mutableListOf<InlineCompletionVariant>()
499+
previousTriggerSessions.forEach { (t, u) ->
500+
logInline(triggerSessionId) {
501+
"Adding results from previous trigger $t for the current display session"
502+
}
503+
result.addAll(
504+
u.itemContexts.map { itemContext ->
505+
itemContext.data.putUserData(KEY_Q_INLINE_ITEM_CONTEXT, itemContext)
506+
InlineCompletionVariant.build(data = itemContext.data, elements = itemContext.channel.receiveAsFlow())
507+
}
508+
)
503509
}
510+
previousTriggerSessions.clear()
511+
512+
result.addAll(
513+
sessionContext.itemContexts.map { itemContext ->
514+
itemContext.data.putUserData(KEY_Q_INLINE_ITEM_CONTEXT, itemContext)
515+
InlineCompletionVariant.build(data = itemContext.data, elements = itemContext.channel.receiveAsFlow())
516+
}
517+
)
518+
return result
519+
}
504520
}
505521
} catch (e: Exception) {
506522
logInline(triggerSessionId, e) {
@@ -509,7 +525,7 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
509525
if (e is CancellationException) {
510526
throw e
511527
}
512-
return InlineCompletionSuggestion.Empty
528+
return@withContext InlineCompletionSuggestion.Empty
513529
}
514530
}
515531

@@ -537,7 +553,8 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
537553
}
538554

539555
logInline(triggerSessionId) {
540-
"Received ${nextPageResult.items.size} items from pagination with token: ${nextToken?.left}"
556+
"Received ${nextPageResult.items.size} items from pagination with current token: ${nextToken?.left}, " +
557+
"next token: ${nextPageResult.partialResultToken?.left}"
541558
}
542559

543560
// Update channels in order with new items from pagination
@@ -587,7 +604,9 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
587604
sessionContext.itemContexts[channelIndex].isDiscarded = discarded
588605
val success = existingChannel.trySend(InlineCompletionGrayTextElement(displayText))
589606
logInline(triggerSessionId) {
590-
"Adding paginated item '${newItem.itemId}' to channel $channelIndex, success: ${success.isSuccess}, discarded: $discarded"
607+
"Adding paginated item '${newItem.itemId}' to channel $channelIndex, " +
608+
"original first line context: ${newItem.insertText.lines()[0]}, " +
609+
"success: ${success.isSuccess}, discarded: $discarded"
591610
}
592611
sessionContext.counter++
593612
}
@@ -638,7 +657,7 @@ class QInlineCompletionProvider(private val cs: CoroutineScope) : InlineCompleti
638657
if (QRegionProfileManager.getInstance().hasValidConnectionButNoActiveProfile(project)) return false
639658
if (event.isManualCall()) return true
640659
if (!CodeWhispererExplorerActionManager.getInstance().isAutoEnabled()) return false
641-
660+
if (request.event.isDeletion()) return false
642661
return true
643662
}
644663
}

0 commit comments

Comments
 (0)