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

api-annotations.mddocs/

Annotations API Reference

Complete API reference for all agent framework annotations.

Agent Definition

@Agent

Primary annotation for defining an agent.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
annotation class Agent(
    val name: String = "",
    val provider: String = "",
    val description: String,
    val version: String = DEFAULT_VERSION,
    val planner: PlannerType = PlannerType.GOAP,
    val scan: Boolean = true,
    val beanName: String = "",
    val opaque: Boolean = false,
    val actionRetryPolicy: ActionRetryPolicy = ActionRetryPolicy.DEFAULT,
    val actionRetryPolicyExpression: String = ""
)

Attributes:

  • name: String - Agent name (default: class simple name)
  • provider: String - Provider namespace (default: empty)
  • description: String - Required agent purpose description
  • version: String - Agent version (default: DEFAULT_VERSION)
  • planner: PlannerType - Planning algorithm (default: PlannerType.GOAP)
  • scan: Boolean - Enable classpath scanning (default: true)
  • beanName: String - Override Spring bean name (default: auto-generated)
  • opaque: Boolean - Hide internal actions/conditions (default: false)
  • actionRetryPolicy: ActionRetryPolicy - Default retry strategy (default: ActionRetryPolicy.DEFAULT)
  • actionRetryPolicyExpression: String - Property expression for retry config (default: empty)

Usage:

@Agent(
    description = "Customer support agent",
    provider = "customer-service",
    version = "1.0.0",
    planner = PlannerType.GOAP,
    scan = true
)
public class CustomerSupportAgent { }
@Agent(
    description = "Data processing agent",
    provider = "data-platform",
    version = "2.1.0",
    planner = PlannerType.GOAP,
    opaque = false
)
class DataProcessingAgent { }

@EmbabelComponent

Marks a class that exposes agent capabilities without being an agent itself.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
annotation class EmbabelComponent(
    val scan: Boolean = true
)

Attributes:

  • scan: Boolean - Enable method scanning (default: true)

Usage:

@EmbabelComponent(scan = true)
public class FileOperations {
    @Action(description = "Read file contents")
    public String readFile(String path) {
        return Files.readString(Path.of(path));
    }
}
@EmbabelComponent(scan = true)
class DatabaseOperations {
    @Action(description = "Query database records")
    fun query(sql: String): List<Record> {
        return executeQuery(sql)
    }
}

Action Definition

@Action

Defines an action that an agent can perform.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Action(
    val description: String,
    val pre: Array<String> = [],
    val post: Array<String> = [],
    val canRerun: Boolean = true,
    val clearBlackboard: Boolean = false,
    val outputBinding: String = "",
    val cost: Double = 0.0,
    val value: Double = 0.0,
    val costMethod: String = "",
    val valueMethod: String = "",
    val toolGroups: Array<String> = [],
    val toolGroupRequirements: Array<String> = [],
    val trigger: KClass<*> = Nothing::class,
    val actionRetryPolicy: ActionRetryPolicy = ActionRetryPolicy.DEFAULT,
    val actionRetryPolicyExpression: String = ""
)

Attributes:

  • description: String - Required action description
  • pre: Array<String> - Preconditions (default: empty)
  • post: Array<String> - Postconditions (default: empty)
  • canRerun: Boolean - Allow multiple executions (default: true)
  • clearBlackboard: Boolean - Clear blackboard after execution (default: false)
  • outputBinding: String - Blackboard variable binding (default: empty)
  • cost: Double - Static execution cost (default: 0.0)
  • value: Double - Static execution value (default: 0.0)
  • costMethod: String - Dynamic cost method name (default: empty)
  • valueMethod: String - Dynamic value method name (default: empty)
  • toolGroups: Array<String> - Tool groups provided (default: empty)
  • toolGroupRequirements: Array<String> - Tool groups required (default: empty)
  • trigger: KClass<*> - Triggering type (default: Nothing)
  • actionRetryPolicy: ActionRetryPolicy - Retry strategy (default: DEFAULT)
  • actionRetryPolicyExpression: String - Retry config expression (default: empty)

Usage:

@Action(
    description = "Fetch task from database",
    post = {"taskLoaded"},
    outputBinding = "task",
    cost = 5.0,
    value = 10.0
)
public Task fetchTask(String taskId) {
    return taskRepository.findById(taskId);
}

