-
Notifications
You must be signed in to change notification settings - Fork 245
Spring Integration AutoConfiguration
Deep dive into how Embabel integrates with Spring Framework, including the powerful auto-configuration system that makes setup effortless.
Embabel is built as a Spring-first framework, embracing Spring's dependency injection, configuration, and testing patterns. It's designed to feel natural to Spring developers while adding agent capabilities.
Think of Embabel like Spring Data or Spring Security - it extends the Spring ecosystem with domain-specific capabilities:
- Spring Boot starters for zero-configuration setup
- Auto-configuration classes that activate based on classpath and annotations
- Profile-based configuration for different deployment scenarios
- Conditional beans that adapt to your environment
- Full integration with Spring's testing framework
Embabel uses sophisticated auto-configuration to automatically set up agents, models, and tools based on your dependencies and annotations.
| Module | Purpose | Activates When |
|---|---|---|
embabel-agent-platform-autoconfigure |
Core agent platform | Always (base functionality) |
embabel-agent-starter-ollama |
Ollama local models | Ollama on classpath + annotation |
embabel-agent-starter-openai |
OpenAI cloud models | OpenAI starter + API key |
embabel-agent-starter-anthropic |
Anthropic cloud models | Anthropic starter + API key |
embabel-agent-starter-shell |
Interactive shell | Shell annotation |
embabel-agent-starter-mcpserver |
MCP server capabilities | MCP server annotation |
graph TD
A[Application Startup] --> B[Scan for @EnableAgents Annotations]
B --> C[Activate Spring Profiles]
C --> D[Load Conditional Configurations]
D --> E[Register Model Providers]
E --> F[Initialize Agent Platform]
F --> G[Ready for Agent Execution]
The simplest way to configure an Embabel application:
@SpringBootApplication
@EnableAgents
class SimpleAgentApplication
fun main(args: Array<String>) {
runApplication<SimpleAgentApplication>(*args)
}This gives you:
- ✅ Agent platform with GOAP planning
- ✅ Local model support (if Ollama available)
- ✅ No external dependencies required
- ✅ Ready for agent development
For interactive agent development:
@SpringBootApplication
class ShellAgentApplication
fun main(args: Array<String>) {
runApplication<ShellAgentApplication>(*args)
}Run with:
mvn spring-boot:run
# Interactive shell starts automatically
help
execute "your agent request here"Full-featured applications with multiple capabilities:
@SpringBootApplication
@EnableAgents(
loggingTheme = LoggingThemes.STAR_WARS, // Fun themed logging
mcpServers = [McpServers.DOCKER_DESKTOP] // Enable MCP tools
)
class AdvancedAgentApplication
fun main(args: Array<String>) {
runApplication<AdvancedAgentApplication>(*args)
}Embabel excels with local models - zero external dependencies needed:
@SpringBootApplication
@EnableAgents
class OllamaAgentApplication
fun main(args: Array<String>) {
runApplication<OllamaAgentApplication>(*args)
}Prerequisites:
- Install Ollama:
curl -fsSL https://ollama.ai/install.sh | sh - Pull models:
ollama pull llama3.2orollama pull codellama - Start Ollama:
ollama serve
Auto-Configuration Magic:
- 🔍 Auto-discovery: Scans Ollama for available models
- 🏷️ Automatic registration: Creates Spring beans for each model
- 🎯 Smart selection: Framework chooses appropriate model for tasks
- 💰 Cost-free: No API costs - all processing local
// Your agent automatically has access to all local models!
@Agent
class LocalModelAgent {
@Action
fun analyzeCode(code: String, context: OperationContext): CodeAnalysis {
// Automatically uses best available local model
return context.ai().withDefaultLlm()
.createObject("Analyze this code for potential issues: $code")
}
}@SpringBootApplication
@EnableAgents
class DockerModelApplicationWith Docker Desktop + MCP:
- Uses Docker-managed model containers
- Automatic model lifecycle management
- Isolated model execution environments
Cloud models enhance capabilities but are completely optional:
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-starter-openai</artifactId>
</dependency>@SpringBootApplication
@EnableAgents
class CloudEnabledApplicationConfiguration:
# Optional - only if you want cloud models
export OPENAI_API_KEY=your_api_keyAuto-Configuration Behavior:
- ✅ With API key: Full OpenAI model suite available
- ✅ Without API key: Gracefully falls back to local models
- 🚫 No startup errors: Application starts successfully either way
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-starter-anthropic</artifactId>
</dependency># Optional - enables Claude models
export ANTHROPIC_API_KEY=your_anthropic_keyEmbabel's auto-configuration enables sophisticated model mixing:
@Agent
class HybridModelAgent {
@Action
fun quickAnalysis(input: String, context: OperationContext): Analysis {
// Use fast, cheap local model for quick tasks
return context.ai()
.withLlm(LlmOptions.withModel("llama3.2:1b")) // Local Ollama model
.createObject("Quick analysis: $input")
}
@Action
fun deepAnalysis(input: String, context: OperationContext): DetailedAnalysis {
// Use powerful cloud model for complex reasoning
return context.ai()
.withLlm(LlmOptions.withModel(OpenAiModels.GPT_41)) // Cloud model (if available)
.createObject("Detailed analysis: $input")
}
}@Configuration
class EnvironmentSpecificConfig {
@Bean
@ConditionalOnProperty("embabel.agent.mode", havingValue = "development")
fun developmentAgentConfig(): AgentConfig {
return AgentConfig(
mockMode = true,
verboseLogging = true,
enableExperimentalFeatures = true
)
}
@Bean
@ConditionalOnProperty("embabel.agent.mode", havingValue = "production")
fun productionAgentConfig(): AgentConfig {
return AgentConfig(
mockMode = false,
verboseLogging = false,
enableExperimentalFeatures = false
)
}
}Auto-configuration adapts to available resources:
@Configuration
class ModelProviderConfig {
@Bean
@ConditionalOnProperty("OPENAI_API_KEY")
@ConditionalOnClass(name = "org.springframework.ai.openai.OpenAiChatModel")
fun openAiProvider(): ModelProvider {
return OpenAiModelProvider()
}
@Bean
@ConditionalOnMissingBean(ModelProvider::class)
fun defaultLocalProvider(): ModelProvider {
return OllamaModelProvider() // Fallback to local
}
}Automatically configures MCP tools when Docker Desktop is available:
@SpringBootApplication
@EnableAgents(mcpServers = [McpServers.DOCKER_DESKTOP])
class McpEnabledApplicationAuto-configures:
- 🔍 Brave Search - Web search capabilities
- 📄 Fetch - URL content retrieval
- 🤖 Puppeteer - Browser automation
- 📚 Wikipedia - Knowledge base access
Agent Usage:
@Agent
class WebEnabledAgent {
@Action(toolGroups = [ToolGroup.WEB])
fun researchTopic(topic: String, context: OperationContext): ResearchReport {
// Automatically has access to web search, fetch, etc.
return context.ai().withDefaultLlm()
.createObject("Research $topic using available web tools")
}
}Configure additional MCP servers:
# application.yml
embabel:
agent:
infrastructure:
mcp:
enabled: true
servers:
github:
command: docker
args: ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "mcp/github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_PERSONAL_ACCESS_TOKEN:}| Starter | Purpose | Dependencies |
|---|---|---|
embabel-agent-starter |
Base agent platform | Platform + auto-configuration |
embabel-agent-starter-shell |
Interactive shell | Core + shell capabilities |
embabel-agent-starter-platform |
Platform only | Minimal agent platform |
| Starter | Models | Requires |
|---|---|---|
embabel-agent-starter-ollama |
Local Ollama models | Ollama installed |
embabel-agent-starter-openai |
GPT models |
OPENAI_API_KEY (optional) |
embabel-agent-starter-anthropic |
Claude models |
ANTHROPIC_API_KEY (optional) |
embabel-agent-starter-bedrock |
AWS Bedrock models | AWS credentials |
embabel-agent-starter-deepseek |
DeepSeek models | DeepSeek API key |
| Starter | Purpose | Use Case |
|---|---|---|
embabel-agent-starter-mcpserver |
MCP server capabilities | Expose agents as MCP servers |
embabel-agent-starter-dockermodels |
Docker-managed models | Containerized model execution |
# Enable/disable auto-configuration modules
embabel:
agent:
platform:
autoconfigure:
enabled: true
models:
ollama:
enabled: true
auto-discovery: true
openai:
enabled: true # Only if API key available
conditional: true
mcp:
enabled: true
docker-desktop: trueembabel:
agent:
platform:
models:
ollama:
base-url: http://localhost:11434
auto-discovery: true
health-check: true
openai:
max-attempts: 10
backoff-millis: 5000
conditional-activation: true # Only activate if API key present@SpringBootTest
@TestPropertySource(properties = [
"embabel.agent.platform.test.mockMode=true"
])
class AgentAutoConfigurationTest {
@Autowired
private lateinit var agentPlatform: AgentPlatform
@Test
fun `should auto-configure agent platform`() {
assertThat(agentPlatform).isNotNull()
}
}@TestConfiguration
class TestAutoConfiguration {
@Bean
@Primary
fun mockModelProvider(): ModelProvider {
return MockModelProvider()
}
@Bean
@Primary
fun fakeOperationContext(): OperationContext {
return FakeOperationContext()
}
}Create your own auto-configuration for domain-specific needs:
@Configuration
@ConditionalOnClass(MyDomainService::class)
@EnableConfigurationProperties(MyDomainProperties::class)
class MyDomainAutoConfiguration {
@Bean
@ConditionalOnMissingBean
fun myDomainAgent(domainService: MyDomainService): MyDomainAgent {
return MyDomainAgent(domainService)
}
}Register in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
com.mycompany.autoconfigure.MyDomainAutoConfiguration
@Configuration
@Profile("production")
class ProductionAutoConfiguration {
@Bean
fun productionModelProvider(): ModelProvider {
return EnterpriseModelProvider()
}
}
@Configuration
@Profile("development")
class DevelopmentAutoConfiguration {
@Bean
fun developmentModelProvider(): ModelProvider {
return FastLocalModelProvider()
}
}# See what auto-configuration is happening
java -jar app.jar --debug
# Specific auto-configuration logging
logging.level.com.embabel.agent.autoconfigure=DEBUG# Check Ollama connectivity
curl http://localhost:11434/api/tags
# Verify auto-configuration
curl http://localhost:8080/actuator/beans | grep -i ollama# Verify environment variables
env | grep -E "(OPENAI|ANTHROPIC)_API_KEY"
# Check conditional activation
logging.level.com.embabel.agent.config.models=DEBUG// Development: Local models only
@EnableAgents
class DevelopmentApp
// Production: Hybrid approach
@EnableAgents
class ProductionApp // Add cloud starters as needed@Bean
@ConditionalOnProperty("app.features.advanced-reasoning", havingValue = "true")
fun advancedReasoningAgent(): AdvancedAgent {
// Only create if feature enabled
}<!-- Development profile -->
<profile>
<id>dev</id>
<dependencies>
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-starter-ollama</artifactId>
</dependency>
</dependencies>
</profile>
<!-- Production profile -->
<profile>
<id>prod</id>
<dependencies>
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-starter-openai</artifactId>
</dependency>
</dependencies>
</profile>@Agent
class RobustAgent {
@Action
fun processRequest(request: Request, context: OperationContext): Response {
return try {
// Try cloud model first
context.ai().withLlm(LlmOptions.withModel(OpenAiModels.GPT_41))
.createObject("Process: $request")
} catch (e: Exception) {
// Fallback to local model
context.ai().withDefaultLlm()
.createObject("Process: $request")
}
}
}The auto-configuration system makes Embabel incredibly easy to adopt - start with zero external dependencies using local models, then optionally enhance with cloud providers as your needs grow!
(c) Embabel Software Inc 2024-2025.