CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-starter

Base starter module for the Embabel Agent Framework providing core dependencies for building agentic flows on the JVM with Spring Boot integration and GOAP-based intelligent path finding.

Overview
Eval results
Files

integration-spring-boot.mddocs/

Spring Boot Integration

Auto-configuration mechanics, component scanning, and META-INF registration for Embabel Agent Framework Spring Boot integration.

Auto-Configuration Classes

AgentPlatformAutoConfiguration

Main auto-configuration class that bootstraps the Embabel Agent Platform.

package com.embabel.agent.autoconfigure.platform;

@AutoConfiguration
@Import({
    ScanConfiguration.class,
    AgentPlatformConfiguration.class,
    ToolGroupsConfiguration.class,
    QuiteMcpClientAutoConfiguration.class
})
public class AgentPlatformAutoConfiguration {
    // Bootstraps Agent Platform, Tools, RAG Services
}

Responsibilities:

  • Imports core configuration classes
  • Registers agent platform beans
  • Configures tool groups
  • Sets up MCP client
  • Enables Spring AI integration with observation

Registration: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

ScanConfiguration

Configures component scanning for agent packages.

@Configuration
@ComponentScan(basePackages = {
    "com.embabel.agent.api",
    "com.embabel.agent.core",
    "com.embabel.agent.experimental",
    "com.embabel.agent.prompt",
    "com.embabel.agent.spi",
    "com.embabel.agent.test",
    "com.embabel.agent.tools",
    "com.embabel.agent.web"
})
@EnableConfigurationProperties
public class ScanConfiguration {
    // Enables component scanning and configuration properties
}

Scanned Packages:

  • com.embabel.agent.api - Core agent API components
  • com.embabel.agent.core - Core implementation classes
  • com.embabel.agent.experimental - Experimental features
  • com.embabel.agent.prompt - Prompt-related components
  • com.embabel.agent.spi - Service Provider Interface implementations
  • com.embabel.agent.test - Testing support components
  • com.embabel.agent.tools - Tool implementations
  • com.embabel.agent.web - Web-related components

Usage: Place your @Agent, @Component, @Service classes in these packages for automatic discovery.

QuiteMcpClientAutoConfiguration

Enhanced MCP (Model Context Protocol) client with resilience patterns.

@AutoConfiguration
@ConditionalOnProperty(
    prefix = "spring.ai.mcp.client",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class QuiteMcpClientAutoConfiguration {
    // Configures resilient MCP client (sync and async)
}

Features:

  • Sync MCP client (default)
  • Async MCP client (when configured)
  • Exponential backoff retry
  • Timeout configuration
  • Resilience patterns

Configuration: spring.ai.mcp.client.* properties

AgentPlatformAutoConfigurationFilter

Filters out conflicting Spring AI auto-configurations.

@AutoConfigurationImportFilter
public class AgentPlatformAutoConfigurationFilter
    implements AutoConfigurationImportFilter {

    @Override
    public boolean[] match(String[] autoConfigurationClasses,
                          AutoConfigurationMetadata autoConfigurationMetadata) {
        // Excludes Spring AI's default McpClientAutoConfiguration
        // Allows Embabel's enhanced implementation to take precedence
    }
}

Purpose: Ensures Embabel's resilient MCP client is used instead of Spring AI's default implementation.

Spring Factories Registration

META-INF/spring.factories

Registers SPI implementations.

# Environment Post Processor
org.springframework.boot.env.EnvironmentPostProcessor=\
com.embabel.agent.config.annotation.spi.EnvironmentPostProcessor

# Auto-Configuration Import Filter
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
com.embabel.agent.autoconfigure.platform.AgentPlatformAutoConfigurationFilter

EnvironmentPostProcessor

Early initialization hook that runs before application context is created.

public class EnvironmentPostProcessor
    implements org.springframework.boot.env.EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(
        ConfigurableEnvironment environment,
        SpringApplication application) {
        // Activates profiles based on @EnableAgents annotation
        // Sets embabel.agent.logging.personality property
    }
}

Timing: Runs during Spring Boot startup, before bean creation.

Actions:

  1. Scans for @EnableAgents annotation
  2. Activates logging theme profiles
  3. Configures MCP server connections
  4. Sets environment properties

Auto-Configuration Registration

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Registers auto-configuration classes.

com.embabel.agent.autoconfigure.platform.AgentPlatformAutoConfiguration

This file is read by Spring Boot to discover auto-configuration classes.

Configuration Properties

agent-platform.properties

Default configuration for the agent platform.

# Scanning
embabel.agent.platform.scanning.annotation=true
embabel.agent.platform.scanning.bean=false

# Ranking
embabel.agent.platform.ranking.max-attempts=5
embabel.agent.platform.ranking.backoff-millis=100
embabel.agent.platform.ranking.backoff-multiplier=5.0
embabel.agent.platform.ranking.backoff-max-interval=180000

# Autonomy
embabel.agent.platform.autonomy.agent-confidence-cut-off=0.6
embabel.agent.platform.autonomy.goal-confidence-cut-off=0.6

# LLM Operations
embabel.agent.platform.llm-operations.prompts.maybe-prompt-template=maybe_prompt_contribution
embabel.agent.platform.llm-operations.prompts.generate-examples-by-default=true
embabel.agent.platform.llm-operations.data-binding.max-attempts=10
embabel.agent.platform.llm-operations.data-binding.fixed-backoff-millis=30

# SSE
embabel.agent.platform.sse.max-buffer-size=100
embabel.agent.platform.sse.max-process-buffers=1000

# Model Provider Retries
embabel.agent.platform.models.anthropic.max-attempts=10
embabel.agent.platform.models.anthropic.backoff-millis=5000
embabel.agent.platform.models.anthropic.backoff-multiplier=5.0
embabel.agent.platform.models.anthropic.backoff-max-interval=180000

embabel.agent.platform.models.openai.max-attempts=10
embabel.agent.platform.models.openai.backoff-millis=5000
embabel.agent.platform.models.openai.backoff-multiplier=5.0
embabel.agent.platform.models.openai.backoff-max-interval=180000

# Testing
embabel.agent.platform.test.mock-mode=true

agent-application.properties

Application-level defaults.

spring.application.name=agent-api
spring.threads.virtual.enabled=true
spring.output.ansi.enabled=ALWAYS

spring.ai.ollama.base-url=http://localhost:11434
spring.ai.openai.api-key=${OPENAI_API_KEY}

management.tracing.enabled=false

embabel.models.default-llm=gpt-4.1-mini
embabel.models.default-embedding-model=text-embedding-3-small

logging.pattern.console=%clr(%d{HH:mm:ss.SSS}){faint} %clr([%t]){magenta} %clr(%-5level) %clr(%logger{0}){cyan} %clr(-){faint} %msg%n

Configuration Metadata

META-INF/additional-spring-configuration-metadata.json

Provides IDE autocomplete and validation.

{
  "properties": [
    {
      "name": "embabel.agent.logging.personality",
      "type": "java.lang.String",
      "description": "Logging personality theme for agent operations",
      "sourceType": "com.embabel.agent.config.annotation.LoggingThemes"
    }
  ],
  "hints": [
    {
      "name": "embabel.agent.logging.personality",
      "values": [
        {"value": "starwars", "description": "Star Wars themed logging"},
        {"value": "severance", "description": "Severance themed logging"},
        {"value": "colossus", "description": "Colossus themed logging"},
        {"value": "hitchhiker", "description": "Hitchhiker's Guide themed logging"},
        {"value": "montypython", "description": "Monty Python themed logging"}
      ]
    }
  ]
}

Benefits:

  • IDE autocomplete for configuration properties
  • Type validation
  • Documentation in IDE
  • Value suggestions

Component Scanning

Package Structure

Place agent classes in scanned packages for automatic discovery:

package com.embabel.agent.api.myapp;  // ✅ Scanned

@Agent(description = "My agent")
@Component
public class MyAgent {
    // Automatically discovered
}
package com.embabel.agent.api.agents

import com.embabel.agent.api.annotation.Agent
import com.embabel.agent.api.annotation.Action
import org.springframework.stereotype.Component

@Agent(description = "Data processing agent")
@Component
class DataProcessingAgent {

    @Action
    fun processData(input: Input): Result {
        // Implementation
    }
}

Custom Package Scanning

Add custom packages to scanning:

package com.mycompany.myapp;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {
    "com.mycompany.myapp.agents",
    "com.mycompany.myapp.services"
})
public class MyAppScanConfiguration {
    // Your custom packages will now be scanned
}
package com.mycompany.myapp

import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration

@Configuration
@ComponentScan(basePackages = [
    "com.mycompany.myapp.agents",
    "com.mycompany.myapp.services"
])
class MyAppScanConfiguration

Scanning Configuration

Control annotation-based agent scanning via properties:

embabel:
  agent:
    platform:
      scanning:
        annotation: true  # Enable @Agent/@Agentic annotation scanning (default: true)
        bean: false       # Enable bean-based agent scanning (default: false)

Dependency Injection

Injecting Agent Platform Services

import com.embabel.agent.api.platform.AgentPlatform;
import com.embabel.agent.api.services.PlatformServices;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private final AgentPlatform platform;
    private final PlatformServices services;

    // Constructor injection (recommended)
    public MyService(AgentPlatform platform, PlatformServices services) {
        this.platform = platform;
        this.services = services;
    }

    public void runAgent() {
        platform.execute(/* ... */);
    }
}

Injecting Configuration Properties

import com.embabel.agent.autoconfigure.platform.AgentPlatformProperties;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private final AgentPlatformProperties properties;

    public MyService(AgentPlatformProperties properties) {
        this.properties = properties;
    }

    public void configure() {
        double cutoff = properties.getAutonomy().getAgentConfidenceCutOff();
        // Use configuration
    }
}

Conditional Configuration

Profile-Based Configuration

# application-dev.yml
embabel:
  agent:
    platform:
      test:
        mock-mode: true  # Enable mocks in development

# application-prod.yml
embabel:
  agent:
    platform:
      test:
        mock-mode: false  # Real LLM calls in production

Activate with:

export SPRING_PROFILES_ACTIVE=dev
# or
java -jar app.jar --spring.profiles.active=prod

Conditional Beans

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomConfiguration {

    @Bean
    @ConditionalOnProperty(
        prefix = "embabel.agent",
        name = "custom-feature-enabled",
        havingValue = "true"
    )
    public CustomFeature customFeature() {
        return new CustomFeature();
    }
}

ConditionalOnMcpConnection

Enable conditional bean creation based on configured MCP connections.

package com.embabel.agent.spi.config.spring

@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Conditional(OnMcpConnectionCondition::class)
annotation class ConditionalOnMcpConnection(
    vararg val value: String
)

Usage Example (Java):

import com.embabel.agent.spi.config.spring.ConditionalOnMcpConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyToolsConfiguration {

    @Bean
    @ConditionalOnMcpConnection("github-mcp")
    public ToolGroup githubTools() {
        // Only created when github-mcp connection is configured
        return ToolGroup.create("github", githubToolList);
    }

    @Bean
    @ConditionalOnMcpConnection("brave-search-mcp", "fetch-mcp")
    public ToolGroup webTools() {
        // Created when ANY of the specified connections exists
        return ToolGroup.create("web", webToolList);
    }
}

Usage Example (Kotlin):

import com.embabel.agent.spi.config.spring.ConditionalOnMcpConnection
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class MyToolsConfiguration {

    @Bean
    @ConditionalOnMcpConnection("github-mcp", "docker-mcp")
    fun githubToolsGroup(): ToolGroup {
        // Created if either github-mcp or docker-mcp is configured
        return McpToolGroup(
            name = "github-tools",
            description = "GitHub API tools",
            clients = mcpSyncClients
        )
    }
}

