Skip to content

Commit 0c97915

Browse files
committed
fix: address review comments
- CoroutineScopeHolder: implement Disposable to cancel parentJob on project disposal - IdeaAgentViewModel: preserve partial streaming output on abort - IdeaAgentApp: simplify AgentTab structure by removing nested Box - build.gradle.kts: extract mppVersion variable to avoid duplication - DomainDictAgent: normalize path separators and skip empty package paths
1 parent 89bb488 commit 0c97915

File tree

5 files changed

+41
-17
lines changed

5 files changed

+41
-17
lines changed

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/subagent/DomainDictAgent.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,14 @@ class DomainDictAgent(
341341
/**
342342
* Extract package path from file path
343343
* e.g., "src/main/kotlin/cc/unitmesh/agent/Tool.kt" -> "cc/unitmesh/agent"
344+
* Handles both Unix (/) and Windows (\) path separators.
344345
*/
345346
private fun extractPackagePath(filePath: String): String {
347+
// Normalize path separators to forward slash for cross-platform compatibility
348+
val normalizedPath = filePath.replace('\\', '/')
349+
346350
// Remove common source prefixes
347-
val cleanPath = filePath
351+
val cleanPath = normalizedPath
348352
.replace(Regex("^.*/src/(main|common)/(kotlin|java|scala)/"), "")
349353
.replace(Regex("^.*/src/"), "")
350354
.replace(Regex("^src/(main|common)/(kotlin|java|scala)/"), "")
@@ -368,7 +372,10 @@ class DomainDictAgent(
368372
val prioritizedFiles = if (importantPackages.isNotEmpty()) {
369373
insights.hotFiles.sortedByDescending { file ->
370374
val pkg = extractPackagePath(file.path)
371-
if (importantPackages.any { pkg.startsWith(it) || it.startsWith(pkg) }) 2 else 1
375+
// Skip empty package paths to avoid matching all entries
376+
if (pkg.isEmpty()) 1
377+
else if (importantPackages.any { pkg.startsWith(it) || it.startsWith(pkg) }) 2
378+
else 1
372379
}
373380
} else {
374381
insights.hotFiles

mpp-idea/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ plugins {
99
}
1010

1111
group = "cc.unitmesh.devins"
12-
version = project.findProperty("mppVersion") as String? ?: "0.3.2"
12+
val mppVersion = project.findProperty("mppVersion") as String? ?: "0.3.2"
13+
version = mppVersion
1314

1415
kotlin {
1516
jvmToolchain(21)
@@ -69,7 +70,7 @@ dependencies {
6970
intellijPlatform {
7071
pluginConfiguration {
7172
name = "AutoDev Compose UI"
72-
version = project.findProperty("mppVersion") as String? ?: "0.3.2"
73+
version = mppVersion
7374

7475
ideaVersion {
7576
sinceBuild = "252"

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/services/CoroutineScopeHolder.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
package cc.unitmesh.devins.idea.services
22

3+
import com.intellij.openapi.Disposable
34
import com.intellij.openapi.components.Service
45
import com.intellij.openapi.components.Service.Level
56
import com.intellij.openapi.project.Project
67
import kotlinx.coroutines.CoroutineScope
78
import kotlinx.coroutines.SupervisorJob
89
import kotlinx.coroutines.Dispatchers
910
import kotlinx.coroutines.CoroutineName
10-
import kotlinx.coroutines.Job
11+
import kotlinx.coroutines.cancel
1112

1213
/**
1314
* A service-level class that provides and manages coroutine scopes for a given project.
15+
* Implements [Disposable] to properly cancel all coroutines when the project is closed.
1416
*
1517
* @constructor Initializes the [CoroutineScopeHolder] with a project instance.
1618
* @param project The project this service is associated with.
1719
*/
1820
@Service(Level.PROJECT)
19-
class CoroutineScopeHolder(private val project: Project) {
21+
class CoroutineScopeHolder(private val project: Project) : Disposable {
2022

2123
private val parentJob = SupervisorJob()
2224
private val projectWideCoroutineScope: CoroutineScope = CoroutineScope(parentJob + Dispatchers.Default)
@@ -37,5 +39,12 @@ class CoroutineScopeHolder(private val project: Project) {
3739
val childJob = SupervisorJob(parentJob)
3840
return CoroutineScope(childJob + Dispatchers.Default + CoroutineName(name))
3941
}
42+
43+
/**
44+
* Cancels all coroutines when the project is disposed.
45+
*/
46+
override fun dispose() {
47+
parentJob.cancel()
48+
}
4049
}
4150

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -256,22 +256,20 @@ private fun AgentTab(
256256
JewelTheme.globalColors.panelBackground
257257
}
258258

259-
Box(
259+
OutlinedButton(
260+
onClick = onClick,
260261
modifier = Modifier
261262
.height(28.dp)
262263
.background(backgroundColor)
263-
.padding(horizontal = 12.dp, vertical = 4.dp),
264-
contentAlignment = Alignment.Center
264+
.padding(horizontal = 4.dp, vertical = 2.dp)
265265
) {
266-
OutlinedButton(onClick = onClick) {
267-
Text(
268-
text = type.displayName,
269-
style = JewelTheme.defaultTextStyle.copy(
270-
fontSize = 12.sp,
271-
fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal
272-
)
266+
Text(
267+
text = type.displayName,
268+
style = JewelTheme.defaultTextStyle.copy(
269+
fontSize = 12.sp,
270+
fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal
273271
)
274-
}
272+
)
275273
}
276274
}
277275

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,18 @@ class IdeaAgentViewModel(
121121

122122
/**
123123
* Abort the current request.
124+
* Preserves partial streaming output if any.
124125
*/
125126
fun abortRequest() {
126127
currentJob?.cancel()
128+
// Preserve partial output if any
129+
if (_streamingOutput.value.isNotEmpty()) {
130+
val partialMessage = ModelChatMessage(
131+
content = _streamingOutput.value + "\n\n[Interrupted]",
132+
role = MessageRole.ASSISTANT
133+
)
134+
_messages.value = _messages.value + listOf(partialMessage)
135+
}
127136
_isProcessing.value = false
128137
_streamingOutput.value = ""
129138
}

0 commit comments

Comments
 (0)