All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.simiacryptus.skyenet.apps.plan.CommandAutoFixTask.kt Maven / Gradle / Ivy

There is a newer version: 1.2.21
Show newest version
package com.simiacryptus.skyenet.apps.plan

import com.simiacryptus.jopenai.API
import com.simiacryptus.jopenai.ChatClient
import com.simiacryptus.skyenet.Retryable
import com.simiacryptus.skyenet.apps.general.CmdPatchApp
import com.simiacryptus.skyenet.apps.general.PatchApp
import com.simiacryptus.skyenet.apps.plan.PlanningTask.TaskBreakdownInterface
import com.simiacryptus.skyenet.webui.session.SessionTask
import com.simiacryptus.skyenet.webui.util.MarkdownUtil
import org.slf4j.LoggerFactory
import java.io.File
import java.util.concurrent.Semaphore

class CommandAutoFixTask(
    planSettings: PlanSettings,
    planTask: PlanningTask.PlanTask
) : AbstractTask(planSettings, planTask) {
    override fun promptSegment(): String {
        return """
             |CommandAutoFix - Run a command and automatically fix any issues that arise
             |  ** Specify the command to be executed and any additional instructions
             |  ** Specify the working directory relative to the root directory
             |  ** Provide the command arguments in the 'commandArguments' field
             |  ** List input files/tasks to be examined when fixing issues
             |  ** Available commands:
             |${planSettings.commandAutoFixCommands?.joinToString("\n") { "    * ${File(it).name}" }}
        """.trimMargin()
    }

    override fun run(
        agent: PlanCoordinator,
        taskId: String,
        userMessage: String,
        plan: TaskBreakdownInterface,
        planProcessingState: PlanProcessingState,
        task: SessionTask,
        api: API
    ) {
        val semaphore = Semaphore(0)
        val onComplete = {
            semaphore.release()
        }
        Retryable(agent.ui, task = task) {
            val task = agent.ui.newTask(false).apply { it.append(placeholder) }
            val alias = this.planTask.execution_task?.command?.first()
            val commandAutoFixCommands = agent.planSettings.commandAutoFixCommands
            val cmds = commandAutoFixCommands
                ?.map { File(it) }?.associateBy { it.name }
                ?.filterKeys { it.startsWith(alias ?: "") }
                ?: emptyMap()
            val executable = cmds.entries.firstOrNull()?.value
            if (executable == null) {
                throw IllegalArgumentException("Command not found: $alias")
            }
            val workingDirectory = (this.planTask.execution_task?.workingDir
                ?.let { agent.root.toFile().resolve(it) } ?: agent.root.toFile())
                .apply { mkdirs() }
            val outputResult = CmdPatchApp(
                root = agent.root,
                session = agent.session,
                settings = PatchApp.Settings(
                    executable = executable,
                    arguments = this.planTask.execution_task?.command?.drop(1)?.joinToString(" ") ?: "",
                    workingDirectory = workingDirectory,
                    exitCodeOption = "nonzero",
                    additionalInstructions = "",
                    autoFix = agent.planSettings.autoFix
                ),
                api = api as ChatClient,
                files = agent.files,
                model = agent.planSettings.getTaskSettings(planTask.task_type!!).model ?: agent.planSettings.defaultModel,
            ).run(
                ui = agent.ui,
                task = task
            )
            planProcessingState.taskResult[taskId] = "Command Auto Fix completed"
            task.add(if (outputResult.exitCode == 0) {
                if (agent.planSettings.autoFix) {
                    onComplete()
                    MarkdownUtil.renderMarkdown("## Auto-applied Command Auto Fix\n", ui = agent.ui)
                } else {
                    MarkdownUtil.renderMarkdown(
                        "## Command Auto Fix Result\n",
                        ui = agent.ui
                    ) + acceptButtonFooter(
                        agent.ui
                    ) {
                        onComplete()
                    }
                }
            } else {
                MarkdownUtil.renderMarkdown(
                    "## Command Auto Fix Failed\n",
                    ui = agent.ui
                ) + acceptButtonFooter(
                    agent.ui
                ) {
                    onComplete()
                }
            })
            task.placeholder
        }
        try {
            semaphore.acquire()
        } catch (e: Throwable) {
            log.warn("Error", e)
        }
        log.debug("Completed command auto fix: $taskId")
    }

    companion object {
        private val log = LoggerFactory.getLogger(CommandAutoFixTask::class.java)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy