feat: adapt spring-ai images api (#3678)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>pull/3686/head
parent
7ac3db5ff8
commit
cb3d302f24
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.example.tongyi.service.impl.images;
|
||||
|
||||
import com.alibaba.cloud.ai.example.tongyi.service.AbstractTongYiServiceImpl;
|
||||
import com.alibaba.cloud.ai.example.tongyi.service.TongYiService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.image.ImageClient;
|
||||
import org.springframework.ai.image.ImagePrompt;
|
||||
import org.springframework.ai.image.ImageResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* gen images example.
|
||||
*
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TongYiImagesServiceImpl extends AbstractTongYiServiceImpl {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TongYiService.class);
|
||||
|
||||
private final ImageClient imageClient;
|
||||
|
||||
@Autowired
|
||||
public TongYiImagesServiceImpl(ImageClient client) {
|
||||
|
||||
this.imageClient = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageResponse genImg(String imgPrompt) {
|
||||
|
||||
var prompt = new ImagePrompt(imgPrompt);
|
||||
|
||||
return imageClient.call(prompt);
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
[Spring AI](https://docs.spring.io/spring-ai/reference/0.8-SNAPSHOT/index.html) <br>
|
||||
[通义大模型](https://help.aliyun.com/zh/dashscope/developer-reference/model-introduction) <br>
|
||||
[Spring AI](https://docs.spring.io/spring-ai/reference/0.8-SNAPSHOT/index.html) <br><br>
|
||||
[通义大模型](https://help.aliyun.com/zh/dashscope/developer-reference/model-introduction) <br><br>
|
||||
[Spring AI chat completion api](https://docs.spring.io/spring-ai/reference/0.8-SNAPSHOT/api/chatclient.html)
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.tongyi;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* TongYi connection API properties.
|
||||
*
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
@ConfigurationProperties(TongYiConnectionProperties.CONFIG_PREFIX)
|
||||
public class TongYiConnectionProperties {
|
||||
|
||||
/**
|
||||
* Spring Cloud Alibaba AI configuration prefix.
|
||||
*/
|
||||
public static final String CONFIG_PREFIX = "spring.cloud.ai.tongyi";
|
||||
|
||||
/**
|
||||
* ApiKey.
|
||||
*/
|
||||
private String apiKey;
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.tongyi;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Base64;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.alibaba.cloud.ai.tongyi.exception.TongYiImagesException;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
|
||||
import com.alibaba.dashscope.exception.NoApiKeyException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.image.Image;
|
||||
import org.springframework.ai.image.ImageClient;
|
||||
import org.springframework.ai.image.ImageGeneration;
|
||||
import org.springframework.ai.image.ImageOptions;
|
||||
import org.springframework.ai.image.ImagePrompt;
|
||||
import org.springframework.ai.image.ImageResponse;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static com.alibaba.cloud.ai.tongyi.metadata.TongYiImagesResponseMetadata.from;
|
||||
|
||||
/**
|
||||
* TongYiImagesClient is a class that implements the ImageClient interface. It provides a
|
||||
* client for calling the TongYi AI image generation API.
|
||||
*
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
public class TongYiImagesClient implements ImageClient {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TongYiImagesClient.class);
|
||||
|
||||
/**
|
||||
* Gen Images API.
|
||||
*/
|
||||
private final ImageSynthesis imageSynthesis;
|
||||
|
||||
/**
|
||||
* TongYi Gen images properties.
|
||||
*/
|
||||
private TongYiImagesOptions defaultOptions;
|
||||
|
||||
/**
|
||||
* Adapt TongYi images api size properties.
|
||||
*/
|
||||
private final String sizeConnection = "*";
|
||||
|
||||
/**
|
||||
* Get default images options.
|
||||
*
|
||||
* @return Default TongYiImagesOptions.
|
||||
*/
|
||||
public TongYiImagesOptions getDefaultOptions() {
|
||||
|
||||
return this.defaultOptions;
|
||||
}
|
||||
|
||||
public TongYiImagesClient(ImageSynthesis imageSynthesis) {
|
||||
|
||||
this(imageSynthesis, TongYiImagesOptions.
|
||||
builder()
|
||||
.withModel(ImageSynthesis.Models.WANX_V1)
|
||||
.withN(1)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
public TongYiImagesClient(ImageSynthesis imageSynthesis, TongYiImagesOptions imagesOptions) {
|
||||
|
||||
Assert.notNull(imageSynthesis, "ImageSynthesis must not be null");
|
||||
Assert.notNull(imagesOptions, "TongYiImagesOptions must not be null");
|
||||
|
||||
this.imageSynthesis = imageSynthesis;
|
||||
this.defaultOptions = imagesOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageResponse call(ImagePrompt imagePrompt) {
|
||||
|
||||
ImageSynthesisResult result;
|
||||
String prompt = imagePrompt.getInstructions().get(0).getText();
|
||||
var imgParams = ImageSynthesisParam.builder()
|
||||
.prompt("")
|
||||
.model(ImageSynthesis.Models.WANX_V1)
|
||||
.build();
|
||||
|
||||
if (this.defaultOptions != null) {
|
||||
imgParams = merge(
|
||||
this.defaultOptions,
|
||||
imgParams
|
||||
);
|
||||
}
|
||||
|
||||
if (imagePrompt.getOptions() != null) {
|
||||
imgParams = merge(
|
||||
toTingYiImageOptions(imagePrompt.getOptions()),
|
||||
imgParams
|
||||
);
|
||||
}
|
||||
imgParams.setPrompt(prompt);
|
||||
|
||||
try {
|
||||
result = imageSynthesis.call(imgParams);
|
||||
}
|
||||
catch (NoApiKeyException e) {
|
||||
logger.error("TongYi models gen images failed: {}.", e.getMessage());
|
||||
throw new TongYiImagesException(e.getMessage());
|
||||
}
|
||||
|
||||
return convert(result);
|
||||
}
|
||||
|
||||
private ImageSynthesisParam merge(TongYiImagesOptions source, ImageSynthesisParam target) {
|
||||
|
||||
var builder = ImageSynthesisParam.builder();
|
||||
|
||||
if (source != null) {
|
||||
if (
|
||||
source.getHeight() != null
|
||||
&&
|
||||
source.getWidth() != null
|
||||
) {
|
||||
builder.size(source.getHeight() + sizeConnection + source.getWidth());
|
||||
}
|
||||
if (source.getModel() != null) {
|
||||
builder.model(source.getModel());
|
||||
}
|
||||
if (source.getN() != null) {
|
||||
builder.n(source.getN());
|
||||
}
|
||||
}
|
||||
|
||||
// prompt is marked non-null but is null.
|
||||
builder.prompt("");
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ImageResponse convert(ImageSynthesisResult result) {
|
||||
|
||||
return new ImageResponse(
|
||||
result.getOutput().getResults().stream()
|
||||
.flatMap(value -> value.entrySet().stream())
|
||||
.map(entry -> {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
try {
|
||||
String base64Image = convertImageToBase64(value);
|
||||
Image image = new Image(value, base64Image);
|
||||
return new ImageGeneration(image);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList()),
|
||||
from(result)
|
||||
);
|
||||
}
|
||||
|
||||
private TongYiImagesOptions toTingYiImageOptions(ImageOptions runtimeImageOptions) {
|
||||
|
||||
var builder = TongYiImagesOptions.builder();
|
||||
|
||||
if (runtimeImageOptions != null) {
|
||||
if (runtimeImageOptions.getN() != null) {
|
||||
|
||||
builder.withN(runtimeImageOptions.getN());
|
||||
}
|
||||
if (runtimeImageOptions.getModel() != null) {
|
||||
|
||||
builder.withModel(runtimeImageOptions.getModel());
|
||||
}
|
||||
if (runtimeImageOptions.getHeight() != null) {
|
||||
|
||||
builder.withHeight(runtimeImageOptions.getHeight());
|
||||
}
|
||||
if (runtimeImageOptions.getWidth() != null) {
|
||||
|
||||
builder.withWidth(runtimeImageOptions.getWidth());
|
||||
}
|
||||
|
||||
// todo ImagesParams.
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public String convertImageToBase64(String imageUrl) throws Exception {
|
||||
|
||||
var url = new URL(imageUrl);
|
||||
var inputStream = url.openStream();
|
||||
var outputStream = new ByteArrayOutputStream();
|
||||
var buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
var imageBytes = outputStream.toByteArray();
|
||||
|
||||
String base64Image = Base64.getEncoder().encodeToString(imageBytes);
|
||||
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
|
||||
return base64Image;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.tongyi;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.alibaba.cloud.ai.tongyi.exception.TongYiImagesException;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
|
||||
|
||||
import org.springframework.ai.image.ImageOptions;
|
||||
|
||||
/**
|
||||
* TongYi Image API options.
|
||||
*
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
public class TongYiImagesOptions implements ImageOptions {
|
||||
|
||||
/**
|
||||
* Specify the model name, currently only wanx-v1 is supported.
|
||||
*/
|
||||
private String model = ImageSynthesis.Models.WANX_V1;
|
||||
|
||||
/**
|
||||
* Gen images number.
|
||||
*/
|
||||
private Integer n;
|
||||
|
||||
/**
|
||||
* The width of the generated images.
|
||||
*/
|
||||
private Integer width = 1024;
|
||||
|
||||
/**
|
||||
* The height of the generated images.
|
||||
*/
|
||||
private Integer height = 1024;
|
||||
|
||||
@Override
|
||||
public Integer getN() {
|
||||
|
||||
return this.n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModel() {
|
||||
|
||||
return this.model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getWidth() {
|
||||
|
||||
return this.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getHeight() {
|
||||
|
||||
return this.height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponseFormat() {
|
||||
|
||||
throw new TongYiImagesException("unimplemented!");
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void setN(Integer n) {
|
||||
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public void setHeight(Integer height) {
|
||||
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TongYiImagesOptions that = (TongYiImagesOptions) o;
|
||||
|
||||
return Objects.equals(model, that.model)
|
||||
&& Objects.equals(n, that.n)
|
||||
&& Objects.equals(width, that.width)
|
||||
&& Objects.equals(height, that.height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(model, n, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
final StringBuilder sb = new StringBuilder("TongYiImagesOptions{");
|
||||
|
||||
sb.append("model='").append(model).append('\'');
|
||||
sb.append(", n=").append(n);
|
||||
sb.append(", width=").append(width);
|
||||
sb.append(", height=").append(height);
|
||||
sb.append('}');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public final static class Builder {
|
||||
|
||||
private final TongYiImagesOptions options;
|
||||
|
||||
private Builder() {
|
||||
this.options = new TongYiImagesOptions();
|
||||
}
|
||||
|
||||
public Builder withN(Integer n) {
|
||||
|
||||
options.setN(n);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withModel(String model) {
|
||||
|
||||
options.setModel(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withWidth(Integer width) {
|
||||
|
||||
options.setWidth(width);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withHeight(Integer height) {
|
||||
|
||||
options.setHeight(height);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TongYiImagesOptions build() {
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.tongyi;
|
||||
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
|
||||
/**
|
||||
* TongYi Image API properties.
|
||||
*
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
@ConfigurationProperties(TongYiImagesProperties.CONFIG_PREFIX)
|
||||
public class TongYiImagesProperties {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TongYiImagesProperties.class);
|
||||
|
||||
/**
|
||||
* Spring Cloud Alibaba AI configuration prefix.
|
||||
*/
|
||||
public static final String CONFIG_PREFIX = "spring.cloud.ai.tongyi.images";
|
||||
|
||||
/**
|
||||
* Default TongYi Chat model.
|
||||
*/
|
||||
public static final String DEFAULT_IMAGES_MODEL_NAME = ImageSynthesis.Models.WANX_V1;
|
||||
|
||||
/**
|
||||
* Enable TongYiQWEN ai chat client.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private TongYiImagesOptions options = TongYiImagesOptions.builder()
|
||||
.withModel(DEFAULT_IMAGES_MODEL_NAME)
|
||||
.withN(1)
|
||||
.build();
|
||||
|
||||
public TongYiImagesOptions getOptions() {
|
||||
|
||||
return this.options;
|
||||
}
|
||||
|
||||
public void setOptions(TongYiImagesOptions options) {
|
||||
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.tongyi.exception;
|
||||
|
||||
/**
|
||||
* TongYi models images exception.
|
||||
*
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
public class TongYiImagesException extends TongYiException {
|
||||
|
||||
public TongYiImagesException(String message) {
|
||||
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TongYiImagesException(String message, Throwable cause) {
|
||||
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2023-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 com.alibaba.cloud.ai.tongyi.metadata;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisTaskMetrics;
|
||||
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisUsage;
|
||||
|
||||
import org.springframework.ai.image.ImageResponseMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
|
||||
* @since 2023.0.0.0-RC1
|
||||
*/
|
||||
|
||||
public class TongYiImagesResponseMetadata implements ImageResponseMetadata {
|
||||
|
||||
private final Long created;
|
||||
|
||||
private String taskId;
|
||||
|
||||
private ImageSynthesisTaskMetrics metrics;
|
||||
|
||||
private ImageSynthesisUsage usage;
|
||||
|
||||
public static TongYiImagesResponseMetadata from(ImageSynthesisResult synthesisResult) {
|
||||
|
||||
Assert.notNull(synthesisResult, "TongYiAiImageResponse must not be null");
|
||||
|
||||
return new TongYiImagesResponseMetadata(
|
||||
System.currentTimeMillis(),
|
||||
synthesisResult.getOutput().getTaskMetrics(),
|
||||
synthesisResult.getOutput().getTaskId(),
|
||||
synthesisResult.getUsage()
|
||||
);
|
||||
}
|
||||
|
||||
protected TongYiImagesResponseMetadata(
|
||||
Long created,
|
||||
ImageSynthesisTaskMetrics metrics,
|
||||
String taskId,
|
||||
ImageSynthesisUsage usage
|
||||
) {
|
||||
|
||||
this.taskId = taskId;
|
||||
this.metrics = metrics;
|
||||
this.created = created;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public ImageSynthesisUsage getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public void setUsage(ImageSynthesisUsage usage) {
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public Long getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public String getTaskId() {
|
||||
return taskId;
|
||||
}
|
||||
|
||||
public void setTaskId(String taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
public ImageSynthesisTaskMetrics getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
void setMetrics(ImageSynthesisTaskMetrics metrics) {
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long created() {
|
||||
return this.created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TongYiImagesResponseMetadata {" + "created=" + created + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TongYiImagesResponseMetadata that = (TongYiImagesResponseMetadata) o;
|
||||
|
||||
return Objects.equals(created, that.created)
|
||||
&& Objects.equals(taskId, that.taskId)
|
||||
&& Objects.equals(metrics, that.metrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(created, taskId, metrics);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue