diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageAutoConfiguration.java
index a7eee06fd3d..e9d4a3e04f2 100644
--- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageAutoConfiguration.java
+++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageAutoConfiguration.java
@@ -49,6 +49,7 @@
* @author Stefan Vassilev
* @author Thomas Vitale
* @author Ilayaperumal Gopinathan
+ * @author lambochen
*/
@AutoConfiguration(after = { RestClientAutoConfiguration.class, WebClientAutoConfiguration.class,
SpringAiRetryAutoConfiguration.class })
@@ -75,6 +76,7 @@ public OpenAiImageModel openAiImageModel(OpenAiConnectionProperties commonProper
.baseUrl(resolved.baseUrl())
.apiKey(new SimpleApiKey(resolved.apiKey()))
.headers(resolved.headers())
+ .imagesPath(imageProperties.getImagesPath())
.restClientBuilder(restClientBuilderProvider.getIfAvailable(RestClient::builder))
.responseErrorHandler(responseErrorHandler)
.build();
diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageProperties.java b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageProperties.java
index ff96b49ddfb..43b80f52f8e 100644
--- a/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageProperties.java
+++ b/auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/java/org/springframework/ai/model/openai/autoconfigure/OpenAiImageProperties.java
@@ -25,6 +25,7 @@
* OpenAI Image autoconfiguration properties.
*
* @author Thomas Vitale
+ * @author lambochen
* @since 0.8.0
*/
@ConfigurationProperties(OpenAiImageProperties.CONFIG_PREFIX)
@@ -32,6 +33,10 @@ public class OpenAiImageProperties extends OpenAiParentProperties {
public static final String CONFIG_PREFIX = "spring.ai.openai.image";
+ public static final String DEFAULT_IMAGES_PATH = "v1/images/generations";
+
+ private String imagesPath = DEFAULT_IMAGES_PATH;
+
public static final String DEFAULT_IMAGE_MODEL = OpenAiImageApi.ImageModel.DALL_E_3.getValue();
/**
@@ -48,4 +53,12 @@ public void setOptions(OpenAiImageOptions options) {
this.options = options;
}
+ public String getImagesPath() {
+ return imagesPath;
+ }
+
+ public void setImagesPath(String imagesPath) {
+ this.imagesPath = imagesPath;
+ }
+
}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
index c6e79b70b64..bd32d42d9f6 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
@@ -39,6 +39,7 @@
* OpenAI Image API.
*
* @see Images
+ * @author lambochen
*/
public class OpenAiImageApi {
@@ -46,15 +47,18 @@ public class OpenAiImageApi {
private final RestClient restClient;
+ private final String imagesPath;
+
/**
* Create a new OpenAI Image API with the provided base URL.
* @param baseUrl the base URL for the OpenAI API.
* @param apiKey OpenAI apiKey.
* @param headers the http headers to use.
+ * @param imagesPath the images path to use.
* @param restClientBuilder the rest client builder to use.
* @param responseErrorHandler the response error handler to use.
*/
- public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap headers,
+ public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap headers, String imagesPath,
RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) {
// @formatter:off
@@ -69,6 +73,8 @@ public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap createImage(OpenAiImageRequest openAiImageRequest) {
@@ -76,7 +82,7 @@ public ResponseEntity createImage(OpenAiImageRequest openAi
Assert.hasLength(openAiImageRequest.prompt(), "Prompt cannot be empty.");
return this.restClient.post()
- .uri("v1/images/generations")
+ .uri(this.imagesPath)
.body(openAiImageRequest)
.retrieve()
.toEntity(OpenAiImageResponse.class);
@@ -163,12 +169,20 @@ public static class Builder {
private ResponseErrorHandler responseErrorHandler = RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER;
+ private String imagesPath = "v1/images/generations";
+
public Builder baseUrl(String baseUrl) {
Assert.hasText(baseUrl, "baseUrl cannot be null or empty");
this.baseUrl = baseUrl;
return this;
}
+ public Builder imagesPath(String imagesPath) {
+ Assert.hasText(imagesPath, "imagesPath cannot be null or empty");
+ this.imagesPath = imagesPath;
+ return this;
+ }
+
public Builder apiKey(ApiKey apiKey) {
Assert.notNull(apiKey, "apiKey cannot be null");
this.apiKey = apiKey;
@@ -201,7 +215,7 @@ public Builder responseErrorHandler(ResponseErrorHandler responseErrorHandler) {
public OpenAiImageApi build() {
Assert.notNull(this.apiKey, "apiKey must be set");
- return new OpenAiImageApi(this.baseUrl, this.apiKey, this.headers, this.restClientBuilder,
+ return new OpenAiImageApi(this.baseUrl, this.apiKey, this.headers, this.imagesPath, this.restClientBuilder,
this.responseErrorHandler);
}