mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-08 01:42:09 +00:00
1.2.0 - 🔥 Add support for the official ChatGPT API (closes #10)
This commit is contained in:
parent
fa1e2a486b
commit
a2ea5a0333
40 changed files with 713 additions and 305 deletions
|
|
@ -1,14 +1,12 @@
|
|||
package ee.carlrobert.chatgpt.client;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ApiRequestDetails {
|
||||
|
||||
private final String url;
|
||||
private final Map<String, Object> body;
|
||||
private final Object body;
|
||||
private final String token;
|
||||
|
||||
public ApiRequestDetails(String url, Map<String, Object> body, String token) {
|
||||
public ApiRequestDetails(String url, Object body, String token) {
|
||||
this.url = url;
|
||||
this.body = body;
|
||||
this.token = token;
|
||||
|
|
@ -18,7 +16,7 @@ public class ApiRequestDetails {
|
|||
return url;
|
||||
}
|
||||
|
||||
public Map<String, Object> getBody() {
|
||||
public Object getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ 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)");
|
||||
DAVINCI("text-davinci-003", "Davinci - Most powerful (Default)"),
|
||||
CHATGPT("gpt-3.5-turbo", "ChatGPT - Most recent and capable model (Default)"),
|
||||
CHATGPT_SNAPSHOT("gpt-3.5-turbo-0301", "ChatGPT - Snapshot of gpt-3.5-turbo from March 1st 2023");
|
||||
|
||||
private final String model;
|
||||
private final String description;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
package ee.carlrobert.chatgpt.client;
|
||||
|
||||
import ee.carlrobert.chatgpt.client.chatgpt.ChatGPTClient;
|
||||
import ee.carlrobert.chatgpt.client.gpt.GPTClient;
|
||||
import ee.carlrobert.chatgpt.client.unofficial.UnofficialChatGPTClient;
|
||||
import ee.carlrobert.chatgpt.client.official.chat.ChatCompletionClient;
|
||||
import ee.carlrobert.chatgpt.client.official.text.TextCompletionClient;
|
||||
import ee.carlrobert.chatgpt.ide.settings.SettingsState;
|
||||
|
||||
public class ClientFactory {
|
||||
|
||||
public Client getClient() {
|
||||
if (SettingsState.getInstance().isGPTOptionSelected) {
|
||||
return GPTClient.getInstance();
|
||||
if (SettingsState.getInstance().isChatCompletionOptionSelected) {
|
||||
return ChatCompletionClient.getInstance();
|
||||
}
|
||||
return TextCompletionClient.getInstance();
|
||||
}
|
||||
return ChatGPTClient.getInstance();
|
||||
return UnofficialChatGPTClient.getInstance();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponseError {
|
||||
|
||||
private ChatGPTResponseErrorDetails detail;
|
||||
|
||||
public ChatGPTResponseErrorDetails getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
public void setDetail(ChatGPTResponseErrorDetails detail) {
|
||||
this.detail = detail;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponseMessage {
|
||||
|
||||
private String id;
|
||||
private ChatGPTResponseMessageAuthor author;
|
||||
private ChatGPTResponseMessageContent content;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ChatGPTResponseMessageAuthor getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(ChatGPTResponseMessageAuthor author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public ChatGPTResponseMessageContent getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(ChatGPTResponseMessageContent content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
package ee.carlrobert.chatgpt.client.gpt;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
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.BodySubscriber;
|
||||
import java.net.http.HttpResponse.ResponseInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class GPTClient extends Client {
|
||||
|
||||
private static final List<Map.Entry<String, String>> queries = new ArrayList<>();
|
||||
private static GPTClient instance;
|
||||
|
||||
private GPTClient() {
|
||||
}
|
||||
|
||||
public static GPTClient getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new GPTClient();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void clearPreviousSession() {
|
||||
queries.clear();
|
||||
}
|
||||
|
||||
protected ApiRequestDetails getRequestDetails(String prompt) {
|
||||
return new ApiRequestDetails(
|
||||
format("https://api.openai.com/v1/engines/%s/completions", SettingsState.getInstance().baseModel.getModel()),
|
||||
Map.of(
|
||||
"stop", List.of(" Human:", " AI:"),
|
||||
"prompt", buildPrompt(prompt),
|
||||
"max_tokens", 1000,
|
||||
"temperature", 0.9,
|
||||
"best_of", 1,
|
||||
"frequency_penalty", 0,
|
||||
"presence_penalty", 0.6,
|
||||
"top_p", 1,
|
||||
"stream", true
|
||||
),
|
||||
SettingsState.getInstance().apiKey);
|
||||
}
|
||||
|
||||
protected BodySubscriber<Void> subscribe(
|
||||
ResponseInfo responseInfo,
|
||||
Consumer<String> onMessageReceived,
|
||||
Runnable onComplete) {
|
||||
if (responseInfo.statusCode() == 200) {
|
||||
return new GPTBodySubscriber(
|
||||
onMessageReceived,
|
||||
finalMsg -> {
|
||||
queries.add(Map.entry(super.userPrompt, finalMsg));
|
||||
onComplete.run();
|
||||
});
|
||||
} else {
|
||||
handleError(responseInfo, onMessageReceived, onComplete);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleError(
|
||||
ResponseInfo responseInfo,
|
||||
Consumer<String> onMessageReceived,
|
||||
Runnable onComplete) {
|
||||
try {
|
||||
if (responseInfo.statusCode() == 401) {
|
||||
onMessageReceived.accept("Incorrect API key provided.\n" +
|
||||
"You can find your API key at https://platform.openai.com/account/api-keys.");
|
||||
throw new IllegalArgumentException();
|
||||
} else if (responseInfo.statusCode() == 429) {
|
||||
onMessageReceived.accept("You exceeded your current quota, please check your plan and billing details.");
|
||||
throw new RuntimeException("Insufficient quota");
|
||||
} else {
|
||||
onMessageReceived.accept("Something went wrong. Please try again later.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} finally {
|
||||
onComplete.run();
|
||||
}
|
||||
}
|
||||
|
||||
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.\n" +
|
||||
"Answer in a markdown language, code blocks should contain language whenever possible.\n");
|
||||
}
|
||||
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 = getBasePrompt();
|
||||
queries.forEach(query ->
|
||||
basePrompt.append("Human: ")
|
||||
.append(query.getKey())
|
||||
.append("\n")
|
||||
.append("AI: ")
|
||||
.append(query.getValue())
|
||||
.append("\n"));
|
||||
basePrompt.append("Human: ")
|
||||
.append(prompt)
|
||||
.append("\n")
|
||||
.append("AI: ")
|
||||
.append("\n");
|
||||
return basePrompt.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package ee.carlrobert.chatgpt.client.official;
|
||||
|
||||
import ee.carlrobert.chatgpt.client.Client;
|
||||
import java.net.http.HttpResponse.BodySubscriber;
|
||||
import java.net.http.HttpResponse.ResponseInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class CompletionClient extends Client {
|
||||
|
||||
protected static final List<Map.Entry<String, String>> queries = new ArrayList<>();
|
||||
|
||||
protected abstract CompletionSubscriber createSubscriber(
|
||||
Consumer<String> responseConsumer,
|
||||
Consumer<String> onCompleteCallback);
|
||||
|
||||
protected BodySubscriber<Void> subscribe(
|
||||
ResponseInfo responseInfo,
|
||||
Consumer<String> onMessageReceived,
|
||||
Runnable onComplete) {
|
||||
if (responseInfo.statusCode() == 200) {
|
||||
return createSubscriber(onMessageReceived, finalMsg -> {
|
||||
queries.add(Map.entry(super.userPrompt, finalMsg));
|
||||
onComplete.run();
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
handleError(responseInfo, onMessageReceived);
|
||||
return null;
|
||||
} finally {
|
||||
onComplete.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleError(ResponseInfo responseInfo, Consumer<String> onMessageReceived) {
|
||||
if (responseInfo.statusCode() == 401) {
|
||||
onMessageReceived.accept("Incorrect API key provided.\n" +
|
||||
"You can find your API key at https://platform.openai.com/account/api-keys.");
|
||||
throw new IllegalArgumentException();
|
||||
} else if (responseInfo.statusCode() == 429) {
|
||||
onMessageReceived.accept("You exceeded your current quota, please check your plan and billing details.");
|
||||
throw new RuntimeException("Insufficient quota");
|
||||
} else {
|
||||
onMessageReceived.accept("Something went wrong. Please try again later.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearPreviousSession() {
|
||||
queries.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
package ee.carlrobert.chatgpt.client.gpt;
|
||||
package ee.carlrobert.chatgpt.client.official;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import ee.carlrobert.chatgpt.client.ApiResponse;
|
||||
import ee.carlrobert.chatgpt.client.Subscriber;
|
||||
import ee.carlrobert.chatgpt.client.gpt.response.GPTResponse;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class GPTBodySubscriber extends Subscriber<GPTResponse> {
|
||||
public abstract class CompletionSubscriber extends Subscriber<ApiResponse> {
|
||||
|
||||
private final Consumer<String> onCompleteCallback;
|
||||
private final StringBuilder messageBuilder = new StringBuilder();
|
||||
private final Consumer<String> onCompleteCallback;
|
||||
private final Consumer<String> responseConsumer;
|
||||
|
||||
public GPTBodySubscriber(
|
||||
protected abstract String getMessage(String responsePayload) throws JsonProcessingException;
|
||||
|
||||
public CompletionSubscriber(
|
||||
Consumer<String> responseConsumer,
|
||||
Consumer<String> onCompleteCallback) {
|
||||
this.responseConsumer = responseConsumer;
|
||||
|
|
@ -30,8 +31,7 @@ public class GPTBodySubscriber extends Subscriber<GPTResponse> {
|
|||
protected void send(String responsePayload, String token) {
|
||||
try {
|
||||
if (!responsePayload.isEmpty()) {
|
||||
var response = new ObjectMapper().readValue(responsePayload, GPTResponse.class);
|
||||
var message = response.getChoices().get(0).getText();
|
||||
var message = getMessage(responsePayload);
|
||||
messageBuilder.append(message);
|
||||
this.responseConsumer.accept(message);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package ee.carlrobert.chatgpt.client.official.chat;
|
||||
|
||||
import ee.carlrobert.chatgpt.client.ApiRequestDetails;
|
||||
import ee.carlrobert.chatgpt.client.official.CompletionClient;
|
||||
import ee.carlrobert.chatgpt.client.official.CompletionSubscriber;
|
||||
import ee.carlrobert.chatgpt.client.official.chat.request.Request;
|
||||
import ee.carlrobert.chatgpt.client.official.chat.request.RequestMessage;
|
||||
import ee.carlrobert.chatgpt.ide.settings.SettingsState;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChatCompletionClient extends CompletionClient {
|
||||
|
||||
private static ChatCompletionClient instance;
|
||||
|
||||
private ChatCompletionClient() {
|
||||
}
|
||||
|
||||
public static ChatCompletionClient getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ChatCompletionClient();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected ApiRequestDetails getRequestDetails(String prompt) {
|
||||
var messages = new ArrayList<RequestMessage>();
|
||||
messages.add(new RequestMessage(
|
||||
"system",
|
||||
"You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible."));
|
||||
queries.forEach(query -> {
|
||||
messages.add(new RequestMessage("user", query.getKey()));
|
||||
messages.add(new RequestMessage("assistant", query.getValue()));
|
||||
});
|
||||
messages.add(new RequestMessage("user", prompt));
|
||||
|
||||
return new ApiRequestDetails(
|
||||
"https://api.openai.com/v1/chat/completions",
|
||||
new Request(
|
||||
SettingsState.getInstance().chatCompletionBaseModel.getModel(),
|
||||
true,
|
||||
messages
|
||||
),
|
||||
SettingsState.getInstance().apiKey);
|
||||
}
|
||||
|
||||
protected CompletionSubscriber createSubscriber(
|
||||
Consumer<String> responseConsumer,
|
||||
Consumer<String> onCompleteCallback) {
|
||||
return new ChatCompletionSubscriber(responseConsumer, onCompleteCallback);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package ee.carlrobert.chatgpt.client.official.chat;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import ee.carlrobert.chatgpt.client.official.CompletionSubscriber;
|
||||
import ee.carlrobert.chatgpt.client.official.chat.response.Response;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChatCompletionSubscriber extends CompletionSubscriber {
|
||||
|
||||
public ChatCompletionSubscriber(Consumer<String> responseConsumer, Consumer<String> onCompleteCallback) {
|
||||
super(responseConsumer, onCompleteCallback);
|
||||
}
|
||||
|
||||
protected String getMessage(String responsePayload) throws JsonProcessingException {
|
||||
return new ObjectMapper()
|
||||
.readValue(responsePayload, Response.class)
|
||||
.getChoices()
|
||||
.get(0)
|
||||
.getDelta()
|
||||
.getContent();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package ee.carlrobert.chatgpt.client.official.chat.request;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Request {
|
||||
|
||||
private final String model;
|
||||
private final boolean stream;
|
||||
private final List<RequestMessage> messages;
|
||||
|
||||
public Request(String model, boolean stream, List<RequestMessage> messages) {
|
||||
this.model = model;
|
||||
this.stream = stream;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public boolean isStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public List<RequestMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package ee.carlrobert.chatgpt.client.official.chat.request;
|
||||
|
||||
public class RequestMessage {
|
||||
|
||||
private final String role;
|
||||
private final String content;
|
||||
|
||||
public RequestMessage(String role, String content) {
|
||||
this.role = role;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
package ee.carlrobert.chatgpt.client.gpt.response;
|
||||
package ee.carlrobert.chatgpt.client.official.chat.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import ee.carlrobert.chatgpt.client.ApiResponse;
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class GPTResponse implements ApiResponse {
|
||||
public class Response implements ApiResponse {
|
||||
|
||||
private String id;
|
||||
private List<GPTResponseChoice> choices;
|
||||
private List<ResponseChoice> choices;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
|
@ -18,11 +18,11 @@ public class GPTResponse implements ApiResponse {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public List<GPTResponseChoice> getChoices() {
|
||||
public List<ResponseChoice> getChoices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
public void setChoices(List<GPTResponseChoice> choices) {
|
||||
public void setChoices(List<ResponseChoice> choices) {
|
||||
this.choices = choices;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package ee.carlrobert.chatgpt.client.official.chat.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ResponseChoice {
|
||||
|
||||
private ResponseChoiceDelta delta;
|
||||
|
||||
public ResponseChoiceDelta getDelta() {
|
||||
return delta;
|
||||
}
|
||||
|
||||
public void setDelta(ResponseChoiceDelta delta) {
|
||||
this.delta = delta;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package ee.carlrobert.chatgpt.client.official.chat.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ResponseChoiceDelta {
|
||||
|
||||
private String role;
|
||||
private String content;
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package ee.carlrobert.chatgpt.client.official.text;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import ee.carlrobert.chatgpt.client.ApiRequestDetails;
|
||||
import ee.carlrobert.chatgpt.client.BaseModel;
|
||||
import ee.carlrobert.chatgpt.client.official.CompletionClient;
|
||||
import ee.carlrobert.chatgpt.client.official.CompletionSubscriber;
|
||||
import ee.carlrobert.chatgpt.ide.settings.SettingsState;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TextCompletionClient extends CompletionClient {
|
||||
|
||||
private static TextCompletionClient instance;
|
||||
|
||||
private TextCompletionClient() {
|
||||
}
|
||||
|
||||
public static TextCompletionClient getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new TextCompletionClient();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected ApiRequestDetails getRequestDetails(String prompt) {
|
||||
return new ApiRequestDetails(
|
||||
format("https://api.openai.com/v1/engines/%s/completions",
|
||||
SettingsState.getInstance().textCompletionBaseModel.getModel()),
|
||||
Map.of(
|
||||
"stop", List.of(" Human:", " AI:"),
|
||||
"prompt", buildPrompt(prompt),
|
||||
"max_tokens", 1000,
|
||||
"temperature", 0.9,
|
||||
"best_of", 1,
|
||||
"frequency_penalty", 0,
|
||||
"presence_penalty", 0.6,
|
||||
"top_p", 1,
|
||||
"stream", true
|
||||
),
|
||||
SettingsState.getInstance().apiKey);
|
||||
}
|
||||
|
||||
protected CompletionSubscriber createSubscriber(
|
||||
Consumer<String> responseConsumer,
|
||||
Consumer<String> onCompleteCallback) {
|
||||
return new TextCompletionSubscriber(responseConsumer, onCompleteCallback);
|
||||
}
|
||||
|
||||
private StringBuilder getBasePrompt() {
|
||||
var isDavinciModel = SettingsState.getInstance().textCompletionBaseModel == BaseModel.DAVINCI;
|
||||
if (isDavinciModel) {
|
||||
return new StringBuilder(
|
||||
"You are ChatGPT, a large language model trained by OpenAI.\n" +
|
||||
"Answer in a markdown language, code blocks should contain language whenever possible.\n");
|
||||
}
|
||||
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 = getBasePrompt();
|
||||
queries.forEach(query ->
|
||||
basePrompt.append("Human: ")
|
||||
.append(query.getKey())
|
||||
.append("\n")
|
||||
.append("AI: ")
|
||||
.append(query.getValue())
|
||||
.append("\n"));
|
||||
basePrompt.append("Human: ")
|
||||
.append(prompt)
|
||||
.append("\n")
|
||||
.append("AI: ")
|
||||
.append("\n");
|
||||
return basePrompt.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package ee.carlrobert.chatgpt.client.official.text;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import ee.carlrobert.chatgpt.client.official.CompletionSubscriber;
|
||||
import ee.carlrobert.chatgpt.client.official.text.response.Response;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TextCompletionSubscriber extends CompletionSubscriber {
|
||||
|
||||
public TextCompletionSubscriber(Consumer<String> responseConsumer, Consumer<String> onCompleteCallback) {
|
||||
super(responseConsumer, onCompleteCallback);
|
||||
}
|
||||
|
||||
protected String getMessage(String responsePayload) throws JsonProcessingException {
|
||||
return new ObjectMapper()
|
||||
.readValue(responsePayload, Response.class)
|
||||
.getChoices()
|
||||
.get(0)
|
||||
.getText();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package ee.carlrobert.chatgpt.client.official.text.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import ee.carlrobert.chatgpt.client.ApiResponse;
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Response implements ApiResponse {
|
||||
|
||||
private String id;
|
||||
private List<ResponseChoice> choices;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<ResponseChoice> getChoices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
public void setChoices(List<ResponseChoice> choices) {
|
||||
this.choices = choices;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package ee.carlrobert.chatgpt.client.gpt.response;
|
||||
package ee.carlrobert.chatgpt.client.official.text.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class GPTResponseChoice {
|
||||
public class ResponseChoice {
|
||||
|
||||
private String text;
|
||||
@JsonProperty("finish_reason")
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt;
|
||||
package ee.carlrobert.chatgpt.client.unofficial;
|
||||
|
||||
import ee.carlrobert.chatgpt.client.ApiRequestDetails;
|
||||
import ee.carlrobert.chatgpt.client.Client;
|
||||
import ee.carlrobert.chatgpt.client.chatgpt.response.ChatGPTResponse;
|
||||
import ee.carlrobert.chatgpt.client.unofficial.response.Response;
|
||||
import ee.carlrobert.chatgpt.ide.settings.SettingsState;
|
||||
import java.net.http.HttpResponse.BodySubscriber;
|
||||
import java.net.http.HttpResponse.ResponseInfo;
|
||||
|
|
@ -12,17 +12,17 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChatGPTClient extends Client {
|
||||
public class UnofficialChatGPTClient extends Client {
|
||||
|
||||
private static ChatGPTClient instance;
|
||||
private static ChatGPTResponse lastReceivedResponse;
|
||||
private static UnofficialChatGPTClient instance;
|
||||
private static Response lastReceivedResponse;
|
||||
|
||||
private ChatGPTClient() {
|
||||
private UnofficialChatGPTClient() {
|
||||
}
|
||||
|
||||
public static ChatGPTClient getInstance() {
|
||||
public static UnofficialChatGPTClient getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ChatGPTClient();
|
||||
instance = new UnofficialChatGPTClient();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ public class ChatGPTClient extends Client {
|
|||
Consumer<String> onMessageReceived,
|
||||
Runnable onComplete) {
|
||||
if (responseInfo.statusCode() == 200) {
|
||||
return new ChatGPTBodySubscriber(
|
||||
return new UnofficialChatGPTSubscriber(
|
||||
onMessageReceived,
|
||||
response -> {
|
||||
lastReceivedResponse = response;
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt;
|
||||
package ee.carlrobert.chatgpt.client.unofficial;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import ee.carlrobert.chatgpt.client.Subscriber;
|
||||
import ee.carlrobert.chatgpt.client.chatgpt.response.ChatGPTResponse;
|
||||
import ee.carlrobert.chatgpt.client.chatgpt.response.ChatGPTResponseDetail;
|
||||
import ee.carlrobert.chatgpt.client.chatgpt.response.ChatGPTResponseError;
|
||||
import ee.carlrobert.chatgpt.client.unofficial.response.Response;
|
||||
import ee.carlrobert.chatgpt.client.unofficial.response.ResponseDetail;
|
||||
import ee.carlrobert.chatgpt.client.unofficial.response.ResponseError;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ChatGPTBodySubscriber extends Subscriber<ChatGPTResponse> {
|
||||
public class UnofficialChatGPTSubscriber extends Subscriber<Response> {
|
||||
|
||||
private final Consumer<String> responseConsumer;
|
||||
private final Consumer<ChatGPTResponse> onCompleteCallback;
|
||||
private final Consumer<Response> onCompleteCallback;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private ChatGPTResponse lastReceivedResponse;
|
||||
private Response lastReceivedResponse;
|
||||
|
||||
public ChatGPTBodySubscriber(
|
||||
public UnofficialChatGPTSubscriber(
|
||||
Consumer<String> responseConsumer,
|
||||
Consumer<ChatGPTResponse> onCompleteCallback) {
|
||||
Consumer<Response> onCompleteCallback) {
|
||||
this.responseConsumer = responseConsumer;
|
||||
this.onCompleteCallback = onCompleteCallback;
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ public class ChatGPTBodySubscriber extends Subscriber<ChatGPTResponse> {
|
|||
protected void send(String responsePayload, String token) {
|
||||
if (!responsePayload.isEmpty() && isValidJson(responsePayload)) {
|
||||
try {
|
||||
var response = objectMapper.readValue(responsePayload, ChatGPTResponse.class);
|
||||
var response = objectMapper.readValue(responsePayload, Response.class);
|
||||
var author = response.getMessage().getAuthor();
|
||||
if (author != null && "assistant".equals(author.getRole())) {
|
||||
var message = response.getFullMessage();
|
||||
|
|
@ -51,7 +51,7 @@ public class ChatGPTBodySubscriber extends Subscriber<ChatGPTResponse> {
|
|||
} else {
|
||||
if (token != null && !token.isEmpty() && isValidJson(token)) {
|
||||
try {
|
||||
var response = objectMapper.readValue(token, ChatGPTResponseDetail.class);
|
||||
var response = objectMapper.readValue(token, ResponseDetail.class);
|
||||
this.responseConsumer.accept(response.getDetail());
|
||||
} catch (JsonProcessingException e) {
|
||||
tryProcessingErrorResponse(token);
|
||||
|
|
@ -62,7 +62,7 @@ public class ChatGPTBodySubscriber extends Subscriber<ChatGPTResponse> {
|
|||
|
||||
private void tryProcessingErrorResponse(String jsonPayload) {
|
||||
try {
|
||||
var error = objectMapper.readValue(jsonPayload, ChatGPTResponseError.class);
|
||||
var error = objectMapper.readValue(jsonPayload, ResponseError.class);
|
||||
if ("invalid_api_key".equals(error.getDetail().getCode())) {
|
||||
responseConsumer.accept(error.getDetail().getMessage());
|
||||
}
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ee.carlrobert.chatgpt.client.ApiResponse;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponse implements ApiResponse {
|
||||
public class Response implements ApiResponse {
|
||||
|
||||
private ChatGPTResponseMessage message;
|
||||
private ResponseMessage message;
|
||||
@JsonProperty("conversation_id")
|
||||
private String conversationId;
|
||||
|
||||
public ChatGPTResponseMessage getMessage() {
|
||||
public ResponseMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(ChatGPTResponseMessage message) {
|
||||
public void setMessage(ResponseMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponseDetail {
|
||||
public class ResponseDetail {
|
||||
|
||||
private String detail;
|
||||
|
||||
public String getDetail() {
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ResponseError {
|
||||
|
||||
private ResponseErrorDetails detail;
|
||||
|
||||
public ResponseErrorDetails getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
public void setDetail(ResponseErrorDetails detail) {
|
||||
this.detail = detail;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponseErrorDetails {
|
||||
public class ResponseErrorDetails {
|
||||
|
||||
private String message;
|
||||
private String type;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ResponseMessage {
|
||||
|
||||
private String id;
|
||||
private ResponseMessageAuthor author;
|
||||
private ResponseMessageContent content;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public ResponseMessageAuthor getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(ResponseMessageAuthor author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public ResponseMessageContent getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(ResponseMessageContent content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponseMessageAuthor {
|
||||
public class ResponseMessageAuthor {
|
||||
|
||||
private String role;
|
||||
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package ee.carlrobert.chatgpt.client.chatgpt.response;
|
||||
package ee.carlrobert.chatgpt.client.unofficial.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ChatGPTResponseMessageContent {
|
||||
public class ResponseMessageContent {
|
||||
|
||||
@JsonProperty("content_type")
|
||||
private String contentType;
|
||||
|
|
@ -8,13 +8,8 @@ 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,
|
||||
});
|
||||
public BaseModelComboBox(BaseModel[] options, BaseModel selectedModel) {
|
||||
super(options);
|
||||
setSelectedItem(selectedModel);
|
||||
setRenderer(getBasicComboBoxRenderer());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import ee.carlrobert.chatgpt.client.BaseModel;
|
|||
import java.awt.Desktop;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
|
|
@ -22,22 +23,40 @@ public class SettingsComponent {
|
|||
|
||||
private final JPanel mainPanel;
|
||||
private final JBTextField apiKeyField;
|
||||
private final JComboBox<BaseModel> baseModelComboBox;
|
||||
private final JComboBox<BaseModel> chatCompletionBaseModelComboBox;
|
||||
private final JComboBox<BaseModel> textCompletionBaseModelComboBox;
|
||||
private final JComboBox<String> reverseProxyComboBox;
|
||||
private final JBTextField accessTokenField;
|
||||
private final JBRadioButton useGPTRadioButton;
|
||||
private final JBRadioButton useChatCompletionRadioButton;
|
||||
private final JBRadioButton useTextCompletionRadioButton;
|
||||
private final JBRadioButton useChatGPTRadioButton;
|
||||
|
||||
public SettingsComponent(SettingsState settings) {
|
||||
apiKeyField = new JBTextField(settings.apiKey);
|
||||
baseModelComboBox = new BaseModelComboBox(settings.baseModel);
|
||||
chatCompletionBaseModelComboBox = new BaseModelComboBox(
|
||||
new BaseModel[] {
|
||||
BaseModel.CHATGPT,
|
||||
BaseModel.CHATGPT_SNAPSHOT,
|
||||
},
|
||||
settings.textCompletionBaseModel);
|
||||
textCompletionBaseModelComboBox = new BaseModelComboBox(
|
||||
new BaseModel[] {
|
||||
BaseModel.DAVINCI,
|
||||
BaseModel.CURIE,
|
||||
BaseModel.BABBAGE,
|
||||
BaseModel.ADA,
|
||||
},
|
||||
settings.textCompletionBaseModel);
|
||||
reverseProxyComboBox = new JComboBox<>(new String[] {
|
||||
"https://chat.duti.tech/api/conversation",
|
||||
"https://gpt.pawan.krd/backend-api/conversation"
|
||||
});
|
||||
accessTokenField = new JBTextField(settings.accessToken, 1);
|
||||
useGPTRadioButton = new JBRadioButton("Use OpenAI's official GPT3 API", settings.isGPTOptionSelected);
|
||||
useChatGPTRadioButton = new JBRadioButton("Use ChatGPT's unofficial backend API", settings.isChatGPTOptionSelected);
|
||||
useGPTRadioButton = new JBRadioButton("Use OpenAI's official API", settings.isGPTOptionSelected);
|
||||
useChatCompletionRadioButton = new JBRadioButton("Use chat completion", settings.isChatCompletionOptionSelected);
|
||||
useTextCompletionRadioButton = new JBRadioButton("Use text completion", settings.isTextCompletionOptionSelected);
|
||||
useChatGPTRadioButton = new JBRadioButton("Use ChatGPT's unofficial API", settings.isChatGPTOptionSelected);
|
||||
mainPanel = FormBuilder.createFormBuilder()
|
||||
.addComponent(new TitledSeparator("Integration Preference"))
|
||||
.addComponent(createMainSelectionForm())
|
||||
|
|
@ -82,6 +101,22 @@ public class SettingsComponent {
|
|||
useGPTRadioButton.setSelected(isSelected);
|
||||
}
|
||||
|
||||
public boolean isChatCompletionOptionSelected() {
|
||||
return useChatCompletionRadioButton.isSelected();
|
||||
}
|
||||
|
||||
public void setUseChatCompletionSelected(boolean isSelected) {
|
||||
useChatCompletionRadioButton.setSelected(isSelected);
|
||||
}
|
||||
|
||||
public boolean isTextCompletionOptionSelected() {
|
||||
return useTextCompletionRadioButton.isSelected();
|
||||
}
|
||||
|
||||
public void setUseTextCompletionSelected(boolean isSelected) {
|
||||
useTextCompletionRadioButton.setSelected(isSelected);
|
||||
}
|
||||
|
||||
public boolean isChatGPTOptionSelected() {
|
||||
return useChatGPTRadioButton.isSelected();
|
||||
}
|
||||
|
|
@ -98,21 +133,61 @@ public class SettingsComponent {
|
|||
reverseProxyComboBox.setSelectedItem(reverseProxyUrl);
|
||||
}
|
||||
|
||||
public BaseModel getBaseModel() {
|
||||
return (BaseModel) baseModelComboBox.getSelectedItem();
|
||||
public BaseModel getTextCompletionBaseModel() {
|
||||
return (BaseModel) textCompletionBaseModelComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
public void setBaseModel(BaseModel baseModel) {
|
||||
baseModelComboBox.setSelectedItem(baseModel);
|
||||
public void setTextCompletionBaseModel(BaseModel baseModel) {
|
||||
textCompletionBaseModelComboBox.setSelectedItem(baseModel);
|
||||
}
|
||||
|
||||
public BaseModel getChatCompletionBaseModel() {
|
||||
return (BaseModel) chatCompletionBaseModelComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
public void setChatCompletionBaseModel(BaseModel baseModel) {
|
||||
chatCompletionBaseModelComboBox.setSelectedItem(baseModel);
|
||||
}
|
||||
|
||||
private JPanel createMainSelectionForm() {
|
||||
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();
|
||||
apiKeyFieldPanel.setBorder(JBUI.Borders.emptyLeft(8));
|
||||
|
||||
var chatCompletionModelsPanel = UI.PanelFactory.panel(chatCompletionBaseModelComboBox)
|
||||
.withLabel("Model:")
|
||||
.createPanel();
|
||||
chatCompletionModelsPanel.setBorder(JBUI.Borders.emptyLeft(24));
|
||||
|
||||
var textCompletionModelsPanel = UI.PanelFactory.panel(textCompletionBaseModelComboBox)
|
||||
.withLabel("Model:")
|
||||
.createPanel();
|
||||
textCompletionModelsPanel.setBorder(JBUI.Borders.emptyLeft(24));
|
||||
|
||||
var gptRadioPanel = FormBuilder.createFormBuilder()
|
||||
.addComponent(apiKeyFieldPanel)
|
||||
.addComponent(UI.PanelFactory.panel(useChatCompletionRadioButton)
|
||||
.withComment("OpenAI’s most advanced language model")
|
||||
.createPanel())
|
||||
.addComponent(chatCompletionModelsPanel)
|
||||
.addVerticalGap(8)
|
||||
.addComponent(UI.PanelFactory.panel(useTextCompletionRadioButton)
|
||||
.withComment("Best for high-quality texts")
|
||||
.createPanel())
|
||||
.addComponent(textCompletionModelsPanel)
|
||||
.getPanel();
|
||||
gptRadioPanel.setBorder(JBUI.Borders.emptyLeft(16));
|
||||
|
||||
|
||||
var panel = FormBuilder.createFormBuilder()
|
||||
.addVerticalGap(8)
|
||||
.addComponent(UI.PanelFactory.panel(useGPTRadioButton)
|
||||
.withComment("Fast and robust, requires API key")
|
||||
.createPanel())
|
||||
.addComponent(createFirstSelectionForm())
|
||||
.addComponent(gptRadioPanel)
|
||||
.addVerticalGap(8)
|
||||
.addComponent(UI.PanelFactory.panel(useChatGPTRadioButton)
|
||||
.withComment("Slow and free, more suitable for conversational tasks, rate-limited")
|
||||
|
|
@ -123,27 +198,6 @@ public class SettingsComponent {
|
|||
return panel;
|
||||
}
|
||||
|
||||
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(baseModelPanel)
|
||||
.addVerticalGap(8)
|
||||
.addComponent(apiKeyFieldPanel)
|
||||
.getPanel();
|
||||
panel.setBorder(JBUI.Borders.emptyLeft(24));
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createSecondSelectionForm() {
|
||||
var reverseProxyUrlPanel = UI.PanelFactory.panel(reverseProxyComboBox)
|
||||
.withLabel("Reverse proxy url:")
|
||||
|
|
@ -181,11 +235,35 @@ public class SettingsComponent {
|
|||
myButtonGroup.add(useChatGPTRadioButton);
|
||||
useGPTRadioButton.addActionListener(e -> registerFields(false));
|
||||
useChatGPTRadioButton.addActionListener(e -> registerFields(true));
|
||||
|
||||
ButtonGroup completionButtonGroup = new ButtonGroup();
|
||||
completionButtonGroup.add(useChatCompletionRadioButton);
|
||||
completionButtonGroup.add(useTextCompletionRadioButton);
|
||||
useChatCompletionRadioButton.addActionListener(e -> {
|
||||
chatCompletionBaseModelComboBox.setEnabled(true);
|
||||
textCompletionBaseModelComboBox.setEnabled(false);
|
||||
});
|
||||
useTextCompletionRadioButton.addActionListener(e -> {
|
||||
chatCompletionBaseModelComboBox.setEnabled(false);
|
||||
textCompletionBaseModelComboBox.setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
private void registerFields(boolean isUseChatGPTOption) {
|
||||
apiKeyField.setEnabled(!isUseChatGPTOption);
|
||||
baseModelComboBox.setEnabled(!isUseChatGPTOption);
|
||||
if (isUseChatGPTOption) {
|
||||
List.of(
|
||||
useChatCompletionRadioButton,
|
||||
useTextCompletionRadioButton,
|
||||
chatCompletionBaseModelComboBox,
|
||||
textCompletionBaseModelComboBox
|
||||
).forEach(it -> it.setEnabled(false));
|
||||
} else {
|
||||
useChatCompletionRadioButton.setEnabled(true);
|
||||
useTextCompletionRadioButton.setEnabled(true);
|
||||
chatCompletionBaseModelComboBox.setEnabled(useChatCompletionRadioButton.isSelected());
|
||||
textCompletionBaseModelComboBox.setEnabled(useTextCompletionRadioButton.isSelected());
|
||||
}
|
||||
accessTokenField.setEnabled(isUseChatGPTOption);
|
||||
reverseProxyComboBox.setEnabled(isUseChatGPTOption);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class SettingsConfigurable implements Configurable {
|
|||
@Nls(capitalization = Nls.Capitalization.Title)
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "ChatGPT: Settings";
|
||||
return "CodeGPT: Settings";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -34,8 +34,11 @@ 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.getChatCompletionBaseModel().equals(settings.chatCompletionBaseModel) ||
|
||||
!settingsComponent.getTextCompletionBaseModel().equals(settings.textCompletionBaseModel) ||
|
||||
settingsComponent.isGPTOptionSelected() != settings.isGPTOptionSelected ||
|
||||
settingsComponent.isChatCompletionOptionSelected() != settings.isChatCompletionOptionSelected ||
|
||||
settingsComponent.isTextCompletionOptionSelected() != settings.isTextCompletionOptionSelected ||
|
||||
settingsComponent.isChatGPTOptionSelected() != settings.isChatGPTOptionSelected;
|
||||
}
|
||||
|
||||
|
|
@ -47,18 +50,24 @@ public class SettingsConfigurable implements Configurable {
|
|||
settings.accessToken = settingsComponent.getAccessToken();
|
||||
settings.apiKey = settingsComponent.getApiKey();
|
||||
settings.reverseProxyUrl = settingsComponent.getReverseProxyUrl();
|
||||
settings.baseModel = settingsComponent.getBaseModel();
|
||||
settings.chatCompletionBaseModel = settingsComponent.getChatCompletionBaseModel();
|
||||
settings.isChatCompletionOptionSelected = settingsComponent.isChatCompletionOptionSelected();
|
||||
settings.isTextCompletionOptionSelected = settingsComponent.isTextCompletionOptionSelected();
|
||||
settings.textCompletionBaseModel = settingsComponent.getTextCompletionBaseModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
var settings = SettingsState.getInstance();
|
||||
settingsComponent.setUseGPTOptionSelected(settings.isGPTOptionSelected);
|
||||
settingsComponent.setUseChatCompletionSelected(settings.isChatCompletionOptionSelected);
|
||||
settingsComponent.setUseTextCompletionSelected(settings.isTextCompletionOptionSelected);
|
||||
settingsComponent.setUseChatGPTOptionSelected(settings.isChatGPTOptionSelected);
|
||||
settingsComponent.setAccessToken(settings.accessToken);
|
||||
settingsComponent.setApiKey(settings.apiKey);
|
||||
settingsComponent.setReverseProxyUrl(settings.reverseProxyUrl);
|
||||
settingsComponent.setBaseModel(settings.baseModel);
|
||||
settingsComponent.setChatCompletionBaseModel(settings.chatCompletionBaseModel);
|
||||
settingsComponent.setTextCompletionBaseModel(settings.textCompletionBaseModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -11,16 +11,19 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
@State(
|
||||
name = "ee.carlrobert.chatgpt.ide.settings.SettingsState",
|
||||
storages = @Storage("SdkSettingsPlugin.xml")
|
||||
storages = @Storage("CodeGPTSettings.xml")
|
||||
)
|
||||
public class SettingsState implements PersistentStateComponent<SettingsState> {
|
||||
|
||||
public String apiKey = "";
|
||||
public String accessToken = "";
|
||||
public String reverseProxyUrl = "";
|
||||
public BaseModel baseModel = BaseModel.DAVINCI;
|
||||
public BaseModel textCompletionBaseModel = BaseModel.DAVINCI;
|
||||
public BaseModel chatCompletionBaseModel = BaseModel.CHATGPT;
|
||||
public boolean isGPTOptionSelected = true;
|
||||
public boolean isChatGPTOptionSelected = false;
|
||||
public boolean isChatCompletionOptionSelected = true;
|
||||
public boolean isTextCompletionOptionSelected = false;
|
||||
|
||||
public static SettingsState getInstance() {
|
||||
return ApplicationManager.getApplication().getService(SettingsState.class);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class ToolWindowService implements LafManagerListener {
|
|||
}
|
||||
|
||||
public ToolWindow getToolWindow(@NotNull Project project) {
|
||||
return ToolWindowManager.getInstance(project).getToolWindow("ChatGPT");
|
||||
return ToolWindowManager.getInstance(project).getToolWindow("CodeGPT");
|
||||
}
|
||||
|
||||
public void paintUserMessage(String userMessage) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue