Skip to content

Commit

Permalink
Fix some problems
Browse files Browse the repository at this point in the history
Details:
Fix #107
Fix the problem of GPT 3.5 Turbo displaying blank
Fix the UI flicker problem.
  • Loading branch information
obiscr committed Mar 14, 2023
1 parent 3dd0d79 commit 3e3b220
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 158 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repositories {
}

dependencies {
implementation("com.alibaba.fastjson2:fastjson2:2.0.17")
implementation("com.google.code.gson:gson:2.10.1")
implementation("cn.hutool:hutool-http:5.8.12")
implementation("com.obiscr:openai-auth:1.0.1")
implementation("com.squareup.okhttp3:okhttp:4.10.0")
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/com/obiscr/chatgpt/ChatGPTHandler.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
package com.obiscr.chatgpt;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.intellij.openapi.project.Project;
import com.obiscr.OpenAIProxy;
import com.obiscr.chatgpt.core.ConversationManager;
import com.obiscr.chatgpt.core.TokenManager;
import com.obiscr.chatgpt.core.builder.OfficialBuilder;
import com.obiscr.chatgpt.core.parser.OfficialParser;
import com.obiscr.chatgpt.settings.SettingConfiguration;
import com.obiscr.chatgpt.settings.OpenAISettingsState;
import com.obiscr.chatgpt.ui.MainPanel;
import com.obiscr.chatgpt.ui.MessageComponent;
import com.obiscr.chatgpt.util.HtmlUtil;
import com.obiscr.chatgpt.util.StringUtil;
import okhttp3.*;
import okhttp3.internal.http2.StreamResetException;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
Expand Down
88 changes: 65 additions & 23 deletions src/main/java/com/obiscr/chatgpt/GPT35TurboHandler.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package com.obiscr.chatgpt;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.obiscr.chatgpt.core.builder.OfficialBuilder;
import com.obiscr.OpenAIProxy;
import com.obiscr.chatgpt.core.parser.OfficialParser;
import com.obiscr.chatgpt.settings.OpenAISettingsState;
import com.obiscr.chatgpt.ui.MainPanel;
import com.obiscr.chatgpt.ui.MessageComponent;
import com.obiscr.chatgpt.ui.MessageGroupComponent;
import com.obiscr.chatgpt.util.StringUtil;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.Proxy;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

import java.net.Proxy;

Expand All @@ -22,42 +27,79 @@
public class GPT35TurboHandler extends AbstractHandler {
private static final Logger LOG = LoggerFactory.getLogger(GPT35TurboHandler.class);

public MessageComponent handle(MainPanel mainPanel, MessageComponent component, String question) {
public Call handle(MainPanel mainPanel, MessageComponent component, String question) {
MessageGroupComponent contentPanel = mainPanel.getContentPanel();

// Define the default system role
if (contentPanel.getMessages().isEmpty()) {
String text = contentPanel.getSystemRole();
contentPanel.getMessages().add(OfficialBuilder.systemMessage(text));
}

Call call = null;
RequestProvider provider = new RequestProvider().create(mainPanel, question);
try {
LOG.info("ChatGPT Request: question={}",question);
HttpResponse response = HttpUtil.createPost(provider.getUrl())
.headerMap(provider.getHeader(),true)
.setProxy(getProxy())
.body(provider.getData().getBytes(StandardCharsets.UTF_8)).executeAsync();
LOG.info("ChatGPT Response: answer={}",response.body());
if (response.getStatus() != 200) {
LOG.info("ChatGPT: Request failure. Url={}, response={}",provider.getUrl(), response.body());
component.setContent("Response failure, please try again. Error message: " + response.body());
mainPanel.aroundRequest(false);
return component;
LOG.info("GPT 3.5 Turbo Request: question={}",question);
Request request = new Request.Builder()
.url(provider.getUrl())
.headers(Headers.of(provider.getHeader()))
.post(RequestBody.create(provider.getData().getBytes(StandardCharsets.UTF_8),
MediaType.parse("application/json")))
.build();
OpenAISettingsState instance = OpenAISettingsState.getInstance();
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(Integer.parseInt(instance.connectionTimeout), TimeUnit.MILLISECONDS)
.readTimeout(Integer.parseInt(instance.readTimeout), TimeUnit.MILLISECONDS);
if (instance.enableProxy) {
Proxy proxy = getProxy();
builder.proxy(proxy);
}
OfficialParser.ParseResult parseResult = OfficialParser.
parseGPT35Turbo(response.body());
OkHttpClient httpClient = builder.build();
call = httpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
String errorMessage = StringUtil.isEmpty(e.getMessage())? "None" : e.getMessage();
if (e instanceof SocketException) {
LOG.info("GPT 3.5 Turbo: Stop generating");
component.setContent("Stop generating");
e.printStackTrace();
return;
}
LOG.error("GPT 3.5 Turbo Request failure. Url={}, error={}",
call.request().url(),
errorMessage);
errorMessage = "GPT 3.5 Turbo Request failure, cause: " + errorMessage;
component.setSourceContent(errorMessage);
component.setContent(errorMessage);
mainPanel.aroundRequest(false);
component.scrollToBottom();
}

mainPanel.getContentPanel().getMessages().add(OfficialBuilder.assistantMessage(parseResult.getSource()));
component.setSourceContent(parseResult.getSource());
component.setContent(parseResult.getHtml());
mainPanel.aroundRequest(false);
component.scrollToBottom();
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String responseMessage = response.body().string();
LOG.info("GPT 3.5 Turbo Response: answer={}",responseMessage);
if (response.code() != 200) {
LOG.info("GPT 3.5 Turbo: Request failure. Url={}, response={}",provider.getUrl(), responseMessage);
component.setContent("Response failure, please try again. Error message: " + responseMessage);
mainPanel.aroundRequest(false);
return;
}
OfficialParser.ParseResult parseResult = OfficialParser.
parseGPT35Turbo(responseMessage);

mainPanel.getContentPanel().getMessages().add(OfficialBuilder.assistantMessage(parseResult.getSource()));
component.setSourceContent(parseResult.getSource());
component.setContent(parseResult.getHtml());
mainPanel.aroundRequest(false);
component.scrollToBottom();
}
});
} catch (Exception e) {
component.setSourceContent(e.getMessage());
component.setContent(e.getMessage());
mainPanel.aroundRequest(false);
}
return component;
return call;
}
}
6 changes: 3 additions & 3 deletions src/main/java/com/obiscr/chatgpt/RequestProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ public RequestProvider create(MainPanel mainPanel, String question) {
provider.url = OFFICIAL_CONVERSATION_URL;
}
provider.header = TokenManager.getInstance().getChatGPTHeaders();
provider.data = JSON.toJSONString(OfficialBuilder.buildChatGPT(myProject,question));
provider.data = OfficialBuilder.buildChatGPT(myProject,question).toString();
} else {
provider.url = "https://api.openai.com/v1/chat/completions";
provider.header = TokenManager.getInstance().getGPT35TurboHeaders();
if (instance.enableContext) {
provider.data = JSON.toJSONString(OfficialBuilder.buildGpt35Turbo(question,mainPanel.getContentPanel()));
provider.data = OfficialBuilder.buildGpt35Turbo(question,mainPanel.getContentPanel()).toString();
} else {
provider.data = JSON.toJSONString(OfficialBuilder.buildGpt35Turbo(question));
provider.data = OfficialBuilder.buildGpt35Turbo(question).toString();
}
}
return provider;
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/com/obiscr/chatgpt/core/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,14 @@ public class Constant {
"**Important tip**: \n\n"+
"Currently using a third-party proxy service. will be unstable. And there is a limit on the number of requests per hour. <br />" +
"**Please don't give me bad reviews. I have been working hard to provide you with a better service.**\n\n<br />" +
"**Instructions**: \n\n" +
"Open *File* - *Setting/Preference* , select *Tool* - *OpenAI* - *ChatGPT*. Enter your own OpenAI account in Official.\n\n<br />" +
"Click Login below to start logging in, and the Access Token below will be automatically refreshed after successful login.\n" +
"The expiration time of the current Token is displayed below the Access Token. After the expiration, you can click Login again to refresh the Access Token.\n\n";
"**Getting Started**: \n\n<br />" +
"Please following this to configure the ChatGPT: [https://chatgpt.en.obiscr.com/settings/chatgpt-settings/](https://chatgpt.en.obiscr.com/settings/chatgpt-settings/) \n\n<br />";

public static final String GPT35_TURBO_CONTENT =
"**Important tip**: \n\n"+
"This model is the official GPT 3.5 Turbo model. \n\n<br />" +
"**Instructions**: \n\n" +
"At first, login to: [https://platform.openai.com/account/api-keys](https://platform.openai.com/account/api-keys). Then create an API Key.\n" +
"Open *File* - *Setting/Preference* , select *Tool* - *OpenAI* - *GPT 3.5 Turbo*. And fill the API Key in text field.";
"**Instructions**: \n\n<br />" +
"Please following this to configure the GPT 3.5 Turbo: [https://chatgpt.en.obiscr.com/settings/gpt-3.5-trubo-settings/](https://chatgpt.en.obiscr.com/settings/gpt-3.5-trubo-settings/) \n\n<br />";


public static String getChatGPTContent() {
Expand Down
12 changes: 5 additions & 7 deletions src/main/java/com/obiscr/chatgpt/core/SendAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.obiscr.chatgpt.ChatGPTHandler;
import com.obiscr.chatgpt.GPT35TurboHandler;
import com.obiscr.chatgpt.MyToolWindowFactory;
Expand All @@ -18,6 +16,7 @@
import com.obiscr.chatgpt.ui.MessageComponent;
import com.obiscr.chatgpt.ui.MessageGroupComponent;
import com.obiscr.chatgpt.util.StringUtil;
import okhttp3.Call;
import okhttp3.sse.EventSource;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -95,7 +94,6 @@ public void doActionPerformed(MainPanel mainPanel, String data) {
mainPanel.getSearchTextArea().getTextArea().setText("");
mainPanel.aroundRequest(true);
Project project = mainPanel.getProject();
ChatGPTHandler chatGPTHandler = project.getService(ChatGPTHandler.class);
MessageGroupComponent contentPanel = mainPanel.getContentPanel();

// Add the message component to container
Expand All @@ -108,21 +106,21 @@ public void doActionPerformed(MainPanel mainPanel, String data) {
ExecutorService executorService = mainPanel.getExecutorService();
// Request the server.
if (mainPanel.isChatGPTModel()) {
ChatGPTHandler chatGPTHandler = project.getService(ChatGPTHandler.class);
executorService.submit(() -> {
EventSource handle = chatGPTHandler.handle(mainPanel, answer, data);
mainPanel.setRequestHolder(handle);
contentPanel.updateLayout();
contentPanel.scrollToBottom();
});
} else {
GPT35TurboHandler gpt35TurboHandler = project.getService(GPT35TurboHandler.class);
executorService.submit(() -> {
new GPT35TurboHandler().handle(mainPanel, answer, data);
Call handle = gpt35TurboHandler.handle(mainPanel, answer, data);
mainPanel.setRequestHolder(handle);
contentPanel.updateLayout();
contentPanel.scrollToBottom();
});
// Because this Http request is blocked, it cannot be placed in Runnable
// So it needs to be executed outside Runnable
mainPanel.setRequestHolder(answer);
}

} catch (Exception e) {
Expand Down
80 changes: 40 additions & 40 deletions src/main/java/com/obiscr/chatgpt/core/builder/OfficialBuilder.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.obiscr.chatgpt.core.builder;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.intellij.openapi.project.Project;
import com.obiscr.chatgpt.core.ConversationManager;
import com.obiscr.chatgpt.settings.OpenAISettingsState;
Expand All @@ -16,75 +16,75 @@
*/
public class OfficialBuilder {

public static JSONObject buildChatGPT(@NotNull Project project, String text) {
JSONObject result = new JSONObject();
result.put("action","next");
public static JsonObject buildChatGPT(@NotNull Project project, String text) {
JsonObject result = new JsonObject();
result.addProperty("action","next");

JSONArray messages = new JSONArray();
JSONObject message0 = new JSONObject();
message0.put("id", UUID.randomUUID());
message0.put("role", "user");
JsonArray messages = new JsonArray();
JsonObject message0 = new JsonObject();
message0.addProperty("id", UUID.randomUUID().toString());
message0.addProperty("role", "user");

JSONObject content = new JSONObject();
content.put("content_type","text");
JSONArray parts = new JSONArray();
JsonObject content = new JsonObject();
content.addProperty("content_type","text");
JsonArray parts = new JsonArray();
parts.add(text);
content.put("parts",parts);
content.add("parts",parts);

JSONObject author = new JSONObject();
author.put("role", "user");
message0.put("content", content);
message0.put("author", author);
JsonObject author = new JsonObject();
author.addProperty("role", "user");
message0.add("content", content);
message0.add("author", author);
messages.add(message0);
result.put("messages", messages);
result.add("messages", messages);

result.put("parent_message_id", ConversationManager.getInstance(project).getParentMessageId());
result.addProperty("parent_message_id", ConversationManager.getInstance(project).getParentMessageId());
String conversationId = ConversationManager.getInstance(project).getConversationId();
if (StringUtil.isNotEmpty(conversationId)) {
result.put("conversation_id",conversationId);
result.addProperty("conversation_id",conversationId);
}
OpenAISettingsState settingsState = OpenAISettingsState.getInstance();
result.put("model",settingsState.chatGptModel);
result.addProperty("model",settingsState.chatGptModel);
return result;
}

public static JSONObject buildGpt35Turbo(String text) {
JSONObject result = new JSONObject();
result.put("model","gpt-3.5-turbo");
JSONArray messages = new JSONArray();
JSONObject message0 = new JSONObject();
message0.put("role","user");
message0.put("content",text);
public static JsonObject buildGpt35Turbo(String text) {
JsonObject result = new JsonObject();
result.addProperty("model","gpt-3.5-turbo");
JsonArray messages = new JsonArray();
JsonObject message0 = new JsonObject();
message0.addProperty("role","user");
message0.addProperty("content",text);
messages.add(message0);
result.put("messages",messages);
result.add("messages",messages);
return result;
}

public static JSONObject buildGpt35Turbo(String text, MessageGroupComponent component) {
JSONObject result = new JSONObject();
public static JsonObject buildGpt35Turbo(String text, MessageGroupComponent component) {
JsonObject result = new JsonObject();
OpenAISettingsState settingsState = OpenAISettingsState.getInstance();
result.put("model",settingsState.gpt35Model);
result.addProperty("model",settingsState.gpt35Model);
component.getMessages().add(userMessage(text));
result.put("messages",component.getMessages());
result.add("messages",component.getMessages());
return result;
}

private static JSONObject message(String role, String text) {
JSONObject message = new JSONObject();
message.put("role",role);
message.put("content",text);
private static JsonObject message(String role, String text) {
JsonObject message = new JsonObject();
message.addProperty("role",role);
message.addProperty("content",text);
return message;
}

public static JSONObject userMessage(String text) {
public static JsonObject userMessage(String text) {
return message("user",text);
}

public static JSONObject systemMessage(String text) {
public static JsonObject systemMessage(String text) {
return message("system",text);
}

public static JSONObject assistantMessage(String text) {
public static JsonObject assistantMessage(String text) {
return message("assistant",text);
}
}
Loading

0 comments on commit 3e3b220

Please sign in to comment.