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-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java | 91 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 88 insertions(+), 3 deletions(-) diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java index 0ee9766..ccc5214 100644 --- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java +++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java @@ -2,6 +2,7 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; import io.reactivex.Single; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -12,9 +13,7 @@ import org.ruoyi.common.chat.constant.OpenAIConst; import org.ruoyi.common.chat.entity.billing.BillingUsage; import org.ruoyi.common.chat.entity.billing.Subscription; -import org.ruoyi.common.chat.entity.chat.ChatCompletion; -import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse; -import org.ruoyi.common.chat.entity.chat.Message; +import org.ruoyi.common.chat.entity.chat.*; import org.ruoyi.common.chat.entity.common.DeleteResponse; import org.ruoyi.common.chat.entity.common.OpenAiResponse; import org.ruoyi.common.chat.entity.completions.Completion; @@ -43,6 +42,8 @@ import org.ruoyi.common.chat.openai.interceptor.DefaultOpenAiAuthInterceptor; import org.ruoyi.common.chat.openai.interceptor.DynamicKeyOpenAiAuthInterceptor; import org.ruoyi.common.chat.openai.interceptor.OpenAiAuthInterceptor; +import org.ruoyi.common.chat.openai.plugin.PluginAbstract; +import org.ruoyi.common.chat.openai.plugin.PluginParam; import org.ruoyi.common.core.exception.base.BaseException; import org.jetbrains.annotations.NotNull; import retrofit2.Retrofit; @@ -697,6 +698,90 @@ } /** + * 鎻掍欢闂瓟绠�鏄撶増 + * 榛樿鍙杕essages鏈�鍚庝竴涓厓绱犳瀯寤烘彃浠跺璇� + * 榛樿妯″瀷锛欳hatCompletion.Model.GPT_3_5_TURBO_16K_0613 + * + * @param chatCompletion 鍙傛暟 + * @param plugin 鎻掍欢 + * @param <R> 鎻掍欢鑷畾涔夊嚱鏁扮殑璇锋眰鍊� + * @param <T> 鎻掍欢鑷畾涔夊嚱鏁扮殑杩斿洖鍊� + * @return ChatCompletionResponse + */ + public <R extends PluginParam, T> ChatCompletionResponse chatCompletionWithPlugin(ChatCompletion chatCompletion, PluginAbstract<R, T> plugin) { + if (Objects.isNull(plugin)) { + return this.chatCompletion(chatCompletion); + } + if (CollectionUtil.isEmpty(chatCompletion.getMessages())) { + throw new BaseException(CommonError.MESSAGE_NOT_NUL.msg()); + } + List<Message> messages = chatCompletion.getMessages(); + Functions functions = Functions.builder() + .name(plugin.getFunction()) + .description(plugin.getDescription()) + .parameters(plugin.getParameters()) + .build(); + //娌℃湁鍊硷紝璁剧疆榛樿鍊� + if (Objects.isNull(chatCompletion.getFunctionCall())) { + chatCompletion.setFunctionCall("auto"); + } + //tip: 瑕嗙洊鑷繁璁剧疆鐨刦unctions鍙傛暟锛屼娇鐢╬lugin鏋勯�犵殑functions + chatCompletion.setFunctions(Collections.singletonList(functions)); + //璋冪敤OpenAi + ChatCompletionResponse functionCallChatCompletionResponse = this.chatCompletion(chatCompletion); + ChatChoice chatChoice = functionCallChatCompletionResponse.getChoices().get(0); + log.debug("鏋勯�犵殑鏂规硶鍊硷細{}", chatChoice.getMessage().getFunctionCall()); + + R realFunctionParam = (R) JSONUtil.toBean(chatChoice.getMessage().getFunctionCall().getArguments(), plugin.getR()); + T tq = plugin.func(realFunctionParam); + + FunctionCall functionCall = FunctionCall.builder() + .arguments(chatChoice.getMessage().getFunctionCall().getArguments()) + .name(plugin.getFunction()) + .build(); + messages.add(Message.builder().role(Message.Role.ASSISTANT).content("function_call").functionCall(functionCall).build()); + messages.add(Message.builder().role(Message.Role.FUNCTION).name(plugin.getFunction()).content(plugin.content(tq)).build()); + //璁剧疆绗簩娆★紝璇锋眰鐨勫弬鏁� + chatCompletion.setFunctionCall(null); + chatCompletion.setFunctions(null); + + ChatCompletionResponse chatCompletionResponse = this.chatCompletion(chatCompletion); + log.debug("鑷畾涔夌殑鏂规硶杩斿洖鍊硷細{}", chatCompletionResponse.getChoices()); + return chatCompletionResponse; + } + + /** + * 鎻掍欢闂瓟绠�鏄撶増 + * 榛樿鍙杕essages鏈�鍚庝竴涓厓绱犳瀯寤烘彃浠跺璇� + * 榛樿妯″瀷锛欳hatCompletion.Model.GPT_3_5_TURBO_16K_0613 + * + * @param messages 闂瓟鍙傛暟 + * @param plugin 鎻掍欢 + * @param <R> 鎻掍欢鑷畾涔夊嚱鏁扮殑璇锋眰鍊� + * @param <T> 鎻掍欢鑷畾涔夊嚱鏁扮殑杩斿洖鍊� + * @return ChatCompletionResponse + */ + public <R extends PluginParam, T> ChatCompletionResponse chatCompletionWithPlugin(List<Message> messages, PluginAbstract<R, T> plugin) { + return chatCompletionWithPlugin(messages, ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), plugin); + } + + /** + * 鎻掍欢闂瓟绠�鏄撶増 + * 榛樿鍙杕essages鏈�鍚庝竴涓厓绱犳瀯寤烘彃浠跺璇� + * + * @param messages 闂瓟鍙傛暟 + * @param model 妯″瀷 + * @param plugin 鎻掍欢 + * @param <R> 鎻掍欢鑷畾涔夊嚱鏁扮殑璇锋眰鍊� + * @param <T> 鎻掍欢鑷畾涔夊嚱鏁扮殑杩斿洖鍊� + * @return ChatCompletionResponse + */ + public <R extends PluginParam, T> ChatCompletionResponse chatCompletionWithPlugin(List<Message> messages, String model, PluginAbstract<R, T> plugin) { + ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).model(model).build(); + return this.chatCompletionWithPlugin(chatCompletion, plugin); + } + + /** * 绠�鏄撶増 璇煶缈昏瘧锛氱洰鍓嶄粎鏀寔缈昏瘧涓鸿嫳鏂� * * @param file 璇煶鏂囦欢 鏈�澶ф敮鎸�25MB mp3, mp4, mpeg, mpga, m4a, wav, webm -- Gitblit v1.9.3