Refactor QianFan model option builder methods
- Deprecate the builder methods with the prefix `with` and add the new methods - Update docs and references
This commit is contained in:
committed by
Mark Pollack
parent
071b897951
commit
18bc0cff25
@@ -104,8 +104,7 @@ public class QianFanChatModel implements ChatModel, StreamingChatModel {
|
||||
* @throws IllegalArgumentException if QianFanApi is null
|
||||
*/
|
||||
public QianFanChatModel(QianFanApi qianFanApi) {
|
||||
this(qianFanApi,
|
||||
QianFanChatOptions.builder().withModel(QianFanApi.DEFAULT_CHAT_MODEL).withTemperature(0.7).build());
|
||||
this(qianFanApi, QianFanChatOptions.builder().model(QianFanApi.DEFAULT_CHAT_MODEL).temperature(0.7).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.ai.qianfan.api.QianFanApi;
|
||||
* frequency penalty, max tokens, etc.
|
||||
*
|
||||
* @author Geng Rong
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @since 1.0
|
||||
* @see ChatOptions
|
||||
*/
|
||||
@@ -87,14 +88,14 @@ public class QianFanChatOptions implements ChatOptions {
|
||||
|
||||
public static QianFanChatOptions fromOptions(QianFanChatOptions fromOptions) {
|
||||
return QianFanChatOptions.builder()
|
||||
.withModel(fromOptions.getModel())
|
||||
.withFrequencyPenalty(fromOptions.getFrequencyPenalty())
|
||||
.withMaxTokens(fromOptions.getMaxTokens())
|
||||
.withPresencePenalty(fromOptions.getPresencePenalty())
|
||||
.withResponseFormat(fromOptions.getResponseFormat())
|
||||
.withStop(fromOptions.getStop())
|
||||
.withTemperature(fromOptions.getTemperature())
|
||||
.withTopP(fromOptions.getTopP())
|
||||
.model(fromOptions.getModel())
|
||||
.frequencyPenalty(fromOptions.getFrequencyPenalty())
|
||||
.maxTokens(fromOptions.getMaxTokens())
|
||||
.presencePenalty(fromOptions.getPresencePenalty())
|
||||
.responseFormat(fromOptions.getResponseFormat())
|
||||
.stop(fromOptions.getStop())
|
||||
.temperature(fromOptions.getTemperature())
|
||||
.topP(fromOptions.getTopP())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -296,41 +297,115 @@ public class QianFanChatOptions implements ChatOptions {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public Builder model(String model) {
|
||||
this.options.model = model;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder frequencyPenalty(Double frequencyPenalty) {
|
||||
this.options.frequencyPenalty = frequencyPenalty;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder maxTokens(Integer maxTokens) {
|
||||
this.options.maxTokens = maxTokens;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder presencePenalty(Double presencePenalty) {
|
||||
this.options.presencePenalty = presencePenalty;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder responseFormat(QianFanApi.ChatCompletionRequest.ResponseFormat responseFormat) {
|
||||
this.options.responseFormat = responseFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder stop(List<String> stop) {
|
||||
this.options.stop = stop;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder temperature(Double temperature) {
|
||||
this.options.temperature = temperature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder topP(Double topP) {
|
||||
this.options.topP = topP;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #model(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withModel(String model) {
|
||||
this.options.model = model;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #frequencyPenalty(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withFrequencyPenalty(Double frequencyPenalty) {
|
||||
this.options.frequencyPenalty = frequencyPenalty;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #maxTokens(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withMaxTokens(Integer maxTokens) {
|
||||
this.options.maxTokens = maxTokens;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #presencePenalty(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withPresencePenalty(Double presencePenalty) {
|
||||
this.options.presencePenalty = presencePenalty;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use
|
||||
* {@link #responseFormat(QianFanApi.ChatCompletionRequest.ResponseFormat)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withResponseFormat(QianFanApi.ChatCompletionRequest.ResponseFormat responseFormat) {
|
||||
this.options.responseFormat = responseFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #stop(List)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withStop(List<String> stop) {
|
||||
this.options.stop = stop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #temperature(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withTemperature(Double temperature) {
|
||||
this.options.temperature = temperature;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #topP(Double)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withTopP(Double topP) {
|
||||
this.options.topP = topP;
|
||||
return this;
|
||||
|
||||
@@ -90,7 +90,7 @@ public class QianFanEmbeddingModel extends AbstractEmbeddingModel {
|
||||
*/
|
||||
public QianFanEmbeddingModel(QianFanApi qianFanApi, MetadataMode metadataMode) {
|
||||
this(qianFanApi, metadataMode,
|
||||
QianFanEmbeddingOptions.builder().withModel(QianFanApi.DEFAULT_EMBEDDING_MODEL).build());
|
||||
QianFanEmbeddingOptions.builder().model(QianFanApi.DEFAULT_EMBEDDING_MODEL).build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,8 +206,8 @@ public class QianFanEmbeddingModel extends AbstractEmbeddingModel {
|
||||
}
|
||||
|
||||
return QianFanEmbeddingOptions.builder()
|
||||
.withModel(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
|
||||
.withUser(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
|
||||
.model(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
|
||||
.user(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.ai.embedding.EmbeddingOptions;
|
||||
*
|
||||
* @author Geng Rong
|
||||
* @author Thomas Vitale
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @since 1.0
|
||||
*/
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
@@ -81,11 +82,29 @@ public class QianFanEmbeddingOptions implements EmbeddingOptions {
|
||||
this.options = new QianFanEmbeddingOptions();
|
||||
}
|
||||
|
||||
public Builder model(String model) {
|
||||
this.options.setModel(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder user(String user) {
|
||||
this.options.setUser(user);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #model(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withModel(String model) {
|
||||
this.options.setModel(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #user(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withUser(String user) {
|
||||
this.options.setUser(user);
|
||||
return this;
|
||||
|
||||
@@ -203,14 +203,13 @@ public class QianFanImageModel implements ImageModel {
|
||||
}
|
||||
|
||||
return QianFanImageOptions.builder()
|
||||
.withModel(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
|
||||
.withN(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getN(), defaultOptions.getN()))
|
||||
.withModel(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
|
||||
.withWidth(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getWidth(), defaultOptions.getWidth()))
|
||||
.withHeight(
|
||||
ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getHeight(), defaultOptions.getHeight()))
|
||||
.withStyle(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getStyle(), defaultOptions.getStyle()))
|
||||
.withUser(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
|
||||
.model(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
|
||||
.N(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getN(), defaultOptions.getN()))
|
||||
.model(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getModel(), defaultOptions.getModel()))
|
||||
.width(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getWidth(), defaultOptions.getWidth()))
|
||||
.height(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getHeight(), defaultOptions.getHeight()))
|
||||
.style(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getStyle(), defaultOptions.getStyle()))
|
||||
.user(ModelOptionsUtils.mergeOption(runtimeOptionsForProvider.getUser(), defaultOptions.getUser()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.ai.image.ImageOptions;
|
||||
* QianFan Image API options. QianFanImageOptions.java
|
||||
*
|
||||
* @author Geng Rong
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @since 1.0
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -196,31 +197,85 @@ public final class QianFanImageOptions implements ImageOptions {
|
||||
this.options = new QianFanImageOptions();
|
||||
}
|
||||
|
||||
public Builder N(Integer n) {
|
||||
this.options.setN(n);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder model(String model) {
|
||||
this.options.setModel(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder width(Integer width) {
|
||||
this.options.setWidth(width);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder height(Integer height) {
|
||||
this.options.setHeight(height);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder style(String style) {
|
||||
this.options.setStyle(style);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder user(String user) {
|
||||
this.options.setUser(user);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #N(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withN(Integer n) {
|
||||
this.options.setN(n);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #model(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withModel(String model) {
|
||||
this.options.setModel(model);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #width(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withWidth(Integer width) {
|
||||
this.options.setWidth(width);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #height(Integer)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withHeight(Integer height) {
|
||||
this.options.setHeight(height);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #style(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withStyle(String style) {
|
||||
this.options.setStyle(style);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #user(String)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.0.0-M5")
|
||||
public Builder withUser(String user) {
|
||||
this.options.setUser(user);
|
||||
return this;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ChatCompletionRequestTests {
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new QianFanChatModel(new QianFanApi("TEST", "TEST"),
|
||||
QianFanChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6).build());
|
||||
QianFanChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build());
|
||||
|
||||
var request = client.createRequest(new Prompt("Test message content"), false);
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ChatCompletionRequestTests {
|
||||
assertThat(request.temperature()).isEqualTo(66.6);
|
||||
|
||||
request = client.createRequest(new Prompt("Test message content",
|
||||
QianFanChatOptions.builder().withModel("PROMPT_MODEL").withTemperature(99.9).build()), true);
|
||||
QianFanChatOptions.builder().model("PROMPT_MODEL").temperature(99.9).build()), true);
|
||||
|
||||
assertThat(request.messages()).hasSize(1);
|
||||
assertThat(request.stream()).isTrue();
|
||||
|
||||
@@ -71,13 +71,13 @@ public class QianFanChatModelObservationIT {
|
||||
void observationForChatOperation() {
|
||||
|
||||
var options = QianFanChatOptions.builder()
|
||||
.withModel(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.withFrequencyPenalty(0.0)
|
||||
.withMaxTokens(2048)
|
||||
.withPresencePenalty(0.0)
|
||||
.withStop(List.of("this-is-the-end"))
|
||||
.withTemperature(0.7)
|
||||
.withTopP(1.0)
|
||||
.model(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.frequencyPenalty(0.0)
|
||||
.maxTokens(2048)
|
||||
.presencePenalty(0.0)
|
||||
.stop(List.of("this-is-the-end"))
|
||||
.temperature(0.7)
|
||||
.topP(1.0)
|
||||
.build();
|
||||
|
||||
Prompt prompt = new Prompt("Why does a raven look like a desk?", options);
|
||||
@@ -94,13 +94,13 @@ public class QianFanChatModelObservationIT {
|
||||
@Test
|
||||
void observationForStreamingChatOperation() {
|
||||
var options = QianFanChatOptions.builder()
|
||||
.withModel(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.withFrequencyPenalty(0.0)
|
||||
.withMaxTokens(2048)
|
||||
.withPresencePenalty(0.0)
|
||||
.withStop(List.of("this-is-the-end"))
|
||||
.withTemperature(0.7)
|
||||
.withTopP(1.0)
|
||||
.model(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.frequencyPenalty(0.0)
|
||||
.maxTokens(2048)
|
||||
.presencePenalty(0.0)
|
||||
.stop(List.of("this-is-the-end"))
|
||||
.temperature(0.7)
|
||||
.topP(1.0)
|
||||
.build();
|
||||
|
||||
Prompt prompt = new Prompt("Why does a raven look like a desk?", options);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class QianFanEmbeddingModelObservationIT {
|
||||
@Test
|
||||
void observationForEmbeddingOperation() {
|
||||
var options = QianFanEmbeddingOptions.builder()
|
||||
.withModel(QianFanApi.EmbeddingModel.BGE_LARGE_ZH.getValue())
|
||||
.model(QianFanApi.EmbeddingModel.BGE_LARGE_ZH.getValue())
|
||||
.build();
|
||||
|
||||
EmbeddingRequest embeddingRequest = new EmbeddingRequest(List.of("Here comes the sun"), options);
|
||||
|
||||
@@ -59,10 +59,10 @@ public class QianFanImageModelObservationIT {
|
||||
@Test
|
||||
void observationForImageOperation() {
|
||||
var options = QianFanImageOptions.builder()
|
||||
.withModel(QianFanImageApi.ImageModel.Stable_Diffusion_XL.getValue())
|
||||
.withHeight(1024)
|
||||
.withWidth(1024)
|
||||
.withStyle("Base")
|
||||
.model(QianFanImageApi.ImageModel.Stable_Diffusion_XL.getValue())
|
||||
.height(1024)
|
||||
.width(1024)
|
||||
.style("Base")
|
||||
.build();
|
||||
|
||||
var instructions = "Here comes the sun";
|
||||
|
||||
@@ -124,8 +124,8 @@ ChatResponse response = chatClient.call(
|
||||
new Prompt(
|
||||
"Generate the names of 5 famous pirates.",
|
||||
QianFanChatOptions.builder()
|
||||
.withModel(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.withTemperature(0.5)
|
||||
.model(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.temperature(0.5)
|
||||
.build()
|
||||
));
|
||||
----
|
||||
@@ -208,9 +208,9 @@ Next, create a `QianFanChatModel` and use it for text generations:
|
||||
var qianFanApi = new QianFanApi(System.getenv("QIANFAN_API_KEY"), System.getenv("QIANFAN_SECRET_KEY"));
|
||||
|
||||
var chatClient = new QianFanChatModel(this.qianFanApi, QianFanChatOptions.builder()
|
||||
.withModel(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.withTemperature(0.4)
|
||||
.withMaxTokens(200)
|
||||
.model(QianFanApi.ChatModel.ERNIE_Speed_8K.getValue())
|
||||
.temperature(0.4)
|
||||
.maxTokens(200)
|
||||
.build());
|
||||
|
||||
ChatResponse response = this.chatClient.call(
|
||||
|
||||
@@ -120,7 +120,7 @@ For example to override the default model name for a specific request:
|
||||
EmbeddingResponse embeddingResponse = embeddingClient.call(
|
||||
new EmbeddingRequest(List.of("Hello World", "World is big and salvation is near"),
|
||||
QianFanEmbeddingOptions.builder()
|
||||
.withModel("Different-Embedding-Model-Deployment-Name")
|
||||
.model("Different-Embedding-Model-Deployment-Name")
|
||||
.build()));
|
||||
----
|
||||
|
||||
@@ -188,10 +188,9 @@ Next, create an `QianFanEmbeddingModel` instance and use it to compute the simil
|
||||
----
|
||||
var qianFanApi = new QianFanApi(System.getenv("MINIMAX_API_KEY"), System.getenv("QIANFAN_SECRET_KEY"));
|
||||
|
||||
var embeddingClient = new QianFanEmbeddingModel(qianFanApi)
|
||||
.withDefaultOptions(QianFanChatOptions.build()
|
||||
.withModel("bge_large_en")
|
||||
.build());
|
||||
var embeddingClient = new QianFanEmbeddingModel(api, MetadataMode.EMBED, QianFanEmbeddingOptions.builder()
|
||||
.model("bge_large_en")
|
||||
.build());
|
||||
|
||||
EmbeddingResponse embeddingResponse = this.embeddingClient
|
||||
.embedForResponse(List.of("Hello World", "World is big and salvation is near"));
|
||||
|
||||
@@ -110,9 +110,9 @@ For example to override the QianFan specific options such as quality and the num
|
||||
ImageResponse response = qianFanImageModel.call(
|
||||
new ImagePrompt("A light cream colored mini golden doodle",
|
||||
QianFanImageOptions.builder()
|
||||
.withN(4)
|
||||
.withHeight(1024)
|
||||
.withWidth(1024).build())
|
||||
.N(4)
|
||||
.height(1024)
|
||||
.width(1024).build())
|
||||
|
||||
);
|
||||
----
|
||||
|
||||
@@ -42,8 +42,8 @@ public class QianFanChatProperties extends QianFanParentProperties {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private QianFanChatOptions options = QianFanChatOptions.builder()
|
||||
.withModel(DEFAULT_CHAT_MODEL)
|
||||
.withTemperature(DEFAULT_TEMPERATURE)
|
||||
.model(DEFAULT_CHAT_MODEL)
|
||||
.temperature(DEFAULT_TEMPERATURE)
|
||||
.build();
|
||||
|
||||
public QianFanChatOptions getOptions() {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class QianFanEmbeddingProperties extends QianFanParentProperties {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private QianFanEmbeddingOptions options = QianFanEmbeddingOptions.builder()
|
||||
.withModel(QianFanApi.DEFAULT_EMBEDDING_MODEL)
|
||||
.model(QianFanApi.DEFAULT_EMBEDDING_MODEL)
|
||||
.build();
|
||||
|
||||
public QianFanEmbeddingOptions getOptions() {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class QianFanImageProperties extends QianFanParentProperties {
|
||||
* Options for QianFan Image API.
|
||||
*/
|
||||
@NestedConfigurationProperty
|
||||
private QianFanImageOptions options = QianFanImageOptions.builder().withModel(DEFAULT_IMAGE_MODEL).build();
|
||||
private QianFanImageOptions options = QianFanImageOptions.builder().model(DEFAULT_IMAGE_MODEL).build();
|
||||
|
||||
public QianFanImageOptions getOptions() {
|
||||
return this.options;
|
||||
|
||||
Reference in New Issue
Block a user