fix: 收紧 starter 自动装配并修复默认连接问题
- 为 llm 与 store 自动配置增加显式属性门槛 - 修复 ollama think 为空时的启动空指针 - 补充 starter 条件装配测试
This commit is contained in:
@@ -51,6 +51,25 @@
|
|||||||
<artifactId>easy-agents-bom</artifactId>
|
<artifactId>easy-agents-bom</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.easyagents.llm.deepseek.DeepseekConfig;
|
|||||||
import com.easyagents.llm.deepseek.DeepseekChatModel;
|
import com.easyagents.llm.deepseek.DeepseekChatModel;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -13,6 +14,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
* DeepSeek
|
* DeepSeek
|
||||||
*/
|
*/
|
||||||
@ConditionalOnClass(DeepseekChatModel.class)
|
@ConditionalOnClass(DeepseekChatModel.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.llm.deepseek", name = "api-key")
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties(DeepSeekProperties.class)
|
@EnableConfigurationProperties(DeepSeekProperties.class)
|
||||||
public class DeepSeekAutoConfiguration {
|
public class DeepSeekAutoConfiguration {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.easyagents.llm.ollama.OllamaChatModel;
|
|||||||
import com.easyagents.llm.ollama.OllamaChatConfig;
|
import com.easyagents.llm.ollama.OllamaChatConfig;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -15,6 +16,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
* @since 2025-02-11
|
* @since 2025-02-11
|
||||||
*/
|
*/
|
||||||
@ConditionalOnClass(OllamaChatModel.class)
|
@ConditionalOnClass(OllamaChatModel.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.llm.ollama", name = "model")
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties(OllamaProperties.class)
|
@EnableConfigurationProperties(OllamaProperties.class)
|
||||||
public class OllamaAutoConfiguration {
|
public class OllamaAutoConfiguration {
|
||||||
@@ -26,7 +28,7 @@ public class OllamaAutoConfiguration {
|
|||||||
config.setApiKey(properties.getApiKey());
|
config.setApiKey(properties.getApiKey());
|
||||||
config.setEndpoint(properties.getEndpoint());
|
config.setEndpoint(properties.getEndpoint());
|
||||||
config.setModel(properties.getModel());
|
config.setModel(properties.getModel());
|
||||||
config.setThinkingEnabled(properties.getThink());
|
config.setThinkingEnabled(Boolean.TRUE.equals(properties.getThink()));
|
||||||
return new OllamaChatModel(config);
|
return new OllamaChatModel(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class OllamaProperties {
|
|||||||
private String model;
|
private String model;
|
||||||
private String endpoint = "http://localhost:11434";
|
private String endpoint = "http://localhost:11434";
|
||||||
private String apiKey;
|
private String apiKey;
|
||||||
private Boolean think;
|
private Boolean think = Boolean.FALSE;
|
||||||
|
|
||||||
public String getModel() {
|
public String getModel() {
|
||||||
return model;
|
return model;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.easyagents.llm.openai.OpenAIChatModel;
|
|||||||
import com.easyagents.llm.openai.OpenAIChatConfig;
|
import com.easyagents.llm.openai.OpenAIChatConfig;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -15,6 +16,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
* @since 2024-04-10
|
* @since 2024-04-10
|
||||||
*/
|
*/
|
||||||
@ConditionalOnClass(OpenAIChatModel.class)
|
@ConditionalOnClass(OpenAIChatModel.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.llm.openai", name = "api-key")
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties(OpenAIProperties.class)
|
@EnableConfigurationProperties(OpenAIProperties.class)
|
||||||
public class OpenAIAutoConfiguration {
|
public class OpenAIAutoConfiguration {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.easyagents.llm.qwen.QwenChatModel;
|
|||||||
import com.easyagents.llm.qwen.QwenChatConfig;
|
import com.easyagents.llm.qwen.QwenChatConfig;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -15,6 +16,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
* @since 2024-04-10
|
* @since 2024-04-10
|
||||||
*/
|
*/
|
||||||
@ConditionalOnClass(QwenChatModel.class)
|
@ConditionalOnClass(QwenChatModel.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.llm.qwen", name = "api-key")
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties(QwenProperties.class)
|
@EnableConfigurationProperties(QwenProperties.class)
|
||||||
public class QwenAutoConfiguration {
|
public class QwenAutoConfiguration {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.easyagents.store.aliyun.AliyunVectorStore;
|
|||||||
import com.easyagents.store.aliyun.AliyunVectorStoreConfig;
|
import com.easyagents.store.aliyun.AliyunVectorStoreConfig;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -14,6 +15,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass(AliyunVectorStore.class)
|
@ConditionalOnClass(AliyunVectorStore.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.store.aliyun", name = "endpoint")
|
||||||
@EnableConfigurationProperties(AliyunProperties.class)
|
@EnableConfigurationProperties(AliyunProperties.class)
|
||||||
public class AliyunAutoConfiguration {
|
public class AliyunAutoConfiguration {
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ package com.easyagents.spring.boot.store.chroma;
|
|||||||
|
|
||||||
import com.easyagents.store.chroma.ChromaVectorStore;
|
import com.easyagents.store.chroma.ChromaVectorStore;
|
||||||
import com.easyagents.store.chroma.ChromaVectorStoreConfig;
|
import com.easyagents.store.chroma.ChromaVectorStoreConfig;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -31,6 +31,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass(ChromaVectorStore.class)
|
@ConditionalOnClass(ChromaVectorStore.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.store.chroma", name = "host")
|
||||||
@EnableConfigurationProperties(ChromaProperties.class)
|
@EnableConfigurationProperties(ChromaProperties.class)
|
||||||
public class ChromaAutoConfiguration {
|
public class ChromaAutoConfiguration {
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.easyagents.store.elasticsearch.ElasticSearchVectorStoreConfig;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -31,6 +32,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass(ElasticSearchVectorStore.class)
|
@ConditionalOnClass(ElasticSearchVectorStore.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.store.elasticsearch", name = "server-url")
|
||||||
@EnableConfigurationProperties(ElasticSearchProperties.class)
|
@EnableConfigurationProperties(ElasticSearchProperties.class)
|
||||||
public class ElasticSearchAutoConfiguration {
|
public class ElasticSearchAutoConfiguration {
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.opensearch.client.opensearch.OpenSearchClient;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -31,13 +32,14 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass(OpenSearchVectorStore.class)
|
@ConditionalOnClass(OpenSearchVectorStore.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.store.opensearch", name = "server-url")
|
||||||
@EnableConfigurationProperties(OpenSearchProperties.class)
|
@EnableConfigurationProperties(OpenSearchProperties.class)
|
||||||
public class OpenSearchAutoConfiguration {
|
public class OpenSearchAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public OpenSearchVectorStore openSearchVectorStore(OpenSearchProperties properties,
|
public OpenSearchVectorStore openSearchVectorStore(OpenSearchProperties properties,
|
||||||
@Autowired(required = false) OpenSearchClient client) {
|
@Autowired(required = false) OpenSearchClient client) {
|
||||||
OpenSearchVectorStoreConfig config = new OpenSearchVectorStoreConfig();
|
OpenSearchVectorStoreConfig config = new OpenSearchVectorStoreConfig();
|
||||||
config.setServerUrl(properties.getServerUrl());
|
config.setServerUrl(properties.getServerUrl());
|
||||||
config.setApiKey(properties.getApiKey());
|
config.setApiKey(properties.getApiKey());
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.easyagents.store.qcloud.QCloudVectorStore;
|
|||||||
import com.easyagents.store.qcloud.QCloudVectorStoreConfig;
|
import com.easyagents.store.qcloud.QCloudVectorStoreConfig;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -14,6 +15,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass(QCloudVectorStore.class)
|
@ConditionalOnClass(QCloudVectorStore.class)
|
||||||
|
@ConditionalOnProperty(prefix = "easy-agents.store.qcloud", name = "host")
|
||||||
@EnableConfigurationProperties(QCloudProperties.class)
|
@EnableConfigurationProperties(QCloudProperties.class)
|
||||||
public class QCloudStoreAutoConfiguration {
|
public class QCloudStoreAutoConfiguration {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.easyagents.spring.boot.autoconfigure;
|
||||||
|
|
||||||
|
import com.easyagents.llm.ollama.OllamaChatModel;
|
||||||
|
import com.easyagents.spring.boot.llm.ollama.OllamaAutoConfiguration;
|
||||||
|
import com.easyagents.spring.boot.rag.ingestion.RagIngestionAutoConfiguration;
|
||||||
|
import com.easyagents.spring.boot.store.opensearch.OpenSearchAutoConfiguration;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
public class StarterConditionalAutoConfigurationTest {
|
||||||
|
|
||||||
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withUserConfiguration(RagIngestionAutoConfiguration.class, OllamaAutoConfiguration.class, OpenSearchAutoConfiguration.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotCreateOptionalBeansWithoutExplicitProperties() {
|
||||||
|
contextRunner.run(context -> {
|
||||||
|
Assert.assertTrue(context.containsBean("ragIngestionService"));
|
||||||
|
Assert.assertFalse(context.containsBean("ollamaLlm"));
|
||||||
|
Assert.assertFalse(context.containsBean("openSearchVectorStore"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldCreateOllamaBeanWhenModelConfigured() {
|
||||||
|
contextRunner
|
||||||
|
.withPropertyValues("easy-agents.llm.ollama.model=qwen3:8b")
|
||||||
|
.run(context -> Assert.assertNotNull(context.getBean(OllamaChatModel.class)));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user