From ff4a1898ff404144484c125f6782750e8bcc43bf Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Wed, 29 May 2024 13:46:06 +0800 Subject: [PATCH 01/10] update version --- build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ba582c20..c1913d63 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,7 @@ dependencies { group = "com.smallcloud" -version = getVersionString("1.3.0") +version = getVersionString("1.3.1") repositories { mavenCentral() @@ -34,8 +34,8 @@ repositories { // Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type intellij { // version.set("LATEST-EAP-SNAPSHOT") - version.set("2022.3.1") - type.set("PC") // Target IDE Platform + version.set("2024.1.2") + type.set("RD") // Target IDE Platform plugins.set(listOf( "Git4Idea", From b6554588b10459c8bab95f4cfa06a1bca17b827b Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Wed, 29 May 2024 14:31:09 +0800 Subject: [PATCH 02/10] fix deadlock with new ide versions --- .../modes/completion/CompletionMode.kt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt b/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt index 8e4c2323..e21f8e7e 100644 --- a/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt +++ b/src/main/kotlin/com/smallcloud/refactai/modes/completion/CompletionMode.kt @@ -143,12 +143,9 @@ class CompletionMode( completionData: Completion, animation: Boolean ) { - var modificationStamp: Long = state.modificationStamp - var offset: Int = state.offset - app.invokeAndWait { - modificationStamp = editor.document.modificationStamp - offset = editor.caretModel.offset - } + val modificationStamp = editor.document.modificationStamp + val offset = editor.caretModel.offset + val invalidStamp = state.modificationStamp != modificationStamp val invalidOffset = state.offset != offset if (invalidStamp || invalidOffset) { @@ -264,10 +261,12 @@ class CompletionMode( return@streamedInferenceFetch } completion.updateCompletion(choice.delta) - synchronized(this) { - renderCompletion( - editorState.editor, editorState, completion, !prediction.cached - ) + app.invokeLater { + synchronized(this) { + renderCompletion( + editorState.editor, editorState, completion, !prediction.cached + ) + } } }?.also { try { From c176da6ce1aab545da90cfedf32c7cc359d26178 Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Wed, 29 May 2024 15:09:08 +0800 Subject: [PATCH 03/10] fix settings and add texts for vecdb/ast --- .../refactai/settings/AppSettingsComponent.kt | 11 ++++++++--- src/main/resources/bundles/RefactAI.properties | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt index 7ceef1b9..0344390b 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt @@ -60,7 +60,7 @@ class AppSettingsComponent { } private val defaultSystemPromptTextArea = JBTextArea() - private val vecdbCheckbox = JCheckBox("VECDB").apply { + private val vecdbCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useVecDB")).apply { isVisible = true } @@ -89,6 +89,13 @@ class AppSettingsComponent { UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER ), 0 ) + addComponent(vecdbCheckbox, UIUtil.LARGE_VGAP) + addComponent( + JBLabel( + RefactAIBundle.message("advancedSettings.useVecDBDescription"), + UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER + ), 0 + ) addLabeledComponent(JBLabel("${RefactAIBundle.message("advancedSettings.codeCompletionModel")}: "), myModelText, (UIUtil.DEFAULT_VGAP * 1.5).toInt(), false) addComponent( @@ -109,8 +116,6 @@ class AppSettingsComponent { addComponent(developerModeCheckBox, UIUtil.LARGE_VGAP) addLabeledComponent(myXDebugLSPPortLabel, myXDebugLSPPort, UIUtil.LARGE_VGAP) addLabeledComponent(myStagingVersionLabel, myStagingVersionText, UIUtil.LARGE_VGAP) - addComponent(astCheckbox, UIUtil.LARGE_VGAP) - addComponent(vecdbCheckbox, UIUtil.LARGE_VGAP) addComponentFillVertically(JPanel(), 0) }.panel diff --git a/src/main/resources/bundles/RefactAI.properties b/src/main/resources/bundles/RefactAI.properties index ca14b7ac..e809a72e 100644 --- a/src/main/resources/bundles/RefactAI.properties +++ b/src/main/resources/bundles/RefactAI.properties @@ -52,6 +52,8 @@ advancedSettings.developerMode=Developer mode advancedSettings.defaultSystemPrompt=Default system prompt advancedSettings.codeCompletionModel=Code Completion Model advancedSettings.codeCompletionModelDesc=Which model to use, for example starcoder2/3b. Leave blank if not sure. +advancedSettings.useVecDB=Use multiple files chatting completion (VecDB) +advancedSettings.useVecDBDescription=In this mode plugin uses multiple files in its context for chatting notifications.loginTo=Login to {0} From 64880277cf4de921cd7c16b56816d98712dfc83a Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Wed, 29 May 2024 15:09:35 +0800 Subject: [PATCH 04/10] add health checker for lsp process --- .../refactai/lsp/LSPProcessHolder.kt | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt index 5b342e82..8c2ead3b 100644 --- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt +++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt @@ -53,7 +53,7 @@ class LSPProcessHolder(val project: Project): Disposable { private var process: Process? = null private var lastConfig: LSPConfig? = null private val logger = Logger.getInstance("LSPProcessHolder") - private val scheduler = AppExecutorUtil.createBoundedScheduledExecutorService( + private val loggerScheduler = AppExecutorUtil.createBoundedScheduledExecutorService( "SMCLSPLoggerScheduler", 1 ) private var loggerTask: Future<*>? = null @@ -63,6 +63,10 @@ class LSPProcessHolder(val project: Project): Disposable { private var capsTask: Future<*>? = null private val messageBus: MessageBus = ApplicationManager.getApplication().messageBus private var isWorking = false + private val healthCheckerScheduler = AppExecutorUtil.createBoundedScheduledExecutorService( + "SMCLSHealthCheckerScheduler", 1 + ) + private var healthCheckerTask: Future<*>? = null init { @@ -121,6 +125,14 @@ class LSPProcessHolder(val project: Project): Disposable { } settingsChanged() + healthCheckerScheduler.scheduleWithFixedDelay({ + if (lastConfig == null) return@scheduleWithFixedDelay + if (InferenceGlobalContext.xDebugLSPPort != null) return@scheduleWithFixedDelay + if (process?.isAlive == false) { + startProcess() + } + }, 1, 1, TimeUnit.SECONDS) + capsTask = schedulerCaps.scheduleWithFixedDelay({ capabilities = getCaps() if (capabilities.cloudName.isNotEmpty()) { @@ -171,16 +183,18 @@ class LSPProcessHolder(val project: Project): Disposable { vecdb = InferenceGlobalContext.vecdbIsEnabled, ) - if (newConfig == lastConfig) return + val processIsAlive = process?.isAlive == true + + if (newConfig == lastConfig && processIsAlive) return capabilities = LSPCapabilities() terminate() if (!newConfig.isValid) return - logger.warn("LSP start_process " + BIN_PATH + " " + newConfig.toArgs()) var attempt = 0 while (attempt < 5) { try { newConfig.port = (32000..32199).random() + logger.warn("LSP start_process " + BIN_PATH + " " + newConfig.toArgs()) process = GeneralCommandLine(listOf(BIN_PATH) + newConfig.toArgs()) .withRedirectErrorStream(true) .createProcess() @@ -195,7 +209,7 @@ class LSPProcessHolder(val project: Project): Disposable { } } } - loggerTask = scheduler.submit { + loggerTask = loggerScheduler.submit { val reader = process!!.inputStream.bufferedReader() var line = reader.readLine() while (line != null) { @@ -258,8 +272,9 @@ class LSPProcessHolder(val project: Project): Disposable { override fun dispose() { terminate() - scheduler.shutdown() + loggerScheduler.shutdown() schedulerCaps.shutdown() + healthCheckerScheduler.shutdown() } private fun getBuildInfo(): String { From 289fb5a30a02422b907242a6a5c4a15a3ccacb65 Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Wed, 29 May 2024 16:34:04 +0800 Subject: [PATCH 05/10] disable ast/vecdb for free users --- .../smallcloud/refactai/account/LoginUser.kt | 6 +-- .../refactai/io/InferenceGlobalContext.kt | 5 ++ .../refactai/lsp/LSPProcessHolder.kt | 12 +++-- .../refactai/settings/AppSettingsComponent.kt | 13 ++++-- .../settings/AppSettingsConfigurable.kt | 46 ++++++++++++++----- .../refactai/settings/AppSettingsState.kt | 4 +- 6 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt b/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt index c0c38a06..535eeabb 100644 --- a/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt +++ b/src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt @@ -114,6 +114,8 @@ private fun tryLoginWithApiKey(): String { val body = gson.fromJson(result.body, JsonObject::class.java) val retcode = body.get("retcode").asString val humanReadableMessage = if (body.has("human_readable_message")) body.get("human_readable_message").asString else "" + AccountManager.activePlan = null + AccountManager.user = null if (retcode == "OK") { if (body.has("account")) { AccountManager.user = body.get("account").asString @@ -151,14 +153,10 @@ private fun tryLoginWithApiKey(): String { UsageStats?.addStatistic(false, UsageStatistic("login-failed"), url.toString(), humanReadableMessage) return "OK" } else if (retcode == "FAILED") { - AccountManager.user = null - AccountManager.activePlan = null logError("login-failed", humanReadableMessage) UsageStats?.addStatistic(false, UsageStatistic("login-failed"), url.toString(), humanReadableMessage) return "" } else { - AccountManager.user = null - AccountManager.activePlan = null logError("login-failed", "unrecognized response") UsageStats?.addStatistic(false, UsageStatistic("login (2)"), url.toString(), "unrecognized response") return "" diff --git a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt index 025c16ae..86b77564 100644 --- a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt +++ b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt @@ -193,6 +193,11 @@ class InferenceGlobalContext : Disposable { .vecdbFlagChanged(newValue) } + val canUseAstVecDB: Boolean + get() { + return (isCloud && AccountManager.isLoggedIn && listOf("PRO", "TEAMS").contains(AccountManager.activePlan)) || isSelfHosted + } + var xDebugLSPPort: Int? get() { return AppSettingsState.xDebugLSPPort } set(newValue) { diff --git a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt index 8c2ead3b..45e23358 100644 --- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt +++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt @@ -66,8 +66,6 @@ class LSPProcessHolder(val project: Project): Disposable { private val healthCheckerScheduler = AppExecutorUtil.createBoundedScheduledExecutorService( "SMCLSHealthCheckerScheduler", 1 ) - private var healthCheckerTask: Future<*>? = null - init { messageBus @@ -78,6 +76,12 @@ class LSPProcessHolder(val project: Project): Disposable { settingsChanged() } } + + override fun planStatusChanged(newPlan: String?) { + AppExecutorUtil.getAppScheduledExecutorService().submit { + settingsChanged() + } + } }) messageBus .connect(this) @@ -179,8 +183,8 @@ class LSPProcessHolder(val project: Project): Disposable { clientVersion = "${Resources.client}-${Resources.version}/${Resources.jbBuildVersion}", useTelemetry = true, deployment = InferenceGlobalContext.deploymentMode, - ast = InferenceGlobalContext.astIsEnabled, - vecdb = InferenceGlobalContext.vecdbIsEnabled, + ast = InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled, + vecdb = InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled, ) val processIsAlive = process?.isAlive == true diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt index 0344390b..45d78815 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt @@ -16,6 +16,7 @@ import javax.swing.JCheckBox import javax.swing.JComponent import javax.swing.JPanel import javax.swing.ScrollPaneConstants +import com.smallcloud.refactai.io.InferenceGlobalContext.Companion.instance as InferenceGlobalContext class AppSettingsComponent { @@ -42,7 +43,10 @@ class AppSettingsComponent { } private val myContrastUrlText = JBTextField() private val myModelText = JBTextField() - private val astCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useMultipleFilesCompletion")) + val astCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useMultipleFilesCompletion")).apply { + isVisible = true + isEnabled = InferenceGlobalContext.canUseAstVecDB + } private val developerModeCheckBox = JCheckBox(RefactAIBundle.message("advancedSettings.developerMode")).apply { isVisible = false } @@ -60,8 +64,9 @@ class AppSettingsComponent { } private val defaultSystemPromptTextArea = JBTextArea() - private val vecdbCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useVecDB")).apply { + val vecdbCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useVecDB")).apply { isVisible = true + isEnabled = InferenceGlobalContext.canUseAstVecDB } @@ -152,12 +157,12 @@ class AppSettingsComponent { } var astIsEnabled: Boolean - get() = astCheckbox.isSelected + get() = InferenceGlobalContext.canUseAstVecDB && astCheckbox.isSelected set(newVal) { astCheckbox.isSelected = newVal } var vecdbIsEnabled: Boolean - get() = vecdbCheckbox.isSelected + get() = InferenceGlobalContext.canUseAstVecDB && vecdbCheckbox.isSelected set(newVal) { vecdbCheckbox.isSelected = newVal } diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt index d952b968..35cf5083 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt @@ -2,7 +2,6 @@ package com.smallcloud.refactai.settings import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.options.Configurable -import com.intellij.openapi.project.ProjectManager import com.smallcloud.refactai.PluginState import com.smallcloud.refactai.account.AccountManagerChangedNotifier import org.jetbrains.annotations.Nls @@ -21,10 +20,25 @@ class AppSettingsConfigurable : Configurable { .subscribe(AccountManagerChangedNotifier.TOPIC, object : AccountManagerChangedNotifier { override fun apiKeyChanged(newApiKey: String?) { mySettingsComponent?.myTokenText?.let { it.text = newApiKey } + mySettingsComponent?.astCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB + mySettingsComponent?.vecdbCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB + mySettingsComponent?.astIsEnabled = + InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled + mySettingsComponent?.vecdbIsEnabled = + InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled + mySettingsComponent?.splitter?.revalidate() + } + + override fun planStatusChanged(newPlan: String?) { + mySettingsComponent?.astCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB + mySettingsComponent?.vecdbCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB + mySettingsComponent?.astIsEnabled = + InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled + mySettingsComponent?.vecdbIsEnabled = + InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled mySettingsComponent?.splitter?.revalidate() } }) - val project = ProjectManager.getInstance().openProjects.first() } // A default constructor with no arguments is required because this implementation @@ -53,12 +67,12 @@ class AppSettingsConfigurable : Configurable { override fun isModified(): Boolean { var modified = (mySettingsComponent!!.tokenText.isNotEmpty() && (AccountManager.apiKey == null || - mySettingsComponent!!.tokenText.trim() != AccountManager.apiKey)) + mySettingsComponent!!.tokenText.trim() != AccountManager.apiKey)) modified = modified || (mySettingsComponent!!.tokenText.isEmpty() && AccountManager.apiKey != null) modified = modified || (mySettingsComponent!!.contrastUrlText.isNotEmpty() && - mySettingsComponent!!.contrastUrlText != InferenceGlobalContext.inferenceUri) + mySettingsComponent!!.contrastUrlText != InferenceGlobalContext.inferenceUri) modified = modified || (mySettingsComponent!!.contrastUrlText.isEmpty() && !InferenceGlobalContext.isCloud) @@ -67,12 +81,16 @@ class AppSettingsConfigurable : Configurable { modified = modified || mySettingsComponent!!.xDebugLSPPort != InferenceGlobalContext.xDebugLSPPort modified = modified || mySettingsComponent!!.stagingVersion != InferenceGlobalContext.stagingVersion - modified = modified || mySettingsComponent!!.defaultSystemPrompt != AppSettingsState.instance.defaultSystemPrompt + modified = + modified || mySettingsComponent!!.defaultSystemPrompt != AppSettingsState.instance.defaultSystemPrompt - modified = modified || mySettingsComponent!!.astIsEnabled != InferenceGlobalContext.astIsEnabled - modified = modified || mySettingsComponent!!.vecdbIsEnabled != InferenceGlobalContext.vecdbIsEnabled + if (InferenceGlobalContext.canUseAstVecDB) { + modified = modified || mySettingsComponent!!.astIsEnabled != InferenceGlobalContext.astIsEnabled + modified = modified || mySettingsComponent!!.vecdbIsEnabled != InferenceGlobalContext.vecdbIsEnabled + } - modified = modified || mySettingsComponent!!.inferenceModel?.trim()?.ifEmpty { null } != InferenceGlobalContext.model + modified = + modified || mySettingsComponent!!.inferenceModel?.trim()?.ifEmpty { null } != InferenceGlobalContext.model return modified } @@ -86,8 +104,10 @@ class AppSettingsConfigurable : Configurable { InferenceGlobalContext.stagingVersion = mySettingsComponent!!.stagingVersion InferenceGlobalContext.xDebugLSPPort = mySettingsComponent!!.xDebugLSPPort AppSettingsState.instance.defaultSystemPrompt = mySettingsComponent!!.defaultSystemPrompt - InferenceGlobalContext.astIsEnabled = mySettingsComponent!!.astIsEnabled - InferenceGlobalContext.vecdbIsEnabled = mySettingsComponent!!.vecdbIsEnabled + if (InferenceGlobalContext.canUseAstVecDB) { + InferenceGlobalContext.astIsEnabled = mySettingsComponent!!.astIsEnabled + InferenceGlobalContext.vecdbIsEnabled = mySettingsComponent!!.vecdbIsEnabled + } InferenceGlobalContext.model = mySettingsComponent!!.inferenceModel?.trim()?.ifEmpty { null } } @@ -98,8 +118,10 @@ class AppSettingsConfigurable : Configurable { mySettingsComponent!!.stagingVersion = InferenceGlobalContext.stagingVersion mySettingsComponent!!.xDebugLSPPort = InferenceGlobalContext.xDebugLSPPort mySettingsComponent!!.defaultSystemPrompt = AppSettingsState.instance.defaultSystemPrompt - mySettingsComponent!!.astIsEnabled = InferenceGlobalContext.astIsEnabled - mySettingsComponent!!.vecdbIsEnabled = InferenceGlobalContext.vecdbIsEnabled + mySettingsComponent!!.astIsEnabled = + InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled + mySettingsComponent!!.vecdbIsEnabled = + InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled 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 0f3cb97c..15a5e792 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt @@ -44,8 +44,8 @@ class AppSettingsState : PersistentStateComponent { var stagingVersion: String = "" var rateUsNotification: Boolean = false var defaultSystemPrompt: String = "" - var astIsEnabled: Boolean = false - var vecdbIsEnabled: Boolean = false + var astIsEnabled: Boolean = true + var vecdbIsEnabled: Boolean = true @Transient private val messageBus: MessageBus = ApplicationManager.getApplication().messageBus From 6e73118ea24e8122408c083aec8f551b0d1f0f9a Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Wed, 29 May 2024 16:37:47 +0800 Subject: [PATCH 06/10] rollout build settings --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c1913d63..5392b52d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,8 +34,8 @@ repositories { // Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type intellij { // version.set("LATEST-EAP-SNAPSHOT") - version.set("2024.1.2") - type.set("RD") // Target IDE Platform + version.set("2022.3.1") + type.set("PC") // Target IDE Platform plugins.set(listOf( "Git4Idea", From 1f6ca4ed84043379bcf5953abf6124fb0f3fc43d Mon Sep 17 00:00:00 2001 From: Marc McIntosh Date: Wed, 29 May 2024 16:08:58 +0200 Subject: [PATCH 07/10] test: see if auto-scroll is causing bugs in JB --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 11f67490..0cbca9ec 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: alpha + branch: jb-auto-scroll name: refact-chat-js-latest path: ./src/main/resources/webview/dist From 56b8e3c23b849e7622e4cb64beddb81d3ffa9cdc Mon Sep 17 00:00:00 2001 From: Marc McIntosh Date: Wed, 29 May 2024 16:46:47 +0200 Subject: [PATCH 08/10] fix: scroll issue on macos --- .github/workflows/build.yml | 2 +- .../refactai/panes/sharedchat/browser/ChatWebView.kt | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0cbca9ec..11f67490 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: jb-auto-scroll + branch: alpha name: refact-chat-js-latest path: ./src/main/resources/webview/dist diff --git a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/browser/ChatWebView.kt b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/browser/ChatWebView.kt index dac4f918..573b1cd4 100644 --- a/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/browser/ChatWebView.kt +++ b/src/main/kotlin/com/smallcloud/refactai/panes/sharedchat/browser/ChatWebView.kt @@ -32,8 +32,15 @@ class ChatWebView(val messageHandler: (event: Events.FromChat) -> Unit): Dispos } val webView by lazy { + val osName = System.getProperty("os.name").lowercase() + val useOsr = when { + osName.contains("mac") || osName.contains("darwin") -> false + osName.contains("win") -> false + osName.contains("nix") || osName.contains("nux") || osName.contains("aix") -> true + else -> true + } // TODO: handle JBCef not being available - val browser = JBCefBrowser() + val browser = JBCefBrowser.createBuilder().setOffScreenRendering(useOsr).build() browser.jbCefClient.setProperty( JBCefClient.Properties.JS_QUERY_POOL_SIZE, jsPoolSize, From 13995a0b042caa8193b9a01e8f603ac77ef92181 Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Fri, 31 May 2024 17:53:17 +0800 Subject: [PATCH 09/10] ast/vecdb available logic reworked; added ast file limit --- .../refactai/io/InferenceGlobalContext.kt | 14 ++++--- .../InferenceGlobalContextChangedNotifier.kt | 1 + .../com/smallcloud/refactai/lsp/LSPConfig.kt | 7 ++++ .../refactai/lsp/LSPProcessHolder.kt | 10 ++++- .../refactai/settings/AppSettingsComponent.kt | 21 +++++++--- .../settings/AppSettingsConfigurable.kt | 39 ++++++------------- .../refactai/settings/AppSettingsState.kt | 10 ++++- .../resources/bundles/RefactAI.properties | 13 ++++--- 8 files changed, 69 insertions(+), 46 deletions(-) diff --git a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt index 86b77564..586a301b 100644 --- a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt +++ b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContext.kt @@ -184,6 +184,15 @@ class InferenceGlobalContext : Disposable { .astFlagChanged(newValue) } + var astFileLimit: Int + get() { return AppSettingsState.astFileLimit } + set(newValue) { + if (newValue == astFileLimit) return + messageBus + .syncPublisher(InferenceGlobalContextChangedNotifier.TOPIC) + .astFileLimitChanged(newValue) + } + var vecdbIsEnabled: Boolean get() = AppSettingsState.vecdbIsEnabled set(newValue) { @@ -193,11 +202,6 @@ class InferenceGlobalContext : Disposable { .vecdbFlagChanged(newValue) } - val canUseAstVecDB: Boolean - get() { - return (isCloud && AccountManager.isLoggedIn && listOf("PRO", "TEAMS").contains(AccountManager.activePlan)) || isSelfHosted - } - var xDebugLSPPort: Int? get() { return AppSettingsState.xDebugLSPPort } 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 f556d516..ea87fb0b 100644 --- a/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContextChangedNotifier.kt +++ b/src/main/kotlin/com/smallcloud/refactai/io/InferenceGlobalContextChangedNotifier.kt @@ -14,6 +14,7 @@ interface InferenceGlobalContextChangedNotifier { fun developerModeEnabledChanged(newValue: Boolean) {} fun deploymentModeChanged(newMode: DeploymentMode) {} fun astFlagChanged(newValue: Boolean) {} + fun astFileLimitChanged(newValue: Int) {} fun vecdbFlagChanged(newValue: Boolean) {} fun xDebugLSPPortChanged(newPort: Int?) {} diff --git a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt index c9d3d9aa..72947df0 100644 --- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt +++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPConfig.kt @@ -10,6 +10,7 @@ data class LSPConfig( var useTelemetry: Boolean = false, var deployment: DeploymentMode = DeploymentMode.CLOUD, var ast: Boolean = false, + var astFileLimit: Int? = null, var vecdb: Boolean = false ) { fun toArgs(): List { @@ -36,6 +37,10 @@ data class LSPConfig( if (ast) { params.add("--ast") } + if (astFileLimit != null) { + params.add("--ast-index-max-files") + params.add("$astFileLimit") + } if (vecdb) { params.add("--vecdb") } @@ -55,6 +60,7 @@ data class LSPConfig( if (deployment != other.deployment) return false if (ast != other.ast) return false if (vecdb != other.vecdb) return false + if (astFileLimit != other.astFileLimit) return false return true } @@ -64,6 +70,7 @@ data class LSPConfig( return address != null && port != null && clientVersion != null + && (astFileLimit != null && astFileLimit!! > 0) // token must be if we are not selfhosted && (deployment == DeploymentMode.SELF_HOSTED || (apiKey != null && (deployment == DeploymentMode.CLOUD || deployment == DeploymentMode.HF))) diff --git a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt index 45e23358..b236279e 100644 --- a/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt +++ b/src/main/kotlin/com/smallcloud/refactai/lsp/LSPProcessHolder.kt @@ -96,6 +96,11 @@ class LSPProcessHolder(val project: Project): Disposable { settingsChanged() } } + override fun astFileLimitChanged(newValue: Int) { + AppExecutorUtil.getAppScheduledExecutorService().submit { + settingsChanged() + } + } override fun vecdbFlagChanged(newValue: Boolean) { AppExecutorUtil.getAppScheduledExecutorService().submit { settingsChanged() @@ -183,8 +188,9 @@ class LSPProcessHolder(val project: Project): Disposable { clientVersion = "${Resources.client}-${Resources.version}/${Resources.jbBuildVersion}", useTelemetry = true, deployment = InferenceGlobalContext.deploymentMode, - ast = InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled, - vecdb = InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled, + ast = InferenceGlobalContext.astIsEnabled, + astFileLimit = InferenceGlobalContext.astFileLimit, + vecdb = InferenceGlobalContext.vecdbIsEnabled, ) val processIsAlive = process?.isAlive == true diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt index 45d78815..97c26143 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt @@ -16,7 +16,6 @@ import javax.swing.JCheckBox import javax.swing.JComponent import javax.swing.JPanel import javax.swing.ScrollPaneConstants -import com.smallcloud.refactai.io.InferenceGlobalContext.Companion.instance as InferenceGlobalContext class AppSettingsComponent { @@ -43,9 +42,9 @@ class AppSettingsComponent { } private val myContrastUrlText = JBTextField() private val myModelText = JBTextField() + private val myAstFileLimitText = JBTextField() val astCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useMultipleFilesCompletion")).apply { isVisible = true - isEnabled = InferenceGlobalContext.canUseAstVecDB } private val developerModeCheckBox = JCheckBox(RefactAIBundle.message("advancedSettings.developerMode")).apply { isVisible = false @@ -66,7 +65,6 @@ class AppSettingsComponent { val vecdbCheckbox = JCheckBox(RefactAIBundle.message("advancedSettings.useVecDB")).apply { isVisible = true - isEnabled = InferenceGlobalContext.canUseAstVecDB } @@ -101,6 +99,14 @@ class AppSettingsComponent { UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER ), 0 ) + addLabeledComponent(JBLabel("${RefactAIBundle.message("advancedSettings.astFileLimit")}: "), myAstFileLimitText, + (UIUtil.DEFAULT_VGAP * 1.5).toInt(), false) + addComponent( + JBLabel( + RefactAIBundle.message("advancedSettings.astFileLimitDescription"), + UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER + ), 0 + ) addLabeledComponent(JBLabel("${RefactAIBundle.message("advancedSettings.codeCompletionModel")}: "), myModelText, (UIUtil.DEFAULT_VGAP * 1.5).toInt(), false) addComponent( @@ -157,12 +163,17 @@ class AppSettingsComponent { } var astIsEnabled: Boolean - get() = InferenceGlobalContext.canUseAstVecDB && astCheckbox.isSelected + get() = astCheckbox.isSelected set(newVal) { astCheckbox.isSelected = newVal } + var astFileLimit: Int + get() = myAstFileLimitText.text.toIntOrNull() ?: 15000 + set(newVal) { + myAstFileLimitText.text = newVal.toString() + } var vecdbIsEnabled: Boolean - get() = InferenceGlobalContext.canUseAstVecDB && vecdbCheckbox.isSelected + get() = vecdbCheckbox.isSelected set(newVal) { vecdbCheckbox.isSelected = newVal } diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt index 35cf5083..e7c5ee8d 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsConfigurable.kt @@ -20,22 +20,8 @@ class AppSettingsConfigurable : Configurable { .subscribe(AccountManagerChangedNotifier.TOPIC, object : AccountManagerChangedNotifier { override fun apiKeyChanged(newApiKey: String?) { mySettingsComponent?.myTokenText?.let { it.text = newApiKey } - mySettingsComponent?.astCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB - mySettingsComponent?.vecdbCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB - mySettingsComponent?.astIsEnabled = - InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled - mySettingsComponent?.vecdbIsEnabled = - InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled - mySettingsComponent?.splitter?.revalidate() - } - - override fun planStatusChanged(newPlan: String?) { - mySettingsComponent?.astCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB - mySettingsComponent?.vecdbCheckbox?.isEnabled = InferenceGlobalContext.canUseAstVecDB - mySettingsComponent?.astIsEnabled = - InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled - mySettingsComponent?.vecdbIsEnabled = - InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled + mySettingsComponent?.astIsEnabled = InferenceGlobalContext.astIsEnabled + mySettingsComponent?.vecdbIsEnabled = InferenceGlobalContext.vecdbIsEnabled mySettingsComponent?.splitter?.revalidate() } }) @@ -84,10 +70,9 @@ class AppSettingsConfigurable : Configurable { modified = modified || mySettingsComponent!!.defaultSystemPrompt != AppSettingsState.instance.defaultSystemPrompt - if (InferenceGlobalContext.canUseAstVecDB) { - modified = modified || mySettingsComponent!!.astIsEnabled != InferenceGlobalContext.astIsEnabled - modified = modified || mySettingsComponent!!.vecdbIsEnabled != InferenceGlobalContext.vecdbIsEnabled - } + modified = modified || mySettingsComponent!!.astIsEnabled != InferenceGlobalContext.astIsEnabled + modified = modified || mySettingsComponent!!.astFileLimit != InferenceGlobalContext.astFileLimit + modified = modified || mySettingsComponent!!.vecdbIsEnabled != InferenceGlobalContext.vecdbIsEnabled modified = modified || mySettingsComponent!!.inferenceModel?.trim()?.ifEmpty { null } != InferenceGlobalContext.model @@ -104,10 +89,9 @@ class AppSettingsConfigurable : Configurable { InferenceGlobalContext.stagingVersion = mySettingsComponent!!.stagingVersion InferenceGlobalContext.xDebugLSPPort = mySettingsComponent!!.xDebugLSPPort AppSettingsState.instance.defaultSystemPrompt = mySettingsComponent!!.defaultSystemPrompt - if (InferenceGlobalContext.canUseAstVecDB) { - InferenceGlobalContext.astIsEnabled = mySettingsComponent!!.astIsEnabled - InferenceGlobalContext.vecdbIsEnabled = mySettingsComponent!!.vecdbIsEnabled - } + InferenceGlobalContext.astIsEnabled = mySettingsComponent!!.astIsEnabled + InferenceGlobalContext.astFileLimit = mySettingsComponent!!.astFileLimit + InferenceGlobalContext.vecdbIsEnabled = mySettingsComponent!!.vecdbIsEnabled InferenceGlobalContext.model = mySettingsComponent!!.inferenceModel?.trim()?.ifEmpty { null } } @@ -118,10 +102,9 @@ class AppSettingsConfigurable : Configurable { mySettingsComponent!!.stagingVersion = InferenceGlobalContext.stagingVersion mySettingsComponent!!.xDebugLSPPort = InferenceGlobalContext.xDebugLSPPort mySettingsComponent!!.defaultSystemPrompt = AppSettingsState.instance.defaultSystemPrompt - mySettingsComponent!!.astIsEnabled = - InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.astIsEnabled - mySettingsComponent!!.vecdbIsEnabled = - InferenceGlobalContext.canUseAstVecDB && InferenceGlobalContext.vecdbIsEnabled + mySettingsComponent!!.astIsEnabled = InferenceGlobalContext.astIsEnabled + mySettingsComponent!!.astFileLimit = InferenceGlobalContext.astFileLimit + mySettingsComponent!!.vecdbIsEnabled = InferenceGlobalContext.vecdbIsEnabled 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 15a5e792..577d2a21 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsState.kt @@ -45,7 +45,10 @@ class AppSettingsState : PersistentStateComponent { var rateUsNotification: Boolean = false var defaultSystemPrompt: String = "" var astIsEnabled: Boolean = true - var vecdbIsEnabled: Boolean = true + var astIsEnabledDefaultChanged: Boolean = false + var vecdbIsEnabled: Boolean = false + var vecdbIsEnabledDefaultChanged: Boolean = false + var astFileLimit: Int = 15000 @Transient private val messageBus: MessageBus = ApplicationManager.getApplication().messageBus @@ -96,9 +99,14 @@ class AppSettingsState : PersistentStateComponent { override fun astFlagChanged(newValue: Boolean) { instance.astIsEnabled = newValue + instance.astIsEnabledDefaultChanged = true + } + override fun astFileLimitChanged(newValue: Int) { + instance.astFileLimit = newValue } override fun vecdbFlagChanged(newValue: Boolean) { instance.vecdbIsEnabled = newValue + instance.vecdbIsEnabledDefaultChanged = true } override fun xDebugLSPPortChanged(newPort: Int?) { instance.xDebugLSPPort = newPort diff --git a/src/main/resources/bundles/RefactAI.properties b/src/main/resources/bundles/RefactAI.properties index e809a72e..8fb84ee0 100644 --- a/src/main/resources/bundles/RefactAI.properties +++ b/src/main/resources/bundles/RefactAI.properties @@ -45,16 +45,19 @@ rootSettings.overridesModel.message=Privacy policy for "{0}" is now "{1}"\ advancedSettings.secretApiKey=Secret API Key advancedSettings.inferenceURL=Inference URL advancedSettings.inferenceURLDescription=Fill this if you are using your own inference server -advancedSettings.useMultipleFilesCompletion=Use multiple files completion mode (AST) advancedSettings.experimentalFeatures=Experimental features -advancedSettings.useMultipleFilesCompletionDescription=In this mode plugin uses multiple files in its context +advancedSettings.useMultipleFilesCompletion=Ast +advancedSettings.useMultipleFilesCompletionDescription=Enable Abstract Syntax Tree parser, works only for popular languages. \ +
Makes "@defenition" and "@references" commmands work in chat, and helps code completion. advancedSettings.developerMode=Developer mode advancedSettings.defaultSystemPrompt=Default system prompt advancedSettings.codeCompletionModel=Code Completion Model advancedSettings.codeCompletionModelDesc=Which model to use, for example starcoder2/3b. Leave blank if not sure. -advancedSettings.useVecDB=Use multiple files chatting completion (VecDB) -advancedSettings.useVecDBDescription=In this mode plugin uses multiple files in its context for chatting - +advancedSettings.useVecDB=Vecdb +advancedSettings.useVecDBDescription=Enable embedded vector database (VecDB) for search (experimental) +advancedSettings.astFileLimit=Ast File Limit +advancedSettings.astFileLimitDescription=Limit the number of files for AST to process, to avoid memory issues. \ +
Increase if you have a large project and sufficient memory. notifications.loginTo=Login to {0} notifications.login=Login From 30ef9beac78552b0abd296b5d4a3aa3446af3ebb Mon Sep 17 00:00:00 2001 From: Kirill Starkov Date: Mon, 3 Jun 2024 15:24:57 +0800 Subject: [PATCH 10/10] added new ast/vecdb descriptions --- .../refactai/settings/AppSettingsComponent.kt | 8 ++++++-- src/main/resources/bundles/RefactAI.properties | 11 +++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt index 97c26143..7d78d725 100644 --- a/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt +++ b/src/main/kotlin/com/smallcloud/refactai/settings/AppSettingsComponent.kt @@ -90,14 +90,18 @@ class AppSettingsComponent { JBLabel( RefactAIBundle.message("advancedSettings.useMultipleFilesCompletionDescription"), UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER - ), 0 + ).apply { + setCopyable(true) + }, 0 ) addComponent(vecdbCheckbox, UIUtil.LARGE_VGAP) addComponent( JBLabel( RefactAIBundle.message("advancedSettings.useVecDBDescription"), UIUtil.ComponentStyle.SMALL, UIUtil.FontColor.BRIGHTER - ), 0 + ).apply { + setCopyable(true) + }, 0 ) addLabeledComponent(JBLabel("${RefactAIBundle.message("advancedSettings.astFileLimit")}: "), myAstFileLimitText, (UIUtil.DEFAULT_VGAP * 1.5).toInt(), false) diff --git a/src/main/resources/bundles/RefactAI.properties b/src/main/resources/bundles/RefactAI.properties index 8fb84ee0..67b1e8f6 100644 --- a/src/main/resources/bundles/RefactAI.properties +++ b/src/main/resources/bundles/RefactAI.properties @@ -47,14 +47,17 @@ advancedSettings.inferenceURL=Inference URL advancedSettings.inferenceURLDescription=Fill this if you are using your own inference server advancedSettings.experimentalFeatures=Experimental features advancedSettings.useMultipleFilesCompletion=Ast -advancedSettings.useMultipleFilesCompletionDescription=Enable Abstract Syntax Tree parser, works only for popular languages. \ -
Makes "@defenition" and "@references" commmands work in chat, and helps code completion. +advancedSettings.useMultipleFilesCompletionDescription=Enable context-aware chat supporting codebase references: @definition, @references, @symbols-at.
\ + RAG performs better with a larger context, available in the Pro plan \ + and for companies. advancedSettings.developerMode=Developer mode advancedSettings.defaultSystemPrompt=Default system prompt advancedSettings.codeCompletionModel=Code Completion Model advancedSettings.codeCompletionModelDesc=Which model to use, for example starcoder2/3b. Leave blank if not sure. -advancedSettings.useVecDB=Vecdb -advancedSettings.useVecDBDescription=Enable embedded vector database (VecDB) for search (experimental) +advancedSettings.useVecDB=Vecdb (experimental) +advancedSettings.useVecDBDescription=Enable more relevant code completions using your codebase context and @workspace command in chat.
\ + RAG performs better with a larger context, available in the Pro plan \ + and for companies. advancedSettings.astFileLimit=Ast File Limit advancedSettings.astFileLimitDescription=Limit the number of files for AST to process, to avoid memory issues. \
Increase if you have a large project and sufficient memory.