Skip to content

Commit 27f0322

Browse files
committed
Builders across Mistral project. Deprecated overloaded constructors.
Signed-off-by: Jason Smith <jasonparallel@gmail.com>
1 parent 925def2 commit 27f0322

File tree

20 files changed

+298
-60
lines changed

20 files changed

+298
-60
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(apiKey)
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
}

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
@@ -83,6 +83,7 @@
8383
* @author luocongqiu
8484
* @author Ilayaperumal Gopinathan
8585
* @author Alexandros Pappas
86+
* @author Jason Smith
8687
* @since 1.0.0
8788
*/
8889
public class MistralAiChatModel implements ChatModel {
@@ -123,6 +124,7 @@ public class MistralAiChatModel implements ChatModel {
123124
*/
124125
private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION;
125126

127+
@Deprecated
126128
public MistralAiChatModel(MistralAiApi mistralAiApi, MistralAiChatOptions defaultOptions,
127129
ToolCallingManager toolCallingManager, RetryTemplate retryTemplate,
128130
ObservationRegistry observationRegistry) {
@@ -538,7 +540,7 @@ public static final class Builder {
538540
.model(MistralAiApi.ChatModel.SMALL.getValue())
539541
.build();
540542

541-
private ToolCallingManager toolCallingManager;
543+
private ToolCallingManager toolCallingManager = DEFAULT_TOOL_CALLING_MANAGER;
542544

543545
private ToolExecutionEligibilityPredicate toolExecutionEligibilityPredicate = new DefaultToolExecutionEligibilityPredicate();
544546

@@ -581,11 +583,7 @@ public Builder observationRegistry(ObservationRegistry observationRegistry) {
581583
}
582584

583585
public MistralAiChatModel build() {
584-
if (this.toolCallingManager != null) {
585-
return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, this.toolCallingManager,
586-
this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate);
587-
}
588-
return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, DEFAULT_TOOL_CALLING_MANAGER,
586+
return new MistralAiChatModel(this.mistralAiApi, this.defaultOptions, this.toolCallingManager,
589587
this.retryTemplate, this.observationRegistry, this.toolExecutionEligibilityPredicate);
590588
}
591589

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)
@@ -403,7 +404,7 @@ public boolean equals(Object obj) {
403404
&& Objects.equals(this.toolContext, other.toolContext);
404405
}
405406

406-
public static class Builder {
407+
public static final class Builder {
407408

408409
private final MistralAiChatOptions options = new MistralAiChatOptions();
409410

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

Lines changed: 54 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,53 @@ 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(mistralAiApi, metadataMode, options, retryTemplate, observationRegistry);
241+
}
242+
243+
}
244+
191245
}

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: 70 additions & 13 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.
@@ -60,10 +60,15 @@
6060
* @author Ricken Bazolo
6161
* @author Christian Tzolov
6262
* @author Thomas Vitale
63+
* @author Jason Smith
6364
* @since 1.0.0
6465
*/
6566
public class MistralAiApi {
6667

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

6974
private static final String DEFAULT_BASE_URL = "https://api.mistral.ai";
@@ -78,45 +83,48 @@ public class MistralAiApi {
7883

7984
/**
8085
* Create a new client api with DEFAULT_BASE_URL
81-
* @param mistralAiApiKey Mistral api Key.
86+
* @param apiKey Mistral api Key.
8287
*/
83-
public MistralAiApi(String mistralAiApiKey) {
84-
this(DEFAULT_BASE_URL, mistralAiApiKey);
88+
@Deprecated
89+
public MistralAiApi(String apiKey) {
90+
this(DEFAULT_BASE_URL, apiKey);
8591
}
8692

8793
/**
8894
* Create a new client api.
8995
* @param baseUrl api base URL.
90-
* @param mistralAiApiKey Mistral api Key.
96+
* @param apiKey Mistral api Key.
9197
*/
92-
public MistralAiApi(String baseUrl, String mistralAiApiKey) {
93-
this(baseUrl, mistralAiApiKey, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
98+
@Deprecated
99+
public MistralAiApi(String baseUrl, String apiKey) {
100+
this(baseUrl, apiKey, RestClient.builder(), RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
94101
}
95102

96103
/**
97104
* Create a new client api.
98105
* @param baseUrl api base URL.
99-
* @param mistralAiApiKey Mistral api Key.
106+
* @param apiKey Mistral api Key.
100107
* @param restClientBuilder RestClient builder.
101108
* @param responseErrorHandler Response error handler.
102109
*/
103-
public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder restClientBuilder,
110+
@Deprecated
111+
public MistralAiApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder,
104112
ResponseErrorHandler responseErrorHandler) {
105-
this(baseUrl, mistralAiApiKey, restClientBuilder, WebClient.builder(), responseErrorHandler);
113+
this(baseUrl, apiKey, restClientBuilder, WebClient.builder(), responseErrorHandler);
106114
}
107115

108116
/**
109117
* Create a new client api.
110118
* @param baseUrl api base URL.
111-
* @param mistralAiApiKey Mistral api Key.
119+
* @param apiKey Mistral api Key.
112120
* @param restClientBuilder RestClient builder.
113121
* @param responseErrorHandler Response error handler.
114122
*/
115-
public MistralAiApi(String baseUrl, String mistralAiApiKey, RestClient.Builder restClientBuilder,
123+
public MistralAiApi(String baseUrl, String apiKey, RestClient.Builder restClientBuilder,
116124
WebClient.Builder webClientBuilder, ResponseErrorHandler responseErrorHandler) {
117125

118126
Consumer<HttpHeaders> jsonContentHeaders = headers -> {
119-
headers.setBearerAuth(mistralAiApiKey);
127+
headers.setBearerAuth(apiKey);
120128
headers.setContentType(MediaType.APPLICATION_JSON);
121129
};
122130

@@ -1074,4 +1082,53 @@ public record ChunkChoice(
10741082

10751083
}
10761084

1085+
public static final class Builder {
1086+
1087+
private String baseUrl = DEFAULT_BASE_URL;
1088+
1089+
private String apiKey;
1090+
1091+
private RestClient.Builder restClientBuilder = RestClient.builder();
1092+
1093+
private WebClient.Builder webClientBuilder = WebClient.builder();
1094+
1095+
private ResponseErrorHandler responseErrorHandler = RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER;
1096+
1097+
public Builder baseUrl(String baseUrl) {
1098+
Assert.hasText(baseUrl, "baseUrl cannot be null or empty");
1099+
this.baseUrl = baseUrl;
1100+
return this;
1101+
}
1102+
1103+
public Builder apiKey(String apiKey) {
1104+
Assert.hasText(apiKey, "apiKey cannot be null or empty");
1105+
this.apiKey = apiKey;
1106+
return this;
1107+
}
1108+
1109+
public Builder restClientBuilder(RestClient.Builder restClientBuilder) {
1110+
Assert.notNull(restClientBuilder, "restClientBuilder cannot be null");
1111+
this.restClientBuilder = restClientBuilder;
1112+
return this;
1113+
}
1114+
1115+
public Builder webClientBuilder(WebClient.Builder webClientBuilder) {
1116+
Assert.notNull(webClientBuilder, "webClientBuilder cannot be null");
1117+
this.webClientBuilder = webClientBuilder;
1118+
return this;
1119+
}
1120+
1121+
public Builder responseErrorHandler(ResponseErrorHandler responseErrorHandler) {
1122+
Assert.notNull(responseErrorHandler, "responseErrorHandler cannot be null");
1123+
this.responseErrorHandler = responseErrorHandler;
1124+
return this;
1125+
}
1126+
1127+
public MistralAiApi build() {
1128+
return new MistralAiApi(this.baseUrl, this.apiKey, this.restClientBuilder, this.webClientBuilder,
1129+
this.responseErrorHandler);
1130+
}
1131+
1132+
}
1133+
10771134
}

0 commit comments

Comments
 (0)