Skip to content

Commit

Permalink
feat(core): add postExecute callback to code execution tasks #29
Browse files Browse the repository at this point in the history
This commit introduces a postExecute callback to the code execution tasks. This callback is invoked after the task execution, passing the final output as a parameter. This change affects the CodeCompletionTask, EditorInteractionProvider, CodeCompletionRequest, FileGenerateTask, and LocationInteractionProvider classes. It also modifies the LocationInteractionContext to include a prompt string.
  • Loading branch information
phodal committed Jul 1, 2024
1 parent 10cfc67 commit af6567b
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ data class LocationInteractionContext(
val editor: Editor?,

val project: Project,

/**
* the [com.phodal.shirecore.llm.ChatMessage]
*/
val prompt: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.intellij.openapi.extensions.ExtensionPointName
interface LocationInteractionProvider {
fun isApplicable(context: LocationInteractionContext): Boolean

fun execute(context: LocationInteractionContext) : String
fun execute(context: LocationInteractionContext, postExecute: (String) -> Unit)

companion object {
private val EP_NAME: ExtensionPointName<LocationInteractionProvider> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ class CodeCompletionTask(private val request: CodeCompletionRequest) :
currentOffset.element = request.offset

val project = request.project
val suggestion = StringBuilder()
val finalOutput = StringBuilder()

flow.collect {
suggestion.append(it)
finalOutput.append(it)
invokeLater {
WriteCommandAction.runWriteCommandAction(project, codeMessage, writeActionGroupId, {
insertStringAndSaveChange(project, it, editor.document, currentOffset.element, false)
Expand All @@ -58,7 +58,8 @@ class CodeCompletionTask(private val request: CodeCompletionRequest) :
}
}

logger.info("Suggestion: $suggestion")
logger.info("Suggestion: $finalOutput")
request.postExecute?.invoke(finalOutput.toString())
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.phodal.shirecore.provider.impl

import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator
import com.phodal.shirecore.ShirelangNotifications
Expand All @@ -18,20 +17,22 @@ class EditorInteractionProvider : LocationInteractionProvider {
return true
}

override fun execute(context: LocationInteractionContext): String {
val msgs: List<ChatMessage> = listOf()
override fun execute(context: LocationInteractionContext, postExecute: (String) -> Unit) {
val msgs: List<ChatMessage> = listOf(
// todo: add system prompt
ChatMessage(ChatRole.User, context.prompt),
)
val targetFile = context.editor?.virtualFile
val result: String = ""

when (context.interactionType) {
InteractionType.AppendCursor,
InteractionType.AppendCursorStream,
-> {
val task = createTask(context, msgs, isReplacement = false)
val task = createTask(context, msgs, isReplacement = false, postExecute = postExecute)

if (task == null) {
ShirelangNotifications.error(context.project, "Failed to create code completion task.")
return ""
return
}

ProgressManager.getInstance()
Expand All @@ -40,17 +41,17 @@ class EditorInteractionProvider : LocationInteractionProvider {

InteractionType.OutputFile -> {
val fileName = targetFile?.name
val task = FileGenerateTask(context.project, msgs, fileName)
val task = FileGenerateTask(context.project, msgs, fileName, postExecute = postExecute)
ProgressManager.getInstance()
.runProcessWithProgressAsynchronously(task, BackgroundableProcessIndicator(task))
}

InteractionType.ReplaceSelection -> {
val task = createTask(context, msgs, true)
val task = createTask(context, msgs, true, postExecute)

if (task == null) {
ShirelangNotifications.error(context.project, "Failed to create code completion task.")
return ""
return
}

ProgressManager.getInstance()
Expand All @@ -59,7 +60,7 @@ class EditorInteractionProvider : LocationInteractionProvider {

InteractionType.ReplaceCurrentFile -> {
val fileName = targetFile?.name
val task = FileGenerateTask(context.project, msgs, fileName)
val task = FileGenerateTask(context.project, msgs, fileName, postExecute = postExecute)

ProgressManager.getInstance()
.runProcessWithProgressAsynchronously(task, BackgroundableProcessIndicator(task))
Expand All @@ -69,14 +70,13 @@ class EditorInteractionProvider : LocationInteractionProvider {
TODO()
}
}

return result
}

private fun createTask(
context: LocationInteractionContext,
msgs: List<ChatMessage>,
isReplacement: Boolean,
postExecute: (String) -> Unit,
): CodeCompletionTask? {
if (context.editor == null) {
ShirelangNotifications.error(context.project, "Editor is null, please open a file to continue.")
Expand All @@ -90,7 +90,15 @@ class EditorInteractionProvider : LocationInteractionProvider {
val userPrompt = msgs.filter { it.role == ChatRole.User }.joinToString("\n") { it.content }

val request = runReadAction {
CodeCompletionRequest.create(editor, offset, element, null, userPrompt, isReplacement = isReplacement)
CodeCompletionRequest.create(
editor,
offset,
element,
null,
userPrompt,
isReplacement = isReplacement,
postExecute = postExecute
)
} ?: return null

val task = CodeCompletionTask(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ open class FileGenerateTask(
val messages: List<ChatMessage>,
val fileName: String?,
private val codeOnly: Boolean = false,
private val taskName: String = ShireCoreBundle.message("intentions.request.background.process.title")
private val taskName: String = ShireCoreBundle.message("intentions.request.background.process.title"),

Check warning on line 28 in core/src/main/kotlin/com/phodal/shirecore/provider/impl/FileGenerateTask.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Constructor parameter is never used as a property

Constructor parameter is never used as a property
val postExecute: ((String) -> Unit)?
) :
Task.Backgroundable(project, taskName) {
private val projectRoot = project.guessProjectDir()!!
Expand Down Expand Up @@ -66,6 +67,8 @@ open class FileGenerateTask(
file.writeText(result)
refreshAndOpenInEditor(Path(projectRoot.path), projectRoot)
}

postExecute?.invoke(result)
}

private fun refreshAndOpenInEditor(file: Path, parentDir: VirtualFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class CodeCompletionRequest(
val editor: Editor,
val suffixText: String,

Check warning on line 22 in core/src/main/kotlin/com/phodal/shirecore/provider/impl/dto/CodeCompletionRequest.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "suffixText" is never used
val isReplacement: Boolean = false,

Check warning on line 23 in core/src/main/kotlin/com/phodal/shirecore/provider/impl/dto/CodeCompletionRequest.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "isReplacement" is never used
val postExecute: ((String) -> Unit)?,
) : Disposable {
companion object {
fun create(
Expand All @@ -29,7 +30,8 @@ class CodeCompletionRequest(
element: PsiElement?,
prefix: String?,
suffix: String?,
isReplacement: Boolean = false
isReplacement: Boolean = false,
postExecute: (String) -> Unit,
): CodeCompletionRequest? {
val project = editor.project ?: return null
val document = editor.document
Expand All @@ -56,7 +58,8 @@ class CodeCompletionRequest(
element,
editor,
suffixText,
isReplacement
isReplacement,
postExecute = postExecute
)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ class ShireDefaultRunner(
interactionType = InteractionType.AppendCursorStream,
editor = context.editor,
project = context.myProject,
prompt = context.prompt
)

if (context.hole?.interaction != null) {
val interactionProvider = LocationInteractionProvider.provide(interactionContext)
if (interactionProvider != null) {
val response = interactionProvider.execute(interactionContext)
postFunction(response)
context.processHandler.detachProcess()
interactionProvider.execute(interactionContext) {
postFunction(it)
context.processHandler.detachProcess()
}
return@invokeLater
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import com.intellij.execution.process.ProcessHandler
import com.intellij.execution.ui.ConsoleView
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.phodal.shirecore.action.ShireActionLocation
import com.phodal.shirecore.agent.InteractionType
import com.phodal.shirecore.provider.ide.LocationInteractionContext
import com.phodal.shirecore.provider.ide.LocationInteractionProvider
import com.phodal.shirelang.compiler.hobbit.HobbitHole
import com.phodal.shirelang.run.ShireConfiguration

Expand Down

0 comments on commit af6567b

Please sign in to comment.