From 6a1b544545ba2a005a1d6263f3b42aaeeef78bcd Mon Sep 17 00:00:00 2001
From: ageerle <ageerle@163.com>
Date: 星期二, 11 三月 2025 17:32:47 +0800
Subject: [PATCH] feat: 支持插件功能

---
 ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java |  172 ++++++++++++++++++++++++--------------------------------
 1 files changed, 74 insertions(+), 98 deletions(-)

diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java
index e2f02b5..a2cfeff 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java
@@ -3,16 +3,11 @@
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import com.alibaba.fastjson.JSONObject;
-import com.azure.ai.openai.OpenAIClient;
-import com.azure.ai.openai.OpenAIClientBuilder;
-import com.azure.ai.openai.models.*;
-import com.azure.core.credential.AzureKeyCredential;
 import io.github.ollama4j.OllamaAPI;
 import io.github.ollama4j.models.chat.OllamaChatMessageRole;
 import io.github.ollama4j.models.chat.OllamaChatRequestBuilder;
 import io.github.ollama4j.models.chat.OllamaChatRequestModel;
 import io.github.ollama4j.models.generate.OllamaStreamHandler;
-import io.github.ollama4j.utils.Options;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -33,6 +28,12 @@
 import org.ruoyi.common.chat.entity.images.ResponseFormat;
 import org.ruoyi.common.chat.entity.whisper.WhisperResponse;
 import org.ruoyi.common.chat.openai.OpenAiStreamClient;
+import org.ruoyi.common.chat.openai.plugin.PluginAbstract;
+import org.ruoyi.common.chat.plugin.CmdPlugin;
+import org.ruoyi.common.chat.plugin.CmdReq;
+import org.ruoyi.common.chat.plugin.SqlPlugin;
+import org.ruoyi.common.chat.plugin.SqlReq;
+import org.ruoyi.common.chat.sse.ConsoleEventSourceListener;
 import org.ruoyi.common.chat.utils.TikTokensUtil;
 import org.ruoyi.common.core.domain.model.LoginUser;
 import org.ruoyi.common.core.exception.base.BaseException;
@@ -43,12 +44,10 @@
 import org.ruoyi.system.domain.bo.SysModelBo;
 import org.ruoyi.system.domain.request.translation.TranslationRequest;
 import org.ruoyi.system.domain.vo.SysModelVo;
-import org.ruoyi.system.domain.vo.SysUserVo;
 import org.ruoyi.system.listener.SSEEventSourceListener;
 import org.ruoyi.system.service.*;
 import org.springframework.core.io.InputStreamResource;
 import org.springframework.core.io.Resource;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
@@ -63,10 +62,10 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 
-import io.github.ollama4j.utils.OptionsBuilder;
 
 @Service
 @Slf4j
@@ -89,9 +88,6 @@
 
     static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
 
-    private final ISysPackagePlanService sysPackagePlanService;
-
-
     @Override
     public SseEmitter sseChat(ChatRequest chatRequest, HttpServletRequest request) {
         openAiStreamClient = chatConfig.getOpenAiStreamClient();
@@ -101,12 +97,7 @@
         List<Message> messages = chatRequest.getMessages();
         try {
             if (StpUtil.isLogin()) {
-                SysUserVo sysUserVo = userService.selectUserById(getUserId());
-//                if (!checkModel(sysUserVo.getUserPlan(), chatRequest.getModel())) {
-//                    throw new BaseException("褰撳墠濂楅涓嶆敮鎸佹妯″瀷!");
-//                }
                 LocalCache.CACHE.put("userId", getUserId());
-
                 Object content = messages.get(messages.size() - 1).getContent();
 
                 String chatString = "";
@@ -161,36 +152,23 @@
                     }
                 }
             }
