From 6bcdf159a05a2295895027a86cebc59ec9a78279 Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Sat, 23 Mar 2024 10:40:12 +0800 Subject: [PATCH] fix(devins-lang): add basic handle for exitCode=-1 to recall function - Improve file writing performance by optimizing the process termination listener and adding a new input field for DevInsCompiledResult. This will enhance the overall efficiency of the DevIns language compiler. --- .../language/compiler/DevInsCompiledResult.kt | 4 +- .../devti/language/compiler/DevInsCompiler.kt | 1 + .../run/DevInsRunConfigurationProfileState.kt | 13 ++++-- .../language/run/flow/DevInsConversations.kt | 43 ++++++++++++++++++- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiledResult.kt b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiledResult.kt index 40be76f4f4..00e414053b 100644 --- a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiledResult.kt +++ b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiledResult.kt @@ -3,8 +3,10 @@ package cc.unitmesh.devti.language.compiler import cc.unitmesh.devti.agent.model.CustomAgentConfig data class DevInsCompiledResult( + var input: String = "", var output: String = "", var isLocalCommand: Boolean = false, var hasError: Boolean = false, var workingAgent: CustomAgentConfig? = null -) +) { +} diff --git a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt index d847ba5d3d..9d3e33fe1c 100644 --- a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt +++ b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/DevInsCompiler.kt @@ -34,6 +34,7 @@ class DevInsCompiler( * Todo: build AST tree, then compile */ fun compile(): DevInsCompiledResult { + result.input = file.text file.children.forEach { when (it.elementType) { DevInTypes.TEXT_SEGMENT -> output.append(it.text) diff --git a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/DevInsRunConfigurationProfileState.kt b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/DevInsRunConfigurationProfileState.kt index 40a2c4bb1a..54f00104c3 100644 --- a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/DevInsRunConfigurationProfileState.kt +++ b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/DevInsRunConfigurationProfileState.kt @@ -29,7 +29,7 @@ import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.ui.components.panels.NonOpaquePanel -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import java.awt.BorderLayout @@ -49,12 +49,18 @@ open class DevInsRunConfigurationProfileState( val sb = StringBuilder() processHandler.addProcessListener(object : ProcessAdapter() { + var result = "" override fun processTerminated(event: ProcessEvent) { super.processTerminated(event) ApplicationManager.getApplication().messageBus .syncPublisher(DevInsRunListener.TOPIC) - .runFinish(sb.toString(), event, configuration.getScriptPath()) + .runFinish(result, event, configuration.getScriptPath()) + } + + override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) { + super.onTextAvailable(event, outputType) + result = sb.toString() } }) @@ -108,6 +114,7 @@ open class DevInsRunConfigurationProfileState( } console.print("\n--------------------\n", ConsoleViewContentType.NORMAL_OUTPUT) + // throw error if contains any if (output.contains("")) { processHandler.exitWithError() @@ -166,7 +173,7 @@ open class DevInsRunConfigurationProfileState( LLMCoroutineScope.scope(myProject).launch { val llmResult = StringBuilder() runBlocking { - llm.stream(output, "").collect { + llm.stream(output, "", false).collect { llmResult.append(it) console.print(it, ConsoleViewContentType.NORMAL_OUTPUT) } diff --git a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/flow/DevInsConversations.kt b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/flow/DevInsConversations.kt index 84fc41120e..ab64c2e9cf 100644 --- a/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/flow/DevInsConversations.kt +++ b/exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/run/flow/DevInsConversations.kt @@ -1,11 +1,18 @@ package cc.unitmesh.devti.language.run.flow +import cc.unitmesh.devti.gui.chat.ChatActionType +import cc.unitmesh.devti.gui.sendToChatWindow import cc.unitmesh.devti.language.compiler.DevInsCompiledResult +import cc.unitmesh.devti.llms.LLMProvider +import cc.unitmesh.devti.llms.LlmFactory +import cc.unitmesh.devti.provider.ContextPrompter import com.intellij.openapi.components.Service import com.intellij.openapi.project.Project @Service(Service.Level.PROJECT) class DevInsConversationService(val project: Project) { + private val llm: LLMProvider = LlmFactory.instance.create(project) + /** * The cached conversations */ @@ -63,13 +70,47 @@ class DevInsConversationService(val project: Project) { conversation.hadReRun = true // call llm again to re-run + + val prompt = StringBuilder() + + // todo: refactor to DevIn template file + if (conversation.compiledResult.isLocalCommand) { + prompt.append("You are a top software developer in the world, which can help me to fix the issue.\n") + prompt.append("When I use DevIn language and compile the script, I got an error, can you help me to fix it?\n") + prompt.append("Origin DevIn script:\n") + prompt.append("```devin\n") + prompt.append(conversation.compiledResult.input) + prompt.append("```\n") + + prompt.append("The Compile Result:\n") + prompt.append("####\n") + prompt.append(conversation.compiledResult.output) + prompt.append("####\n") + } + + prompt.append(""" + Here is the run result, can you help me to fix it? + Run result: + #### + ${conversation.ideOutput} + #### + """.trimIndent() + ) + + val finalPrompt = prompt.toString() + sendToChatWindow(project, ChatActionType.CHAT) { panel, service -> + service.handlePromptAndResponse(panel, object : ContextPrompter() { + override fun displayPrompt(): String = finalPrompt + override fun requestPrompt(): String = finalPrompt + }, null, true) + } } } data class DevInsConversation( val scriptPath: String, - val result: DevInsCompiledResult, + val compiledResult: DevInsCompiledResult, val llmResponse: String, val ideOutput: String, val messages: MutableList = mutableListOf(),