Skip to content

Spring Integration AutoConfiguration

Alexander Hein-Heifetz edited this page Sep 22, 2025 · 2 revisions

Spring Integration & Auto-Configuration

Deep dive into how Embabel integrates with Spring Framework, including the powerful auto-configuration system that makes setup effortless.

Spring Integration Philosophy

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.

The Spring Ecosystem Integration 🌱

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

Auto-Configuration System

Embabel uses sophisticated auto-configuration to automatically set up agents, models, and tools based on your dependencies and annotations.

Core Auto-Configuration Modules

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

Auto-Configuration Flow

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]
Loading

Annotation-Driven Configuration

Basic Agent Applications

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

Shell Applications

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"

Advanced Configuration

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)
}

Model Provider Auto-Configuration

Local Models (No API Keys Required!)

Embabel excels with local models - zero external dependencies needed:

Ollama Integration

@SpringBootApplication
@EnableAgents
class OllamaAgentApplication

fun main(args: Array<String>) {
    runApplication<OllamaAgentApplication>(*args)
}

Prerequisites:

  1. Install Ollama: curl -fsSL https://ollama.ai/install.sh | sh
  2. Pull models: ollama pull llama3.2 or ollama pull codellama
  3. 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")
    }
}

Docker Models Integration

@SpringBootApplication
@EnableAgents
class DockerModelApplication

With Docker Desktop + MCP:

  • Uses Docker-managed model containers
  • Automatic model lifecycle management
  • Isolated model execution environments

Cloud Models (Optional Enhancement)

Cloud models enhance capabilities but are completely optional:

OpenAI Integration

<dependency>
    <groupId>com.embabel.agent</groupId>
    <artifactId>embabel-agent-starter-openai</artifactId>
</dependency>
@SpringBootApplication
@EnableAgents
class CloudEnabledApplication

Configuration:

# Optional - only if you want cloud models
export OPENAI_API_KEY=your_api_key

Auto-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

Anthropic Integration

<dependency>
    <groupId>com.embabel.agent</groupId>
    <artifactId>embabel-agent-starter-anthropic</artifactId>
</dependency>
# Optional - enables Claude models
export ANTHROPIC_API_KEY=your_anthropic_key

Hybrid Model Strategies

Embabel'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")
    }
}

Conditional Configuration

Environment-Based Auto-Configuration

@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
        )
    }
}

Model Provider Conditions

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
    }
}

MCP (Model Context Protocol) Auto-Configuration

Docker Desktop MCP

Automatically configures MCP tools when Docker Desktop is available:

@SpringBootApplication
@EnableAgents(mcpServers = [McpServers.DOCKER_DESKTOP])
class McpEnabledApplication

Auto-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")
    }
}

Custom MCP Servers

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:}

Spring Boot Starters Reference

Core Starters

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

Model Provider Starters

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

Integration Starters

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

Configuration Properties Deep Dive

Auto-Configuration Properties

# 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: true

Model Provider Properties

embabel:
  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

Testing with Auto-Configuration

Test Configuration

@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()
    }
}

Mock Model Providers

@TestConfiguration
class TestAutoConfiguration {
    
    @Bean
    @Primary
    fun mockModelProvider(): ModelProvider {
        return MockModelProvider()
    }
    
    @Bean
    @Primary  
    fun fakeOperationContext(): OperationContext {
        return FakeOperationContext()
    }
}

Advanced Auto-Configuration Patterns

Custom Auto-Configuration

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

Profile-Based Auto-Configuration

@Configuration
@Profile("production")
class ProductionAutoConfiguration {
    
    @Bean
    fun productionModelProvider(): ModelProvider {
        return EnterpriseModelProvider()
    }
}

@Configuration
@Profile("development")  
class DevelopmentAutoConfiguration {
    
    @Bean
    fun developmentModelProvider(): ModelProvider {
        return FastLocalModelProvider()
    }
}

Troubleshooting Auto-Configuration

Debug Auto-Configuration

# See what auto-configuration is happening
java -jar app.jar --debug

# Specific auto-configuration logging
logging.level.com.embabel.agent.autoconfigure=DEBUG

Common Issues

Models Not Auto-Discovered

# Check Ollama connectivity
curl http://localhost:11434/api/tags

# Verify auto-configuration
curl http://localhost:8080/actuator/beans | grep -i ollama

API Keys Not Recognized

# Verify environment variables
env | grep -E "(OPENAI|ANTHROPIC)_API_KEY"

# Check conditional activation
logging.level.com.embabel.agent.config.models=DEBUG

Best Practices

1. Start Local, Scale Cloud

// Development: Local models only
@EnableAgents
class DevelopmentApp

// Production: Hybrid approach  
@EnableAgents
class ProductionApp  // Add cloud starters as needed

2. Use Conditional Configuration

@Bean
@ConditionalOnProperty("app.features.advanced-reasoning", havingValue = "true")
fun advancedReasoningAgent(): AdvancedAgent {
    // Only create if feature enabled
}

3. Environment-Specific Starters

<!-- 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>

4. Graceful Degradation

@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!

Clone this wiki locally