diff --git a/buildSrc/src/main/kotlin/codegpt.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/codegpt.java-conventions.gradle.kts index 9b154dee..b8df294a 100644 --- a/buildSrc/src/main/kotlin/codegpt.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/codegpt.java-conventions.gradle.kts @@ -23,7 +23,7 @@ checkstyle { } dependencies { - implementation("ee.carlrobert:llm-client:0.6.1") + implementation("ee.carlrobert:llm-client:0.6.2") } tasks { @@ -61,4 +61,4 @@ tasks { signPlugin { enabled = false } -} \ No newline at end of file +} diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java index c3e9c71f..dc14abe6 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java @@ -77,7 +77,7 @@ public class CompletionRequestProvider { } public static String getPromptWithContext(List referencedFiles, - String userPrompt) { + String userPrompt) { var includedFilesSettings = IncludedFilesSettings.getCurrentState(); var repeatableContext = referencedFiles.stream() .map(item -> includedFilesSettings.getRepeatableContext() @@ -158,6 +158,8 @@ public class CompletionRequestProvider { public YouCompletionRequest buildYouCompletionRequest(Message message) { var requestBuilder = new YouCompletionRequest.Builder(message.getPrompt()) .setUseGPT4Model(YouSettings.getCurrentState().isUseGPT4Model()) + .setChatMode(YouSettings.getCurrentState().getChatMode()) + .setCustomModel(YouSettings.getCurrentState().getCustomModel()) .setChatHistory(conversation.getMessages().stream() .map(prevMessage -> new YouCompletionRequestMessage( prevMessage.getPrompt(), diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java index 3aba0682..e6f8d6f5 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java @@ -1,5 +1,7 @@ package ee.carlrobert.codegpt.settings.service.you; +import ee.carlrobert.llm.client.you.completion.YouCompletionCustomModel; +import ee.carlrobert.llm.client.you.completion.YouCompletionMode; import java.util.Objects; public class YouSettingsState { @@ -7,6 +9,8 @@ public class YouSettingsState { private String email = ""; private boolean displayWebSearchResults = true; private boolean useGPT4Model; + private YouCompletionMode chatMode = YouCompletionMode.DEFAULT; + private YouCompletionCustomModel customModel; public String getEmail() { return email; @@ -32,6 +36,22 @@ public class YouSettingsState { this.useGPT4Model = useGPT4Model; } + public YouCompletionMode getChatMode() { + return chatMode; + } + + public void setChatMode(YouCompletionMode chatMode) { + this.chatMode = chatMode; + } + + public YouCompletionCustomModel getCustomModel() { + return customModel; + } + + public void setCustomModel(YouCompletionCustomModel customModel) { + this.customModel = customModel; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -43,11 +63,13 @@ public class YouSettingsState { YouSettingsState that = (YouSettingsState) o; return displayWebSearchResults == that.displayWebSearchResults && useGPT4Model == that.useGPT4Model - && Objects.equals(email, that.email); + && Objects.equals(email, that.email) + && chatMode == that.chatMode + && customModel == that.customModel; } @Override public int hashCode() { - return Objects.hash(displayWebSearchResults, useGPT4Model, email); + return Objects.hash(displayWebSearchResults, useGPT4Model, email, chatMode, customModel); } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java index afb39e1a..e025d655 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java @@ -141,6 +141,9 @@ public class ChatMessageResponseBody extends JPanel { if (responseReceived) { add(createTextPane(html, false)); } else { + if (currentlyProcessedTextPane == null) { + prepareProcessingText(false); + } currentlyProcessedTextPane.setText(html); } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java index 1a9e38ab..9fe48b23 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java @@ -2,6 +2,7 @@ package ee.carlrobert.codegpt.toolwindow.chat.ui.textarea; import static ee.carlrobert.codegpt.settings.service.ServiceType.CUSTOM_OPENAI; import static ee.carlrobert.codegpt.settings.service.ServiceType.OPENAI; +import static ee.carlrobert.codegpt.settings.service.ServiceType.YOU; import static java.lang.String.format; import com.intellij.openapi.actionSystem.AnAction; @@ -9,9 +10,13 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.util.messages.MessageBusConnection; import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.completions.llama.LlamaModel; +import ee.carlrobert.codegpt.completions.you.YouUserManager; +import ee.carlrobert.codegpt.completions.you.auth.SignedOutNotifier; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.ConversationsState; import ee.carlrobert.codegpt.settings.GeneralSettings; @@ -21,7 +26,11 @@ import ee.carlrobert.codegpt.settings.service.custom.CustomServiceSettings; import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; import ee.carlrobert.codegpt.settings.service.openai.OpenAISettingsState; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; +import ee.carlrobert.codegpt.settings.service.you.YouSettingsState; import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; +import ee.carlrobert.llm.client.you.completion.YouCompletionCustomModel; +import ee.carlrobert.llm.client.you.completion.YouCompletionMode; import java.util.List; import javax.swing.Icon; import javax.swing.JComponent; @@ -32,12 +41,16 @@ public class ModelComboBoxAction extends ComboBoxAction { private final Runnable onAddNewTab; private final GeneralSettingsState settings; private final OpenAISettingsState openAISettings; + private final YouSettingsState youSettings; public ModelComboBoxAction(Runnable onAddNewTab, ServiceType selectedService) { this.onAddNewTab = onAddNewTab; settings = GeneralSettings.getCurrentState(); openAISettings = OpenAISettings.getCurrentState(); + youSettings = YouSettings.getCurrentState(); updateTemplatePresentation(selectedService); + + subscribeToYouSignedOutTopic(ApplicationManager.getApplication().getMessageBus().connect()); } public JComponent createCustomComponent(@NotNull String place) { @@ -87,8 +100,22 @@ public class ModelComboBoxAction extends ComboBoxAction { getLlamaCppPresentationText(), Icons.Llama, presentation)); - actionGroup.addSeparator(); - actionGroup.add(createModelAction(ServiceType.YOU, "You.com", Icons.YouSmall, presentation)); + + if (YouUserManager.getInstance().isSubscribed()) { + actionGroup.addSeparator("You.com"); + List.of( + YouCompletionMode.DEFAULT, + YouCompletionMode.AGENT, + YouCompletionMode.RESEARCH) + .forEach(mode -> actionGroup.add(createYouModeAction(mode, presentation))); + List.of( + YouCompletionCustomModel.values() + ) + .forEach(model -> actionGroup.add(createYouModelAction(model, presentation))); + } else { + actionGroup.addSeparator(); + actionGroup.add(createYouModeAction(YouCompletionMode.DEFAULT, presentation)); + } return actionGroup; } @@ -97,6 +124,22 @@ public class ModelComboBoxAction extends ComboBoxAction { return true; } + private void subscribeToYouSignedOutTopic( + MessageBusConnection messageBusConnection + ) { + messageBusConnection.subscribe( + SignedOutNotifier.SIGNED_OUT_TOPIC, + (SignedOutNotifier) () -> { + var youSettings = YouSettings.getCurrentState(); + if (!YouUserManager.getInstance().isSubscribed() + && youSettings.getChatMode() != YouCompletionMode.DEFAULT) { + youSettings.setChatMode(YouCompletionMode.DEFAULT); + updateTemplatePresentation(GeneralSettings.getCurrentState().getSelectedService()); + } + } + ); + } + private void updateTemplatePresentation(ServiceType selectedService) { var templatePresentation = getTemplatePresentation(); switch (selectedService) { @@ -121,7 +164,11 @@ public class ModelComboBoxAction extends ComboBoxAction { break; case YOU: templatePresentation.setIcon(Icons.YouSmall); - templatePresentation.setText("You.com"); + templatePresentation.setText( + youSettings.getChatMode() == YouCompletionMode.CUSTOM + ? youSettings.getCustomModel().getDescription() + : youSettings.getChatMode().getDescription() + ); break; case LLAMA_CPP: templatePresentation.setText(getLlamaCppPresentationText()); @@ -207,4 +254,53 @@ public class ModelComboBoxAction extends ComboBoxAction { } }; } + + private AnAction createYouModeAction( + YouCompletionMode mode, + Presentation comboBoxPresentation) { + createModelAction(YOU, mode.getDescription(), Icons.YouSmall, + comboBoxPresentation); + return new DumbAwareAction(mode.getDescription(), "", Icons.YouSmall) { + @Override + public void update(@NotNull AnActionEvent event) { + var presentation = event.getPresentation(); + presentation.setEnabled(!presentation.getText().equals(comboBoxPresentation.getText())); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + youSettings.setChatMode(mode); + handleProviderChange( + YOU, + mode.getDescription(), + Icons.YouSmall, + comboBoxPresentation); + } + }; + } + + private AnAction createYouModelAction( + YouCompletionCustomModel model, + Presentation comboBoxPresentation) { + createModelAction(YOU, model.getDescription(), Icons.YouSmall, + comboBoxPresentation); + return new DumbAwareAction(model.getDescription(), "", Icons.YouSmall) { + @Override + public void update(@NotNull AnActionEvent event) { + var presentation = event.getPresentation(); + presentation.setEnabled(!presentation.getText().equals(comboBoxPresentation.getText())); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + youSettings.setCustomModel(model); + youSettings.setChatMode(YouCompletionMode.CUSTOM); + handleProviderChange( + YOU, + model.getDescription(), + Icons.YouSmall, + comboBoxPresentation); + } + }; + } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/UserPromptTextAreaHeader.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/UserPromptTextAreaHeader.java index 5591ed99..d350d857 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/UserPromptTextAreaHeader.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/UserPromptTextAreaHeader.java @@ -26,9 +26,6 @@ public class UserPromptTextAreaHeader extends JPanel { add(totalTokensPanel, BorderLayout.LINE_START); break; case YOU: - JBCheckBox gpt4CheckBox = new YouProCheckbox(); - subscribeToYouTopics(gpt4CheckBox); - add(gpt4CheckBox, BorderLayout.LINE_START); break; default: } diff --git a/src/test/java/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.java b/src/test/java/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.java index 9d59ce47..955b298c 100644 --- a/src/test/java/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.java +++ b/src/test/java/ee/carlrobert/codegpt/completions/DefaultCompletionRequestHandlerTest.java @@ -146,6 +146,7 @@ public class DefaultCompletionRequestHandlerTest extends IntegrationTest { + "count=10&" + "safeSearch=WebPages,Translations,TimeZone,Computation,RelatedSearches&" + "domain=youchat&" + + "selectedChatMode=default&" + "chat=[{\"question\":\"Ping\",\"answer\":\"Pong\"}]&" + "utm_source=ide&" + "utm_medium=jetbrains&"