Commit a14aebd5ee2a71b2548a8b71ab1cf74ea17f4efc
1 parent
633b1126
对接 openai dall-e-3,发送请求解析地址存在问题,链接不上
Showing
8 changed files
with
412 additions
and
3 deletions
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/imageopenai/OpenAiImageApi.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.imageopenai; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageRequest; | ||
| 4 | +import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageResponse; | ||
| 5 | +import cn.iocoder.yudao.framework.ai.util.JacksonUtil; | ||
| 6 | +import io.netty.channel.ChannelOption; | ||
| 7 | +import org.springframework.http.client.reactive.ReactorClientHttpConnector; | ||
| 8 | +import org.springframework.web.reactive.function.BodyInserters; | ||
| 9 | +import org.springframework.web.reactive.function.client.WebClient; | ||
| 10 | +import reactor.netty.http.client.HttpClient; | ||
| 11 | + | ||
| 12 | +import java.time.Duration; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * open ai image | ||
| 16 | + * <p> | ||
| 17 | + * author: fansili | ||
| 18 | + * time: 2024/3/17 09:53 | ||
| 19 | + */ | ||
| 20 | +public class OpenAiImageApi { | ||
| 21 | + | ||
| 22 | + private static final String DEFAULT_BASE_URL = "https://api.openai.com"; | ||
| 23 | + private String apiKey = "your-api-key"; | ||
| 24 | + // 发送请求 webClient | ||
| 25 | + private final WebClient webClient; | ||
| 26 | + | ||
| 27 | + public OpenAiImageApi(String apiKey) { | ||
| 28 | + this.apiKey = apiKey; | ||
| 29 | + // 创建一个HttpClient实例并设置超时 | ||
| 30 | + HttpClient httpClient = HttpClient.create() | ||
| 31 | + .responseTimeout(Duration.ofSeconds(300)) // 设置响应超时时间为30秒 | ||
| 32 | + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000 * 100); // 设置连接超时为5秒 | ||
| 33 | + this.webClient = WebClient.builder() | ||
| 34 | + .baseUrl(DEFAULT_BASE_URL) | ||
| 35 | + .clientConnector(new ReactorClientHttpConnector(httpClient)) | ||
| 36 | + .build(); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + public OpenAiImageResponse createImage(OpenAiImageRequest request) { | ||
| 40 | + String res = webClient.post() | ||
| 41 | + .uri(uriBuilder -> uriBuilder.path("/v1/images/generations").build()) | ||
| 42 | + .header("Content-Type", "application/json") | ||
| 43 | + .header("Authorization", "Bearer " + apiKey) | ||
| 44 | + // 设置请求体(这里假设jsonStr是一个JSON格式的字符串) | ||
| 45 | + .body(BodyInserters.fromValue(JacksonUtil.toJson(request))) | ||
| 46 | + // 发送请求并获取响应体 | ||
| 47 | + .retrieve() | ||
| 48 | + // 转换响应体为String类型 | ||
| 49 | + .bodyToMono(String.class) | ||
| 50 | + .block(); | ||
| 51 | + // TODO: 2024/3/17 这里发送请求会失败! | ||
| 52 | + return null; | ||
| 53 | + } | ||
| 54 | +} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/imageopenai/OpenAiImageClient.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.imageopenai; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.bean.BeanUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.ai.chat.ChatException; | ||
| 5 | +import cn.iocoder.yudao.framework.ai.chatyiyan.exception.YiYanApiException; | ||
| 6 | +import cn.iocoder.yudao.framework.ai.image.ImageClient; | ||
| 7 | +import cn.iocoder.yudao.framework.ai.image.ImageOptions; | ||
| 8 | +import cn.iocoder.yudao.framework.ai.image.ImagePrompt; | ||
| 9 | +import cn.iocoder.yudao.framework.ai.image.ImageResponse; | ||
| 10 | +import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageRequest; | ||
| 11 | +import cn.iocoder.yudao.framework.ai.imageopenai.api.OpenAiImageResponse; | ||
| 12 | +import jdk.jfr.Frequency; | ||
| 13 | +import lombok.extern.slf4j.Slf4j; | ||
| 14 | +import org.springframework.retry.RetryCallback; | ||
| 15 | +import org.springframework.retry.RetryContext; | ||
| 16 | +import org.springframework.retry.RetryListener; | ||
| 17 | +import org.springframework.retry.support.RetryTemplate; | ||
| 18 | + | ||
| 19 | +import java.time.Duration; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * open ai 生成 image | ||
| 23 | + * | ||
| 24 | + * author: fansili | ||
| 25 | + * time: 2024/3/17 09:51 | ||
| 26 | + */ | ||
| 27 | +@Slf4j | ||
| 28 | +public class OpenAiImageClient implements ImageClient { | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * open image ai | ||
| 32 | + */ | ||
| 33 | + private OpenAiImageApi openAiImageApi; | ||
| 34 | + /** | ||
| 35 | + * 默认使用的 ImageOptions | ||
| 36 | + */ | ||
| 37 | + private OpenAiImageOptions defaultImageOptions; | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + public final RetryTemplate retryTemplate = RetryTemplate.builder() | ||
| 41 | + // 最大重试次数 10 | ||
| 42 | + .maxAttempts(10) | ||
| 43 | + .retryOn(YiYanApiException.class) | ||
| 44 | + // 最大重试5次,第一次间隔3000ms,第二次3000ms * 2,第三次3000ms * 3,以此类推,最大间隔3 * 60000ms | ||
| 45 | + .exponentialBackoff(Duration.ofMillis(3000), 2, Duration.ofMillis(3 * 60000)) | ||
| 46 | + .withListener(new RetryListener() { | ||
| 47 | + @Override | ||
| 48 | + public <T extends Object, E extends Throwable> void onError(RetryContext context, | ||
| 49 | + RetryCallback<T, E> callback, Throwable throwable) { | ||
| 50 | + log.warn("重试异常:" + context.getRetryCount(), throwable); | ||
| 51 | + }; | ||
| 52 | + }) | ||
| 53 | + .build(); | ||
| 54 | + | ||
| 55 | + public OpenAiImageClient(OpenAiImageApi openAiImageApi, OpenAiImageOptions defaultImageOptions) { | ||
| 56 | + this.openAiImageApi = openAiImageApi; | ||
| 57 | + this.defaultImageOptions = defaultImageOptions; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public ImageResponse call(ImagePrompt imagePrompt) { | ||
| 62 | + return this.retryTemplate.execute(ctx -> { | ||
| 63 | + // 检查是否配置了 OpenAiImageOptions | ||
| 64 | + if (defaultImageOptions == null && imagePrompt.getOptions() == null) { | ||
| 65 | + throw new ChatException("OpenAiImageOptions 未配置参数!"); | ||
| 66 | + } | ||
| 67 | + // 优先使用 request 中的 ImageOptions | ||
| 68 | + ImageOptions useImageOptions = imagePrompt.getOptions() == null ? defaultImageOptions : imagePrompt.getOptions(); | ||
| 69 | + if (!(useImageOptions instanceof OpenAiImageOptions)) { | ||
| 70 | + throw new ChatException("配置信息不正确,传入的必须是 OpenAiImageOptions!"); | ||
| 71 | + } | ||
| 72 | + // 转换 OpenAiImageOptions | ||
| 73 | + OpenAiImageOptions openAiImageOptions = (OpenAiImageOptions) useImageOptions; | ||
| 74 | + // 创建请求 | ||
| 75 | + OpenAiImageRequest request = new OpenAiImageRequest(); | ||
| 76 | + BeanUtil.copyProperties(openAiImageOptions, request); | ||
| 77 | + // 发送请求 | ||
| 78 | + OpenAiImageResponse response = openAiImageApi.createImage(request); | ||
| 79 | + return null; | ||
| 80 | + }); | ||
| 81 | + } | ||
| 82 | +} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/imageopenai/OpenAiImageOptions.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.imageopenai; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.ai.image.ImageOptions; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import lombok.experimental.Accessors; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * open ai 配置文件 | ||
| 9 | + * | ||
| 10 | + * 文档地址:https://platform.openai.com/docs/api-reference/images/create | ||
| 11 | + * | ||
| 12 | + * author: fansili | ||
| 13 | + * time: 2024/3/17 09:53 | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@Accessors(chain = true) | ||
| 17 | +public class OpenAiImageOptions implements ImageOptions { | ||
| 18 | + | ||
| 19 | + // 必填字段,用于描述期望生成图像的文字说明。对于dall-e-2模型最大长度为1000个字符,对于dall-e-3模型最大长度为4000个字符。 | ||
| 20 | + private String prompt; | ||
| 21 | + | ||
| 22 | + // 可选字段,默认为dall-e-2 | ||
| 23 | + // 指定用于生成图像的模型名称。 | ||
| 24 | + private String model = "dall-e-2"; | ||
| 25 | + | ||
| 26 | + // 可选字段,默认为1 | ||
| 27 | + // 生成图像的数量,必须在1到10之间。对于dall-e-3模型,目前仅支持n=1。 | ||
| 28 | + private Integer n = 1; | ||
| 29 | + | ||
| 30 | + // 可选字段,默认为standard | ||
| 31 | + // 设置生成图像的质量。hd质量将创建细节更丰富、图像整体一致性更高的图片。该参数仅对dall-e-3模型有效。 | ||
| 32 | + private String quality = "standard"; | ||
| 33 | + | ||
| 34 | + // 可选字段,默认为url | ||
| 35 | + // 返回生成图像的格式。必须是url或b64_json中的一种。URL链接的有效期是从生成图像后开始计算的60分钟内有效。 | ||
| 36 | + private String responseFormat = "url"; | ||
| 37 | + | ||
| 38 | + // 可选字段,默认为1024x1024 | ||
| 39 | + // 生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。 | ||
| 40 | + private String imageSize = "1024x1024"; | ||
| 41 | + | ||
| 42 | + // 可选字段,默认为vivid | ||
| 43 | + // 图像生成的风格。可为vivid(生动)或natural(自然)。vivid会使模型偏向生成超现实和戏剧性的图像,而natural则会让模型产出更自然、不那么超现实的图像。该参数仅对dall-e-3模型有效。 | ||
| 44 | + private String style = "vivid"; | ||
| 45 | + | ||
| 46 | + // 可选字段 | ||
| 47 | + // 代表您的终端用户的唯一标识符,有助于OpenAI监控并检测滥用行为。了解更多信息请参考官方文档。 | ||
| 48 | + private String endUserId; | ||
| 49 | + | ||
| 50 | + // | ||
| 51 | + // 适配 spring ai | ||
| 52 | + | ||
| 53 | + @Override | ||
| 54 | + public Integer getN() { | ||
| 55 | + return this.n; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + public String getModel() { | ||
| 60 | + return this.model; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 64 | + public Integer getWidth() { | ||
| 65 | + return null; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @Override | ||
| 69 | + public Integer getHeight() { | ||
| 70 | + return null; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + @Override | ||
| 74 | + public String getResponseFormat() { | ||
| 75 | + return this.responseFormat; | ||
| 76 | + } | ||
| 77 | +} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/imageopenai/api/OpenAiImageRequest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.imageopenai.api; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonProperty; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import lombok.experimental.Accessors; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * open ai 配置文件 | ||
| 9 | + * | ||
| 10 | + * 文档地址:https://platform.openai.com/docs/api-reference/images/create | ||
| 11 | + * | ||
| 12 | + * author: fansili | ||
| 13 | + * time: 2024/3/17 09:53 | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@Accessors(chain = true) | ||
| 17 | +public class OpenAiImageRequest { | ||
| 18 | + | ||
| 19 | + // 必填字段,用于描述期望生成图像的文字说明。对于dall-e-2模型最大长度为1000个字符,对于dall-e-3模型最大长度为4000个字符。 | ||
| 20 | + @JsonProperty("prompt") | ||
| 21 | + private String prompt; | ||
| 22 | + | ||
| 23 | + // 可选字段,默认为dall-e-2、dall-e-3 | ||
| 24 | + // 指定用于生成图像的模型名称。 | ||
| 25 | + @JsonProperty("model") | ||
| 26 | + private String model = "dall-e-2"; | ||
| 27 | + | ||
| 28 | + // 可选字段,默认为1 | ||
| 29 | + // 生成图像的数量,必须在1到10之间。对于dall-e-3模型,目前仅支持n=1。 | ||
| 30 | + @JsonProperty("n") | ||
| 31 | + private Integer n = 1; | ||
| 32 | + | ||
| 33 | + // 可选字段,默认为standard | ||
| 34 | + // 设置生成图像的质量。hd质量将创建细节更丰富、图像整体一致性更高的图片。该参数仅对dall-e-3模型有效。 | ||
| 35 | + @JsonProperty("quality") | ||
| 36 | + private String quality = "standard"; | ||
| 37 | + | ||
| 38 | + // 可选字段,默认为url | ||
| 39 | + // 返回生成图像的格式。必须是url或b64_json中的一种。URL链接的有效期是从生成图像后开始计算的60分钟内有效。 | ||
| 40 | + @JsonProperty("response_format") | ||
| 41 | + private String responseFormat = "url"; | ||
| 42 | + | ||
| 43 | + // 可选字段,默认为1024x1024 | ||
| 44 | + // 生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。 | ||
| 45 | + @JsonProperty("size") | ||
| 46 | + private String imageSize = "1024x1024"; | ||
| 47 | + | ||
| 48 | + // 可选字段,默认为vivid | ||
| 49 | + // 图像生成的风格。可为vivid(生动)或natural(自然)。vivid会使模型偏向生成超现实和戏剧性的图像,而natural则会让模型产出更自然、不那么超现实的图像。该参数仅对dall-e-3模型有效。 | ||
| 50 | + @JsonProperty("style") | ||
| 51 | + private String style = "vivid"; | ||
| 52 | + | ||
| 53 | + // 可选字段 | ||
| 54 | + // 代表您的终端用户的唯一标识符,有助于OpenAI监控并检测滥用行为。了解更多信息请参考官方文档。 | ||
| 55 | + @JsonProperty("user") | ||
| 56 | + private String endUserId; | ||
| 57 | + | ||
| 58 | +} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/imageopenai/api/OpenAiImageResponse.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.imageopenai.api; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | +import lombok.experimental.Accessors; | ||
| 5 | + | ||
| 6 | +import java.util.List; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * image 返回 | ||
| 10 | + * | ||
| 11 | + * author: fansili | ||
| 12 | + * time: 2024/3/17 10:27 | ||
| 13 | + */ | ||
| 14 | +@Data | ||
| 15 | +@Accessors(chain = true) | ||
| 16 | +public class OpenAiImageResponse { | ||
| 17 | + | ||
| 18 | + private long created; | ||
| 19 | + private List<Item> data; | ||
| 20 | + | ||
| 21 | + @Data | ||
| 22 | + @Accessors(chain = true) | ||
| 23 | + public static class Item { | ||
| 24 | + | ||
| 25 | + private String url; | ||
| 26 | + | ||
| 27 | + } | ||
| 28 | +} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/util/JacksonUtil.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.util; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonInclude; | ||
| 4 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
| 5 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 6 | +import com.fasterxml.jackson.databind.SerializationFeature; | ||
| 7 | +import com.fasterxml.jackson.databind.module.SimpleModule; | ||
| 8 | +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | ||
| 9 | + | ||
| 10 | +import java.io.IOException; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * Jackson工具类 | ||
| 14 | + * | ||
| 15 | + * author: fansili | ||
| 16 | + * time: 2024/3/17 10:13 | ||
| 17 | + */ | ||
| 18 | +public class JacksonUtil { | ||
| 19 | + | ||
| 20 | + private static final ObjectMapper objectMapper = new ObjectMapper(); | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 初始化 ObjectMapper 以美化输出(即格式化JSON内容) | ||
| 24 | + */ | ||
| 25 | + static { | ||
| 26 | + // 美化输出(缩进) | ||
| 27 | + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); | ||
| 28 | + // 忽略值为 null 的属性 | ||
| 29 | + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | ||
| 30 | + // 配置一个模块来将 Long 类型转换为 String 类型 | ||
| 31 | + SimpleModule module = new SimpleModule(); | ||
| 32 | + module.addSerializer(Long.class, ToStringSerializer.instance); | ||
| 33 | + objectMapper.registerModule(module); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 将对象转换为 JSON 字符串 | ||
| 38 | + * | ||
| 39 | + * @param obj 需要序列化的Java对象 | ||
| 40 | + * @return 序列化后的 JSON 字符串 | ||
| 41 | + * @throws JsonProcessingException 当 JSON 序列化过程中出现错误时抛出异常 | ||
| 42 | + */ | ||
| 43 | + public static String toJson(Object obj) { | ||
| 44 | + try { | ||
| 45 | + return objectMapper.writeValueAsString(obj); | ||
| 46 | + } catch (JsonProcessingException e) { | ||
| 47 | + throw new RuntimeException(e); | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * 将 JSON 字符串反序列化为指定类型的对象 | ||
| 53 | + * | ||
| 54 | + * @param json JSON 字符串 | ||
| 55 | + * @param clazz 目标类型 Class 对象 | ||
| 56 | + * @param <T> 泛型类型参数 | ||
| 57 | + * @return 反序列化后的 Java 对象 | ||
| 58 | + * @throws IOException 当 JSON 解析过程中出现错误时抛出异常 | ||
| 59 | + */ | ||
| 60 | + public static <T> T fromJson(String json, Class<T> clazz) { | ||
| 61 | + try { | ||
| 62 | + return objectMapper.readValue(json, clazz); | ||
| 63 | + } catch (JsonProcessingException e) { | ||
| 64 | + throw new RuntimeException(e); | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * 将对象转换为格式化的 JSON 字符串(已启用 INDENT_OUTPUT 功能,所以所有方法都会返回格式化后的 JSON) | ||
| 70 | + * | ||
| 71 | + * @param obj 需要序列化的Java对象 | ||
| 72 | + * @return 格式化后的 JSON 字符串 | ||
| 73 | + * @throws JsonProcessingException 当 JSON 序列化过程中出现错误时抛出异常 | ||
| 74 | + */ | ||
| 75 | + public static String toFormattedJson(Object obj) { | ||
| 76 | + // 已在类初始化时设置了 SerializationFeature.INDENT_OUTPUT,此处无需额外操作 | ||
| 77 | + return toJson(obj); | ||
| 78 | + } | ||
| 79 | +} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java
| @@ -23,9 +23,9 @@ public class QianWenChatClientTests { | @@ -23,9 +23,9 @@ public class QianWenChatClientTests { | ||
| 23 | @Before | 23 | @Before |
| 24 | public void setup() { | 24 | public void setup() { |
| 25 | QianWenApi qianWenApi = new QianWenApi( | 25 | QianWenApi qianWenApi = new QianWenApi( |
| 26 | - "", | ||
| 27 | - "", | ||
| 28 | - "", | 26 | + "LTAI5tNTVhXW4fLKUjMrr98z", |
| 27 | + "ZJ0JQeyjzxxm5CfeTV6k1wNE9UsvZP", | ||
| 28 | + "f0c1088824594f589c8f10567ccd929f_p_efm", | ||
| 29 | null | 29 | null |
| 30 | ); | 30 | ); |
| 31 | qianWenChatClient = new QianWenChatClient( | 31 | qianWenChatClient = new QianWenChatClient( |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageClientTests.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.image; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageApi; | ||
| 4 | +import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient; | ||
| 5 | +import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions; | ||
| 6 | +import org.junit.Before; | ||
| 7 | +import org.junit.Test; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * author: fansili | ||
| 11 | + * time: 2024/3/17 10:40 | ||
| 12 | + */ | ||
| 13 | +public class OpenAiImageClientTests { | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + private OpenAiImageClient openAiImageClient; | ||
| 17 | + | ||
| 18 | + @Before | ||
| 19 | + public void setup() { | ||
| 20 | + // 初始化 openAiImageClient | ||
| 21 | + this.openAiImageClient = new OpenAiImageClient( | ||
| 22 | + new OpenAiImageApi(""), | ||
| 23 | + new OpenAiImageOptions() | ||
| 24 | + ); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + @Test | ||
| 28 | + public void callTest() { | ||
| 29 | + openAiImageClient.call(new ImagePrompt("我和我的小狗,一起在北极和企鹅玩排球。")); | ||
| 30 | + } | ||
| 31 | +} |