From 1bff2791a6d4a4294795a34581e59f623d138c12 Mon Sep 17 00:00:00 2001 From: ageerle <32251822+ageerle@users.noreply.github.com> Date: 星期日, 25 五月 2025 14:36:23 +0800 Subject: [PATCH] Merge pull request #108 from liudalian/20250520 --- ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java | 85 ++++++++++++++ ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java | 7 + ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java | 7 + ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java | 84 ++++++++++++++ ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java | 77 ++++++++++++ ruoyi-modules-api/ruoyi-chat-api/pom.xml | 67 ++++++++++ ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java | 3 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java | 4 8 files changed, 326 insertions(+), 8 deletions(-) diff --git a/ruoyi-modules-api/ruoyi-chat-api/pom.xml b/ruoyi-modules-api/ruoyi-chat-api/pom.xml index b47d9c3..7e08c9a 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/pom.xml +++ b/ruoyi-modules-api/ruoyi-chat-api/pom.xml @@ -34,11 +34,11 @@ <!-- 瀵硅瘽鍩虹妯″潡 --> <dependencies> -<!-- <dependency>--> -<!-- <groupId>io.modelcontextprotocol.sdk</groupId>--> -<!-- <artifactId>mcp-spring-webflux</artifactId>--> -<!-- <version>0.8.0</version>--> -<!-- </dependency>--> + <!-- <dependency>--> + <!-- <groupId>io.modelcontextprotocol.sdk</groupId>--> + <!-- <artifactId>mcp-spring-webflux</artifactId>--> + <!-- <version>0.8.0</version>--> + <!-- </dependency>--> <dependency> <groupId>org.ruoyi</groupId> @@ -83,6 +83,63 @@ <version>0.3.1</version> </dependency> + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-open-ai</artifactId> + <version>1.0.1</version> + </dependency> + + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-core</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-http-client-jdk</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-community-zhipu-ai</artifactId> + <version>1.0.1-beta6</version> + </dependency> + + + + <dependency> + <groupId>dev.langchain4j</groupId> + <artifactId>langchain4j-community-dashscope</artifactId> + <version>1.0.1-beta6</version> + </dependency> + + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt</artifactId> + <version>0.12.6</version> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-api</artifactId> + <version>0.12.6</version> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-impl</artifactId> + <version>0.12.6</version> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt-jackson</artifactId> + <version>0.12.6</version> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-webflux</artifactId> + </dependency> + + </dependencies> </project> diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java index d29bccd..8388ad2 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java @@ -8,6 +8,13 @@ CHAT("chat", "涓浆妯″瀷"), DIFY("dify", "DIFY"), COZE("coze", "鎵e瓙"), + + ZHIPU("zhipu", "鏅鸿氨娓呰█"), + + DEEPSEEK("deepseek", "娣卞害姹傜储"), + + QIANWEN("qianwen", "閫氫箟鍗冮棶"), + VECTOR("vector", "鐭ヨ瘑搴撳悜閲忔ā鍨�"); private final String code; diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java index 55ea2ac..df49209 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java @@ -3,6 +3,9 @@ import org.ruoyi.common.chat.request.ChatRequest; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + /** * 瀵硅瘽Service鎺ュ彛 * diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java new file mode 100644 index 0000000..b185427 --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java @@ -0,0 +1,7 @@ +package org.ruoyi.chat.service.chat; + +import dev.langchain4j.service.TokenStream; + +public interface StreamAssistant { + TokenStream chat(String message); +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java index 6da0988..7cbb592 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java @@ -5,7 +5,6 @@ import com.coze.openapi.client.chat.model.ChatEventType; import com.coze.openapi.client.connversations.message.model.Message; import com.coze.openapi.service.auth.TokenAuth; -import com.coze.openapi.service.config.Consts; import com.coze.openapi.service.service.CozeAPI; import io.reactivex.Flowable; import lombok.extern.slf4j.Slf4j; @@ -37,7 +36,6 @@ @Override public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); - TokenAuth authCli = new TokenAuth(chatModelVo.getApiKey()); CozeAPI coze = new CozeAPI.Builder() @@ -49,7 +47,7 @@ CreateChatReq.builder() .botID(chatModelVo.getModelName()) .userID(chatRequest.getUserId().toString()) - .messages(Collections.singletonList(Message.buildUserQuestionText("What can you do?"))) + .messages(Collections.singletonList(Message.buildUserQuestionText(chatRequest.getPrompt()))) .build(); Flowable<ChatEvent> resp = coze.chat().stream(req); diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java new file mode 100644 index 0000000..8e805dd --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java @@ -0,0 +1,77 @@ +package org.ruoyi.chat.service.chat.impl; + + +import dev.langchain4j.model.chat.StreamingChatModel; +import dev.langchain4j.model.chat.response.ChatResponse; +import dev.langchain4j.model.chat.response.StreamingChatResponseHandler; +import dev.langchain4j.model.openai.OpenAiStreamingChatModel; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.ruoyi.chat.enums.ChatModeType; +import org.ruoyi.chat.service.chat.IChatService; +import org.ruoyi.common.chat.request.ChatRequest; +import org.ruoyi.domain.vo.ChatModelVo; +import org.ruoyi.service.IChatModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.HashMap; +import java.util.Map; + +/** + * deepseek + */ +@Service +@Slf4j +public class DeepSeekChatImpl implements IChatService { + + @Autowired + private IChatModelService chatModelService; + + @Override + public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { + ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); + StreamingChatModel chatModel = OpenAiStreamingChatModel.builder() + .baseUrl(chatModelVo.getApiHost()) + .apiKey(chatModelVo.getApiKey()) + .modelName(chatModelVo.getModelName()) + .logRequests(true) + .logResponses(true) + .temperature(0.8) + .build(); + // 鍙戦�佹祦寮忔秷鎭� + try { + chatModel.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() { + @SneakyThrows + @Override + public void onPartialResponse(String partialResponse) { + emitter.send(partialResponse); + log.info("鏀跺埌娑堟伅鐗囨: {}", partialResponse); + System.out.print(partialResponse); + } + + @Override + public void onCompleteResponse(ChatResponse completeResponse) { + emitter.complete(); + log.info("娑堟伅缁撴潫锛屽畬鏁存秷鎭疘D: {}", completeResponse); + } + + @Override + public void onError(Throwable error) { + System.err.println("閿欒: " + error.getMessage()); + } + }); + + } catch (Exception e) { + log.error("deepseek璇锋眰澶辫触锛歿}", e.getMessage()); + } + + return emitter; + } + + @Override + public String getCategory() { + return ChatModeType.DEEPSEEK.getCode(); + } +} diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java new file mode 100644 index 0000000..6e4308d --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java @@ -0,0 +1,84 @@ +package org.ruoyi.chat.service.chat.impl; + +import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel; +import dev.langchain4j.community.model.zhipu.ZhipuAiStreamingChatModel; +import dev.langchain4j.model.chat.StreamingChatModel; +import dev.langchain4j.model.chat.response.ChatResponse; +import dev.langchain4j.model.chat.response.StreamingChatResponseHandler; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.ruoyi.chat.enums.ChatModeType; +import org.ruoyi.chat.service.chat.IChatService; +import org.ruoyi.common.chat.request.ChatRequest; +import org.ruoyi.domain.ChatMessage; +import org.ruoyi.domain.vo.ChatModelVo; +import org.ruoyi.service.IChatModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +import static dev.langchain4j.data.message.SystemMessage.systemMessage; +import static dev.langchain4j.data.message.UserMessage.userMessage; +import static java.util.Arrays.asList; + + +/** + * 闃块噷閫氫箟鍗冮棶 + */ +@Service +@Slf4j +public class QianWenAiChatServiceImpl implements IChatService { + + @Autowired + private IChatModelService chatModelService; + + + @Override + public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { + ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); + StreamingChatModel model = QwenStreamingChatModel.builder() + .apiKey(chatModelVo.getApiKey()) + .modelName(chatModelVo.getModelName()) + .build(); + + // 鍙戦�佹祦寮忔秷鎭� + try { + model.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() { + @SneakyThrows + @Override + public void onPartialResponse(String partialResponse) { + emitter.send(partialResponse); + log.info("鏀跺埌娑堟伅鐗囨: {}", partialResponse); + } + + @Override + public void onCompleteResponse(ChatResponse completeResponse) { + emitter.complete(); + log.info("娑堟伅缁撴潫锛屽畬鏁存秷鎭疘D: {}", completeResponse); + } + + @Override + public void onError(Throwable error) { + error.printStackTrace(); + } + }); + } catch (Exception e) { + log.error("鍗冮棶璇锋眰澶辫触锛歿}", e.getMessage()); + } + + return emitter; + + } + + @Override + public String getCategory() { + return ChatModeType.QIANWEN.getCode(); + } + + + +} diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java new file mode 100644 index 0000000..b09d961 --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java @@ -0,0 +1,85 @@ +package org.ruoyi.chat.service.chat.impl; + +import dev.langchain4j.agent.tool.ToolSpecification; +import dev.langchain4j.community.model.zhipu.ZhipuAiStreamingChatModel; +import dev.langchain4j.model.chat.StreamingChatModel; +import dev.langchain4j.model.chat.response.ChatResponse; +import dev.langchain4j.model.chat.response.StreamingChatResponseHandler; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.ruoyi.chat.enums.ChatModeType; +import org.ruoyi.chat.service.chat.IChatService; +import org.ruoyi.common.chat.request.ChatRequest; +import org.ruoyi.domain.vo.ChatModelVo; +import org.ruoyi.service.IChatModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + + +/** + * 鏅鸿氨AI + */ +@Service +@Slf4j +public class ZhipuAiChatServiceImpl implements IChatService { + + @Autowired + private IChatModelService chatModelService; + + + ToolSpecification currentTime = ToolSpecification.builder() + .name("currentTime") + .description("currentTime") + .build(); + + + @Override + public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter){ + ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); + // 鍙戦�佹祦寮忔秷鎭� + try { + StreamingChatResponseHandler handler = new StreamingChatResponseHandler() { + @SneakyThrows + @Override + public void onPartialResponse(String token) { + System.out.println(token); + emitter.send(token); + } + + @SneakyThrows + @Override + public void onError(Throwable error) { + System.out.println(error.getMessage()); + emitter.send(error.getMessage()); + } + + @Override + public void onCompleteResponse(ChatResponse response) { + emitter.complete(); + log.info("娑堟伅缁撴潫锛屽畬鏁存秷鎭疘D: {}", response.aiMessage()); + } + }; + + StreamingChatModel model = ZhipuAiStreamingChatModel.builder() + .model(chatModelVo.getModelName()) + .apiKey(chatModelVo.getApiKey()) + .logRequests(true) + .logResponses(true) + .build(); + model.chat(chatRequest.getPrompt(), handler); + } catch (Exception e) { + log.error("鏅鸿氨娓呰█璇锋眰澶辫触锛歿}", e.getMessage()); + } + + return emitter; + } + + @Override + public String getCategory() { + return ChatModeType.ZHIPU.getCode(); + } +} -- Gitblit v1.9.3