Configuration Example:

spring:
  ai:
    mcp:
      client:
        stdio:
          connections:
            github-mcp:
              command: npx
              args:
                - -y
                - @modelcontextprotocol/server-github
            docker-mcp:
              command: docker
              args:
                - run
                - -i
                - --rm
                - ghcr.io/modelcontextprotocol/servers/github

How It Works:

  • Checks for configuration properties at startup
  • For STDIO connections: spring.ai.mcp.client.stdio.connections.{name}.command
  • For SSE connections: spring.ai.mcp.client.sse.connections.{name}.url
  • If ANY specified connection name has configuration, the bean is created
  • If NONE of the connections are configured, the bean is skipped

Integration Patterns

Pattern 1: REST API with Agent Backend

@RestController
@RequestMapping("/api/agents")
public class AgentController {
    private final AgentPlatform platform;

    public AgentController(AgentPlatform platform) {
        this.platform = platform;
    }

    @PostMapping("/execute")
    public ResponseEntity<Result> execute(@RequestBody Request request) {
        Result result = platform.execute(request);
        return ResponseEntity.ok(result);
    }
}

Pattern 2: Scheduled Agent Execution

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledAgentRunner {
    private final AgentPlatform platform;

    public ScheduledAgentRunner(AgentPlatform platform) {
        this.platform = platform;
    }

    @Scheduled(cron = "0 0 * * * *")  // Every hour
    public void runPeriodicAgent() {
        platform.execute(/* periodic task */);
    }
}

Pattern 3: Event-Driven Agent Execution

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class EventDrivenAgentRunner {
    private final AgentPlatform platform;

    public EventDrivenAgentRunner(AgentPlatform platform) {
        this.platform = platform;
    }

    @EventListener
    public void handleCustomEvent(CustomEvent event) {
        platform.execute(event.getData());
    }
}

Troubleshooting

Issue: Beans Not Found

Solution: Ensure your classes are in scanned packages (com.embabel.agent.*).

Issue: Configuration Not Applied

Solution: Check property names and ensure application.yml is in src/main/resources/.

Issue: MCP Client Not Working

Solution: Verify Spring Milestones repository is configured and spring.ai.mcp.client.enabled=true.

Issue: Auto-Configuration Conflicts

Solution: Check for conflicting auto-configurations and exclude them in @SpringBootApplication:

@SpringBootApplication(exclude = {ConflictingAutoConfiguration.class})
public class MyApplication {
    // ...
}

Issue: Agent Not Discovered

Solutions:

  1. Verify agent is in a scanned package (com.embabel.agent.*)
  2. Check for @Component annotation on agent class
  3. Ensure @Agent annotation is present
  4. Verify no exclusion filters are blocking discovery
  5. Check that scanning.annotation=true in configuration

Issue: Circular Dependencies

Solution: Use constructor injection and @Lazy where needed:

@Component
public class ServiceA {
    private final ServiceB serviceB;

    public ServiceA(@Lazy ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}
tessl i tessl/maven-com-embabel-agent--embabel-agent-starter@0.3.1

docs

api-annotations.md

api-domain-model.md

api-invocation.md

api-tools.md

concepts-actions.md

concepts-agents.md

concepts-goals.md

concepts-invocation.md

concepts-tools.md

guides-creating-agents.md

guides-creating-tools.md

guides-defining-actions.md

guides-goal-achievement.md

guides-human-in-loop.md

guides-multimodal.md

index.md

integration-mcp.md

integration-model-providers.md

integration-spring-boot.md

LlmTool.md

quickstart.md

reference-component-scanning.md

reference-configuration-properties.md

reference-installation.md

reference-logging.md

reference-resilience.md

reference-streaming.md

tile.json