@Action(
    description = "Process task using LLM",
    pre = {"taskLoaded"},
    post = {"taskProcessed"},
    outputBinding = "result",
    cost = 20.0,
    value = 50.0,
    toolGroups = {"llm-tools"}
)
public ProcessedResult processTask(Task task, Ai ai) {
    return ai.process(task);
}
@Action(
    description = "Validate order data",
    post = ["orderValidated"],
    cost = 2.0,
    value = 15.0
)
fun validateOrder(order: Order): ValidationResult {
    return validator.validate(order)
}

@Action(
    description = "Calculate shipping cost",
    pre = ["orderValidated"],
    post = ["shippingCalculated"],
    outputBinding = "shippingCost",
    costMethod = "calculateCostDynamic"
)
fun calculateShipping(order: Order): Double {
    return shippingCalculator.calculate(order)
}

@Condition

Marks a method as a condition check for GOAP planning.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Condition(
    val name: String,
    val cost: ZeroToOne = ZeroToOne.ZERO
)

Attributes:

  • name: String - Required unique condition name
  • cost: ZeroToOne - Evaluation cost 0.0-1.0 (default: 0.0)

Usage:

@Condition(name = "hasStock", cost = ZeroToOne.of(0.1))
public boolean hasStock(String productId) {
    return inventory.getStock(productId) > 0;
}

@Condition(name = "lowStock", cost = ZeroToOne.of(0.1))
public boolean isLowStock(String productId) {
    return inventory.getStock(productId) < THRESHOLD;
}

@Action(description = "Reorder product", pre = {"lowStock"})
public void reorderProduct(String productId) {
    supplier.placeOrder(productId);
}
@Condition(name = "userAuthenticated", cost = ZeroToOne.of(0.05))
fun isAuthenticated(userId: String): Boolean {
    return authService.isAuthenticated(userId)
}

@Condition(name = "hasPermission", cost = ZeroToOne.of(0.15))
fun hasPermission(userId: String, resource: String): Boolean {
    return authService.checkPermission(userId, resource)
}

@Cost

Marks a method as cost/value computation for dynamic planning.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Cost(
    val name: String
)

Attributes:

  • name: String - Required unique computation method name

Usage:

@Action(
    description = "Allocate compute resources",
    costMethod = "computeAllocationCost",
    valueMethod = "computeAllocationValue"
)
public Allocation allocateResources(Request request) {
    return allocator.allocate(request);
}

@Cost(name = "computeAllocationCost")
public double computeAllocationCost(Request request) {
    double systemLoad = monitor.getCurrentLoad();
    return request.getResourceCount() * systemLoad * 10.0;
}

@Cost(name = "computeAllocationValue")
public double computeAllocationValue(Request request) {
    return request.getPriority() * 100.0;
}
@Action(
    description = "Cache data item",
    costMethod = "cachingCost"
)
fun cacheItem(key: String, value: Any): Unit {
    cache.put(key, value)
}

@Cost(name = "cachingCost")
fun cachingCost(key: String, value: Any): Double {
    val size = estimateSize(value)
    val availableMemory = cache.getAvailableMemory()
    return if (size > availableMemory) 100.0 else 1.0
}

@Provided

Marks a parameter as platform-provided (not from blackboard).

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Provided

Usage:

@Action(description = "Generate article content")
public Article generateContent(
    String topic,
    @Provided Ai ai,
    @Provided ActionContext context
) {
    context.updateProgress("Generating content for: " + topic);
    return ai.withLlm(OpenAiModels.GPT_4_TURBO)
             .createObject("Write an article about: " + topic);
}
@Action(description = "Analyze data with LLM")
fun analyzeData(
    data: Dataset,
    @Provided ai: Ai,
    @Provided context: ActionContext
): Analysis {
    context.sendMessage("Analyzing dataset: ${data.name}")
    return ai.createObject("Analyze this data: ${data.summary}")
}

Tool Annotations

@LlmTool

Exposes a method as an LLM-callable tool.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class LlmTool(
    val description: String,
    val name: String = "",
    val returnDirect: Boolean = false,
    val category: String = ""
)

Attributes:

  • description: String - Required tool description (shown to LLM)
  • name: String - Override tool name (default: method name)
  • returnDirect: Boolean - Skip LLM processing (default: false)
  • category: String - Category for MatryoshkaTools (default: empty)

Usage:

