diff --git a/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingComponent.kt b/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingComponent.kt index 578dcb940e..68999a8b97 100644 --- a/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingComponent.kt +++ b/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingComponent.kt @@ -68,7 +68,8 @@ class ChatCodingComponent(private val chatCodingService: ChatCodingService) : JB } fun add(message: String, isMe: Boolean = false) { - val messageView = MessageView(message, ChatRole.User) + val role = if (isMe) ChatRole.User else ChatRole.Assistant + val messageView = MessageView(message, role) myList.add(messageView) updateLayout() @@ -124,7 +125,7 @@ class ChatCodingComponent(private val chatCodingService: ChatCodingService) : JB } private suspend fun updateMessageInUi(content: Flow): String { - val messageView = MessageView("...", ChatRole.Assistant) + val messageView = MessageView("", ChatRole.Assistant) myList.add(messageView) var text = "" diff --git a/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingService.kt b/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingService.kt index 38be00610b..2214febf16 100644 --- a/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingService.kt +++ b/src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingService.kt @@ -4,6 +4,7 @@ import cc.unitmesh.devti.AutoDevBundle import cc.unitmesh.devti.provider.ContextPrompter import cc.unitmesh.devti.llms.ConnectorFactory import cc.unitmesh.devti.editor.LLMCoroutineScopeService +import cc.unitmesh.devti.gui.chat.block.SimpleMessage import cc.unitmesh.devti.parser.PostCodeProcessor import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project @@ -25,7 +26,7 @@ class ChatCodingService(var actionType: ChatActionType, val project: Project) { prompt: ContextPrompter, context: ChatContext? = null ) { - ui.add(prompt.displayPrompt(), true) + ui.add(prompt.requestPrompt(), true) ui.add(AutoDevBundle.message("devti.loading")) ApplicationManager.getApplication().executeOnPooledThread { diff --git a/src/main/kotlin/cc/unitmesh/devti/gui/chat/MessageView.kt b/src/main/kotlin/cc/unitmesh/devti/gui/chat/MessageView.kt index 698f6a99ec..e6d0d8c1ce 100644 --- a/src/main/kotlin/cc/unitmesh/devti/gui/chat/MessageView.kt +++ b/src/main/kotlin/cc/unitmesh/devti/gui/chat/MessageView.kt @@ -40,47 +40,53 @@ class MessageView(private val message: String, role: ChatRole) : JBPanel { - var currentContextType = MessageBlockType.PlainText + fun layoutAll(messageText: String, message: CompletableMessage): List { + val currentContextTypeRef = Ref.ObjectRef() + currentContextTypeRef.element = MessageBlockType.PlainText + val blockStart: Ref.IntRef = Ref.IntRef() - val parts = ArrayList() + val parts = mutableListOf() for ((index, item) in messageText.withIndex()) { val param = Parameters(item, index, messageText) val suggestTypeChange = - MessageCodeBlockCharProcessor().suggestTypeChange(param, currentContextType, blockStart.element) - - if (suggestTypeChange != null) { - when { - suggestTypeChange.contextType == currentContextType -> { - if (suggestTypeChange.borderType == BorderType.START) { - logger.error("suggestTypeChange return $currentContextType START while there is already $currentContextType opened") - } else { - pushPart(blockStart, messageText, currentContextType, message, parts, index) - } + MessageCodeBlockCharProcessor().suggestTypeChange( + param, + currentContextTypeRef.element, + blockStart.element + ) + ?: continue + + when { + suggestTypeChange.contextType == currentContextTypeRef.element -> { + if (suggestTypeChange.borderType == BorderType.START) { + logger.error("suggestTypeChange return ${currentContextTypeRef.element} START while there is already ${currentContextTypeRef.element} opened") + } else { + pushPart(blockStart, messageText, currentContextTypeRef, message, parts, index) } + } - suggestTypeChange.borderType == BorderType.START -> { - if (index > blockStart.element) { - pushPart(blockStart, messageText, currentContextType, message, parts, index - 1) - } - blockStart.element = index - currentContextType = suggestTypeChange.contextType + suggestTypeChange.borderType == BorderType.START -> { + if (index > blockStart.element) { + pushPart(blockStart, messageText, currentContextTypeRef, message, parts, index - 1) } + blockStart.element = index + currentContextTypeRef.element = suggestTypeChange.contextType + } - else -> { - logger.error("suggestTypeChange return $currentContextType END when there wasn't open tag") - } + else -> { + logger.error("suggestTypeChange return ${currentContextTypeRef.element} END when there wasn't open tag") } } } if (blockStart.element < messageText.length) { - pushPart(blockStart, messageText, currentContextType, message, parts, messageText.length - 1) + pushPart(blockStart, messageText, currentContextTypeRef, message, parts, messageText.length - 1) } return parts @@ -89,12 +95,39 @@ class MessageView(private val message: String, role: ChatRole) : JBPanel, + currentContextType: Ref.ObjectRef, + message: CompletableMessage, + list: MutableList, partUpperOffset: Int ) { + val newPart = createPart(blockStart.element, partUpperOffset, messageText, currentContextType, message) + list.add(newPart) + + blockStart.element = partUpperOffset + 1 + currentContextType.element = MessageBlockType.PlainText + } + + private fun createPart( + blockStart: Int, + partUpperOffset: Int, + messageText: String, + currentContextType: Ref.ObjectRef, + message: CompletableMessage + ): MessageBlock { + check(blockStart < messageText.length) + check(partUpperOffset < messageText.length) + + val blockText = messageText.substring(blockStart, partUpperOffset + 1) + val part: MessageBlock = when (currentContextType.element!!) { + MessageBlockType.CodeEditor -> TextBlock(message) + MessageBlockType.PlainText -> CodeBlock(message) + } + + if (blockText.isNotEmpty()) { + part.addContent(blockText) + } + return part } fun updateContent(content: String) { @@ -135,6 +168,6 @@ class MessageView(private val message: String, role: ChatRole) : JBPanel = mutableListOf() + + override fun addTextListener(textListener: MessageBlockTextListener) { + textListeners += textListener + } + + override fun removeTextListener(textListener: MessageBlockTextListener) { + textListeners -= textListener + } +} \ No newline at end of file