@@ -3,6 +3,8 @@ package cc.unitmesh.devti.mcp.ui
3
3
import cc.unitmesh.devti.AutoDevBundle
4
4
import cc.unitmesh.devti.mcp.client.CustomMcpServerManager
5
5
import cc.unitmesh.devti.mcp.ui.model.McpChatConfig
6
+ import cc.unitmesh.devti.mcp.ui.model.McpMessage
7
+ import cc.unitmesh.devti.mcp.ui.model.MessageType
6
8
import cc.unitmesh.devti.mcp.ui.model.ToolCall
7
9
import com.intellij.openapi.project.Project
8
10
import com.intellij.ui.JBColor
@@ -15,6 +17,8 @@ import io.modelcontextprotocol.kotlin.sdk.Tool
15
17
import kotlinx.serialization.encodeToString
16
18
import kotlinx.serialization.json.Json
17
19
import java.awt.*
20
+ import java.time.LocalDateTime
21
+ import java.util.UUID
18
22
import javax.swing.*
19
23
import javax.swing.border.CompoundBorder
20
24
import javax.swing.border.EmptyBorder
@@ -37,6 +41,8 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
37
41
border = JBUI .Borders .empty(8 )
38
42
}
39
43
44
+ private val messageLogPanel = McpMessageLogPanel ()
45
+
40
46
private val responseScrollPane = JBScrollPane (rawResultTextArea).apply {
41
47
border = BorderFactory .createEmptyBorder()
42
48
verticalScrollBarPolicy = JScrollPane .VERTICAL_SCROLLBAR_AS_NEEDED
@@ -50,11 +56,13 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
50
56
private val tabbedPane = JBTabbedPane ().apply {
51
57
addTab(AutoDevBundle .message(" mcp.chat.result.tab.response" ), responseScrollPane)
52
58
addTab(AutoDevBundle .message(" mcp.chat.result.tab.tools" ), toolsScrollPane)
59
+ addTab(AutoDevBundle .message(" mcp.chat.result.tab.messages" ), messageLogPanel)
53
60
}
54
61
55
62
private val borderColor = JBColor (0xE5E7EB , 0x3C3F41 ) // Equivalent to Tailwind gray-200
56
63
57
64
private var currentHeight = 300
65
+ private var toolCalls: List <ToolCall > = emptyList()
58
66
59
67
init {
60
68
background = UIUtil .getPanelBackground()
@@ -74,7 +82,7 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
74
82
private fun parseAndShowTools (text : String ) {
75
83
toolsPanel.removeAll()
76
84
77
- val toolCalls = ToolCall .fromString(text)
85
+ toolCalls = ToolCall .fromString(text)
78
86
if (toolCalls.isEmpty()) {
79
87
val noToolsLabel = JBLabel (AutoDevBundle .message(" mcp.chat.result.no.tools" )).apply {
80
88
foreground = JBColor (0x6B7280 , 0x9DA0A8 ) // Gray text
@@ -92,6 +100,29 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
92
100
} else {
93
101
var gridY = 0
94
102
103
+ // Add "Execute All Tools" button
104
+ val executeAllButton = JButton (AutoDevBundle .message(" mcp.chat.result.execute.all" )).apply {
105
+ font = JBUI .Fonts .label(12f ).asBold()
106
+ addActionListener {
107
+ executeAllTools()
108
+ }
109
+ }
110
+
111
+ val buttonPanel = JPanel (FlowLayout (FlowLayout .LEFT )).apply {
112
+ isOpaque = false
113
+ add(executeAllButton)
114
+ }
115
+
116
+ val buttonGbc = GridBagConstraints ().apply {
117
+ gridx = 0
118
+ gridy = gridY++
119
+ weightx = 1.0
120
+ fill = GridBagConstraints .HORIZONTAL
121
+ insets = JBUI .insetsBottom(10 )
122
+ }
123
+
124
+ toolsPanel.add(buttonPanel, buttonGbc)
125
+
95
126
toolCalls.forEach { toolCall ->
96
127
val toolPanel = createToolCallPanel(toolCall)
97
128
@@ -128,6 +159,51 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
128
159
}
129
160
}
130
161
162
+ private fun executeAllTools () {
163
+ if (toolCalls.isEmpty()) return
164
+
165
+ SwingUtilities .invokeLater {
166
+ for (toolCall in toolCalls) {
167
+ val matchingTool = findMatchingTool(toolCall.name)
168
+ if (matchingTool != null ) {
169
+ val startTime = System .currentTimeMillis()
170
+
171
+ // Log request message
172
+ val params = try {
173
+ json.encodeToString(toolCall.parameters)
174
+ } catch (e: Exception ) {
175
+ " {}"
176
+ }
177
+
178
+ val requestMessage = McpMessage (
179
+ type = MessageType .REQUEST ,
180
+ method = toolCall.name,
181
+ timestamp = LocalDateTime .now(),
182
+ content = " Tool: ${toolCall.name} \n Parameters: $params "
183
+ )
184
+ messageLogPanel.addMessage(requestMessage)
185
+
186
+ // Execute the tool
187
+ val result = mcpServerManager.execute(project, matchingTool, params)
188
+ val duration = System .currentTimeMillis() - startTime
189
+
190
+ // Log response message
191
+ val responseMessage = McpMessage (
192
+ type = MessageType .RESPONSE ,
193
+ method = toolCall.name,
194
+ timestamp = LocalDateTime .now(),
195
+ duration = duration,
196
+ content = result
197
+ )
198
+ messageLogPanel.addMessage(responseMessage)
199
+ }
200
+ }
201
+
202
+ // Switch to messages tab
203
+ tabbedPane.selectedIndex = 2
204
+ }
205
+ }
206
+
131
207
private fun createToolCallPanel (toolCall : ToolCall ): JPanel {
132
208
val panel = JPanel (BorderLayout ()).apply {
133
209
background = UIUtil .getPanelBackground().brighter()
@@ -240,14 +316,33 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
240
316
" {}"
241
317
}
242
318
319
+ // Log request message
320
+ val requestMessage = McpMessage (
321
+ type = MessageType .REQUEST ,
322
+ method = toolCall.name,
323
+ timestamp = LocalDateTime .now(),
324
+ content = " Tool: ${toolCall.name} \n Parameters: $params "
325
+ )
326
+ messageLogPanel.addMessage(requestMessage)
327
+
243
328
val matchingTool = findMatchingTool(toolCall.name)
244
329
val result = if (matchingTool != null ) {
245
330
mcpServerManager.execute(project, matchingTool, params)
246
331
} else {
247
332
AutoDevBundle .message(" mcp.chat.result.error.tool.not.found" , toolCall.name)
248
333
}
249
334
335
+ // Log response message
250
336
val executionTime = System .currentTimeMillis() - startTime
337
+ val responseMessage = McpMessage (
338
+ type = MessageType .RESPONSE ,
339
+ method = toolCall.name,
340
+ timestamp = LocalDateTime .now(),
341
+ duration = executionTime,
342
+ content = result
343
+ )
344
+ messageLogPanel.addMessage(responseMessage)
345
+
251
346
resultPanel.removeAll()
252
347
253
348
val timeInfoPanel = JPanel (FlowLayout (FlowLayout .LEFT )).apply {
@@ -290,4 +385,3 @@ class McpChatResultPanel(private val project: Project, val config: McpChatConfig
290
385
return null
291
386
}
292
387
}
293
-
0 commit comments