From 724870a4ed16a4a893db08bb03051c7cceab80f4 Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Sun, 29 Dec 2024 23:49:02 +0000 Subject: [PATCH] fix: do not process chat files for codegpt api --- .../ProjectCompilationStatusListener.java | 5 +- .../ee/carlrobert/codegpt/ReferencedFile.java | 52 ++++++++++--------- .../actions/IncludeFilesInContextAction.java | 2 +- .../actions/editor/EditorActionsUtil.java | 3 +- .../toolwindow/chat/ChatToolWindowPanel.java | 2 +- .../chat/ChatToolWindowTabPanel.java | 4 +- .../chat/ui/textarea/TotalTokensPanel.java | 4 +- .../ui/checkbox/PsiElementCheckboxTree.java | 3 +- .../ui/checkbox/VirtualFileCheckboxTree.java | 2 +- .../completions/CompletionRequestUtil.kt | 4 +- .../factory/CodeGPTRequestFactory.kt | 4 +- .../factory/OpenAIRequestFactory.kt | 9 ++-- .../AcceptNextPredictionRevisionAction.kt | 7 +-- .../codegpt/predictions/PredictionService.kt | 9 ++++ .../service/ollama/OllamaSettingsForm.kt | 4 +- .../codegpt/toolwindow/chat/MessageBuilder.kt | 2 +- .../codegpt/ui/textarea/FileSearchService.kt | 3 +- 17 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java b/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java index 24999507..695700e8 100644 --- a/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java +++ b/src/main/java/ee/carlrobert/codegpt/ProjectCompilationStatusListener.java @@ -17,7 +17,6 @@ import ee.carlrobert.codegpt.conversations.message.Message; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.ui.OverlayUtil; -import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -66,7 +65,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen var message = new Message("Fix the following compile errors:\n\n" + prompt); message.setReferencedFilePaths(errorMapping.keySet().stream() - .map(ReferencedFile::getFilePath) + .map(ReferencedFile::filePath) .toList()); message.setPrompt(CompletionRequestUtil.getPromptWithContext( new ArrayList<>(errorMapping.keySet()), @@ -77,7 +76,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen private HashMap> getErrorMapping(CompileContext compileContext) { var errorMapping = new HashMap>(); for (var compilerMessage : compileContext.getMessages(CompilerMessageCategory.ERROR)) { - var key = new ReferencedFile(new File(compilerMessage.getVirtualFile().getPath())); + var key = ReferencedFile.from(compilerMessage.getVirtualFile()); var prevValue = errorMapping.get(key); if (prevValue == null) { prevValue = new ArrayList<>(); diff --git a/src/main/java/ee/carlrobert/codegpt/ReferencedFile.java b/src/main/java/ee/carlrobert/codegpt/ReferencedFile.java index 126edde0..64ea4ff2 100644 --- a/src/main/java/ee/carlrobert/codegpt/ReferencedFile.java +++ b/src/main/java/ee/carlrobert/codegpt/ReferencedFile.java @@ -1,5 +1,7 @@ package ee.carlrobert.codegpt; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -8,38 +10,38 @@ import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ReferencedFile { +public record ReferencedFile(String fileName, String filePath, String fileContent) { - private final String fileName; - private final String filePath; - private final String fileContent; + public static ReferencedFile from(File file) { + return new ReferencedFile( + file.getName(), + file.getPath(), + readContent(file) + ); + } - public ReferencedFile(File file) { - this.fileName = file.getName(); - this.filePath = file.getPath(); + public static ReferencedFile from(VirtualFile virtualFile) { + return new ReferencedFile( + virtualFile.getName(), + virtualFile.getPath(), + readContent(virtualFile) + ); + } + + private static String readContent(File file) { try { - this.fileContent = new String(Files.readAllBytes(Paths.get(filePath))); + return new String(Files.readAllBytes(Paths.get(file.getPath()))); } catch (IOException e) { - throw new RuntimeException(e); + throw new RuntimeException("Failed to read file content", e); } } - public ReferencedFile(String fileName, String filePath, String fileContent) { - this.fileName = fileName; - this.filePath = filePath; - this.fileContent = fileContent; - } - - public String getFileName() { - return fileName; - } - - public String getFilePath() { - return filePath; - } - - public String getFileContent() { - return fileContent; + private static String readContent(VirtualFile virtualFile) { + try { + return VfsUtilCore.loadText(virtualFile); + } catch (IOException e) { + throw new RuntimeException("Failed to read virtual file content", e); + } } public String getFileExtension() { diff --git a/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java b/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java index d936bdd4..624e86d7 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java @@ -167,7 +167,7 @@ public class IncludeFilesInContextAction extends AnAction { private int calculateTotalTokens(List referencedFiles) { return referencedFiles.stream() - .mapToInt(file -> encodingManager.countTokens(file.getFileContent())) + .mapToInt(file -> encodingManager.countTokens(file.fileContent())) .sum(); } } diff --git a/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java b/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java index 5e53c7d4..3eb1aecc 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/editor/EditorActionsUtil.java @@ -12,7 +12,6 @@ import com.intellij.openapi.project.Project; import ee.carlrobert.codegpt.CodeGPTKeys; import ee.carlrobert.codegpt.ReferencedFile; import ee.carlrobert.codegpt.conversations.message.Message; -import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; import ee.carlrobert.codegpt.settings.prompts.PromptsSettings; import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; import ee.carlrobert.codegpt.util.file.FileUtil; @@ -69,7 +68,7 @@ public class EditorActionsUtil { message.setReferencedFilePaths( Stream.ofNullable(project.getUserData(CodeGPTKeys.SELECTED_FILES)) .flatMap(Collection::stream) - .map(ReferencedFile::getFilePath) + .map(ReferencedFile::filePath) .toList()); toolWindowContentManager.sendMessage(message); } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java index 6797a5c0..e9aa0866 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java @@ -110,7 +110,7 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel { } var referencedFilePaths = referencedFiles.stream() - .map(ReferencedFile::getFilePath) + .map(ReferencedFile::filePath) .toList(); selectedFilesNotification.show( referencedFiles.size() + " files selected", diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java index 900c20fa..ec96ea26 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java @@ -137,7 +137,7 @@ public class ChatToolWindowTabPanel implements Disposable { }) .forEach(filePath -> { try { - referencedFiles.put(filePath, new ReferencedFile(new File(filePath))); + referencedFiles.put(filePath, ReferencedFile.from(new File(filePath))); } catch (Exception ex) { LOG.error("Failed to create referenced file for path: " + filePath, ex); } @@ -145,7 +145,7 @@ public class ChatToolWindowTabPanel implements Disposable { List selectedFiles = project.getUserData(CodeGPTKeys.SELECTED_FILES); if (selectedFiles != null) { - selectedFiles.forEach(file -> referencedFiles.put(file.getFilePath(), file)); + selectedFiles.forEach(file -> referencedFiles.put(file.filePath(), file)); } return new ArrayList<>(referencedFiles.values()); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/TotalTokensPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/TotalTokensPanel.java index 51d22980..7a7400a2 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/TotalTokensPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/TotalTokensPanel.java @@ -131,7 +131,7 @@ public class TotalTokensPanel extends JPanel { public void updateReferencedFilesTokens(List includedFiles) { totalTokensDetails.setReferencedFilesTokens(includedFiles.stream() - .mapToInt(file -> encodingManager.countTokens(file.getFileContent())) + .mapToInt(file -> encodingManager.countTokens(file.fileContent())) .sum()); update(); } @@ -145,7 +145,7 @@ public class TotalTokensPanel extends JPanel { tokenDetails.setConversationTokens(encodingManager.countConversationTokens(conversation)); if (includedFiles != null) { tokenDetails.setReferencedFilesTokens(includedFiles.stream() - .mapToInt(file -> encodingManager.countTokens(file.getFileContent())) + .mapToInt(file -> encodingManager.countTokens(file.fileContent())) .sum()); } if (highlightedText != null) { diff --git a/src/main/java/ee/carlrobert/codegpt/ui/checkbox/PsiElementCheckboxTree.java b/src/main/java/ee/carlrobert/codegpt/ui/checkbox/PsiElementCheckboxTree.java index ceec5b42..73229577 100644 --- a/src/main/java/ee/carlrobert/codegpt/ui/checkbox/PsiElementCheckboxTree.java +++ b/src/main/java/ee/carlrobert/codegpt/ui/checkbox/PsiElementCheckboxTree.java @@ -32,8 +32,7 @@ public class PsiElementCheckboxTree extends FileCheckboxTree { } return Arrays.stream(checkedNodes) - .map(item -> new ReferencedFile( - new File(item.getContainingFile().getVirtualFile().getPath()))) + .map(item -> ReferencedFile.from(item.getContainingFile().getVirtualFile())) .toList(); } diff --git a/src/main/java/ee/carlrobert/codegpt/ui/checkbox/VirtualFileCheckboxTree.java b/src/main/java/ee/carlrobert/codegpt/ui/checkbox/VirtualFileCheckboxTree.java index 72d91702..69c14468 100644 --- a/src/main/java/ee/carlrobert/codegpt/ui/checkbox/VirtualFileCheckboxTree.java +++ b/src/main/java/ee/carlrobert/codegpt/ui/checkbox/VirtualFileCheckboxTree.java @@ -30,7 +30,7 @@ public class VirtualFileCheckboxTree extends FileCheckboxTree { .map(item -> { var file = new File(item.getPath()); if (file.isFile()) { - return new ReferencedFile(file); + return ReferencedFile.from(item); } return null; }) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/CompletionRequestUtil.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/CompletionRequestUtil.kt index df699e34..7037ce8a 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/CompletionRequestUtil.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/CompletionRequestUtil.kt @@ -15,12 +15,12 @@ object CompletionRequestUtil { val repeatableContext = referencedFiles.stream() .map { item: ReferencedFile -> includedFilesSettings.repeatableContext - .replace("{FILE_PATH}", item.filePath) + .replace("{FILE_PATH}", item.filePath()) .replace( "{FILE_CONTENT}", String.format( "```%s%n%s%n```", item.fileExtension, - item.fileContent.trim { it <= ' ' }) + item.fileContent().trim { it <= ' ' }) ) } .collect(Collectors.joining("\n\n")) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/CodeGPTRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/CodeGPTRequestFactory.kt index f61792a3..dff0b373 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/CodeGPTRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/CodeGPTRequestFactory.kt @@ -17,7 +17,7 @@ class CodeGPTRequestFactory : BaseRequestFactory() { val model = service().state.chatCompletionSettings.model val configuration = service().state val requestBuilder: ChatCompletionRequest.Builder = - ChatCompletionRequest.Builder(buildOpenAIMessages(model, params)) + ChatCompletionRequest.Builder(buildOpenAIMessages(model, params, emptyList())) .setModel(model) .setSessionId(params.sessionId) .setStream(true) @@ -49,7 +49,7 @@ class CodeGPTRequestFactory : BaseRequestFactory() { } params.referencedFiles?.let { val fileContexts = it.map { file -> - ContextFile(file.fileName, file.fileContent) + ContextFile(file.fileName(), file.fileContent()) } requestBuilder.setContext(AdditionalRequestContext(fileContexts)) } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt index 6701b951..6040b814 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt @@ -2,6 +2,7 @@ package ee.carlrobert.codegpt.completions.factory import com.intellij.openapi.components.service import ee.carlrobert.codegpt.EncodingManager +import ee.carlrobert.codegpt.ReferencedFile import ee.carlrobert.codegpt.completions.* import ee.carlrobert.codegpt.conversations.ConversationsState import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings @@ -106,8 +107,9 @@ class OpenAIRequestFactory : CompletionRequestFactory { fun buildOpenAIMessages( model: String?, callParameters: ChatCompletionParameters, + referencedFiles: List? = null ): List { - val messages = buildOpenAIChatMessages(model, callParameters) + val messages = buildOpenAIChatMessages(model, callParameters, referencedFiles ?: callParameters.referencedFiles) if (model == null) { return messages @@ -142,6 +144,7 @@ class OpenAIRequestFactory : CompletionRequestFactory { private fun buildOpenAIChatMessages( model: String?, callParameters: ChatCompletionParameters, + referencedFiles: List? = null ): MutableList { val message = callParameters.message val messages = mutableListOf() @@ -225,11 +228,11 @@ class OpenAIRequestFactory : CompletionRequestFactory { ) ) } else { - val prompt = if (callParameters.referencedFiles.isNullOrEmpty()) { + val prompt = if (referencedFiles.isNullOrEmpty()) { message.prompt } else { CompletionRequestUtil.getPromptWithContext( - callParameters.referencedFiles!!, + referencedFiles, message.prompt ) } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/predictions/AcceptNextPredictionRevisionAction.kt b/src/main/kotlin/ee/carlrobert/codegpt/predictions/AcceptNextPredictionRevisionAction.kt index 2998f7ff..665c1329 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/predictions/AcceptNextPredictionRevisionAction.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/predictions/AcceptNextPredictionRevisionAction.kt @@ -2,6 +2,7 @@ package ee.carlrobert.codegpt.predictions import com.intellij.codeInsight.hint.HintManagerImpl import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.components.service import com.intellij.openapi.editor.Caret import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.actionSystem.EditorAction @@ -17,11 +18,7 @@ class AcceptNextPredictionRevisionAction : EditorAction(Handler()), HintManagerI private class Handler : EditorWriteActionHandler() { override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) { - val diffViewer = editor.getUserData(CodeGPTKeys.EDITOR_PREDICTION_DIFF_VIEWER) - if (diffViewer != null && diffViewer.isVisible()) { - diffViewer.applyChanges() - return - } + service().acceptPrediction(editor) } override fun isEnabledForCaret(editor: Editor, caret: Caret, dataContext: DataContext): Boolean { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/predictions/PredictionService.kt b/src/main/kotlin/ee/carlrobert/codegpt/predictions/PredictionService.kt index dc17549f..d1d3bca6 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/predictions/PredictionService.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/predictions/PredictionService.kt @@ -7,6 +7,7 @@ import com.intellij.openapi.application.runReadAction import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.editor.Editor +import ee.carlrobert.codegpt.CodeGPTKeys import ee.carlrobert.codegpt.CodeGPTKeys.IS_FETCHING_COMPLETION import ee.carlrobert.codegpt.CodeGPTKeys.PENDING_PREDICTION_CALL import ee.carlrobert.codegpt.codecompletions.CodeCompletionProgressNotifier @@ -55,6 +56,14 @@ class PredictionService { displayInlineDiff(editor, request) } + fun acceptPrediction(editor: Editor) { + val diffViewer = editor.getUserData(CodeGPTKeys.EDITOR_PREDICTION_DIFF_VIEWER) + if (diffViewer != null && diffViewer.isVisible()) { + diffViewer.applyChanges() + return + } + } + private fun displayInlineDiff(editor: Editor, request: Request) { val prediction = getPrediction(editor, request) if (prediction != null && !prediction.nextRevision.isNullOrEmpty()) { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt index 5956c9a9..08ec8ed2 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt @@ -159,8 +159,8 @@ class OllamaSettingsForm { .build() .modelTags .models - .map { it.name } - .sortedWith(compareBy({ it.split(":").first() }, { + ?.map { it.name } + ?.sortedWith(compareBy({ it.split(":").first() }, { if (it.contains("latest")) 1 else 0 })) } catch (t: Throwable) { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/MessageBuilder.kt b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/MessageBuilder.kt index c7b6ef58..d4e18df7 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/MessageBuilder.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/MessageBuilder.kt @@ -29,7 +29,7 @@ class MessageBuilder(private val project: Project, private val text: String) { fun withReferencedFiles(referencedFiles: List): MessageBuilder { if (referencedFiles.isNotEmpty()) { - message.referencedFilePaths = referencedFiles.map { it.filePath } + message.referencedFilePaths = referencedFiles.map { it.filePath() } } return this } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/FileSearchService.kt b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/FileSearchService.kt index aa66aefd..e11ce6c9 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/FileSearchService.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/FileSearchService.kt @@ -4,6 +4,7 @@ import com.intellij.openapi.components.Service import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.readText import ee.carlrobert.codegpt.CodeGPTKeys import ee.carlrobert.codegpt.ReferencedFile import ee.carlrobert.codegpt.actions.IncludeFilesInContextNotifier @@ -25,7 +26,7 @@ class FileSearchService private constructor(val project: Project) { project.getUserData(CodeGPTKeys.SELECTED_FILES).orEmpty().toMutableList() files.forEach { file -> try { - filesIncluded.add(ReferencedFile(File(file.path))) + filesIncluded.add(ReferencedFile(file.name, file.path, file.readText())) } catch (e: Exception) { logger.error("Failed to add file to session", e) }