Skip to content

Commit 6604477

Browse files
committed
feat(settings): setting migration
1 parent e6feea3 commit 6604477

File tree

12 files changed

+178
-105
lines changed

12 files changed

+178
-105
lines changed

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/AICommitAction.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.github.blarc.ai.commits.intellij.plugin.AICommitsUtils.constructPromp
77
import com.github.blarc.ai.commits.intellij.plugin.AICommitsUtils.isPromptTooLarge
88
import com.github.blarc.ai.commits.intellij.plugin.notifications.Notification
99
import com.github.blarc.ai.commits.intellij.plugin.notifications.sendNotification
10-
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings
10+
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2
1111
import com.intellij.openapi.actionSystem.AnAction
1212
import com.intellij.openapi.actionSystem.AnActionEvent
1313
import com.intellij.openapi.progress.runBackgroundableTask
@@ -40,7 +40,7 @@ class AICommitAction : AnAction(), DumbAware {
4040

4141
val branch = commonBranch(includedChanges, project)
4242
val hint = commitMessage?.text
43-
val prompt = constructPrompt(AppSettings.instance.currentPrompt.content, diff, branch, hint)
43+
val prompt = constructPrompt(AppSettings2.instance.currentPrompt.content, diff, branch, hint)
4444
if (isPromptTooLarge(prompt)) {
4545
sendNotification(Notification.promptTooLarge())
4646
return@runBackgroundableTask
@@ -56,7 +56,7 @@ class AICommitAction : AnAction(), DumbAware {
5656
try {
5757
val generatedCommitMessage = openAIService.generateCommitMessage(prompt)
5858
commitMessage.setCommitMessage(generatedCommitMessage)
59-
AppSettings.instance.recordHit()
59+
AppSettings2.instance.recordHit()
6060
} catch (e: Exception) {
6161
commitMessage.setCommitMessage(e.message ?: message("action.error"))
6262
sendNotification(Notification.unsuccessfulRequest(e.message ?: message("action.unknown-error")))

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/AICommitsUtils.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.github.blarc.ai.commits.intellij.plugin
22

33
import com.github.blarc.ai.commits.intellij.plugin.notifications.Notification
44
import com.github.blarc.ai.commits.intellij.plugin.notifications.sendNotification
5-
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings
5+
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2
66
import com.github.blarc.ai.commits.intellij.plugin.settings.ProjectSettings
77
import com.intellij.credentialStore.CredentialAttributes
88
import com.intellij.credentialStore.Credentials
@@ -21,7 +21,7 @@ import java.nio.file.FileSystems
2121
object AICommitsUtils {
2222

2323
fun isPathExcluded(path: String, project: Project): Boolean {
24-
return !AppSettings.instance.isPathExcluded(path) && !project.service<ProjectSettings>().isPathExcluded(path)
24+
return !AppSettings2.instance.isPathExcluded(path) && !project.service<ProjectSettings>().isPathExcluded(path)
2525
}
2626

2727
fun matchesGlobs(text: String, globs: Set<String>): Boolean {
@@ -37,7 +37,7 @@ object AICommitsUtils {
3737

3838
fun constructPrompt(promptContent: String, diff: String, branch: String, hint: String?): String {
3939
var content = promptContent
40-
content = content.replace("{locale}", AppSettings.instance.locale.displayLanguage)
40+
content = content.replace("{locale}", AppSettings2.instance.locale.displayLanguage)
4141
content = content.replace("{branch}", branch)
4242
content = replaceHint(content, hint)
4343

@@ -130,7 +130,7 @@ object AICommitsUtils {
130130
* If no model type matches, let the request go through and let the OpenAI API handle it
131131
*/
132132
val modelType = ModelType.entries
133-
.filter { AppSettings.instance.currentLlmProvider.modelId.contains(it.name) }
133+
.filter { AppSettings2.instance.getActiveLLMClient().modelId.contains(it.name) }
134134
.maxByOrNull { it.name.length }
135135
?: return false
136136

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/OpenAIService.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.github.blarc.ai.commits.intellij.plugin
22

33
import com.aallam.openai.api.chat.*
4-
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings
4+
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2
55
import com.intellij.openapi.application.ApplicationManager
66
import com.intellij.openapi.components.Service
77

@@ -15,15 +15,15 @@ class OpenAIService {
1515
}
1616

1717
suspend fun generateCommitMessage(prompt: String): String {
18-
return AppSettings.instance.currentLlmProvider.generateCommitMessage(prompt)
18+
return AppSettings2.instance.getActiveLLMClient().generateCommitMessage(prompt)
1919
}
2020

2121
suspend fun refreshOpenAIModelIds() {
22-
AppSettings.instance.currentLlmProvider.refreshModels()
22+
AppSettings2.instance.getActiveLLMClient().refreshModels()
2323
}
2424

2525
@Throws(Exception::class)
2626
suspend fun verifyOpenAIConfiguration(host: String, proxy: String?, timeout: String, token: String){
27-
AppSettings.instance.currentLlmProvider.verifyConfiguration(host, proxy, timeout, token)
27+
AppSettings2.instance.getActiveLLMClient().verifyConfiguration(host, proxy, timeout, token)
2828
}
2929
}

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/listeners/ApplicationStartupListener.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.github.blarc.ai.commits.intellij.plugin.listeners
33
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle
44
import com.github.blarc.ai.commits.intellij.plugin.notifications.Notification
55
import com.github.blarc.ai.commits.intellij.plugin.notifications.sendNotification
6-
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings
6+
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2
77
import com.intellij.openapi.project.Project
88
import com.intellij.openapi.startup.ProjectActivity
99

@@ -14,7 +14,7 @@ class ApplicationStartupListener : ProjectActivity {
1414
showVersionNotification(project)
1515
}
1616
private fun showVersionNotification(project: Project) {
17-
val settings = AppSettings.instance
17+
val settings = AppSettings2.instance
1818
val version = AICommitsBundle.plugin()?.version
1919

2020
if (version == settings.lastVersion) {
@@ -27,4 +27,4 @@ class ApplicationStartupListener : ProjectActivity {
2727
}
2828
firstTime = false
2929
}
30-
}
30+
}

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/notifications/Notification.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.github.blarc.ai.commits.intellij.plugin.notifications
33
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle
44
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle.message
55
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle.openPluginSettings
6-
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings
6+
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2
77
import com.intellij.ide.browsers.BrowserLauncher
88
import com.intellij.openapi.components.service
99
import com.intellij.openapi.project.Project
@@ -31,10 +31,10 @@ data class Notification(
3131
""".trimIndent(),
3232
actions = setOf(
3333
NotificationAction.openRepository() {
34-
service<AppSettings>().requestSupport = false;
34+
service<AppSettings2>().requestSupport = false;
3535
},
3636
NotificationAction.doNotAskAgain() {
37-
service<AppSettings>().requestSupport = false;
37+
service<AppSettings2>().requestSupport = false;
3838
}
3939
)
4040
)

src/main/kotlin/com/github/blarc/ai/commits/intellij/plugin/settings/AppSettings.kt

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,60 @@
11
package com.github.blarc.ai.commits.intellij.plugin.settings
22

3-
import com.aallam.openai.client.OpenAI
43
import com.aallam.openai.client.OpenAIHost
5-
import com.github.blarc.ai.commits.intellij.plugin.AICommitsUtils
6-
import com.github.blarc.ai.commits.intellij.plugin.notifications.Notification
7-
import com.github.blarc.ai.commits.intellij.plugin.notifications.sendNotification
84
import com.github.blarc.ai.commits.intellij.plugin.settings.prompts.DefaultPrompts
9-
import com.github.blarc.ai.commits.intellij.plugin.settings.providers.OpenAIClient
105
import com.intellij.openapi.application.ApplicationManager
116
import com.intellij.openapi.components.PersistentStateComponent
7+
import com.intellij.openapi.components.Service
128
import com.intellij.openapi.components.State
139
import com.intellij.openapi.components.Storage
1410
import com.intellij.util.xmlb.Converter
1511
import com.intellij.util.xmlb.XmlSerializerUtil
1612
import com.intellij.util.xmlb.annotations.OptionTag
1713
import java.util.*
1814

15+
1916
@State(
2017
name = AppSettings.SERVICE_NAME,
21-
storages = [
22-
Storage("AICommit.xml", deprecated = true),
23-
Storage("AICommits2.xml")
24-
]
18+
storages = [Storage("AICommit.xml")]
2519
)
20+
@Service(Service.Level.APP)
21+
//@Deprecated("No longer used. Need for migration.")
2622
class AppSettings : PersistentStateComponent<AppSettings> {
2723

28-
private var hits = 0
29-
var requestSupport = true
30-
var lastVersion: String? = null
24+
val openAITokenTitle = "OpenAIToken"
25+
var hits = 0
3126

3227
@OptionTag(converter = LocaleConverter::class)
3328
var locale: Locale = Locale.ENGLISH
3429

35-
var llmProviders = setOf(OpenAIClient.instance)
36-
var currentLlmProvider = OpenAIClient.instance
37-
38-
var prompts = DefaultPrompts.toPromptsMap()
39-
var currentPrompt = prompts["basic"]!!
40-
41-
var appExclusions: Set<String> = setOf()
42-
43-
// Old single LLM provider configuration - needed for migration
44-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
30+
var requestSupport = true
31+
var lastVersion: String? = null
4532
var openAIHost = OpenAIHost.OpenAI.baseUrl
46-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
4733
var openAIHosts = mutableSetOf(OpenAIHost.OpenAI.baseUrl)
48-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
4934
var openAISocketTimeout = "30"
50-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
5135
var proxyUrl: String? = null
52-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
36+
37+
var prompts = DefaultPrompts.toPromptsMap()
38+
var currentPrompt = prompts["basic"]!!
39+
5340
var openAIModelId = "gpt-3.5-turbo"
54-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
5541
var openAIModelIds = listOf("gpt-3.5-turbo", "gpt-4")
56-
@Deprecated("Old configuration property that is no longer used. Needed only for migrating.")
5742
var openAITemperature = "0.7"
5843

59-
override fun getState() = this
60-
61-
override fun loadState(state: AppSettings) {
62-
XmlSerializerUtil.copyBean(state, this)
63-
64-
// Migration from single LLM provider to multiple LLM providers
65-
OpenAIClient.instance.host = openAIHost
66-
OpenAIClient.instance.hosts = openAIHosts
67-
openAISocketTimeout.toIntOrNull()?.let { OpenAIClient.instance.timeout = it }
68-
proxyUrl?.let { OpenAIClient.instance.proxyUrl = it }
69-
OpenAIClient.instance.modelId = openAIModelId
70-
OpenAIClient.instance.modelIds = openAIModelIds
71-
OpenAIClient.instance.temperature = openAITemperature
72-
AICommitsUtils.retrieveToken( "OpenAIToken")?.let { OpenAIClient.instance.token = it }
73-
}
74-
75-
fun recordHit() {
76-
hits++
77-
if (requestSupport && (hits == 50 || hits % 100 == 0)) {
78-
sendNotification(Notification.star())
79-
}
80-
}
81-
82-
fun isPathExcluded(path: String): Boolean {
83-
return AICommitsUtils.matchesGlobs(path, appExclusions)
84-
}
44+
var appExclusions: Set<String> = setOf()
8545

8646
companion object {
8747
const val SERVICE_NAME = "com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings"
8848
val instance: AppSettings
8949
get() = ApplicationManager.getApplication().getService(AppSettings::class.java)
9050
}
9151

52+
override fun getState() = null
53+
54+
override fun loadState(state: AppSettings) {
55+
XmlSerializerUtil.copyBean(state, this)
56+
}
57+
9258
class LocaleConverter : Converter<Locale>() {
9359
override fun toString(value: Locale): String? {
9460
return value.toLanguageTag()
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.AICommitsUtils
4+
import com.github.blarc.ai.commits.intellij.plugin.notifications.Notification
5+
import com.github.blarc.ai.commits.intellij.plugin.notifications.sendNotification
6+
import com.github.blarc.ai.commits.intellij.plugin.settings.prompts.DefaultPrompts
7+
import com.github.blarc.ai.commits.intellij.plugin.settings.providers.LLMClient
8+
import com.github.blarc.ai.commits.intellij.plugin.settings.providers.OpenAIClient
9+
import com.intellij.openapi.application.ApplicationManager
10+
import com.intellij.openapi.components.PersistentStateComponent
11+
import com.intellij.openapi.components.Service
12+
import com.intellij.openapi.components.State
13+
import com.intellij.openapi.components.Storage
14+
import com.intellij.util.xmlb.Converter
15+
import com.intellij.util.xmlb.XmlSerializerUtil
16+
import com.intellij.util.xmlb.annotations.OptionTag
17+
import java.util.*
18+
19+
@State(
20+
name = AppSettings2.SERVICE_NAME,
21+
storages = [
22+
Storage("AICommits2.xml")
23+
]
24+
)
25+
@Service(Service.Level.APP)
26+
class AppSettings2 : PersistentStateComponent<AppSettings2> {
27+
28+
companion object {
29+
const val SERVICE_NAME = "com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2"
30+
val instance: AppSettings2
31+
get() = ApplicationManager.getApplication().getService(AppSettings2::class.java)
32+
}
33+
34+
private var hits = 0
35+
var requestSupport = true
36+
var lastVersion: String? = null
37+
38+
@OptionTag(converter = LocaleConverter::class)
39+
var locale: Locale = Locale.ENGLISH
40+
41+
private var activeLlmClient = "OpenAI"
42+
var llmClients = mapOf(
43+
"OpenAI" to OpenAIClient()
44+
)
45+
46+
var prompts = DefaultPrompts.toPromptsMap()
47+
var currentPrompt = prompts["basic"]!!
48+
49+
var appExclusions: Set<String> = setOf()
50+
51+
override fun getState() = this
52+
53+
override fun loadState(state: AppSettings2) {
54+
XmlSerializerUtil.copyBean(state, this)
55+
}
56+
57+
override fun noStateLoaded() {
58+
val appSettings = AppSettings.instance
59+
60+
// Migration from old settings
61+
hits = appSettings.hits
62+
locale = appSettings.locale
63+
lastVersion = appSettings.lastVersion
64+
requestSupport = appSettings.requestSupport
65+
66+
prompts = appSettings.prompts
67+
currentPrompt = appSettings.currentPrompt
68+
69+
appExclusions = appSettings.appExclusions
70+
71+
// TODO: currentLlmClient vs OpenAIClient.instance()
72+
llmClients["OpenAI"]?.host = appSettings.openAIHost
73+
llmClients["OpenAI"]?.hosts = appSettings.openAIHosts
74+
appSettings.openAISocketTimeout.toIntOrNull()?.let { llmClients["OpenAI"]?.timeout = it }
75+
appSettings.proxyUrl?.let { llmClients["OpenAI"]?.proxyUrl = it }
76+
llmClients["OpenAI"]?.modelId = appSettings.openAIModelId
77+
llmClients["OpenAI"]?.modelIds = appSettings.openAIModelIds
78+
llmClients["OpenAI"]?.temperature = appSettings.openAITemperature
79+
AICommitsUtils.retrieveToken( appSettings.openAITokenTitle)?.let { llmClients["OpenAI"]?.token = it }
80+
}
81+
82+
fun recordHit() {
83+
hits++
84+
if (requestSupport && (hits == 50 || hits % 100 == 0)) {
85+
sendNotification(Notification.star())
86+
}
87+
}
88+
89+
fun isPathExcluded(path: String): Boolean {
90+
return AICommitsUtils.matchesGlobs(path, appExclusions)
91+
}
92+
93+
fun getActiveLLMClient(): LLMClient {
94+
return llmClients[activeLlmClient]!!
95+
}
96+
97+
fun setActiveLlmClient(llmClientName: String) {
98+
// TODO @Blarc: Throw exception if llm client name is not valid
99+
llmClients[llmClientName]?.let {
100+
activeLlmClient = llmClientName
101+
}
102+
}
103+
104+
class LocaleConverter : Converter<Locale>() {
105+
override fun toString(value: Locale): String? {
106+
return value.toLanguageTag()
107+
}
108+
109+
override fun fromString(value: String): Locale? {
110+
return Locale.forLanguageTag(value)
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)