Skip to content

Commit 0bf03d6

Browse files
committed
feat(llm): add synchronous cancellation for LLM requests #412
Implement cancelCurrentRequestSync method in LLMProviderAdapter and update ChatCodingService to use it, allowing immediate cancellation of streaming responses. This provides a cleaner way to stop ongoing LLM operations without waiting for completion.
1 parent eb5a89d commit 0bf03d6

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import cc.unitmesh.devti.custom.compile.CustomVariable
99
import cc.unitmesh.devti.gui.chat.message.ChatActionType
1010
import cc.unitmesh.devti.gui.chat.message.ChatContext
1111
import cc.unitmesh.devti.gui.chat.message.ChatRole
12-
import cc.unitmesh.devti.llm2.LLMProvider2
12+
import cc.unitmesh.devti.llms.LLMProvider
13+
import cc.unitmesh.devti.llms.LLMProviderAdapter
1314
import cc.unitmesh.devti.llms.LlmFactory
1415
import cc.unitmesh.devti.llms.custom.Message
1516
import cc.unitmesh.devti.provider.ContextPrompter
@@ -22,7 +23,7 @@ import kotlinx.coroutines.flow.Flow
2223
import kotlinx.coroutines.launch
2324

2425
class ChatCodingService(var actionType: ChatActionType, val project: Project) {
25-
private var llmProvider = LlmFactory.create(project)
26+
private var llmProvider: LLMProvider = LlmFactory.create(project)
2627
private val counitProcessor = project.service<CustomAgentChatProcessor>()
2728
private var currentJob: Job? = null
2829

@@ -32,9 +33,8 @@ class ChatCodingService(var actionType: ChatActionType, val project: Project) {
3233
// Cancel the coroutine job
3334
currentJob?.cancel()
3435

35-
// Also cancel the underlying LLM provider if it supports cancellation
36-
if (llmProvider is LLMProvider2) {
37-
(llmProvider as LLMProvider2).cancelCurrentRequestSync()
36+
if (llmProvider is LLMProviderAdapter) {
37+
(llmProvider as LLMProviderAdapter).cancelCurrentRequestSync()
3838
}
3939

4040
currentJob = null

core/src/main/kotlin/cc/unitmesh/devti/llms/LLMProviderAdapter.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import cc.unitmesh.devti.settings.coder.coderSetting
1212
import com.intellij.openapi.diagnostic.logger
1313
import com.intellij.openapi.project.Project
1414
import kotlinx.coroutines.flow.Flow
15-
import kotlinx.coroutines.flow.map
1615

1716
/**
1817
* Adapter that bridges the old LLMProvider interface with the new LLMProvider2 implementation.
@@ -27,6 +26,7 @@ class LLMProviderAdapter(
2726

2827
private val messages: MutableList<Message> = mutableListOf()
2928
private var currentSession: ChatSession<Message> = ChatSession("adapter-session")
29+
private var currentProvider: LLMProvider2? = null
3030

3131
override val defaultTimeout: Long get() = 600
3232

@@ -58,6 +58,7 @@ class LLMProviderAdapter(
5858
}
5959

6060
val actualProvider = LLMProvider2.fromConfig(actualLlmConfig, project)
61+
currentProvider = actualProvider
6162
if (!keepHistory || project.coderSetting.state.noChatHistory) {
6263
clearMessage()
6364
currentSession = ChatSession("adapter-session")
@@ -133,6 +134,17 @@ class LLMProviderAdapter(
133134
currentSession = ChatSession("adapter-session")
134135
}
135136

137+
/**
138+
* Cancels the current LLM request synchronously without waiting for completion.
139+
* This is useful for immediately stopping streaming responses from the LLM.
140+
*/
141+
fun cancelCurrentRequestSync() {
142+
logger.info("Cancelling current LLM request synchronously")
143+
currentProvider?.cancelCurrentRequestSync() ?: run {
144+
logger.warn("No active LLM provider to cancel")
145+
}
146+
}
147+
136148
override fun getAllMessages(): List<Message> {
137149
return messages.toList()
138150
}

0 commit comments

Comments
 (0)