Skip to content

Commit 091ca1b

Browse files
committed
feat(clients): support gemini
1 parent 54e93bf commit 091ca1b

File tree

8 files changed

+185
-0
lines changed

8 files changed

+185
-0
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ dependencies {
127127
implementation("dev.langchain4j:langchain4j-open-ai:0.32.0")
128128
implementation("dev.langchain4j:langchain4j-ollama:0.32.0")
129129
implementation("dev.langchain4j:langchain4j-qianfan:0.32.0") // The Baidu Qianfan Large Model Platform, including the ERNIE series, can be accessed at https://docs.langchain4j.dev/integrations/language-models/qianfan/.
130+
implementation("dev.langchain4j:langchain4j-vertex-ai-gemini:0.32.0")
130131
// implementation("dev.langchain4j:langchain4j-hugging-face:0.28.0")
131132
// implementation("dev.langchain4j:langchain4j-milvus:0.28.0")
132133
// implementation("dev.langchain4j:langchain4j-local-ai:0.28.0")

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ object Icons {
77
val OPEN_AI = IconLoader.getIcon("/icons/openai.svg", javaClass)
88
val OLLAMA = IconLoader.getIcon("/icons/ollama15.svg", javaClass)
99
val QIANFAN = IconLoader.getIcon("/icons/qianfan.png", javaClass)
10+
val GEMINI = IconLoader.getIcon("/icons/gemini.png", javaClass)
1011
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients.gemini
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.Icons
4+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClientConfiguration
5+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClientSharedState
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.vcs.ui.CommitMessage
8+
import com.intellij.util.xmlb.annotations.Attribute
9+
import javax.swing.Icon
10+
11+
class GeminiClientConfiguration : LLMClientConfiguration(
12+
"Gemini",
13+
"gemini-pro",
14+
"0.7"
15+
) {
16+
@Attribute
17+
var projectId: String = ""
18+
@Attribute
19+
var location: String = "us-central1"
20+
21+
companion object {
22+
const val CLIENT_NAME = "Gemini"
23+
}
24+
25+
override fun getClientName(): String {
26+
return CLIENT_NAME
27+
}
28+
29+
override fun getClientIcon(): Icon {
30+
return Icons.GEMINI
31+
}
32+
33+
override fun getSharedState(): LLMClientSharedState {
34+
return GeminiClientSharedState.getInstance()
35+
}
36+
37+
override fun generateCommitMessage(prompt: String, project: Project, commitMessage: CommitMessage) {
38+
return GeminiClientService.getInstance().generateCommitMessage(this, prompt, project, commitMessage)
39+
}
40+
41+
// Model names are hard-coded and do not need to be refreshed.
42+
override fun getRefreshModelsFunction() = null
43+
44+
override fun clone(): LLMClientConfiguration {
45+
val copy = GeminiClientConfiguration()
46+
copy.id = id
47+
copy.name = name
48+
copy.modelId = modelId
49+
copy.temperature = temperature
50+
copy.projectId = projectId
51+
copy.location = location
52+
return copy
53+
}
54+
55+
override fun panel() = GeminiClientPanel(this)
56+
57+
58+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients.gemini
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.AICommitsBundle.message
4+
import com.github.blarc.ai.commits.intellij.plugin.notBlank
5+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClientPanel
6+
import com.intellij.ui.components.JBTextField
7+
import com.intellij.ui.dsl.builder.Panel
8+
import com.intellij.ui.dsl.builder.bindText
9+
import com.intellij.ui.dsl.builder.panel
10+
11+
class GeminiClientPanel private constructor(
12+
private val clientConfiguration: GeminiClientConfiguration,
13+
val service: GeminiClientService
14+
) : LLMClientPanel(clientConfiguration) {
15+
16+
private val projectIdTextField = JBTextField()
17+
private val locationTextField = JBTextField()
18+
19+
constructor(configuration: GeminiClientConfiguration): this(configuration, GeminiClientService.getInstance())
20+
21+
override fun create() = panel {
22+
nameRow()
23+
projectIdRow()
24+
locationRow()
25+
modelIdRow()
26+
temperatureRow()
27+
verifyRow()
28+
}
29+
30+
private fun Panel.projectIdRow() {
31+
row {
32+
label(message("settings.gemini.project-id"))
33+
.widthGroup("label")
34+
35+
cell(projectIdTextField)
36+
.bindText(clientConfiguration::projectId)
37+
.resizableColumn()
38+
.widthGroup("input")
39+
.validationOnInput { notBlank(it.text) }
40+
.comment(message("settings.gemini.project-id.comment"))
41+
}
42+
43+
}
44+
45+
private fun Panel.locationRow() {
46+
row {
47+
label(message("settings.gemini.location"))
48+
.widthGroup("label")
49+
cell(locationTextField)
50+
.bindText(clientConfiguration::location)
51+
.resizableColumn()
52+
.validationOnInput { notBlank(it.text) }
53+
.widthGroup("input")
54+
}
55+
}
56+
57+
override fun verifyConfiguration() {
58+
// Configuration passed to panel is already a copy of the original or a new configuration
59+
clientConfiguration.modelId = modelComboBox.item
60+
clientConfiguration.temperature = temperatureTextField.text
61+
62+
service.verifyConfiguration(clientConfiguration, verifyLabel)
63+
}
64+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients.gemini
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClientService
4+
import com.intellij.openapi.components.Service
5+
import com.intellij.openapi.components.service
6+
import dev.langchain4j.model.chat.ChatLanguageModel
7+
import dev.langchain4j.model.vertexai.VertexAiGeminiChatModel
8+
import kotlinx.coroutines.CoroutineScope
9+
10+
@Service(Service.Level.APP)
11+
class GeminiClientService(private val cs: CoroutineScope): LLMClientService<GeminiClientConfiguration>(cs) {
12+
13+
companion object {
14+
@JvmStatic
15+
fun getInstance(): GeminiClientService = service()
16+
}
17+
18+
override suspend fun buildChatModel(client: GeminiClientConfiguration): ChatLanguageModel {
19+
return VertexAiGeminiChatModel.builder()
20+
.project(client.projectId)
21+
.location(client.location)
22+
.modelName(client.modelId)
23+
.temperature(client.temperature.toFloat())
24+
.build()
25+
}
26+
27+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.github.blarc.ai.commits.intellij.plugin.settings.clients.gemini
2+
3+
import com.github.blarc.ai.commits.intellij.plugin.settings.clients.LLMClientSharedState
4+
import com.intellij.openapi.components.*
5+
import com.intellij.util.xmlb.XmlSerializerUtil
6+
import com.intellij.util.xmlb.annotations.XCollection
7+
8+
@Service(Service.Level.APP)
9+
@State(name = "GeminiClientSharedState", storages = [Storage("AICommitsGemini.xml")])
10+
class GeminiClientSharedState : PersistentStateComponent<GeminiClientSharedState>, LLMClientSharedState {
11+
12+
companion object {
13+
@JvmStatic
14+
fun getInstance(): GeminiClientSharedState = service()
15+
}
16+
17+
@XCollection(style = XCollection.Style.v2)
18+
override val hosts = mutableSetOf("http://localhost:11434/")
19+
20+
@XCollection(style = XCollection.Style.v2)
21+
override val modelIds: MutableSet<String> = mutableSetOf(
22+
"gemini-pro",
23+
"gemini-ultra"
24+
)
25+
26+
override fun getState(): GeminiClientSharedState = this
27+
28+
override fun loadState(state: GeminiClientSharedState) {
29+
XmlSerializerUtil.copyBean(state, this)
30+
}
31+
}
1.04 KB
Loading

src/main/resources/messages/AiCommitsBundle.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,6 @@ settings.openAi.organizationId=Organization ID
7979
settings.qianfan.apiKey=API key
8080
settings.qianfan.secretKey=Secret key
8181
notifications.client-not-set=LLM client is not set.
82+
settings.gemini.project-id=Project ID
83+
settings.gemini.project-id.comment=Google Cloud project's ID.
84+
settings.gemini.location=Location

0 commit comments

Comments
 (0)