From be8d9c1a5f195fea30c5df5a0e7d9e49ef720e06 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Fri, 26 Apr 2024 18:05:14 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E9=80=9A=E4=B9=89=E5=8D=83=E9=97=AE?= =?UTF-8?q?=E3=80=91=E9=87=8D=E6=96=B0=E5=AF=B9=E6=8E=A5=E9=98=BF=E9=87=8C?= =?UTF-8?q?=E4=BA=91=E9=80=9A=E4=B9=89=E5=89=8D=E6=96=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/dal/dataobject/AiChatModalDO.java | 16 ++- .../module/ai/vo/AiChatModalListRes.java | 2 +- .../src/main/resources/http/chat-modal.http | 19 +++ .../yudao-spring-boot-starter-ai/pom.xml | 11 +- .../yudao/framework/ai/AiPlatformEnum.java | 8 +- .../ai/chatqianwen/QianWenChatClient.java | 108 ++++++++---------- .../ai/chatqianwen/QianWenChatModal.java | 21 ++-- .../ai/chatqianwen/QianWenOptions.java | 13 +-- .../ai/chatqianwen/api/QianWenApi.java | 81 +++++++------ .../api/QianWenChatCompletion.java | 3 +- .../api/QianWenChatCompletionRequest.java | 10 +- .../ai/config/YudaoAiAutoConfiguration.java | 5 +- .../api/MidjourneyInteractionsApi.java | 6 +- .../listener/MidjourneyMessageListener.java | 6 +- 14 files changed, 160 insertions(+), 149 deletions(-) create mode 100644 yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-modal.http diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/AiChatModalDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/AiChatModalDO.java index 1c30531fa..c417e5a44 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/AiChatModalDO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/AiChatModalDO.java @@ -22,13 +22,23 @@ public class AiChatModalDO extends BaseDO { */ private Long id; /** - * 模型名字 + * 模型key */ - private Long modelName; + private String modelKey; /** - * 模型类型(qianwen、yiyan、xinghuo、openai) + * 模型类型 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum} + */ + private String modelPlatform; + /** + * 模型类型 + * {@link cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel} + * {@link cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel} */ private String modelType; + /** + * 模型名字 + */ + private String modelName; /** * 模型照片 */ diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiChatModalListRes.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiChatModalListRes.java index 4c5cdbb51..3d1701560 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiChatModalListRes.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiChatModalListRes.java @@ -20,7 +20,7 @@ public class AiChatModalListRes { /** * 模型名字 */ - private Long modelName; + private String modelName; /** * 模型类型(qianwen、yiyan、xinghuo、openai) */ diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-modal.http b/yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-modal.http new file mode 100644 index 000000000..aa2949920 --- /dev/null +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-modal.http @@ -0,0 +1,19 @@ + + +### chat call +GET {{baseUrl}}/ai/chat/modal/list +Authorization: {{token}} + + + +### chat call +PUT {{baseUrl}}/ai/chat/modal +Content-Type: application/json +Authorization: {{token}} + +{ + "modelName": "小红书Ai写作大模型", + "modelType": "yiyan", + "modalImage": "", + "modelConfig": "" +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml b/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml index 81d303ab6..3a52489a5 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml @@ -110,9 +110,9 @@ - com.aliyun - broadscope-bailian-sdk-java - 1.3.0 + com.alibaba + dashscope-sdk-java + 2.11.0 org.apache.httpcomponents @@ -129,6 +129,11 @@ com.fasterxml.jackson.core jackson-databind + + com.alibaba.fastjson2 + fastjson2 + 2.0.45 + com.squareup.okhttp3 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java index e939efb5d..717ced538 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java @@ -4,13 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; /** - * 讯飞星火 模型 - * - * 文档地址:https://www.xfyun.cn/doc/spark/Web.html#_1-%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E - * - * 1tokens 约等于1.5个中文汉字 或者 0.8个英文单词 - * 星火V1.5支持[搜索]内置插件;星火V2.0、V3.0和V3.5支持[搜索]、[天气]、[日期]、[诗词]、[字词]、[股票]六个内置插件 - * 星火V3.5 现已支持system、Function Call 功能。 + * ai 模型平台 * * author: fansili * time: 2024/3/11 10:12 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatClient.java index 7bab37586..6aaf47d35 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatClient.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatClient.java @@ -1,14 +1,15 @@ package cn.iocoder.yudao.framework.ai.chatqianwen; -import cn.hutool.core.util.IdUtil; -import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.ai.chat.*; -import cn.iocoder.yudao.framework.ai.chat.messages.MessageType; import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi; +import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenChatCompletionRequest; import cn.iocoder.yudao.framework.ai.chatyiyan.exception.YiYanApiException; -import com.aliyun.broadscope.bailian.sdk.models.*; +import com.alibaba.dashscope.aigc.generation.GenerationResult; +import com.alibaba.dashscope.aigc.generation.models.QwenParam; +import com.alibaba.dashscope.common.Message; +import io.reactivex.Flowable; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.retry.RetryCallback; @@ -23,9 +24,9 @@ import java.util.stream.Collectors; /** * 阿里 通义千问 client - * + *

* 文档地址:https://help.aliyun.com/document_detail/2587494.html?spm=a2c4g.2587492.0.0.53f33c566sXskp - * + *

* author: fansili * time: 2024/3/13 21:06 */ @@ -37,7 +38,9 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { private QianWenOptions qianWenOptions; - public QianWenChatClient() {} + public QianWenChatClient() { + } + public QianWenChatClient(QianWenApi qianWenApi) { this.qianWenApi = qianWenApi; } @@ -59,7 +62,7 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { public void onError(RetryContext context, RetryCallback callback, Throwable throwable) { log.warn("重试异常:" + context.getRetryCount(), throwable); - }; + } }) .build(); @@ -68,21 +71,21 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { return this.retryTemplate.execute(ctx -> { // ctx 会有重试的信息 // 创建 request 请求,stream模式需要供应商支持 - CompletionsRequest request = this.createRequest(prompt, false); + QianWenChatCompletionRequest request = this.createRequest(prompt, false); // 调用 callWithFunctionSupport 发送请求 - ResponseEntity responseEntity = qianWenApi.chatCompletionEntity(request); + ResponseEntity responseEntity = qianWenApi.chatCompletionEntity(request); // 获取结果封装 chatCompletion - CompletionsResponse response = responseEntity.getBody(); - if (!response.isSuccess()) { - return new ChatResponse(List.of(new Generation(String.format("failed to create completion, requestId: %s, code: %s, message: %s\n", - response.getRequestId(), response.getCode(), response.getMessage())))); - } + GenerationResult response = responseEntity.getBody(); +// if (!response.isSuccess()) { +// return new ChatResponse(List.of(new Generation(String.format("failed to create completion, requestId: %s, code: %s, message: %s\n", +// response.getRequestId(), response.getCode(), response.getMessage())))); +// } // 转换为 Generation 返回 - return new ChatResponse(List.of(new Generation(response.getData().getText()))); + return new ChatResponse(List.of(new Generation(response.getOutput().getText()))); }); } - private CompletionsRequest createRequest(Prompt prompt, boolean stream) { + private QianWenChatCompletionRequest createRequest(Prompt prompt, boolean stream) { // 两个都为null 则没有配置文件 if (qianWenOptions == null && prompt.getOptions() == null) { throw new ChatException("ChatOptions 未配置参数!"); @@ -93,61 +96,40 @@ public class QianWenChatClient implements ChatClient, StreamingChatClient { options = (ChatOptions) prompt.getOptions(); } // Prompt 里面是一个 ChatOptions,用户可以随意传入,这里做一下判断 - if (!(options instanceof QianWenOptions)) { + if (!(options instanceof QianWenOptions qianWenOptions)) { throw new ChatException("Prompt 传入的不是 QianWenOptions!"); } - QianWenOptions qianWenOptions = (QianWenOptions) options; - // 需要额外处理 - if (!stream) { - // 如果不需要 stream 输出,那么需要将这个设置为false,不然只会输出最后几个文字 - if (qianWenOptions.getParameters() == null) { - qianWenOptions.setParameters(new CompletionsRequest.Parameter().setIncrementalOutput(false)); - } else { - qianWenOptions.getParameters().setIncrementalOutput(false); - } - } else { - // 如果不需要 stream 输出,设置为true这样不会输出累加内容 - if (qianWenOptions.getParameters() == null) { - qianWenOptions.setParameters(new CompletionsRequest.Parameter().setIncrementalOutput(true)); - } else { - qianWenOptions.getParameters().setIncrementalOutput(true); - } - } - - // 创建request - return new CompletionsRequest() - // 请求唯一标识,请确保RequestId不重复。 - .setRequestId(IdUtil.getSnowflakeNextIdStr()) - // 设置 appid - .setAppId(qianWenOptions.getAppId()) - .setMessages(prompt.getInstructions().stream().map(m -> { - // 转换成 千问 对于的请求message - if (MessageType.USER == m.getMessageType()) { - return new ChatUserMessage(m.getContent()); - } else if (MessageType.SYSTEM == m.getMessageType()) { - return new ChatSystemMessage(m.getContent()); - } else if (MessageType.ASSISTANT == m.getMessageType()) { - return new ChatAssistantMessage(m.getContent()); - } - throw new ChatException(String.format("存在不能适配的消息! %s", JSONUtil.toJsonPrettyStr(m))); + return (QianWenChatCompletionRequest) QianWenChatCompletionRequest.builder() + .model(qianWenApi.getQianWenChatModal().getValue()) + .apiKey(qianWenApi.getApiKey()) + .messages(prompt.getInstructions().stream().map(m -> { + Message message = new Message(); + message.setRole(m.getMessageType().getValue()); + message.setContent(m.getContent()); + return message; }).collect(Collectors.toList())) - // 返回choice message结果 - .setParameters(qianWenOptions.getParameters()) - // 设置 ChatOptions 里面公共的参数 - .setTopP(options.getTopP() == null ? null : options.getTopP().doubleValue()) - // 设置输出方式 - .setStream(stream); + .resultFormat(QwenParam.ResultFormat.MESSAGE) + // 动态改变的三个参数 + .topP(Double.valueOf(qianWenOptions.getTopP())) + .topK(qianWenOptions.getTopK()) + .temperature(qianWenOptions.getTemperature()) + .incrementalOutput(true) + .build(); } @Override public Flux stream(Prompt prompt) { // ctx 会有重试的信息 // 创建 request 请求,stream模式需要供应商支持 - CompletionsRequest request = this.createRequest(prompt, true); + QianWenChatCompletionRequest request = this.createRequest(prompt, true); // 调用 callWithFunctionSupport 发送请求 - Flux response = this.qianWenApi.chatCompletionStream(request); - return response.map(res -> { - return new ChatResponse(List.of(new Generation(res.getData().getText()))); - }); + Flowable responseResult = this.qianWenApi.chatCompletionStream(request); + return Flux.create(fluxSink -> + responseResult.subscribe( + value -> fluxSink.next(new ChatResponse(List.of(new Generation(value.getOutput().getText())))), + error -> fluxSink.error(error), + () -> fluxSink.complete() + ) + ); } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatModal.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatModal.java index 5c9298d45..96646233a 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatModal.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenChatModal.java @@ -7,6 +7,7 @@ import lombok.Getter; * 千问 chat 模型 * * 模型地址:https://help.aliyun.com/document_detail/2712576.html + * 模型介绍:https://help.aliyun.com/document_detail/2666503.html?spm=a2c4g.2701795.0.0.26eb34dfKzcWN4 * * @author fansili * @time 2024/4/26 10:15 @@ -16,18 +17,22 @@ import lombok.Getter; @Getter public enum QianWenChatModal { - qwen_turbo("通义千问超大规模语言模型", "qwen-turbo"), - qwen_plus("通义千问超大规模语言模型增强版", "qwen-plus"), - qwen_max("通义千问千亿级别超大规模语言模型", "qwen-max"), - qwen_max_0403("通义千问千亿级别超大规模语言模型-0403", "qwen-max-0403"), - qwen_max_0107("通义千问千亿级别超大规模语言模型-0107", "qwen-max-0107"), - qwen_max_1201("通义千问千亿级别超大规模语言模型-1201", "qwen-max-1201"), - qwen_max_longcontext("通义千问千亿级别超大规模语言模型-28k tokens", "qwen-max-longcontext"), + // 千问付费模型 + QWEN_TURBO("通义千问超大规模语言模型", "qwen-turbo"), + QWEN_PLUS("通义千问超大规模语言模型增强版", "qwen-plus"), + QWEN_MAX("通义千问千亿级别超大规模语言模型", "qwen-max"), + QWEN_MAX_0403("通义千问千亿级别超大规模语言模型-0403", "qwen-max-0403"), + QWEN_MAX_0107("通义千问千亿级别超大规模语言模型-0107", "qwen-max-0107"), + QWEN_MAX_1201("通义千问千亿级别超大规模语言模型-1201", "qwen-max-1201"), + QWEN_MAX_LONGCONTEXT("通义千问千亿级别超大规模语言模型-28k tokens", "qwen-max-longcontext"), + + // 开源模型 + // https://help.aliyun.com/document_detail/2666503.html?spm=a2c4g.2701795.0.0.26eb34dfKzcWN4 + QWEN_72B_CHAT("通义千问1.5对外开源的72B规模参数量的经过人类指令对齐的chat模型", "qwen-72b-chat"), ; private String name; private String value; - } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenOptions.java index 26c6ef66f..eb598d366 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenOptions.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/QianWenOptions.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.framework.ai.chatqianwen; import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; -import com.aliyun.broadscope.bailian.sdk.models.CompletionsRequest; import lombok.Data; import lombok.experimental.Accessors; @@ -34,22 +33,18 @@ public class QianWenOptions implements ChatOptions { * 默认值为0.8。注意,取值不要大于等于1 */ private Float topP; - /** - * 模型参数设置。 - */ - private CompletionsRequest.Parameter parameters = new CompletionsRequest.Parameter(); // // 适配 ChatOptions @Override public Float getTemperature() { - return Float.parseFloat(this.parameters.getTemperature().toString()); + return null; } @Override public void setTemperature(Float temperature) { - this.parameters.setTemperature(Double.valueOf(temperature.toString())); + } @Override @@ -59,12 +54,12 @@ public class QianWenOptions implements ChatOptions { @Override public Integer getTopK() { - return this.parameters.getTopK(); + return null; } @Override public void setTopK(Integer topK) { - this.parameters.setTopK(topK); + } @Data diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenApi.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenApi.java index c8170af0f..2095e32ce 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenApi.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenApi.java @@ -1,64 +1,63 @@ package cn.iocoder.yudao.framework.ai.chatqianwen.api; -import com.aliyun.broadscope.bailian.sdk.AccessTokenClient; -import com.aliyun.broadscope.bailian.sdk.ApplicationClient; -import com.aliyun.broadscope.bailian.sdk.models.CompletionsRequest; -import com.aliyun.broadscope.bailian.sdk.models.CompletionsResponse; +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal; +import cn.iocoder.yudao.framework.ai.exception.AiException; +import com.alibaba.dashscope.aigc.generation.Generation; +import com.alibaba.dashscope.aigc.generation.GenerationResult; +import com.alibaba.dashscope.common.Message; +import com.alibaba.dashscope.common.Role; +import com.alibaba.dashscope.exception.InputRequiredException; +import com.alibaba.dashscope.exception.NoApiKeyException; +import io.reactivex.Flowable; import lombok.Getter; import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; -import reactor.core.publisher.Flux; // TODO done @fansili:是不是挪到 api 包里?按照 spring ai 的结构;根目录只放 client 和 options + /** * 阿里 通义千问 - * - * https://www.aliyun.com/search?k=%E9%80%9A%E4%B9%89%E5%A4%A7%E6%A8%A1%E5%9E%8B&scene=all - * + *

* author: fansili * time: 2024/3/13 21:09 */ @Getter public class QianWenApi { - /** - * accessKeyId、accessKeySecret、agentKey、appId 获取方式如下链接 - * https://help.aliyun.com/document_detail/2587494.html?spm=a2c4g.2587492.0.0.53f33c566sXskp - */ - private String accessKeyId; - private String accessKeySecret; - private String agentKey; - private String appId; - private String endpoint = "bailian.cn-beijing.aliyuncs.com"; - private String token; - private ApplicationClient client; + // api key 获取地址:https://bailian.console.aliyun.com/?spm=5176.28197581.0.0.38db29a4G3GcVb&apiKey=1#/api-key + private String apiKey = "sk-Zsd81gZYg7"; + private Generation gen = new Generation(); + private QianWenChatModal qianWenChatModal; - public QianWenApi(String accessKeyId, String accessKeySecret, String agentKey, String endpoint) { - this.accessKeyId = accessKeyId; - this.accessKeySecret = accessKeySecret; - this.agentKey = agentKey; + public QianWenApi(String apiKey, QianWenChatModal qianWenChatModal) { + this.apiKey = apiKey; + this.qianWenChatModal = qianWenChatModal; + } - if (endpoint != null) { - this.endpoint = endpoint; + public ResponseEntity chatCompletionEntity(QianWenChatCompletionRequest request) { + Message userMsg = Message.builder().role(Role.USER.getValue()).content("用萝卜、土豆、茄子做饭,给我个菜谱").build(); + + GenerationResult call; + try { + call = gen.call(request); + } catch (NoApiKeyException e) { + throw new AiException("没有找到apiKey!" + e.getMessage()); + } catch (InputRequiredException e) { + throw new AiException("chat缺少必填字段!" + e.getMessage()); } - - // 获取token - AccessTokenClient accessTokenClient = new AccessTokenClient(accessKeyId, accessKeySecret, agentKey); - token = accessTokenClient.getToken(); - // 构建client - client = ApplicationClient.builder() - .token(token) - .build(); - } - - public ResponseEntity chatCompletionEntity(CompletionsRequest request) { - // 发送请求 - CompletionsResponse response = client.completions(request); // 阿里云的这个 http code 随便设置,外面判断是否成功用的 CompletionsResponse.isSuccess - return new ResponseEntity<>(response, HttpStatusCode.valueOf(200)); + return new ResponseEntity<>(call, HttpStatusCode.valueOf(200)); } - public Flux chatCompletionStream(CompletionsRequest request) { - return client.streamCompletions(request); + public Flowable chatCompletionStream(QianWenChatCompletionRequest request) { + Flowable resultFlowable; + try { + resultFlowable = gen.streamCall(request); + } catch (NoApiKeyException e) { + throw new AiException("没有找到apiKey!" + e.getMessage()); + } catch (InputRequiredException e) { + throw new AiException("chat缺少必填字段!" + e.getMessage()); + } + return resultFlowable; } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletion.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletion.java index 4e646748e..474a7d826 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletion.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletion.java @@ -1,10 +1,9 @@ package cn.iocoder.yudao.framework.ai.chatqianwen.api; -import com.aliyun.broadscope.bailian.sdk.models.CompletionsResponse; /** * author: fansili * time: 2024/3/13 21:07 */ -public class QianWenChatCompletion extends CompletionsResponse { +public class QianWenChatCompletion { } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletionRequest.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletionRequest.java index c3e27da62..5017ea4ea 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletionRequest.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chatqianwen/api/QianWenChatCompletionRequest.java @@ -1,12 +1,16 @@ package cn.iocoder.yudao.framework.ai.chatqianwen.api; -import com.aliyun.broadscope.bailian.sdk.models.ChatRequestMessage; -import com.aliyun.broadscope.bailian.sdk.models.ChatUserMessage; +import com.alibaba.dashscope.aigc.generation.models.QwenParam; /** + * 千问 + * * author: fansili * time: 2024/3/13 21:07 */ -public class QianWenChatCompletionRequest extends ChatRequestMessage { +public class QianWenChatCompletionRequest extends QwenParam { + protected QianWenChatCompletionRequest(QwenParamBuilder b) { + super(b); + } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java index abf4eee77..483e88477 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.framework.ai.config; import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient; +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal; import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions; import cn.iocoder.yudao.framework.ai.chatqianwen.api.QianWenApi; import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatClient; @@ -45,10 +46,8 @@ public class YudaoAiAutoConfiguration { YudaoAiProperties.QianWenProperties qianWenProperties = yudaoAiProperties.getQianwen(); return new QianWenChatClient( new QianWenApi( - qianWenProperties.getAccessKeyId(), - qianWenProperties.getAccessKeySecret(), qianWenProperties.getAgentKey(), - qianWenProperties.getEndpoint() + QianWenChatModal.QWEN_72B_CHAT ), new QianWenOptions() .setAppId(qianWenProperties.getAppId()) diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/MidjourneyInteractionsApi.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/MidjourneyInteractionsApi.java index f71a81667..e0b2334eb 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/MidjourneyInteractionsApi.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/api/MidjourneyInteractionsApi.java @@ -2,13 +2,13 @@ package cn.iocoder.yudao.framework.ai.midjourney.api; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig; -import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; import cn.iocoder.yudao.framework.ai.midjourney.api.req.AttachmentsReq; import cn.iocoder.yudao.framework.ai.midjourney.api.req.DescribeReq; import cn.iocoder.yudao.framework.ai.midjourney.api.req.ReRollReq; import cn.iocoder.yudao.framework.ai.midjourney.api.res.UploadAttachmentsRes; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; +import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.FileSystemResource; diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/listener/MidjourneyMessageListener.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/listener/MidjourneyMessageListener.java index 5e63b079c..a044f3613 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/listener/MidjourneyMessageListener.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/midjourney/webSocket/listener/MidjourneyMessageListener.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyConstants; import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyGennerateStatusEnum; import cn.iocoder.yudao.framework.ai.midjourney.constants.MidjourneyMessageTypeEnum; import cn.iocoder.yudao.framework.ai.midjourney.util.MidjourneyUtil; -import com.alibaba.fastjson.JSON; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.utils.data.DataObject; @@ -45,13 +45,13 @@ public class MidjourneyMessageListener { // 转换 components if (!data.getArray(MidjourneyConstants.MSG_COMPONENTS).isEmpty()) { String componentsJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_COMPONENTS).toJson(), "UTF-8"); - List components = JSON.parseArray(componentsJson, MidjourneyMessage.ComponentType.class); + List components = JsonUtils.parseArray(componentsJson, MidjourneyMessage.ComponentType.class); mjMessage.setComponents(components); } // 转换附件 if (!data.getArray(MidjourneyConstants.MSG_ATTACHMENTS).isEmpty()) { String attachmentsJson = StrUtil.str(data.getArray(MidjourneyConstants.MSG_ATTACHMENTS).toJson(), "UTF-8"); - List attachments = JSON.parseArray(attachmentsJson, MidjourneyMessage.Attachment.class); + List attachments = JsonUtils.parseArray(attachmentsJson, MidjourneyMessage.Attachment.class); mjMessage.setAttachments(attachments); } // 转换状态