-
-//            else {
-//
-//                    // 鍒濆璇锋眰娆℃暟
-//                    int number = 1;
-//                    // 鑾峰彇璇锋眰IP
-//                    String realIp = getClientIpAddress(request);
-//                    // 鏍规嵁IP鑾峰彇娆℃暟
-//                    Integer requestNumber = RedisUtils.getCacheObject(realIp);
-//                    if (requestNumber == null) {
-//                        // 璁板綍ip浣跨敤娆℃暟
-//                        RedisUtils.setCacheObject(realIp, number);
-//                    } else {
-//                        String configValue = configService.getConfigValue("mail", "free");
-//                        if (requestNumber > Integer.parseInt(configValue)) {
-//                            throw new BaseException("鍓╀綑娆℃暟涓嶈冻锛岃鍏呭�煎悗浣跨敤");
-//                        }
-//                        RedisUtils.setCacheObject(realIp, requestNumber + 1);
-//                    }
-//
-//            }
-            ChatCompletion completion = ChatCompletion
-                .builder()
-                .messages(messages)
-                .model(chatRequest.getModel())
-                .temperature(chatRequest.getTemperature())
-                .topP(chatRequest.getTop_p())
-                .stream(true)
-                .build();
-            openAiStreamClient.streamChatCompletion(completion, openAIEventSourceListener);
+            if("openCmd".equals(chatRequest.getModel())) {
+                sseEmitter.send(cmdPlugin(messages));
+                sseEmitter.complete();
+            }else if ("sqlPlugin".equals(chatRequest.getModel())){
+                sseEmitter.send(sqlPlugin(messages));
+                sseEmitter.complete();
+            } else {
+                ChatCompletion completion = ChatCompletion
+                        .builder()
+                        .messages(messages)
+                        .model(chatRequest.getModel())
+                        .temperature(chatRequest.getTemperature())
+                        .topP(chatRequest.getTop_p())
+                        .stream(true)
+                        .build();
+                openAiStreamClient.streamChatCompletion(completion, openAIEventSourceListener);
+            }
         } catch (Exception e) {
             String message = e.getMessage();
             sendErrorEvent(sseEmitter, message);
@@ -199,32 +177,51 @@
         return sseEmitter;
     }
 
