diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiMultiModalEmbeddingAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiMultiModalEmbeddingAutoConfiguration.java index 5015bec2f4d..f676ef6acf6 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiMultiModalEmbeddingAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiMultiModalEmbeddingAutoConfiguration.java @@ -26,7 +26,6 @@ import org.springframework.ai.vertexai.embedding.VertexAiEmbeddingConnectionDetails; import org.springframework.ai.vertexai.embedding.multimodal.VertexAiMultimodalEmbeddingModel; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -41,13 +40,11 @@ * @author Ilayaperumal Gopinathan * @since 1.0.0 */ -@AutoConfiguration(after = { SpringAiRetryAutoConfiguration.class }) +@AutoConfiguration(after = { SpringAiRetryAutoConfiguration.class, VertexAiEmbeddingConnectionAutoConfiguration.class }) @ConditionalOnClass({ VertexAI.class, VertexAiMultimodalEmbeddingModel.class }) @ConditionalOnProperty(name = SpringAIModelProperties.MULTI_MODAL_EMBEDDING_MODEL, havingValue = SpringAIModels.VERTEX_AI, matchIfMissing = true) @EnableConfigurationProperties(VertexAiMultimodalEmbeddingProperties.class) -@ImportAutoConfiguration( - classes = { SpringAiRetryAutoConfiguration.class, VertexAiEmbeddingConnectionAutoConfiguration.class }) public class VertexAiMultiModalEmbeddingAutoConfiguration { @Bean diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingAutoConfiguration.java index 54fc82e486d..56e253dc2d2 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingAutoConfiguration.java @@ -26,7 +26,6 @@ import org.springframework.ai.vertexai.embedding.text.VertexAiTextEmbeddingModel; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -42,13 +41,11 @@ * @author Ilayaperumal Gopinathan * @since 1.0.0 */ -@AutoConfiguration(after = { SpringAiRetryAutoConfiguration.class }) +@AutoConfiguration(after = { SpringAiRetryAutoConfiguration.class, VertexAiEmbeddingConnectionAutoConfiguration.class }) @ConditionalOnClass(VertexAiTextEmbeddingModel.class) @ConditionalOnProperty(name = SpringAIModelProperties.TEXT_EMBEDDING_MODEL, havingValue = SpringAIModels.VERTEX_AI, matchIfMissing = true) @EnableConfigurationProperties(VertexAiTextEmbeddingProperties.class) -@ImportAutoConfiguration( - classes = { SpringAiRetryAutoConfiguration.class, VertexAiEmbeddingConnectionAutoConfiguration.class }) public class VertexAiTextEmbeddingAutoConfiguration { @Bean diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfiguration.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfiguration.java index 2a61904ea9e..edb7057c1e6 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfiguration.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/main/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfiguration.java @@ -33,7 +33,6 @@ import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -59,7 +58,6 @@ @ConditionalOnProperty(name = SpringAIModelProperties.CHAT_MODEL, havingValue = SpringAIModels.VERTEX_AI, matchIfMissing = true) @EnableConfigurationProperties({ VertexAiGeminiChatProperties.class, VertexAiGeminiConnectionProperties.class }) -@ImportAutoConfiguration(classes = { SpringAiRetryAutoConfiguration.class, ToolCallingAutoConfiguration.class }) public class VertexAiGeminiChatAutoConfiguration { @Bean diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingModelAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingModelAutoConfigurationIT.java index 9f45cccf9f3..4622de32a0a 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingModelAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingModelAutoConfigurationIT.java @@ -28,6 +28,7 @@ import org.springframework.ai.embedding.EmbeddingOptionsBuilder; import org.springframework.ai.embedding.EmbeddingResponse; import org.springframework.ai.embedding.EmbeddingResultMetadata; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.vertexai.embedding.multimodal.VertexAiMultimodalEmbeddingModel; import org.springframework.ai.vertexai.embedding.text.VertexAiTextEmbeddingModel; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -52,12 +53,13 @@ public class VertexAiTextEmbeddingModelAutoConfigurationIT { @Test public void textEmbedding() { - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiTextEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiTextEmbeddingAutoConfiguration.class)) .run(context -> { var connectionProperties = context.getBean(VertexAiEmbeddingConnectionProperties.class); var textEmbeddingProperties = context.getBean(VertexAiTextEmbeddingProperties.class); assertThat(connectionProperties).isNotNull(); + assertThat(textEmbeddingProperties).isNotNull(); VertexAiTextEmbeddingModel embeddingModel = context.getBean(VertexAiTextEmbeddingModel.class); assertThat(embeddingModel).isInstanceOf(VertexAiTextEmbeddingModel.class); @@ -71,21 +73,21 @@ public void textEmbedding() { @Test void textEmbeddingActivation() { - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiTextEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiTextEmbeddingAutoConfiguration.class)) .withPropertyValues("spring.ai.model.embedding.text=none") .run(context -> { assertThat(context.getBeansOfType(VertexAiTextEmbeddingProperties.class)).isEmpty(); assertThat(context.getBeansOfType(VertexAiTextEmbeddingModel.class)).isEmpty(); }); - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiTextEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiTextEmbeddingAutoConfiguration.class)) .withPropertyValues("spring.ai.model.embedding.text=vertexai") .run(context -> { assertThat(context.getBeansOfType(VertexAiTextEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(VertexAiTextEmbeddingModel.class)).isNotEmpty(); }); - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiTextEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiTextEmbeddingAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(VertexAiTextEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(VertexAiTextEmbeddingModel.class)).isNotEmpty(); @@ -95,12 +97,13 @@ void textEmbeddingActivation() { @Test public void multimodalEmbedding() { - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiMultiModalEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiMultiModalEmbeddingAutoConfiguration.class)) .run(context -> { var connectionProperties = context.getBean(VertexAiEmbeddingConnectionProperties.class); var multimodalEmbeddingProperties = context.getBean(VertexAiMultimodalEmbeddingProperties.class); assertThat(connectionProperties).isNotNull(); + assertThat(multimodalEmbeddingProperties).isNotNull(); VertexAiMultimodalEmbeddingModel multiModelEmbeddingModel = context .getBean(VertexAiMultimodalEmbeddingModel.class); @@ -129,21 +132,21 @@ public void multimodalEmbedding() { @Test void multimodalEmbeddingActivation() { - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiMultiModalEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiMultiModalEmbeddingAutoConfiguration.class)) .withPropertyValues("spring.ai.model.embedding.multimodal=none") .run(context -> { assertThat(context.getBeansOfType(VertexAiMultimodalEmbeddingProperties.class)).isEmpty(); assertThat(context.getBeansOfType(VertexAiMultimodalEmbeddingModel.class)).isEmpty(); }); - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiMultiModalEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiMultiModalEmbeddingAutoConfiguration.class)) .withPropertyValues("spring.ai.model.embedding.multimodal=vertexai") .run(context -> { assertThat(context.getBeansOfType(VertexAiMultimodalEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(VertexAiMultimodalEmbeddingModel.class)).isNotEmpty(); }); - this.contextRunner.withConfiguration(AutoConfigurations.of(VertexAiMultiModalEmbeddingAutoConfiguration.class)) + this.contextRunner.withConfiguration(vertexAiAutoConfig(VertexAiMultiModalEmbeddingAutoConfiguration.class)) .run(context -> { assertThat(context.getBeansOfType(VertexAiMultimodalEmbeddingProperties.class)).isNotEmpty(); assertThat(context.getBeansOfType(VertexAiMultimodalEmbeddingModel.class)).isNotEmpty(); @@ -151,4 +154,15 @@ void multimodalEmbeddingActivation() { } + private static AutoConfigurations vertexAiAutoConfig(Class... additionalAutoConfigurations) { + Class[] dependencies = new Class[] { SpringAiRetryAutoConfiguration.class, + VertexAiEmbeddingConnectionAutoConfiguration.class }; + Class[] allAutoConfigurations = new Class[dependencies.length + additionalAutoConfigurations.length]; + System.arraycopy(dependencies, 0, allAutoConfigurations, 0, dependencies.length); + System.arraycopy(additionalAutoConfigurations, 0, allAutoConfigurations, dependencies.length, + additionalAutoConfigurations.length); + + return AutoConfigurations.of(allAutoConfigurations); + } + } diff --git a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfigurationIT.java b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfigurationIT.java index a623599d644..30e1a3bdc31 100644 --- a/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfigurationIT.java +++ b/auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai/src/test/java/org/springframework/ai/model/vertexai/autoconfigure/gemini/VertexAiGeminiChatAutoConfigurationIT.java @@ -16,20 +16,21 @@ package org.springframework.ai.model.vertexai.autoconfigure.gemini; -import java.util.stream.Collectors; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; -import reactor.core.publisher.Flux; - import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration; +import org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration; import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatModel; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import reactor.core.publisher.Flux; + +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -42,7 +43,7 @@ public class VertexAiGeminiChatAutoConfigurationIT { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withPropertyValues("spring.ai.vertex.ai.gemini.project-id=" + System.getenv("VERTEX_AI_GEMINI_PROJECT_ID"), "spring.ai.vertex.ai.gemini.location=" + System.getenv("VERTEX_AI_GEMINI_LOCATION")) - .withConfiguration(AutoConfigurations.of(VertexAiGeminiChatAutoConfiguration.class)); + .withConfiguration(vertexAiAutoConfig(VertexAiGeminiChatAutoConfiguration.class)); @Test void generate() { @@ -70,4 +71,14 @@ void generateStreaming() { }); } + private static AutoConfigurations vertexAiAutoConfig(Class... additionalAutoConfigurations) { + Class[] dependencies = new Class[] { SpringAiRetryAutoConfiguration.class, ToolCallingAutoConfiguration.class}; + Class[] allAutoConfigurations = new Class[dependencies.length + additionalAutoConfigurations.length]; + System.arraycopy(dependencies, 0, allAutoConfigurations, 0, dependencies.length); + System.arraycopy(additionalAutoConfigurations, 0, allAutoConfigurations, dependencies.length, + additionalAutoConfigurations.length); + + return AutoConfigurations.of(allAutoConfigurations); + } + }