Skip to content

Commit 7c38f33

Browse files
authored
Merge branch 'unit-mesh:master' into master
2 parents 5c72977 + 110fab2 commit 7c38f33

File tree

4 files changed

+67
-12
lines changed

4 files changed

+67
-12
lines changed

src/main/kotlin/cc/unitmesh/devti/gui/chat/AutoDevInput.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum class AutoDevInputTrigger {
3737
interface AutoDevInputListener : EventListener {
3838
fun editorAdded(editor: EditorEx) {}
3939
fun onSubmit(component: AutoDevInputSection, trigger: AutoDevInputTrigger) {}
40+
fun onStop(component: AutoDevInputSection) {}
4041
}
4142

4243
class AutoDevInput(

src/main/kotlin/cc/unitmesh/devti/gui/chat/AutoDevInputSection.kt

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,31 @@ import com.intellij.util.ui.JBEmptyBorder
3232
import com.intellij.util.ui.JBUI
3333
import com.intellij.util.ui.UIUtil
3434
import com.intellij.util.ui.components.BorderLayoutPanel
35-
import kotlinx.serialization.decodeFromString
3635
import kotlinx.serialization.json.Json
36+
import java.awt.CardLayout
3737
import java.awt.Color
3838
import java.awt.Dimension
3939
import java.awt.event.MouseAdapter
4040
import java.awt.event.MouseEvent
4141
import java.util.function.Supplier
4242
import javax.swing.Box
4343
import javax.swing.JComponent
44+
import javax.swing.JPanel
4445
import kotlin.math.max
4546
import kotlin.math.min
47+
import kotlinx.serialization.decodeFromString
4648

4749
/**
4850
*
4951
*/
5052
class AutoDevInputSection(private val project: Project, val disposable: Disposable?) : BorderLayoutPanel() {
5153
private val input: AutoDevInput
5254
private val documentListener: DocumentListener
53-
private val buttonPresentation: Presentation
54-
private val button: ActionButton
55+
private val sendButtonPresentation: Presentation
56+
private val stopButtonPresentation: Presentation
57+
private val sendButton: ActionButton
58+
private val stopButton: ActionButton
59+
private val buttonPanel = JPanel(CardLayout())
5560

5661
private val defaultRag: CustomAgentConfig = CustomAgentConfig("<Select Custom Agent>", "Normal")
5762
private var customRag: ComboBox<CustomAgentConfig> = ComboBox(MutableCollectionComboBoxModel(listOf()))
@@ -70,18 +75,37 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
7075
}
7176

7277
init {
73-
val presentation = Presentation(AutoDevBundle.message("chat.panel.send"))
74-
presentation.setIcon(AutoDevIcons.Send)
75-
buttonPresentation = presentation
76-
button = ActionButton(
78+
val sendButtonPresentation = Presentation(AutoDevBundle.message("chat.panel.send"))
79+
sendButtonPresentation.setIcon(AutoDevIcons.Send)
80+
this.sendButtonPresentation = sendButtonPresentation
81+
82+
val stopButtonPresentation = Presentation("Stop")
83+
stopButtonPresentation.setIcon(AutoDevIcons.Idea)
84+
this.stopButtonPresentation = stopButtonPresentation
85+
86+
sendButton = ActionButton(
7787
DumbAwareAction.create {
7888
object : DumbAwareAction("") {
7989
override fun actionPerformed(e: AnActionEvent) {
90+
showStopButton()
8091
editorListeners.multicaster.onSubmit(this@AutoDevInputSection, AutoDevInputTrigger.Button)
8192
}
8293
}.actionPerformed(it)
8394
},
84-
buttonPresentation,
95+
this.sendButtonPresentation,
96+
"",
97+
Dimension(20, 20)
98+
)
99+
100+
stopButton = ActionButton(
101+
DumbAwareAction.create {
102+
object : DumbAwareAction("") {
103+
override fun actionPerformed(e: AnActionEvent) {
104+
editorListeners.multicaster.onStop(this@AutoDevInputSection)
105+
}
106+
}.actionPerformed(it)
107+
},
108+
this.stopButtonPresentation,
85109
"",
86110
Dimension(20, 20)
87111
)
@@ -125,13 +149,17 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
125149
layoutPanel.addToLeft(customRag)
126150
}
127151

152+
153+
buttonPanel.add(sendButton, "Send")
154+
buttonPanel.add(stopButton, "Stop")
155+
128156
layoutPanel.addToCenter(horizontalGlue)
129-
layoutPanel.addToRight(button)
157+
layoutPanel.addToRight(buttonPanel)
130158
addToBottom(layoutPanel)
131159

132160
ComponentValidator(disposable!!).withValidator(Supplier<ValidationInfo?> {
133161
val validationInfo: ValidationInfo? = this.getInputValidationInfo()
134-
button.setEnabled(validationInfo == null)
162+
sendButton.setEnabled(validationInfo == null)
135163
return@Supplier validationInfo
136164
}).installOn((this as JComponent)).revalidate()
137165

@@ -144,6 +172,16 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
144172
tokenizer = TokenizerImpl.INSTANCE
145173
}
146174

175+
fun showStopButton() {
176+
(buttonPanel.layout as? CardLayout)?.show(buttonPanel, "Stop")
177+
stopButton.isEnabled = true
178+
}
179+
180+
fun showSendButton() {
181+
(buttonPanel.layout as? CardLayout)?.show(buttonPanel, "Send")
182+
buttonPanel.isEnabled = true
183+
}
184+
147185
private fun loadRagApps(): List<CustomAgentConfig> {
148186
val ragsJsonConfig = project.customAgentSetting.ragsJsonConfig
149187
if (ragsJsonConfig.isEmpty()) return listOf(defaultRag)

src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingPanel.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,17 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
9090

9191
inputSection = AutoDevInputSection(chatCodingService.project, disposable)
9292
inputSection.addListener(object : AutoDevInputListener {
93+
override fun onStop(component: AutoDevInputSection) {
94+
chatCodingService.stop()
95+
inputSection.showSendButton()
96+
}
97+
9398
override fun onSubmit(component: AutoDevInputSection, trigger: AutoDevInputTrigger) {
9499
var prompt = component.text
95100
component.text = ""
96101

102+
inputSection.showStopButton()
103+
97104
if (prompt.isEmpty() || prompt == "\n") {
98105
return
99106
}
@@ -216,6 +223,7 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
216223
var text = ""
217224
content.onCompletion {
218225
logger.info("onCompletion ${it?.message}")
226+
inputSection.showSendButton()
219227
}.catch {
220228
it.printStackTrace()
221229
}.collect {

src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingService.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import cc.unitmesh.devti.provider.ContextPrompter
1313
import com.intellij.openapi.application.ApplicationManager
1414
import com.intellij.openapi.components.service
1515
import com.intellij.openapi.project.Project
16+
import kotlinx.coroutines.Job
1617
import kotlinx.coroutines.flow.Flow
1718
import kotlinx.coroutines.launch
1819

@@ -22,14 +23,21 @@ class ChatCodingService(var actionType: ChatActionType, val project: Project) {
2223

2324
val action = actionType.instruction(project = project).requestText
2425

26+
var currentJob: Job? = null
27+
2528
fun getLabel(): String = "$actionType Code"
2629

30+
fun stop() {
31+
currentJob?.cancel()
32+
}
33+
2734
fun handlePromptAndResponse(
2835
ui: ChatCodingPanel,
2936
prompter: ContextPrompter,
3037
context: ChatContext? = null,
3138
newChatContext: Boolean
3239
) {
40+
currentJob?.cancel()
3341
var requestPrompt = prompter.requestPrompt()
3442
var displayPrompt = prompter.displayPrompt()
3543

@@ -59,7 +67,7 @@ class ChatCodingService(var actionType: ChatActionType, val project: Project) {
5967

6068
ApplicationManager.getApplication().executeOnPooledThread {
6169
val response = this.makeChatBotRequest(requestPrompt, newChatContext)
62-
LLMCoroutineScope.scope(project).launch {
70+
currentJob = LLMCoroutineScope.scope(project).launch {
6371
when {
6472
actionType === ChatActionType.REFACTOR -> ui.updateReplaceableContent(response) {
6573
context?.postAction?.invoke(it)
@@ -84,7 +92,7 @@ class ChatCodingService(var actionType: ChatActionType, val project: Project) {
8492
ApplicationManager.getApplication().executeOnPooledThread {
8593
val response = llmProvider.stream(requestPrompt, systemPrompt)
8694

87-
LLMCoroutineScope.scope(project).launch {
95+
currentJob = LLMCoroutineScope.scope(project).launch {
8896
ui.updateMessage(response)
8997
}
9098
}

0 commit comments

Comments
 (0)