+    public String cmdPlugin(List<Message> messages) {
+        CmdPlugin plugin = new CmdPlugin(CmdReq.class);
+        // 鎻掍欢鍚嶇О
+        plugin.setName("鍛戒护琛屽伐鍏�");
+        // 鏂规硶鍚嶇О
+        plugin.setFunction("openCmd");
+        // 鏂规硶璇存槑
+        plugin.setDescription("鎻愪緵涓�涓懡浠よ鎸囦护,姣斿<璁颁簨鏈�>,鎸囦护浣跨敤涓枃");
 
-//    /**
-//     * 鏌ュ綋鍓嶇敤鎴锋槸鍚﹀彲浠ヨ皟鐢ㄦ妯″瀷
-//     *
-//     * @param planId
-//     * @return
-//     */
-//    public Boolean checkModel(String planId, String modelName) {
-//        SysPackagePlanBo sysPackagePlanBo = new SysPackagePlanBo();
-//        if (modelName.startsWith("gpt-4-gizmo")) {
-//            modelName = "gpt-4-gizmo";
-//        }
-//        if (StringUtils.isEmpty(planId)) {
-//            sysPackagePlanBo.setName("Visitor");
-//        } else if ("Visitor".equals(planId) || "Free".equals(planId)) {
-//            sysPackagePlanBo.setName(planId);
-//        } else {
-//            // sysPackagePlanBo.setId(Long.valueOf(planId));
-//            return true;
-//        }
-//
-//        SysPackagePlanVo sysPackagePlanVo = sysPackagePlanService.queryList(sysPackagePlanBo).get(0);
-//        // 灏嗗瓧绗︿覆杞崲涓烘暟缁�
-//        String[] array = sysPackagePlanVo.getPlanDetail().split(",");
-//        return Arrays.asList(array).contains(modelName);
-//    }
+        PluginAbstract.Arg arg = new PluginAbstract.Arg();
+        // 鍙傛暟鍚嶇О
+        arg.setName("cmd");
+        // 鍙傛暟璇存槑
+        arg.setDescription("鍛戒护琛屾寚浠�");
+        // 鍙傛暟绫诲瀷
+        arg.setType("string");
+        arg.setRequired(true);
+        plugin.setArgs(Collections.singletonList(arg));
+        //鏈夊洓涓噸杞芥柟娉曪紝閮藉彲浠ヤ娇鐢�
+        ChatCompletionResponse response = openAiStreamClient.chatCompletionWithPlugin(messages,"gpt-4o-mini",plugin);
+        return response.getChoices().get(0).getMessage().getContent().toString();
+    }
+
+    public String sqlPlugin(List<Message> messages) {
+        SqlPlugin plugin = new SqlPlugin(SqlReq.class);
+        // 鎻掍欢鍚嶇О
+        plugin.setName("鏁版嵁搴撴煡璇㈡彃浠�");
+        // 鏂规硶鍚嶇О
+        plugin.setFunction("sqlPlugin");
+        // 鏂规硶璇存槑
+        plugin.setDescription("鎻愪緵涓�涓敤鎴峰悕绉版煡璇綑棰濅俊鎭�");
+
+        PluginAbstract.Arg arg = new PluginAbstract.Arg();
+        // 鍙傛暟鍚嶇О
+        arg.setName("username");
+        // 鍙傛暟璇存槑
+        arg.setDescription("鐢ㄦ埛鍚嶇О");
+        // 鍙傛暟绫诲瀷
+        arg.setType("string");
+        arg.setRequired(true);
+        plugin.setArgs(Collections.singletonList(arg));
+        //鏈夊洓涓噸杞芥柟娉曪紝閮藉彲浠ヤ娇鐢�
+        ChatCompletionResponse response = openAiStreamClient.chatCompletionWithPlugin(messages,"gpt-4o-mini",plugin);
+        return response.getChoices().get(0).getMessage().getContent().toString();
+    }
 
     /**
      * 鏍规嵁娆℃暟鎵i櫎浣欓
@@ -295,25 +292,6 @@
 
     @Override
     public String chat(ChatRequest chatRequest, String userId) {
-//        chatService.deductUserBalance(Long.valueOf(userId), 0.01);
-//        // 淇濆瓨娑堟伅璁板綍
-//        ChatMessageBo chatMessageBo = new ChatMessageBo();
-//        chatMessageBo.setUserId(Long.valueOf(userId));
-//        chatMessageBo.setModelName(ChatCompletion.Model.GPT_3_5_TURBO.getName());
-//        chatMessageBo.setContent(chatRequest.getPrompt());
-//        chatMessageBo.setDeductCost(0.01);
-//        chatMessageBo.setTotalTokens(0);
-//        chatMessageService.insertByBo(chatMessageBo);
-//
-//        openAiStreamClient = chatConfig.getOpenAiStreamClient();
-//        Message message = Message.builder().role(Message.Role.USER).content(chatRequest.getPrompt()).build();
-//        ChatCompletion chatCompletion = ChatCompletion
-//            .builder()
-//            .messages(Collections.singletonList(message))
-//            .model(chatRequest.getModel())
-//            .build();
-//        ChatCompletionResponse chatCompletionResponse = openAiStreamClient.chatCompletion(chatCompletion);
-//        return chatCompletionResponse.getChoices().get(0).getMessage().getContent();
          return  null;
     }
 
@@ -540,7 +518,8 @@
 
     @Override
     public String translation(TranslationRequest translationRequest) {
-
+        // 缈昏瘧妯″瀷鍥哄畾涓篻pt-4o-mini
+        translationRequest.setModel("gpt-4o-mini");
         ChatMessageBo chatMessageBo = new ChatMessageBo();
         chatMessageBo.setUserId(getUserId());
         chatMessageBo.setModelName(translationRequest.getModel());
@@ -557,17 +536,12 @@
             "\n" +
             "璇峰皢鐢ㄦ埛杈撳叆璇嶈缈昏瘧鎴恵" + translationRequest.getTargetLanguage() + "}\n" +
             "\n" +
-            "璁╂垜浠竴姝ヤ竴姝ユ潵鎬濊�僜n" +
             "==绀轰緥杈撳嚭==\n" +
+            "**鍘熸枃** : <杩欓噷鏄剧ず瑕佺炕璇戠殑鍘熸枃淇℃伅>\n" +
             "**缈昏瘧** : <杩欓噷鏄剧ず缈昏瘧鎴愯嫳璇殑缁撴灉>\n" +
-            "\n" +
-            "**閫犲彞** : What's the weather like today? Use the 'Weather Query' plugin to find out instantly! <閫犱竴涓嫳璇彞瀛�>\n" +
-            "\n" +
-            "**鍚屼箟璇�** : Add-on銆丒xtension銆丮odule  <杩欓噷鏄剧ず1-3涓嫳鏂囩殑鍚屼箟璇�>\n" +
-            "\n" +
             "==绀轰緥缁撴潫==\n" +
             "\n" +
-            "娉ㄦ剰锛氳涓ユ牸鎸夌ず渚嬭繘琛岃緭鍑�").build();
+            "娉ㄦ剰锛氳涓ユ牸鎸夌ず渚嬭繘琛岃緭鍑猴紝杩斿洖markdown鏍煎紡").build();
         messageList.add(sysMessage);
         Message message = Message.builder().role(Message.Role.USER).content(translationRequest.getPrompt()).build();
         messageList.add(message);
@@ -646,4 +620,6 @@
         ChatCompletionResponse chatCompletionResponse = openAiStreamClient.chatCompletion(chatCompletion);
         return chatCompletionResponse.getChoices().get(0).getMessage().getContent().toString();
     }
+
+
 }

--
Gitblit v1.9.3