mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	【通义千问】重新对接阿里云通义前文。
This commit is contained in:
		| @@ -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; | ||||
|     /** | ||||
|      * 模型照片 | ||||
|      */ | ||||
|   | ||||
| @@ -20,7 +20,7 @@ public class AiChatModalListRes { | ||||
|     /** | ||||
|      * 模型名字 | ||||
|      */ | ||||
|     private Long modelName; | ||||
|     private String modelName; | ||||
|     /** | ||||
|      * 模型类型(qianwen、yiyan、xinghuo、openai) | ||||
|      */ | ||||
|   | ||||
| @@ -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": "" | ||||
| } | ||||
| @@ -110,9 +110,9 @@ | ||||
|         </dependency> | ||||
|         <!--    阿里云 通义千问    --> | ||||
|         <dependency> | ||||
|             <groupId>com.aliyun</groupId> | ||||
|             <artifactId>broadscope-bailian-sdk-java</artifactId> | ||||
|             <version>1.3.0</version> | ||||
|             <groupId>com.alibaba</groupId> | ||||
|             <artifactId>dashscope-sdk-java</artifactId> | ||||
|             <version>2.11.0</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.httpcomponents</groupId> | ||||
| @@ -129,6 +129,11 @@ | ||||
|             <groupId>com.fasterxml.jackson.core</groupId> | ||||
|             <artifactId>jackson-databind</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.alibaba.fastjson2</groupId> | ||||
|             <artifactId>fastjson2</artifactId> | ||||
|             <version>2.0.45</version> | ||||
|         </dependency> | ||||
|         <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp --> | ||||
|         <dependency> | ||||
|             <groupId>com.squareup.okhttp3</groupId> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|  * | ||||
|  * <p> | ||||
|  * 文档地址:https://help.aliyun.com/document_detail/2587494.html?spm=a2c4g.2587492.0.0.53f33c566sXskp | ||||
|  * | ||||
|  * <p> | ||||
|  * 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 <T extends Object, E extends Throwable> void onError(RetryContext context, | ||||
|                                                                             RetryCallback<T, E> 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<CompletionsResponse> responseEntity = qianWenApi.chatCompletionEntity(request); | ||||
|             ResponseEntity<GenerationResult> 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<ChatResponse> stream(Prompt prompt) { | ||||
|         // ctx 会有重试的信息 | ||||
|         // 创建 request 请求,stream模式需要供应商支持 | ||||
|         CompletionsRequest request = this.createRequest(prompt, true); | ||||
|         QianWenChatCompletionRequest request = this.createRequest(prompt, true); | ||||
|         // 调用 callWithFunctionSupport 发送请求 | ||||
|         Flux<CompletionsResponse> response = this.qianWenApi.chatCompletionStream(request); | ||||
|         return response.map(res -> { | ||||
|             return new ChatResponse(List.of(new Generation(res.getData().getText()))); | ||||
|         }); | ||||
|         Flowable<GenerationResult> 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() | ||||
|                 ) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|  * | ||||
|  * <p> | ||||
|  * 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<GenerationResult> 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<CompletionsResponse> 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<CompletionsResponse> chatCompletionStream(CompletionsRequest request) { | ||||
|         return client.streamCompletions(request); | ||||
|     public Flowable<GenerationResult> chatCompletionStream(QianWenChatCompletionRequest request) { | ||||
|         Flowable<GenerationResult> 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; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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()) | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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<MidjourneyMessage.ComponentType> components = JSON.parseArray(componentsJson, MidjourneyMessage.ComponentType.class); | ||||
|             List<MidjourneyMessage.ComponentType> 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<MidjourneyMessage.Attachment> attachments = JSON.parseArray(attachmentsJson, MidjourneyMessage.Attachment.class); | ||||
|             List<MidjourneyMessage.Attachment> attachments = JsonUtils.parseArray(attachmentsJson, MidjourneyMessage.Attachment.class); | ||||
|             mjMessage.setAttachments(attachments); | ||||
|         } | ||||
|         // 转换状态 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 cherishsince
					cherishsince