Skip to content

Commit

Permalink
return toolbox
Browse files Browse the repository at this point in the history
  • Loading branch information
reymondzzzz committed Nov 24, 2023
1 parent 97c6225 commit b43c234
Show file tree
Hide file tree
Showing 49 changed files with 3,618 additions and 38 deletions.
7 changes: 2 additions & 5 deletions src/main/kotlin/com/smallcloud/refactai/Initializer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import com.intellij.ide.plugins.PluginInstaller
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.ProjectActivity
import com.intellij.openapi.util.Disposer
import com.smallcloud.refactai.account.LoginStateService
import com.smallcloud.refactai.account.login
import com.smallcloud.refactai.io.ConnectivityManager
Expand All @@ -27,9 +25,8 @@ class Initializer : ProjectActivity, Disposable {
initialize(project)
}
private fun initialize(project: Project) {
val listener = LastEditorGetterListener()
Disposer.register(PluginState.instance, listener)
EditorFactory.getInstance().addEditorFactoryListener(listener, PluginState.instance)
val listener = LastEditorGetterListener.instance
// Disposer.register(PluginState.instance, listener)

Logger.getInstance("SMCInitializer").info("Bin prefix = ${Resources.binPrefix}")
ConnectivityManager.instance.startup()
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/com/smallcloud/refactai/Resources.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ object Resources {
const val defaultCloudAuthLink: String = "https://refact.smallcloud.ai/authentication?token=%s&utm_source=plugin&utm_medium=jetbrains&utm_campaign=login"
val defaultCloudUrl: URI = URI("https://www.smallcloud.ai")
val defaultCodeCompletionUrlSuffix = URI("v1/code-completion")
val defaultContrastUrlSuffix = URI("v1/contrast")
val defaultChatUrlSuffix = URI("v1/chat")
val defaultRecallUrl: URI = defaultCloudUrl.resolve("/v1/streamlined-login-recall-ticket")
val loginSuffixUrl = URI("v1/login")
val defaultLikeReportUrl: URI = defaultCloudUrl.resolve("/v1/longthink-like")
val defaultLoginUrl: URI = defaultCloudUrl.resolve(loginSuffixUrl)
val defaultReportUrlSuffix: URI = URI("v1/telemetry-network")
val defaultSnippetAcceptedUrlSuffix: URI = URI("v1/snippet-accepted")
Expand All @@ -77,6 +79,7 @@ object Resources {
const val loginCoolDown: Int = 300 // sec
const val titleStr: String = "RefactAI"
val pluginId: PluginId = getPluginId()
const val stagingFilterPrefix: String = "STAGING"
val jbBuildVersion: String = ApplicationInfo.getInstance().build.toString()
const val refactAIRootSettingsID = "refactai_root"

Expand Down
21 changes: 20 additions & 1 deletion src/main/kotlin/com/smallcloud/refactai/account/LoginUser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ import com.smallcloud.refactai.Resources.defaultRecallUrl
import com.smallcloud.refactai.Resources.loginSuffixUrl
import com.smallcloud.refactai.io.ConnectionStatus
import com.smallcloud.refactai.io.sendRequest
import com.smallcloud.refactai.listeners.QuickLongthinkActionsService.Companion.instance as QuickLongthinkActionsServiceInstance
import com.smallcloud.refactai.aitoolbox.LongthinkFunctionProvider.Companion.instance as DiffIntentProviderInstance
import com.smallcloud.refactai.settings.ExtraState.Companion.instance as ExtraState
import com.smallcloud.refactai.statistic.UsageStatistic
import com.smallcloud.refactai.struct.DeploymentMode
import com.smallcloud.refactai.struct.LongthinkFunctionEntry
import com.smallcloud.refactai.utils.makeGson
import org.apache.http.client.utils.URIBuilder
import java.net.URI
import com.smallcloud.refactai.account.AccountManager.Companion.instance as AccountManager
Expand Down Expand Up @@ -110,7 +115,7 @@ private fun tryLoginWithApiKey(): String {
try {
val result = sendRequest(url, "GET", headers, requestProperties = mapOf("redirect" to "follow", "cache" to "no-cache", "referrer" to "no-referrer"))

val gson = Gson()
val gson = makeGson()
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 ""
Expand All @@ -135,6 +140,20 @@ private fun tryLoginWithApiKey(): String {
PluginState.instance.loginMessage = body.get("login_message").asString
}

if (body.has("longthink-functions-today-v2")) {
val cloudEntries = body.get("longthink-functions-today-v2").asJsonObject.entrySet().map {
val elem = gson.fromJson(it.value, LongthinkFunctionEntry::class.java)
elem.entryName = it.key
return@map elem.mergeLocalInfo(ExtraState.getLocalLongthinkInfo(elem.entryName))
}
DiffIntentProviderInstance.defaultThirdPartyFunctions = cloudEntries
QuickLongthinkActionsServiceInstance.recreateActions()
}

if (body.has("longthink-filters")) {
val filters = body.get("longthink-filters").asJsonArray.map { it.asString }
DiffIntentProviderInstance.intentFilters = filters
}
if (body.has("metering_balance")) {
AccountManager.meteringBalance = body.get("metering_balance").asInt
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.smallcloud.refactai.aitoolbox

import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.ui.getUserData
import com.intellij.openapi.util.Key
import com.smallcloud.refactai.listeners.AIToolboxInvokeAction
import com.smallcloud.refactai.listeners.LastEditorGetterListener
import com.smallcloud.refactai.struct.LongthinkFunctionEntry
import com.smallcloud.refactai.struct.LongthinkFunctionVariation
import javax.swing.JComponent

val LongthinkKey = Key.create<LongthinkFunctionVariation>("refact.longthink")

class LongthinkAction: DumbAwareAction() {
override fun actionPerformed(e: AnActionEvent) {
val longthink = (e.inputEvent?.component as JComponent).getUserData(LongthinkKey)
if (longthink?.entryName?.isNotEmpty() == true) {
doActionPerformed(longthink.functions.first())
}
}
fun doActionPerformed(longthink: LongthinkFunctionEntry) {
LastEditorGetterListener.LAST_EDITOR?.let { AIToolboxInvokeAction().doActionPerformed(it, longthink) }
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.smallcloud.refactai.aitoolbox

import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.util.messages.Topic
import com.smallcloud.refactai.struct.LongthinkFunctionEntry
import com.smallcloud.refactai.struct.LongthinkFunctionVariation
import com.smallcloud.refactai.struct.ShortLongthinkHistoryInfo
import com.smallcloud.refactai.settings.ExtraState.Companion.instance as ExtraState

interface LongthinkFunctionProviderChangedNotifier {
fun longthinkFunctionsChanged(functions: List<LongthinkFunctionEntry>) {}
fun longthinkFiltersChanged(filters: List<String>) {}

companion object {
val TOPIC = Topic.create(
"Longthink Function Provider Changed Notifier",
LongthinkFunctionProviderChangedNotifier::class.java
)
}
}


class LongthinkFunctionProvider: Disposable {
private var _cloudIntents: List<LongthinkFunctionEntry> = emptyList()
private var _intentFilters: List<String> = emptyList()

var intentFilters: List<String>
get() = _intentFilters
set(newList) {
if (_intentFilters != newList) {
_intentFilters = newList
ApplicationManager.getApplication().messageBus
.syncPublisher(LongthinkFunctionProviderChangedNotifier.TOPIC)
.longthinkFiltersChanged(_intentFilters)
}
}

val functionVariations: List<LongthinkFunctionVariation>
get() {
val functionNameToVariations = mutableMapOf<String, Pair<MutableList<String>,
MutableList<LongthinkFunctionEntry>>>()

for (func in defaultThirdPartyFunctions) {
val matchedFilter = _intentFilters.firstOrNull { func.functionName.endsWith(it) }
val funcName = if (matchedFilter != null)
func.functionName.substring(0, func.functionName.length - matchedFilter.length - 1) else
func.functionName
val filtersAndVariations = functionNameToVariations.getOrPut(funcName) { Pair(mutableListOf(), mutableListOf()) }
filtersAndVariations.first.add(matchedFilter ?: "")
filtersAndVariations.second.add(func)
}
return functionNameToVariations.map { LongthinkFunctionVariation(it.value.second, it.value.first) }
}

var defaultThirdPartyFunctions: List<LongthinkFunctionEntry>
get(): List<LongthinkFunctionEntry> {
return _cloudIntents.filter { !(it.functionName.contains("free-chat") ||
it.functionName.contains("completion")) }
}
set(newList) {
if (_cloudIntents != newList) {
_cloudIntents = newList
ApplicationManager.getApplication().messageBus
.syncPublisher(LongthinkFunctionProviderChangedNotifier.TOPIC)
.longthinkFunctionsChanged(_cloudIntents)
}
}

var historyIntents: List<LongthinkFunctionEntry>
set(newVal) {
ExtraState.historyEntries = newVal.map { ShortLongthinkHistoryInfo.fromEntry(it) }
}
get() = ExtraState.historyEntries.map { shortInfo ->
var appropriateEntry = _cloudIntents.find { it.functionName == shortInfo.functionName } ?: return@map null
appropriateEntry = appropriateEntry.mergeShortInfo(shortInfo)
if (appropriateEntry.intent.isEmpty()) return@map null
appropriateEntry
}.filterNotNull()


fun pushFrontHistoryIntent(newEntry: LongthinkFunctionEntry) {
if (newEntry.intent.isEmpty()) return
var srcHints = historyIntents.filter { it.intent != newEntry.intent }
srcHints = srcHints.subList(0, minOf(srcHints.size, 20))
historyIntents = listOf(newEntry) + srcHints
}

fun lastHistoryEntry(): LongthinkFunctionEntry? {
return historyIntents.firstOrNull()
}

val allChats: List<LongthinkFunctionEntry>
get() {
return _cloudIntents.filter {
it.functionName.contains("chat") && it.model?.isNotEmpty() ?: false
}
}

companion object {
@JvmStatic
val instance: LongthinkFunctionProvider
get() = ApplicationManager.getApplication().getService(LongthinkFunctionProvider::class.java)
}

override fun dispose() {}

fun cleanUp() {
defaultThirdPartyFunctions = emptyList()
intentFilters = emptyList()
}
}
6 changes: 6 additions & 0 deletions src/main/kotlin/com/smallcloud/refactai/aitoolbox/Mode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.smallcloud.refactai.aitoolbox

enum class Mode {
FILTER,
HISTORY,
}
40 changes: 40 additions & 0 deletions src/main/kotlin/com/smallcloud/refactai/aitoolbox/State.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.smallcloud.refactai.aitoolbox

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.LogicalPosition
import com.smallcloud.refactai.listeners.LastEditorGetterListener
import com.smallcloud.refactai.struct.LongthinkFunctionEntry


object State {
var entry: LongthinkFunctionEntry = LongthinkFunctionEntry()
var currentIntent: String = ""
var historyIndex: Int = -1
val startPosition: LogicalPosition = LogicalPosition(0, 0)
val finishPosition: LogicalPosition = LogicalPosition(0, 0)
val activeFilters: MutableSet<String> = mutableSetOf()

val activeMode: Mode
get() {
return if (historyIndex >= 0) {
Mode.HISTORY
} else {
Mode.FILTER
}
}

val editor: Editor?
get() {
return LastEditorGetterListener.LAST_EDITOR
}

val haveSelection: Boolean
get() {
var hasSelection = false
ApplicationManager.getApplication().invokeAndWait {
hasSelection = editor?.selectionModel?.hasSelection() ?: false
}
return hasSelection
}
}
Loading

0 comments on commit b43c234

Please sign in to comment.