Skip to content

Commit 4ba932b

Browse files
ilayaperumalgmarkpollack
authored andcommitted
Refactor auto-configurations
- Split model autoconfigurations based on the model - Change the autoconfiguration class into model specific autoconfigurations - chat, embedding, image etc., - Update/add tests based on this change - Make sure the conditional logic to enable the model auto configuration is at the class level so that the configuration properties as well as the models are not enabled when the model is explicitly disabled. By default, the condition will allow enabling the beans if not explicitly overridden. - Remove spring-ai-spring-boot-autoconfigure as a dedicated auto-configuration module Signed-off-by: Ilayaperumal Gopinathan <[email protected]>
1 parent 8a1dcfc commit 4ba932b

File tree

375 files changed

+1775
-22857
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

375 files changed

+1775
-22857
lines changed

auto-configurations/models/spring-ai-autoconfigure-model-anthropic/pom.xml

-3
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,18 @@
3939
<groupId>org.springframework.ai</groupId>
4040
<artifactId>spring-ai-autoconfigure-model-tool</artifactId>
4141
<version>${project.parent.version}</version>
42-
<optional>true</optional>
4342
</dependency>
4443

4544
<dependency>
4645
<groupId>org.springframework.ai</groupId>
4746
<artifactId>spring-ai-autoconfigure-retry</artifactId>
4847
<version>${project.parent.version}</version>
49-
<optional>true</optional>
5048
</dependency>
5149

5250
<dependency>
5351
<groupId>org.springframework.ai</groupId>
5452
<artifactId>spring-ai-autoconfigure-model-chat-observation</artifactId>
5553
<version>${project.parent.version}</version>
56-
<optional>true</optional>
5754
</dependency>
5855

