Skip to content

Commit 3916667

Browse files
committed
feat(settings): basic LLMClients table and edit dialog
1 parent 04fe183 commit 3916667

File tree

9 files changed

+188
-8
lines changed

9 files changed

+188
-8
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.github.blarc.ai.commits.intellij.plugin.settings
33
import com.aallam.openai.api.exception.OpenAIAPIException
44
import com.github.blarc.ai.commits.intellij.plugin.*
55
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle.message
6+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClientTable
67
import com.github.blarc.ai.commits.intellij.plugin.settings.prompts.Prompt
78
import com.github.blarc.ai.commits.intellij.plugin.settings.prompts.PromptTable
89
import com.intellij.icons.AllIcons
@@ -29,7 +30,9 @@ class AppSettingsConfigurable : BoundConfigurable(message("settings.general.grou
2930
private val proxyTextField = JBTextField()
3031
private val socketTimeoutTextField = JBTextField()
3132
private var modelComboBox = ComboBox<String>()
33+
private val llmClientTable = LLMClientTable()
3234
private val promptTable = PromptTable()
35+
private lateinit var llmClientToolbarDecorator: ToolbarDecorator
3336
private lateinit var toolbarDecorator: ToolbarDecorator
3437
private lateinit var promptComboBox: Cell<ComboBox<Prompt>>
3538

@@ -135,8 +138,21 @@ class AppSettingsConfigurable : BoundConfigurable(message("settings.general.grou
135138
cell(verifyLabel)
136139
.align(AlignX.RIGHT)
137140
}
141+
142+
row {
143+
llmClientToolbarDecorator = ToolbarDecorator.createDecorator(llmClientTable.table)
144+
.setAddAction {
145+
llmClientTable.addLlmClient()
146+
}
147+
.disableUpDownActions()
148+
149+
cell(llmClientToolbarDecorator.createPanel())
150+
.align(Align.FILL)
151+
}
138152
}
139153

154+
155+
140156
group(JBLabel("Prompt")) {
141157
row {
142158
label(message("settings.locale")).widthGroup("labelPrompt")

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

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

33
import com.aallam.openai.api.model.ModelId
4+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClient
45
import com.github.blarc.ai.commits.intellij.plugin.settings.prompts.Prompt
56
import java.awt.Component
67
import java.util.*
@@ -16,14 +17,22 @@ class AppSettingsListCellRenderer : DefaultListCellRenderer() {
1617
cellHasFocus: Boolean
1718
): Component {
1819
val component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)
19-
if (value is Locale) {
20-
text = value.displayLanguage
21-
}
22-
if (value is Prompt) {
23-
text = value.name
24-
}
25-
if (value is ModelId) {
26-
text = value.id
20+
when (value) {
21+
is Locale -> {
22+
text = value.displayLanguage
23+
}
24+
25+
is Prompt -> {
26+
text = value.name
27+
}
28+
29+
is ModelId -> {
30+
text = value.id
31+
}
32+
33+
is LLMClient -> {
34+
text = value.displayName
35+
}
2736
}
2837
return component
2938
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ abstract class LLMClient(
3939
newToken: String
4040
)
4141

42+
abstract fun panel(): LLMClientPanel
43+
4244
private fun saveToken(token: String) {
4345
try {
4446
PasswordSafe.instance.setPassword(getCredentialAttributes(displayName), token)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients
2+
3+
import javax.swing.JComponent
4+
5+
interface LLMClientPanel {
6+
7+
fun create(): JComponent
8+
9+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle
4+
import com.github.blarc.ai.commits.intellij.plugin.createColumn
5+
import com.github.blarc.ai.commits.intellij.plugin.settings.AppSettings2
6+
import com.intellij.openapi.ui.ComboBox
7+
import com.intellij.openapi.ui.DialogWrapper
8+
import com.intellij.ui.JBCardLayout
9+
import com.intellij.ui.components.Panel
10+
import com.intellij.ui.dsl.builder.Align
11+
import com.intellij.ui.dsl.builder.panel
12+
import com.intellij.ui.table.TableView
13+
import com.intellij.util.ui.ListTableModel
14+
import javax.swing.DefaultComboBoxModel
15+
import javax.swing.ListSelectionModel.SINGLE_SELECTION
16+
17+
class LLMClientTable {
18+
private var llmClients = AppSettings2.instance.llmClients
19+
private val tableModel = createTableModel()
20+
21+
val table = TableView(tableModel).apply {
22+
setShowColumns(true)
23+
setSelectionMode(SINGLE_SELECTION)
24+
}
25+
26+
private fun createTableModel(): ListTableModel<LLMClient> = ListTableModel(
27+
arrayOf(
28+
createColumn<LLMClient>(AICommitsBundle.message("settings.prompt.name")) { llmClient -> llmClient.displayName },
29+
),
30+
llmClients.toList()
31+
)
32+
33+
fun addLlmClient(): LLMClient? {
34+
val dialog = LLMClientDialog()
35+
36+
if (dialog.showAndGet()) {
37+
return null
38+
}
39+
return null
40+
}
41+
42+
private class LLMClientDialog(val newLlmClient: LLMClient? = null) : DialogWrapper(true) {
43+
private val cardLayout = JBCardLayout()
44+
private val cardPanel = Panel(null, cardLayout)
45+
private val llmClients: List<LLMClient> = getLlmClients(newLlmClient)
46+
private val llmClientsComboBox: ComboBox<LLMClient> = createLlmClientsComboBox(newLlmClient)
47+
48+
init {
49+
title = newLlmClient?.let { "Edit LLM Client" } ?: "Add LLM Client"
50+
llmClients.forEach {
51+
cardPanel.add(it.displayName, it.panel().create())
52+
}
53+
cardLayout.show(cardPanel, llmClients[0].displayName)
54+
init()
55+
}
56+
57+
override fun createCenterPanel() = panel {
58+
row("Type") {
59+
cell(llmClientsComboBox)
60+
.align(Align.FILL)
61+
.applyToComponent {
62+
addItemListener { cardLayout.show(cardPanel, (it.item as LLMClient).displayName) }
63+
}
64+
}
65+
row {
66+
cell(cardPanel)
67+
}
68+
}
69+
70+
private fun getLlmClients(newLLMClient: LLMClient?) : List<LLMClient> {
71+
return if (newLLMClient == null) {
72+
// TODO: Find a better way to create the list of all possible LLM Clients that implement LLMClient abstract class
73+
listOf(
74+
OpenAIClient(),
75+
TestAIClient()
76+
)
77+
} else {
78+
listOf(newLLMClient)
79+
}
80+
}
81+
82+
private fun createLlmClientsComboBox(newLLMClient: LLMClient?) : ComboBox<LLMClient> {
83+
val comboBoxModel = DefaultComboBoxModel(getLlmClients(newLLMClient).toTypedArray())
84+
with(ComboBox(comboBoxModel)){
85+
// Type of LLM Client can not be changed when editing a LLM Client
86+
if (newLLMClient != null) isEnabled = false
87+
return this
88+
}
89+
}
90+
}
91+
92+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class OpenAIClient(displayName: String = "OpenAI") : LLMClient(
7070
openAI.models()
7171
}
7272

73+
override fun panel(): LLMClientPanel {
74+
return OpenAIClientPanel(this)
75+
}
76+
7377
private fun openAIConfig() = OpenAIConfig(
7478
token,
7579
host = host.takeIf { it.isNotBlank() }?.let { OpenAIHost(it) } ?: OpenAIHost.OpenAI,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle
4+
import com.intellij.openapi.ui.ComboBox
5+
import com.intellij.ui.dsl.builder.bindItem
6+
import com.intellij.ui.dsl.builder.panel
7+
import com.intellij.ui.dsl.builder.toNullableProperty
8+
9+
class OpenAIClientPanel(private val client: OpenAIClient) : LLMClientPanel {
10+
11+
private val hostComboBox = ComboBox(client.hosts.toTypedArray())
12+
13+
override fun create() = panel {
14+
row {
15+
label(AICommitsBundle.message("settings.openAIHost"))
16+
.widthGroup("label")
17+
18+
cell(hostComboBox)
19+
.bindItem(client::host.toNullableProperty())
20+
.widthGroup("input")
21+
}
22+
}
23+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ class TestAIClient(displayName: String = "TestAI") : LLMClient(
2020
override suspend fun verifyConfiguration(newHost: String, newProxy: String?, newTimeout: String, newToken: String) {
2121
}
2222

23+
override fun panel(): LLMClientPanel {
24+
return TestAIClientPanel(this)
25+
}
2326
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients
2+
3+
import com.intellij.openapi.ui.ComboBox
4+
import com.intellij.ui.dsl.builder.bindItem
5+
import com.intellij.ui.dsl.builder.panel
6+
import com.intellij.ui.dsl.builder.toNullableProperty
7+
8+
class TestAIClientPanel(private val client: TestAIClient): LLMClientPanel {
9+
10+
private val hostComboBox = ComboBox(client.hosts.toTypedArray())
11+
12+
override fun create() = panel {
13+
row {
14+
label("Test AI")
15+
.widthGroup("label")
16+
17+
cell(hostComboBox)
18+
.bindItem(client::host.toNullableProperty())
19+
.widthGroup("input")
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)