diff --git a/build.gradle.kts b/build.gradle.kts index 4bc7e16b..c1e94a4b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -26,7 +26,7 @@ version = properties("pluginVersion") val kotlin_version = "2.0.0-Beta5" // This line can be removed if not used elsewhere val jetty_version = "11.0.18" val slf4j_version = "2.0.9" -val skyenet_version = "1.0.80" +val skyenet_version = "1.0.81" val remoterobot_version = "0.11.21" val jackson_version = "2.17.0" diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt index 03b02d20..654439fb 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt @@ -62,14 +62,22 @@ class CommandAutofixAction : BaseAction() { .map { root.relativize(it) ?: it }.toSet() override fun codeSummary(paths: List): String = paths - .filter { settings.workingDirectory?.resolve(it.toFile())?.exists() == true } + .filter { + val file = settings.workingDirectory?.resolve(it.toFile()) + file?.exists() == true && !file.isDirectory && file.length() < (256 * 1024) + } .joinToString("\n\n") { path -> - """ - |# ${path} - |$tripleTilde${path.toString().split('.').lastOrNull()} - |${settings.workingDirectory?.resolve(path.toFile())?.readText(Charsets.UTF_8)} - |$tripleTilde - """.trimMargin() + try { + """ + |# ${path} + |$tripleTilde${path.toString().split('.').lastOrNull()} + |${settings.workingDirectory?.resolve(path.toFile())?.readText(Charsets.UTF_8)} + |$tripleTilde + """.trimMargin() + } catch (e: Exception) { + log.warn("Error reading file", e) + "Error reading file `${path}` - ${e.message}" + } } override fun projectSummary(): String { @@ -315,10 +323,6 @@ class CommandAutofixAction : BaseAction() { ) var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { - val map = codeFiles().associateWith { root.resolve(it.toFile()).readText(Charsets.UTF_8) } - map - }, response = response, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -326,6 +330,7 @@ class CommandAutofixAction : BaseAction() { } }, ui = ui, + api=api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt index 2f667c8c..10f4cd7b 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt @@ -6,6 +6,7 @@ import com.github.simiacryptus.aicoder.actions.generic.MassPatchAction.Settings import com.github.simiacryptus.aicoder.config.AppSettingsState import com.github.simiacryptus.aicoder.config.AppSettingsState.Companion.chatModel import com.github.simiacryptus.aicoder.config.Name +import com.github.simiacryptus.aicoder.util.FileSystemUtils.isLLMIncludable import com.github.simiacryptus.aicoder.util.UITools import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent @@ -71,7 +72,7 @@ class MassPatchAction : BaseAction() { /*override*/ fun getConfig(project: Project?, e: AnActionEvent): Settings { val root = UITools.getSelectedFolder(e)?.toNioPath() val files = Files.walk(root) - .filter { Files.isRegularFile(it) && !Files.isDirectory(it) } + .filter { isLLMIncludable(it.toFile()) } .toList().filterNotNull().toTypedArray() val settingsUI = SettingsUI().apply { filesToProcess.setItems(files.toMutableList()) { path -> @@ -96,22 +97,8 @@ class MassPatchAction : BaseAction() { val project = e.project val config = getConfig(project, e) - val codeSummary = config?.settings?.filesToProcess?.filter { - it.toFile().exists() - }?.associateWith { it.toFile().readText(Charsets.UTF_8) } - ?.entries?.joinToString("\n\n") { (path, code) -> - val extension = path.toString().split('.').lastOrNull() - """ - |# $path - |```$extension - |${code.let { /*escapeHtml4*/(it)/*.indent(" ")*/ }} - |``` - """.trimMargin() - } - - val session = StorageInterface.newGlobalID() - SessionProxyServer.chats[session] = MassPatchServer(codeSummary=codeSummary, config=config, api=api) + SessionProxyServer.chats[session] = MassPatchServer(config=config, api=api) val server = AppServer.getServer(e.project) Thread { @@ -165,7 +152,6 @@ class MassPatchAction : BaseAction() { } class MassPatchServer( - val codeSummary: String?, val config: Settings, val api: OpenAIClient ) : ApplicationServer( @@ -173,55 +159,56 @@ class MassPatchServer( path = "/patchChat", showMenubar = false, ) { + + override val singleInput = false override val stickyInput = true private val mainActor: SimpleActor - get() = SimpleActor( - prompt = """ - |You are a helpful AI that helps people with coding. - | - |You will be answering questions about the following code: - | - |${codeSummary ?: ""} - | - |Response should use one or more code patches in diff format within ```diff code blocks. - |Each diff should be preceded by a header that identifies the file being modified. - |The diff format should use + for line additions, - for line deletions. - |The diff should include 2 lines of context before and after every change. - | - |Example: - | - |Here are the patches: - | - |### src/utils/exampleUtils.js - |```diff - | // Utility functions for example feature - | const b = 2; - | function exampleFunction() { - |- return b + 1; - |+ return b + 2; - | } - |``` - | - |### tests/exampleUtils.test.js - |```diff - | // Unit tests for exampleUtils - | const assert = require('assert'); - | const { exampleFunction } = require('../src/utils/exampleUtils'); - | - | describe('exampleFunction', () => { - |- it('should return 3', () => { - |+ it('should return 4', () => { - | assert.equal(exampleFunction(), 3); - | }); - | }); - |``` - | - |If needed, new files can be created by using code blocks labeled with the filename in the same manner. - """.trimMargin(), - model = AppSettingsState.instance.smartModel.chatModel(), - temperature = AppSettingsState.instance.temperature, - ) + get() { + + return SimpleActor( + prompt = """ + |You are a helpful AI that helps people with coding. + | + |Response should use one or more code patches in diff format within ```diff code blocks. + |Each diff should be preceded by a header that identifies the file being modified. + |The diff format should use + for line additions, - for line deletions. + |The diff should include 2 lines of context before and after every change. + | + |Example: + | + |Here are the patches: + | + |### src/utils/exampleUtils.js + |```diff + | // Utility functions for example feature + | const b = 2; + | function exampleFunction() { + |- return b + 1; + |+ return b + 2; + | } + |``` + | + |### tests/exampleUtils.test.js + |```diff + | // Unit tests for exampleUtils + | const assert = require('assert'); + | const { exampleFunction } = require('../src/utils/exampleUtils'); + | + | describe('exampleFunction', () => { + |- it('should return 3', () => { + |+ it('should return 4', () => { + | assert.equal(exampleFunction(), 3); + | }); + | }); + |``` + | + |If needed, new files can be created by using code blocks labeled with the filename in the same manner. + """.trimMargin(), + model = AppSettingsState.instance.smartModel.chatModel(), + temperature = AppSettingsState.instance.temperature, + ) + } override fun newSession(user: User?, session: Session): SocketManager { val socketManager = super.newSession(user, session) @@ -234,6 +221,18 @@ class MassPatchServer( socketManager.scheduledThreadPoolExecutor.schedule({ socketManager.pool.submit { try { + val codeSummary = listOf(path) + ?.filter { isLLMIncludable(it.toFile()) } + ?.associateWith { it.toFile().readText(Charsets.UTF_8) } + ?.entries?.joinToString("\n\n") { (path, code) -> + val extension = path.toString().split('.').lastOrNull() + """ + |# $path + |```$extension + |${code.let { /*escapeHtml4*/(it)/*.indent(" ")*/ }} + |``` + """.trimMargin() + } val fileTask = ui.newTask(false).apply { tabs[path.toString()] = placeholder } @@ -248,7 +247,6 @@ class MassPatchServer( outputFn = { design: String -> var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { codeFiles.associateWith { root.resolve(it.toFile()).readText(Charsets.UTF_8) } }, response = design, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -256,6 +254,7 @@ class MassPatchServer( } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt index 3829b66b..3e063115 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt @@ -127,7 +127,6 @@ class MultiCodeChatAction : BaseAction() { outputFn = { design: String -> var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { codeFiles.associateWith { root.resolve(it.toFile()).readText(Charsets.UTF_8) } }, response = design, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -135,6 +134,7 @@ class MultiCodeChatAction : BaseAction() { } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt index 7574dd6a..f91f83ab 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt @@ -160,7 +160,6 @@ class MultiDiffChatAction : BaseAction() { outputFn = { design: String -> var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { codeFiles.associateWith { root.resolve(it.toFile()).readText(Charsets.UTF_8) } }, response = design, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -168,6 +167,7 @@ class MultiDiffChatAction : BaseAction() { } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt index c8cd769d..a162aed3 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt @@ -3,7 +3,6 @@ package com.github.simiacryptus.aicoder.actions.generic import ai.grazie.utils.mpp.UUID import com.github.simiacryptus.aicoder.AppServer import com.github.simiacryptus.aicoder.actions.BaseAction -import com.github.simiacryptus.aicoder.actions.BaseAction.Companion import com.github.simiacryptus.aicoder.config.AppSettingsState import com.github.simiacryptus.aicoder.util.UITools import com.intellij.openapi.actionSystem.ActionUpdateThread @@ -258,7 +257,6 @@ class MultiStepPatchAction : BaseAction() { } renderMarkdown(ui.socketManager!!.addApplyFileDiffLinks( root = root, - code = { codeFiles.associateWith { root.resolve(it).toFile().readText() } }, response = taskActor.answer(listOf( codeSummary(), userMessage, @@ -275,7 +273,8 @@ class MultiStepPatchAction : BaseAction() { task.complete("$path Updated") } }, - ui = ui + ui = ui, + api = api )) } catch (e: Exception) { task.error(ui, e) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/PlanAheadAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/PlanAheadAction.kt index 27772359..f068fcfa 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/PlanAheadAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/PlanAheadAction.kt @@ -4,7 +4,8 @@ import com.github.simiacryptus.aicoder.AppServer import com.github.simiacryptus.aicoder.actions.BaseAction import com.github.simiacryptus.aicoder.config.AppSettingsState import com.github.simiacryptus.aicoder.config.AppSettingsState.Companion.chatModel -import com.github.simiacryptus.aicoder.util.FileSystemUtils.isGitignore +import com.github.simiacryptus.aicoder.util.FileSystemUtils.expandFileList +import com.github.simiacryptus.aicoder.util.FileSystemUtils.isLLMIncludable import com.github.simiacryptus.aicoder.util.UITools import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent @@ -508,7 +509,8 @@ class PlanAheadAgent( """.trimMargin() } val codeFiles = codeFiles - fun inputFileCode() = subTask.input_files?.joinToString("\n\n\n") { + fun inputFileCode() = ((subTask.input_files ?: listOf()) + (subTask.output_files ?: listOf())) + .filter { isLLMIncludable(root.toFile().resolve(it)) }.joinToString("\n\n") { try { """ |# $it @@ -521,7 +523,7 @@ class PlanAheadAgent( log.warn("Error: root=$root ", e) "" } - } ?: "" + } task.add( renderMarkdown( """ @@ -777,7 +779,7 @@ class PlanAheadAgent( ) genState.taskResult[taskId] = codeResult renderMarkdown(ui.socketManager!!.addSaveLinks(root, codeResult, task, ui = ui), ui = ui) + acceptButtonFooter(sb) { - taskTabs.selectedTab = taskTabs.selectedTab + 1 + taskTabs.selectedTab += 1 taskTabs.update() onComplete() } @@ -811,14 +813,14 @@ class PlanAheadAgent( renderMarkdown( ui.socketManager!!.addApplyFileDiffLinks( root = root, - code = { codeFiles }, response = codeResult, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> task.complete("$path Updated") } }, - ui = ui + ui = ui, + api = api ) + acceptButtonFooter(sb) { taskTabs.selectedTab += 1 taskTabs.update() @@ -852,7 +854,7 @@ class PlanAheadAgent( ) genState.taskResult[taskId] = docResult renderMarkdown("## Generated Documentation\n$docResult", ui = ui) + acceptButtonFooter(sb) { - taskTabs.selectedTab = taskTabs.selectedTab + 1 + taskTabs.selectedTab += 1 taskTabs.update() task.complete() onComplete() @@ -1054,20 +1056,7 @@ class PlanAheadAgent( } val isWindows = System.getProperty("os.name").lowercase(Locale.getDefault()).contains("windows") - fun expandFileList(data: Array): Array { - return data.flatMap { - (when { - it.name.startsWith(".") -> arrayOf() - isGitignore(it) -> arrayOf() - it.length > 1e6 -> arrayOf() - it.extension?.lowercase(Locale.getDefault()) in - setOf("jar", "zip", "class", "png", "jpg", "jpeg", "gif", "ico") -> arrayOf() - - it.isDirectory -> expandFileList(it.children) - else -> arrayOf(it) - }).toList() - }.toTypedArray() - } + } } diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ReactTypescriptWebDevelopmentAssistantAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ReactTypescriptWebDevelopmentAssistantAction.kt index ecef0eea..d1dc9dc6 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ReactTypescriptWebDevelopmentAssistantAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ReactTypescriptWebDevelopmentAssistantAction.kt @@ -551,20 +551,14 @@ Here are the patches: renderMarkdown( ui.socketManager!!.addApplyFileDiffLinks( root = root.toPath(), - code = { - codeFiles.filter { - if (it.name.lowercase().endsWith(".png")) return@filter false - if (it.name.lowercase().endsWith(".jpg")) return@filter false - true - }.map { it to root.resolve(it.toFile()).readText() }.toMap() - }, response = code, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> task.complete("$path Updated") } }, - ui = ui + ui = ui, + api = api ) ) }, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt index 6b97b5cf..fc4a415e 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt @@ -115,7 +115,7 @@ class SimpleCommandAction : BaseAction() { api: API ) { val task = ui.newTask() - task.echo(userMessage) + task.echo(renderMarkdown(userMessage)) Thread { run(ui, task, session, settings, userMessage) }.start() @@ -246,11 +246,6 @@ class SimpleCommandAction : BaseAction() { ) var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { - val map = - codeFiles().associateWith { root.resolve(it.toFile()).readText(Charsets.UTF_8) } - map - }, response = response, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -258,6 +253,7 @@ class SimpleCommandAction : BaseAction() { } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt index bb120999..a91d7774 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt @@ -2,7 +2,6 @@ import com.github.simiacryptus.aicoder.AppServer import com.github.simiacryptus.aicoder.actions.BaseAction -import com.github.simiacryptus.aicoder.actions.BaseAction.Companion import com.github.simiacryptus.aicoder.config.AppSettingsState import com.github.simiacryptus.aicoder.util.UITools import com.intellij.openapi.actionSystem.ActionUpdateThread @@ -419,18 +418,14 @@ class WebDevelopmentAssistantAction : BaseAction() { renderMarkdown( ui.socketManager!!.addApplyFileDiffLinks( root = root.toPath(), - code = { codeFiles.filter { - if (it.name.lowercase().endsWith(".png")) return@filter false - if (it.name.lowercase().endsWith(".jpg")) return@filter false - true - }.map { it to root.resolve(it.toFile()).readText() }.toMap() }, response = code, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> task.complete("$path Updated") } }, - ui = ui + ui = ui, + api = api ) ) }, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt index b96d7d28..12111bca 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt @@ -303,11 +303,6 @@ class ReplicateCommitAction : BaseAction() { ) var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { - val map = - codeFiles().associateWith { root.resolve(it.toFile()).readText(Charsets.UTF_8) } - map - }, response = response, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -315,6 +310,7 @@ class ReplicateCommitAction : BaseAction() { } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt index db77d5a8..78403e9e 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt @@ -21,6 +21,7 @@ import com.intellij.psi.PsiManager import com.intellij.openapi.fileEditor.FileDocumentManager import com.simiacryptus.diff.addApplyFileDiffLinks import com.simiacryptus.diff.addSaveLinks +import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.util.JsonUtil import com.simiacryptus.skyenet.AgentPatterns import com.simiacryptus.skyenet.Retryable @@ -36,7 +37,6 @@ import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.webui.session.SocketManager import com.simiacryptus.skyenet.webui.util.MarkdownUtil.renderMarkdown import java.awt.Desktop -import java.io.File import javax.swing.JOptionPane class AnalyzeProblemAction : AnAction() { @@ -139,12 +139,12 @@ class AnalyzeProblemAction : AnAction() { val task = ui.newTask() task.add("Analyzing problem and suggesting fixes...") Thread { - analyzeProblem(ui, task) + analyzeProblem(ui, task, api = IdeaOpenAIClient.instance) }.start() return socketManager } - private fun analyzeProblem(ui: ApplicationInterface, task: SessionTask) { + private fun analyzeProblem(ui: ApplicationInterface, task: SessionTask, api: API) { try { Retryable(ui, task) { val plan = ParsedActor( @@ -187,7 +187,7 @@ class AnalyzeProblemAction : AnAction() { } } - generateAndAddResponse(ui, task, error, summary, filesToFix) + generateAndAddResponse(ui, task, error, summary, filesToFix, api) } } "" @@ -201,7 +201,8 @@ class AnalyzeProblemAction : AnAction() { task: SessionTask, error: ParsedError, summary: String, - filesToFix: List + filesToFix: List, + api: API ) : String { val response = SimpleActor( prompt = """ @@ -222,10 +223,6 @@ class AnalyzeProblemAction : AnAction() { var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { - val map = filesToFix.map { File(it) }.associate { it.toPath() to root.resolve((it)).readText(Charsets.UTF_8) } - map - }, response = response, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -233,6 +230,7 @@ class AnalyzeProblemAction : AnAction() { } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt index 241754bf..a10c02a3 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt @@ -2,7 +2,6 @@ package com.github.simiacryptus.aicoder.actions.test import com.github.simiacryptus.aicoder.AppServer import com.github.simiacryptus.aicoder.actions.BaseAction -import com.github.simiacryptus.aicoder.actions.generic.CommandAutofixAction import com.github.simiacryptus.aicoder.actions.generic.SessionProxyServer import com.github.simiacryptus.aicoder.config.AppSettingsState import com.github.simiacryptus.aicoder.util.FileSystemUtils.isGitignore @@ -286,10 +285,6 @@ $projectStructure var markdown = ui.socketManager?.addApplyFileDiffLinks( root = root.toPath(), - code = { - val map = filesToFix.map { File(it) }.associate { it.toPath() to root.resolve((it)).readText(Charsets.UTF_8) } - map - }, response = response, handle = { newCodeMap -> newCodeMap.forEach { (path, newCode) -> @@ -297,6 +292,7 @@ $projectStructure } }, ui = ui, + api = api, ) markdown = ui.socketManager?.addSaveLinks( root = root.toPath(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/util/FileSystemUtils.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/util/FileSystemUtils.kt index f05c4987..bdca9551 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/util/FileSystemUtils.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/util/FileSystemUtils.kt @@ -1,9 +1,11 @@ package com.github.simiacryptus.aicoder.util import com.intellij.openapi.vfs.VirtualFile +import java.io.File import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +import java.util.* object FileSystemUtils { @@ -113,6 +115,43 @@ object FileSystemUtils { } } + fun isLLMIncludable(file: File) : Boolean { + return when { + !file.exists() -> false + file.isDirectory -> false + file.name.startsWith(".") -> false + isGitignore(file.toPath()) -> false + file.length() > (256 * 1024) -> false + file.extension?.lowercase(Locale.getDefault()) in setOf( + "jar", + "zip", + "class", + "png", + "jpg", + "jpeg", + "gif", + "ico", + "stl" + ) -> false + else -> true + } + } + + fun expandFileList(data: Array): Array { + return data.flatMap { + (when { + it.name.startsWith(".") -> arrayOf() + isGitignore(it) -> arrayOf() + it.length > 1e6 -> arrayOf() + it.extension?.lowercase(Locale.getDefault()) in + setOf("jar", "zip", "class", "png", "jpg", "jpeg", "gif", "ico") -> arrayOf() + + it.isDirectory -> expandFileList(it.children) + else -> arrayOf(it) + }).toList() + }.toTypedArray() + } + fun isGitignore(file: VirtualFile) = isGitignore(file.toNioPath()) fun isGitignore(path: Path): Boolean {