@LlmTool(
    description = "Read the contents of a file from the filesystem",
    name = "read_file"
)
public String readFile(
    @LlmTool.Param(description = "Path to the file to read", required = true)
    String filePath
) {
    return Files.readString(Path.of(filePath));
}

@LlmTool(
    description = "Write content to a file on the filesystem",
    name = "write_file"
)
public void writeFile(
    @LlmTool.Param(description = "Path to the file to write", required = true)
    String filePath,
    @LlmTool.Param(description = "Content to write to the file", required = true)
    String content
) {
    Files.writeString(Path.of(filePath), content);
}
@LlmTool(
    description = "Execute a SQL query and return results",
    name = "sql_query"
)
fun executeQuery(
    @LlmTool.Param(description = "SQL query to execute", required = true)
    query: String
): List<Map<String, Any>> {
    return database.execute(query)
}

@LlmTool(
    description = "Get database schema information",
    name = "get_schema",
    returnDirect = true
)
fun getSchema(): String {
    return database.describeSchema()
}

@LlmTool.Param

Nested annotation for documenting LLM tool parameters.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Param(
    val description: String,
    val required: Boolean = true
)

Attributes:

  • description: String - Required parameter description (shown to LLM)
  • required: Boolean - Parameter required flag (default: true)

@ToolGroup

Marks a method as providing a tool group.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class ToolGroup(
    val role: String
)

Attributes:

  • role: String - Required tool group role/name

Usage:

@ToolGroup(role = "data-analysis")
public List<Tool> getAnalysisTools() {
    return List.of(
        Tool.create("calculate_statistics", this::calculateStats),
        Tool.create("generate_chart", this::generateChart),
        Tool.create("find_correlations", this::findCorrelations)
    );
}
@ToolGroup(role = "web-scraping")
fun getWebTools(): List<Tool> {
    return listOf(
        Tool.create("fetch_url", ::fetchUrl),
        Tool.create("parse_html", ::parseHtml),
        Tool.create("extract_links", ::extractLinks)
    )
}

@MatryoshkaTools

Creates a progressive disclosure tool facade.

package com.embabel.agent.api.annotation

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class MatryoshkaTools(
    val name: String,
    val description: String,
    val removeOnInvoke: Boolean = true,
    val categoryParameter: String = "category"
)

Attributes:

  • name: String - Required facade tool name
  • description: String - Required facade tool description (shown to LLM)
  • removeOnInvoke: Boolean - Remove facade after first invocation (default: true)
  • categoryParameter: String - Category selection parameter name (default: "category")

Usage:

@EmbabelComponent
@MatryoshkaTools(
    name = "data_operations",
    description = "Choose a category of data operations: read, write, or analyze",
    removeOnInvoke = true
)
public class DataOperationsTools {
    @LlmTool(description = "Read data from a source", category = "read")
    public String readData(@LlmTool.Param(description = "Source path") String path) {
        return dataService.read(path);
    }

    @LlmTool(description = "Write data to a destination", category = "write")
    public void writeData(
        @LlmTool.Param(description = "Destination path") String path,
        @LlmTool.Param(description = "Data to write") String data
    ) {
        dataService.write(path, data);
    }

    @LlmTool(description = "Analyze data and generate report", category = "analyze")
    public Report analyzeData(@LlmTool.Param(description = "Data source") String path) {
        return dataService.analyze(path);
    }
}
@EmbabelComponent
@MatryoshkaTools(
    name = "file_operations",
    description = "Select file operation type: basic, advanced, or search",
    removeOnInvoke = true
)
class FileOperationsTools {
    @LlmTool(description = "List files in directory", category = "basic")
    fun listFiles(@LlmTool.Param(description = "Directory path") path: String): List<String> {
        return fileService.list(path)
    }

    @LlmTool(description = "Copy file with options", category = "advanced")
    fun copyFile(
        @LlmTool.Param(description = "Source path") source: String,
        @LlmTool.Param(description = "Destination path") dest: String
    ) {
        fileService.copy(source, dest)
    }

    @LlmTool(description = "Search files by pattern", category = "search")
    fun searchFiles(@LlmTool.Param(description = "Search pattern") pattern: String): List<String> {
        return fileService.search(pattern)
    }
}

Goal Achievement

@AchievesGoal

Marks an action as achieving a specific goal.

package com.embabel.agent.api.annotation;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AchievesGoal {
    String description();
    double value() default 0.0;
    String[] tags() default {};
    String[] examples() default {};
    Export export() default @Export;
}

