From e3fdf9859018664bf8bce74868b01914b7c2fe37 Mon Sep 17 00:00:00 2001
From: Kirill Starkov
Date: Wed, 11 Dec 2024 17:15:50 +0800
Subject: [PATCH 1/9] disable logs for jcef
---
.../com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
index 5b648fc0..5a796dcf 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
@@ -509,7 +509,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
}
val webView by lazy {
- System.setProperty("ide.browser.jcef.log.level", "info")
+// System.setProperty("ide.browser.jcef.log.level", "info")
browser.webView
}
From 854e990da97249198c89219c27e5c6b68076bd80 Mon Sep 17 00:00:00 2001
From: Kirill Starkov
Date: Wed, 11 Dec 2024 17:29:19 +0800
Subject: [PATCH 2/9] fix robot telemetry
---
.../refactai/codecompletion/RefactAICompletionProvider.kt | 5 ++++-
.../com/smallcloud/refactai/listeners/AcceptAction.kt | 7 +++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
index c9791cdb..79169966 100644
--- a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
@@ -18,6 +18,7 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.Key
import com.intellij.ui.components.JBLabel
import com.intellij.util.application
import com.intellij.util.ui.JBFont
@@ -50,6 +51,8 @@ import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import com.smallcloud.refactai.io.InferenceGlobalContext.Companion.instance as InferenceGlobalContext
+val EditorRefactLastSnippetTelemetryIdKey = Key.create("refact.snippetTelemetryId")
+
private class Default : InlineCompletionSuggestionUpdateManager.Adapter {
override fun onDocumentChange(
event: InlineCompletionEvent.DocumentChange,
@@ -253,10 +256,10 @@ class RefactAICompletionProvider : DebouncedInlineCompletionProvider() {
send(it)
delay(2)
}
+ EditorRefactLastSnippetTelemetryIdKey[request.editor] = completion.snippetTelemetryId
}
}
awaitClose()
-
})
private fun getSingleLineElements(
diff --git a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
index 7956f5a3..ff03f200 100644
--- a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
@@ -5,14 +5,17 @@ import com.intellij.codeInsight.hint.HintManagerImpl.ActionToIgnore
import com.intellij.codeInsight.inline.completion.InlineCompletion
import com.intellij.codeInsight.inline.completion.session.InlineCompletionContext
import com.intellij.openapi.actionSystem.DataContext
+import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.actionSystem.EditorAction
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler
import com.smallcloud.refactai.Resources
+import com.smallcloud.refactai.codecompletion.EditorRefactLastSnippetTelemetryIdKey
import com.smallcloud.refactai.codecompletion.InlineCompletionGrayTextElementCustom
import com.smallcloud.refactai.modes.ModeProvider
+import com.smallcloud.refactai.statistic.UsageStats
const val ACTION_ID_ = "TabPressedAction"
@@ -29,6 +32,10 @@ class TabPressedAction : EditorAction(InlineCompletionHandler()), ActionToIgnore
val provider = ModeProvider.getOrCreateModeProvider(editor)
if (provider.isInCompletionMode()) {
InlineCompletion.getHandlerOrNull(editor)?.insert()
+ EditorRefactLastSnippetTelemetryIdKey[editor]?.also {
+ editor.project?.service()?.snippetAccepted(it)
+ EditorRefactLastSnippetTelemetryIdKey[editor] = null
+ }
} else {
provider.onTabPressed(editor, caret, dataContext)
}
From fc1a3c81cbe4a78a9e05181e238c15d23c3ee2ac Mon Sep 17 00:00:00 2001
From: Kirill Starkov
Date: Wed, 11 Dec 2024 19:09:25 +0800
Subject: [PATCH 3/9] add open chat event telemetry
---
.../com/smallcloud/refactai/Resources.kt | 1 +
.../refactai/code_lens/CodeLensAction.kt | 4 ++
.../panes/sharedchat/ChatPaneInvokeAction.kt | 6 ++-
.../refactai/statistic/UsageStats.kt | 43 +++++++++++++++++++
4 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/Resources.kt b/src/main/kotlin/com/smallcloud/refactai/Resources.kt
index bc23e020..e71a7cda 100644
--- a/src/main/kotlin/com/smallcloud/refactai/Resources.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/Resources.kt
@@ -65,6 +65,7 @@ object Resources {
val defaultCodeCompletionUrlSuffix = URI("v1/code-completion")
val cloudUserMessage: URI = defaultCloudUrl.resolve("/v1/user-message")
val defaultReportUrlSuffix: URI = URI("v1/telemetry-network")
+ val defaultChatReportUrlSuffix: URI = URI("v1/telemetry-chat")
val defaultSnippetAcceptedUrlSuffix: URI = URI("v1/snippet-accepted")
val version: String = getVersion()
const val client: String = "jetbrains"
diff --git a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
index 52c58d0a..a4fde2ba 100644
--- a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
@@ -2,6 +2,7 @@ package com.smallcloud.refactai.code_lens
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.components.service
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.project.DumbAwareAction
@@ -9,6 +10,8 @@ import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.wm.ToolWindowManager
import com.smallcloud.refactai.Resources
import com.smallcloud.refactai.panes.RefactAIToolboxPaneFactory
+import com.smallcloud.refactai.statistic.UsageStatistic
+import com.smallcloud.refactai.statistic.UsageStats
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.io.path.relativeTo
@@ -50,6 +53,7 @@ class CodeLensAction(
chat?.activate {
RefactAIToolboxPaneFactory.chat?.requestFocus()
RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand(formatMessage(), sendImmediately, openNewTab)
+ editor.project?.service()?.addChatStatistic(true, UsageStatistic("openChatByCodelens"), "")
}
// If content is empty, then it's "Open Chat" instruction, selecting range of code in active tab
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPaneInvokeAction.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPaneInvokeAction.kt
index a9799221..860dac4b 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPaneInvokeAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPaneInvokeAction.kt
@@ -2,9 +2,12 @@ package com.smallcloud.refactai.panes.sharedchat
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.components.service
import com.intellij.openapi.wm.ToolWindowManager
import com.smallcloud.refactai.Resources
import com.smallcloud.refactai.panes.RefactAIToolboxPaneFactory
+import com.smallcloud.refactai.statistic.UsageStatistic
+import com.smallcloud.refactai.statistic.UsageStats
import com.smallcloud.refactai.utils.getLastUsedProject
class ChatPaneInvokeAction: AnAction(Resources.Icons.LOGO_RED_16x16) {
@@ -14,8 +17,9 @@ class ChatPaneInvokeAction: AnAction(Resources.Icons.LOGO_RED_16x16) {
fun actionPerformed() {
val chat = ToolWindowManager.getInstance(getLastUsedProject()).getToolWindow("Refact")
- chat?.activate{
+ chat?.activate {
RefactAIToolboxPaneFactory.focusChat()
+ getLastUsedProject().service().addChatStatistic(true, UsageStatistic("openChatByShortcut"), "")
}
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt b/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt
index 6873c5fe..acb91422 100644
--- a/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/statistic/UsageStats.kt
@@ -7,6 +7,7 @@ import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.util.concurrency.AppExecutorUtil
+import com.smallcloud.refactai.Resources.defaultChatReportUrlSuffix
import com.smallcloud.refactai.Resources.defaultReportUrlSuffix
import com.smallcloud.refactai.Resources.defaultSnippetAcceptedUrlSuffix
import com.smallcloud.refactai.io.sendRequest
@@ -93,6 +94,48 @@ class UsageStats(private val project: Project): Disposable {
}
}
}
+
+ fun addChatStatistic(
+ positive: Boolean,
+ stat: UsageStatistic,
+ errorMessage: Any
+ ) {
+ var errorMessageStr = errorMessage.toString()
+ val gson = Gson()
+ if (errorMessageStr.length > 200) {
+ errorMessageStr = errorMessageStr.substring(0, 200) + "…"
+ }
+
+ val errorMessageJson = gson.toJson(errorMessageStr)
+ var scope = stat.scope
+ if (stat.subScope.isNotEmpty()) {
+ scope += ":" + stat.subScope
+ }
+
+ val scopeJson = gson.toJson(scope)
+ val body = gson.toJson(
+ mapOf(
+ "success" to positive,
+ "error_message" to errorMessageJson,
+ "scope" to scopeJson,
+ )
+ )
+ val url = getLSPProcessHolder(project)!!.url.resolve(defaultChatReportUrlSuffix)
+ execService.submit {
+ try {
+ val res = sendRequest(url, "POST", body=body)
+ if (res.body.isNullOrEmpty()) return@submit
+
+ val json = gson.fromJson(res.body, JsonObject::class.java)
+ val success = if (json.has("success")) json.get("success").asInt else null
+ if (success != null && success != 1) {
+ throw Exception(json.get("human_readable_message").asString)
+ }
+ } catch (e: Exception) {
+ Logger.getInstance(UsageStats::class.java).warn("report to $url failed: $e")
+ }
+ }
+ }
companion object {
@JvmStatic
From 9932ac69f3444916f482af98ba18ff089f10e533 Mon Sep 17 00:00:00 2001
From: Kirill Starkov
Date: Fri, 13 Dec 2024 21:58:52 +0800
Subject: [PATCH 4/9] TMP CICD CHANGES
---
.github/workflows/build.yml | 2 +-
refact_lsp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f4f131f2..c6226702 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -43,7 +43,7 @@ jobs:
workflow: node.js.yml
workflow_search: true
repo: smallcloudai/refact-chat-js
- branch: main
+ branch: alpha
name: refact-chat-js-latest
path: ./src/main/resources/webview/dist
diff --git a/refact_lsp b/refact_lsp
index a6eeb03f..312e7df8 100644
--- a/refact_lsp
+++ b/refact_lsp
@@ -1 +1 @@
-v0.10.5
\ No newline at end of file
+self_configure
\ No newline at end of file
From 5577ad7d5108c2f0b41e0afb90516fc147ab70d5 Mon Sep 17 00:00:00 2001
From: Kirill Starkov
Date: Fri, 20 Dec 2024 00:19:39 +0800
Subject: [PATCH 5/9] fix completion action on win
---
.../com/smallcloud/refactai/Initializer.kt | 38 -------------------
.../RefactAICompletionProvider.kt | 2 +
.../refactai/listeners/AcceptAction.kt | 12 ++++--
.../listeners/AcceptActionPromoter.kt | 12 ++++--
.../GenerateGitCommitMessageAction.kt | 4 +-
src/main/resources/META-INF/plugin.xml | 16 ++++----
6 files changed, 28 insertions(+), 56 deletions(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/Initializer.kt b/src/main/kotlin/com/smallcloud/refactai/Initializer.kt
index 64620cee..ce32be75 100644
--- a/src/main/kotlin/com/smallcloud/refactai/Initializer.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/Initializer.kt
@@ -40,44 +40,6 @@ class Initializer : ProjectActivity, Disposable {
PluginInstaller.addStateListener(UninstallListener())
UpdateChecker.instance
- ApplicationManager.getApplication()
- .messageBus
- .connect(PluginState.instance)
- .subscribe(KeymapManagerListener.TOPIC, object : KeymapManagerListener {
- override fun shortcutsChanged(
- keymap: Keymap,
- actionIds: MutableCollection,
- fromSettings: Boolean
- ) {
- if (Thread.currentThread().stackTrace.count { it.className.startsWith("com.smallcloud.refactai.Initializer") } > 1) {
- return
- }
- for (id in actionIds) {
- if (!listOf(IdeActions.ACTION_INSERT_INLINE_COMPLETION, ACTION_ID_).contains(id)) {
- continue
- }
- val shortcuts = keymap.getShortcuts(id)
- if (id == IdeActions.ACTION_INSERT_INLINE_COMPLETION) {
- keymap.removeAllActionShortcuts(ACTION_ID_)
- for (shortcut in shortcuts) {
- keymap.addShortcut(
- ACTION_ID_,
- shortcut
- )
- }
- } else if (id == ACTION_ID_) {
- keymap.removeAllActionShortcuts(IdeActions.ACTION_INSERT_INLINE_COMPLETION)
- for (shortcut in shortcuts) {
- keymap.addShortcut(
- IdeActions.ACTION_INSERT_INLINE_COMPLETION,
- shortcut
- )
- }
- }
- }
- }
- })
-
ApplicationManager.getApplication().getService(CloudMessageService::class.java)
if (!isJcefCanStart()) {
emitInfo(RefactAIBundle.message("notifications.chatCanNotStartWarning"), false)
diff --git a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
index 79169966..ae5e3605 100644
--- a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
@@ -52,6 +52,7 @@ import kotlin.time.Duration.Companion.milliseconds
import com.smallcloud.refactai.io.InferenceGlobalContext.Companion.instance as InferenceGlobalContext
val EditorRefactLastSnippetTelemetryIdKey = Key.create("refact.snippetTelemetryId")
+val EditorRefactLastCompletionIsMultilineKey = Key.create("refact.lastCompletion.isMultiline")
private class Default : InlineCompletionSuggestionUpdateManager.Adapter {
override fun onDocumentChange(
@@ -257,6 +258,7 @@ class RefactAICompletionProvider : DebouncedInlineCompletionProvider() {
delay(2)
}
EditorRefactLastSnippetTelemetryIdKey[request.editor] = completion.snippetTelemetryId
+ EditorRefactLastCompletionIsMultilineKey[request.editor] = completion.multiline
}
}
awaitClose()
diff --git a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
index ff03f200..fbcaed7d 100644
--- a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
@@ -12,6 +12,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.actionSystem.EditorAction
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler
import com.smallcloud.refactai.Resources
+import com.smallcloud.refactai.codecompletion.EditorRefactLastCompletionIsMultilineKey
import com.smallcloud.refactai.codecompletion.EditorRefactLastSnippetTelemetryIdKey
import com.smallcloud.refactai.codecompletion.InlineCompletionGrayTextElementCustom
import com.smallcloud.refactai.modes.ModeProvider
@@ -19,14 +20,14 @@ import com.smallcloud.refactai.statistic.UsageStats
const val ACTION_ID_ = "TabPressedAction"
-class TabPressedAction : EditorAction(InlineCompletionHandler()), ActionToIgnore {
+class TabPressedAction : EditorAction(InsertInlineCompletionHandler()), ActionToIgnore {
val ACTION_ID = ACTION_ID_
init {
this.templatePresentation.icon = Resources.Icons.LOGO_RED_16x16
}
- class InlineCompletionHandler : EditorWriteActionHandler() {
+ class InsertInlineCompletionHandler : EditorWriteActionHandler() {
override fun executeWriteAction(editor: Editor, caret: Caret?, dataContext: DataContext) {
Logger.getInstance("RefactTabPressedAction").debug("executeWriteAction")
val provider = ModeProvider.getOrCreateModeProvider(editor)
@@ -35,6 +36,7 @@ class TabPressedAction : EditorAction(InlineCompletionHandler()), ActionToIgnore
EditorRefactLastSnippetTelemetryIdKey[editor]?.also {
editor.project?.service()?.snippetAccepted(it)
EditorRefactLastSnippetTelemetryIdKey[editor] = null
+ EditorRefactLastCompletionIsMultilineKey[editor] = null
}
} else {
provider.onTabPressed(editor, caret, dataContext)
@@ -51,8 +53,10 @@ class TabPressedAction : EditorAction(InlineCompletionHandler()), ActionToIgnore
val ctx = InlineCompletionContext.getOrNull(editor) ?: return false
if (ctx.state.elements.size != 1) return false
val elem = ctx.state.elements.first()
- if (elem !is InlineCompletionGrayTextElementCustom.Presentable) return false
- return elem.delta == caret.logicalPosition.column
+ val isMultiline = EditorRefactLastCompletionIsMultilineKey[editor]
+ if (isMultiline && elem is InlineCompletionGrayTextElementCustom.Presentable)
+ return elem.delta == caret.logicalPosition.column
+ return true
} else {
return ModeProvider.getOrCreateModeProvider(editor).modeInActiveState()
}
diff --git a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptActionPromoter.kt b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptActionPromoter.kt
index f525988d..ffa46641 100644
--- a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptActionPromoter.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptActionPromoter.kt
@@ -1,5 +1,6 @@
package com.smallcloud.refactai.listeners
+import com.intellij.codeInsight.inline.completion.session.InlineCompletionContext
import com.intellij.openapi.actionSystem.ActionPromoter
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.CommonDataKeys
@@ -10,9 +11,12 @@ class AcceptActionsPromoter : ActionPromoter {
private fun getEditor(dataContext: DataContext): Editor? {
return CommonDataKeys.EDITOR.getData(dataContext)
}
- override fun promote(actions: MutableList, context: DataContext): MutableList {
- if (getEditor(context) == null)
- return actions.toMutableList()
- return actions.filterIsInstance().toMutableList()
+ override fun promote(actions: MutableList, context: DataContext): List {
+ val editor = getEditor(context) ?: return emptyList()
+ if (InlineCompletionContext.getOrNull(editor) == null) {
+ return emptyList()
+ }
+ actions.filterIsInstance().takeIf { it.isNotEmpty() }?.let { return it }
+ return emptyList()
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/smallcloud/refactai/listeners/GenerateGitCommitMessageAction.kt b/src/main/kotlin/com/smallcloud/refactai/listeners/GenerateGitCommitMessageAction.kt
index 33e51cdb..140ea980 100644
--- a/src/main/kotlin/com/smallcloud/refactai/listeners/GenerateGitCommitMessageAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/listeners/GenerateGitCommitMessageAction.kt
@@ -37,7 +37,7 @@ class GenerateGitCommitMessageAction : AnAction(
val lspService =
event.project?.service() ?: return@invokeLater
- val isEnabled = lspService.isWorking && (commitWorkflowUi.getIncludedChanges().isNotEmpty() && commitWorkflowUi.getIncludedUnversionedFiles().isNotEmpty())
+ val isEnabled = lspService.isWorking && (commitWorkflowUi.getIncludedChanges().isNotEmpty() || commitWorkflowUi.getIncludedUnversionedFiles().isNotEmpty())
event.presentation.isEnabled = isEnabled
event.presentation.text = if (lspService.isWorking) {
@@ -54,7 +54,6 @@ class GenerateGitCommitMessageAction : AnAction(
return
}
-
val gitDiff = getDiff(event, project) ?: return
val commitWorkflowUi = event.getData(VcsDataKeys.COMMIT_WORKFLOW_UI)
if (commitWorkflowUi != null) {
@@ -87,7 +86,6 @@ class GenerateGitCommitMessageAction : AnAction(
try {
val includedChanges = commitWorkflowUi.getIncludedChanges()
- commitWorkflowUi.getIncludedUnversionedFiles()
val filePatches = IdeaTextPatchBuilder.buildPatch(
project, includedChanges, projectFileVcsRoot.toNioPath(), false, true
)
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 05ef895b..4bb36ad9 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -148,9 +148,11 @@ integrated into a single package that follows your privacy settings.
+
-
-
-
-
-
-
+
+
+
+
bundles.RefactAI
From f7a19a3750b36d4c51807a8b7a3020a3ff54d88b Mon Sep 17 00:00:00 2001
From: Kirill Starkov
Date: Fri, 20 Dec 2024 23:39:22 +0800
Subject: [PATCH 6/9] fix completion filepath
---
refact_lsp | 2 +-
.../refactai/codecompletion/RefactAICompletionProvider.kt | 7 +++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/refact_lsp b/refact_lsp
index 312e7df8..88d050b1 100644
--- a/refact_lsp
+++ b/refact_lsp
@@ -1 +1 @@
-self_configure
\ No newline at end of file
+main
\ No newline at end of file
diff --git a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
index ae5e3605..6117b8c5 100644
--- a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
@@ -148,17 +148,16 @@ class RefactAICompletionProvider : DebouncedInlineCompletionProvider() {
override fun restartOn(event: InlineCompletionEvent): Boolean = false
- private fun getActiveFile(document: Document, project: Project?): String? {
- val projectPath = project?.basePath ?: return null
+ private fun getActiveFile(document: Document): String? {
val file = FileDocumentManager.getInstance().getFile(document) ?: return null
- return Path(file.path).toUri().toString().replace(Path(projectPath).toUri().toString(), "")
+ return Path(file.path).toString()
}
private class Context(val request: SMCRequest, val editorState: EditorTextState, val force: Boolean = false)
private fun makeContext(request: InlineCompletionRequest): Context? {
- val fileName = getActiveFile(request.document, request.editor.project) ?: return null
+ val fileName = getActiveFile(request.document) ?: return null
if (PrivacyService.instance.getPrivacy(FileDocumentManager.getInstance().getFile(request.document))
== Privacy.DISABLED && !InferenceGlobalContext.isSelfHosted
) return null
From 92c6535724f7f964fa309f8b96178294764076f6 Mon Sep 17 00:00:00 2001
From: alashchev17
Date: Wed, 8 Jan 2025 19:07:07 +0100
Subject: [PATCH 7/9] wip: working with messages, functions to process
message.content
---
.../refactai/code_lens/CodeLensAction.kt | 44 ++++++++++++++++---
.../refactai/panes/sharedchat/ChatPanes.kt | 5 ++-
.../refactai/panes/sharedchat/Events.kt | 17 ++++++-
.../panes/sharedchat/SharedChatPane.kt | 9 ++--
4 files changed, 61 insertions(+), 14 deletions(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
index a4fde2ba..f54f567c 100644
--- a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
@@ -12,6 +12,7 @@ import com.smallcloud.refactai.Resources
import com.smallcloud.refactai.panes.RefactAIToolboxPaneFactory
import com.smallcloud.refactai.statistic.UsageStatistic
import com.smallcloud.refactai.statistic.UsageStats
+import com.smallcloud.refactai.struct.ChatMessage
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.io.path.relativeTo
@@ -19,7 +20,7 @@ class CodeLensAction(
private val editor: Editor,
private val line1: Int,
private val line2: Int,
- private val contentMsg: String,
+ private val messages: Array,
private val sendImmediately: Boolean,
private val openNewTab: Boolean
) : DumbAwareAction(Resources.Icons.LOGO_RED_16x16) {
@@ -27,7 +28,37 @@ class CodeLensAction(
actionPerformed()
}
- private fun formatMessage(): String {
+ private fun replaceVariablesInText(
+ text: String,
+ relativePath: String,
+ cursor: Int?,
+ codeSelection: String
+ ): String {
+ return text
+ .replace("%CURRENT_FILE%", relativePath)
+ .replace("%CURSOR_LINE%", cursor?.plus(1)?.toString() ?: "")
+ .replace("%CODE_SELECTION%", codeSelection)
+ .replace("%PROMPT_EXPLORATION_TOOLS%", "")
+ }
+
+ private fun formatMultipleMessagesForCodeLens(
+ messages: Array,
+ relativePath: String,
+ cursor: Int?,
+ text: String
+ ): Array {
+ return messages.map { message ->
+ if (message.role == "user") {
+ message.copy(
+ content = replaceVariablesInText(message.content, relativePath, cursor, text)
+ )
+ } else {
+ message
+ }
+ }.toTypedArray()
+ }
+
+ private fun formatMessage(): Array {
val pos1 = LogicalPosition(line1, 0)
val text = editor.document.text.slice(
editor.logicalPositionToOffset(pos1) until editor.document.getLineEndOffset(line2)
@@ -39,10 +70,9 @@ class CodeLensAction(
}.minBy { it.toString().length }
}
- return contentMsg
- .replace("%CURRENT_FILE%", relativePath?.toString() ?: filePath.toString())
- .replace("%CURSOR_LINE%", line1.toString())
- .replace("%CODE_SELECTION%", text)
+ val formattedMessages = formatMultipleMessagesForCodeLens(messages, relativePath?.toString() ?: filePath.toString(), line1, text);
+
+ return formattedMessages
}
private val isActionRunning = AtomicBoolean(false)
@@ -52,7 +82,7 @@ class CodeLensAction(
chat?.activate {
RefactAIToolboxPaneFactory.chat?.requestFocus()
- RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand(formatMessage(), sendImmediately, openNewTab)
+ RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand("", formatMessage(), sendImmediately, openNewTab)
editor.project?.service()?.addChatStatistic(true, UsageStatistic("openChatByCodelens"), "")
}
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt
index 2a77fb87..8d066aab 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt
@@ -3,6 +3,7 @@ package com.smallcloud.refactai.panes.sharedchat
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.invokeLater
import com.intellij.openapi.project.Project
+import com.smallcloud.refactai.struct.ChatMessage
import java.awt.BorderLayout
import javax.swing.JComponent
import javax.swing.JPanel
@@ -31,8 +32,8 @@ class ChatPanes(val project: Project) : Disposable {
return holder
}
- fun executeCodeLensCommand(command: String, sendImmediately: Boolean, openNewTab: Boolean) {
- pane?.executeCodeLensCommand(command, sendImmediately, openNewTab)
+ fun executeCodeLensCommand(command: String, messages: Array, sendImmediately: Boolean, openNewTab: Boolean) {
+ pane?.executeCodeLensCommand(command, messages, sendImmediately, openNewTab)
}
fun requestFocus() {
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/Events.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/Events.kt
index 677f730e..2924ed9b 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/Events.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/Events.kt
@@ -7,6 +7,7 @@ import com.google.gson.JsonElement
import com.google.gson.annotations.SerializedName
import com.smallcloud.refactai.settings.Host
import com.smallcloud.refactai.settings.HostDeserializer
+import com.smallcloud.refactai.struct.ChatMessage
import java.io.Serializable
import java.lang.reflect.Type
@@ -366,7 +367,21 @@ class Events {
data class CodeLensCommandPayload(
val value: String = "",
@SerializedName("send_immediately") val sendImmediately: Boolean = false,
- ) : Payload()
+ val messages: Array
+ ) : Payload() {
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as CodeLensCommandPayload
+
+ return messages.contentEquals(other.messages)
+ }
+
+ override fun hashCode(): Int {
+ return messages.contentHashCode()
+ }
+ }
class CodeLensCommand(payload: CodeLensCommandPayload) : ToChat(EventNames.ToChat.CODE_LENS_EXEC, payload)
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
index 5a796dcf..87bce638 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
@@ -40,6 +40,7 @@ import com.smallcloud.refactai.panes.sharedchat.Events.Editor
import com.smallcloud.refactai.panes.sharedchat.browser.ChatWebView
import com.smallcloud.refactai.settings.AppSettingsConfigurable
import com.smallcloud.refactai.settings.Host
+import com.smallcloud.refactai.struct.ChatMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -55,7 +56,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
private val editor = Editor(project)
private var currentPage: String = ""
private var isChatStreaming: Boolean = false
- var id: String? = null;
+ var id: String? = null
private val animatedFiles = mutableSetOf()
private val scheduler = AppExecutorUtil.createBoundedScheduledExecutorService("SMCRainbowScheduler", 2)
@@ -98,7 +99,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
}
}
- fun executeCodeLensCommand(command: String, sendImmediately: Boolean, openNewTab: Boolean) {
+ fun executeCodeLensCommand(command: String, messages: Array, sendImmediately: Boolean, openNewTab: Boolean) {
if (isChatStreaming) return
if (openNewTab || this.currentPage != "chat") {
newChat()
@@ -109,7 +110,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
return
}
isChatStreaming = true
- this.postMessage(Events.CodeLensCommand(Events.CodeLensCommandPayload(command, sendImmediately)))
+ this.postMessage(Events.CodeLensCommand(Events.CodeLensCommandPayload(command, sendImmediately, messages)))
}
private fun sendUserConfig() {
@@ -152,7 +153,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
val out = process.getResultStdoutStr().getOrNull()
if (out == null) {
println("Save btok file output is null")
- return;
+ return
}
val fileName = out.lines().last()
From eea12540976a39845af0ee750c0878727502a040 Mon Sep 17 00:00:00 2001
From: alashchev17
Date: Thu, 9 Jan 2025 11:33:35 +0100
Subject: [PATCH 8/9] feat: adjusted ChatMessage data class & fixed
RefactCodeVisionProvider
---
.../smallcloud/refactai/code_lens/CodeLensAction.kt | 9 +++++----
.../refactai/code_lens/RefactCodeVisionProvider.kt | 11 +++++++----
.../refactai/panes/sharedchat/SharedChatPane.kt | 2 +-
.../com/smallcloud/refactai/struct/ChatMessage.kt | 2 +-
4 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
index f54f567c..dd20b7b6 100644
--- a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
@@ -47,7 +47,7 @@ class CodeLensAction(
cursor: Int?,
text: String
): Array {
- return messages.map { message ->
+ val formattedMessages = messages.map { message ->
if (message.role == "user") {
message.copy(
content = replaceVariablesInText(message.content, relativePath, cursor, text)
@@ -56,9 +56,10 @@ class CodeLensAction(
message
}
}.toTypedArray()
+ return formattedMessages
}
- private fun formatMessage(): Array {
+ private fun formatMessages(): Array {
val pos1 = LogicalPosition(line1, 0)
val text = editor.document.text.slice(
editor.logicalPositionToOffset(pos1) until editor.document.getLineEndOffset(line2)
@@ -82,12 +83,12 @@ class CodeLensAction(
chat?.activate {
RefactAIToolboxPaneFactory.chat?.requestFocus()
- RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand("", formatMessage(), sendImmediately, openNewTab)
+ RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand("", formatMessages(), sendImmediately, openNewTab)
editor.project?.service()?.addChatStatistic(true, UsageStatistic("openChatByCodelens"), "")
}
// If content is empty, then it's "Open Chat" instruction, selecting range of code in active tab
- if (contentMsg.isEmpty() && isActionRunning.compareAndSet(false, true)) {
+ if (messages.isEmpty() && isActionRunning.compareAndSet(false, true)) {
ApplicationManager.getApplication().invokeLater {
try {
val pos1 = LogicalPosition(line1, 0)
diff --git a/src/main/kotlin/com/smallcloud/refactai/code_lens/RefactCodeVisionProvider.kt b/src/main/kotlin/com/smallcloud/refactai/code_lens/RefactCodeVisionProvider.kt
index 0f6b86c6..49885806 100644
--- a/src/main/kotlin/com/smallcloud/refactai/code_lens/RefactCodeVisionProvider.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/code_lens/RefactCodeVisionProvider.kt
@@ -70,16 +70,19 @@ class RefactCodeVisionProvider(
val value = allCodeLenses.get(commandKey).asJsonObject
val msgs = value.asJsonObject.get("messages").asJsonArray.map {
gson.fromJson(it.asJsonObject, ChatMessage::class.java)
- }.toList()
- val msg = msgs.find { it.role == "user" }
+ }.toTypedArray()
+ val userMsg = msgs.find { it.role == "user" }
+
val sendImmediately = value.asJsonObject.get("auto_submit").asBoolean
val openNewTab = value.asJsonObject.get("new_tab")?.asBoolean ?: true
- if (msg != null || msgs.isEmpty()) {
+
+ val isValidCodeLen = msgs.isEmpty() || userMsg != null
+ if (isValidCodeLen) {
resCodeLenses.add(
CodeLen(
range,
value.asJsonObject.get("label").asString,
- CodeLensAction(editor, line1, line2, msg?.content ?: "", sendImmediately, openNewTab)
+ CodeLensAction(editor, line1, line2, msgs, sendImmediately, openNewTab)
)
)
}
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
index 87bce638..3b66d2d3 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
@@ -104,7 +104,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
if (openNewTab || this.currentPage != "chat") {
newChat()
}
- if (command.isEmpty()) {
+ if (messages.isEmpty()) {
// Just opening a new chat, no codelens execution
newChat()
return
diff --git a/src/main/kotlin/com/smallcloud/refactai/struct/ChatMessage.kt b/src/main/kotlin/com/smallcloud/refactai/struct/ChatMessage.kt
index 48e7ad18..ba3b3ddb 100644
--- a/src/main/kotlin/com/smallcloud/refactai/struct/ChatMessage.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/struct/ChatMessage.kt
@@ -4,5 +4,5 @@ import com.google.gson.annotations.SerializedName
data class ChatMessage(val role: String,
val content: String,
- @SerializedName("tool_call_id") val toolCallId: String,
+ @SerializedName("tool_call_id") val toolCallId: String?,
val usage: String?)
\ No newline at end of file
From 7c5b726971cd724bc3057a69dafad7498e75e200 Mon Sep 17 00:00:00 2001
From: alashchev17
Date: Fri, 10 Jan 2025 12:45:27 +0100
Subject: [PATCH 9/9] fix: removed command from executeCodeLensCommand action
since sending messages directly
---
.../com/smallcloud/refactai/code_lens/CodeLensAction.kt | 2 +-
.../com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt | 4 ++--
.../smallcloud/refactai/panes/sharedchat/SharedChatPane.kt | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
index dd20b7b6..c0fa3f1d 100644
--- a/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/code_lens/CodeLensAction.kt
@@ -83,7 +83,7 @@ class CodeLensAction(
chat?.activate {
RefactAIToolboxPaneFactory.chat?.requestFocus()
- RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand("", formatMessages(), sendImmediately, openNewTab)
+ RefactAIToolboxPaneFactory.chat?.executeCodeLensCommand(formatMessages(), sendImmediately, openNewTab)
editor.project?.service()?.addChatStatistic(true, UsageStatistic("openChatByCodelens"), "")
}
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt
index 8d066aab..a74eb909 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/ChatPanes.kt
@@ -32,8 +32,8 @@ class ChatPanes(val project: Project) : Disposable {
return holder
}
- fun executeCodeLensCommand(command: String, messages: Array, sendImmediately: Boolean, openNewTab: Boolean) {
- pane?.executeCodeLensCommand(command, messages, sendImmediately, openNewTab)
+ fun executeCodeLensCommand(messages: Array, sendImmediately: Boolean, openNewTab: Boolean) {
+ pane?.executeCodeLensCommand(messages, sendImmediately, openNewTab)
}
fun requestFocus() {
diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
index 3b66d2d3..6da4c49d 100644
--- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/SharedChatPane.kt
@@ -99,7 +99,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
}
}
- fun executeCodeLensCommand(command: String, messages: Array, sendImmediately: Boolean, openNewTab: Boolean) {
+ fun executeCodeLensCommand(messages: Array, sendImmediately: Boolean, openNewTab: Boolean) {
if (isChatStreaming) return
if (openNewTab || this.currentPage != "chat") {
newChat()
@@ -110,7 +110,7 @@ class SharedChatPane(val project: Project) : JPanel(), Disposable {
return
}
isChatStreaming = true
- this.postMessage(Events.CodeLensCommand(Events.CodeLensCommandPayload(command, sendImmediately, messages)))
+ this.postMessage(Events.CodeLensCommand(Events.CodeLensCommandPayload("", sendImmediately, messages)))
}
private fun sendUserConfig() {