Commit 59c744520ad3d19e87aa830f2cc3cb761d30daef

Authored by YunaiV
1 parent 813e7af8

【代码优化】AI:硅基流动的图片生成

Showing 9 changed files with 79 additions and 264 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java
... ... @@ -11,7 +11,7 @@ import cn.hutool.extra.spring.SpringUtil;
11 11 import cn.hutool.http.HttpUtil;
12 12 import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
13 13 import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
14   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconflowImageOptions;
  14 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowImageOptions;
15 15 import cn.iocoder.yudao.framework.common.pojo.PageResult;
16 16 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
17 17 import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO;
... ... @@ -147,8 +147,8 @@ public class AiImageServiceImpl implements AiImageService {
147 147 .build();
148 148 } else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.SILICON_FLOW.getPlatform())) {
149 149 // https://docs.siliconflow.cn/cn/api-reference/images/images-generations
150   - return SiliconflowImageOptions.builder().model(model.getModel())
151   - .withHeight(draw.getHeight()).withHeight(draw.getWidth())
  150 + return SiliconFlowImageOptions.builder().model(model.getModel())
  151 + .height(draw.getHeight()).width(draw.getWidth())
152 152 .build();
153 153 } else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.STABLE_DIFFUSION.getPlatform())) {
154 154 // https://platform.stability.ai/docs/api-reference#tag/SDXL-and-SD1.6/operation/textToImage
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
... ... @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
8 8 import cn.iocoder.yudao.framework.ai.core.model.doubao.DouBaoChatModel;
9 9 import cn.iocoder.yudao.framework.ai.core.model.hunyuan.HunYuanChatModel;
10 10 import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
11   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiiconflowApiConstants;
  11 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowApiConstants;
12 12 import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowChatModel;
13 13 import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
14 14 import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
... ... @@ -114,11 +114,11 @@ public class YudaoAiAutoConfiguration {
114 114  
115 115 public SiliconFlowChatModel buildSiliconFlowChatClient(YudaoAiProperties.SiliconFlowProperties properties) {
116 116 if (StrUtil.isEmpty(properties.getModel())) {
117   - properties.setModel(SiiconflowApiConstants.MODEL_DEFAULT);
  117 + properties.setModel(SiliconFlowApiConstants.MODEL_DEFAULT);
118 118 }
119 119 OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()
120 120 .openAiApi(OpenAiApi.builder()
121   - .baseUrl(SiiconflowApiConstants.DEFAULT_BASE_URL)
  121 + .baseUrl(SiliconFlowApiConstants.DEFAULT_BASE_URL)
122 122 .apiKey(properties.getApiKey())
123 123 .build())
124 124 .defaultOptions(OpenAiChatOptions.builder()
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
... ... @@ -15,10 +15,10 @@ import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
15 15 import cn.iocoder.yudao.framework.ai.core.model.doubao.DouBaoChatModel;
16 16 import cn.iocoder.yudao.framework.ai.core.model.hunyuan.HunYuanChatModel;
17 17 import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
18   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiiconflowApiConstants;
19   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiiconflowmageApi;
  18 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowApiConstants;
20 19 import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowChatModel;
21   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconflowImageModel;
  20 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowImageApi;
  21 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowImageModel;
22 22 import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
23 23 import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
24 24 import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;
... ... @@ -45,6 +45,7 @@ import org.springframework.ai.autoconfigure.moonshot.MoonshotAutoConfiguration;
45 45 import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration;
46 46 import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
47 47 import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration;
  48 +import org.springframework.ai.autoconfigure.stabilityai.StabilityAiImageAutoConfiguration;
48 49 import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusServiceClientConnectionDetails;
49 50 import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusServiceClientProperties;
50 51 import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreAutoConfiguration;
... ... @@ -228,7 +229,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
228 229 case OPENAI:
229 230 return buildOpenAiImageModel(apiKey, url);
230 231 case SILICON_FLOW:
231   - return buildSiiconflowImageModel(apiKey,url);
  232 + return buildSiliconFlowImageModel(apiKey,url);
232 233 case STABLE_DIFFUSION:
233 234 return buildStabilityAiImageModel(apiKey, url);
234 235 default:
... ... @@ -474,12 +475,12 @@ public class AiModelFactoryImpl implements AiModelFactory {
474 475 }
475 476  
476 477 /**
477   - * Siiconflow
  478 + * 创建 SiliconFlowImageModel 对象
478 479 */
479   - private SiliconflowImageModel buildSiiconflowImageModel(String apiToken, String url) {
480   - url = StrUtil.blankToDefault(url, SiiconflowApiConstants.DEFAULT_BASE_URL);
481   - SiiconflowmageApi openAiApi = SiiconflowmageApi.builder().baseUrl(url).apiKey(apiToken).build();
482   - return new SiliconflowImageModel(openAiApi);
  480 + private SiliconFlowImageModel buildSiliconFlowImageModel(String apiToken, String url) {
  481 + url = StrUtil.blankToDefault(url, SiliconFlowApiConstants.DEFAULT_BASE_URL);
  482 + SiliconFlowImageApi openAiApi = new SiliconFlowImageApi(url, apiToken);
  483 + return new SiliconFlowImageModel(openAiApi);
483 484 }
484 485  
485 486 /**
... ... @@ -490,6 +491,9 @@ public class AiModelFactoryImpl implements AiModelFactory {
490 491 return OllamaChatModel.builder().ollamaApi(ollamaApi).toolCallingManager(getToolCallingManager()).build();
491 492 }
492 493  
  494 + /**
  495 + * 可参考 {@link StabilityAiImageAutoConfiguration} 的 stabilityAiImageModel 方法
  496 + */
493 497 private StabilityAiImageModel buildStabilityAiImageModel(String apiKey, String url) {
494 498 url = StrUtil.blankToDefault(url, StabilityAiApi.DEFAULT_BASE_URL);
495 499 StabilityAiApi stabilityAiApi = new StabilityAiApi(apiKey, StabilityAiApi.DEFAULT_IMAGE_MODEL, url);
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiiconflowApiConstants.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiliconFlowApiConstants.java
... ... @@ -17,11 +17,11 @@
17 17 package cn.iocoder.yudao.framework.ai.core.model.siliconflow;
18 18  
19 19 /**
20   - * Common value constants for Siiconflow api.
  20 + * SiliconFlow API 枚举类
21 21 *
22 22 * @author zzt
23 23 */
24   -public final class SiiconflowApiConstants {
  24 +public final class SiliconFlowApiConstants {
25 25  
26 26 public static final String DEFAULT_BASE_URL = "https://api.siliconflow.cn";
27 27  
... ... @@ -29,8 +29,4 @@ public final class SiiconflowApiConstants {
29 29  
30 30 public static final String PROVIDER_NAME = "Siiconflow";
31 31  
32   - private SiiconflowApiConstants() {
33   -
34   - }
35   -
36 32 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiiconflowmageApi.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiliconFlowImageApi.java
... ... @@ -27,7 +27,6 @@ import org.springframework.http.MediaType;
27 27 import org.springframework.http.ResponseEntity;
28 28 import org.springframework.util.Assert;
29 29 import org.springframework.util.CollectionUtils;
30   -import org.springframework.util.LinkedMultiValueMap;
31 30 import org.springframework.util.MultiValueMap;
32 31 import org.springframework.web.client.ResponseErrorHandler;
33 32 import org.springframework.web.client.RestClient;
... ... @@ -35,68 +34,40 @@ import org.springframework.web.client.RestClient;
35 34 import java.util.Map;
36 35  
37 36 /**
38   - * Siiconflow Image API.
  37 + * 硅基流动 Image API
39 38 *
40 39 * @see <a href= "https://docs.siliconflow.cn/cn/api-reference/images/images-generations">Images</a>
41 40 *
42 41 * @author zzt
43 42 */
44   -public class SiiconflowmageApi {
  43 +public class SiliconFlowImageApi {
45 44  
46 45 private final RestClient restClient;
47 46  
48   - /**
49   - * Create a new Siiconflow Image api with base URL set.
50   - * @param aiToken OpenAI apiKey.
51   - */
52   - public SiiconflowmageApi(String aiToken) {
53   - this(SiiconflowApiConstants.DEFAULT_BASE_URL, aiToken, RestClient.builder());
  47 + public SiliconFlowImageApi(String aiToken) {
  48 + this(SiliconFlowApiConstants.DEFAULT_BASE_URL, aiToken, RestClient.builder());
54 49 }
55 50  
56   - /**
57   - * Create a new Siiconflow Image API with the provided base URL.
58   - * @param baseUrl the base URL for the OpenAI API.
59   - * @param openAiToken Siiconflow apiKey.
60   - */
61   - public SiiconflowmageApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) {
  51 + public SiliconFlowImageApi(String baseUrl, String openAiToken) {
  52 + this(baseUrl, openAiToken, RestClient.builder());
  53 + }
  54 +
  55 + public SiliconFlowImageApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder) {
62 56 this(baseUrl, openAiToken, restClientBuilder, RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
63 57 }
64 58  
65   - /**
66   - * Create a new OpenAI Image API with the provided base URL.
67   - * @param baseUrl the base URL for the OpenAI API.
68   - * @param apiKey OpenAI apiKey.
69   - * @param restClientBuilder the rest client builder to use.
70   - */
71   - public SiiconflowmageApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder,
72   - ResponseErrorHandler responseErrorHandler) {
  59 + public SiliconFlowImageApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder,
  60 + ResponseErrorHandler responseErrorHandler) {
73 61 this(baseUrl, apiKey, CollectionUtils.toMultiValueMap(Map.of()), restClientBuilder, responseErrorHandler);
74 62 }
75 63  
76   - /**
77   - * Create a new OpenAI Image API with the provided base URL.
78   - * @param baseUrl the base URL for the OpenAI API.
79   - * @param apiKey OpenAI apiKey.
80   - * @param headers the http headers to use.
81   - * @param restClientBuilder the rest client builder to use.
82   - * @param responseErrorHandler the response error handler to use.
83   - */
84   - public SiiconflowmageApi(String baseUrl, String apiKey, MultiValueMap<String, String> headers,
85   - RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
86   -
  64 + public SiliconFlowImageApi(String baseUrl, String apiKey, MultiValueMap<String, String> headers,
  65 + RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
87 66 this(baseUrl, new SimpleApiKey(apiKey), headers, restClientBuilder, responseErrorHandler);
88 67 }
89 68  
90   - /**
91   - * Create a new OpenAI Image API with the provided base URL.
92   - * @param baseUrl the base URL for the OpenAI API.
93   - * @param apiKey OpenAI apiKey.
94   - * @param headers the http headers to use.
95   - * @param restClientBuilder the rest client builder to use.
96   - * @param responseErrorHandler the response error handler to use.
97   - */
98   - public SiiconflowmageApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> headers,
99   - RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
  69 + public SiliconFlowImageApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> headers,
  70 + RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
100 71  
101 72 // @formatter:off
102 73 this.restClient = restClientBuilder.baseUrl(baseUrl)
... ... @@ -141,67 +112,4 @@ public class SiiconflowmageApi {
141 112 }
142 113 }
143 114  
144   - public static Builder builder() {
145   - return new Builder();
146   - }
147   -
148   - /**
149   - * Builder to construct {@link SiiconflowmageApi} instance.
150   - */
151   - public static class Builder {
152   -
153   - private String baseUrl = SiiconflowApiConstants.DEFAULT_BASE_URL;
154   -
155   - private ApiKey apiKey;
156   -
157   - private MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
158   -
159   - private RestClient.Builder restClientBuilder = RestClient.builder();
160   -
161   - private ResponseErrorHandler responseErrorHandler = RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER;
162   -
163   - public Builder baseUrl(String baseUrl) {
164   - Assert.hasText(baseUrl, "baseUrl cannot be null or empty");
165   - this.baseUrl = baseUrl;
166   - return this;
167   - }
168   -
169   - public Builder apiKey(ApiKey apiKey) {
170   - Assert.notNull(apiKey, "apiKey cannot be null");
171   - this.apiKey = apiKey;
172   - return this;
173   - }
174   -
175   - public Builder apiKey(String simpleApiKey) {
176   - Assert.notNull(simpleApiKey, "simpleApiKey cannot be null");
177   - this.apiKey = new SimpleApiKey(simpleApiKey);
178   - return this;
179   - }
180   -
181   - public Builder headers(MultiValueMap<String, String> headers) {
182   - Assert.notNull(headers, "headers cannot be null");
183   - this.headers = headers;
184   - return this;
185   - }
186   -
187   - public Builder restClientBuilder(RestClient.Builder restClientBuilder) {
188   - Assert.notNull(restClientBuilder, "restClientBuilder cannot be null");
189   - this.restClientBuilder = restClientBuilder;
190   - return this;
191   - }
192   -
193   - public Builder responseErrorHandler(ResponseErrorHandler responseErrorHandler) {
194   - Assert.notNull(responseErrorHandler, "responseErrorHandler cannot be null");
195   - this.responseErrorHandler = responseErrorHandler;
196   - return this;
197   - }
198   -
199   - public SiiconflowmageApi build() {
200   - Assert.notNull(this.apiKey, "apiKey must be set");
201   - return new SiiconflowmageApi(this.baseUrl, this.apiKey, this.headers, this.restClientBuilder,
202   - this.responseErrorHandler);
203   - }
204   -
205   - }
206   -
207 115 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiliconflowImageModel.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiliconFlowImageModel.java
... ... @@ -17,6 +17,7 @@
17 17 package cn.iocoder.yudao.framework.ai.core.model.siliconflow;
18 18  
19 19 import io.micrometer.observation.ObservationRegistry;
  20 +import lombok.Setter;
20 21 import org.slf4j.Logger;
21 22 import org.slf4j.LoggerFactory;
22 23 import org.springframework.ai.image.*;
... ... @@ -25,8 +26,8 @@ import org.springframework.ai.image.observation.ImageModelObservationContext;
25 26 import org.springframework.ai.image.observation.ImageModelObservationConvention;
26 27 import org.springframework.ai.image.observation.ImageModelObservationDocumentation;
27 28 import org.springframework.ai.model.ModelOptionsUtils;
  29 +import org.springframework.ai.openai.OpenAiImageModel;
28 30 import org.springframework.ai.openai.api.OpenAiImageApi;
29   -import org.springframework.ai.openai.api.common.OpenAiApiConstants;
30 31 import org.springframework.ai.openai.metadata.OpenAiImageGenerationMetadata;
31 32 import org.springframework.ai.retry.RetryUtils;
32 33 import org.springframework.http.ResponseEntity;
... ... @@ -36,77 +37,44 @@ import org.springframework.util.Assert;
36 37 import java.util.List;
37 38  
38 39 /**
39   - * cv openapi图片模型方法
  40 + * 硅基流动 {@link ImageModel} 实现类
  41 + *
  42 + * 参考 {@link OpenAiImageModel} 实现
40 43 *
41 44 * @author zzt
42 45 */
43   -public class SiliconflowImageModel implements ImageModel {
  46 +public class SiliconFlowImageModel implements ImageModel {
44 47  
45   - private static final Logger logger = LoggerFactory.getLogger(SiliconflowImageModel.class);
  48 + private static final Logger logger = LoggerFactory.getLogger(SiliconFlowImageModel.class);
46 49  
47 50 private static final ImageModelObservationConvention DEFAULT_OBSERVATION_CONVENTION = new DefaultImageModelObservationConvention();
48 51  
49   - /**
50   - * The default options used for the image completion requests.
51   - */
52   - private final SiliconflowImageOptions defaultOptions;
  52 + private final SiliconFlowImageOptions defaultOptions;
53 53  
54   - /**
55   - * The retry template used to retry the OpenAI Image API calls.
56   - */
57 54 private final RetryTemplate retryTemplate;
58 55  
59   - /**
60   - * Low-level access to the OpenAI Image API.
61   - */
62   - private final SiiconflowmageApi siiconflowmageApi;
  56 + private final SiliconFlowImageApi siliconFlowImageApi;
63 57  
64   - /**
65   - * Observation registry used for instrumentation.
66   - */
67 58 private final ObservationRegistry observationRegistry;
68 59  
69   - /**
70   - * Conventions to use for generating observations.
71   - */
  60 + @Setter
72 61 private ImageModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION;
73 62  
74   - /**
75   - * Creates an instance of the OpenAiImageModel.
76   - * @param siiconflowmageApi The OpenAiImageApi instance to be used for interacting with
77   - * the OpenAI Image API.
78   - * @throws IllegalArgumentException if openAiImageApi is null
79   - */
80   - public SiliconflowImageModel(SiiconflowmageApi siiconflowmageApi) {
81   - this(siiconflowmageApi, SiliconflowImageOptions.builder().build(), RetryUtils.DEFAULT_RETRY_TEMPLATE);
  63 + public SiliconFlowImageModel(SiliconFlowImageApi siliconFlowImageApi) {
  64 + this(siliconFlowImageApi, SiliconFlowImageOptions.builder().build(), RetryUtils.DEFAULT_RETRY_TEMPLATE);
82 65 }
83 66  
84   - /**
85   - * Initializes a new instance of the OpenAiImageModel.
86   - * @param siiconflowmageApi The OpenAiImageApi instance to be used for interacting with
87   - * the OpenAI Image API.
88   - * @param options The OpenAiImageOptions to configure the image model.
89   - * @param retryTemplate The retry template.
90   - */
91   - public SiliconflowImageModel(SiiconflowmageApi siiconflowmageApi, SiliconflowImageOptions options, RetryTemplate retryTemplate) {
92   - this(siiconflowmageApi, options, retryTemplate, ObservationRegistry.NOOP);
  67 + public SiliconFlowImageModel(SiliconFlowImageApi siliconFlowImageApi, SiliconFlowImageOptions options, RetryTemplate retryTemplate) {
  68 + this(siliconFlowImageApi, options, retryTemplate, ObservationRegistry.NOOP);
93 69 }
94 70  
95   - /**
96   - * Initializes a new instance of the OpenAiImageModel.
97   - * @param siiconflowmageApi The OpenAiImageApi instance to be used for interacting with
98   - * the OpenAI Image API.
99   - * @param options The OpenAiImageOptions to configure the image model.
100   - * @param retryTemplate The retry template.
101   - * @param observationRegistry The ObservationRegistry used for instrumentation.
102   - */
103   - public SiliconflowImageModel(SiiconflowmageApi siiconflowmageApi, SiliconflowImageOptions options, RetryTemplate retryTemplate,
  71 + public SiliconFlowImageModel(SiliconFlowImageApi siliconFlowImageApi, SiliconFlowImageOptions options, RetryTemplate retryTemplate,
104 72 ObservationRegistry observationRegistry) {
105   - Assert.notNull(siiconflowmageApi, "OpenAiImageApi must not be null");
  73 + Assert.notNull(siliconFlowImageApi, "OpenAiImageApi must not be null");
106 74 Assert.notNull(options, "options must not be null");
107 75 Assert.notNull(retryTemplate, "retryTemplate must not be null");
108 76 Assert.notNull(observationRegistry, "observationRegistry must not be null");
109   - this.siiconflowmageApi = siiconflowmageApi;
  77 + this.siliconFlowImageApi = siliconFlowImageApi;
110 78 this.defaultOptions = options;
111 79 this.retryTemplate = retryTemplate;
112 80 this.observationRegistry = observationRegistry;
... ... @@ -114,11 +82,11 @@ public class SiliconflowImageModel implements ImageModel {
114 82  
115 83 @Override
116 84 public ImageResponse call(ImagePrompt imagePrompt) {
117   - SiiconflowmageApi.SiliconflowImageRequest imageRequest = createRequest(imagePrompt);
  85 + SiliconFlowImageApi.SiliconflowImageRequest imageRequest = createRequest(imagePrompt);
118 86  
119 87 var observationContext = ImageModelObservationContext.builder()
120 88 .imagePrompt(imagePrompt)
121   - .provider(OpenAiApiConstants.PROVIDER_NAME)
  89 + .provider(SiliconFlowApiConstants.PROVIDER_NAME)
122 90 .requestOptions(imagePrompt.getOptions())
123 91 .build();
124 92  
... ... @@ -127,7 +95,7 @@ public class SiliconflowImageModel implements ImageModel {
127 95 this.observationRegistry)
128 96 .observe(() -> {
129 97 ResponseEntity<OpenAiImageApi.OpenAiImageResponse> imageResponseEntity = this.retryTemplate
130   - .execute(ctx -> this.siiconflowmageApi.createImage(imageRequest));
  98 + .execute(ctx -> this.siliconFlowImageApi.createImage(imageRequest));
131 99  
132 100 ImageResponse imageResponse = convertResponse(imageResponseEntity, imageRequest);
133 101  
... ... @@ -137,17 +105,17 @@ public class SiliconflowImageModel implements ImageModel {
137 105 });
138 106 }
139 107  
140   - private SiiconflowmageApi.SiliconflowImageRequest createRequest(ImagePrompt imagePrompt) {
  108 + private SiliconFlowImageApi.SiliconflowImageRequest createRequest(ImagePrompt imagePrompt) {
141 109 String instructions = imagePrompt.getInstructions().get(0).getText();
142 110  
143   - SiiconflowmageApi.SiliconflowImageRequest imageRequest = new SiiconflowmageApi.SiliconflowImageRequest(instructions,
  111 + SiliconFlowImageApi.SiliconflowImageRequest imageRequest = new SiliconFlowImageApi.SiliconflowImageRequest(instructions,
144 112 imagePrompt.getOptions().getModel());
145 113  
146   - return ModelOptionsUtils.merge(imagePrompt.getOptions(), imageRequest, SiiconflowmageApi.SiliconflowImageRequest.class);
  114 + return ModelOptionsUtils.merge(imagePrompt.getOptions(), imageRequest, SiliconFlowImageApi.SiliconflowImageRequest.class);
147 115 }
148 116  
149 117 private ImageResponse convertResponse(ResponseEntity<OpenAiImageApi.OpenAiImageResponse> imageResponseEntity,
150   - SiiconflowmageApi.SiliconflowImageRequest siliconflowImageRequest) {
  118 + SiliconFlowImageApi.SiliconflowImageRequest siliconflowImageRequest) {
151 119 OpenAiImageApi.OpenAiImageResponse imageApiResponse = imageResponseEntity.getBody();
152 120 if (imageApiResponse == null) {
153 121 logger.warn("No image response returned for request: {}", siliconflowImageRequest);
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiliconflowImageOptions.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/siliconflow/SiliconFlowImageOptions.java
1 1 package cn.iocoder.yudao.framework.ai.core.model.siliconflow;
2 2  
3 3 import com.fasterxml.jackson.annotation.JsonProperty;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Builder;
4 6 import lombok.Data;
  7 +import lombok.NoArgsConstructor;
5 8 import org.springframework.ai.image.ImageOptions;
6   -import org.springframework.ai.openai.OpenAiImageOptions;
7 9  
8 10 /**
9   - * 硅基流动画图能力
  11 + * 硅基流动 {@link ImageOptions}
10 12 *
11 13 * @author zzt
12 14 */
13 15 @Data
14   -public class SiliconflowImageOptions implements ImageOptions {
  16 +@Builder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class SiliconFlowImageOptions implements ImageOptions {
15 20  
16 21 @JsonProperty("model")
17 22 private String model;
... ... @@ -37,7 +42,6 @@ public class SiliconflowImageOptions implements ImageOptions {
37 42 @JsonProperty("num_inference_steps")
38 43 private Integer numInferenceSteps = 25;
39 44  
40   -
41 45 /**
42 46 * This value is used to control the degree of match between the generated image and the given prompt. The higher the value, the more the generated image will tend to strictly match the text prompt. The lower the value, the more creative and diverse the generated image will be, potentially containing more unexpected elements.
43 47 *
... ... @@ -47,7 +51,7 @@ public class SiliconflowImageOptions implements ImageOptions {
47 51 private Float guidanceScale = 0.75F;
48 52  
49 53 /**
50   - * 如果想要每次都生成固定的图片,可以把seed设置为固定值。
  54 + * 如果想要每次都生成固定的图片,可以把 seed 设置为固定值
51 55 *
52 56 */
53 57 @JsonProperty("seed")
... ... @@ -59,13 +63,11 @@ public class SiliconflowImageOptions implements ImageOptions {
59 63 @JsonProperty("image")
60 64 private String image;
61 65  
62   -
63 66 /**
64 67 * 宽
65 68 */
66 69 private Integer width;
67 70  
68   -
69 71 /**
70 72 * 高
71 73 */
... ... @@ -85,21 +87,6 @@ public class SiliconflowImageOptions implements ImageOptions {
85 87 }
86 88 }
87 89  
88   - /**
89   - * 硅基流动
90   - * @return
91   - */
92   - public static SiliconflowImageOptions.Builder builder() {
93   - return new SiliconflowImageOptions.Builder();
94   - }
95   -
96   - @Override
97   - public String toString() {
98   -
99   - return "SiliconflowImageOptions{" + "model='" + getModel() + '\'' + ", batch_size=" + batchSize + ", imageSize=" + imageSize + ", negativePrompt='"
100   - + negativePrompt + '\'' + '}';
101   - }
102   -
103 90 @Override
104 91 public Integer getN() {
105 92 return null;
... ... @@ -115,52 +102,4 @@ public class SiliconflowImageOptions implements ImageOptions {
115 102 return null;
116 103 }
117 104  
118   - public static class Builder extends OpenAiImageOptions{
119   -
120   - private final SiliconflowImageOptions options;
121   -
122   - private Builder() {
123   - this.options = new SiliconflowImageOptions();
124   - }
125   -
126   - public SiliconflowImageOptions.Builder model(String model) {
127   - this.options.setModel(model);
128   - return this;
129   - }
130   -
131   - public SiliconflowImageOptions.Builder withBatchSize(Integer batchSize) {
132   - options.setBatchSize(batchSize);
133   - return this;
134   - }
135   -
136   - public SiliconflowImageOptions.Builder withModel(String model) {
137   - options.setModel(model);
138   - return this;
139   - }
140   -
141   - public SiliconflowImageOptions.Builder withWidth(Integer width) {
142   - options.setWidth(width);
143   - return this;
144   - }
145   -
146   - public SiliconflowImageOptions.Builder withHeight(Integer height) {
147   - options.setHeight(height);
148   - return this;
149   - }
150   -
151   - public SiliconflowImageOptions.Builder withSeed(Integer seed) {
152   - options.setSeed(seed);
153   - return this;
154   - }
155   -
156   - public SiliconflowImageOptions.Builder withNegativePrompt(String negativePrompt) {
157   - options.setNegativePrompt(negativePrompt);
158   - return this;
159   - }
160   -
161   - public SiliconflowImageOptions build() {
162   - return options;
163   - }
164   -
165   - }
166 105 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/SiliconFlowChatModelTests.java
1 1 package cn.iocoder.yudao.framework.ai.chat;
2 2  
3   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiiconflowApiConstants;
  3 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowApiConstants;
4 4 import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowChatModel;
5 5 import org.junit.jupiter.api.Disabled;
6 6 import org.junit.jupiter.api.Test;
... ... @@ -26,11 +26,11 @@ public class SiliconFlowChatModelTests {
26 26  
27 27 private final OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()
28 28 .openAiApi(OpenAiApi.builder()
29   - .baseUrl(SiiconflowApiConstants.DEFAULT_BASE_URL)
  29 + .baseUrl(SiliconFlowApiConstants.DEFAULT_BASE_URL)
30 30 .apiKey("sk-epsakfenqnyzoxhmbucsxlhkdqlcbnimslqoivkshalvdozz") // apiKey
31 31 .build())
32 32 .defaultOptions(OpenAiChatOptions.builder()
33   - .model(SiiconflowApiConstants.MODEL_DEFAULT) // 模型
  33 + .model(SiliconFlowApiConstants.MODEL_DEFAULT) // 模型
34 34 // .model("deepseek-ai/DeepSeek-R1") // 模型(deepseek-ai/DeepSeek-R1)可用赠费
35 35 // .model("Pro/deepseek-ai/DeepSeek-R1") // 模型(Pro/deepseek-ai/DeepSeek-R1)需要付费
36 36 .temperature(0.7)
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/SiliconFlowImageModelTests.java
1 1 package cn.iocoder.yudao.framework.ai.image;
2 2  
3   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiiconflowmageApi;
4   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconflowImageModel;
5   -import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconflowImageOptions;
  3 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowImageApi;
  4 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowImageModel;
  5 +import cn.iocoder.yudao.framework.ai.core.model.siliconflow.SiliconFlowImageOptions;
6 6 import org.junit.jupiter.api.Disabled;
7 7 import org.junit.jupiter.api.Test;
8 8 import org.springframework.ai.image.ImagePrompt;
9 9 import org.springframework.ai.image.ImageResponse;
10 10  
11 11 /**
12   - * {@link SiliconflowImageModel} 集成测试
  12 + * {@link SiliconFlowImageModel} 集成测试
13 13 */
14 14 public class SiliconFlowImageModelTests {
15 15  
16   - private final SiliconflowImageModel imageModel = new SiliconflowImageModel(
17   - new SiiconflowmageApi("sk-epsakfenqnyzoxhmbucsxlhkdqlcbnimslqoivkshalvdozz") // 密钥
  16 + private final SiliconFlowImageModel imageModel = new SiliconFlowImageModel(
  17 + new SiliconFlowImageApi("sk-epsakfenqnyzoxhmbucsxlhkdqlcbnimslqoivkshalvdozz") // 密钥
18 18 );
19 19  
20 20 @Test
21 21 @Disabled
22 22 public void testCall() {
23 23 // 准备参数
24   - SiliconflowImageOptions imageOptions = SiliconflowImageOptions.builder()
  24 + SiliconFlowImageOptions imageOptions = SiliconFlowImageOptions.builder()
25 25 .model("Kwai-Kolors/Kolors")
26 26 .build();
27 27 ImagePrompt prompt = new ImagePrompt("万里长城", imageOptions);
... ...