From fbd1977152c8fb133de341cc33fc5f027bd393b6 Mon Sep 17 00:00:00 2001 From: ronger Date: Fri, 26 May 2023 18:42:36 +0800 Subject: [PATCH 1/5] =?UTF-8?q?:art:=20=E4=BD=BF=E7=94=A8=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=20IP=20=E8=BF=9B=E8=A1=8C=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../openai/service/IpAddressInterceptor.java | 29 +++++++++++++++++++ .../forest/openai/service/OpenAiService.java | 10 +++++-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/rymcu/forest/openai/service/IpAddressInterceptor.java diff --git a/src/main/java/com/rymcu/forest/openai/service/IpAddressInterceptor.java b/src/main/java/com/rymcu/forest/openai/service/IpAddressInterceptor.java new file mode 100644 index 0000000..ea8aab7 --- /dev/null +++ b/src/main/java/com/rymcu/forest/openai/service/IpAddressInterceptor.java @@ -0,0 +1,29 @@ +package com.rymcu.forest.openai.service; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.IOException; + +/** + * OkHttp Interceptor that adds an ip address header + * @author ronger + */ +public class IpAddressInterceptor implements Interceptor { + + private final String ip; + + IpAddressInterceptor(String ip) { + this.ip = ip; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request() + .newBuilder() + .header("x-forwarded-for", ip) + .build(); + return chain.proceed(request); + } +} diff --git a/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java b/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java index ad468b8..b9d00fb 100644 --- a/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java +++ b/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.rymcu.forest.util.SpringContextHolder; +import com.rymcu.forest.util.Utils; import com.theokanning.openai.DeleteResult; import com.theokanning.openai.OpenAiApi; import com.theokanning.openai.OpenAiError; @@ -30,18 +31,20 @@ import com.theokanning.openai.image.ImageResult; import com.theokanning.openai.model.Model; import com.theokanning.openai.moderation.ModerationRequest; import com.theokanning.openai.moderation.ModerationResult; - import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; import io.reactivex.Single; import okhttp3.*; import org.springframework.core.env.Environment; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import retrofit2.Call; import retrofit2.HttpException; import retrofit2.Retrofit; -import retrofit2.Call; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.jackson.JacksonConverterFactory; +import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.time.Duration; import java.util.List; @@ -336,8 +339,11 @@ public class OpenAiService { } public static OkHttpClient defaultClient(String token, Duration timeout) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String ip = Utils.getIpAddress(request); return new OkHttpClient.Builder() .addInterceptor(new AuthenticationInterceptor(token)) + .addInterceptor(new IpAddressInterceptor(ip)) .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)) .readTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS) .build(); From b9a360339c2b3ce2e0a62b5e6f44cb9db080d913 Mon Sep 17 00:00:00 2001 From: ronger Date: Fri, 14 Jul 2023 18:17:23 +0800 Subject: [PATCH 2/5] =?UTF-8?q?:art:=20=E7=BB=9F=E4=B8=80=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../forest/config/BaseExceptionHandler.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/rymcu/forest/config/BaseExceptionHandler.java b/src/main/java/com/rymcu/forest/config/BaseExceptionHandler.java index 1a07fac..bedebd2 100644 --- a/src/main/java/com/rymcu/forest/config/BaseExceptionHandler.java +++ b/src/main/java/com/rymcu/forest/config/BaseExceptionHandler.java @@ -1,6 +1,6 @@ package com.rymcu.forest.config; -import com.alibaba.fastjson.support.spring.FastJsonJsonView; +import com.alibaba.fastjson.support.spring.annotation.FastJsonView; import com.rymcu.forest.core.exception.BusinessException; import com.rymcu.forest.core.exception.ServiceException; import com.rymcu.forest.core.exception.TransactionException; @@ -47,7 +47,7 @@ public class BaseExceptionHandler { result = new GlobalResult<>(ResultCode.UNAUTHORIZED); logger.info("用户无权限"); } else if (ex instanceof UnknownAccountException) { - // 账号或密码错误 + // 未知账号 result = new GlobalResult<>(ResultCode.UNKNOWN_ACCOUNT); logger.info(ex.getMessage()); } else if (ex instanceof AccountException) { @@ -91,7 +91,7 @@ public class BaseExceptionHandler { return result; } else { ModelAndView mv = new ModelAndView(); - FastJsonJsonView view = new FastJsonJsonView(); + FastJsonView view = new FastJsonView(); Map attributes = new HashMap(2); if (ex instanceof UnauthenticatedException) { attributes.put("code", ResultCode.UNAUTHENTICATED.getCode()); @@ -99,6 +99,16 @@ public class BaseExceptionHandler { } else if (ex instanceof UnauthorizedException) { attributes.put("code", ResultCode.UNAUTHORIZED.getCode()); attributes.put("message", ResultCode.UNAUTHORIZED.getMessage()); + } else if (ex instanceof UnknownAccountException) { + // 未知账号 + attributes.put("code", ResultCode.UNKNOWN_ACCOUNT.getCode()); + attributes.put("message", ex.getMessage()); + logger.info(ex.getMessage()); + } else if (ex instanceof AccountException) { + // 账号或密码错误 + attributes.put("code", ResultCode.INCORRECT_ACCOUNT_OR_PASSWORD.getCode()); + attributes.put("message", ex.getMessage()); + logger.info(ex.getMessage()); } else if (ex instanceof ServiceException) { //业务失败的异常,如“账号或密码错误” attributes.put("code", ((ServiceException) ex).getCode()); From 8ca74e13b535dfae554f2bfdf3dc809542a75e4b Mon Sep 17 00:00:00 2001 From: ronger Date: Sun, 16 Jul 2023 15:48:36 +0800 Subject: [PATCH 3/5] =?UTF-8?q?:art:=20openai=20=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rymcu/forest/openai/OpenAiController.java | 30 +++++++++++++++++++ .../openai/entity/ChatMessageModel.java | 26 ++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/main/java/com/rymcu/forest/openai/entity/ChatMessageModel.java diff --git a/src/main/java/com/rymcu/forest/openai/OpenAiController.java b/src/main/java/com/rymcu/forest/openai/OpenAiController.java index b07ae55..6820373 100644 --- a/src/main/java/com/rymcu/forest/openai/OpenAiController.java +++ b/src/main/java/com/rymcu/forest/openai/OpenAiController.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject; import com.rymcu.forest.core.result.GlobalResult; import com.rymcu.forest.core.result.GlobalResultGenerator; import com.rymcu.forest.entity.User; +import com.rymcu.forest.openai.entity.ChatMessageModel; import com.rymcu.forest.openai.service.OpenAiService; import com.rymcu.forest.openai.service.SseService; import com.rymcu.forest.util.UserUtils; @@ -13,6 +14,7 @@ import com.theokanning.openai.completion.chat.ChatCompletionRequest; import com.theokanning.openai.completion.chat.ChatMessage; import io.reactivex.Flowable; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,6 +24,7 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.time.Duration; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -50,6 +53,33 @@ public class OpenAiController { ChatMessage chatMessage = new ChatMessage("user", message); List list = new ArrayList<>(4); list.add(chatMessage); + return sendMessage(user, list); + } + + @PostMapping("/new-chat") + public GlobalResult newChat(@RequestBody List messages) { + if (messages.isEmpty()) { + throw new IllegalArgumentException("参数异常!"); + } + User user = UserUtils.getCurrentUserByToken(); + Collections.reverse(messages); + List list = new ArrayList<>(messages.size()); + if (messages.size() > 4) { + messages = messages.subList(messages.size() - 4, messages.size()); + } + if (messages.size() >= 4 && messages.size() % 4 == 0) { + ChatMessage message = new ChatMessage("system", "简单总结一下你和用户的对话, 用作后续的上下文提示 prompt, 控制在 200 字内"); + list.add(message); + } + messages.forEach(chatMessageModel -> { + ChatMessage message = new ChatMessage(chatMessageModel.getRole(), chatMessageModel.getContent()); + list.add(message); + }); + return sendMessage(user, list); + } + + @NotNull + private GlobalResult sendMessage(User user, List list) { OpenAiService service = new OpenAiService(token, Duration.ofSeconds(180)); ChatCompletionRequest completionRequest = ChatCompletionRequest.builder() .model("gpt-3.5-turbo") diff --git a/src/main/java/com/rymcu/forest/openai/entity/ChatMessageModel.java b/src/main/java/com/rymcu/forest/openai/entity/ChatMessageModel.java new file mode 100644 index 0000000..908f7ac --- /dev/null +++ b/src/main/java/com/rymcu/forest/openai/entity/ChatMessageModel.java @@ -0,0 +1,26 @@ +package com.rymcu.forest.openai.entity; + +import lombok.Data; + +/** + * Created on 2023/7/16 14:52. + * + * @author ronger + * @email ronger-x@outlook.com + * @desc : com.rymcu.forest.openai.entity + */ +@Data +public class ChatMessageModel { + + Long dataId; + + String to; + + String from; + + Integer dataType; + + String content; + + String role; +} From 36721f4cfbd45a17ffa6dd84c09668c1eedc6c9f Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 17 Jul 2023 10:41:39 +0800 Subject: [PATCH 4/5] =?UTF-8?q?:art:=20openai=20model=20=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/rymcu/forest/openai/OpenAiController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rymcu/forest/openai/OpenAiController.java b/src/main/java/com/rymcu/forest/openai/OpenAiController.java index 6820373..f70c949 100644 --- a/src/main/java/com/rymcu/forest/openai/OpenAiController.java +++ b/src/main/java/com/rymcu/forest/openai/OpenAiController.java @@ -7,6 +7,7 @@ import com.rymcu.forest.entity.User; import com.rymcu.forest.openai.entity.ChatMessageModel; import com.rymcu.forest.openai.service.OpenAiService; import com.rymcu.forest.openai.service.SseService; +import com.rymcu.forest.util.Html2TextUtil; import com.rymcu.forest.util.UserUtils; import com.theokanning.openai.completion.chat.ChatCompletionChoice; import com.theokanning.openai.completion.chat.ChatCompletionChunk; @@ -72,7 +73,7 @@ public class OpenAiController { list.add(message); } messages.forEach(chatMessageModel -> { - ChatMessage message = new ChatMessage(chatMessageModel.getRole(), chatMessageModel.getContent()); + ChatMessage message = new ChatMessage(chatMessageModel.getRole(), Html2TextUtil.getContent(chatMessageModel.getContent())); list.add(message); }); return sendMessage(user, list); @@ -82,7 +83,7 @@ public class OpenAiController { private GlobalResult sendMessage(User user, List list) { OpenAiService service = new OpenAiService(token, Duration.ofSeconds(180)); ChatCompletionRequest completionRequest = ChatCompletionRequest.builder() - .model("gpt-3.5-turbo") + .model("gpt-3.5-turbo-16k-0613") .stream(true) .messages(list) .build(); From fc8be5ca3a7714b708261f97d7d428dd32f7c82f Mon Sep 17 00:00:00 2001 From: ronger Date: Wed, 19 Jul 2023 07:43:07 +0800 Subject: [PATCH 5/5] =?UTF-8?q?:arrow=5Fup:=20=E4=BE=9D=E8=B5=96=E5=8D=87?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3f4d58f..1719943 100644 --- a/pom.xml +++ b/pom.xml @@ -152,7 +152,7 @@ com.alibaba fastjson - 2.0.20 + 2.0.25 @@ -305,12 +305,12 @@ cn.hutool hutool-core - 5.8.11 + 5.8.19 cn.hutool hutool-http - 5.8.11 + 5.8.19