diff --git a/spring-boot-starter/pom.xml b/spring-boot-starter/pom.xml
index ec97c6be..70c94872 100644
--- a/spring-boot-starter/pom.xml
+++ b/spring-boot-starter/pom.xml
@@ -69,6 +69,12 @@
${junit.version}
test
+
+ org.springframework.boot
+ spring-boot-starter-test
+ ${spring-boot.version}
+ test
+
diff --git a/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AAutoConfiguration.java b/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AAutoConfiguration.java
index e186024b..4a13720e 100644
--- a/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AAutoConfiguration.java
+++ b/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AAutoConfiguration.java
@@ -42,6 +42,7 @@
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -75,6 +76,7 @@
@AutoConfiguration
@ConditionalOnWebApplication
@ConditionalOnClass(AgentExecutor.class)
+@ConditionalOnProperty(name = "a2at.server.enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(A2AProperties.class)
public class A2AAutoConfiguration {
diff --git a/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AProperties.java b/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AProperties.java
index 71281a3b..6c69e9ac 100644
--- a/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AProperties.java
+++ b/spring-boot-starter/src/main/java/dev/openan/workflow/engine/spring/A2AProperties.java
@@ -30,6 +30,9 @@
@ConfigurationProperties(prefix = "a2at.server")
public class A2AProperties {
+ /** Whether A2A server autoconfiguration is enabled. Set false to disable all A2A beans. */
+ private boolean enabled = true;
+
/** Path to the AgentCard JSON file (classpath: or file: prefix supported). */
private String agentCard = "classpath:agentcard.json";
@@ -57,6 +60,14 @@ public class A2AProperties {
/** Idle timeout for server executor threads above the core size. */
private int executorKeepAliveSeconds = 60;
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
public String getAgentCard() {
return agentCard;
}
diff --git a/spring-boot-starter/src/test/java/dev/openan/workflow/engine/spring/A2AAutoConfigurationTest.java b/spring-boot-starter/src/test/java/dev/openan/workflow/engine/spring/A2AAutoConfigurationTest.java
index 1efba5e2..55d8ab32 100644
--- a/spring-boot-starter/src/test/java/dev/openan/workflow/engine/spring/A2AAutoConfigurationTest.java
+++ b/spring-boot-starter/src/test/java/dev/openan/workflow/engine/spring/A2AAutoConfigurationTest.java
@@ -6,9 +6,17 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import org.a2aproject.sdk.server.config.A2AConfigProvider;
+import org.a2aproject.sdk.server.agentexecution.AgentExecutor;
+import org.a2aproject.sdk.server.requesthandlers.RequestHandler;
+import org.a2aproject.sdk.spec.AgentCard;
+import org.a2aproject.sdk.transport.rest.handler.RestHandler;
import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
@@ -58,4 +66,34 @@ void executorRejectsMaxBelowCore() {
IllegalArgumentException.class,
() -> new A2AAutoConfiguration().agentExecutorPool(properties));
}
+
+ @Test
+ void whenEnabledFalseThenNoA2ABeansCreated() {
+ new WebApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(A2AAutoConfiguration.class))
+ .withPropertyValues("a2at.server.enabled=false")
+ .run(context -> {
+ assertFalse(context.containsBean("agentCard"));
+ assertFalse(context.containsBean("requestHandler"));
+ assertFalse(context.containsBean("restHandler"));
+ assertFalse(context.containsBean("a2aController"));
+ assertFalse(context.containsBean("agentExecutorPool"));
+ assertFalse(context.containsBean("eventBus"));
+ assertFalse(context.containsBean("taskStore"));
+ });
+ }
+
+ @Test
+ void whenEnabledTrueThenA2ABeansCreated() {
+ new WebApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(A2AAutoConfiguration.class))
+ .withPropertyValues("a2at.server.enabled=true")
+ .run(context -> {
+ // agentCard will fail to load without a real classpath resource,
+ // but the bean definition should be present (condition matched)
+ assertFalse(context.getStartupFailure() != null
+ && context.getStartupFailure().getMessage() != null
+ && context.getStartupFailure().getMessage().contains("did not match"));
+ });
+ }
}