mirror of
https://github.com/YuWanTingbb/unofficial-gpt4.git
synced 2025-10-13 13:45:06 +00:00
gpt4-copilot-java-native v0.2.1
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,3 +2,6 @@
|
||||
e -i 66fe458e9ff3b7072252b455b08ac5c3076591bc^
|
||||
*.json
|
||||
*.json
|
||||
*.json
|
||||
machineIdList.json
|
||||
machineIdList.json
|
||||
|
26
config.json
26
config.json
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"password": "920052ec-14fc-4215-974d-d6fd3c89dd91",
|
||||
"gpt4_prompt": true,
|
||||
"gpt3_sleepTime": 0,
|
||||
"gpt4_sleepTime": 100,
|
||||
"maxPoolSize": 300,
|
||||
"vscode_version": "1.88.0",
|
||||
"copilot_chat_version": "0.15.2024041001",
|
||||
"get_token_url": "https://api.cocopilot.org/copilot_internal/v2/token",
|
||||
"one_copilot_limit": 30,
|
||||
"one_coCopilot_limit": 30,
|
||||
"one_selfCopilot_limit": 30,
|
||||
"serverPort": 8080,
|
||||
"prefix": "/"
|
||||
"password":"920052ec-14fc-4215-974d-d6fd3c89dd91",
|
||||
"gpt4_prompt":true,
|
||||
"gpt3_sleepTime":0,
|
||||
"gpt4_sleepTime":100,
|
||||
"maxPoolSize":300,
|
||||
"vscode_version":"1.88.0",
|
||||
"copilot_chat_version":"0.15.2024041001",
|
||||
"get_token_url":"https://api.cocopilot.org/copilot_internal/v2/token",
|
||||
"one_copilot_limit":30,
|
||||
"one_coCopilot_limit":30,
|
||||
"one_selfCopilot_limit":30,
|
||||
"serverPort":8080,
|
||||
"prefix":"/"
|
||||
}
|
8
pom.xml
8
pom.xml
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
<groupId>com.gpt4.copilot</groupId>
|
||||
<artifactId>gpt-4-copilot</artifactId>
|
||||
<version>0.2.0</version>
|
||||
<version>0.2.1</version>
|
||||
<name>native</name>
|
||||
<description>Demo project for Spring Boot with GraalVM Native Image</description>
|
||||
<properties>
|
||||
@@ -48,6 +48,12 @@
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<!-- 统计token-->
|
||||
<dependency>
|
||||
<groupId>com.unfbx</groupId>
|
||||
<artifactId>chatgpt-java</artifactId>
|
||||
<version>1.1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@@ -10,6 +10,8 @@ import com.gpt4.copilot.copilotApplication;
|
||||
import com.gpt4.copilot.pojo.Conversation;
|
||||
import com.gpt4.copilot.pojo.Result;
|
||||
import com.gpt4.copilot.pojo.SystemSetting;
|
||||
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
|
||||
import com.unfbx.chatgpt.entity.chat.Message;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.Data;
|
||||
@@ -327,16 +329,14 @@ public class ChatController {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, String> getStringStringMap() {
|
||||
private static Message getStringStringMap(String model) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
|
||||
String formattedNow = now.format(format);
|
||||
Map<String, String> newMessage = new HashMap<>();
|
||||
newMessage.put("role", "system");
|
||||
newMessage.put("content", "\nYou are ChatGPT, a large language model trained by OpenAI." +
|
||||
"\nKnowledge cutoff: 2021-09" +
|
||||
"\nCurrent model: gpt-4" +
|
||||
"\nCurrent time: " + formattedNow + "\n\n");
|
||||
String systemContent = "\\nYou are ChatGPT, a large language model trained by OpenAI.\" +\n" +
|
||||
" \"\\nCurrent model: " + model + "\" +\n" +
|
||||
" \"\\nCurrent time: \"" + formattedNow + "\"\\n\\n ";
|
||||
Message newMessage = Message.builder().role(Message.Role.SYSTEM).content(systemContent).build();
|
||||
return newMessage;
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ public class ChatController {
|
||||
@PostMapping(value = "/v1/chat/completions")
|
||||
public ResponseEntity<Object> coPilotConversation(HttpServletResponse response,
|
||||
HttpServletRequest request,
|
||||
@org.springframework.web.bind.annotation.RequestBody Conversation conversation) {
|
||||
@org.springframework.web.bind.annotation.RequestBody ChatCompletion conversation) {
|
||||
String header = request.getHeader("Authorization");
|
||||
String authorizationHeader = (header != null && !header.trim().isEmpty()) ? header.trim() : null;
|
||||
// 异步处理
|
||||
@@ -530,7 +530,18 @@ public class ChatController {
|
||||
return getObjectResponseEntity(response, future);
|
||||
}
|
||||
|
||||
private String getRequestApikey(String authorizationHeader, @org.springframework.web.bind.annotation.RequestBody Object conversation) {
|
||||
private String getRequestApikey(String authorizationHeader, @org.springframework.web.bind.annotation.RequestBody ChatCompletion conversation) {
|
||||
checkConversation(conversation);
|
||||
String apiKey;
|
||||
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
|
||||
apiKey = authorizationHeader.substring(7);
|
||||
} else {
|
||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Authorization header is missing");
|
||||
}
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
private String getEmbRequestApikey(String authorizationHeader, @org.springframework.web.bind.annotation.RequestBody Object conversation) {
|
||||
if (conversation == null) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Request body is missing or not in JSON format");
|
||||
}
|
||||
@@ -543,7 +554,7 @@ public class ChatController {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
private String modelAdjust(Conversation conversation) {
|
||||
private String modelAdjust(ChatCompletion conversation) {
|
||||
String model = conversation.getModel();
|
||||
if (model == null) {
|
||||
conversation.setModel("gpt-3.5-turbo");
|
||||
@@ -572,7 +583,7 @@ public class ChatController {
|
||||
@PostMapping(value = "/cocopilot/v1/chat/completions")
|
||||
public ResponseEntity<Object> coCoPilotConversation(HttpServletResponse response,
|
||||
HttpServletRequest request,
|
||||
@org.springframework.web.bind.annotation.RequestBody Conversation conversation) {
|
||||
@org.springframework.web.bind.annotation.RequestBody ChatCompletion conversation) {
|
||||
String header = request.getHeader("Authorization");
|
||||
String authorizationHeader = (header != null && !header.trim().isEmpty()) ? header.trim() : null;
|
||||
// 异步处理
|
||||
@@ -654,22 +665,43 @@ public class ChatController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Message
|
||||
* 获取url和apiKey
|
||||
*
|
||||
* @param authorizationHeader
|
||||
* @param conversation
|
||||
* @throws IOException
|
||||
*/
|
||||
private String[] extractApiKeyAndRequestUrl(String authorizationHeader, Object conversation) throws IllegalArgumentException {
|
||||
private String[] extractApiKeyAndRequestUrl(String authorizationHeader, ChatCompletion conversation) throws IllegalArgumentException {
|
||||
checkConversation(conversation);
|
||||
return getApiKeyAndRequestUrl(authorizationHeader);
|
||||
}
|
||||
|
||||
private void checkConversation(ChatCompletion conversation) {
|
||||
if (conversation == null) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Request body is missing or not in JSON format");
|
||||
}
|
||||
long tokens = conversation.tokens();
|
||||
if (tokens > 32 * 1024) {
|
||||
log.error("本次请求tokens is too long and over 32K: " + tokens);
|
||||
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Message is too long and over 32K");
|
||||
} else if (tokens <= 0) {
|
||||
log.error("本次请求tokens is none: " + tokens);
|
||||
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Message is none");
|
||||
} else {
|
||||
log.info("本次请求tokens: " + tokens);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String[] getApiKeyAndRequestUrl(String authorizationHeader) {
|
||||
String apiKey = null;
|
||||
String requestUrl = null;
|
||||
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
|
||||
String keyAndUrl = authorizationHeader.substring(7);
|
||||
if (!keyAndUrl.contains("|")) {
|
||||
apiKey = keyAndUrl;
|
||||
;
|
||||
} else {
|
||||
String[] parts = keyAndUrl.split("\\|");
|
||||
requestUrl = parts[0];
|
||||
@@ -682,6 +714,21 @@ public class ChatController {
|
||||
return new String[]{requestUrl, apiKey};
|
||||
}
|
||||
|
||||
/**
|
||||
* embaddings
|
||||
* 获取url和apiKey
|
||||
*
|
||||
* @param authorizationHeader
|
||||
* @param conversation
|
||||
* @throws IOException
|
||||
*/
|
||||
private String[] extractEmbApiKeyAndRequestUrl(String authorizationHeader, Object conversation) throws IllegalArgumentException {
|
||||
if (conversation == null) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Request body is missing or not in JSON format");
|
||||
}
|
||||
return getApiKeyAndRequestUrl(authorizationHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求体不是json 会报Request body is missing or not in JSON format
|
||||
* Authorization token缺失 会报Authorization header is missing
|
||||
@@ -697,7 +744,7 @@ public class ChatController {
|
||||
@PostMapping(value = "/self/v1/chat/completions")
|
||||
public ResponseEntity<Object> selfConversation(HttpServletResponse response,
|
||||
HttpServletRequest request,
|
||||
@org.springframework.web.bind.annotation.RequestBody Conversation conversation) {
|
||||
@org.springframework.web.bind.annotation.RequestBody ChatCompletion conversation) {
|
||||
String header = request.getHeader("Authorization");
|
||||
String authorizationHeader = (header != null && !header.trim().isEmpty()) ? header.trim() : null;
|
||||
// 异步处理
|
||||
@@ -730,6 +777,7 @@ public class ChatController {
|
||||
String model = modelAdjust(conversation);
|
||||
Request streamRequest = getPrompt(conversation, model, headersMap);
|
||||
try (Response resp = client.newCall(streamRequest).execute()) {
|
||||
log.info("response code: " + resp.body());
|
||||
if (!resp.isSuccessful()) {
|
||||
if (resp.code() == 429) {
|
||||
return new ResponseEntity<>(Result.error("rate limit exceeded"), HttpStatus.TOO_MANY_REQUESTS);
|
||||
@@ -768,7 +816,7 @@ public class ChatController {
|
||||
* @return
|
||||
*/
|
||||
public Object againConversation(HttpServletResponse response,
|
||||
@org.springframework.web.bind.annotation.RequestBody Conversation conversation,
|
||||
@org.springframework.web.bind.annotation.RequestBody ChatCompletion conversation,
|
||||
String token,
|
||||
String apiKey,
|
||||
String model) {
|
||||
@@ -791,14 +839,22 @@ public class ChatController {
|
||||
}
|
||||
}
|
||||
|
||||
private Request getPrompt(@org.springframework.web.bind.annotation.RequestBody Conversation conversation, String model, Map<String, String> headersMap) {
|
||||
private Request getPrompt(@org.springframework.web.bind.annotation.RequestBody ChatCompletion conversation, String model, Map<String, String> headersMap) {
|
||||
try {
|
||||
if (model.startsWith("gpt-4") && systemSetting.getGpt4_prompt()) {
|
||||
Map<String, String> newMessage = getStringStringMap();
|
||||
Message newMessage = getStringStringMap(model);
|
||||
conversation.getMessages().add(0, newMessage);
|
||||
|
||||
log.info("gpt-4模型,添加系统消息注入!");
|
||||
}
|
||||
String json = com.alibaba.fastjson2.JSON.toJSONString(conversation);
|
||||
|
||||
// 创建符合 github copilot 的请求体
|
||||
Conversation newConversation = new Conversation();
|
||||
newConversation.setStream(conversation.isStream());
|
||||
newConversation.setModel(conversation.getModel());
|
||||
newConversation.setMessages(conversation.getMessages());
|
||||
|
||||
String json = com.alibaba.fastjson2.JSON.toJSONString(newConversation);
|
||||
RequestBody requestBody = RequestBody.create(json, JSON);
|
||||
Request.Builder requestBuilder = new Request.Builder().url(github_chat_url).post(requestBody);
|
||||
headersMap.forEach(requestBuilder::addHeader);
|
||||
@@ -846,7 +902,7 @@ public class ChatController {
|
||||
// 异步处理
|
||||
CompletableFuture<ResponseEntity<Object>> future = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
String apiKey = getRequestApikey(authorizationHeader, conversation);
|
||||
String apiKey = getEmbRequestApikey(authorizationHeader, conversation);
|
||||
if (!copilotTokenList.containsKey(apiKey)) {
|
||||
String token = getCopilotToken(apiKey);
|
||||
if (token == null) {
|
||||
@@ -874,7 +930,7 @@ public class ChatController {
|
||||
if (resp.code() == 429) {
|
||||
return new ResponseEntity<>(Result.error("rate limit exceeded"), HttpStatus.TOO_MANY_REQUESTS);
|
||||
} else if (resp.code() == 400) {
|
||||
return new ResponseEntity<>(Result.error("messages is none or too long and over 32K"), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return new ResponseEntity<>(Result.error("Model is not accessible"), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
} else {
|
||||
String token = getCopilotToken(apiKey);
|
||||
if (token == null) {
|
||||
@@ -936,7 +992,7 @@ public class ChatController {
|
||||
// 异步处理
|
||||
CompletableFuture<ResponseEntity<Object>> future = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
String apiKey = getRequestApikey(authorizationHeader, conversation);
|
||||
String apiKey = getEmbRequestApikey(authorizationHeader, conversation);
|
||||
if (!coCopilotTokenList.containsKey(apiKey)) {
|
||||
String token = getCoCoToken(apiKey);
|
||||
if (token == null) {
|
||||
@@ -964,7 +1020,7 @@ public class ChatController {
|
||||
if (resp.code() == 429) {
|
||||
return new ResponseEntity<>(Result.error("rate limit exceeded"), HttpStatus.TOO_MANY_REQUESTS);
|
||||
} else if (resp.code() == 400) {
|
||||
return new ResponseEntity<>(Result.error("messages is none or too long and over 32K"), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return new ResponseEntity<>(Result.error("Model is not accessible"), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
} else {
|
||||
String token = getCoCoToken(apiKey);
|
||||
if (token == null) {
|
||||
@@ -1011,7 +1067,7 @@ public class ChatController {
|
||||
// 异步处理
|
||||
CompletableFuture<ResponseEntity<Object>> future = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
String[] result = extractApiKeyAndRequestUrl(authorizationHeader, conversation);
|
||||
String[] result = extractEmbApiKeyAndRequestUrl(authorizationHeader, conversation);
|
||||
String requestUrl = result[0];
|
||||
String apiKey = result[1];
|
||||
if (!selfTokenList.containsKey(apiKey)) {
|
||||
@@ -1040,7 +1096,7 @@ public class ChatController {
|
||||
if (resp.code() == 429) {
|
||||
return new ResponseEntity<>(Result.error("rate limit exceeded"), HttpStatus.TOO_MANY_REQUESTS);
|
||||
} else if (resp.code() == 400) {
|
||||
return new ResponseEntity<>(Result.error("messages is none or too long and over 32K"), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return new ResponseEntity<>(Result.error("Model is not accessible"), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
} else {
|
||||
String token = getSelfToken(apiKey, requestUrl);
|
||||
if (token == null) {
|
||||
@@ -1217,9 +1273,9 @@ public class ChatController {
|
||||
* @param resp
|
||||
* @param conversation
|
||||
*/
|
||||
private void outPutChat(HttpServletResponse response, Response resp, Conversation conversation, String model) {
|
||||
private void outPutChat(HttpServletResponse response, Response resp, ChatCompletion conversation, String model) {
|
||||
try {
|
||||
boolean isStream = (conversation.getStream() != null) ? conversation.getStream() : false;
|
||||
boolean isStream = conversation.isStream();
|
||||
int sleep_time = calculateSleepTime(model, isStream);
|
||||
if (isStream) {
|
||||
response.setContentType("text/event-stream; charset=UTF-8");
|
||||
|
@@ -25,7 +25,7 @@ public class CustomErrorController implements ErrorController {
|
||||
" <title>Document</title>\n" +
|
||||
"</head>\n" +
|
||||
"<body>\n" +
|
||||
" <p>Thanks you use gpt4-copilot-java-0.2.0</p>\n" +
|
||||
" <p>Thanks you use gpt4-copilot-java-0.2.1</p>\n" +
|
||||
" <p><a href=\"https://apifox.com/apidoc/shared-4301e565-a8df-48a0-85a5-bda2c4c3965a\">详细使用文档</a></p>\n" +
|
||||
" <p><a href=\"https://github.com/Yanyutin753/gpt4-copilot-java-sh\">项目地址</a></p>\n" +
|
||||
"</body>\n" +
|
||||
|
@@ -296,7 +296,7 @@ public class copilotApplication {
|
||||
System.out.println("one_selfCopilot_limit:" + ChatController.getSystemSetting().getOne_selfCopilot_limit());
|
||||
System.out.println("gpt4-copilot-java 初始化接口成功!");
|
||||
System.out.println("======================================================");
|
||||
System.out.println("******原神gpt4-copilot-java-native v0.2.0启动成功******");
|
||||
System.out.println("******原神gpt4-copilot-java-native v0.2.1启动成功******");
|
||||
System.out.println("* 对chat接口的模型进行重定向,减少潜在的风险");
|
||||
System.out.println("* 使用ConcurrentHashMap,粗略的对于每个密钥按每分钟进行限速");
|
||||
System.out.println("* 新增环境变量用于对gpt-4*等模型进行系统prompt提示");
|
||||
|
@@ -1,12 +1,12 @@
|
||||
package com.gpt4.copilot.pojo;
|
||||
|
||||
import com.unfbx.chatgpt.entity.chat.Message;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author YANGYANG
|
||||
@@ -19,7 +19,7 @@ public class Conversation {
|
||||
|
||||
private String model;
|
||||
|
||||
private List<Map<String, String>> messages;
|
||||
private List<Message> messages;
|
||||
|
||||
private Boolean stream;
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
target/gpt-4-copilot-0.2.1.jar.original
Normal file
BIN
target/gpt-4-copilot-0.2.1.jar.original
Normal file
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
artifactId=gpt-4-copilot
|
||||
groupId=com.gpt4.copilot
|
||||
version=0.2.0
|
||||
version=0.2.1
|
||||
|
Reference in New Issue
Block a user