diff --git a/shirelang/src/main/kotlin/com/phodal/shirelang/actions/ShireRunFileAction.kt b/shirelang/src/main/kotlin/com/phodal/shirelang/actions/ShireRunFileAction.kt index f70498211..f38083169 100644 --- a/shirelang/src/main/kotlin/com/phodal/shirelang/actions/ShireRunFileAction.kt +++ b/shirelang/src/main/kotlin/com/phodal/shirelang/actions/ShireRunFileAction.kt @@ -6,12 +6,8 @@ import com.intellij.execution.RunnerAndConfigurationSettings import com.intellij.execution.actions.ConfigurationContext import com.intellij.execution.actions.RunConfigurationProducer import com.intellij.execution.executors.DefaultRunExecutor -import com.intellij.execution.impl.ConsoleViewImpl import com.intellij.execution.process.ProcessEvent -import com.intellij.execution.process.ProcessHandler -import com.intellij.execution.process.ProcessTerminatedListener import com.intellij.execution.runners.ExecutionEnvironmentBuilder -import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys @@ -28,9 +24,7 @@ import com.phodal.shirelang.psi.ShireFile import com.phodal.shirelang.run.* import com.phodal.shirelang.run.flow.ShireProcessProcessor import org.jetbrains.annotations.NonNls -import java.io.OutputStream import java.util.concurrent.CompletableFuture -import javax.swing.SwingUtilities.invokeAndWait class ShireRunFileAction : DumbAwareAction() { override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT @@ -177,12 +171,8 @@ class ShireRunFileAction : DumbAwareAction() { val hintDisposable = Disposer.newDisposable() val connection = ApplicationManager.getApplication().messageBus.connect(hintDisposable) connection.subscribe(ShireRunListener.TOPIC, object : ShireRunListener { - override fun runFinish(string: String, event: ProcessEvent, scriptPath: String) { - val consoleView = (executionEnvironment.state as? ShireRunConfigurationProfileState)?.console - executionEnvironment.project.getService(ShireProcessProcessor::class.java) - .process(string, event, scriptPath, consoleView) - - future.complete(string) + override fun runFinish(allOutput: String, llmOutput: String, event: ProcessEvent, scriptPath: String) { + future.complete(allOutput) } }) diff --git a/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireProgramRunner.kt b/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireProgramRunner.kt index 939d34417..fcb280326 100644 --- a/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireProgramRunner.kt +++ b/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireProgramRunner.kt @@ -35,7 +35,7 @@ class ShireProgramRunner : GenericProgramRunner(), Disposable { if (!isSubscribed) { connection.subscribe(ShireRunListener.TOPIC, object : ShireRunListener { - override fun runFinish(string: String, event: ProcessEvent, scriptPath: String) { + override fun runFinish(string: String, llmOutput: String, event: ProcessEvent, scriptPath: String) { val consoleView = (environment.state as? ShireRunConfigurationProfileState)?.console environment.project.getService(ShireProcessProcessor::class.java) .process(string, event, scriptPath, consoleView) diff --git a/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunConfigurationProfileState.kt b/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunConfigurationProfileState.kt index bdc00be10..49471cc70 100644 --- a/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunConfigurationProfileState.kt +++ b/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunConfigurationProfileState.kt @@ -15,19 +15,15 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.ActionManager import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.progress.runBlockingCancellable import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.ui.components.panels.NonOpaquePanel import com.phodal.shirecore.ShireCoroutineScope import com.phodal.shirecore.config.ShireActionLocation import com.phodal.shirecore.provider.context.ActionLocationEditor -import com.phodal.shirecore.workerThread import com.phodal.shirelang.compiler.ShireSyntaxAnalyzer import com.phodal.shirelang.psi.ShireFile import com.phodal.shirelang.run.runner.ShireRunner -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import java.awt.BorderLayout import javax.swing.JComponent @@ -54,7 +50,8 @@ open class ShireRunConfigurationProfileState( ProcessTerminatedListener.attach(processHandler) val sb = StringBuilder() - processHandler.addProcessListener(ShireProcessAdapter(sb, configuration)) + val processAdapter = ShireProcessAdapter(sb, configuration) + processHandler.addProcessListener(processAdapter) // start message log in here console!!.addMessageFilter { line, _ -> @@ -85,7 +82,8 @@ open class ShireRunConfigurationProfileState( console!!.print("Prepare for running ${configuration.name}...\n", ConsoleViewContentType.NORMAL_OUTPUT) ShireCoroutineScope.scope(myProject).launch { - shireRunner.execute(parsedResult) + val llmOutput = shireRunner.execute(parsedResult) + processAdapter.setLlmOutput(llmOutput) } return DefaultExecutionResult(console, processHandler) @@ -121,17 +119,29 @@ class ShireConsoleView(private val executionConsole: ConsoleViewImpl) : class ShireProcessAdapter(private val sb: StringBuilder, val configuration: ShireConfiguration) : ProcessAdapter() { var result = "" + private var llmOutput: String = "" + override fun processTerminated(event: ProcessEvent) { super.processTerminated(event) ApplicationManager.getApplication().messageBus .syncPublisher(ShireRunListener.TOPIC) - .runFinish(result, event, configuration.getScriptPath()) + .runFinish(result, llmOutput, event, configuration.getScriptPath()) } override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) { super.onTextAvailable(event, outputType) result = sb.toString() } + + fun setLlmOutput(llmOutput: String?) { + if (llmOutput != null) { + this.llmOutput = llmOutput + } + } + + fun getLlmOutput(): String? { + return llmOutput + } } diff --git a/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunListener.kt b/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunListener.kt index 6945ae734..615b5a503 100644 --- a/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunListener.kt +++ b/shirelang/src/main/kotlin/com/phodal/shirelang/run/ShireRunListener.kt @@ -6,7 +6,7 @@ import java.util.* @FunctionalInterface interface ShireRunListener : EventListener { - fun runFinish(string: String, event: ProcessEvent, scriptPath: String) + fun runFinish(allOutput: String, llmOutput: String, event: ProcessEvent, scriptPath: String) companion object { @Topic.AppLevel diff --git a/shirelang/src/main/kotlin/com/phodal/shirelang/run/runner/ShireRunner.kt b/shirelang/src/main/kotlin/com/phodal/shirelang/run/runner/ShireRunner.kt index c4908c59a..0bda99a2b 100644 --- a/shirelang/src/main/kotlin/com/phodal/shirelang/run/runner/ShireRunner.kt +++ b/shirelang/src/main/kotlin/com/phodal/shirelang/run/runner/ShireRunner.kt @@ -13,7 +13,6 @@ import com.phodal.shirecore.llm.LlmProvider import com.phodal.shirecore.middleware.PostCodeHandleContext import com.phodal.shirecore.provider.action.TerminalLocationExecutor import com.phodal.shirecore.provider.context.ActionLocationEditor -import com.phodal.shirecore.workerThread import com.phodal.shirelang.ShireBundle import com.phodal.shirelang.compiler.SHIRE_ERROR import com.phodal.shirelang.compiler.ShireParsedResult @@ -28,10 +27,8 @@ import com.phodal.shirelang.run.executor.ShireDefaultLlmExecutor import com.phodal.shirelang.run.executor.ShireLlmExecutor import com.phodal.shirelang.run.executor.ShireLlmExecutorContext import com.phodal.shirelang.run.flow.ShireConversationService -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.* +import java.util.concurrent.CompletableFuture class ShireRunner( private val shireFile: ShireFile, @@ -44,24 +41,32 @@ class ShireRunner( private var compiledVariables: Map = mapOf() private val terminalLocationExecutor = TerminalLocationExecutor.provide(project) - suspend fun execute(parsedResult: ShireParsedResult) { + suspend fun execute(parsedResult: ShireParsedResult): String? { prepareExecute(parsedResult) + val result = CompletableFuture() + val runnerContext = processTemplateCompile(parsedResult) - if (runnerContext.hasError) return + if (runnerContext.hasError) return null project.getService(ShireConversationService::class.java) .createConversation(configuration.getScriptPath(), runnerContext.compileResult) if (runnerContext.hole?.actionLocation == ShireActionLocation.TERMINAL_MENU) { executeTerminalUiTask(runnerContext) { response, textRange -> + result.complete(response) executePostFunction(runnerContext, runnerContext.hole, response, textRange) } } else { executeNormalUiTask(runnerContext) { response, textRange -> + result.complete(response) executePostFunction(runnerContext, runnerContext.hole, response, textRange) } } + + return withContext(Dispatchers.IO) { + result.get() + } } private fun executeTerminalUiTask(context: ShireRunnerContext, postFunction: PostFunction) {