mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-20 09:24:08 +00:00
refactor: chat request message building
This commit is contained in:
parent
1f74dd2311
commit
148946c5ee
28 changed files with 254 additions and 236 deletions
|
|
@ -61,6 +61,10 @@ public final class EncodingManager {
|
|||
}
|
||||
|
||||
public int countTokens(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
// #444: Cl100kParser.split() throws AssertionError "Input is not UTF-8: "
|
||||
return encoding.countTokens(text.replaceAll("<|", "").replaceAll("|>", ""));
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen
|
|||
message.setReferencedFilePaths(errorMapping.keySet().stream()
|
||||
.map(ReferencedFile::getFilePath)
|
||||
.toList());
|
||||
message.setUserMessage(message.getPrompt());
|
||||
message.setPrompt(CompletionRequestUtil.getPromptWithContext(
|
||||
new ArrayList<>(errorMapping.keySet()),
|
||||
prompt));
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ public class AskQuestionAction extends BaseEditorAction {
|
|||
previousUserPrompt = dialog.getUserPrompt();
|
||||
var message = new Message(
|
||||
format("%s%n```%s%n%s%n```", previousUserPrompt, fileExtension, selectedText));
|
||||
message.setUserMessage(previousUserPrompt);
|
||||
SwingUtilities.invokeLater(() ->
|
||||
project.getService(ChatToolWindowContentManager.class).sendMessage(message));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package ee.carlrobert.codegpt.actions.editor;
|
|||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.intellij.icons.AllIcons.Actions;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
|
|
@ -11,7 +10,6 @@ import com.intellij.openapi.extensions.PluginId;
|
|||
import com.intellij.openapi.project.Project;
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys;
|
||||
import ee.carlrobert.codegpt.ReferencedFile;
|
||||
import ee.carlrobert.codegpt.actions.IncludeFilesInContextAction;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager;
|
||||
|
|
@ -53,15 +51,14 @@ public class EditorActionsUtil {
|
|||
var action = new BaseEditorAction(label, label) {
|
||||
@Override
|
||||
protected void actionPerformed(Project project, Editor editor, String selectedText) {
|
||||
var fileExtension = FileUtil.getFileExtension(editor.getVirtualFile().getName());
|
||||
var message = new Message(prompt.replace(
|
||||
"{{selectedCode}}",
|
||||
format("%n```%s%n%s%n```", fileExtension, selectedText)));
|
||||
message.setUserMessage(prompt.replace("{{selectedCode}}", ""));
|
||||
var toolWindowContentManager =
|
||||
project.getService(ChatToolWindowContentManager.class);
|
||||
toolWindowContentManager.getToolWindow().show();
|
||||
|
||||
var fileExtension = FileUtil.getFileExtension(editor.getVirtualFile().getName());
|
||||
var message = new Message(prompt.replace(
|
||||
"{{selectedCode}}",
|
||||
format("%n```%s%n%s%n```", fileExtension, selectedText)));
|
||||
message.setReferencedFilePaths(
|
||||
Stream.ofNullable(project.getUserData(CodeGPTKeys.SELECTED_FILES))
|
||||
.flatMap(Collection::stream)
|
||||
|
|
|
|||
|
|
@ -45,23 +45,28 @@ public class ChatCompletionEventListener implements CompletionEventListener<Stri
|
|||
|
||||
@Override
|
||||
public void onComplete(StringBuilder messageBuilder) {
|
||||
eventListener.handleCompleted(messageBuilder.toString(), callParameters);
|
||||
handleCompleted(messageBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(StringBuilder messageBuilder) {
|
||||
eventListener.handleCompleted(messageBuilder.toString(), callParameters);
|
||||
handleCompleted(messageBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorDetails error, Throwable ex) {
|
||||
try {
|
||||
callParameters.getConversation().addMessage(callParameters.getMessage());
|
||||
eventListener.handleError(error, ex);
|
||||
} finally {
|
||||
sendError(error, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCompleted(StringBuilder messageBuilder) {
|
||||
eventListener.handleCompleted(messageBuilder.toString(), callParameters);
|
||||
}
|
||||
|
||||
private void sendError(ErrorDetails error, Throwable ex) {
|
||||
var telemetryMessage = TelemetryAction.COMPLETION_ERROR.createActionMessage();
|
||||
if ("insufficient_quota".equals(error.getCode())) {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
package ee.carlrobert.codegpt.conversations.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ee.carlrobert.codegpt.settings.persona.PersonaDetails;
|
||||
import ee.carlrobert.codegpt.ui.DocumentationDetails;
|
||||
import ee.carlrobert.llm.client.you.completion.YouSerpResult;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Message {
|
||||
|
||||
private final UUID id;
|
||||
private String prompt;
|
||||
private String response;
|
||||
private String userMessage;
|
||||
private List<YouSerpResult> serpResults;
|
||||
private List<String> referencedFilePaths;
|
||||
private @Nullable String imageFilePath;
|
||||
private boolean webSearchIncluded;
|
||||
|
|
@ -54,22 +53,6 @@ public class Message {
|
|||
this.response = response;
|
||||
}
|
||||
|
||||
public String getUserMessage() {
|
||||
return userMessage;
|
||||
}
|
||||
|
||||
public void setUserMessage(String userMessage) {
|
||||
this.userMessage = userMessage;
|
||||
}
|
||||
|
||||
public List<YouSerpResult> getSerpResults() {
|
||||
return serpResults;
|
||||
}
|
||||
|
||||
public void setSerpResults(List<YouSerpResult> serpResults) {
|
||||
this.serpResults = serpResults;
|
||||
}
|
||||
|
||||
public List<String> getReferencedFilePaths() {
|
||||
return referencedFilePaths;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
|||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys;
|
||||
|
|
@ -21,7 +22,6 @@ import ee.carlrobert.codegpt.conversations.Conversation;
|
|||
import ee.carlrobert.codegpt.conversations.ConversationService;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.actionprocessor.ActionProcessorFactory;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatMessageResponseBody;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatToolWindowScrollablePanel;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel;
|
||||
|
|
@ -37,9 +37,6 @@ import ee.carlrobert.codegpt.util.file.FileUtil;
|
|||
import git4idea.GitCommit;
|
||||
import java.awt.BorderLayout;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -89,7 +86,7 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
if (conversation.getMessages().isEmpty()) {
|
||||
displayLandingView();
|
||||
} else {
|
||||
displayConversation(conversation);
|
||||
displayConversation();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,8 +115,8 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
totalTokensPanel.updateConversationTokens(conversation);
|
||||
}
|
||||
|
||||
public void addSelection(String fileName, SelectionModel selectionModel) {
|
||||
userInputPanel.addSelection(fileName, selectionModel);
|
||||
public void addSelection(VirtualFile editorFile, SelectionModel selectionModel) {
|
||||
userInputPanel.addSelection(editorFile, selectionModel);
|
||||
}
|
||||
|
||||
public void addCommitReferences(List<GitCommit> gitCommits) {
|
||||
|
|
@ -153,42 +150,27 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
}
|
||||
|
||||
public void sendMessage(Message message, ConversationType conversationType) {
|
||||
sendMessage(message, conversationType, null);
|
||||
}
|
||||
|
||||
public void sendMessage(
|
||||
Message message,
|
||||
ConversationType conversationType,
|
||||
@Nullable String highlightedText) {
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
List<ReferencedFile> referencedFiles = getReferencedFiles();
|
||||
if (!referencedFiles.isEmpty()) {
|
||||
message.setReferencedFilePaths(referencedFiles.stream()
|
||||
.map(ReferencedFile::getFilePath)
|
||||
.toList());
|
||||
message.setUserMessage(message.getPrompt());
|
||||
}
|
||||
var callParameters = ChatCompletionParameters.builder(conversation, message)
|
||||
.sessionId(chatSession.getId())
|
||||
.conversationType(conversationType)
|
||||
.imageDetailsFromPath(CodeGPTKeys.IMAGE_ATTACHMENT_FILE_PATH.get(project))
|
||||
.referencedFiles(getReferencedFiles())
|
||||
.build();
|
||||
|
||||
String attachedImagePath = CodeGPTKeys.IMAGE_ATTACHMENT_FILE_PATH.get(project);
|
||||
if (attachedImagePath != null) {
|
||||
message.setImageFilePath(attachedImagePath);
|
||||
}
|
||||
|
||||
totalTokensPanel.updateConversationTokens(conversation);
|
||||
totalTokensPanel.updateReferencedFilesTokens(referencedFiles);
|
||||
|
||||
if (attachedImagePath != null || !referencedFiles.isEmpty()) {
|
||||
var referencedFiles = callParameters.getReferencedFiles();
|
||||
if ((referencedFiles != null && !referencedFiles.isEmpty())
|
||||
|| callParameters.getImageDetails() != null) {
|
||||
project.getService(ChatToolWindowContentManager.class)
|
||||
.tryFindChatToolWindowPanel()
|
||||
.ifPresent(panel -> panel.clearNotifications(project));
|
||||
}
|
||||
|
||||
var callParameters = getCallParameters(
|
||||
message,
|
||||
conversationType,
|
||||
referencedFiles,
|
||||
highlightedText,
|
||||
attachedImagePath);
|
||||
totalTokensPanel.updateConversationTokens(conversation);
|
||||
if (callParameters.getReferencedFiles() != null) {
|
||||
totalTokensPanel.updateReferencedFilesTokens(callParameters.getReferencedFiles());
|
||||
}
|
||||
|
||||
var responsePanel = createResponsePanel(callParameters);
|
||||
var messagePanel = toolWindowScrollablePanel.addMessage(message.getId());
|
||||
messagePanel.add(new UserMessagePanel(project, message, this));
|
||||
|
|
@ -198,30 +180,6 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
});
|
||||
}
|
||||
|
||||
private ChatCompletionParameters getCallParameters(
|
||||
Message message,
|
||||
ConversationType conversationType,
|
||||
List<ReferencedFile> referencedFiles,
|
||||
@Nullable String highlightedText,
|
||||
@Nullable String attachedImagePath) {
|
||||
var builder = ChatCompletionParameters.builder(conversation, message)
|
||||
.sessionId(chatSession.getId())
|
||||
.conversationType(conversationType)
|
||||
.highlightedText(highlightedText)
|
||||
.referencedFiles(referencedFiles);
|
||||
|
||||
if (attachedImagePath != null && !attachedImagePath.isEmpty()) {
|
||||
try {
|
||||
builder
|
||||
.imageData(Files.readAllBytes(Path.of(attachedImagePath)))
|
||||
.imageMediaType(FileUtil.getImageMediaType(attachedImagePath));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private boolean hasReferencedFilePaths(Message message) {
|
||||
return message.getReferencedFilePaths() != null && !message.getReferencedFilePaths().isEmpty();
|
||||
}
|
||||
|
|
@ -243,7 +201,6 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
.addContent(
|
||||
new ChatMessageResponseBody(
|
||||
project,
|
||||
callParameters.getHighlightedText(),
|
||||
true,
|
||||
false,
|
||||
message.isWebSearchIncluded(),
|
||||
|
|
@ -318,38 +275,21 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
}
|
||||
|
||||
private Unit handleSubmit(String text, List<? extends AppliedActionInlay> appliedInlayActions) {
|
||||
var message = new Message(text);
|
||||
var editor = EditorUtil.getSelectedEditor(project);
|
||||
var messageBuilder = new MessageBuilder(project, text)
|
||||
.withSelectedEditorContent()
|
||||
.withInlays(appliedInlayActions);
|
||||
|
||||
var remainingText = new StringBuilder(text);
|
||||
var promptBuilder = new StringBuilder();
|
||||
|
||||
for (var actionInlay : appliedInlayActions) {
|
||||
var inlayOffset = actionInlay.getInlay().getOffset();
|
||||
promptBuilder.append(remainingText, 0, Math.min(inlayOffset, remainingText.length()))
|
||||
.append("\n");
|
||||
ActionProcessorFactory.getProcessor(actionInlay)
|
||||
.process(message, actionInlay, editor, promptBuilder);
|
||||
remainingText.delete(0, inlayOffset);
|
||||
}
|
||||
promptBuilder.append(remainingText);
|
||||
|
||||
String selectedText = "";
|
||||
String selectedTextMd = "";
|
||||
if (editor != null) {
|
||||
var selectionModel = editor.getSelectionModel();
|
||||
selectedText = selectionModel.getSelectedText();
|
||||
if (selectedText != null && !selectedText.isEmpty()) {
|
||||
var fileExtension = FileUtil.getFileExtension(editor.getVirtualFile().getName());
|
||||
selectedTextMd = format("\n```%s\n%s\n```\n", fileExtension, selectedText);
|
||||
selectionModel.removeSelection();
|
||||
}
|
||||
List<ReferencedFile> referencedFiles = getReferencedFiles();
|
||||
if (!referencedFiles.isEmpty()) {
|
||||
messageBuilder.withReferencedFiles(referencedFiles);
|
||||
}
|
||||
|
||||
message.setUserMessage(selectedTextMd + promptBuilder);
|
||||
message.setPrompt(selectedTextMd + promptBuilder);
|
||||
String attachedImagePath = CodeGPTKeys.IMAGE_ATTACHMENT_FILE_PATH.get(project);
|
||||
if (attachedImagePath != null) {
|
||||
messageBuilder.withImage(attachedImagePath);
|
||||
}
|
||||
|
||||
sendMessage(message, ConversationType.DEFAULT, selectedText);
|
||||
sendMessage(messageBuilder.build(), ConversationType.DEFAULT);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
|
|
@ -386,18 +326,17 @@ public class ChatToolWindowTabPanel implements Disposable {
|
|||
var message = new Message(action.getPrompt().replace(
|
||||
"{{selectedCode}}",
|
||||
format("%n```%s%n%s%n```", fileExtension, editor.getSelectionModel().getSelectedText())));
|
||||
message.setUserMessage(action.getUserMessage());
|
||||
|
||||
sendMessage(message, ConversationType.DEFAULT);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
private void displayConversation(@NotNull Conversation conversation) {
|
||||
private void displayConversation() {
|
||||
clearWindow();
|
||||
conversation.getMessages().forEach(message -> {
|
||||
var response = message.getResponse() == null ? "" : message.getResponse();
|
||||
var messageResponseBody =
|
||||
new ChatMessageResponseBody(project, this).withResponse(message.getResponse());
|
||||
new ChatMessageResponseBody(project, this).withResponse(response);
|
||||
|
||||
messageResponseBody.hideCaret();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.actionprocessor;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.ui.textarea.AppliedActionInlay;
|
||||
|
||||
public interface ActionProcessor {
|
||||
|
||||
void process(Message message, AppliedActionInlay action, Editor editor,
|
||||
StringBuilder promptBuilder);
|
||||
void process(Message message, AppliedActionInlay action, StringBuilder promptBuilder);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.actionprocessor;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import ee.carlrobert.codegpt.ui.textarea.AppliedActionInlay;
|
||||
import ee.carlrobert.codegpt.ui.textarea.AppliedCodeActionInlay;
|
||||
import ee.carlrobert.codegpt.ui.textarea.AppliedSuggestionActionInlay;
|
||||
|
||||
public class ActionProcessorFactory {
|
||||
|
||||
public static ActionProcessor getProcessor(AppliedActionInlay action) {
|
||||
public static ActionProcessor getProcessor(Project project, AppliedActionInlay action) {
|
||||
if (action instanceof AppliedSuggestionActionInlay) {
|
||||
return new SuggestionActionProcessor();
|
||||
return new SuggestionActionProcessor(project);
|
||||
} else if (action instanceof AppliedCodeActionInlay) {
|
||||
return new CodeActionProcessor();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.actionprocessor;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.ui.textarea.AppliedActionInlay;
|
||||
import ee.carlrobert.codegpt.ui.textarea.AppliedCodeActionInlay;
|
||||
|
|
@ -9,18 +8,16 @@ import ee.carlrobert.codegpt.util.file.FileUtil;
|
|||
public class CodeActionProcessor implements ActionProcessor {
|
||||
|
||||
@Override
|
||||
public void process(Message message, AppliedActionInlay action, Editor editor,
|
||||
StringBuilder promptBuilder) {
|
||||
public void process(Message message, AppliedActionInlay action, StringBuilder promptBuilder) {
|
||||
if (!(action instanceof AppliedCodeActionInlay codeAction)) {
|
||||
throw new IllegalArgumentException("Invalid action type");
|
||||
}
|
||||
processCodeAction(codeAction, editor, promptBuilder);
|
||||
processCodeAction(codeAction, promptBuilder);
|
||||
}
|
||||
|
||||
private void processCodeAction(AppliedCodeActionInlay action, Editor editor,
|
||||
StringBuilder promptBuilder) {
|
||||
private void processCodeAction(AppliedCodeActionInlay action, StringBuilder promptBuilder) {
|
||||
promptBuilder
|
||||
.append("\n```%s\n".formatted(FileUtil.getFileExtension(editor.getVirtualFile().getName())))
|
||||
.append("\n```%s\n".formatted(FileUtil.getFileExtension(action.getEditorFile().getName())))
|
||||
.append(action.getCode())
|
||||
.append("\n```\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.actionprocessor;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import ee.carlrobert.codegpt.CodeGPTKeys;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
|
|
@ -11,36 +10,38 @@ import ee.carlrobert.codegpt.ui.textarea.suggestion.item.DocumentationActionItem
|
|||
import ee.carlrobert.codegpt.ui.textarea.suggestion.item.GitCommitActionItem;
|
||||
import ee.carlrobert.codegpt.ui.textarea.suggestion.item.PersonaActionItem;
|
||||
import ee.carlrobert.codegpt.ui.textarea.suggestion.item.WebSearchActionItem;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SuggestionActionProcessor implements ActionProcessor {
|
||||
|
||||
private final Project project;
|
||||
|
||||
public SuggestionActionProcessor(Project project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(Message message, AppliedActionInlay action, Editor editor,
|
||||
public void process(
|
||||
Message message,
|
||||
AppliedActionInlay action,
|
||||
StringBuilder promptBuilder) {
|
||||
if (!(action instanceof AppliedSuggestionActionInlay suggestionAction)) {
|
||||
throw new IllegalArgumentException("Invalid action type");
|
||||
}
|
||||
processSuggestionAction(message, suggestionAction, editor, promptBuilder);
|
||||
processSuggestionAction(message, suggestionAction, promptBuilder);
|
||||
}
|
||||
|
||||
private void processSuggestionAction(
|
||||
Message message,
|
||||
AppliedSuggestionActionInlay action,
|
||||
@Nullable Editor editor,
|
||||
StringBuilder promptBuilder) {
|
||||
message.setWebSearchIncluded(action.getSuggestion() instanceof WebSearchActionItem);
|
||||
if (editor != null) {
|
||||
processDocumentationAction(message, action, editor.getProject());
|
||||
processPersonaAction(message, action, editor.getProject());
|
||||
}
|
||||
|
||||
processDocumentationAction(message, action);
|
||||
processPersonaAction(message, action);
|
||||
processGitCommitAction(action, promptBuilder);
|
||||
}
|
||||
|
||||
private void processDocumentationAction(
|
||||
Message message,
|
||||
AppliedSuggestionActionInlay action,
|
||||
Project project) {
|
||||
private void processDocumentationAction(Message message, AppliedSuggestionActionInlay action) {
|
||||
var addedDocumentation = CodeGPTKeys.ADDED_DOCUMENTATION.get(project);
|
||||
var appliedInlayExists = action.getSuggestion() instanceof DocumentationActionItem
|
||||
|| action.getSuggestion() instanceof CreateDocumentationActionItem;
|
||||
|
|
@ -51,10 +52,7 @@ public class SuggestionActionProcessor implements ActionProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private void processPersonaAction(
|
||||
Message message,
|
||||
AppliedSuggestionActionInlay action,
|
||||
Project project) {
|
||||
private void processPersonaAction(Message message, AppliedSuggestionActionInlay action) {
|
||||
var addedPersona = CodeGPTKeys.ADDED_PERSONA.get(project);
|
||||
var personaInlayExists = action.getSuggestion() instanceof PersonaActionItem;
|
||||
if (addedPersona != null && personaInlayExists) {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import ee.carlrobert.codegpt.util.EditorUtil;
|
|||
import java.awt.BorderLayout;
|
||||
import javax.swing.JPanel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ResponseEditorPanel extends JPanel implements Disposable {
|
||||
|
||||
|
|
@ -49,7 +48,6 @@ public class ResponseEditorPanel extends JPanel implements Disposable {
|
|||
String code,
|
||||
String markdownLanguage,
|
||||
boolean readOnly,
|
||||
@Nullable String highlightedText,
|
||||
Disposable disposableParent) {
|
||||
super(new BorderLayout());
|
||||
setBorder(JBUI.Borders.empty(8, 0));
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import javax.swing.DefaultListModel;
|
|||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextPane;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChatMessageResponseBody extends JPanel {
|
||||
|
||||
|
|
@ -56,25 +56,22 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
private final DefaultListModel<WebSearchEventDetails> webpageListModel = new DefaultListModel<>();
|
||||
private final WebpageList webpageList = new WebpageList(webpageListModel);
|
||||
private final ResponseBodyProgressPanel progressPanel = new ResponseBodyProgressPanel();
|
||||
private final @Nullable String highlightedText;
|
||||
private ResponseEditorPanel currentlyProcessedEditorPanel;
|
||||
private JEditorPane currentlyProcessedTextPane;
|
||||
private JPanel webpageListPanel;
|
||||
|
||||
public ChatMessageResponseBody(Project project, Disposable parentDisposable) {
|
||||
this(project, null, false, false, false, false, parentDisposable);
|
||||
this(project, false, false, false, false, parentDisposable);
|
||||
}
|
||||
|
||||
public ChatMessageResponseBody(
|
||||
Project project,
|
||||
@Nullable String highlightedText,
|
||||
boolean withGhostText,
|
||||
boolean readOnly,
|
||||
boolean webSearchIncluded,
|
||||
boolean withProgress,
|
||||
Disposable parentDisposable) {
|
||||
this.project = project;
|
||||
this.highlightedText = highlightedText;
|
||||
this.parentDisposable = parentDisposable;
|
||||
this.streamParser = new StreamParser();
|
||||
this.readOnly = readOnly;
|
||||
|
|
@ -97,7 +94,7 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
public ChatMessageResponseBody withResponse(String response) {
|
||||
public ChatMessageResponseBody withResponse(@NotNull String response) {
|
||||
try {
|
||||
for (var message : MarkdownUtil.splitCodeBlocks(response)) {
|
||||
processResponse(message, message.startsWith("```"), false);
|
||||
|
|
@ -265,9 +262,8 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
private void prepareProcessingCode(String code, String markdownLanguage) {
|
||||
hideCaret();
|
||||
currentlyProcessedTextPane = null;
|
||||
currentlyProcessedEditorPanel = new ResponseEditorPanel(project, code, markdownLanguage,
|
||||
readOnly, highlightedText,
|
||||
parentDisposable);
|
||||
currentlyProcessedEditorPanel =
|
||||
new ResponseEditorPanel(project, code, markdownLanguage, readOnly, parentDisposable);
|
||||
add(currentlyProcessedEditorPanel);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,15 +47,10 @@ public class UserMessagePanel extends JPanel {
|
|||
displayImage(message.getImageFilePath());
|
||||
}
|
||||
|
||||
var referencedFilePaths = message.getReferencedFilePaths();
|
||||
if (referencedFilePaths != null && !referencedFilePaths.isEmpty()) {
|
||||
add(createResponseBody(
|
||||
project,
|
||||
message.getUserMessage(),
|
||||
parentDisposable), BorderLayout.SOUTH);
|
||||
} else {
|
||||
add(createResponseBody(project, message.getPrompt(), parentDisposable), BorderLayout.SOUTH);
|
||||
}
|
||||
add(createResponseBody(
|
||||
project,
|
||||
message.getPrompt(),
|
||||
parentDisposable), BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
public @Nullable JPanel getAdditionalContextPanel(Project project, Message message) {
|
||||
|
|
@ -99,7 +94,7 @@ public class UserMessagePanel extends JPanel {
|
|||
Project project,
|
||||
String prompt,
|
||||
Disposable parentDisposable) {
|
||||
return new ChatMessageResponseBody(project, null, false, true, false, false, parentDisposable)
|
||||
return new ChatMessageResponseBody(project, false, true, false, false, parentDisposable)
|
||||
.withResponse(prompt);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.ui.textarea;
|
||||
|
||||
import ee.carlrobert.codegpt.EncodingManager;
|
||||
import ee.carlrobert.codegpt.settings.persona.PersonaSettings;
|
||||
|
||||
public class TotalTokensDetails {
|
||||
|
||||
private final int systemPromptTokens;
|
||||
|
|
@ -11,8 +8,8 @@ public class TotalTokensDetails {
|
|||
private int highlightedTokens;
|
||||
private int referencedFilesTokens;
|
||||
|
||||
public TotalTokensDetails(EncodingManager encodingManager) {
|
||||
systemPromptTokens = encodingManager.countTokens(PersonaSettings.getSystemPrompt());
|
||||
public TotalTokensDetails(int systemPromptTokens) {
|
||||
this.systemPromptTokens = systemPromptTokens;
|
||||
}
|
||||
|
||||
public int getSystemPromptTokens() {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ import ee.carlrobert.codegpt.EncodingManager;
|
|||
import ee.carlrobert.codegpt.ReferencedFile;
|
||||
import ee.carlrobert.codegpt.actions.IncludeFilesInContextNotifier;
|
||||
import ee.carlrobert.codegpt.conversations.Conversation;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.settings.GeneralSettings;
|
||||
import ee.carlrobert.codegpt.settings.persona.PersonaSettings;
|
||||
import ee.carlrobert.codegpt.settings.service.ServiceType;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
|
|
@ -105,6 +107,13 @@ public class TotalTokensPanel extends JPanel {
|
|||
label.setText(getLabelHtml(total));
|
||||
}
|
||||
|
||||
public void updateConversationTokens(Conversation conversation, Message message) {
|
||||
totalTokensDetails.setConversationTokens(
|
||||
encodingManager.countConversationTokens(conversation)
|
||||
+ encodingManager.countMessageTokens("user", message.getPrompt()));
|
||||
update();
|
||||
}
|
||||
|
||||
public void updateConversationTokens(Conversation conversation) {
|
||||
totalTokensDetails.setConversationTokens(encodingManager.countConversationTokens(conversation));
|
||||
update();
|
||||
|
|
@ -131,7 +140,8 @@ public class TotalTokensPanel extends JPanel {
|
|||
Conversation conversation,
|
||||
List<ReferencedFile> includedFiles,
|
||||
@Nullable String highlightedText) {
|
||||
var tokenDetails = new TotalTokensDetails(encodingManager);
|
||||
var tokenDetails = new TotalTokensDetails(
|
||||
encodingManager.countTokens(PersonaSettings.getSystemPrompt()));
|
||||
tokenDetails.setConversationTokens(encodingManager.countConversationTokens(conversation));
|
||||
if (includedFiles != null) {
|
||||
tokenDetails.setReferencedFilesTokens(includedFiles.stream()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue