mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-11 21:31:04 +00:00
Support you.com gpt-4 model (#233)
This commit is contained in:
parent
0343842af9
commit
21fa61d2af
18 changed files with 311 additions and 168 deletions
|
|
@ -1,5 +1,7 @@
|
|||
package ee.carlrobert.codegpt.completions;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import ee.carlrobert.codegpt.completions.you.YouUserManager;
|
||||
import ee.carlrobert.codegpt.conversations.Conversation;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.settings.state.AzureSettingsState;
|
||||
|
|
@ -20,6 +22,8 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
public class CompletionRequestHandler {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(CompletionRequestHandler.class);
|
||||
|
||||
private final StringBuilder messageBuilder = new StringBuilder();
|
||||
private SwingWorker<Void, String> swingWorker;
|
||||
private EventSource eventSource;
|
||||
|
|
@ -77,8 +81,21 @@ public class CompletionRequestHandler {
|
|||
|
||||
try {
|
||||
if (settings.isUseYouService()) {
|
||||
return CompletionClientProvider.getYouClient("", "")
|
||||
.getChatCompletion(requestProvider.buildYouCompletionRequest(message), eventListener);
|
||||
var sessionId = "";
|
||||
var accessToken = "";
|
||||
var youUserManager = YouUserManager.getInstance();
|
||||
if (youUserManager.isAuthenticated()) {
|
||||
var authenticationResponse =
|
||||
youUserManager.getAuthenticationResponse().getData();
|
||||
sessionId = authenticationResponse.getSession().getSessionId();
|
||||
accessToken = authenticationResponse.getSessionJwt();
|
||||
}
|
||||
var request = requestProvider.buildYouCompletionRequest(message);
|
||||
LOG.info("Initiating completion request using model: " +
|
||||
(request.isUseGPT4Model() ? "GPT-4" : "YouBot"));
|
||||
|
||||
return CompletionClientProvider.getYouClient(sessionId, accessToken)
|
||||
.getChatCompletion(request, eventListener);
|
||||
}
|
||||
|
||||
if (settings.isUseAzureService()) {
|
||||
|
|
@ -130,8 +147,8 @@ public class CompletionRequestHandler {
|
|||
message,
|
||||
isRetry,
|
||||
settings.isUseYouService() ?
|
||||
getYouCompletionEventListener() :
|
||||
getCompletionEventListener());
|
||||
new BaseCompletionEventListener() :
|
||||
new YouRequestCompletionEventListener());
|
||||
} catch (TotalUsageExceededException e) {
|
||||
if (tokensExceededListener != null) {
|
||||
tokensExceededListener.run();
|
||||
|
|
@ -152,66 +169,41 @@ public class CompletionRequestHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private CompletionEventListener getCompletionEventListener() {
|
||||
return new CompletionEventListener() {
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
publish(message);
|
||||
}
|
||||
class BaseCompletionEventListener implements CompletionEventListener {
|
||||
|
||||
@Override
|
||||
public void onComplete(StringBuilder messageBuilder) {
|
||||
if (completedListener != null) {
|
||||
completedListener.accept(messageBuilder.toString());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
publish(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorDetails error, Throwable ex) {
|
||||
try {
|
||||
if (errorListener != null) {
|
||||
errorListener.accept(error, ex);
|
||||
}
|
||||
} finally {
|
||||
sendError(error, ex);
|
||||
}
|
||||
@Override
|
||||
public void onComplete(StringBuilder messageBuilder) {
|
||||
if (completedListener != null) {
|
||||
completedListener.accept(messageBuilder.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorDetails error, Throwable ex) {
|
||||
try {
|
||||
if (errorListener != null) {
|
||||
errorListener.accept(error, ex);
|
||||
}
|
||||
} finally {
|
||||
sendError(error, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Refactor
|
||||
private YouCompletionEventListener getYouCompletionEventListener() {
|
||||
return new YouCompletionEventListener() {
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
publish(message);
|
||||
}
|
||||
class YouRequestCompletionEventListener extends BaseCompletionEventListener
|
||||
implements YouCompletionEventListener {
|
||||
|
||||
@Override
|
||||
public void onComplete(StringBuilder messageBuilder) {
|
||||
if (completedListener != null) {
|
||||
completedListener.accept(messageBuilder.toString());
|
||||
}
|
||||
@Override
|
||||
public void onSerpResults(List<YouSerpResult> results) {
|
||||
if (serpResultsListener != null) {
|
||||
serpResultsListener.accept(results);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorDetails error, Throwable ex) {
|
||||
try {
|
||||
if (errorListener != null) {
|
||||
errorListener.accept(error, ex);
|
||||
}
|
||||
} finally {
|
||||
sendError(error, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSerpResults(List<YouSerpResult> results) {
|
||||
if (serpResultsListener != null) {
|
||||
serpResultsListener.accept(results);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void sendInfo(SettingsState settings) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import ee.carlrobert.codegpt.conversations.ConversationsState;
|
|||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.settings.configuration.ConfigurationState;
|
||||
import ee.carlrobert.codegpt.settings.state.SettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.YouSettingsState;
|
||||
import ee.carlrobert.embedding.EmbeddingsService;
|
||||
import ee.carlrobert.llm.client.openai.completion.chat.OpenAIChatCompletionModel;
|
||||
import ee.carlrobert.llm.client.openai.completion.chat.request.OpenAIChatCompletionMessage;
|
||||
|
|
@ -55,6 +56,7 @@ public class CompletionRequestProvider {
|
|||
|
||||
public YouCompletionRequest buildYouCompletionRequest(Message message) {
|
||||
return new YouCompletionRequest.Builder(message.getPrompt())
|
||||
.setUseGPT4Model(YouSettingsState.getInstance().isUseGPT4Model())
|
||||
.setChatHistory(conversation.getMessages().stream()
|
||||
.map(prevMessage -> new YouCompletionRequestMessage(prevMessage.getPrompt(), prevMessage.getResponse()))
|
||||
.collect(toList()))
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import ee.carlrobert.codegpt.settings.state.OpenAISettingsState;
|
|||
import ee.carlrobert.codegpt.settings.state.SettingsState;
|
||||
import ee.carlrobert.codegpt.completions.you.YouUserManager;
|
||||
import ee.carlrobert.codegpt.completions.you.auth.AuthenticationNotifier;
|
||||
import ee.carlrobert.codegpt.settings.state.YouSettingsState;
|
||||
import ee.carlrobert.codegpt.util.SwingUtils;
|
||||
import ee.carlrobert.llm.client.openai.completion.chat.OpenAIChatCompletionModel;
|
||||
import ee.carlrobert.llm.completion.CompletionModel;
|
||||
|
|
@ -34,7 +35,7 @@ public class ServiceSelectionForm {
|
|||
|
||||
private final Disposable parentDisposable;
|
||||
|
||||
private static final OpenAIChatCompletionModel[] DEFAULT_OPENAI_MODELS = new OpenAIChatCompletionModel[] {
|
||||
private static final OpenAIChatCompletionModel[] DEFAULT_OPENAI_MODELS = new OpenAIChatCompletionModel[]{
|
||||
OpenAIChatCompletionModel.GPT_3_5,
|
||||
OpenAIChatCompletionModel.GPT_3_5_16k,
|
||||
OpenAIChatCompletionModel.GPT_4,
|
||||
|
|
@ -88,7 +89,8 @@ public class ServiceSelectionForm {
|
|||
|
||||
azureActiveDirectoryTokenField = new JBPasswordField();
|
||||
azureActiveDirectoryTokenField.setColumns(30);
|
||||
azureActiveDirectoryTokenField.setText(AzureCredentialsManager.getInstance().getAzureActiveDirectoryToken());
|
||||
azureActiveDirectoryTokenField.setText(
|
||||
AzureCredentialsManager.getInstance().getAzureActiveDirectoryToken());
|
||||
|
||||
azureActiveDirectoryTokenFieldPanel = UI.PanelFactory.panel(azureActiveDirectoryTokenField)
|
||||
.withLabel("Bearer token:")
|
||||
|
|
@ -103,26 +105,37 @@ public class ServiceSelectionForm {
|
|||
azureSettings.isUseAzureActiveDirectoryAuthentication());
|
||||
|
||||
useOpenAIServiceRadioButton = new JBRadioButton(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.service.useOpenAIServiceRadioButtonLabel"), settings.isUseOpenAIService());
|
||||
CodeGPTBundle.get("settingsConfigurable.section.service.useOpenAIServiceRadioButtonLabel"),
|
||||
settings.isUseOpenAIService());
|
||||
useAzureServiceRadioButton = new JBRadioButton(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.service.useAzureServiceRadioButtonLabel"), settings.isUseAzureService());
|
||||
CodeGPTBundle.get("settingsConfigurable.section.service.useAzureServiceRadioButtonLabel"),
|
||||
settings.isUseAzureService());
|
||||
useYouServiceRadioButton = new JBRadioButton(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.service.useYouServiceRadioButtonLabel"), settings.isUseYouService());
|
||||
CodeGPTBundle.get("settingsConfigurable.section.service.useYouServiceRadioButtonLabel"),
|
||||
settings.isUseYouService());
|
||||
|
||||
openAIBaseHostField = new JBTextField(openAISettings.getBaseHost(), 30);
|
||||
openAIPathField = new JBTextField(openAISettings.getPath(), 30);
|
||||
openAIOrganizationField = new JBTextField(openAISettings.getOrganization(), 30);
|
||||
openAICompletionModelComboBox = new ModelComboBox(DEFAULT_OPENAI_MODELS, OpenAIChatCompletionModel.findByCode(openAISettings.getModel()));
|
||||
openAICompletionModelComboBox = new ModelComboBox(
|
||||
DEFAULT_OPENAI_MODELS,
|
||||
OpenAIChatCompletionModel.findByCode(openAISettings.getModel()));
|
||||
|
||||
azureBaseHostField = new JBTextField(azureSettings.getBaseHost(), 35);
|
||||
azurePathField = new JBTextField(azureSettings.getPath(), 35);
|
||||
azureResourceNameField = new JBTextField(azureSettings.getResourceName(), 35);
|
||||
azureDeploymentIdField = new JBTextField(azureSettings.getDeploymentId(), 35);
|
||||
azureApiVersionField = new JBTextField(azureSettings.getApiVersion(), 35);
|
||||
azureCompletionModelComboBox = new ModelComboBox(DEFAULT_OPENAI_MODELS, OpenAIChatCompletionModel.findByCode(azureSettings.getModel()));
|
||||
azureCompletionModelComboBox.getEditor().getEditorComponent().setMaximumSize(azureBaseHostField.getPreferredSize());
|
||||
azureCompletionModelComboBox = new ModelComboBox(
|
||||
DEFAULT_OPENAI_MODELS,
|
||||
OpenAIChatCompletionModel.findByCode(azureSettings.getModel()));
|
||||
azureCompletionModelComboBox.getEditor()
|
||||
.getEditorComponent()
|
||||
.setMaximumSize(azureBaseHostField.getPreferredSize());
|
||||
|
||||
displayWebSearchResultsCheckBox = new JBCheckBox("Display web search results", settings.isDisplayWebSearchResults());
|
||||
displayWebSearchResultsCheckBox = new JBCheckBox(
|
||||
"Display web search results",
|
||||
YouSettingsState.getInstance().isDisplayWebSearchResults());
|
||||
displayWebSearchResultsCheckBox.setEnabled(YouUserManager.getInstance().isAuthenticated());
|
||||
|
||||
openAIServiceSectionPanel = createOpenAIServiceSectionPanel();
|
||||
|
|
@ -135,7 +148,8 @@ public class ServiceSelectionForm {
|
|||
ApplicationManager.getApplication()
|
||||
.getMessageBus()
|
||||
.connect()
|
||||
.subscribe(AuthenticationNotifier.AUTHENTICATION_TOPIC, (AuthenticationNotifier) () -> displayWebSearchResultsCheckBox.setEnabled(true));
|
||||
.subscribe(AuthenticationNotifier.AUTHENTICATION_TOPIC,
|
||||
(AuthenticationNotifier) () -> displayWebSearchResultsCheckBox.setEnabled(true));
|
||||
}
|
||||
|
||||
public JPanel getForm() {
|
||||
|
|
@ -158,9 +172,11 @@ public class ServiceSelectionForm {
|
|||
private JPanel createOpenAIServiceSectionPanel() {
|
||||
var requestConfigurationPanel = UI.PanelFactory.grid()
|
||||
.add(UI.PanelFactory.panel(openAIOrganizationField)
|
||||
.withLabel(CodeGPTBundle.get("settingsConfigurable.section.service.openai.organizationField.label"))
|
||||
.withLabel(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.openai.organizationField.label"))
|
||||
.resizeX(false)
|
||||
.withComment(CodeGPTBundle.get("settingsConfigurable.section.service.openai.organizationField.comment")))
|
||||
.withComment(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.openai.organizationField.comment")))
|
||||
.add(UI.PanelFactory.panel(openAIBaseHostField)
|
||||
.withLabel("Base host:")
|
||||
.resizeX(false))
|
||||
|
|
@ -175,7 +191,8 @@ public class ServiceSelectionForm {
|
|||
var apiKeyFieldPanel = UI.PanelFactory.panel(openAIApiKeyField)
|
||||
.withLabel(CodeGPTBundle.get("settingsConfigurable.section.integration.apiKeyField.label"))
|
||||
.resizeX(false)
|
||||
.withComment(CodeGPTBundle.get("settingsConfigurable.section.integration.apiKeyField.comment"))
|
||||
.withComment(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.integration.apiKeyField.comment"))
|
||||
.withCommentHyperlinkListener(SwingUtils::handleHyperlinkClicked)
|
||||
.createPanel();
|
||||
|
||||
|
|
@ -204,17 +221,23 @@ public class ServiceSelectionForm {
|
|||
|
||||
var configPanel = withEmptyLeftBorder(UI.PanelFactory.grid()
|
||||
.add(UI.PanelFactory.panel(azureResourceNameField)
|
||||
.withLabel(CodeGPTBundle.get("settingsConfigurable.section.service.azure.resourceNameField.label"))
|
||||
.withLabel(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.azure.resourceNameField.label"))
|
||||
.resizeX(false)
|
||||
.withComment(CodeGPTBundle.get("settingsConfigurable.section.service.azure.resourceNameField.comment")))
|
||||
.withComment(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.azure.resourceNameField.comment")))
|
||||
.add(UI.PanelFactory.panel(azureDeploymentIdField)
|
||||
.withLabel(CodeGPTBundle.get("settingsConfigurable.section.service.azure.deploymentIdField.label"))
|
||||
.withLabel(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.azure.deploymentIdField.label"))
|
||||
.resizeX(false)
|
||||
.withComment(CodeGPTBundle.get("settingsConfigurable.section.service.azure.deploymentIdField.comment")))
|
||||
.withComment(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.azure.deploymentIdField.comment")))
|
||||
.add(UI.PanelFactory.panel(azureApiVersionField)
|
||||
.withLabel(CodeGPTBundle.get("settingsConfigurable.section.service.azure.apiVersionField.label"))
|
||||
.withLabel(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.azure.apiVersionField.label"))
|
||||
.resizeX(false)
|
||||
.withComment(CodeGPTBundle.get("settingsConfigurable.section.service.azure.apiVersionField.comment")))
|
||||
.withComment(CodeGPTBundle.get(
|
||||
"settingsConfigurable.section.service.azure.apiVersionField.comment")))
|
||||
.add(UI.PanelFactory.panel(azureBaseHostField)
|
||||
.withLabel("Base host:")
|
||||
.resizeX(false))
|
||||
|
|
@ -251,7 +274,8 @@ public class ServiceSelectionForm {
|
|||
openAIServiceSectionPanel.setVisible(settings.isUseOpenAIService());
|
||||
azureServiceSectionPanel.setVisible(settings.isUseAzureService());
|
||||
azureApiKeyFieldPanel.setVisible(azureSettings.isUseAzureApiKeyAuthentication());
|
||||
azureActiveDirectoryTokenFieldPanel.setVisible(azureSettings.isUseAzureActiveDirectoryAuthentication());
|
||||
azureActiveDirectoryTokenFieldPanel.setVisible(
|
||||
azureSettings.isUseAzureActiveDirectoryAuthentication());
|
||||
youServiceSectionPanel.setVisible(settings.isUseYouService());
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +288,8 @@ public class ServiceSelectionForm {
|
|||
registerRadioButtons(
|
||||
List.of(
|
||||
Map.entry(useAzureApiKeyAuthenticationRadioButton, azureApiKeyFieldPanel),
|
||||
Map.entry(useAzureActiveDirectoryAuthenticationRadioButton, azureActiveDirectoryTokenFieldPanel)));
|
||||
Map.entry(useAzureActiveDirectoryAuthenticationRadioButton,
|
||||
azureActiveDirectoryTokenFieldPanel)));
|
||||
}
|
||||
|
||||
private void registerRadioButtons(List<Map.Entry<JBRadioButton, JPanel>> entries) {
|
||||
|
|
@ -343,7 +368,9 @@ public class ServiceSelectionForm {
|
|||
}
|
||||
|
||||
public String getOpenAIModel() {
|
||||
return ((OpenAIChatCompletionModel) (openAICompletionModelComboBox.getModel().getSelectedItem())).getCode();
|
||||
return ((OpenAIChatCompletionModel) (openAICompletionModelComboBox.getModel()
|
||||
.getSelectedItem()))
|
||||
.getCode();
|
||||
}
|
||||
|
||||
public void setAzureActiveDirectoryAuthenticationSelected(boolean selected) {
|
||||
|
|
@ -415,7 +442,9 @@ public class ServiceSelectionForm {
|
|||
}
|
||||
|
||||
public String getAzureModel() {
|
||||
return ((OpenAIChatCompletionModel) (azureCompletionModelComboBox.getModel().getSelectedItem())).getCode();
|
||||
return ((OpenAIChatCompletionModel) (azureCompletionModelComboBox.getModel()
|
||||
.getSelectedItem()))
|
||||
.getCode();
|
||||
}
|
||||
|
||||
public void setDisplayWebSearchResults(boolean displayWebSearchResults) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager;
|
|||
import ee.carlrobert.codegpt.settings.state.AzureSettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.OpenAISettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.SettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.YouSettingsState;
|
||||
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager;
|
||||
import ee.carlrobert.codegpt.util.ApplicationUtils;
|
||||
|
|
@ -54,7 +55,8 @@ public class SettingsConfigurable implements Configurable {
|
|||
isServiceChanged(serviceSelectionForm, settings) ||
|
||||
openAISettings.isModified(serviceSelectionForm) ||
|
||||
azureSettings.isModified(serviceSelectionForm) ||
|
||||
serviceSelectionForm.isDisplayWebSearchResults() != settings.isDisplayWebSearchResults();
|
||||
serviceSelectionForm.isDisplayWebSearchResults() !=
|
||||
YouSettingsState.getInstance().isDisplayWebSearchResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -76,7 +78,8 @@ public class SettingsConfigurable implements Configurable {
|
|||
settings.setUseOpenAIService(serviceSelectionForm.isOpenAIServiceSelected());
|
||||
settings.setUseAzureService(serviceSelectionForm.isAzureServiceSelected());
|
||||
settings.setUseYouService(serviceSelectionForm.isYouServiceSelected());
|
||||
settings.setDisplayWebSearchResults(serviceSelectionForm.isDisplayWebSearchResults());
|
||||
YouSettingsState.getInstance()
|
||||
.setDisplayWebSearchResults(serviceSelectionForm.isDisplayWebSearchResults());
|
||||
|
||||
openAISettings.apply(serviceSelectionForm);
|
||||
azureSettings.apply(serviceSelectionForm);
|
||||
|
|
@ -108,7 +111,8 @@ public class SettingsConfigurable implements Configurable {
|
|||
openAISettings.reset(serviceSelectionForm);
|
||||
azureSettings.reset(serviceSelectionForm);
|
||||
|
||||
serviceSelectionForm.setDisplayWebSearchResults(settings.isDisplayWebSearchResults());
|
||||
serviceSelectionForm.setDisplayWebSearchResults(
|
||||
YouSettingsState.getInstance().isDisplayWebSearchResults());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.intellij.ui.TitledSeparator;
|
|||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBPasswordField;
|
||||
import com.intellij.ui.components.JBTextField;
|
||||
import com.intellij.ui.components.OnOffButton;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
import com.intellij.util.ui.FormBuilder;
|
||||
import com.intellij.util.ui.JBFont;
|
||||
|
|
@ -51,7 +52,8 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
if (!settings.getEmail().isEmpty()) {
|
||||
passwordField.setText(YouCredentialsManager.getInstance().getAccountPassword());
|
||||
}
|
||||
signInButton = new JButton(CodeGPTBundle.get("settingsConfigurable.section.userAuthentication.signIn.label"));
|
||||
signInButton = new JButton(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.userAuthentication.signIn.label"));
|
||||
signUpTextPane = createSignUpTextPane();
|
||||
loadingSpinner = new AsyncProcessIcon("sign_in_spinner");
|
||||
loadingSpinner.setBorder(JBUI.Borders.emptyLeft(8));
|
||||
|
|
@ -63,11 +65,15 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
signInButton.addActionListener(e -> {
|
||||
emailValidator.revalidate();
|
||||
passwordValidator.revalidate();
|
||||
if (emailValidator.getValidationInfo() == null && passwordValidator.getValidationInfo() == null) {
|
||||
if (emailValidator.getValidationInfo() == null
|
||||
&& passwordValidator.getValidationInfo() == null) {
|
||||
loadingSpinner.resume();
|
||||
loadingSpinner.setVisible(true);
|
||||
YouAuthenticationService.getInstance()
|
||||
.signInAsync(emailField.getText(), new String(passwordField.getPassword()), new UserAuthenticationHandler());
|
||||
.signInAsync(
|
||||
emailField.getText(),
|
||||
new String(passwordField.getPassword()),
|
||||
new UserAuthenticationHandler());
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -91,14 +97,17 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
return new String(passwordField.getPassword());
|
||||
}
|
||||
|
||||
private ComponentValidator createInputValidator(Disposable parentDisposable, JComponent component) {
|
||||
private ComponentValidator createInputValidator(
|
||||
Disposable parentDisposable,
|
||||
JComponent component) {
|
||||
var validator = new ComponentValidator(parentDisposable)
|
||||
.withValidator(() -> {
|
||||
String value;
|
||||
if (component instanceof JBTextField) {
|
||||
value = ((JBTextField) component).getText();
|
||||
if (!isValidEmail(value)) {
|
||||
return new ValidationInfo("The email you entered is invalid.", component).withOKEnabled();
|
||||
return new ValidationInfo("The email you entered is invalid.", component)
|
||||
.withOKEnabled();
|
||||
}
|
||||
} else {
|
||||
value = new String(((JPasswordField) component).getPassword());
|
||||
|
|
@ -124,7 +133,8 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
}
|
||||
|
||||
private JTextPane createSignUpTextPane() {
|
||||
var textPane = createTextPane("<html><a href=\"https://you.com/code\">Don't have an account? Sign up</a></html>");
|
||||
var textPane = createTextPane(
|
||||
"<html><a href=\"https://you.com/code\">Don't have an account? Sign up</a></html>");
|
||||
textPane.setBorder(JBUI.Borders.emptyLeft(4));
|
||||
return textPane;
|
||||
}
|
||||
|
|
@ -148,7 +158,10 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createUserAuthenticationPanel(JBTextField emailAddressField, JBPasswordField passwordField, @Nullable YouAuthenticationError error) {
|
||||
private JPanel createUserAuthenticationPanel(
|
||||
JBTextField emailAddressField,
|
||||
JBPasswordField passwordField,
|
||||
@Nullable YouAuthenticationError error) {
|
||||
var contentPanelBuilder = FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent("Email address:", emailAddressField)
|
||||
.addLabeledComponent("Password:", passwordField)
|
||||
|
|
@ -160,12 +173,12 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
var invalidCredentialsLabel = new JBLabel(error.getErrorMessage());
|
||||
invalidCredentialsLabel.setForeground(JBColor.red);
|
||||
invalidCredentialsLabel.setBorder(JBUI.Borders.emptyLeft(4));
|
||||
|
||||
contentPanelBuilder.addComponentToRightColumn(invalidCredentialsLabel);
|
||||
}
|
||||
|
||||
return FormBuilder.createFormBuilder()
|
||||
.addComponent(new TitledSeparator(CodeGPTBundle.get("settingsConfigurable.section.userAuthentication.title")))
|
||||
.addComponent(new TitledSeparator(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.userAuthentication.title")))
|
||||
.addComponent(JBUI.Panels
|
||||
.simplePanel(contentPanelBuilder.getPanel())
|
||||
.withBorder(JBUI.Borders.emptyLeft(16)))
|
||||
|
|
@ -175,7 +188,8 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
private JPanel createUserInformationPanel(YouUser user) {
|
||||
var userManager = YouUserManager.getInstance();
|
||||
var contentPanelBuilder = FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent("Email address:", new JBLabel(user.getEmails().get(0).getEmail()).withFont(JBFont.label().asBold()));
|
||||
.addLabeledComponent("Email address:",
|
||||
new JBLabel(user.getEmails().get(0).getEmail()).withFont(JBFont.label().asBold()));
|
||||
|
||||
var signOutButton = new JButton("Sign Out");
|
||||
signOutButton.addActionListener(e -> {
|
||||
|
|
@ -184,7 +198,8 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
});
|
||||
|
||||
return FormBuilder.createFormBuilder()
|
||||
.addComponent(new TitledSeparator(CodeGPTBundle.get("settingsConfigurable.section.userInformation.title")))
|
||||
.addComponent(new TitledSeparator(
|
||||
CodeGPTBundle.get("settingsConfigurable.section.userInformation.title")))
|
||||
.addVerticalGap(8)
|
||||
.addComponent(JBUI.Panels
|
||||
.simplePanel(contentPanelBuilder.addVerticalGap(4)
|
||||
|
|
@ -209,13 +224,18 @@ public class YouServiceSelectionPanel extends JPanel {
|
|||
|
||||
@Override
|
||||
public void handleGenericError() {
|
||||
SwingUtilities.invokeLater(() -> refreshView(
|
||||
createUserAuthenticationPanel(emailField, passwordField, new YouAuthenticationError("unknown", "Something went wrong."))));
|
||||
SwingUtilities.invokeLater(() -> refreshView(createUserAuthenticationPanel(
|
||||
emailField,
|
||||
passwordField,
|
||||
new YouAuthenticationError("unknown", "Something went wrong."))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(YouAuthenticationError error) {
|
||||
SwingUtilities.invokeLater(() -> refreshView(createUserAuthenticationPanel(emailField, passwordField, error)));
|
||||
SwingUtilities.invokeLater(() -> refreshView(createUserAuthenticationPanel(
|
||||
emailField,
|
||||
passwordField,
|
||||
error)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public class SettingsState implements PersistentStateComponent<SettingsState> {
|
|||
private boolean useOpenAIService = true;
|
||||
private boolean useAzureService;
|
||||
private boolean useYouService;
|
||||
private boolean displayWebSearchResults = true;
|
||||
|
||||
public SettingsState() {
|
||||
}
|
||||
|
|
@ -104,12 +103,4 @@ public class SettingsState implements PersistentStateComponent<SettingsState> {
|
|||
public void setUseYouService(boolean useYouService) {
|
||||
this.useYouService = useYouService;
|
||||
}
|
||||
|
||||
public boolean isDisplayWebSearchResults() {
|
||||
return displayWebSearchResults;
|
||||
}
|
||||
|
||||
public void setDisplayWebSearchResults(boolean displayWebSearchResults) {
|
||||
this.displayWebSearchResults = displayWebSearchResults;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package ee.carlrobert.codegpt.settings.state;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@State(name = "CodeGPT_YouSettings", storages = @Storage("CodeGPT_YouSettings.xml"))
|
||||
public class YouSettingsState implements PersistentStateComponent<YouSettingsState> {
|
||||
|
||||
private boolean displayWebSearchResults = true;
|
||||
private boolean useGPT4Model;
|
||||
|
||||
public static YouSettingsState getInstance() {
|
||||
return ApplicationManager.getApplication().getService(YouSettingsState.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YouSettingsState getState() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(@NotNull YouSettingsState state) {
|
||||
XmlSerializerUtil.copyBean(state, this);
|
||||
}
|
||||
|
||||
public boolean isDisplayWebSearchResults() {
|
||||
return displayWebSearchResults;
|
||||
}
|
||||
|
||||
public void setDisplayWebSearchResults(boolean displayWebSearchResults) {
|
||||
this.displayWebSearchResults = displayWebSearchResults;
|
||||
}
|
||||
|
||||
public boolean isUseGPT4Model() {
|
||||
return useGPT4Model;
|
||||
}
|
||||
|
||||
public void setUseGPT4Model(boolean useGPT4Model) {
|
||||
this.useGPT4Model = useGPT4Model;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,12 +5,15 @@ import static ee.carlrobert.codegpt.util.ThemeUtils.getPanelBackgroundColor;
|
|||
import static java.lang.String.format;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.intellij.ide.HelpTooltip;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ui.componentsList.components.ScrollablePanel;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.components.OnOffButton;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.JBUI.Borders;
|
||||
import ee.carlrobert.codegpt.actions.ActionType;
|
||||
import ee.carlrobert.codegpt.completions.CompletionRequestHandler;
|
||||
import ee.carlrobert.codegpt.completions.you.YouSerpResult;
|
||||
|
|
@ -22,6 +25,7 @@ import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager;
|
|||
import ee.carlrobert.codegpt.settings.state.AzureSettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.OpenAISettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.SettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.YouSettingsState;
|
||||
import ee.carlrobert.codegpt.telemetry.TelemetryAction;
|
||||
import ee.carlrobert.codegpt.toolwindow.ModelIconLabel;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.components.ChatMessageResponseBody;
|
||||
|
|
@ -29,10 +33,9 @@ import ee.carlrobert.codegpt.toolwindow.chat.components.ResponsePanel;
|
|||
import ee.carlrobert.codegpt.toolwindow.chat.components.SmartScroller;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.components.UserMessagePanel;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.components.UserPromptTextArea;
|
||||
import ee.carlrobert.codegpt.completions.you.YouUserManager;
|
||||
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 java.awt.BorderLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
|
|
@ -131,10 +134,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
public void dispose() {
|
||||
}
|
||||
|
||||
private boolean isCredentialSet() {
|
||||
if (SettingsState.getInstance().isUseYouService()) {
|
||||
return YouUserManager.getInstance().isAuthenticated();
|
||||
}
|
||||
private boolean isRequestAllowed() {
|
||||
if (SettingsState.getInstance().isUseAzureService()) {
|
||||
return AzureCredentialsManager.getInstance().isCredentialSet();
|
||||
}
|
||||
|
|
@ -148,7 +148,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
boolean isRetry) {
|
||||
ChatMessageResponseBody responseContainer = (ChatMessageResponseBody) responsePanel.getContent();
|
||||
|
||||
if (!isCredentialSet()) {
|
||||
if (!isRequestAllowed()) {
|
||||
responseContainer.displayMissingCredential();
|
||||
return;
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
|
||||
var serpResults = serpResultsMapping.get(message.getId());
|
||||
var containsResults = serpResults != null && !serpResults.isEmpty();
|
||||
if (SettingsState.getInstance().isDisplayWebSearchResults()) {
|
||||
if (YouSettingsState.getInstance().isDisplayWebSearchResults()) {
|
||||
if (containsResults) {
|
||||
responseContainer.displaySerpResults(serpResults);
|
||||
}
|
||||
|
|
@ -332,9 +332,10 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
gbc.gridy = 1;
|
||||
|
||||
var model = getModel();
|
||||
var modelIconWrapper = JBUI.Panels.simplePanel(
|
||||
new ModelIconLabel(getClientCode(), model)).withBorder(JBUI.Borders.empty(0, 0, 8, 4));
|
||||
modelIconWrapper.setBackground(getPanelBackgroundColor());
|
||||
var modelIconWrapper = JBUI.Panels
|
||||
.simplePanel(new ModelIconLabel(getClientCode(), model))
|
||||
.withBorder(Borders.emptyRight(4))
|
||||
.withBackground(getPanelBackgroundColor());
|
||||
|
||||
var wrapper = new JPanel(new BorderLayout());
|
||||
wrapper.setBorder(JBUI.Borders.compound(
|
||||
|
|
@ -343,13 +344,46 @@ public abstract class BaseChatToolWindowTabPanel implements ChatToolWindowTabPan
|
|||
wrapper.setBackground(getPanelBackgroundColor());
|
||||
wrapper.add(userPromptTextArea, BorderLayout.SOUTH);
|
||||
if (model != null) {
|
||||
wrapper.add(modelIconWrapper, BorderLayout.LINE_END);
|
||||
var header = new JPanel(new BorderLayout());
|
||||
header.setBackground(getPanelBackgroundColor());
|
||||
header.setBorder(JBUI.Borders.emptyBottom(8));
|
||||
if ("YouCode".equals(model)) {
|
||||
var gpt4ToggleButton = new OnOffButton();
|
||||
var useGPT4Model = YouSettingsState.getInstance().isUseGPT4Model();
|
||||
gpt4ToggleButton.setSelected(useGPT4Model);
|
||||
gpt4ToggleButton.setOnText("GPT-4");
|
||||
gpt4ToggleButton.setOffText("GPT-4");
|
||||
gpt4ToggleButton.addActionListener(
|
||||
actionEvent -> {
|
||||
project.getMessageBus()
|
||||
.syncPublisher(YouModelChangeNotifier.YOU_MODEL_CHANGE_NOTIFIER_TOPIC)
|
||||
.modelChanged(gpt4ToggleButton.isSelected());
|
||||
YouSettingsState.getInstance().setUseGPT4Model(gpt4ToggleButton.isSelected());
|
||||
installHelpTooltip(gpt4ToggleButton.isSelected(), gpt4ToggleButton);
|
||||
});
|
||||
project.getMessageBus()
|
||||
.connect()
|
||||
.subscribe(
|
||||
YouModelChangeNotifier.YOU_MODEL_CHANGE_NOTIFIER_TOPIC,
|
||||
(YouModelChangeNotifier) gpt4ToggleButton::setSelected);
|
||||
|
||||
installHelpTooltip(useGPT4Model, gpt4ToggleButton);
|
||||
header.add(gpt4ToggleButton, BorderLayout.LINE_START);
|
||||
}
|
||||
header.add(modelIconWrapper, BorderLayout.LINE_END);
|
||||
wrapper.add(header);
|
||||
}
|
||||
rootPanel.add(wrapper, gbc);
|
||||
userPromptTextArea.requestFocusInWindow();
|
||||
userPromptTextArea.requestFocus();
|
||||
}
|
||||
|
||||
private void installHelpTooltip(boolean selected, JComponent component) {
|
||||
new HelpTooltip()
|
||||
.setDescription(selected ? "Turn off for faster responses" : "Turn on for complex queries")
|
||||
.installOn(component);
|
||||
}
|
||||
|
||||
private String getClientCode() {
|
||||
var settings = SettingsState.getInstance();
|
||||
if (settings.isUseOpenAIService()) {
|
||||
|
|
|
|||
|
|
@ -21,5 +21,6 @@ public interface ChatToolWindowTabPanel extends Disposable {
|
|||
void startNewConversation(Message message);
|
||||
|
||||
void sendMessage(Message message);
|
||||
|
||||
void requestFocusForTextArea();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat;
|
||||
|
||||
import com.intellij.util.messages.Topic;
|
||||
|
||||
public interface YouModelChangeNotifier {
|
||||
|
||||
Topic<YouModelChangeNotifier> YOU_MODEL_CHANGE_NOTIFIER_TOPIC =
|
||||
Topic.create("youModelChangeTopic", YouModelChangeNotifier.class);
|
||||
|
||||
void modelChanged(boolean selected);
|
||||
}
|
||||
|
|
@ -102,9 +102,7 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
}
|
||||
|
||||
public void displayMissingCredential() {
|
||||
var message = SettingsState.getInstance().isUseYouService() ?
|
||||
"Please <a href=\"#\">log in</a> to access the chat feature." :
|
||||
"API key not provided. Open <a href=\"#\">Settings</a> to set one.";
|
||||
var message = "API key not provided. Open <a href=\"#\">Settings</a> to set one.";
|
||||
currentlyProcessedTextPane.setText(
|
||||
format("<html><p style=\"margin-top: 4px; margin-bottom: 8px;\">%s</p></html>", message));
|
||||
currentlyProcessedTextPane.addHyperlinkListener(e -> {
|
||||
|
|
|
|||
|
|
@ -1,24 +1,19 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat.editor;
|
||||
|
||||
import static ee.carlrobert.codegpt.util.file.FileUtils.findFileNameExtensionMapping;
|
||||
import static java.lang.String.format;
|
||||
import static ee.carlrobert.codegpt.util.file.FileUtils.findLanguageExtensionMapping;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.EditorKind;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.ContextMenuPopupHandler;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
|
|
@ -32,43 +27,26 @@ import ee.carlrobert.codegpt.toolwindow.chat.editor.actions.ReplaceSelectionActi
|
|||
import ee.carlrobert.codegpt.util.EditorUtils;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class ResponseEditor extends JPanel implements Disposable {
|
||||
|
||||
private final Editor editor;
|
||||
private final String fileName;
|
||||
private final String fileExtension;
|
||||
private final String language;
|
||||
private final String extension;
|
||||
|
||||
public ResponseEditor(
|
||||
Project project,
|
||||
String code,
|
||||
String language,
|
||||
String markdownLanguage,
|
||||
Disposable disposableParent) {
|
||||
super(new BorderLayout());
|
||||
|
||||
var fileNameExtensionMapping = findFileNameExtensionMapping(language);
|
||||
this.fileName = fileNameExtensionMapping.getKey();
|
||||
this.fileExtension = fileNameExtensionMapping.getValue();
|
||||
|
||||
var timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
|
||||
var fileName = "temp_" + timestamp + fileExtension;
|
||||
var lightVirtualFile = new LightVirtualFile(
|
||||
format("%s/%s", PathManager.getTempPath(), fileName), code);
|
||||
var document = FileDocumentManager.getInstance().getDocument(lightVirtualFile);
|
||||
if (document == null) {
|
||||
document = EditorFactory.getInstance().createDocument(code);
|
||||
}
|
||||
EditorUtils.disableHighlighting(project, document);
|
||||
editor = EditorFactory.getInstance().createEditor(
|
||||
document,
|
||||
project,
|
||||
lightVirtualFile,
|
||||
true,
|
||||
EditorKind.UNTYPED);
|
||||
var extensionMapping = findLanguageExtensionMapping(markdownLanguage);
|
||||
language = extensionMapping.getKey();
|
||||
extension = extensionMapping.getValue();
|
||||
editor = EditorUtils.createEditor(project, extension, code);
|
||||
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
group.add(new ReplaceCodeInMainEditorAction());
|
||||
|
|
@ -85,12 +63,14 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
editorEx.installPopupHandler(new ContextMenuPopupHandler.Simple(group));
|
||||
editorEx.setColorsScheme(EditorColorsManager.getInstance().getSchemeForCurrentUITheme());
|
||||
|
||||
var settings = editor.getSettings();
|
||||
var settings = editorEx.getSettings();
|
||||
settings.setAdditionalColumnsCount(0);
|
||||
settings.setAdditionalLinesCount(0);
|
||||
settings.setAdditionalPageAtBottom(false);
|
||||
settings.setVirtualSpace(false);
|
||||
settings.setUseSoftWraps(false);
|
||||
settings.setLineMarkerAreaShown(true);
|
||||
settings.setGutterIconsShown(true);
|
||||
|
||||
add(createHeaderComponent(), BorderLayout.NORTH);
|
||||
add(editor.getComponent(), BorderLayout.SOUTH);
|
||||
|
|
@ -112,7 +92,7 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
headerComponent.setBorder(JBUI.Borders.compound(
|
||||
JBUI.Borders.customLine(JBColor.border(), 1, 1, 1, 1),
|
||||
JBUI.Borders.empty(8)));
|
||||
headerComponent.add(new JBLabel(fileName), BorderLayout.LINE_START);
|
||||
headerComponent.add(new JBLabel(language), BorderLayout.LINE_START);
|
||||
headerComponent.add(createHeaderActions(), BorderLayout.LINE_END);
|
||||
return headerComponent;
|
||||
}
|
||||
|
|
@ -123,7 +103,7 @@ public class ResponseEditor extends JPanel implements Disposable {
|
|||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
wrapper.add(new IconActionButton(new EditAction(editor)));
|
||||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
wrapper.add(new IconActionButton(new NewFileAction(editor, fileExtension)));
|
||||
wrapper.add(new IconActionButton(new NewFileAction(editor, extension)));
|
||||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
wrapper.add(new IconActionButton(new CopyAction(editor)));
|
||||
wrapper.add(Box.createHorizontalStrut(8));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.intellij.openapi.project.Project;
|
|||
import ee.carlrobert.codegpt.conversations.Conversation;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import ee.carlrobert.codegpt.settings.state.SettingsState;
|
||||
import ee.carlrobert.codegpt.settings.state.YouSettingsState;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.BaseChatToolWindowTabPanel;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.components.ChatMessageResponseBody;
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.components.ResponsePanel;
|
||||
|
|
@ -24,7 +25,8 @@ public class StandardChatToolWindowTabPanel extends BaseChatToolWindowTabPanel {
|
|||
this(project, null);
|
||||
}
|
||||
|
||||
public StandardChatToolWindowTabPanel(@NotNull Project project, @Nullable Conversation conversation) {
|
||||
public StandardChatToolWindowTabPanel(@NotNull Project project,
|
||||
@Nullable Conversation conversation) {
|
||||
super(project, false);
|
||||
if (conversation == null) {
|
||||
displayLandingView();
|
||||
|
|
@ -39,12 +41,14 @@ public class StandardChatToolWindowTabPanel extends BaseChatToolWindowTabPanel {
|
|||
var editor = EditorUtils.getSelectedEditor(project);
|
||||
if (editor == null || !editor.getSelectionModel().hasSelection()) {
|
||||
OverlayUtils.showWarningBalloon(
|
||||
editor == null ? "Unable to locate a selected editor" : "Please select a target code before proceeding",
|
||||
editor == null ? "Unable to locate a selected editor"
|
||||
: "Please select a target code before proceeding",
|
||||
locationOnScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
var fileExtension = FileUtils.getFileExtension(((EditorImpl) editor).getVirtualFile().getName());
|
||||
var fileExtension = FileUtils.getFileExtension(
|
||||
((EditorImpl) editor).getVirtualFile().getName());
|
||||
var message = new Message(action.getPrompt().replace(
|
||||
"{{selectedCode}}",
|
||||
format("\n```%s\n%s\n```", fileExtension, editor.getSelectionModel().getSelectedText())));
|
||||
|
|
@ -66,7 +70,8 @@ public class StandardChatToolWindowTabPanel extends BaseChatToolWindowTabPanel {
|
|||
.withResponse(message.getResponse());
|
||||
|
||||
var serpResults = message.getSerpResults();
|
||||
if (SettingsState.getInstance().isDisplayWebSearchResults() && serpResults != null && !serpResults.isEmpty()) {
|
||||
if (YouSettingsState.getInstance().isDisplayWebSearchResults() &&
|
||||
serpResults != null && !serpResults.isEmpty()) {
|
||||
messageResponseBody.displaySerpResults(serpResults);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,48 @@
|
|||
package ee.carlrobert.codegpt.util;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.EditorKind;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class EditorUtils {
|
||||
|
||||
public static Editor createEditor(@NotNull Project project, String fileExtension, String code) {
|
||||
var timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
|
||||
var fileName = "temp_" + timestamp + fileExtension;
|
||||
var lightVirtualFile = new LightVirtualFile(
|
||||
format("%s/%s", PathManager.getTempPath(), fileName),
|
||||
code);
|
||||
var existingDocument = FileDocumentManager.getInstance().getDocument(lightVirtualFile);
|
||||
var document = existingDocument != null
|
||||
? existingDocument
|
||||
: EditorFactory.getInstance().createDocument(code);
|
||||
|
||||
disableHighlighting(project, document);
|
||||
|
||||
return EditorFactory.getInstance().createEditor(
|
||||
document,
|
||||
project,
|
||||
lightVirtualFile,
|
||||
false,
|
||||
EditorKind.MAIN_EDITOR);
|
||||
}
|
||||
|
||||
public static boolean hasSelection(@Nullable Editor editor) {
|
||||
return editor != null && editor.getSelectionModel().hasSelection();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,17 +67,17 @@ public class FileUtils {
|
|||
return "";
|
||||
}
|
||||
|
||||
public static Map.Entry<String, String> findFileNameExtensionMapping(String language) {
|
||||
public static Map.Entry<String, String> findLanguageExtensionMapping(String language) {
|
||||
var defaultValue = Map.entry("Text", ".txt");
|
||||
var mapper = new ObjectMapper();
|
||||
|
||||
List<FileExtensionLanguageDetails> fileExtensionLanguageMappings;
|
||||
List<LanguageFileExtensionDetails> languageFileExtensionMappings;
|
||||
List<FileExtensionLanguageDetails> extensionToLanguageMappings;
|
||||
List<LanguageFileExtensionDetails> languageToExtensionMappings;
|
||||
try {
|
||||
fileExtensionLanguageMappings = mapper.readValue(
|
||||
extensionToLanguageMappings = mapper.readValue(
|
||||
getResourceContent("/fileExtensionLanguageMappings.json"), new TypeReference<>() {
|
||||
});
|
||||
languageFileExtensionMappings = mapper.readValue(
|
||||
languageToExtensionMappings = mapper.readValue(
|
||||
getResourceContent("/languageFileExtensionMappings.json"), new TypeReference<>() {
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
|
|
@ -85,11 +85,11 @@ public class FileUtils {
|
|||
return defaultValue;
|
||||
}
|
||||
|
||||
return findFirstExtension(languageFileExtensionMappings, language)
|
||||
.orElseGet(() -> fileExtensionLanguageMappings.stream()
|
||||
return findFirstExtension(languageToExtensionMappings, language)
|
||||
.orElseGet(() -> extensionToLanguageMappings.stream()
|
||||
.filter(it -> it.getExtension().equalsIgnoreCase(language))
|
||||
.findFirst()
|
||||
.map(it -> findFirstExtension(languageFileExtensionMappings, it.getValue())
|
||||
.map(it -> findFirstExtension(languageToExtensionMappings, it.getValue())
|
||||
.orElse(defaultValue))
|
||||
.orElse(defaultValue));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue