Add checkstyle rules (#274)

This commit is contained in:
Carl-Robert 2023-11-16 17:15:11 +02:00 committed by GitHub
parent fe613afc74
commit c4115e257b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1129 additions and 564 deletions

View file

@ -16,7 +16,9 @@ public class CodeGPTBundle extends DynamicBundle {
return INSTANCE.getMessage(key);
}
public static String get(@NotNull @PropertyKey(resourceBundle = "messages.codegpt") String key, Object... params) {
public static String get(
@NotNull @PropertyKey(resourceBundle = "messages.codegpt") String key,
Object... params) {
return INSTANCE.getMessage(key, params);
}
}

View file

@ -6,7 +6,8 @@ import javax.swing.Icon;
public final class Icons {
public static final Icon DefaultIcon = IconLoader.getIcon("/icons/codegpt.svg", Icons.class);
public static final Icon DefaultSmallIcon = IconLoader.getIcon("/icons/codegpt-small.svg", Icons.class);
public static final Icon DefaultSmallIcon =
IconLoader.getIcon("/icons/codegpt-small.svg", Icons.class);
public static final Icon AzureIcon = IconLoader.getIcon("/icons/azure.svg", Icons.class);
public static final Icon LlamaIcon = IconLoader.getIcon("/icons/llama.svg", Icons.class);
public static final Icon OpenAIIcon = IconLoader.getIcon("/icons/openai.svg", Icons.class);

View file

@ -8,13 +8,13 @@ import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.startup.StartupActivity;
import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil;
import ee.carlrobert.codegpt.completions.you.YouUserManager;
import ee.carlrobert.codegpt.completions.you.auth.AuthenticationHandler;
import ee.carlrobert.codegpt.completions.you.auth.SessionVerificationJob;
import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationError;
import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationService;
import ee.carlrobert.codegpt.completions.you.auth.response.YouAuthenticationResponse;
import ee.carlrobert.codegpt.credentials.YouCredentialsManager;
import ee.carlrobert.codegpt.settings.state.SettingsState;
import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationError;
import ee.carlrobert.codegpt.completions.you.auth.AuthenticationHandler;
import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationService;
import ee.carlrobert.codegpt.completions.you.auth.SessionVerificationJob;
import ee.carlrobert.codegpt.completions.you.auth.response.YouAuthenticationResponse;
import ee.carlrobert.codegpt.util.OverlayUtils;
import org.jetbrains.annotations.NotNull;
import org.quartz.JobBuilder;
@ -89,18 +89,24 @@ public class PluginStartupActivity implements StartupActivity {
.signInAsync(settings.getEmail(), password, new AuthenticationHandler() {
@Override
public void handleAuthenticated(YouAuthenticationResponse authenticationResponse) {
OverlayUtils.showNotification("Authentication successful.", NotificationType.INFORMATION);
OverlayUtils.showNotification(
"Authentication successful.",
NotificationType.INFORMATION);
startSessionVerificationJob();
}
@Override
public void handleGenericError() {
OverlayUtils.showNotification("Something went wrong while trying to authenticate.", NotificationType.ERROR);
OverlayUtils.showNotification(
"Something went wrong while trying to authenticate.",
NotificationType.ERROR);
}
@Override
public void handleError(YouAuthenticationError youAuthenticationError) {
OverlayUtils.showNotification(youAuthenticationError.getErrorMessage(), NotificationType.ERROR);
OverlayUtils.showNotification(
youAuthenticationError.getErrorMessage(),
NotificationType.ERROR);
}
});
}

View file

@ -12,8 +12,8 @@ import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UI;
import ee.carlrobert.codegpt.conversations.message.Message;
import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager;
import ee.carlrobert.codegpt.util.file.FileUtils;
import ee.carlrobert.codegpt.util.SwingUtils;
import ee.carlrobert.codegpt.util.file.FileUtils;
import javax.swing.JComponent;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
@ -31,18 +31,22 @@ class CustomPromptAction extends BaseEditorAction {
@Override
protected void actionPerformed(Project project, Editor editor, String selectedText) {
if (selectedText != null && !selectedText.isEmpty()) {
var fileExtension = FileUtils.getFileExtension(((EditorImpl) editor).getVirtualFile().getName());
var fileExtension =
FileUtils.getFileExtension(((EditorImpl) editor).getVirtualFile().getName());
var dialog = new CustomPromptDialog(previousUserPrompt);
if (dialog.showAndGet()) {
previousUserPrompt = dialog.getUserPrompt();
var message = new Message(format("%s\n```%s\n%s\n```", previousUserPrompt, fileExtension, selectedText));
var message = new Message(
format("%s\n```%s\n%s\n```", previousUserPrompt, fileExtension, selectedText));
message.setUserMessage(previousUserPrompt);
SwingUtilities.invokeLater(() -> project.getService(StandardChatToolWindowContentManager.class).sendMessage(message));
SwingUtilities.invokeLater(() ->
project.getService(StandardChatToolWindowContentManager.class).sendMessage(message));
}
}
}
private static class CustomPromptDialog extends DialogWrapper {
private final JTextArea userPromptTextArea;
public CustomPromptDialog(String previousUserPrompt) {

View file

@ -21,7 +21,8 @@ import org.apache.commons.text.CaseUtils;
public class EditorActionsUtil {
public static Map<String, String> DEFAULT_ACTIONS = new LinkedHashMap<>(Map.of(
"Find Bugs", "Find bugs and output code with bugs fixed in the following code: {{selectedCode}}",
"Find Bugs", "Find bugs and output code with bugs "
+ "fixed in the following code: {{selectedCode}}",
"Write Tests", "Write Tests for the selected code {{selectedCode}}",
"Explain", "Explain the selected code {{selectedCode}}",
"Refactor", "Refactor the selected code {{selectedCode}}",
@ -38,7 +39,8 @@ public class EditorActionsUtil {
}
public static void refreshActions() {
AnAction actionGroup = ActionManager.getInstance().getAction("action.editor.group.EditorActionGroup");
AnAction actionGroup =
ActionManager.getInstance().getAction("action.editor.group.EditorActionGroup");
if (actionGroup instanceof DefaultActionGroup) {
DefaultActionGroup group = (DefaultActionGroup) actionGroup;
group.removeAll();
@ -53,10 +55,14 @@ public class EditorActionsUtil {
var action = new BaseEditorAction(label, label) {
@Override
protected void actionPerformed(Project project, Editor editor, String selectedText) {
var fileExtension = FileUtils.getFileExtension(((EditorImpl) editor).getVirtualFile().getName());
var message = new Message(prompt.replace("{{selectedCode}}", format("\n```%s\n%s\n```", fileExtension, selectedText)));
var fileExtension = FileUtils.getFileExtension(
((EditorImpl) 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(StandardChatToolWindowContentManager.class);
var toolWindowContentManager =
project.getService(StandardChatToolWindowContentManager.class);
var toolWindow = toolWindowContentManager.getToolWindow();
if (toolWindow != null) {
toolWindow.show();

View file

@ -5,8 +5,8 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import ee.carlrobert.codegpt.actions.ActionType;
import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil;
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
import ee.carlrobert.codegpt.conversations.ConversationsState;
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
import org.jetbrains.annotations.NotNull;
public class ClearChatWindowAction extends AnAction {

View file

@ -8,8 +8,8 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.Messages;
import ee.carlrobert.codegpt.actions.ActionType;
import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil;
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
import ee.carlrobert.codegpt.conversations.ConversationService;
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager;
import org.jetbrains.annotations.NotNull;

View file

@ -11,8 +11,8 @@ import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.testFramework.LightVirtualFile;
import ee.carlrobert.codegpt.actions.ActionType;
import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil;
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
import ee.carlrobert.codegpt.conversations.ConversationsState;
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
import java.time.format.DateTimeFormatter;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;

View file

@ -20,8 +20,8 @@ public class ReplaceCodeInMainEditorAction extends AnAction {
@Override
public void update(@NotNull AnActionEvent event) {
event.getPresentation().setEnabled(
EditorUtils.isMainEditorTextSelected(requireNonNull(event.getProject())) &&
EditorUtils.hasSelection(event.getData(PlatformDataKeys.EDITOR)));
EditorUtils.isMainEditorTextSelected(requireNonNull(event.getProject()))
&& EditorUtils.hasSelection(event.getData(PlatformDataKeys.EDITOR)));
}
@Override
@ -29,7 +29,9 @@ public class ReplaceCodeInMainEditorAction extends AnAction {
var project = event.getProject();
var toolWindowEditor = event.getData(PlatformDataKeys.EDITOR);
if (project != null && toolWindowEditor != null) {
EditorUtils.replaceMainEditorSelection(project, requireNonNull(toolWindowEditor.getSelectionModel().getSelectedText()));
EditorUtils.replaceMainEditorSelection(
project,
requireNonNull(toolWindowEditor.getSelectionModel().getSelectedText()));
}
}
}

View file

@ -54,7 +54,9 @@ public class CompletionRequestHandler {
} catch (Throwable ex) {
var errorMessage = "Something went wrong";
if (ex instanceof TotalUsageExceededException) {
errorMessage = "The length of the context exceeds the maximum limit that the model can handle. Try reducing the input message or maximum completion token size.";
errorMessage =
"The length of the context exceeds the maximum limit that the model can handle. "
+ "Try reducing the input message or maximum completion token size.";
}
completionResponseEventListener.handleError(new ErrorDetails(errorMessage), ex);
throw ex;

View file

@ -35,27 +35,27 @@ public class CompletionRequestProvider {
private static final Logger LOG = Logger.getInstance(CompletionRequestProvider.class);
public static final String COMPLETION_SYSTEM_PROMPT = "You are an AI programming assistant.\n" +
"Follow the user's requirements carefully & to the letter.\n" +
"Your responses should be informative and logical.\n" +
"You should always adhere to technical information.\n" +
"If the user asks for code or technical questions, you must provide code suggestions and " +
"adhere to technical information.\n" +
"If the question is related to a developer, you must respond with " +
"content related to a developer.\n" +
"First think step-by-step - describe your plan for what to build in pseudocode, " +
"written out in great detail.\n" +
"Then output the code in a single code block.\n" +
"Minimize any other prose.\n" +
"Keep your answers short and impersonal.\n" +
"Use Markdown formatting in your answers.\n" +
"Make sure to include the programming language name at the start of the " +
"Markdown code blocks.\n" +
"Avoid wrapping the whole response in triple backticks.\n" +
"The user works in an IDE built by JetBrains which has a concept for editors " +
"with open files, integrated unit test support, and output pane that shows " +
"the output of running the code as well as an integrated terminal.\n" +
"You can only give one reply for each conversation turn.";
public static final String COMPLETION_SYSTEM_PROMPT = "You are an AI programming assistant.\n"
+ "Follow the user's requirements carefully & to the letter.\n"
+ "Your responses should be informative and logical.\n"
+ "You should always adhere to technical information.\n"
+ "If the user asks for code or technical questions, you must provide code suggestions and "
+ "adhere to technical information.\n"
+ "If the question is related to a developer, you must respond with "
+ "content related to a developer.\n"
+ "First think step-by-step - describe your plan for what to build in pseudocode, "
+ "written out in great detail.\n"
+ "Then output the code in a single code block.\n"
+ "Minimize any other prose.\n"
+ "Keep your answers short and impersonal.\n"
+ "Use Markdown formatting in your answers.\n"
+ "Make sure to include the programming language name at the start of the "
+ "Markdown code blocks.\n"
+ "Avoid wrapping the whole response in triple backticks.\n"
+ "The user works in an IDE built by JetBrains which has a concept for editors "
+ "with open files, integrated unit test support, and output pane that shows "
+ "the output of running the code as well as an integrated terminal.\n"
+ "You can only give one reply for each conversation turn.";
private final EncodingManager encodingManager = EncodingManager.getInstance();
private final EmbeddingsService embeddingsService;
@ -70,9 +70,9 @@ public class CompletionRequestProvider {
public LlamaCompletionRequest buildLlamaCompletionRequest(Message message) {
var settings = LlamaSettingsState.getInstance();
var promptTemplate = settings.isUseCustomModel() ?
settings.getPromptTemplate() :
LlamaModel.findByHuggingFaceModel(settings.getHuggingFaceModel()).getPromptTemplate();
var promptTemplate = settings.isUseCustomModel()
? settings.getPromptTemplate()
: LlamaModel.findByHuggingFaceModel(settings.getHuggingFaceModel()).getPromptTemplate();
var prompt = promptTemplate.buildPrompt(
COMPLETION_SYSTEM_PROMPT,
message.getPrompt(),
@ -90,8 +90,8 @@ public class CompletionRequestProvider {
prevMessage.getPrompt(),
prevMessage.getResponse()))
.collect(toList()));
if (TelemetryConfiguration.getInstance().isEnabled() &&
!ApplicationManager.getApplication().isUnitTestMode()) {
if (TelemetryConfiguration.getInstance().isEnabled()
&& !ApplicationManager.getApplication().isUnitTestMode()) {
requestBuilder.setUserId(UUID.fromString(UserId.INSTANCE.get()));
}
return requestBuilder.build();

View file

@ -12,7 +12,10 @@ import org.jetbrains.annotations.NotNull;
public enum LlamaModel {
CODE_LLAMA(
"Code Llama",
"Code Llama is a family of large language models for code based on Llama 2 providing state-of-the-art performance among open models, infilling capabilities, support for large input contexts, and zero-shot instruction following ability for programming tasks.",
"Code Llama is a family of large language models for code based on Llama 2 "
+ "providing state-of-the-art performance among open models, infilling capabilities, "
+ "support for large input contexts, and zero-shot instruction following ability for "
+ "programming tasks.",
PromptTemplate.LLAMA,
List.of(
HuggingFaceModel.CODE_LLAMA_7B_Q3,
@ -27,7 +30,9 @@ public enum LlamaModel {
),
CODE_BOOGA(
"CodeBooga",
"CodeBooga is a high-performing code instruct model created by merging two existing code models: <ol><li>Phind-CodeLlama-34B-v2</li><li>WizardCoder-Python-34B-V1.0</li></ol>",
"CodeBooga is a high-performing code instruct model created by merging two existing"
+ " code models: "
+ "<ol><li>Phind-CodeLlama-34B-v2</li><li>WizardCoder-Python-34B-V1.0</li></ol>",
PromptTemplate.ALPACA,
List.of(
HuggingFaceModel.CODE_BOOGA_34B_Q3,
@ -35,7 +40,9 @@ public enum LlamaModel {
HuggingFaceModel.CODE_BOOGA_34B_Q5)),
PHIND_CODE_LLAMA(
"Phind Code Llama",
"This model is fine-tuned from Phind-CodeLlama-34B-v1 on an additional 1.5B tokens high-quality programming-related data, achieving 73.8% pass@1 on HumanEval. It's the current state-of-the-art amongst open-source models.",
"This model is fine-tuned from Phind-CodeLlama-34B-v1 on an additional 1.5B tokens "
+ "high-quality programming-related data, achieving 73.8% pass@1 on HumanEval. "
+ "It's the current state-of-the-art amongst open-source models.",
PromptTemplate.ALPACA,
List.of(
HuggingFaceModel.PHIND_CODE_LLAMA_34B_Q3,
@ -43,7 +50,9 @@ public enum LlamaModel {
HuggingFaceModel.PHIND_CODE_LLAMA_34B_Q5)),
WIZARD_CODER_PYTHON(
"WizardCoder - Python",
"WizardCoder, a Code Evol-Instruct fine-tuned Code LLM, which achieves the 73.2 pass@1 and surpasses GPT4 (2023/03/15), ChatGPT-3.5, and Claude2 on the HumanEval Benchmarks.",
"WizardCoder, a Code Evol-Instruct fine-tuned Code LLM, which achieves "
+ "the 73.2 pass@1 and surpasses GPT4 (2023/03/15), ChatGPT-3.5, "
+ "and Claude2 on the HumanEval Benchmarks.",
PromptTemplate.ALPACA,
List.of(
HuggingFaceModel.WIZARD_CODER_PYTHON_7B_Q3,

View file

@ -57,9 +57,9 @@ public final class LlamaServerAgent implements Disposable {
}
public boolean isServerRunning() {
return startServerProcessHandler != null &&
startServerProcessHandler.isStartNotified() &&
!startServerProcessHandler.isProcessTerminated();
return startServerProcessHandler != null
&& startServerProcessHandler.isStartNotified()
&& !startServerProcessHandler.isProcessTerminated();
}
private ProcessListener getMakeProcessListener(
@ -117,6 +117,7 @@ public final class LlamaServerAgent implements Disposable {
onSuccess.run();
}
} catch (Exception ignore) {
// ignore
}
}
}

View file

@ -78,8 +78,8 @@ public enum PromptTemplate {
public String buildPrompt(String systemPrompt, String userPrompt, List<Message> history) {
StringBuilder prompt = new StringBuilder();
prompt.append(
"Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n");
prompt.append("Below is an instruction that describes a task. "
+ "Write a response that appropriately completes the request.\n\n");
for (Message message : history) {
prompt.append("### Instruction\n")

View file

@ -30,10 +30,10 @@ public final class YouApiClient {
.header("Cache-Control", "no-cache")
.header("User-Agent", "youide CodeGPT")
.header("Cookie", (
"stytch_session=" + sessionId + "; " +
"ydc_stytch_session=" + sessionId + "; " +
"stytch_session_jwt=" + sessionJwt + "; " +
"ydc_stytch_session_jwt=" + sessionJwt + "; "))
"stytch_session=" + sessionId + "; "
+ "ydc_stytch_session=" + sessionId + "; "
+ "stytch_session_jwt=" + sessionJwt + "; "
+ "ydc_stytch_session_jwt=" + sessionJwt + "; "))
.get()
.build();

View file

@ -4,7 +4,8 @@ import com.intellij.util.messages.Topic;
public interface AuthenticationNotifier {
Topic<AuthenticationNotifier> AUTHENTICATION_TOPIC = Topic.create("authenticationTopic", AuthenticationNotifier.class);
Topic<AuthenticationNotifier> AUTHENTICATION_TOPIC =
Topic.create("authenticationTopic", AuthenticationNotifier.class);
void authenticationSuccessful();
}

View file

@ -4,7 +4,8 @@ import com.intellij.util.messages.Topic;
public interface SignedOutNotifier {
Topic<SignedOutNotifier> SIGNED_OUT_TOPIC = Topic.create("signedOutTopic", SignedOutNotifier.class);
Topic<SignedOutNotifier> SIGNED_OUT_TOPIC =
Topic.create("signedOutTopic", SignedOutNotifier.class);
void signedOut();
}

View file

@ -17,7 +17,15 @@ import okhttp3.RequestBody;
public final class YouAuthClient {
private static final String API_BASE_URL = "https://web.stytch.com/sdk";
private static final String publicToken = "public-token-live-507a52ad-7e69-496b-aee0-1c9863c7c819";
private static final String PUBLIC_TOKEN =
"public-token-live-507a52ad-7e69-496b-aee0-1c9863c7c819";
private static final String SDK_CLIENT_JWT = "eyJldmVudF9pZCI6ImV2ZW50LWlkLWY5YmU4YWU5LWE3Mjct"
+ "NGFlYy1hNzY0LTk4NDg1NDFkZjcwYSIsImFwcF9zZXNzaW9uX2lkIjoiYXBwLXNlc3Npb24taWQtYjY1NzcwZjM"
+ "tMWFkMy00YjlhLWFjYzctMzJjNWQyMGMxNGU0IiwicGVyc2lzdGVudF9pZCI6InBlcnNpc3RlbnQtaWQtYzY0M2"
+ "M0YTMtZDg5MC00ZGJkLTk3YjQtMjY0MmFlODdkMTZhIiwiY2xpZW50X3NlbnRfYXQiOiIyMDIzLTA5LTAxVDIyO"
+ "jMwOjU1LjIzNFoiLCJ0aW1lem9uZSI6IkV1cm9wZS9UYWxsaW5uIiwiYXBwIjp7ImlkZW50aWZpZXIiOiJ5b3Uu"
+ "Y29tIn0sInNkayI6eyJpZGVudGlmaWVyIjoiU3R5dGNoLmpzIEphdmFzY3JpcHQgU0RLIC0gWU9VLkNPTSBERUJ"
+ "VRyBCVUlMRCIsInZlcnNpb24iOiI0LjAuMCJ9fQ==";
public static YouAuthClient getInstance() {
return ApplicationManager.getApplication().getService(YouAuthClient.class);
@ -31,8 +39,9 @@ public final class YouAuthClient {
.headers(Headers.of(
"content-type", "application/json",
"authority", "web.stytch.com",
"authorization", "Basic " + Base64.getEncoder().encodeToString((publicToken + ":" + publicToken).getBytes()),
"x-sdk-client", "eyJldmVudF9pZCI6ImV2ZW50LWlkLWY5YmU4YWU5LWE3MjctNGFlYy1hNzY0LTk4NDg1NDFkZjcwYSIsImFwcF9zZXNzaW9uX2lkIjoiYXBwLXNlc3Npb24taWQtYjY1NzcwZjMtMWFkMy00YjlhLWFjYzctMzJjNWQyMGMxNGU0IiwicGVyc2lzdGVudF9pZCI6InBlcnNpc3RlbnQtaWQtYzY0M2M0YTMtZDg5MC00ZGJkLTk3YjQtMjY0MmFlODdkMTZhIiwiY2xpZW50X3NlbnRfYXQiOiIyMDIzLTA5LTAxVDIyOjMwOjU1LjIzNFoiLCJ0aW1lem9uZSI6IkV1cm9wZS9UYWxsaW5uIiwiYXBwIjp7ImlkZW50aWZpZXIiOiJ5b3UuY29tIn0sInNkayI6eyJpZGVudGlmaWVyIjoiU3R5dGNoLmpzIEphdmFzY3JpcHQgU0RLIC0gWU9VLkNPTSBERUJVRyBCVUlMRCIsInZlcnNpb24iOiI0LjAuMCJ9fQ==",
"authorization", "Basic " + Base64.getEncoder().encodeToString(
(PUBLIC_TOKEN + ":" + PUBLIC_TOKEN).getBytes()),
"x-sdk-client", SDK_CLIENT_JWT,
"x-sdk-parent-host", "https://you.com"
))
.post(RequestBody.create(new ObjectMapper()

View file

@ -9,7 +9,9 @@ public class YouAuthenticationError {
private final String errorType;
private final String errorMessage;
public YouAuthenticationError(@JsonProperty("error_type") String errorType, @JsonProperty("error_message") String errorMessage) {
public YouAuthenticationError(
@JsonProperty("error_type") String errorType,
@JsonProperty("error_message") String errorMessage) {
this.errorType = errorType;
this.errorMessage = errorMessage;
}

View file

@ -196,9 +196,9 @@ public final class ConversationService {
return "YouCode";
case LLAMA_CPP:
var llamaSettings = LlamaSettingsState.getInstance();
return llamaSettings.isUseCustomModel() ?
llamaSettings.getCustomLlamaModelPath() :
llamaSettings.getHuggingFaceModel().getCode();
return llamaSettings.isUseCustomModel()
? llamaSettings.getCustomLlamaModelPath()
: llamaSettings.getHuggingFaceModel().getCode();
default:
throw new RuntimeException("Could not find corresponding service mapping");
}

View file

@ -13,7 +13,9 @@ import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@State(name = "ee.carlrobert.codegpt.state.conversations.ConversationsState", storages = @Storage("ChatGPTConversations_170.xml"))
@State(
name = "ee.carlrobert.codegpt.state.conversations.ConversationsState",
storages = @Storage("ChatGPTConversations_170.xml"))
public class ConversationsState implements PersistentStateComponent<ConversationsState> {
@OptionTag(converter = ConversationsConverter.class)

View file

@ -19,7 +19,8 @@ public final class AzureCredentialsManager {
private AzureCredentialsManager() {
azureOpenAIApiKey = CredentialsUtil.getPassword(azureOpenAIApiKeyCredentialAttributes);
azureActiveDirectoryToken = CredentialsUtil.getPassword(azureActiveDirectoryTokenCredentialAttributes);
azureActiveDirectoryToken =
CredentialsUtil.getPassword(azureActiveDirectoryTokenCredentialAttributes);
}
public static AzureCredentialsManager getInstance() {
@ -27,7 +28,9 @@ public final class AzureCredentialsManager {
}
public String getSecret() {
return AzureSettingsState.getInstance().isUseAzureActiveDirectoryAuthentication() ? azureActiveDirectoryToken : azureOpenAIApiKey;
return AzureSettingsState.getInstance().isUseAzureActiveDirectoryAuthentication()
? azureActiveDirectoryToken
: azureOpenAIApiKey;
}
public @Nullable String getAzureOpenAIApiKey() {
@ -45,7 +48,9 @@ public final class AzureCredentialsManager {
public void setAzureActiveDirectoryToken(String azureActiveDirectoryToken) {
this.azureActiveDirectoryToken = azureActiveDirectoryToken;
CredentialsUtil.setPassword(azureActiveDirectoryTokenCredentialAttributes, azureActiveDirectoryToken);
CredentialsUtil.setPassword(
azureActiveDirectoryTokenCredentialAttributes,
azureActiveDirectoryToken);
}
public boolean isCredentialSet() {

View file

@ -8,7 +8,8 @@ import org.jetbrains.annotations.Nullable;
@Service
public final class OpenAICredentialsManager {
private static final CredentialAttributes openAIApiKeyCredentialAttributes = CredentialsUtil.createCredentialAttributes("OPENAI_API_KEY");
private static final CredentialAttributes openAIApiKeyCredentialAttributes =
CredentialsUtil.createCredentialAttributes("OPENAI_API_KEY");
private String openAIApiKey;

View file

@ -8,7 +8,8 @@ import org.jetbrains.annotations.Nullable;
@Service
public final class YouCredentialsManager {
private static final CredentialAttributes accountPasswordCredentialAttributes = CredentialsUtil.createCredentialAttributes("ACCOUNT_PASSWORD");
private static final CredentialAttributes accountPasswordCredentialAttributes =
CredentialsUtil.createCredentialAttributes("ACCOUNT_PASSWORD");
private String accountPassword;

View file

@ -14,8 +14,8 @@ import com.intellij.openapi.util.io.FileUtil;
import ee.carlrobert.codegpt.CodeGPTBundle;
import ee.carlrobert.codegpt.CodeGPTPlugin;
import ee.carlrobert.codegpt.completions.CompletionClientProvider;
import ee.carlrobert.codegpt.util.file.FileUtils;
import ee.carlrobert.codegpt.util.OverlayUtils;
import ee.carlrobert.codegpt.util.file.FileUtils;
import ee.carlrobert.embedding.CheckedFile;
import ee.carlrobert.embedding.EmbeddingsService;
import ee.carlrobert.vector.VectorStore;
@ -34,7 +34,9 @@ public class CodebaseIndexingTask extends Task.Backgroundable {
super(project, CodeGPTBundle.get("codebaseIndexing.task.title"), true);
this.project = project;
this.checkedFiles = checkedFiles;
this.embeddingsService = new EmbeddingsService(CompletionClientProvider.getOpenAIClient(), CodeGPTPlugin.getPluginBasePath());
this.embeddingsService = new EmbeddingsService(
CompletionClientProvider.getOpenAIClient(),
CodeGPTPlugin.getPluginBasePath());
}
public void run() {
@ -56,11 +58,13 @@ public class CodebaseIndexingTask extends Task.Backgroundable {
if (!FileUtil.exists(CodeGPTPlugin.getIndexStorePath())) {
FileUtils.tryCreateDirectory(CodeGPTPlugin.getIndexStorePath());
}
FileUtils.createFile(CodeGPTPlugin.getProjectIndexStorePath(project), "index.json", fileContent);
FileUtils.createFile(
CodeGPTPlugin.getProjectIndexStorePath(project), "index.json", fileContent);
try {
indicator.setFraction(0);
List<Item<Object, double[]>> embeddings = embeddingsService.createEmbeddings(checkedFiles, indicator);
List<Item<Object, double[]>> embeddings =
embeddingsService.createEmbeddings(checkedFiles, indicator);
VectorStore.getInstance(CodeGPTPlugin.getPluginBasePath()).save(embeddings);
OverlayUtils.showNotification("Indexing completed", NotificationType.INFORMATION);

View file

@ -86,6 +86,7 @@ public class FolderStructureTreePanel {
totalSize -= length;
}
} catch (Throwable ignored) {
// ignore
}
}
});
@ -122,10 +123,11 @@ public class FolderStructureTreePanel {
panel.add(new JBLabel("Total size:"));
panel.add(loadingFilesSpinner);
} else {
panel.add(new JBLabel("Total size: " +
FileUtils.convertFileSize(totalSize) + " ~ " +
(convertLongValue(totalSize / 4)) + " tokens " + " ~ " +
new DecimalFormat("#.##").format(((double) (totalSize / 4) / 1000) * 0.0001) + " $"));
panel.add(new JBLabel("Total size: "
+ FileUtils.convertFileSize(totalSize) + " ~ "
+ (convertLongValue(totalSize / 4)) + " tokens " + " ~ "
+ new DecimalFormat("#.##")
.format(((double) (totalSize / 4) / 1000) * 0.0001) + " $"));
}
return panel;
}
@ -149,16 +151,17 @@ public class FolderStructureTreePanel {
try {
if (node.isChecked()) {
node.setChecked(!changeListManager.isIgnoredFile(file) &&
!ignoreManager.isPotentiallyIgnoredFile(file) &&
FileUtils.isUtf8File(file.getPath()) &&
fileSize < Math.pow(1024, 2));
node.setChecked(!changeListManager.isIgnoredFile(file)
&& !ignoreManager.isPotentiallyIgnoredFile(file)
&& FileUtils.isUtf8File(file.getPath())
&& fileSize < Math.pow(1024, 2));
}
if (node.isChecked()) {
totalSize += fileSize;
}
} catch (RuntimeException ignored) {
// ignore
}
}

View file

@ -98,8 +98,8 @@ public class SettingsComponent {
.withValidator(() -> {
if (component instanceof ComboBox) {
var selectedItem = ((ComboBox<?>) component).getSelectedItem();
if (selectedItem == ServiceType.OPENAI &&
OpenAISettingsState.getInstance().isOpenAIQuotaExceeded()) {
if (selectedItem == ServiceType.OPENAI
&& OpenAISettingsState.getInstance().isOpenAIQuotaExceeded()) {
return new ValidationInfo(
CodeGPTBundle.get("settings.openaiQuotaExceeded"),
component);

View file

@ -54,31 +54,25 @@ public class SettingsConfigurable implements Configurable {
var serviceSelectionForm = settingsComponent.getServiceSelectionForm();
var llamaModelPreferencesForm = serviceSelectionForm.getLlamaModelPreferencesForm();
return !settingsComponent.getDisplayName().equals(settings.getDisplayName()) ||
isServiceChanged(settings) ||
openAISettings.isModified(serviceSelectionForm) ||
azureSettings.isModified(serviceSelectionForm) ||
serviceSelectionForm.isDisplayWebSearchResults() !=
YouSettingsState.getInstance().isDisplayWebSearchResults() ||
return !settingsComponent.getDisplayName().equals(settings.getDisplayName())
|| isServiceChanged(settings)
|| openAISettings.isModified(serviceSelectionForm)
|| azureSettings.isModified(serviceSelectionForm)
|| serviceSelectionForm.isDisplayWebSearchResults()
!= YouSettingsState.getInstance().isDisplayWebSearchResults()
llamaSettings.isUseCustomModel() != llamaModelPreferencesForm.isUseCustomLlamaModel() ||
llamaSettings.getServerPort() != serviceSelectionForm.getLlamaServerPort() ||
llamaSettings.getContextSize() != serviceSelectionForm.getContextSize() ||
llamaSettings.getHuggingFaceModel() != llamaModelPreferencesForm.getSelectedModel() ||
!llamaSettings.getPromptTemplate().equals(llamaModelPreferencesForm.getPromptTemplate()) ||
!llamaSettings.getCustomLlamaModelPath()
.equals(llamaModelPreferencesForm.getCustomLlamaModelPath());
|| llamaSettings.isUseCustomModel() != llamaModelPreferencesForm.isUseCustomLlamaModel()
|| llamaSettings.getServerPort() != serviceSelectionForm.getLlamaServerPort()
|| llamaSettings.getContextSize() != serviceSelectionForm.getContextSize()
|| llamaSettings.getHuggingFaceModel() != llamaModelPreferencesForm.getSelectedModel()
|| !llamaSettings.getPromptTemplate().equals(llamaModelPreferencesForm.getPromptTemplate())
|| !llamaSettings.getCustomLlamaModelPath()
.equals(llamaModelPreferencesForm.getCustomLlamaModelPath());
}
@Override
public void apply() {
var serviceSelectionForm = settingsComponent.getServiceSelectionForm();
var settings = SettingsState.getInstance();
var openAISettings = OpenAISettingsState.getInstance();
var azureSettings = AzureSettingsState.getInstance();
var llamaSettings = LlamaSettingsState.getInstance();
var serviceChanged = isServiceChanged(settings);
var modelChanged = !openAISettings.getModel().equals(serviceSelectionForm.getOpenAIModel());
var prevKey = OpenAICredentialsManager.getInstance().getApiKey();
if (prevKey != null && !prevKey.equals(serviceSelectionForm.getOpenAIApiKey())) {
@ -90,10 +84,12 @@ public class SettingsConfigurable implements Configurable {
AzureCredentialsManager.getInstance()
.setAzureActiveDirectoryToken(serviceSelectionForm.getAzureActiveDirectoryToken());
var settings = SettingsState.getInstance();
settings.setDisplayName(settingsComponent.getDisplayName());
settings.setSelectedService(settingsComponent.getSelectedService());
var llamaModelPreferencesForm = serviceSelectionForm.getLlamaModelPreferencesForm();
var llamaSettings = LlamaSettingsState.getInstance();
llamaSettings.setCustomLlamaModelPath(llamaModelPreferencesForm.getCustomLlamaModelPath());
llamaSettings.setHuggingFaceModel(llamaModelPreferencesForm.getSelectedModel());
llamaSettings.setUseCustomModel(llamaModelPreferencesForm.isUseCustomLlamaModel());
@ -101,11 +97,15 @@ public class SettingsConfigurable implements Configurable {
llamaSettings.setServerPort(serviceSelectionForm.getLlamaServerPort());
llamaSettings.setContextSize(serviceSelectionForm.getContextSize());
var azureSettings = AzureSettingsState.getInstance();
var openAISettings = OpenAISettingsState.getInstance();
openAISettings.apply(serviceSelectionForm);
azureSettings.apply(serviceSelectionForm);
YouSettingsState.getInstance()
.setDisplayWebSearchResults(serviceSelectionForm.isDisplayWebSearchResults());
var serviceChanged = isServiceChanged(settings);
var modelChanged = !openAISettings.getModel().equals(serviceSelectionForm.getOpenAIModel());
if (serviceChanged || modelChanged) {
resetActiveTab();
if (serviceChanged) {
@ -119,15 +119,13 @@ public class SettingsConfigurable implements Configurable {
@Override
public void reset() {
var settings = SettingsState.getInstance();
var openAISettings = OpenAISettingsState.getInstance();
var azureSettings = AzureSettingsState.getInstance();
var llamaSettings = LlamaSettingsState.getInstance();
var serviceSelectionForm = settingsComponent.getServiceSelectionForm();
// settingsComponent.setEmail(settings.getEmail());
settingsComponent.setDisplayName(settings.getDisplayName());
settingsComponent.setSelectedService(settings.getSelectedService());
var llamaSettings = LlamaSettingsState.getInstance();
var llamaModelPreferencesForm = serviceSelectionForm.getLlamaModelPreferencesForm();
llamaModelPreferencesForm.setSelectedModel(llamaSettings.getHuggingFaceModel());
llamaModelPreferencesForm.setCustomLlamaModelPath(llamaSettings.getCustomLlamaModelPath());
@ -135,8 +133,9 @@ public class SettingsConfigurable implements Configurable {
llamaModelPreferencesForm.setPromptTemplate(llamaSettings.getPromptTemplate());
serviceSelectionForm.setLlamaServerPort(llamaSettings.getServerPort());
serviceSelectionForm.setContextSize(llamaSettings.getContextSize());
openAISettings.reset(serviceSelectionForm);
azureSettings.reset(serviceSelectionForm);
OpenAISettingsState.getInstance().reset(serviceSelectionForm);
AzureSettingsState.getInstance().reset(serviceSelectionForm);
serviceSelectionForm.setDisplayWebSearchResults(
YouSettingsState.getInstance().isDisplayWebSearchResults());

View file

@ -30,7 +30,7 @@ public class AdvancedSettingsComponent {
private final PortField readTimeoutField;
public AdvancedSettingsComponent(AdvancedSettingsState advancedSettings) {
proxyTypeComboBox = new ComboBox<>(new Proxy.Type[] {
proxyTypeComboBox = new ComboBox<>(new Proxy.Type[]{
Proxy.Type.SOCKS,
Proxy.Type.HTTP,
Proxy.Type.DIRECT,
@ -57,7 +57,8 @@ public class AdvancedSettingsComponent {
"advancedSettingsConfigurable.proxy.title")))
.addComponent(createProxySettingsForm())
.addVerticalGap(4)
.addComponent(new TitledSeparator(CodeGPTBundle.get("advancedSettingsConfigurable.connectionSettings.title")))
.addComponent(new TitledSeparator(
CodeGPTBundle.get("advancedSettingsConfigurable.connectionSettings.title")))
.addComponent(createConnectionSettingsForm())
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
@ -65,8 +66,13 @@ public class AdvancedSettingsComponent {
private JPanel createConnectionSettingsForm() {
var panel = FormBuilder.createFormBuilder()
.addLabeledComponent(CodeGPTBundle.get("advancedSettingsConfigurable.connectionSettings.connectionTimeout.label"), connectionTimeoutField)
.addLabeledComponent(CodeGPTBundle.get("advancedSettingsConfigurable.connectionSettings.readTimeout.label"), readTimeoutField)
.addLabeledComponent(
CodeGPTBundle.get(
"advancedSettingsConfigurable.connectionSettings.connectionTimeout.label"),
connectionTimeoutField)
.addLabeledComponent(
CodeGPTBundle.get("advancedSettingsConfigurable.connectionSettings.readTimeout.label"),
readTimeoutField)
.getPanel();
panel.setBorder(JBUI.Borders.emptyLeft(16));
return panel;

View file

@ -27,14 +27,16 @@ public class AdvancedSettingsConfigurable implements Configurable {
@Override
public boolean isModified() {
var advancedSettings = AdvancedSettingsState.getInstance();
return !advancedSettingsComponent.getProxyType().equals(advancedSettings.getProxyType()) ||
!advancedSettingsComponent.getProxyHost().equals(advancedSettings.getProxyHost()) ||
advancedSettingsComponent.getProxyPort() != advancedSettings.getProxyPort() ||
advancedSettingsComponent.isProxyAuthSelected() != advancedSettings.isProxyAuthSelected() ||
!advancedSettingsComponent.getProxyAuthUsername().equals(advancedSettings.getProxyUsername()) ||
!advancedSettingsComponent.getProxyAuthPassword().equals(advancedSettings.getProxyPassword()) ||
advancedSettingsComponent.getConnectionTimeout() != advancedSettings.getConnectTimeout() ||
advancedSettingsComponent.getReadTimeout() != advancedSettings.getReadTimeout();
return !advancedSettingsComponent.getProxyType().equals(advancedSettings.getProxyType())
|| !advancedSettingsComponent.getProxyHost().equals(advancedSettings.getProxyHost())
|| advancedSettingsComponent.getProxyPort() != advancedSettings.getProxyPort()
|| advancedSettingsComponent.isProxyAuthSelected() != advancedSettings.isProxyAuthSelected()
|| !advancedSettingsComponent.getProxyAuthUsername()
.equals(advancedSettings.getProxyUsername())
|| !advancedSettingsComponent.getProxyAuthPassword()
.equals(advancedSettings.getProxyPassword())
|| advancedSettingsComponent.getConnectionTimeout() != advancedSettings.getConnectTimeout()
|| advancedSettingsComponent.getReadTimeout() != advancedSettings.getReadTimeout();
}
@Override

View file

@ -9,7 +9,9 @@ import java.net.Proxy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@State(name = "CodeGPT_AdvancedSettings_210", storages = @Storage("CodeGPT_AdvancedSettings_210.xml"))
@State(
name = "CodeGPT_AdvancedSettings_210",
storages = @Storage("CodeGPT_AdvancedSettings_210.xml"))
public class AdvancedSettingsState implements PersistentStateComponent<AdvancedSettingsState> {
private String proxyHost = "";

View file

@ -60,7 +60,8 @@ public class ConfigurationComponent {
table.getColumnModel().getColumn(1).setPreferredWidth(240);
table.getEmptyText().setText(CodeGPTBundle.get("configurationConfigurable.table.emptyText"));
var tablePanel = createTablePanel();
tablePanel.setBorder(BorderFactory.createTitledBorder(CodeGPTBundle.get("configurationConfigurable.table.title")));
tablePanel.setBorder(BorderFactory.createTitledBorder(
CodeGPTBundle.get("configurationConfigurable.table.title")));
temperatureField = new JBTextField(12);
temperatureField.setText(String.valueOf(configuration.getTemperature()));
@ -99,14 +100,16 @@ public class ConfigurationComponent {
systemPromptTextArea.setColumns(60);
systemPromptTextArea.setRows(3);
openNewTabCheckBox = new JBCheckBox(CodeGPTBundle.get("configurationConfigurable.openNewTabCheckBox.label"), false);
openNewTabCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.openNewTabCheckBox.label"), false);
mainPanel = FormBuilder.createFormBuilder()
.addComponent(tablePanel)
.addVerticalGap(4)
.addComponent(openNewTabCheckBox)
.addVerticalGap(4)
.addComponent(new TitledSeparator(CodeGPTBundle.get("configurationConfigurable.section.assistant.title")))
.addComponent(new TitledSeparator(
CodeGPTBundle.get("configurationConfigurable.section.assistant.title")))
.addComponent(createAssistantConfigurationForm())
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
@ -140,7 +143,11 @@ public class ConfigurationComponent {
}
// Formatted keys are not referenced in the messages bundle file
private void addAssistantFormLabeledComponent(FormBuilder formBuilder, String labelKey, String commentKey, JComponent component) {
private void addAssistantFormLabeledComponent(
FormBuilder formBuilder,
String labelKey,
String commentKey,
JComponent component) {
formBuilder.addLabeledComponent(
new JBLabel(CodeGPTBundle.get(labelKey))
.withBorder(JBUI.Borders.emptyLeft(2)),
@ -180,17 +187,23 @@ public class ConfigurationComponent {
return form;
}
private ComponentValidator createInputValidator(Disposable parentDisposable, JBTextField component) {
private ComponentValidator createInputValidator(
Disposable parentDisposable,
JBTextField component) {
var validator = new ComponentValidator(parentDisposable)
.withValidator(() -> {
var valueText = component.getText();
try {
var value = Double.parseDouble(valueText);
if (value > 1.0 || value < 0.0) {
return new ValidationInfo(CodeGPTBundle.get("validation.error.mustBeBetweenZeroAndOne"), component);
return new ValidationInfo(
CodeGPTBundle.get("validation.error.mustBeBetweenZeroAndOne"),
component);
}
} catch (NumberFormatException e) {
return new ValidationInfo(CodeGPTBundle.get("validation.error.mustBeNumber"), component);
return new ValidationInfo(
CodeGPTBundle.get("validation.error.mustBeNumber"),
component);
}
return null;
@ -246,7 +259,9 @@ public class ConfigurationComponent {
class RevertToDefaultsActionButton extends AnActionButton {
RevertToDefaultsActionButton() {
super(CodeGPTBundle.get("configurationConfigurable.table.action.revertToDefaults.text"), AllIcons.Actions.Rollback);
super(
CodeGPTBundle.get("configurationConfigurable.table.action.revertToDefaults.text"),
AllIcons.Actions.Rollback);
}
@Override
@ -261,7 +276,9 @@ public class ConfigurationComponent {
class KeymapActionButton extends AnActionButton {
KeymapActionButton() {
super(CodeGPTBundle.get("configurationConfigurable.table.action.addKeymap.text"), Nodes.KeymapEditor);
super(
CodeGPTBundle.get("configurationConfigurable.table.action.addKeymap.text"),
Nodes.KeymapEditor);
}
@Override

View file

@ -33,11 +33,12 @@ public class ConfigurationConfigurable implements Configurable {
@Override
public boolean isModified() {
var configuration = ConfigurationState.getInstance();
return !configurationComponent.getTableData().equals(configuration.getTableData()) ||
configurationComponent.getMaxTokens() != configuration.getMaxTokens() ||
configurationComponent.getTemperature() != configuration.getTemperature() ||
!configurationComponent.getSystemPrompt().equals(configuration.getSystemPrompt()) ||
configurationComponent.isCreateNewChatOnEachAction() != configuration.isCreateNewChatOnEachAction();
return !configurationComponent.getTableData().equals(configuration.getTableData())
|| configurationComponent.getMaxTokens() != configuration.getMaxTokens()
|| configurationComponent.getTemperature() != configuration.getTemperature()
|| !configurationComponent.getSystemPrompt().equals(configuration.getSystemPrompt())
|| configurationComponent.isCreateNewChatOnEachAction()
!= configuration.isCreateNewChatOnEachAction();
}
@Override
@ -47,7 +48,8 @@ public class ConfigurationConfigurable implements Configurable {
configuration.setMaxTokens(configurationComponent.getMaxTokens());
configuration.setTemperature(configurationComponent.getTemperature());
configuration.setSystemPrompt(configurationComponent.getSystemPrompt());
configuration.setCreateNewChatOnEachAction(configurationComponent.isCreateNewChatOnEachAction());
configuration.setCreateNewChatOnEachAction(
configurationComponent.isCreateNewChatOnEachAction());
EditorActionsUtil.refreshActions();
}
@ -58,7 +60,8 @@ public class ConfigurationConfigurable implements Configurable {
configurationComponent.setMaxTokens(configuration.getMaxTokens());
configurationComponent.setTemperature(configuration.getTemperature());
configurationComponent.setSystemPrompt(configuration.getSystemPrompt());
configurationComponent.setCreateNewChatOnEachAction(configuration.isCreateNewChatOnEachAction());
configurationComponent.setCreateNewChatOnEachAction(
configuration.isCreateNewChatOnEachAction());
EditorActionsUtil.refreshActions();
}

View file

@ -12,7 +12,9 @@ import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@State(name = "CodeGPT_ConfigurationSettings_210", storages = @Storage("CodeGPT_ConfigurationSettings_210.xml"))
@State(
name = "CodeGPT_ConfigurationSettings_210",
storages = @Storage("CodeGPT_ConfigurationSettings_210.xml"))
public class ConfigurationState implements PersistentStateComponent<ConfigurationState> {
private String systemPrompt = COMPLETION_SYSTEM_PROMPT;

View file

@ -54,7 +54,10 @@ public class DownloadModelAction extends AnAction {
class DownloadBackgroundTask extends Task.Backgroundable {
DownloadBackgroundTask(Project project) {
super(project, CodeGPTBundle.get("settingsConfigurable.service.llama.progress.downloadingModel.title"), true);
super(
project,
CodeGPTBundle.get("settingsConfigurable.service.llama.progress.downloadingModel.title"),
true);
}
@Override
@ -68,15 +71,20 @@ public class DownloadModelAction extends AnAction {
onDownload.accept(indicator);
indicator.setIndeterminate(false);
indicator.setText(format(CodeGPTBundle.get("settingsConfigurable.service.llama.progress.downloadingModelIndicator.text"), model.getFileName()));
indicator.setText(format(
CodeGPTBundle.get(
"settingsConfigurable.service.llama.progress.downloadingModelIndicator.text"),
model.getFileName()));
long fileSize = url.openConnection().getContentLengthLong();
long[] bytesRead = {0};
long startTime = System.currentTimeMillis();
progressUpdateScheduler = executorService.scheduleAtFixedRate(() ->
onUpdateProgress.accept(
DownloadingUtils.getFormattedDownloadProgress(startTime, fileSize, bytesRead[0])),
onUpdateProgress.accept(DownloadingUtils.getFormattedDownloadProgress(
startTime,
fileSize,
bytesRead[0])),
0, 1, TimeUnit.SECONDS);
FileUtils.copyFileWithProgress(model.getFileName(), url, bytesRead, fileSize, indicator);
} catch (IOException ex) {

View file

@ -125,14 +125,16 @@ public class LlamaModelPreferencesForm {
modelComboBoxModel,
modelSizeComboBoxModel,
huggingFaceComboBoxModel);
modelSizeComboBox.setEnabled(initialModelSizes.size() > 1 && !llamaServerAgent.isServerRunning());
modelSizeComboBox.setEnabled(
initialModelSizes.size() > 1 && !llamaServerAgent.isServerRunning());
promptTemplateComboBox = new ComboBox<>(new EnumComboBoxModel<>(PromptTemplate.class));
promptTemplateComboBox.setSelectedItem(llamaSettings.getPromptTemplate());
promptTemplateComboBox.setEnabled(
llamaSettings.isUseCustomModel() && !llamaServerAgent.isServerRunning());
promptTemplateComboBox.setPreferredSize(modelComboBox.getPreferredSize());
useCustomModelCheckBox = new JBCheckBox(CodeGPTBundle.get(
"settingsConfigurable.service.llama.useCustomModel.label"), llamaSettings.isUseCustomModel());
"settingsConfigurable.service.llama.useCustomModel.label"),
llamaSettings.isUseCustomModel());
useCustomModelCheckBox.setEnabled(!llamaServerAgent.isServerRunning());
useCustomModelCheckBox.addChangeListener(e -> {
var selected = ((JBCheckBox) e.getSource()).isSelected();
@ -167,16 +169,25 @@ public class LlamaModelPreferencesForm {
huggingFaceModelComboBoxWrapper.add(modelDetailsLabel);
return FormBuilder.createFormBuilder()
.addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.shared.model.label"), modelComboBoxWrapper)
.addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.service.llama.modelSize.label"), modelSizeComboBox)
.addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.service.llama.quantization.label"), huggingFaceModelComboBoxWrapper)
.addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.shared.model.label"),
modelComboBoxWrapper)
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.modelSize.label"),
modelSizeComboBox)
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.quantization.label"),
huggingFaceModelComboBoxWrapper)
.addComponentToRightColumn(quantizationHelpText)
.addComponentToRightColumn(downloadModelActionLinkWrapper)
.addComponentToRightColumn(progressLabel)
.addVerticalGap(8)
.addComponent(useCustomModelCheckBox)
.addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.service.llama.promptTemplate.label"), promptTemplateComboBox)
.addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.service.llama.customModelPath.label"), customModelPathBrowserButton)
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.promptTemplate.label"),
promptTemplateComboBox)
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.customModelPath.label"),
customModelPathBrowserButton)
.addComponentToRightColumn(customModelHelpText)
.addVerticalGap(4)
.getPanel();
@ -297,8 +308,8 @@ public class LlamaModelPreferencesForm {
var models = selectedModel.getHuggingFaceModels().stream()
.filter(model -> {
var selectedModelSize = (ModelSize) modelSizeComboBoxModel.getSelectedItem();
return selectedModelSize != null &&
selectedModelSize.getSize() == model.getParameterSize();
return selectedModelSize != null
&& selectedModelSize.getSize() == model.getParameterSize();
})
.collect(toList());
if (!models.isEmpty()) {
@ -349,18 +360,23 @@ public class LlamaModelPreferencesForm {
JPanel actionLinkWrapper,
DefaultComboBoxModel<HuggingFaceModel> huggingFaceComboBoxModel,
ProgressIndicator progressIndicator) {
return new AnActionLink(CodeGPTBundle.get("settingsConfigurable.service.llama.cancelDownloadLink.label"), new AnAction() {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
SwingUtilities.invokeLater(() -> {
configureFieldsForDownloading(false);
updateActionLink(
actionLinkWrapper,
createDownloadModelLink(progressLabel, actionLinkWrapper, huggingFaceComboBoxModel));
progressIndicator.cancel();
return new AnActionLink(
CodeGPTBundle.get("settingsConfigurable.service.llama.cancelDownloadLink.label"),
new AnAction() {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
SwingUtilities.invokeLater(() -> {
configureFieldsForDownloading(false);
updateActionLink(
actionLinkWrapper,
createDownloadModelLink(
progressLabel,
actionLinkWrapper,
huggingFaceComboBoxModel));
progressIndicator.cancel();
});
}
});
}
});
}
private void updateActionLink(JPanel actionLinkWrapper, AnActionLink actionLink) {
@ -383,33 +399,39 @@ public class LlamaModelPreferencesForm {
JBLabel progressLabel,
JPanel actionLinkWrapper,
DefaultComboBoxModel<HuggingFaceModel> huggingFaceComboBoxModel) {
return new AnActionLink(CodeGPTBundle.get("settingsConfigurable.service.llama.downloadModelLink.label"), new DownloadModelAction(
progressIndicator -> {
SwingUtilities.invokeLater(() -> {
configureFieldsForDownloading(true);
updateActionLink(
actionLinkWrapper,
createCancelDownloadLink(
progressLabel,
return new AnActionLink(
CodeGPTBundle.get("settingsConfigurable.service.llama.downloadModelLink.label"),
new DownloadModelAction(
progressIndicator -> {
SwingUtilities.invokeLater(() -> {
configureFieldsForDownloading(true);
updateActionLink(
actionLinkWrapper,
huggingFaceComboBoxModel,
progressIndicator));
});
},
() -> SwingUtilities.invokeLater(() -> {
configureFieldsForDownloading(false);
updateActionLink(
actionLinkWrapper,
createDownloadModelLink(progressLabel, actionLinkWrapper, huggingFaceComboBoxModel));
actionLinkWrapper.setVisible(false);
LlamaSettingsState.getInstance()
.setHuggingFaceModel((HuggingFaceModel) huggingFaceComboBoxModel.getSelectedItem());
}),
(error) -> {
throw new RuntimeException(error);
},
(text) -> SwingUtilities.invokeLater(() -> progressLabel.setText(text)),
huggingFaceComboBoxModel), "unknown");
createCancelDownloadLink(
progressLabel,
actionLinkWrapper,
huggingFaceComboBoxModel,
progressIndicator));
});
},
() -> SwingUtilities.invokeLater(() -> {
configureFieldsForDownloading(false);
updateActionLink(
actionLinkWrapper,
createDownloadModelLink(
progressLabel,
actionLinkWrapper,
huggingFaceComboBoxModel));
actionLinkWrapper.setVisible(false);
LlamaSettingsState.getInstance()
.setHuggingFaceModel(
(HuggingFaceModel) huggingFaceComboBoxModel.getSelectedItem());
}),
(error) -> {
throw new RuntimeException(error);
},
(text) -> SwingUtilities.invokeLater(() -> progressLabel.setText(text)),
huggingFaceComboBoxModel), "unknown");
}
private void updateModelHelpTooltip(HuggingFaceModel model) {
@ -418,7 +440,9 @@ public class LlamaModelPreferencesForm {
new HelpTooltip()
.setTitle(llamaModel.getLabel())
.setDescription("<html><p>" + llamaModel.getDescription() + "</p></html>")
.setBrowserLink(CodeGPTBundle.get("settingsConfigurable.service.llama.linkToModel.label"), model.getHuggingFaceURL())
.setBrowserLink(
CodeGPTBundle.get("settingsConfigurable.service.llama.linkToModel.label"),
model.getHuggingFaceURL())
.installOn(helpIcon);
}

View file

@ -31,12 +31,12 @@ public class LlamaServiceSelectionForm extends JPanel {
private final IntegerField maxTokensField;
public LlamaServiceSelectionForm() {
var llamaServerAgent = ApplicationManager.getApplication().getService(LlamaServerAgent.class);
var llamaServerAgent =
ApplicationManager.getApplication().getService(LlamaServerAgent.class);
var serverRunning = llamaServerAgent.isServerRunning();
portField = new PortField(LlamaSettingsState.getInstance().getServerPort());
portField.setEnabled(!serverRunning);
var serverProgressPanel = new ServerProgressPanel();
llamaModelPreferencesForm = new LlamaModelPreferencesForm();
maxTokensField = new IntegerField("max_tokens", 256, 4096);
@ -44,10 +44,68 @@ public class LlamaServiceSelectionForm extends JPanel {
maxTokensField.setValue(2048);
maxTokensField.setEnabled(!serverRunning);
var serverProgressPanel = new ServerProgressPanel();
var serverButton = getServerButton(serverRunning, llamaServerAgent, serverProgressPanel);
var contextSizeHelpText = ComponentPanelBuilder.createCommentComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.contextSize.comment"),
true);
contextSizeHelpText.setBorder(JBUI.Borders.empty(0, 4));
setLayout(new BorderLayout());
add(FormBuilder.createFormBuilder()
.addComponent(new TitledSeparator(
CodeGPTBundle.get("settingsConfigurable.service.llama.modelPreferences.title")))
.addComponent(withEmptyLeftBorder(llamaModelPreferencesForm.getForm()))
.addComponent(new TitledSeparator(
CodeGPTBundle.get("settingsConfigurable.service.llama.serverPreferences.title")))
.addComponent(withEmptyLeftBorder(FormBuilder.createFormBuilder()
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.contextSize.label"),
maxTokensField)
.addComponentToRightColumn(contextSizeHelpText)
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.port.label"),
JBUI.Panels.simplePanel()
.addToLeft(portField)
.addToRight(serverButton))
.getPanel()))
.addVerticalGap(4)
.addComponent(withEmptyLeftBorder(serverProgressPanel))
.addComponentFillVertically(new JPanel(), 0)
.getPanel());
}
public void setServerPort(int serverPort) {
portField.setNumber(serverPort);
}
public int getServerPort() {
return portField.getNumber();
}
public LlamaModelPreferencesForm getLlamaModelPreferencesForm() {
return llamaModelPreferencesForm;
}
private JComponent withEmptyLeftBorder(JComponent component) {
component.setBorder(JBUI.Borders.emptyLeft(16));
return component;
}
public int getContextSize() {
return maxTokensField.getValue();
}
public void setContextSize(int contextSize) {
maxTokensField.setValue(contextSize);
}
private JButton getServerButton(boolean serverRunning, LlamaServerAgent llamaServerAgent,
ServerProgressPanel serverProgressPanel) {
var serverButton = new JButton();
serverButton.setText(serverRunning ?
CodeGPTBundle.get("settingsConfigurable.service.llama.stopServer.label") :
CodeGPTBundle.get("settingsConfigurable.service.llama.startServer.label"));
serverButton.setText(serverRunning
? CodeGPTBundle.get("settingsConfigurable.service.llama.stopServer.label")
: CodeGPTBundle.get("settingsConfigurable.service.llama.startServer.label"));
serverButton.setIcon(serverRunning ? Actions.Suspend : Actions.Execute);
serverButton.addActionListener(event -> {
if (llamaModelPreferencesForm.isUseCustomLlamaModel()) {
@ -87,11 +145,11 @@ public class LlamaServiceSelectionForm extends JPanel {
CodeGPTBundle.get("settingsConfigurable.service.llama.progress.startingServer"));
// TODO: Move to LlamaModelPreferencesForm
var modelPath = llamaModelPreferencesForm.isUseCustomLlamaModel() ?
llamaModelPreferencesForm.getCustomLlamaModelPath() :
CodeGPTPlugin.getLlamaModelsPath() +
File.separator +
llamaModelPreferencesForm.getSelectedModel().getFileName();
var modelPath = llamaModelPreferencesForm.isUseCustomLlamaModel()
? llamaModelPreferencesForm.getCustomLlamaModelPath()
: CodeGPTPlugin.getLlamaModelsPath()
+ File.separator
+ llamaModelPreferencesForm.getSelectedModel().getFileName();
llamaServerAgent.startAgent(
modelPath,
maxTokensField.getValue(),
@ -104,34 +162,7 @@ public class LlamaServiceSelectionForm extends JPanel {
});
}
});
var contextSizeHelpText = ComponentPanelBuilder.createCommentComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.contextSize.comment"),
true);
contextSizeHelpText.setBorder(JBUI.Borders.empty(0, 4));
setLayout(new BorderLayout());
add(FormBuilder.createFormBuilder()
.addComponent(new TitledSeparator(
CodeGPTBundle.get("settingsConfigurable.service.llama.modelPreferences.title")))
.addComponent(withEmptyLeftBorder(llamaModelPreferencesForm.getForm()))
.addComponent(new TitledSeparator(
CodeGPTBundle.get("settingsConfigurable.service.llama.serverPreferences.title")))
.addComponent(withEmptyLeftBorder(FormBuilder.createFormBuilder()
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.contextSize.label"),
maxTokensField)
.addComponentToRightColumn(contextSizeHelpText)
.addLabeledComponent(
CodeGPTBundle.get("settingsConfigurable.service.llama.port.label"),
JBUI.Panels.simplePanel()
.addToLeft(portField)
.addToRight(serverButton))
.getPanel()))
.addVerticalGap(4)
.addComponent(withEmptyLeftBorder(serverProgressPanel))
.addComponentFillVertically(new JPanel(), 0)
.getPanel());
return serverButton;
}
private boolean isModelExists(HuggingFaceModel model) {
@ -144,29 +175,4 @@ public class LlamaServiceSelectionForm extends JPanel {
portField.setEnabled(enabled);
maxTokensField.setEnabled(enabled);
}
public void setServerPort(int serverPort) {
portField.setNumber(serverPort);
}
public int getServerPort() {
return portField.getNumber();
}
public LlamaModelPreferencesForm getLlamaModelPreferencesForm() {
return llamaModelPreferencesForm;
}
private JComponent withEmptyLeftBorder(JComponent component) {
component.setBorder(JBUI.Borders.emptyLeft(16));
return component;
}
public int getContextSize() {
return maxTokensField.getValue();
}
public void setContextSize(int contextSize) {
maxTokensField.setValue(contextSize);
}
}

View file

@ -61,12 +61,17 @@ public class ServiceSelectionForm {
public ServiceSelectionForm(Disposable parentDisposable) {
this.parentDisposable = parentDisposable;
var openAISettings = OpenAISettingsState.getInstance();
var azureSettings = AzureSettingsState.getInstance();
openAIApiKeyField = new JBPasswordField();
openAIApiKeyField.setColumns(30);
openAIApiKeyField.setText(OpenAICredentialsManager.getInstance().getApiKey());
var azureSettings = AzureSettingsState.getInstance();
useAzureApiKeyAuthenticationRadioButton = new JBRadioButton(
CodeGPTBundle.get("settingsConfigurable.service.azure.useApiKeyAuth.label"),
azureSettings.isUseAzureApiKeyAuthentication());
useAzureActiveDirectoryAuthenticationRadioButton = new JBRadioButton(
CodeGPTBundle.get("settingsConfigurable.service.azure.useActiveDirectoryAuth.label"),
azureSettings.isUseAzureActiveDirectoryAuthentication());
azureApiKeyField = new JBPasswordField();
azureApiKeyField.setColumns(30);
azureApiKeyField.setText(AzureCredentialsManager.getInstance().getAzureOpenAIApiKey());
@ -82,13 +87,8 @@ public class ServiceSelectionForm {
.withLabel(CodeGPTBundle.get("settingsConfigurable.service.azure.bearerToken.label"))
.resizeX(false)
.createPanel();
useAzureApiKeyAuthenticationRadioButton = new JBRadioButton(
CodeGPTBundle.get("settingsConfigurable.service.azure.useApiKeyAuth.label"),
azureSettings.isUseAzureApiKeyAuthentication());
useAzureActiveDirectoryAuthenticationRadioButton = new JBRadioButton(
CodeGPTBundle.get("settingsConfigurable.service.azure.useActiveDirectoryAuth.label"),
azureSettings.isUseAzureActiveDirectoryAuthentication());
var openAISettings = OpenAISettingsState.getInstance();
openAIBaseHostField = new JBTextField(openAISettings.getBaseHost(), 30);
openAIPathField = new JBTextField(openAISettings.getPath(), 30);
openAIOrganizationField = new JBTextField(openAISettings.getOrganization(), 30);

View file

@ -158,8 +158,13 @@ public class YouServiceSelectionForm extends JPanel {
"<html>"
+ "<body>"
+ "<h1 style=\"text-align: center; padding: 0; margin: 0;\">Free GPT-4</h1>"
+ "<p style=\"text-align: center; margin-top: 8px; margin-bottom: 8px;\">Your coupon code</p>"
+ "<h1 style=\"text-align: center; border: 2px dotted #646464; padding: 4px 32px; margin: 0 0 12px 0; background-color: #45494a; cursor: pointer;\">CODEGPT</h1>"
+ "<p style=\"text-align: center; margin-top: 8px; margin-bottom: 8px;\">"
+ "Your coupon code"
+ "</p>"
+ "<h1 style=\"text-align: center; border: 2px dotted #646464; padding: 4px 32px; "
+ "margin: 0 0 12px 0; background-color: #45494a; cursor: pointer;\">"
+ "CODEGPT"
+ "</h1>"
+ "</body>"
+ "</html>")
.withBorder(JBUI.Borders.emptyLeft(45)) // TODO

View file

@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
@State(name = "CodeGPT_AzureSettings_210", storages = @Storage("CodeGPT_AzureSettings_210.xml"))
public class AzureSettingsState implements PersistentStateComponent<AzureSettingsState> {
private final String BASE_PATH = "/openai/deployments/%s/chat/completions?api-version=%s";
private static final String BASE_PATH = "/openai/deployments/%s/chat/completions?api-version=%s";
private String resourceName = "";
private String deploymentId = "";
@ -38,23 +38,24 @@ public class AzureSettingsState implements PersistentStateComponent<AzureSetting
public boolean isModified(ServiceSelectionForm serviceSelectionForm) {
var credentialsManager = AzureCredentialsManager.getInstance();
return serviceSelectionForm.isAzureActiveDirectoryAuthenticationSelected() !=
isUseAzureActiveDirectoryAuthentication() ||
serviceSelectionForm.isAzureApiKeyAuthenticationSelected() !=
isUseAzureApiKeyAuthentication() ||
!serviceSelectionForm.getAzureActiveDirectoryToken()
.equals(credentialsManager.getAzureActiveDirectoryToken()) ||
!serviceSelectionForm.getAzureOpenAIApiKey()
.equals(credentialsManager.getAzureOpenAIApiKey()) ||
!serviceSelectionForm.getAzureResourceName().equals(resourceName) ||
!serviceSelectionForm.getAzureDeploymentId().equals(deploymentId) ||
!serviceSelectionForm.getAzureApiVersion().equals(apiVersion) ||
!serviceSelectionForm.getAzureBaseHost().equals(baseHost) ||
!serviceSelectionForm.getAzurePath().equals(path);
return serviceSelectionForm.isAzureActiveDirectoryAuthenticationSelected()
!= isUseAzureActiveDirectoryAuthentication()
|| serviceSelectionForm.isAzureApiKeyAuthenticationSelected()
!= isUseAzureApiKeyAuthentication()
|| !serviceSelectionForm.getAzureActiveDirectoryToken()
.equals(credentialsManager.getAzureActiveDirectoryToken())
|| !serviceSelectionForm.getAzureOpenAIApiKey()
.equals(credentialsManager.getAzureOpenAIApiKey())
|| !serviceSelectionForm.getAzureResourceName().equals(resourceName)
|| !serviceSelectionForm.getAzureDeploymentId().equals(deploymentId)
|| !serviceSelectionForm.getAzureApiVersion().equals(apiVersion)
|| !serviceSelectionForm.getAzureBaseHost().equals(baseHost)
|| !serviceSelectionForm.getAzurePath().equals(path);
}
public void apply(ServiceSelectionForm serviceSelectionForm) {
useAzureActiveDirectoryAuthentication = serviceSelectionForm.isAzureActiveDirectoryAuthenticationSelected();
useAzureActiveDirectoryAuthentication =
serviceSelectionForm.isAzureActiveDirectoryAuthenticationSelected();
useAzureApiKeyAuthentication = serviceSelectionForm.isAzureApiKeyAuthenticationSelected();
resourceName = serviceSelectionForm.getAzureResourceName();

View file

@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
@State(name = "CodeGPT_OpenAISettings_210", storages = @Storage("CodeGPT_OpenAISettings_210.xml"))
public class OpenAISettingsState implements PersistentStateComponent<OpenAISettingsState> {
private final String BASE_PATH = "/v1/chat/completions";
private static final String BASE_PATH = "/v1/chat/completions";
private String organization = "";
private String baseHost = "https://api.openai.com";
@ -36,11 +36,12 @@ public class OpenAISettingsState implements PersistentStateComponent<OpenAISetti
}
public boolean isModified(ServiceSelectionForm serviceSelectionForm) {
return !serviceSelectionForm.getOpenAIApiKey().equals(OpenAICredentialsManager.getInstance().getApiKey()) ||
!serviceSelectionForm.getOpenAIOrganization().equals(organization) ||
!serviceSelectionForm.getOpenAIBaseHost().equals(baseHost) ||
!serviceSelectionForm.getOpenAIPath().equals(path) ||
!serviceSelectionForm.getOpenAIModel().equals(model);
return !serviceSelectionForm.getOpenAIApiKey()
.equals(OpenAICredentialsManager.getInstance().getApiKey())
|| !serviceSelectionForm.getOpenAIOrganization().equals(organization)
|| !serviceSelectionForm.getOpenAIBaseHost().equals(baseHost)
|| !serviceSelectionForm.getOpenAIPath().equals(path)
|| !serviceSelectionForm.getOpenAIModel().equals(model);
}
public void apply(ServiceSelectionForm serviceSelectionForm) {

View file

@ -16,7 +16,8 @@ public class ProjectToolWindowFactory implements ToolWindowFactory, DumbAware {
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
var chatToolWindowPanel = new StandardChatToolWindowPanel(project, toolWindow.getDisposable());
// var contextualChatToolWindowPanel = new ContextualChatToolWindowPanel(project, toolWindow.getDisposable());
// var contextualChatToolWindowPanel =
// new ContextualChatToolWindowPanel(project, toolWindow.getDisposable());
var conversationsToolWindow = new ConversationsToolWindow(project);
addContent(toolWindow, chatToolWindowPanel, "Chat");

View file

@ -159,7 +159,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
}
private void call(Message message, ResponsePanel responsePanel, boolean retry) {
ChatMessageResponseBody responseContainer = (ChatMessageResponseBody) responsePanel.getContent();
var responseContainer = (ChatMessageResponseBody) responsePanel.getContent();
if (!CompletionRequestService.getInstance().isRequestAllowed()) {
responseContainer.displayMissingCredential();
@ -215,13 +215,14 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
}
private JPanel createRootPanel(SettingsState settings) {
var rootPanel = new JPanel(new GridBagLayout());
var gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1;
gbc.weightx = 1;
gbc.gridx = 0;
gbc.gridy = 0;
var rootPanel = new JPanel(new GridBagLayout());
rootPanel.add(createScrollPaneWithSmartScroller(toolWindowScrollablePanel), gbc);
gbc.weighty = 0;

View file

@ -34,8 +34,8 @@ public class ChatToolWindowScrollablePanel extends ScrollablePanel {
public void displayLandingView(JComponent landingView) {
clearAll();
add(landingView);
if (settings.getSelectedService() == ServiceType.YOU &&
(!youUserManager.isAuthenticated() || !youUserManager.isSubscribed())) {
if (settings.getSelectedService() == ServiceType.YOU
&& (!youUserManager.isAuthenticated() || !youUserManager.isSubscribed())) {
add(new ResponsePanel().addContent(createYouCouponTextPane()));
}
}

View file

@ -40,7 +40,11 @@ public class StreamParser {
new StreamParseResponse(StreamResponseType.TEXT, messageBuilder.toString()));
}
return List.of(new StreamParseResponse(isProcessingCode ? StreamResponseType.CODE : StreamResponseType.TEXT, messageBuilder.toString()));
return List.of(new StreamParseResponse(
isProcessingCode
? StreamResponseType.CODE
: StreamResponseType.TEXT,
messageBuilder.toString()));
}
public void clear() {

View file

@ -185,10 +185,10 @@ public class ChatMessageResponseBody extends JPanel {
result.getUrl(), result.getName()))
.collect(Collectors.joining());
return format(
"<html>" +
"<p><strong>Search results:</strong></p>" +
"<ol>%s</ol>" +
"</html>", titles);
"<html>"
+ "<p><strong>Search results:</strong></p>"
+ "<ol>%s</ol>"
+ "</html>", titles);
}
public void clear() {

View file

@ -10,45 +10,21 @@ import javax.swing.SwingUtilities;
import javax.swing.text.DefaultCaret;
import javax.swing.text.JTextComponent;
/**
* The SmartScroller will attempt to keep the viewport positioned based on
* the users interaction with the scrollbar. The normal behaviour is to keep
* the viewport positioned to see new data as it is dynamically added.
* <p>
* Assuming vertical scrolling and data is added to the bottom:
* <p>
* - when the viewport is at the bottom and new data is added,
* then automatically scroll the viewport to the bottom
* - when the viewport is not at the bottom and new data is added,
* then do nothing with the viewport
* <p>
* Assuming vertical scrolling and data is added to the top:
* <p>
* - when the viewport is at the top and new data is added,
* then do nothing with the viewport
* - when the viewport is not at the top and new data is added, then adjust
* the viewport to the relative position it was at before the data was added
* <p>
* Similiar logic would apply for horizontal scrolling.
*/
public class SmartScroller implements AdjustmentListener {
public final static int HORIZONTAL = 0;
public final static int VERTICAL = 1;
public final static int START = 0;
public final static int END = 1;
private static final int HORIZONTAL = 0;
private static final int VERTICAL = 1;
private static final int START = 0;
private static final int END = 1;
private int viewportPosition;
private final int viewportPosition;
private JScrollBar scrollBar;
private boolean adjustScrollBar = true;
private int previousValue = -1;
private int previousMaximum = -1;
/**
* Convenience constructor.
* Scroll direction is VERTICAL and viewport position is at the END.
* Convenience constructor. Scroll direction is VERTICAL and viewport position is at the END.
*
* @param scrollPane the scroll pane to monitor
*/
@ -56,26 +32,15 @@ public class SmartScroller implements AdjustmentListener {
this(scrollPane, VERTICAL, END);
}
/**
* Convenience constructor.
* Scroll direction is VERTICAL.
*
* @param scrollPane the scroll pane to monitor
* @param viewportPosition valid values are START and END
*/
public SmartScroller(JScrollPane scrollPane, int viewportPosition) {
this(scrollPane, VERTICAL, viewportPosition);
}
/**
* Specify how the SmartScroller will function.
*
* @param scrollPane the scroll pane to monitor
* @param scrollDirection indicates which JScrollBar to monitor.
* Valid values are HORIZONTAL and VERTICAL.
* @param viewportPosition indicates where the viewport will normally be
* positioned as data is added.
* Valid values are START and END
* @param scrollDirection indicates which JScrollBar to monitor. Valid values are HORIZONTAL and
* VERTICAL.
* @param viewportPosition indicates where the viewport will normally be positioned as data is
* added. Valid values are START and END
*/
public SmartScroller(JScrollPane scrollPane, int scrollDirection, int viewportPosition) {
if (scrollDirection != HORIZONTAL
@ -90,6 +55,7 @@ public class SmartScroller implements AdjustmentListener {
this.viewportPosition = viewportPosition;
JScrollBar scrollBar;
if (scrollDirection == HORIZONTAL) {
scrollBar = scrollPane.getHorizontalScrollBar();
} else {

View file

@ -35,6 +35,7 @@ public class UserPromptTextAreaHeader extends JPanel {
subscribeToYouTopics(project, gpt4CheckBox);
add(gpt4CheckBox, BorderLayout.LINE_START);
break;
default:
}
add(JBUI.Panels
.simplePanel(new ModelIconLabel(

View file

@ -31,9 +31,9 @@ public class YouProCheckbox extends JBCheckBox {
private String getTooltipText(YouUserManager youUserManager, boolean selected) {
if (youUserManager.isSubscribed()) {
return selected ?
CodeGPTBundle.get("toolwindow.chat.youProCheckBox.disable") :
CodeGPTBundle.get("toolwindow.chat.youProCheckBox.enable");
return selected
? CodeGPTBundle.get("toolwindow.chat.youProCheckBox.disable")
: CodeGPTBundle.get("toolwindow.chat.youProCheckBox.enable");
}
return CodeGPTBundle.get("toolwindow.chat.youProCheckBox.notAllowed");
}

View file

@ -19,19 +19,13 @@ import ee.carlrobert.vector.VectorStore;
import javax.swing.JTextPane;
import javax.swing.event.HyperlinkEvent;
@FunctionalInterface
interface ActionEvent {
void handleAction(String prompt);
}
class ContextualChatToolWindowLandingPanel extends ResponsePanel {
private static final Logger LOG = Logger.getInstance(ContextualChatToolWindowLandingPanel.class);
private final Project project;
private final ActionEvent actionEvent;
private final EditorActionEvent actionEvent;
ContextualChatToolWindowLandingPanel(Project project, ActionEvent actionEvent) {
ContextualChatToolWindowLandingPanel(Project project, EditorActionEvent actionEvent) {
this.project = project;
this.actionEvent = actionEvent;
addContent(createContent());
@ -45,26 +39,38 @@ class ContextualChatToolWindowLandingPanel extends ResponsePanel {
private JTextPane createContent() {
var description = createTextPane();
if (VectorStore.getInstance(CodeGPTPlugin.getPluginBasePath()).isIndexExists()) {
description.setText("<html>" +
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">Feel free to ask me anything about your codebase, and I'll be your helpful guide, dedicated to providing you with the best answers possible!</p>"
+
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">Here are a few examples of how I might be helpful:</p>"
+
"<ul>" +
"<li><a href=\"LIST_DEPENDENCIES\">List all the dependencies that the project uses</a></li"
+
"<li><a href=\"SCHEDULED_TASKS\">Are there any scheduled tasks or background jobs running in our codebase, and if so, what are they responsible for?</a></li>"
+
"<li><a href=\"AUTHENTICATION_MECHANISM\">Can you provide an overview of the authentication and authorization mechanism implemented in our application?</a></li>"
+
"</html>");
description.setText("<html>"
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "Feel free to ask me anything about your codebase, and I'll be your helpful guide, "
+ "dedicated to providing you with the best answers possible!"
+ "</p>"
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "Here are a few examples of how I might be helpful:"
+ "</p>"
+ "<ul>"
+ "<li>"
+ "<a href=\"LIST_DEPENDENCIES\">List all the dependencies that the project uses</a>"
+ "</li>"
+ "<li>"
+ "<a href=\"SCHEDULED_TASKS\">Are there any scheduled tasks or background jobs "
+ "running in our codebase, and if so, what are they responsible for?</a>"
+ "</li>"
+ "<li>"
+ "<a href=\"AUTHENTICATION_MECHANISM\">Can you provide an overview of the "
+ "authentication and authorization mechanism implemented in our application?</a>"
+ "</li>"
+ "</ul>"
+ "</html>");
} else {
description.setText("<html>" +
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">It looks like you haven't indexed your codebase yet.</p>"
+
"<p style=\"margin-top: 4px; margin-bottom: 4px;\"><a href=\"START_INDEXING\">Start indexing</a> your codebase to get access to contextual chat experience.</p>"
+
"</html>");
description.setText("<html>"
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "It looks like you haven't indexed your codebase yet."
+ "</p>"
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "<a href=\"START_INDEXING\">Start indexing</a> your codebase to get "
+ "access to contextual chat experience."
+ "</p>"
+ "</html>");
}
return description;
@ -87,12 +93,12 @@ class ContextualChatToolWindowLandingPanel extends ResponsePanel {
actionEvent.handleAction("List all the dependencies that the project uses");
break;
case "SCHEDULED_TASKS":
actionEvent.handleAction(
"Are there any scheduled tasks or background jobs running in our codebase, and if so, what are they responsible for?");
actionEvent.handleAction("Are there any scheduled tasks or background "
+ "jobs running in our codebase, and if so, what are they responsible for?");
break;
case "AUTHENTICATION_MECHANISM":
actionEvent.handleAction(
"Can you provide an overview of the authentication and authorization mechanism implemented in our application?");
actionEvent.handleAction("Can you provide an overview of the authentication "
+ "and authorization mechanism implemented in our application?");
break;
case "START_INDEXING":
var folderStructureTreePanel = new FolderStructureTreePanel(project);

View file

@ -0,0 +1,7 @@
package ee.carlrobert.codegpt.toolwindow.chat.contextual;
@FunctionalInterface
public interface EditorActionEvent {
void handleAction(String prompt);
}

View file

@ -112,11 +112,11 @@ public class ResponseEditor extends JPanel implements Disposable {
}
private String getLinkText(boolean expanded) {
return expanded ?
format(
return expanded
? format(
CodeGPTBundle.get("toolwindow.chat.editor.action.expand"),
((EditorEx) editor).getDocument().getLineCount() - 1) :
CodeGPTBundle.get("toolwindow.chat.editor.action.collapse");
((EditorEx) editor).getDocument().getLineCount() - 1)
: CodeGPTBundle.get("toolwindow.chat.editor.action.collapse");
}
private JPanel createFooterComponent(Color backgroundColor) {

View file

@ -18,8 +18,8 @@ import ee.carlrobert.codegpt.CodeGPTBundle;
import ee.carlrobert.codegpt.actions.ActionType;
import ee.carlrobert.codegpt.actions.TrackableAction;
import ee.carlrobert.codegpt.util.EditorUtils;
import ee.carlrobert.codegpt.util.file.FileUtils;
import ee.carlrobert.codegpt.util.OverlayUtils;
import ee.carlrobert.codegpt.util.file.FileUtils;
import org.jetbrains.annotations.NotNull;
public class DiffAction extends TrackableAction {

View file

@ -34,9 +34,9 @@ public class EditAction extends TrackableAction {
settings.setCaretRowShown(!viewer);
event.getPresentation().setIcon(viewer ? Actions.EditSource : Actions.Show);
event.getPresentation().setText(viewer ?
CodeGPTBundle.get("toolwindow.chat.editor.action.edit.title") :
CodeGPTBundle.get("toolwindow.chat.editor.action.disableEditing.title"));
event.getPresentation().setText(viewer
? CodeGPTBundle.get("toolwindow.chat.editor.action.edit.title")
: CodeGPTBundle.get("toolwindow.chat.editor.action.disableEditing.title"));
var locationOnScreen = ((MouseEvent) event.getInputEvent()).getLocationOnScreen();
locationOnScreen.y = locationOnScreen.y - 16;

View file

@ -1,11 +1,26 @@
package ee.carlrobert.codegpt.toolwindow.chat.standard;
enum EditorAction {
FIND_BUGS("Find Bugs", "Find bugs in the following code", "Find bugs and output code with bugs fixed in the following code: {{selectedCode}}"),
WRITE_TESTS("Write Tests", "Write Tests for the following code", "Write Tests for the following code: {{selectedCode}}"),
EXPLAIN("Explain", "Explain the following code", "Explain the following code: {{selectedCode}}"),
REFACTOR("Refactor", "Refactor the following code", "Refactor the following code: {{selectedCode}}"),
OPTIMIZE("Optimize", "Optimize the following code", "Optimize the following code: {{selectedCode}}");
FIND_BUGS(
"Find Bugs",
"Find bugs in the following code",
"Find bugs and output code with bugs fixed in the following code: {{selectedCode}}"),
WRITE_TESTS(
"Write Tests",
"Write Tests for the following code",
"Write Tests for the following code: {{selectedCode}}"),
EXPLAIN(
"Explain",
"Explain the following code",
"Explain the following code: {{selectedCode}}"),
REFACTOR(
"Refactor",
"Refactor the following code",
"Refactor the following code: {{selectedCode}}"),
OPTIMIZE(
"Optimize",
"Optimize the following code",
"Optimize the following code: {{selectedCode}}");
private final String label;
private final String userMessage;

View file

@ -25,18 +25,36 @@ class StandardChatToolWindowLandingPanel extends ResponsePanel {
private JTextPane createContent() {
var textPane = SwingUtils.createTextPane(
"<html>" +
format(
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">Welcome <strong>%s</strong>, I'm your intelligent code companion, here to be your partner-in-crime for getting things done in a flash. Together, we'll tackle tasks swiftly and efficiently, making your coding experience a joy.</p>",
SettingsState.getInstance().getDisplayName()) +
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">Feel free to ask me anything you'd like, but my true superpower lies in assisting you with your code! Here are a few examples of how I can assist you:</p>" +
"<ul style=\"margin-top: 4px; margin-bottom: 4px;\">" +
"<li><a href=\"GENERATE_UNIT_TESTS\">Generate unit tests for the selected code</a></li" +
"<li><a href=\"EXPLAIN_CODE\">Explain the selected code</a></li>" +
"<li><a href=\"FIND_BUGS\">Find bugs in the selected code</a></li>" +
"</ul" +
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">Being an AI-powered assistant, I may occasionally have surprises or make mistakes. Therefore, it's wise to double-check any code or suggestions I provide.</p>" +
"</html>",
"<html>"
+ format(
"<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "Welcome <strong>%s</strong>, I'm your intelligent code companion, here to be"
+ " your partner-in-crime for getting things done in a flash. Together, we'll "
+ "tackle tasks swiftly and efficiently, making your coding experience a joy."
+ "</p>",
SettingsState.getInstance().getDisplayName())
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "Feel free to ask me anything you'd like, but my true superpower lies in assisting "
+ "you with your code! Here are a few examples of how I can assist you:"
+ "</p>"
+ "<ul style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "<li>"
+ "<a href=\"GENERATE_UNIT_TESTS\">Generate unit tests for the selected code</a>"
+ "</li>"
+ "<li>"
+ "<a href=\"EXPLAIN_CODE\">Explain the selected code</a>"
+ "</li>"
+ "<li>"
+ "<a href=\"FIND_BUGS\">Find bugs in the selected code</a>"
+ "</li>"
+ "</ul"
+ "<p style=\"margin-top: 4px; margin-bottom: 4px;\">"
+ "Being an AI-powered assistant, I may occasionally have surprises or make mistakes. "
+ "Therefore, it's wise to double-check any code or suggestions I provide."
+ "</p>"
+ "</html>",
this::handleHyperlinkClicked);
textPane.setBackground(getPanelBackgroundColor());
return textPane;

View file

@ -61,8 +61,8 @@ public class StandardChatToolWindowTabPanel extends BaseChatToolWindowTabPanel {
.withResponse(message.getResponse());
var serpResults = message.getSerpResults();
if (YouSettingsState.getInstance().isDisplayWebSearchResults() &&
serpResults != null && !serpResults.isEmpty()) {
if (YouSettingsState.getInstance().isDisplayWebSearchResults()
&& serpResults != null && !serpResults.isEmpty()) {
messageResponseBody.displaySerpResults(serpResults);
}

View file

@ -59,9 +59,9 @@ class ConversationPanel extends JPanel {
}
private void addStyles(boolean isSelected) {
var border = isSelected ?
JBUI.Borders.customLine(JBUI.CurrentTheme.ActionButton.focusedBorder(), 2, 2, 2, 2) :
JBUI.Borders.customLine(JBColor.border(), 1, 0, 1, 0);
var border = isSelected
? JBUI.Borders.customLine(JBUI.CurrentTheme.ActionButton.focusedBorder(), 2, 2, 2, 2)
: JBUI.Borders.customLine(JBColor.border(), 1, 0, 1, 0);
setBackground(getPanelBackgroundColor());
setBorder(JBUI.Borders.compound(border, JBUI.Borders.empty(8)));
setLayout(new GridBagLayout());

View file

@ -10,11 +10,12 @@ import java.util.regex.Pattern;
public class MarkdownUtils {
/**
* Splits a given string into a list of strings where each element is either a code block surrounded by triple backticks
* or a non-code block text.
* Splits a given string into a list of strings where each element is either a code block
* surrounded by triple backticks or a non-code block text.
*
* @param inputMarkdown The input markdown formatted string to be split.
* @return A list of strings where each element is a code block or a non-code block text from the input string.
* @param inputMarkdown The input markdown formatted string to be split.
* @return A list of strings where each element is a code block or a non-code block text from the
* input string.
*/
public static List<String> splitCodeBlocks(String inputMarkdown) {
List<String> result = new ArrayList<>();

View file

@ -34,18 +34,23 @@ import org.jetbrains.annotations.NotNull;
public class OverlayUtils {
public static void showNotification(String content, NotificationType type) {
Notifications.Bus.notify(new Notification("CodeGPT Notification Group", "CodeGPT", content, type));
Notifications.Bus.notify(
new Notification("CodeGPT Notification Group", "CodeGPT", content, type));
}
public static int showFileStructureDialog(Project project, FolderStructureTreePanel folderStructureTreePanel) {
public static int showFileStructureDialog(
Project project,
FolderStructureTreePanel folderStructureTreePanel) {
var dialogBuilder = new DialogBuilder(project);
dialogBuilder.setNorthPanel(JBUI.Panels.simplePanel(new JBLabel(
"<html>" +
"<p>Indexing files enables direct queries related to your codebase.</p>" +
"<br/>" +
"<p>File indexing occurs locally on your computer; no files are sent to any 3rd party services.</p>" +
"<p>For additional information, refer to the <a href=\"https://google.com\">CodeGPT documentation</a>.</p>" +
"</html>")
"<html>"
+ "<p>Indexing files enables direct queries related to your codebase.</p>"
+ "<br/>"
+ "<p>File indexing occurs locally on your computer; "
+ "no files are sent to any 3rd party services.</p>"
+ "<p>For additional information, refer to the "
+ "<a href=\"https://google.com\">CodeGPT documentation</a>.</p>"
+ "</html>")
.setCopyable(true)
.setAllowAutoWrapping(true)
.withFont(JBFont.medium()))