mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-06 08:02:13 +00:00
1.1.2 - Add option to select other language models(closes #7)
This commit is contained in:
parent
36c8255aa6
commit
f8fdb2cbab
8 changed files with 144 additions and 43 deletions
25
src/main/java/ee/carlrobert/chatgpt/client/BaseModel.java
Normal file
25
src/main/java/ee/carlrobert/chatgpt/client/BaseModel.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package ee.carlrobert.chatgpt.client;
|
||||
|
||||
public enum BaseModel {
|
||||
|
||||
ADA("text-ada-001", "Ada - Fastest"),
|
||||
BABBAGE("text-babbage-001", "Babbage - Powerful"),
|
||||
CURIE("text-curie-001", "Curie - Fast and efficient"),
|
||||
DAVINCI("text-davinci-003", "Davinci - Most powerful (Default)");
|
||||
|
||||
private final String model;
|
||||
private final String description;
|
||||
|
||||
BaseModel(String model, String description) {
|
||||
this.model = model;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package ee.carlrobert.chatgpt.client.gpt;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import ee.carlrobert.chatgpt.EmptyCallback;
|
||||
import ee.carlrobert.chatgpt.client.ApiRequestDetails;
|
||||
import ee.carlrobert.chatgpt.client.BaseModel;
|
||||
import ee.carlrobert.chatgpt.client.Client;
|
||||
import ee.carlrobert.chatgpt.ide.settings.SettingsState;
|
||||
import java.net.http.HttpResponse;
|
||||
|
|
@ -32,13 +35,16 @@ public class GPTClient extends Client {
|
|||
|
||||
protected ApiRequestDetails getRequestDetails(String prompt) {
|
||||
return new ApiRequestDetails(
|
||||
"https://api.openai.com/v1/completions",
|
||||
format("https://api.openai.com/v1/engines/%s/completions", SettingsState.getInstance().baseModel.getModel()),
|
||||
Map.of(
|
||||
"model", "text-davinci-003",
|
||||
"stop", List.of("<|im_end|>"),
|
||||
"stop", List.of(" Human:", " AI:"),
|
||||
"prompt", buildPrompt(prompt),
|
||||
"max_tokens", 1000,
|
||||
"temperature", 1.0,
|
||||
"temperature", 0.9,
|
||||
"best_of", 1,
|
||||
"frequency_penalty", 0,
|
||||
"presence_penalty", 0.6,
|
||||
"top_p", 1,
|
||||
"stream", true
|
||||
),
|
||||
SettingsState.getInstance().apiKey);
|
||||
|
|
@ -68,26 +74,32 @@ public class GPTClient extends Client {
|
|||
}
|
||||
}
|
||||
|
||||
private StringBuilder getBasePrompt() {
|
||||
var isDavinciModel = SettingsState.getInstance().baseModel == BaseModel.DAVINCI;
|
||||
if (isDavinciModel) {
|
||||
return new StringBuilder("""
|
||||
You are ChatGPT, a large language model trained by OpenAI.
|
||||
Answer in a markdown language, code blocks should contain language whenever possible.
|
||||
""");
|
||||
}
|
||||
return new StringBuilder(
|
||||
"The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.\n\n");
|
||||
}
|
||||
|
||||
private String buildPrompt(String prompt) {
|
||||
var basePrompt = new StringBuilder("""
|
||||
You are ChatGPT, a large language model trained by OpenAI.
|
||||
One of your main goals is code generation but not only.
|
||||
Answer in a markdown language. Markdown code blocks should contain language whenever possible.
|
||||
""");
|
||||
var basePrompt = getBasePrompt();
|
||||
queries.forEach(query ->
|
||||
basePrompt.append("User:\n")
|
||||
basePrompt.append("Human: ")
|
||||
.append(query.getKey())
|
||||
.append("<|im_end|>\n")
|
||||
.append("\n")
|
||||
.append("ChatGPT:\n")
|
||||
.append("AI: ")
|
||||
.append(query.getValue())
|
||||
.append("<|im_end|>\n")
|
||||
.append("\n"));
|
||||
basePrompt.append("User:\n")
|
||||
basePrompt.append("Human: ")
|
||||
.append(prompt)
|
||||
.append("<|im_end|>\n")
|
||||
.append("\n")
|
||||
.append("ChatGPT:\n");
|
||||
.append("AI: ")
|
||||
.append("\n");
|
||||
return basePrompt.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
package ee.carlrobert.chatgpt.ide.settings;
|
||||
|
||||
import ee.carlrobert.chatgpt.client.BaseModel;
|
||||
import java.awt.Component;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.plaf.basic.BasicComboBoxRenderer;
|
||||
|
||||
public class BaseModelComboBox extends JComboBox<BaseModel> {
|
||||
|
||||
public BaseModelComboBox(BaseModel selectedModel) {
|
||||
super(new BaseModel[] {
|
||||
BaseModel.DAVINCI,
|
||||
BaseModel.CURIE,
|
||||
BaseModel.BABBAGE,
|
||||
BaseModel.ADA,
|
||||
});
|
||||
setSelectedItem(selectedModel);
|
||||
setRenderer(getBasicComboBoxRenderer());
|
||||
}
|
||||
|
||||
private BasicComboBoxRenderer getBasicComboBoxRenderer() {
|
||||
return new BasicComboBoxRenderer() {
|
||||
public Component getListCellRendererComponent(
|
||||
JList list,
|
||||
Object value,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index,
|
||||
isSelected, cellHasFocus);
|
||||
|
||||
if (value != null) {
|
||||
BaseModel model = (BaseModel) value;
|
||||
setText(model.getDescription());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.intellij.ui.components.JBTextField;
|
|||
import com.intellij.util.ui.FormBuilder;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UI;
|
||||
import ee.carlrobert.chatgpt.client.BaseModel;
|
||||
import java.awt.Desktop;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
|
@ -21,6 +22,7 @@ public class SettingsComponent {
|
|||
|
||||
private final JPanel mainPanel;
|
||||
private final JBTextField apiKeyField;
|
||||
private final JComboBox<BaseModel> baseModelComboBox;
|
||||
private final JComboBox<String> reverseProxyComboBox;
|
||||
private final JBTextField accessTokenField;
|
||||
private final JBRadioButton useGPTRadioButton;
|
||||
|
|
@ -28,6 +30,7 @@ public class SettingsComponent {
|
|||
|
||||
public SettingsComponent(SettingsState settings) {
|
||||
apiKeyField = new JBTextField(settings.apiKey);
|
||||
baseModelComboBox = new BaseModelComboBox(settings.baseModel);
|
||||
reverseProxyComboBox = new JComboBox<>(new String[] {
|
||||
"https://chat.duti.tech/api/conversation",
|
||||
"https://gpt.pawan.krd/backend-api/conversation"
|
||||
|
|
@ -41,16 +44,8 @@ public class SettingsComponent {
|
|||
.addComponentFillVertically(new JPanel(), 0)
|
||||
.getPanel();
|
||||
|
||||
if (settings.isGPTOptionSelected) {
|
||||
reverseProxyComboBox.setEnabled(false);
|
||||
accessTokenField.setEnabled(false);
|
||||
} else {
|
||||
apiKeyField.setEnabled(false);
|
||||
reverseProxyComboBox.setEnabled(true);
|
||||
accessTokenField.setEnabled(true);
|
||||
}
|
||||
|
||||
registerButtons();
|
||||
registerFields(settings.isChatGPTOptionSelected);
|
||||
}
|
||||
|
||||
public JPanel getPanel() {
|
||||
|
|
@ -103,6 +98,14 @@ public class SettingsComponent {
|
|||
reverseProxyComboBox.setSelectedItem(reverseProxyUrl);
|
||||
}
|
||||
|
||||
public BaseModel getBaseModel() {
|
||||
return (BaseModel) baseModelComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
public void setBaseModel(BaseModel baseModel) {
|
||||
baseModelComboBox.setSelectedItem(baseModel);
|
||||
}
|
||||
|
||||
private JPanel createMainSelectionForm() {
|
||||
var panel = FormBuilder.createFormBuilder()
|
||||
.addVerticalGap(8)
|
||||
|
|
@ -121,22 +124,30 @@ public class SettingsComponent {
|
|||
}
|
||||
|
||||
private JPanel createFirstSelectionForm() {
|
||||
var baseModelPanel = UI.PanelFactory.panel(baseModelComboBox)
|
||||
.withLabel("Model:")
|
||||
.createPanel();
|
||||
var apiKeyFieldPanel = UI.PanelFactory.panel(apiKeyField)
|
||||
.withLabel("API key:")
|
||||
.withComment("You can find your Secret API key in your <a href=\"https://platform.openai.com/account/api-keys\">User settings</a>.")
|
||||
.withCommentHyperlinkListener(this::handleHyperlinkClicked)
|
||||
.createPanel();
|
||||
|
||||
setEqualLabelWidths(baseModelPanel, apiKeyFieldPanel);
|
||||
|
||||
var panel = FormBuilder.createFormBuilder()
|
||||
.addComponent(UI.PanelFactory.panel(apiKeyField)
|
||||
.withLabel("API key:")
|
||||
.withComment("You can find your Secret API key in your <a href=\"https://platform.openai.com/account/api-keys\">User settings</a>.")
|
||||
.withCommentHyperlinkListener(this::handleHyperlinkClicked)
|
||||
.createPanel())
|
||||
.addComponent(baseModelPanel)
|
||||
.addVerticalGap(8)
|
||||
.addComponent(apiKeyFieldPanel)
|
||||
.getPanel();
|
||||
panel.setBorder(JBUI.Borders.emptyLeft(24));
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createSecondSelectionForm() {
|
||||
var reverseProxyUrlPanel = FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent("Reverse proxy url:", reverseProxyComboBox)
|
||||
.getPanel();
|
||||
|
||||
var reverseProxyUrlPanel = UI.PanelFactory.panel(reverseProxyComboBox)
|
||||
.withLabel("Reverse proxy url:")
|
||||
.createPanel();
|
||||
var accessTokenPanel = UI.PanelFactory.panel(accessTokenField)
|
||||
.withLabel("Access token:")
|
||||
.withComment(
|
||||
|
|
@ -144,11 +155,7 @@ public class SettingsComponent {
|
|||
.withCommentHyperlinkListener(this::handleHyperlinkClicked)
|
||||
.createPanel();
|
||||
|
||||
var accessTokenLabel = accessTokenPanel.getComponents()[0];
|
||||
var reverseProxyUrlLabel = reverseProxyUrlPanel.getComponents()[0];
|
||||
if (accessTokenLabel instanceof JLabel && reverseProxyUrlLabel instanceof JLabel) {
|
||||
accessTokenLabel.setPreferredSize(reverseProxyUrlLabel.getPreferredSize());
|
||||
}
|
||||
setEqualLabelWidths(accessTokenPanel, reverseProxyUrlPanel);
|
||||
|
||||
var panel = FormBuilder.createFormBuilder()
|
||||
.addComponent(reverseProxyUrlPanel)
|
||||
|
|
@ -159,16 +166,26 @@ public class SettingsComponent {
|
|||
return panel;
|
||||
}
|
||||
|
||||
// TODO: Find better way of doing this
|
||||
private void setEqualLabelWidths(JPanel firstPanel, JPanel secondPanel) {
|
||||
var firstLabel = firstPanel.getComponents()[0];
|
||||
var secondLabel = secondPanel.getComponents()[0];
|
||||
if (firstLabel instanceof JLabel && secondLabel instanceof JLabel) {
|
||||
firstLabel.setPreferredSize(secondLabel.getPreferredSize());
|
||||
}
|
||||
}
|
||||
|
||||
private void registerButtons() {
|
||||
ButtonGroup myButtonGroup = new ButtonGroup();
|
||||
myButtonGroup.add(useGPTRadioButton);
|
||||
myButtonGroup.add(useChatGPTRadioButton);
|
||||
useGPTRadioButton.addActionListener(e -> handleRadioOptionChange(false));
|
||||
useChatGPTRadioButton.addActionListener(e -> handleRadioOptionChange(true));
|
||||
useGPTRadioButton.addActionListener(e -> registerFields(false));
|
||||
useChatGPTRadioButton.addActionListener(e -> registerFields(true));
|
||||
}
|
||||
|
||||
private void handleRadioOptionChange(boolean isUseChatGPTOption) {
|
||||
private void registerFields(boolean isUseChatGPTOption) {
|
||||
apiKeyField.setEnabled(!isUseChatGPTOption);
|
||||
baseModelComboBox.setEnabled(!isUseChatGPTOption);
|
||||
accessTokenField.setEnabled(isUseChatGPTOption);
|
||||
reverseProxyComboBox.setEnabled(isUseChatGPTOption);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public class SettingsConfigurable implements Configurable {
|
|||
return !settingsComponent.getApiKey().equals(settings.apiKey) ||
|
||||
!settingsComponent.getAccessToken().equals(settings.accessToken) ||
|
||||
!settingsComponent.getReverseProxyUrl().equals(settings.reverseProxyUrl) ||
|
||||
!settingsComponent.getBaseModel().equals(settings.baseModel) ||
|
||||
settingsComponent.isGPTOptionSelected() != settings.isGPTOptionSelected ||
|
||||
settingsComponent.isChatGPTOptionSelected() != settings.isChatGPTOptionSelected;
|
||||
}
|
||||
|
|
@ -46,6 +47,7 @@ public class SettingsConfigurable implements Configurable {
|
|||
settings.accessToken = settingsComponent.getAccessToken();
|
||||
settings.apiKey = settingsComponent.getApiKey();
|
||||
settings.reverseProxyUrl = settingsComponent.getReverseProxyUrl();
|
||||
settings.baseModel = settingsComponent.getBaseModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -56,6 +58,7 @@ public class SettingsConfigurable implements Configurable {
|
|||
settingsComponent.setAccessToken(settings.accessToken);
|
||||
settingsComponent.setApiKey(settings.apiKey);
|
||||
settingsComponent.setReverseProxyUrl(settings.reverseProxyUrl);
|
||||
settingsComponent.setBaseModel(settings.baseModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ 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 ee.carlrobert.chatgpt.client.BaseModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
|
@ -17,6 +18,7 @@ public class SettingsState implements PersistentStateComponent<SettingsState> {
|
|||
public String apiKey = "";
|
||||
public String accessToken = "";
|
||||
public String reverseProxyUrl = "";
|
||||
public BaseModel baseModel = BaseModel.DAVINCI;
|
||||
public boolean isGPTOptionSelected = true;
|
||||
public boolean isChatGPTOptionSelected = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue