Skip to content

Commit b8dfc09

Browse files
jasonparallelilayaperumalg
authored andcommitted
Builders across Mistral module
- Deprecated overloaded constructors. Signed-off-by: Jason Smith <[email protected]>
1 parent 93cf476 commit b8dfc09

File tree

18 files changed

+288
-59
lines changed

18 files changed

+288
-59
lines changed

auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiChatAutoConfiguration.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,13 @@ private MistralAiApi mistralAiApi(String apiKey, String commonApiKey, String bas
104104
Assert.hasText(resolvedApiKey, "Mistral API key must be set");
105105
Assert.hasText(resoledBaseUrl, "Mistral base URL must be set");
106106

107-
return new MistralAiApi(resoledBaseUrl, resolvedApiKey, restClientBuilder, webClientBuilder,
108-
responseErrorHandler);
107+
return MistralAiApi.builder()
108+
.baseUrl(resoledBaseUrl)
109+
.apiKey(resolvedApiKey)
110+
.restClientBuilder(restClientBuilder)
111+
.webClientBuilder(webClientBuilder)
112+
.responseErrorHandler(responseErrorHandler)
113+
.build();
109114
}
110115

111116
}

auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiEmbeddingAutoConfiguration.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,13 @@ public MistralAiEmbeddingModel mistralAiEmbeddingModel(MistralAiCommonProperties
6868
embeddingProperties.getBaseUrl(), commonProperties.getBaseUrl(),
6969
restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler);
7070

71-
var embeddingModel = new MistralAiEmbeddingModel(mistralAiApi, embeddingProperties.getMetadataMode(),
72-
embeddingProperties.getOptions(), retryTemplate,
73-
observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP));
71+
var embeddingModel = MistralAiEmbeddingModel.builder()
72+
.mistralAiApi(mistralAiApi)
73+
.metadataMode(embeddingProperties.getMetadataMode())
74+
.options(embeddingProperties.getOptions())
75+
.retryTemplate(retryTemplate)
76+
.observationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
77+
.build();
7478

7579
observationConvention.ifAvailable(embeddingModel::setObservationConvention);
7680

@@ -86,7 +90,12 @@ private MistralAiApi mistralAiApi(String apiKey, String commonApiKey, String bas
8690
Assert.hasText(resolvedApiKey, "Mistral API key must be set");
8791
Assert.hasText(resoledBaseUrl, "Mistral base URL must be set");
8892

89-
return new MistralAiApi(resoledBaseUrl, resolvedApiKey, restClientBuilder, responseErrorHandler);
93+
return MistralAiApi.builder()
94+
.baseUrl(resoledBaseUrl)
95+
.apiKey(resolvedApiKey)
96+
.restClientBuilder(restClientBuilder)
97+
.responseErrorHandler(responseErrorHandler)
98+
.build();
9099
}
91100

92101
}

auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiModerationAutoConfiguration.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,18 @@ public MistralAiModerationModel mistralAiModerationModel(MistralAiCommonProperti
6868
Assert.hasText(resolvedApiKey, "Mistral API key must be set");
6969
Assert.hasText(resoledBaseUrl, "Mistral base URL must be set");
7070

71-
var mistralAiModerationAi = new MistralAiModerationApi(resoledBaseUrl, resolvedApiKey,
72-
restClientBuilderProvider.getIfAvailable(RestClient::builder), responseErrorHandler);
71+
var mistralAiModerationApi = MistralAiModerationApi.builder()
72+
.baseUrl(resoledBaseUrl)
73+
.apiKey(resolvedApiKey)
74+
.restClientBuilder(restClientBuilderProvider.getIfAvailable(RestClient::builder))
75+
.responseErrorHandler(responseErrorHandler)
76+
.build();
7377

74-
return new MistralAiModerationModel(mistralAiModerationAi, retryTemplate, moderationProperties.getOptions());
78+
return MistralAiModerationModel.builder()
79+
.mistralAiModerationApi(mistralAiModerationApi)
80+
.retryTemplate(retryTemplate)
81+
.options(moderationProperties.getOptions())
82+
.build();
7583
}
7684

7785
}

auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/test/java/org/springframework/ai/model/mistralai/autoconfigure/MistralAiPropertiesTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ public void embeddingOptionsTest() {
128128

129129
new ApplicationContextRunner()
130130
.withPropertyValues("spring.ai.mistralai.api-key=API_KEY", "spring.ai.mistralai.base-url=TEST_BASE_URL",
131-
132131
"spring.ai.mistralai.embedding.options.model=MODEL_XYZ",
133132
"spring.ai.mistralai.embedding.options.encodingFormat=MyEncodingFormat")
134133
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,

models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatModel.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
* @author Ilayaperumal Gopinathan
8787
* @author Alexandros Pappas
8888
* @author Nicolas Krier
89+
* @author Jason Smith
8990
* @since 1.0.0
9091
*/
9192
public class MistralAiChatModel implements ChatModel {
@@ -126,6 +127,7 @@ public class MistralAiChatModel implements ChatModel {
126127
*/
127128
private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION;
128129

130+
@Deprecated
129131
public MistralAiChatModel(MistralAiApi mistralAiApi, MistralAiChatOptions defaultOptions,
130132
ToolCallingManager toolCallingManager, RetryTemplate retryTemplate,
131133
ObservationRegistry observationRegistry) {
@@ -584,7 +586,7 @@ public static final class Builder {
584586
.model(MistralAiApi.ChatModel.SMALL.getValue())
585587
.build();
586588

587-
private ToolCallingManager toolCallingManager;
589+
private ToolCallingManager toolCallingManager = DEFAULT_TOOL_CALLING_MANAGER;
588590

589591
private ToolExecutionEligibilityPredicate toolExecutionEligibilityPredicate = new DefaultToolExecutionEligibilityPredicate();
590592

@@ -627,11 +629,7 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) {
627629
}
628630

629631
public MistralAiChatModel build() {
630-
if (this.toolCallingManager != null) {
631-
return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, this.toolCallingManager,
632-
this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate);
633-
}
634-
return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER,
632+
return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, this.toolCallingManager,
635633
this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate);
636634
}
637635

models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
* @author Christian Tzolov
4646
* @author Thomas Vitale
4747
* @author Alexandros Pappas
48+
* @author Jason Smith
4849
* @since 0.8.1
4950
*/
5051
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -405,7 +406,7 @@ public boolean equals(Object obj) {
405406
&& Objects.equals(this.toolContext, other.toolContext);
406407
}
407408

408-
public static class Builder {
409+
public static final class Builder {
409410

410411
private final MistralAiChatOptions options = new MistralAiChatOptions();
411412

models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingModel.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
* @see AbstractEmbeddingModel
4848
* @author Ricken Bazolo
4949
* @author Thomas Vitale
50+
* @author Jason Smith
5051
* @since 1.0.0
5152
*/
5253
public class MistralAiEmbeddingModel extends AbstractEmbeddingModel {
@@ -73,20 +74,24 @@ public class MistralAiEmbeddingModel extends AbstractEmbeddingModel {
7374
*/
7475
private EmbeddingModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION;
7576

77+
@Deprecated
7678
public MistralAiEmbeddingModel(MistralAiApi mistralAiApi) {
7779
this(mistralAiApi, MetadataMode.EMBED);
7880
}
7981

82+
@Deprecated
8083
public MistralAiEmbeddingModel(MistralAiApi mistralAiApi, MetadataMode metadataMode) {
8184
this(mistralAiApi, metadataMode,
8285
MistralAiEmbeddingOptions.builder().withModel(MistralAiApi.EmbeddingModel.EMBED.getValue()).build(),
8386
RetryUtils.DEFAULT_RETRY_TEMPLATE);
8487
}
8588

89+
@Deprecated
8690
public MistralAiEmbeddingModel(MistralAiApi mistralAiApi, MistralAiEmbeddingOptions options) {
8791
this(mistralAiApi, MetadataMode.EMBED, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
8892
}
8993

94+
@Deprecated
9095
public MistralAiEmbeddingModel(MistralAiApi mistralAiApi, MetadataMode metadataMode,
9196
MistralAiEmbeddingOptions options, RetryTemplate retryTemplate) {
9297
this(mistralAiApi, metadataMode, options, retryTemplate, ObservationRegistry.NOOP);
@@ -188,4 +193,54 @@ public void setObservationConvention(EmbeddingModelObservationConvention observa
188193
this.observationConvention = observationConvention;
189194
}
190195

196+
public static Builder builder() {
197+
return new Builder();
198+
}
199+
200+
public static final class Builder {
201+
202+
private MistralAiApi mistralAiApi;
203+
204+
private MetadataMode metadataMode = MetadataMode.EMBED;
205+
206+
private MistralAiEmbeddingOptions options = MistralAiEmbeddingOptions.builder()
207+
.withModel(MistralAiApi.EmbeddingModel.EMBED.getValue())
208+
.build();
209+
210+
private RetryTemplate retryTemplate = RetryUtils.DEFAULT_RETRY_TEMPLATE;
211+
212+
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
213+
214+
public Builder mistralAiApi(MistralAiApi mistralAiApi) {
215+
this.mistralAiApi = mistralAiApi;
216+
return this;
217+
}
218+
219+
public Builder metadataMode(MetadataMode metadataMode) {
220+
this.metadataMode = metadataMode;
221+
return this;
222+
}
223+
224+
public Builder options(MistralAiEmbeddingOptions options) {
225+
this.options = options;
226+
return this;
227+
}
228+
229+
public Builder retryTemplate(RetryTemplate retryTemplate) {
230+
this.retryTemplate = retryTemplate;
231+
return this;
232+
}
233+
234+
public Builder observationRegistry(ObservationRegistry observationRegistry) {
235+
this.observationRegistry = observationRegistry;
236+
return this;
237+
}
238+
239+
public MistralAiEmbeddingModel build() {
240+
return new MistralAiEmbeddingModel(this.mistralAiApi, this.metadataMode, this.options, this.retryTemplate,
241+
this.observationRegistry);
242+
}
243+
244+
}
245+
191246
}

models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
2828
*
2929
* @author Ricken Bazolo
3030
* @author Thomas Vitale
31+
* @author Jason Smith
3132
* @since 0.8.1
3233
*/
3334
@JsonInclude(Include.NON_NULL)
@@ -70,7 +71,7 @@ public Integer getDimensions() {
7071
return null;
7172
}
7273

73-
public static class Builder {
74+
public static final class Builder {
7475

7576
protected MistralAiEmbeddingOptions options;
7677

models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/api/MistralAiApi.java

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,15 @@
6161
* @author Ricken Bazolo
6262
* @author Christian Tzolov
6363
* @author Thomas Vitale
64+
* @author Jason Smith
6465
* @since 1.0.0
6566
*/
6667
public class MistralAiApi {
6768

69+
public static Builder builder() {
70+
return new Builder();
71+
}
72+
6873
public static final String PROVIDER_NAME = AiProvider.MISTRAL_AI.value();
6974

7075
private static final String DEFAULT_BASE_URL = "https://api.mistral.ai";
@@ -79,45 +84,48 @@ public class MistralAiApi {
7984

8085
/**
8186
* Create a new client api with DEFAULT_BASE_URL
82-
* @param mistralAiApiKey Mistral api Key.
87+
* @param apiKey Mistral api Key.
8388
*/
84-
public MistralAiApi(String mistralAiApiKey) {
85-
this(DEFAULT_BASE_URL, mistralAiApiKey);
89+
@Deprecated
90+
public MistralAiApi(String apiKey) {
91+
this(DEFAULT_BASE_URL, apiKey);
8692
}
8793

8894
/**
8995
* Create a new client api.
9096
* @param baseUrl api base URL.
91-
* @param mistralAiApiKey Mistral api Key.
97+
* @param apiKey Mistral api Key.
9298
*/
93-
public MistralAiApi(String baseUrl, String mistralAiApiKey) {
94-
this(baseUrl, mistralAiApiKey, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
99+
@Deprecated
100+
public MistralAiApi(String baseUrl, String apiKey) {
101+
this(baseUrl, apiKey, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
95102
}
96103

97104
/**
98105
* Create a new client api.
99106
* @param baseUrl api base URL.
100-
* @param mistralAiApiKey Mistral api Key.
107+
* @param apiKey Mistral api Key.
101108
* @param restClientBuilder RestClient builder.
102109
* @param responseErrorHandler Response error handler.
103110
*/
104-
public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder restClientBuilder,
111+
@Deprecated
112+
public MistralAiApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder,
105113
ResponseErrorHandler responseErrorHandler) {
106-
this(baseUrl, mistralAiApiKey, restClientBuilder, WebClient.builder(), responseErrorHandler);
114+
this(baseUrl, apiKey, restClientBuilder, WebClient.builder(), responseErrorHandler);
107115
}
108116

109117
/**
110118
* Create a new client api.
111119
* @param baseUrl api base URL.
112-
* @param mistralAiApiKey Mistral api Key.
120+
* @param apiKey Mistral api Key.
113121
* @param restClientBuilder RestClient builder.
114122
* @param responseErrorHandler Response error handler.
115123
*/
116-
public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder restClientBuilder,
124+
public MistralAiApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder,
117125
WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) {
118126

119127
Consumer<HttpHeaders> jsonContentHeaders = headers -> {
120-
headers.setBearerAuth(mistralAiApiKey);
128+
headers.setBearerAuth(apiKey);
121129
headers.setContentType(MediaType.APPLICATION_JSON);
122130
};
123131

@@ -1084,4 +1092,53 @@ public record ChunkChoice(
10841092

10851093
}
10861094

1095+
public static final class Builder {
1096+
1097+
private String baseUrl = DEFAULT_BASE_URL;
1098+
1099+
private String apiKey;
1100+
1101+
private RestClient.Builder restClientBuilder = RestClient.builder();
1102+
1103+
private WebClient.Builder webClientBuilder = WebClient.builder();
1104+
1105+
private ResponseErrorHandler responseErrorHandler = RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER;
1106+
1107+
public Builder baseUrl(String baseUrl) {
1108+
Assert.hasText(baseUrl, "baseUrl cannot be null or empty");
1109+
this.baseUrl = baseUrl;
1110+
return this;
1111+
}
1112+
1113+
public Builder apiKey(String apiKey) {
1114+
Assert.hasText(apiKey, "apiKey cannot be null or empty");
1115+
this.apiKey = apiKey;
1116+
return this;
1117+
}
1118+
1119+
public Builder restClientBuilder(RestClient.Builder restClientBuilder) {
1120+
Assert.notNull(restClientBuilder, "restClientBuilder cannot be null");
1121+
this.restClientBuilder = restClientBuilder;
1122+
return this;
1123+
}
1124+
1125+
public Builder webClientBuilder(WebClient.Builder webClientBuilder) {
1126+
Assert.notNull(webClientBuilder, "webClientBuilder cannot be null");
1127+
this.webClientBuilder = webClientBuilder;
1128+
return this;
1129+
}
1130+
1131+
public Builder responseErrorHandler(ResponseErrorHandler responseErrorHandler) {
1132+
Assert.notNull(responseErrorHandler, "responseErrorHandler cannot be null");
1133+
this.responseErrorHandler = responseErrorHandler;
1134+
return this;
1135+
}
1136+
1137+
public MistralAiApi build() {
1138+
return new MistralAiApi(this.baseUrl, this.apiKey, this.restClientBuilder, this.webClientBuilder,
1139+
this.responseErrorHandler);
1140+
}
1141+
1142+
}
1143+
10871144
}

0 commit comments

Comments
 (0)