5956
<!-- Boot dependencies -->
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@
5656
ToolCallingAutoConfiguration.class })
5757
@EnableConfigurationProperties({ AnthropicChatProperties.class, AnthropicConnectionProperties.class })
5858
@ConditionalOnClass(AnthropicApi.class)
59+
@ConditionalOnProperty(name = SpringAIModelProperties.CHAT_MODEL, havingValue = SpringAIModels.ANTHROPIC,
60+
matchIfMissing = true)
5961
@ImportAutoConfiguration(classes = { SpringAiRetryAutoConfiguration.class, RestClientAutoConfiguration.class,
6062
ToolCallingAutoConfiguration.class, WebClientAutoConfiguration.class })
61-
public class AnthropicAutoConfiguration {
63+
public class AnthropicChatAutoConfiguration {
6264

6365
@Bean
6466
@ConditionalOnMissingBean
@@ -74,8 +76,6 @@ public AnthropicApi anthropicApi(AnthropicConnectionProperties connectionPropert
7476

7577
@Bean
7678
@ConditionalOnMissingBean
77-
@ConditionalOnProperty(name = SpringAIModelProperties.CHAT_MODEL, havingValue = SpringAIModels.ANTHROPIC,
78-
matchIfMissing = true)
7979
public AnthropicChatModel anthropicChatModel(AnthropicApi anthropicApi, AnthropicChatProperties chatProperties,
8080
RetryTemplate retryTemplate, ToolCallingManager toolCallingManager,
8181
ObjectProvider<ObservationRegistry> observationRegistry,

auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
#
16-
org.springframework.ai.model.anthropic.autoconfigure.AnthropicAutoConfiguration
16+
org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@
3939
import static org.assertj.core.api.Assertions.assertThat;
4040

4141
@EnabledIfEnvironmentVariable(named = "ANTHROPIC_API_KEY", matches = ".*")
42-
public class AnthropicAutoConfigurationIT {
42+
public class AnthropicChatAutoConfigurationIT {
4343

44-
private static final Log logger = LogFactory.getLog(AnthropicAutoConfigurationIT.class);
44+
private static final Log logger = LogFactory.getLog(AnthropicChatAutoConfigurationIT.class);
4545

4646
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
4747
.withPropertyValues("spring.ai.anthropic.apiKey=" + System.getenv("ANTHROPIC_API_KEY"))
48-
.withConfiguration(AutoConfigurations.of(AnthropicAutoConfiguration.class));
48+
.withConfiguration(AutoConfigurations.of(AnthropicChatAutoConfiguration.class));
4949

5050
@Test
5151
void call() {

auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicModelConfigurationTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525
import static org.assertj.core.api.Assertions.assertThat;
2626

2727
/**
28-
* Unit Tests for {@link AnthropicAutoConfiguration}'s conditional enabling of models.
28+
* Unit Tests for {@link AnthropicChatAutoConfiguration}'s conditional enabling of models.
2929
*
3030
* @author Ilayaperumal Gopinathan
3131
*/
3232
public class AnthropicModelConfigurationTests {
3333

3434
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
3535
.withPropertyValues("spring.ai.anthropic.apiKey=" + System.getenv("ANTHROPIC_API_KEY"))
36-
.withConfiguration(AutoConfigurations.of(AnthropicAutoConfiguration.class));
36+
.withConfiguration(AutoConfigurations.of(AnthropicChatAutoConfiguration.class));
3737

3838
@Test
3939
void chatModelActivation() {
@@ -42,7 +42,7 @@ void chatModelActivation() {
4242
});
4343

4444
this.contextRunner.withPropertyValues("spring.ai.model.chat=none").run(context -> {
45-
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isNotEmpty();
45+
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isEmpty();
4646
assertThat(context.getBeansOfType(AnthropicChatModel.class)).isEmpty();
4747
});
4848

auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/AnthropicPropertiesTests.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void connectionProperties() {
4444
"spring.ai.anthropic.chat.options.temperature=0.55")
4545
// @formatter:on
4646
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
47-
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
47+
RestClientAutoConfiguration.class, AnthropicChatAutoConfiguration.class))
4848
.run(context -> {
4949
var chatProperties = context.getBean(AnthropicChatProperties.class);
5050
var connectionProperties = context.getBean(AnthropicConnectionProperties.class);
@@ -80,7 +80,7 @@ public void chatOptionsTest() {
8080
)
8181
// @formatter:on
8282
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
83-
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
83+
RestClientAutoConfiguration.class, AnthropicChatAutoConfiguration.class))
8484
.run(context -> {
8585
var chatProperties = context.getBean(AnthropicChatProperties.class);
8686
var connectionProperties = context.getBean(AnthropicConnectionProperties.class);
@@ -104,7 +104,7 @@ public void chatCompletionDisabled() {
104104
// It is enabled by default
105105
new ApplicationContextRunner()
106106
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
107-
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
107+
RestClientAutoConfiguration.class, AnthropicChatAutoConfiguration.class))
108108
.run(context -> {
109109
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isNotEmpty();
110110
assertThat(context.getBeansOfType(AnthropicChatModel.class)).isNotEmpty();
@@ -113,7 +113,7 @@ public void chatCompletionDisabled() {
113113
// Explicitly enable the chat auto-configuration.
114114
new ApplicationContextRunner().withPropertyValues("spring.ai.anthropic.chat.enabled=true")
115115
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
116-
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
116+
RestClientAutoConfiguration.class, AnthropicChatAutoConfiguration.class))
117117
.run(context -> {
118118
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isNotEmpty();
119119
assertThat(context.getBeansOfType(AnthropicChatModel.class)).isNotEmpty();
@@ -122,7 +122,7 @@ public void chatCompletionDisabled() {
122122
// Explicitly disable the chat auto-configuration.
123123
new ApplicationContextRunner().withPropertyValues("spring.ai.model.chat=none")
124124
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
125-
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
125+
RestClientAutoConfiguration.class, AnthropicChatAutoConfiguration.class))
126126
.run(context -> {
127127
assertThat(context.getBeansOfType(AnthropicChatModel.class)).isEmpty();
128128
});

auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithFunctionBeanIT.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@
2727
import org.springframework.ai.anthropic.AnthropicChatModel;
2828
import org.springframework.ai.anthropic.AnthropicChatOptions;
2929
import org.springframework.ai.anthropic.api.AnthropicApi;
30-
import org.springframework.ai.model.anthropic.autoconfigure.AnthropicAutoConfiguration;
30+
import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration;
3131
import org.springframework.ai.model.anthropic.autoconfigure.tool.MockWeatherService.Request;
3232
import org.springframework.ai.model.anthropic.autoconfigure.tool.MockWeatherService.Response;
3333
import org.springframework.ai.chat.messages.UserMessage;
3434
import org.springframework.ai.chat.model.ChatResponse;
3535
import org.springframework.ai.chat.prompt.Prompt;
36-
import org.springframework.ai.model.function.FunctionCallingOptions;
3736
import org.springframework.ai.model.tool.ToolCallingChatOptions;
3837
import org.springframework.boot.autoconfigure.AutoConfigurations;
3938
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -50,7 +49,7 @@ class FunctionCallWithFunctionBeanIT {
5049

5150
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
5251
.withPropertyValues("spring.ai.anthropic.apiKey=" + System.getenv("ANTHROPIC_API_KEY"))
53-
.withConfiguration(AutoConfigurations.of(AnthropicAutoConfiguration.class))
52+
.withConfiguration(AutoConfigurations.of(AnthropicChatAutoConfiguration.class))
5453
.withUserConfiguration(Config.class);
5554

5655
@Test

auto-configurations/models/spring-ai-autoconfigure-model-anthropic/src/test/java/org/springframework/ai/model/anthropic/autoconfigure/tool/FunctionCallWithPromptFunctionIT.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.springframework.ai.anthropic.AnthropicChatModel;
2727
import org.springframework.ai.anthropic.AnthropicChatOptions;
2828
import org.springframework.ai.anthropic.api.AnthropicApi;
29-
import org.springframework.ai.model.anthropic.autoconfigure.AnthropicAutoConfiguration;
29+
import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration;
3030
import org.springframework.ai.chat.messages.UserMessage;
3131
import org.springframework.ai.chat.model.ChatResponse;
3232
import org.springframework.ai.chat.prompt.Prompt;
@@ -43,7 +43,7 @@ public class FunctionCallWithPromptFunctionIT {
4343

4444
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
4545
.withPropertyValues("spring.ai.anthropic.apiKey=" + System.getenv("ANTHROPIC_API_KEY"))
46-
.withConfiguration(AutoConfigurations.of(AnthropicAutoConfiguration.class));
46+
.withConfiguration(AutoConfigurations.of(AnthropicChatAutoConfiguration.class));
4747

4848
@Test
4949
void functionCallTest() {

auto-configurations/models/spring-ai-autoconfigure-model-azure-openai/pom.xml

-5
Original file line numberDiff line numberDiff line change
@@ -39,35 +39,30 @@
3939
<groupId>org.springframework.ai</groupId>
4040
<artifactId>spring-ai-autoconfigure-model-tool</artifactId>
4141
<version>${project.parent.version}</version>
42-
<optional>true</optional>
4342
</dependency>
4443

4544
<dependency>
4645
<groupId>org.springframework.ai</groupId>
4746
<artifactId>spring-ai-autoconfigure-retry</artifactId>
4847
<version>${project.parent.version}</version>
49-
<optional>true</optional>
5048
</dependency>
5149

5250
<dependency>
5351
<groupId>org.springframework.ai</groupId>
5452
<artifactId>spring-ai-autoconfigure-model-chat-observation</artifactId>
5553
<version>${project.parent.version}</version>
56-
<optional>true</optional>
5754
</dependency>
5855

5956
<dependency>
6057
<groupId>org.springframework.ai</groupId>
6158
<artifactId>spring-ai-autoconfigure-model-embedding-observation</artifactId>
6259
<version>${project.parent.version}</version>
63-
<optional>true</optional>
6460
</dependency>
6561

6662
<dependency>
6763
<groupId>org.springframework.ai</groupId>
6864
<artifactId>spring-ai-autoconfigure-model-image-observation</artifactId>
6965
<version>${project.parent.version}</version>
70-
<optional>true</optional>
7166
</dependency>
7267

7368
<!-- Boot dependencies -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.model.azure.openai.autoconfigure;
18+
19+
import com.azure.ai.openai.OpenAIClientBuilder;
20+
21+
import org.springframework.ai.azure.openai.AzureOpenAiAudioTranscriptionModel;
22+
import org.springframework.ai.azure.openai.AzureOpenAiChatModel;
23+
import org.springframework.ai.model.SpringAIModelProperties;
24+
import org.springframework.ai.model.SpringAIModels;
25+
import org.springframework.boot.autoconfigure.AutoConfiguration;
26+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
27+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
28+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
29+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
30+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
31+
import org.springframework.context.annotation.Bean;
32+
33+
/**
34+
* {@link AutoConfiguration Auto-configuration} for Azure OpenAI.
35+
*
36+
* @author Piotr Olaszewski
37+
* @author Soby Chacko
38+
* @author Manuel Andreo Garcia
39+
* @author Ilayaperumal Gopinathan
40+
*/
41+
@AutoConfiguration
42+
@ConditionalOnClass({ AzureOpenAiAudioTranscriptionModel.class })
43+
@EnableConfigurationProperties(AzureOpenAiAudioTranscriptionProperties.class)
44+
@ConditionalOnProperty(name = SpringAIModelProperties.AUDIO_TRANSCRIPTION_MODEL,
45+
havingValue = SpringAIModels.AZURE_OPENAI, matchIfMissing = true)
46+
@ImportAutoConfiguration(classes = AzureOpenAiClientBuilderAutoConfiguration.class)
47+
public class AzureOpenAiAudioTranscriptionAutoConfiguration {
48+
49+
@Bean
50+
@ConditionalOnMissingBean
51+
public AzureOpenAiAudioTranscriptionModel azureOpenAiAudioTranscriptionModel(OpenAIClientBuilder openAIClient,
52+
AzureOpenAiAudioTranscriptionProperties audioProperties) {
53+
return new AzureOpenAiAudioTranscriptionModel(openAIClient.buildClient(), audioProperties.getOptions());
54+
}
55+
56+
}

0 commit comments

Comments
 (0)