Attributes:

  • description(): String - Required goal description
  • value(): double - Numeric goal value (default: 0.0)
  • tags(): String[] - Capability tags (default: empty)
  • examples(): String[] - Example scenarios (default: empty)
  • export(): @Export - Export configuration (default: @Export defaults)

Usage:

@AchievesGoal(
    description = "Generate a summary report from analyzed data",
    value = 1.0,
    tags = {"reporting", "summarization"},
    examples = {
        "Summarize sales data for Q4",
        "Generate monthly performance report"
    },
    export = @Export(remote = true, local = true)
)
public Report generateSummaryReport(AnalyzedData data) {
    return new Report();
}
@AchievesGoal(
    description = "Process user request and generate response",
    tags = ["processing", "generation"],
    export = Export(remote = true, local = true)
)
fun processRequest(input: UserInput): Result {
    return Result()
}

@Export

Nested annotation for configuring goal export.

package com.embabel.agent.api.annotation;

public @interface Export {
    String name() default "";
    boolean remote() default false;
    boolean local() default true;
    Class<?>[] startingInputTypes() default {};
}

Attributes:

  • name(): String - Override export name (default: empty, uses method name)
  • remote(): boolean - Expose remotely (e.g., MCP, A2A) (default: false)
  • local(): boolean - Expose locally within platform (default: true)
  • startingInputTypes(): Class<?>[] - Starting input types (default: empty)

Usage:

@AchievesGoal(
    description = "Internal processing step",
    export = @Export(local = true, remote = false)
)
public InternalResult processInternal(Data data) { }

@AchievesGoal(
    description = "Publicly accessible API endpoint",
    export = @Export(
        name = "processUserQuery",
        remote = true,
        local = true,
        startingInputTypes = {String.class, UserQuery.class}
    )
)
public Response processQuery(UserQuery query) { }

Human-in-the-Loop

WaitFor

Utility class for simplified HITL operations (Java syntax sugar).

package com.embabel.agent.api.annotation;

public class WaitFor {
    public static <T> FormBindingRequest<T> formSubmission(String title, Class<T> clazz);
    public static <P> ConfirmationRequest<P> confirmation(P what, String description);
    public static <P> Awaitable<P, ?> awaitable(Awaitable<P, ?> awaitable);
}

Methods:

formSubmission

public static <T> FormBindingRequest<T> formSubmission(String title, Class<T> clazz)

Parameters:

  • title: String - Form title shown to user
  • clazz: Class<T> - Class type for form data binding

Returns: FormBindingRequest<T> - Request object that can be awaited

Usage:

public class UserDetails {
    private String name;
    private String email;
    private int age;
}

FormBindingRequest<UserDetails> request =
    WaitFor.formSubmission("Enter Your Details", UserDetails.class);

UserDetails details = request.await();

confirmation

public static <P> ConfirmationRequest<P> confirmation(P what, String description)

Parameters:

  • what: P - Object requiring confirmation
  • description: String - Description shown to user

Returns: ConfirmationRequest<P> - Request object that can be awaited

Usage:

DeleteAction action = new DeleteAction(resource);

ConfirmationRequest<DeleteAction> request =
    WaitFor.confirmation(action, "Delete this resource permanently?");

boolean confirmed = request.await();

if (confirmed) {
    action.execute();
}

awaitable

public static <P> Awaitable<P, ?> awaitable(Awaitable<P, ?> awaitable)

Parameters:

  • awaitable: Awaitable<P, ?> - Custom awaitable implementation

Returns: Awaitable<P, ?> - Wrapped awaitable

Usage:

Awaitable<CustomResult, ?> customAwaitable = createCustomAwaitable();
Awaitable<CustomResult, ?> wrapped = WaitFor.awaitable(customAwaitable);
CustomResult result = wrapped.await();

Configuration (Deprecated)

@EnableAgents

Deprecated since 0.3.1 - Use application.properties or application.yml instead.

package com.embabel.agent.config.annotation

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableAgents {
    String loggingTheme() default "";
    String[] mcpServers() default {};
}

Attributes:

  • loggingTheme: String - Logging personality theme (default: empty)
    • Values: "starwars", "severance", "colossus", "hitchhiker", "montypython"
  • mcpServers: String[] - Deprecated MCP servers to enable (default: empty)

Alternative (application.yml):

embabel:
  agent:
    logging:
      personality: starwars
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