From c3e36c19ead84ae4706103470c49cccb440a0ce7 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Sun, 17 Mar 2024 09:46:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=8D=E5=88=B6=20spring-ai=20image?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/framework/ai/image/Image.java | 73 +++++++++++ .../yudao/framework/ai/image/ImageClient.java | 27 ++++ .../framework/ai/image/ImageGeneration.java | 52 ++++++++ .../ai/image/ImageGenerationMetadata.java | 23 ++++ .../framework/ai/image/ImageMessage.java | 63 ++++++++++ .../framework/ai/image/ImageOptions.java | 37 ++++++ .../ai/image/ImageOptionsBuilder.java | 119 ++++++++++++++++++ .../yudao/framework/ai/image/ImagePrompt.java | 84 +++++++++++++ .../framework/ai/image/ImageResponse.java | 75 +++++++++++ .../ai/image/ImageResponseMetadata.java | 31 +++++ 10 files changed, 584 insertions(+) create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/Image.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageClient.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGeneration.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGenerationMetadata.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageMessage.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptions.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptionsBuilder.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImagePrompt.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponse.java create mode 100644 yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponseMetadata.java diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/Image.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/Image.java new file mode 100644 index 000000000..b56ceb746 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/Image.java @@ -0,0 +1,73 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +import java.util.Objects; + +public class Image { + + /** + * The URL where the image can be accessed. + */ + private String url; + + /** + * Base64 encoded image string. + */ + private String b64Json; + + public Image(String url, String b64Json) { + this.url = url; + this.b64Json = b64Json; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getB64Json() { + return b64Json; + } + + public void setB64Json(String b64Json) { + this.b64Json = b64Json; + } + + @Override + public String toString() { + return "Image{" + "url='" + url + '\'' + ", b64Json='" + b64Json + '\'' + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Image image)) + return false; + return Objects.equals(url, image.url) && Objects.equals(b64Json, image.b64Json); + } + + @Override + public int hashCode() { + return Objects.hash(url, b64Json); + } + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageClient.java new file mode 100644 index 000000000..3034fbf02 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageClient.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + + +import cn.iocoder.yudao.framework.ai.model.ModelClient; + +@FunctionalInterface +public interface ImageClient extends ModelClient { + + ImageResponse call(ImagePrompt request); + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGeneration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGeneration.java new file mode 100644 index 000000000..16942fde1 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGeneration.java @@ -0,0 +1,52 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + + +import cn.iocoder.yudao.framework.ai.model.ModelResult; + +public class ImageGeneration implements ModelResult { + + private ImageGenerationMetadata imageGenerationMetadata; + + private Image image; + + public ImageGeneration(Image image) { + this.image = image; + } + + public ImageGeneration(Image image, ImageGenerationMetadata imageGenerationMetadata) { + this.image = image; + this.imageGenerationMetadata = imageGenerationMetadata; + } + + @Override + public Image getOutput() { + return image; + } + + @Override + public ImageGenerationMetadata getMetadata() { + return imageGenerationMetadata; + } + + @Override + public String toString() { + return "ImageGeneration{" + "imageGenerationMetadata=" + imageGenerationMetadata + ", image=" + image + '}'; + } + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGenerationMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGenerationMetadata.java new file mode 100644 index 000000000..1d620d2c7 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageGenerationMetadata.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +import cn.iocoder.yudao.framework.ai.model.ResultMetadata; + +public interface ImageGenerationMetadata extends ResultMetadata { + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageMessage.java new file mode 100644 index 000000000..6a01c6c21 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageMessage.java @@ -0,0 +1,63 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +import java.util.Objects; + +public class ImageMessage { + + private String text; + + private Float weight; + + public ImageMessage(String text) { + this.text = text; + } + + public ImageMessage(String text, Float weight) { + this.text = text; + this.weight = weight; + } + + public String getText() { + return text; + } + + public Float getWeight() { + return weight; + } + + @Override + public String toString() { + return "mageMessage{" + "text='" + text + '\'' + ", weight=" + weight + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof ImageMessage that)) + return false; + return Objects.equals(text, that.text) && Objects.equals(weight, that.weight); + } + + @Override + public int hashCode() { + return Objects.hash(text, weight); + } + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptions.java new file mode 100644 index 000000000..d9cfd0e86 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptions.java @@ -0,0 +1,37 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +import cn.iocoder.yudao.framework.ai.model.ModelOptions; + +/** + * ImageOptions represent the common options, portable across different image generation + * models. + */ +public interface ImageOptions extends ModelOptions { + + Integer getN(); + + String getModel(); + + Integer getWidth(); + + Integer getHeight(); + + String getResponseFormat(); // openai - url or base64 : stability ai byte[] or base64 + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptionsBuilder.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptionsBuilder.java new file mode 100644 index 000000000..d1bc47473 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageOptionsBuilder.java @@ -0,0 +1,119 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +public class ImageOptionsBuilder { + + private class ImageModelOptionsImpl implements ImageOptions { + + private Integer n; + + private String model; + + private Integer width; + + private Integer height; + + private String responseFormat; + + @Override + public Integer getN() { + return n; + } + + public void setN(Integer n) { + this.n = n; + } + + @Override + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + @Override + public String getResponseFormat() { + return responseFormat; + } + + public void setResponseFormat(String responseFormat) { + this.responseFormat = responseFormat; + } + + @Override + public Integer getWidth() { + return width; + } + + public void setWidth(Integer width) { + this.width = width; + } + + @Override + public Integer getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = height; + } + + } + + private final ImageModelOptionsImpl options = new ImageModelOptionsImpl(); + + private ImageOptionsBuilder() { + + } + + public static ImageOptionsBuilder builder() { + return new ImageOptionsBuilder(); + } + + public ImageOptionsBuilder withN(Integer n) { + options.setN(n); + return this; + } + + public ImageOptionsBuilder withModel(String model) { + options.setModel(model); + return this; + } + + public ImageOptionsBuilder withResponseFormat(String responseFormat) { + options.setResponseFormat(responseFormat); + return this; + } + + public ImageOptionsBuilder withWidth(Integer width) { + options.setWidth(width); + return this; + } + + public ImageOptionsBuilder withHeight(Integer height) { + options.setHeight(height); + return this; + } + + public ImageOptions build() { + return options; + } + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImagePrompt.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImagePrompt.java new file mode 100644 index 000000000..c8fac6ef6 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImagePrompt.java @@ -0,0 +1,84 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +import cn.iocoder.yudao.framework.ai.model.ModelRequest; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * 图片内容 + */ +public class ImagePrompt implements ModelRequest> { + + private final List messages; + + private ImageOptions imageModelOptions; + + public ImagePrompt(List messages) { + this.messages = messages; + } + + public ImagePrompt(List messages, ImageOptions imageModelOptions) { + this.messages = messages; + this.imageModelOptions = imageModelOptions; + } + + public ImagePrompt(ImageMessage imageMessage, ImageOptions imageOptions) { + this(Collections.singletonList(imageMessage), imageOptions); + } + + public ImagePrompt(String instructions, ImageOptions imageOptions) { + this(new ImageMessage(instructions), imageOptions); + } + + public ImagePrompt(String instructions) { + this(new ImageMessage(instructions), ImageOptionsBuilder.builder().build()); + } + + @Override + public List getInstructions() { + return messages; + } + + @Override + public ImageOptions getOptions() { + return imageModelOptions; + } + + @Override + public String toString() { + return "NewImagePrompt{" + "messages=" + messages + ", imageModelOptions=" + imageModelOptions + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof ImagePrompt that)) + return false; + return Objects.equals(messages, that.messages) && Objects.equals(imageModelOptions, that.imageModelOptions); + } + + @Override + public int hashCode() { + return Objects.hash(messages, imageModelOptions); + } + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponse.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponse.java new file mode 100644 index 000000000..ca91be5c0 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponse.java @@ -0,0 +1,75 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + +import cn.iocoder.yudao.framework.ai.model.ModelResponse; + +import java.util.List; +import java.util.Objects; + +public class ImageResponse implements ModelResponse { + + private final ImageResponseMetadata imageResponseMetadata; + + private final List imageGenerations; + + public ImageResponse(List generations) { + this(generations, ImageResponseMetadata.NULL); + } + + public ImageResponse(List generations, ImageResponseMetadata imageResponseMetadata) { + this.imageResponseMetadata = imageResponseMetadata; + this.imageGenerations = List.copyOf(generations); + } + + @Override + public ImageGeneration getResult() { + return imageGenerations.get(0); + } + + @Override + public List getResults() { + return imageGenerations; + } + + @Override + public ImageResponseMetadata getMetadata() { + return imageResponseMetadata; + } + + @Override + public String toString() { + return "ImageResponse{" + "imageResponseMetadata=" + imageResponseMetadata + ", imageGenerations=" + + imageGenerations + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof ImageResponse that)) + return false; + return Objects.equals(imageResponseMetadata, that.imageResponseMetadata) + && Objects.equals(imageGenerations, that.imageGenerations); + } + + @Override + public int hashCode() { + return Objects.hash(imageResponseMetadata, imageGenerations); + } + +} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponseMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponseMetadata.java new file mode 100644 index 000000000..c4332c6c3 --- /dev/null +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/image/ImageResponseMetadata.java @@ -0,0 +1,31 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.yudao.framework.ai.image; + + +import cn.iocoder.yudao.framework.ai.model.ResponseMetadata; + +public interface ImageResponseMetadata extends ResponseMetadata { + + ImageResponseMetadata NULL = new ImageResponseMetadata() { + }; + + default Long created() { + return System.currentTimeMillis(); + } + +}