mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
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
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c7104b975b
commit
5ba949ceaa
@@ -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.
|
// 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
|
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.editor.InlineCompletionEditorType
|
||||||
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionElement
|
import com.intellij.codeInsight.inline.completion.elements.InlineCompletionElement
|
||||||
import com.intellij.codeInsight.inline.completion.listeners.InlineSessionWiseCaretListener
|
import com.intellij.codeInsight.inline.completion.listeners.InlineSessionWiseCaretListener
|
||||||
@@ -85,9 +84,6 @@ abstract class InlineCompletionHandler @ApiStatus.Internal constructor(
|
|||||||
invalidationListeners.addListener(logsListener)
|
invalidationListeners.addListener(logsListener)
|
||||||
addEventListener(UserFactorsListener())
|
addEventListener(UserFactorsListener())
|
||||||
|
|
||||||
// Adaptive debounce listener: tracks acceptance/rejection outcomes for the last 10 minutes
|
|
||||||
addEventListener(InlineCompletionAdaptiveDebounceListener(editor))
|
|
||||||
|
|
||||||
Disposer.register(parentDisposable, /* child = */ executor)
|
Disposer.register(parentDisposable, /* child = */ executor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<InlineCompletionProviderID, ArrayDeque<FinishedCompletion>> = 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<FinishedCompletion> {
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user