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..88d050b1 100644
--- a/refact_lsp
+++ b/refact_lsp
@@ -1 +1 @@
-v0.10.5
\ No newline at end of file
+main
\ No newline at end of file
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/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/codecompletion/RefactAICompletionProvider.kt b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAICompletionProvider.kt
index c9791cdb..6117b8c5 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,9 @@ 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")
+val EditorRefactLastCompletionIsMultilineKey = Key.create("refact.lastCompletion.isMultiline")
+
private class Default : InlineCompletionSuggestionUpdateManager.Adapter {
override fun onDocumentChange(
event: InlineCompletionEvent.DocumentChange,
@@ -144,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
@@ -253,10 +256,11 @@ class RefactAICompletionProvider : DebouncedInlineCompletionProvider() {
send(it)
delay(2)
}
+ EditorRefactLastSnippetTelemetryIdKey[request.editor] = completion.snippetTelemetryId
+ EditorRefactLastCompletionIsMultilineKey[request.editor] = completion.multiline
}
}
awaitClose()
-
})
private fun getSingleLineElements(
diff --git a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAIContinuousEvent.kt b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAIContinuousEvent.kt
index 00fb7f5d..0adfbe95 100644
--- a/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAIContinuousEvent.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/codecompletion/RefactAIContinuousEvent.kt
@@ -22,17 +22,21 @@ class RefactAIContinuousEvent(val editor: Editor, val offset: Int) : InlineCompl
@RequiresBlockingContext
private fun getPsiFile(editor: Editor, project: Project): PsiFile? {
return runReadAction {
- val file =
- PsiDocumentManager.getInstance(project).getPsiFile(editor.document) ?: return@runReadAction null
- // * [PsiUtilBase] takes into account injected [PsiFile] (like in Jupyter Notebooks)
- // * However, it loads a file into the memory, which is expensive
- // * Some tests forbid loading a file when tearing down
- // * On tearing down, Lookup Cancellation happens, which causes the event
- // * Existence of [treeElement] guarantees that it's in the memory
- if (file.isLoadedInMemory()) {
- PsiUtilBase.getPsiFileInEditor(editor, project)
- } else {
- file
+ try {
+ val file =
+ PsiDocumentManager.getInstance(project).getPsiFile(editor.document) ?: return@runReadAction null
+ // * [PsiUtilBase] takes into account injected [PsiFile] (like in Jupyter Notebooks)
+ // * However, it loads a file into the memory, which is expensive
+ // * Some tests forbid loading a file when tearing down
+ // * On tearing down, Lookup Cancellation happens, which causes the event
+ // * Existence of [treeElement] guarantees that it's in the memory
+ if (file.isLoadedInMemory()) {
+ PsiUtilBase.getPsiFileInEditor(editor, project)
+ } else {
+ file
+ }
+ } catch (e: Exception) {
+ return@runReadAction null
}
}
}
diff --git a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt
index 8a835e99..0973eda7 100644
--- a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt
@@ -126,16 +126,6 @@ class InferenceGlobalContext : Disposable {
.astFileLimitChanged(newValue)
}
- var astLightMode: Boolean
- get() = AppSettingsState.astLightMode
- set(newValue) {
- if (newValue == astLightMode) return
- messageBus
- .syncPublisher(InferenceGlobalContextChangedNotifier.TOPIC)
- .astLightModeChanged(newValue)
- }
-
-
var vecdbIsEnabled: Boolean
get() = AppSettingsState.vecdbIsEnabled
set(newValue) {
diff --git a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContextChangedNotifier.kt b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContextChangedNotifier.kt
index 18b91eb8..ca0a5a7d 100644
--- a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContextChangedNotifier.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContextChangedNotifier.kt
@@ -15,7 +15,6 @@ interface InferenceGlobalContextChangedNotifier {
fun deploymentModeChanged(newMode: DeploymentMode) {}
fun astFlagChanged(newValue: Boolean) {}
fun astFileLimitChanged(newValue: Int) {}
- fun astLightModeChanged(newValue: Boolean) {}
fun vecdbFlagChanged(newValue: Boolean) {}
fun vecdbFileLimitChanged(newValue: Int) {}
fun xDebugLSPPortChanged(newPort: Int?) {}
diff --git a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
index 7956f5a3..c6259b8a 100644
--- a/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/listeners/AcceptAction.kt
@@ -5,30 +5,39 @@ 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.EditorRefactLastCompletionIsMultilineKey
+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"
-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)
if (provider.isInCompletionMode()) {
InlineCompletion.getHandlerOrNull(editor)?.insert()
+ EditorRefactLastSnippetTelemetryIdKey[editor]?.also {
+ editor.project?.service()?.snippetAccepted(it)
+ EditorRefactLastSnippetTelemetryIdKey[editor] = null
+ EditorRefactLastCompletionIsMultilineKey[editor] = null
+ }
} else {
provider.onTabPressed(editor, caret, dataContext)
}
@@ -42,10 +51,12 @@ class TabPressedAction : EditorAction(InlineCompletionHandler()), ActionToIgnore
val provider = ModeProvider.getOrCreateModeProvider(editor)
if (provider.isInCompletionMode()) {
val ctx = InlineCompletionContext.getOrNull(editor) ?: return false
- if (ctx.state.elements.size != 1) return false
+ if (ctx.state.elements.isEmpty()) 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/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt
index 9adec101..aed2bacb 100644
--- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt
@@ -11,7 +11,6 @@ data class LSPConfig(
var deployment: DeploymentMode = DeploymentMode.CLOUD,
var ast: Boolean = true,
var astFileLimit: Int? = null,
- var astLightMode: Boolean = false,
var vecdb: Boolean = true,
var vecdbFileLimit: Int? = null,
var insecureSSL: Boolean = false,
@@ -44,9 +43,6 @@ data class LSPConfig(
params.add("--ast-max-files")
params.add("$astFileLimit")
}
- if (ast && astLightMode) {
- params.add("--ast-light-mode")
- }
if (vecdb) {
params.add("--vecdb")
}
@@ -72,7 +68,6 @@ data class LSPConfig(
if (useTelemetry != other.useTelemetry) return false
if (deployment != other.deployment) return false
if (ast != other.ast) return false
- if (astLightMode != other.astLightMode) return false
if (vecdb != other.vecdb) return false
if (astFileLimit != other.astFileLimit) return false
if (vecdbFileLimit != other.vecdbFileLimit) return false
diff --git a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt
index 91925eb7..3b0ed00a 100644
--- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt
@@ -118,12 +118,6 @@ class LSPProcessHolder(val project: Project) : Disposable {
}
}
- override fun astLightModeChanged(newValue: Boolean) {
- AppExecutorUtil.getAppScheduledExecutorService().submit {
- settingsChanged()
- }
- }
-
override fun vecdbFlagChanged(newValue: Boolean) {
AppExecutorUtil.getAppScheduledExecutorService().submit {
settingsChanged()
@@ -192,7 +186,6 @@ class LSPProcessHolder(val project: Project) : Disposable {
deployment = InferenceGlobalContext.deploymentMode,
ast = InferenceGlobalContext.astIsEnabled,
astFileLimit = InferenceGlobalContext.astFileLimit,
- astLightMode = InferenceGlobalContext.astLightMode,
vecdb = InferenceGlobalContext.vecdbIsEnabled,
vecdbFileLimit = InferenceGlobalContext.vecdbFileLimit,
insecureSSL = InferenceGlobalContext.insecureSSL,
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/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
}
diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt
index f5e02769..7edd84f4 100644
--- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt
@@ -48,7 +48,6 @@ class AppSettingsComponent {
private val myContrastUrlText = JBTextField()
private val myModelText = JBTextField()
private val myAstFileLimitText = JBTextField()
- private val myAstLightMode = JCheckBox(RefactAIBundle.message("advancedSettings.useASTLightMode"))
private val myVecdbFileLimitText = JBTextField()
private val insecureSSLCheckBox = JCheckBox(RefactAIBundle.message("advancedSettings.insecureSSL"))
private val telemetrySnippetCheckBox = JCheckBox(RefactAIBundle.message("advancedSettings.telemetryCodeSnippets"))
@@ -175,15 +174,6 @@ class AppSettingsComponent {
UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER
), 0
)
- addComponent(myAstLightMode, UIUtil.LARGE_VGAP)
- addComponent(
- JBLabel(
- RefactAIBundle.message("advancedSettings.useASTLightModeDescription"),
- UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER
- ).apply {
- setCopyable(true)
- }, 0
- )
addComponent(vecdbCheckbox, UIUtil.LARGE_VGAP)
addComponent(
@@ -257,11 +247,6 @@ class AppSettingsComponent {
set(newVal) {
myAstFileLimitText.text = newVal.toString()
}
- var astLightMode: Boolean
- get() = myAstLightMode.isSelected
- set(newVal) {
- myAstLightMode.isSelected = newVal
- }
var vecdbIsEnabled: Boolean
get() = vecdbCheckbox.isSelected
set(newVal) {
diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt
index 9a5c28fd..46672d64 100644
--- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt
@@ -61,7 +61,6 @@ class AppSettingsConfigurable : Configurable {
modified = modified || mySettingsComponent!!.astIsEnabled != InferenceGlobalContext.astIsEnabled
modified = modified || mySettingsComponent!!.astFileLimit != InferenceGlobalContext.astFileLimit
- modified = modified || mySettingsComponent!!.astLightMode != InferenceGlobalContext.astLightMode
modified = modified || mySettingsComponent!!.vecdbIsEnabled != InferenceGlobalContext.vecdbIsEnabled
modified = modified || mySettingsComponent!!.vecdbFileLimit != InferenceGlobalContext.vecdbFileLimit
@@ -83,7 +82,6 @@ class AppSettingsConfigurable : Configurable {
InferenceGlobalContext.xDebugLSPPort = mySettingsComponent!!.xDebugLSPPort
InferenceGlobalContext.astIsEnabled = mySettingsComponent!!.astIsEnabled
InferenceGlobalContext.astFileLimit = mySettingsComponent!!.astFileLimit
- InferenceGlobalContext.astLightMode = mySettingsComponent!!.astLightMode
InferenceGlobalContext.vecdbIsEnabled = mySettingsComponent!!.vecdbIsEnabled
InferenceGlobalContext.vecdbFileLimit = mySettingsComponent!!.vecdbFileLimit
InferenceGlobalContext.insecureSSL = mySettingsComponent!!.insecureSSL
@@ -101,7 +99,6 @@ class AppSettingsConfigurable : Configurable {
mySettingsComponent!!.xDebugLSPPort = InferenceGlobalContext.xDebugLSPPort
mySettingsComponent!!.astIsEnabled = InferenceGlobalContext.astIsEnabled
mySettingsComponent!!.astFileLimit = InferenceGlobalContext.astFileLimit
- mySettingsComponent!!.astLightMode = InferenceGlobalContext.astLightMode
mySettingsComponent!!.vecdbIsEnabled = InferenceGlobalContext.vecdbIsEnabled
mySettingsComponent!!.vecdbFileLimit = InferenceGlobalContext.vecdbFileLimit
mySettingsComponent!!.inferenceModel = InferenceGlobalContext.model
diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt
index a9084c9c..ef8cbe89 100644
--- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt
+++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt
@@ -50,7 +50,6 @@ class AppSettingsState : PersistentStateComponent {
var vecdbIsEnabledDefaultChanged: Boolean = false
var astFileLimit: Int = 15000
var vecdbFileLimit: Int = 15000
- var astLightMode: Boolean = false
var completionMaxTokens: Int = 0
var insecureSSL: Boolean = false
var telemetrySnippetsEnabled: Boolean = false
@@ -110,9 +109,6 @@ class AppSettingsState : PersistentStateComponent {
override fun astFileLimitChanged(newValue: Int) {
instance.astFileLimit = newValue
}
- override fun astLightModeChanged(newValue: Boolean) {
- instance.astLightMode = newValue
- }
override fun vecdbFileLimitChanged(newValue: Int) {
instance.vecdbFileLimit = newValue
}
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
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