From 5ba949ceaa1571cbc718bd0572e7e4e6fa97a57c Mon Sep 17 00:00:00 2001 From: Roman Chertishchev Date: Wed, 10 Sep 2025 19:52:32 +0200 Subject: [PATCH] LLM-18251: change per provider listening to only cloud completion provider listening for dynamic debouncing (cherry picked from commit 4218fcee6e17ab03e9aea136bc257c37a539a1df) (cherry picked from commit 91bb294944c12b1215e8ff4d2db610e1e5585c02) IJ-MR-175246 GitOrigin-RevId: 0b07fce6d913f5d3c0c2b3d9de83f33af0709523 --- .../completion/InlineCompletionHandler.kt | 4 -- ...nlineCompletionAdaptiveDebounceListener.kt | 39 ------------ ...ineCompletionFinishedCompletionsStorage.kt | 59 ------------------- 3 files changed, 102 deletions(-) delete mode 100644 platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionAdaptiveDebounceListener.kt delete mode 100644 platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionFinishedCompletionsStorage.kt diff --git a/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/InlineCompletionHandler.kt b/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/InlineCompletionHandler.kt index db5581cb35da..143f65a15096 100644 --- a/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/InlineCompletionHandler.kt +++ b/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/InlineCompletionHandler.kt @@ -1,7 +1,6 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.inline.completion -import com.intellij.codeInsight.inline.completion.debounce.InlineCompletionAdaptiveDebounceListener import com.intellij.codeInsight.inline.completion.editor.InlineCompletionEditorType import com.intellij.codeInsight.inline.completion.elements.InlineCompletionElement import com.intellij.codeInsight.inline.completion.listeners.InlineSessionWiseCaretListener @@ -85,9 +84,6 @@ abstract class InlineCompletionHandler @ApiStatus.Internal constructor( invalidationListeners.addListener(logsListener) addEventListener(UserFactorsListener()) - // Adaptive debounce listener: tracks acceptance/rejection outcomes for the last 10 minutes - addEventListener(InlineCompletionAdaptiveDebounceListener(editor)) - Disposer.register(parentDisposable, /* child = */ executor) } diff --git a/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionAdaptiveDebounceListener.kt b/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionAdaptiveDebounceListener.kt deleted file mode 100644 index 092297d5278a..000000000000 --- a/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionAdaptiveDebounceListener.kt +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInsight.inline.completion.debounce - -import com.intellij.codeInsight.inline.completion.InlineCompletionEventAdapter -import com.intellij.codeInsight.inline.completion.InlineCompletionEventType -import com.intellij.codeInsight.inline.completion.logs.InlineCompletionUsageTracker.ShownEvents.FinishType -import com.intellij.codeInsight.inline.completion.session.InlineCompletionSession -import com.intellij.openapi.editor.Editor - -/** - * Listener that observes inline completion lifecycle and records - * accept/reject finish type into [InlineCompletionFinishedCompletionsStorage] per provider. - */ -internal class InlineCompletionAdaptiveDebounceListener(private val editor: Editor) : InlineCompletionEventAdapter { - - private fun serviceOrNull(): InlineCompletionFinishedCompletionsStorage? = editor.project?.let { InlineCompletionFinishedCompletionsStorage.getInstance(it) } - - override fun onHide(event: InlineCompletionEventType.Hide) { - val result = when (event.finishType) { - FinishType.CARET_CHANGED, - FinishType.EDITOR_REMOVED, - FinishType.FOCUS_LOST, - FinishType.TYPED, - FinishType.EMPTY, - FinishType.ERROR, - FinishType.OTHER, - FinishType.BACKSPACE_PRESSED, - FinishType.KEY_PRESSED, - FinishType.INVALIDATED, - FinishType.MOUSE_PRESSED, - FinishType.DOCUMENT_CHANGED, - -> InlineCompletionFinishedCompletionsStorage.Result.OTHER - FinishType.ESCAPE_PRESSED -> InlineCompletionFinishedCompletionsStorage.Result.REJECTED - FinishType.SELECTED -> InlineCompletionFinishedCompletionsStorage.Result.ACCEPTED - } - val provider = InlineCompletionSession.getOrNull(editor)?.provider?.id - provider?.let { serviceOrNull()?.record(it, result) } - } -} diff --git a/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionFinishedCompletionsStorage.kt b/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionFinishedCompletionsStorage.kt deleted file mode 100644 index 52c93f1236fc..000000000000 --- a/platform/platform-impl/codeinsight-inline/src/com/intellij/codeInsight/inline/completion/debounce/InlineCompletionFinishedCompletionsStorage.kt +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInsight.inline.completion.debounce - -import com.intellij.codeInsight.inline.completion.InlineCompletionProviderID -import com.intellij.codeInsight.inline.completion.debounce.InlineCompletionFinishedCompletionsStorage.Companion.EXPIRATION_MS -import com.intellij.openapi.components.Service -import com.intellij.openapi.components.service -import com.intellij.openapi.project.Project -import org.jetbrains.annotations.ApiStatus -import java.util.* - -/** - * Project-level container of recent inline-completions for adaptive debounce tuning. - * - * Retains completions for the last [EXPIRATION_MS] milliseconds (10 minutes) and discards older ones. - */ -@Service(Service.Level.PROJECT) -@ApiStatus.Internal -class InlineCompletionFinishedCompletionsStorage { - enum class Result { ACCEPTED, REJECTED, OTHER } - - data class FinishedCompletion(val providerId: InlineCompletionProviderID, val result: Result, val finishTime: Long) - - private val completionsPerProvider: MutableMap> = HashMap() - - fun record(provider: InlineCompletionProviderID, result: Result) { - val now = System.currentTimeMillis() - cleanupExpired(now) - val q = completionsPerProvider.getOrPut(provider) { ArrayDeque() } - q.addLast(FinishedCompletion(provider, result, now)) - } - - /** - * Returns a snapshot of recent completions with timestamps (most recent at the end) for the given provider. - */ - fun getRecentCompletions(provider: InlineCompletionProviderID): List { - cleanupExpired(System.currentTimeMillis()) - return completionsPerProvider[provider]?.toList().orEmpty() - } - - private fun cleanupExpired(now: Long) { - val threshold = now - EXPIRATION_MS - val it = completionsPerProvider.entries.iterator() - while (it.hasNext()) { - val entry = it.next() - val q = entry.value - while (true) { - val first = q.peekFirst() ?: break - if (first.finishTime < threshold) q.removeFirst() else break - } - if (q.isEmpty()) it.remove() - } - } - - companion object { - private const val EXPIRATION_MS: Long = 10 * 60 * 1000 // 10 minutes - fun getInstance(project: Project): InlineCompletionFinishedCompletionsStorage = project.service() - } -}