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-tools.mddocs/

Tool API Reference

Complete API reference for creating, managing, and using tools in agent execution.

Base Tool Interface

Tool

Base interface for all tools with factory methods for programmatic creation.

package com.embabel.agent.api

interface Tool {
    companion object {
        fun create(name: String, function: Function<*, *>): Tool
        fun create(name: String, description: String, function: Function<*, *>): Tool
        fun fromMethod(method: Method): Tool
        fun fromMethod(instance: Any, method: Method): Tool
    }

    fun getName(): String
    fun getDescription(): String
    fun getParameters(): List<ToolParameter>

    fun execute(arguments: Map<String, Any>): Any
}

Factory Methods:

  • create(name: String, function: Function<*, *>): Tool - Create tool with name and function
  • create(name: String, description: String, function: Function<*, *>): Tool - Create tool with name, description, and function
  • fromMethod(method: Method): Tool - Create tool from method
  • fromMethod(instance: Any, method: Method): Tool - Create tool from instance method

Methods:

  • getName(): String - Get tool name
  • getDescription(): String - Get tool description
  • getParameters(): List<ToolParameter> - Get parameter definitions
  • execute(arguments: Map<String, Any>): Any - Execute tool with arguments

Usage:

@EmbabelComponent
public class CalculatorTools {

    public List<Tool> createCalculatorTools() {
        return List.of(
            Tool.create("add", "Add two numbers", (args) -> {
                double a = (Double) args.get("a");
                double b = (Double) args.get("b");
                return a + b;
            }),

            Tool.create("multiply", "Multiply two numbers", (args) -> {
                double a = (Double) args.get("a");
                double b = (Double) args.get("b");
                return a * b;
            }),

            Tool.create("divide", "Divide two numbers", (args) -> {
                double a = (Double) args.get("a");
                double b = (Double) args.get("b");
                if (b == 0) throw new IllegalArgumentException("Division by zero");
                return a / b;
            })
        );
    }
}
@EmbabelComponent
class StringTools {

    fun createStringTools(): List<Tool> {
        return listOf(
            Tool.create("uppercase", "Convert string to uppercase") { args ->
                (args["text"] as String).uppercase()
            },

            Tool.create("lowercase", "Convert string to lowercase") { args ->
                (args["text"] as String).lowercase()
            },

            Tool.create("reverse", "Reverse a string") { args ->
                (args["text"] as String).reversed()
            },

            Tool.create("length", "Get string length") { args ->
                (args["text"] as String).length
            }
        )
    }
}

Creating from Methods:

import com.embabel.agent.api.Tool;
import java.lang.reflect.Method;

public class ReflectiveToolFactory {

    public Tool createToolFromMethod() throws NoSuchMethodException {
        Method method = this.getClass().getMethod("processData", String.class);
        return Tool.fromMethod(this, method);
    }

    public String processData(String input) {
        return "Processed: " + input;
    }
}

Progressive Disclosure Tools

MatryoshkaTool

Progressive disclosure tool facade that reveals specific tools based on category selection.

package com.embabel.agent.api

class MatryoshkaTool : Tool {
    companion object {
        fun fromInstance(instance: Any): MatryoshkaTool
    }

    fun selectCategory(category: String): List<Tool>
    fun getCategories(): List<String>
}

Factory Methods:

  • fromInstance(instance: Any): MatryoshkaTool - Create from annotated class instance

Methods:

  • selectCategory(category: String): List<Tool> - Select tools by category
  • getCategories(): List<String> - Get available categories

Usage:

import com.embabel.agent.api.MatryoshkaTool;
import com.embabel.agent.api.annotation.MatryoshkaTools;
import com.embabel.agent.api.annotation.LlmTool;

@EmbabelComponent
@MatryoshkaTools(
    name = "database_operations",
    description = "Database tools - select category: query, insert, update, or delete"
)
public class DatabaseTools {

    public static MatryoshkaTool createDatabaseTool() {
        return MatryoshkaTool.fromInstance(new DatabaseTools());
    }

    @LlmTool(description = "Execute SELECT query", category = "query")
    public List<Map<String, Object>> select(
        @LlmTool.Param(description = "SQL SELECT statement") String sql
    ) {
        return database.executeQuery(sql);
    }

    @LlmTool(description = "Insert new record", category = "insert")
    public int insert(
        @LlmTool.Param(description = "Table name") String table,
        @LlmTool.Param(description = "Record data") Map<String, Object> data
    ) {
        return database.insert(table, data);
    }

    @LlmTool(description = "Update existing record", category = "update")
    public int update(
        @LlmTool.Param(description = "Table name") String table,
        @LlmTool.Param(description = "WHERE clause") String where,
        @LlmTool.Param(description = "Updated data") Map<String, Object> data
    ) {
        return database.update(table, where, data);
    }

    @LlmTool(description = "Delete record", category = "delete")
    public int delete(
        @LlmTool.Param(description = "Table name") String table,
        @LlmTool.Param(description = "WHERE clause") String where
    ) {
        return database.delete(table, where);
    }
}
import com.embabel.agent.api.MatryoshkaTool
import com.embabel.agent.api.annotation.MatryoshkaTools
import com.embabel.agent.api.annotation.LlmTool

@EmbabelComponent
@MatryoshkaTools(
    name = "file_system",
    description = "File system tools - choose: read, write, or manage"
)
class FileSystemTools {

    companion object {
        fun createFileSystemTool(): MatryoshkaTool {
            return MatryoshkaTool.fromInstance(FileSystemTools())
        }
    }

    @LlmTool(description = "Read file contents", category = "read")
    fun readFile(@LlmTool.Param(description = "File path") path: String): String {
        return fileService.read(path)
    }

    @LlmTool(description = "List directory contents", category = "read")
    fun listDirectory(@LlmTool.Param(description = "Directory path") path: String): List<String> {
        return fileService.list(path)
    }

    @LlmTool(description = "Write file", category = "write")
    fun writeFile(
        @LlmTool.Param(description = "File path") path: String,
        @LlmTool.Param(description = "Content") content: String
    ) {
        fileService.write(path, content)
    }

    @LlmTool(description = "Delete file", category = "manage")
    fun deleteFile(@LlmTool.Param(description = "File path") path: String) {
        fileService.delete(path)
    }

    @LlmTool(description = "Move file", category = "manage")
    fun moveFile(
        @LlmTool.Param(description = "Source path") source: String,
        @LlmTool.Param(description = "Destination path") dest: String
    ) {
        fileService.move(source, dest)
    }
}

Agentic Tools

AgenticTool

Tools that wrap agent invocations and expose them as callable functions.

package com.embabel.agent.api

class AgenticTool : Tool {
    companion object {
        fun fromAgent(agent: Agent): AgenticTool
        fun fromAgent(agentClass: Class<*>): AgenticTool
        fun fromAgent(agentName: String): AgenticTool
    }

    fun invokeAgent(arguments: Map<String, Any>): Any
}

Factory Methods:

  • fromAgent(agent: Agent): AgenticTool - Create from agent instance
  • fromAgent(agentClass: Class<*>): AgenticTool - Create from agent class
  • fromAgent(agentName: String): AgenticTool - Create from agent name

Methods:

  • invokeAgent(arguments: Map<String, Any>): Any - Invoke wrapped agent with arguments

Usage:

import com.embabel.agent.api.AgenticTool;

@EmbabelComponent
public class AgentToolProvider {

    public List<Tool> createAgenticTools() {
        return List.of(
            AgenticTool.fromAgent(DataAnalyzerAgent.class),
            AgenticTool.fromAgent("ReportGeneratorAgent"),
            AgenticTool.fromAgent(summarizerAgentInstance)
        );
    }

    @Action(description = "Use agentic tools for complex processing")
    public Result processWithAgenticTools(
        Input input,
        @Provided Ai ai
    ) {
        List<Tool> tools = createAgenticTools();

        return ai.withLlm(OpenAiModels.GPT_4_TURBO)
                 .withTools(tools)
                 .createObject("Process this input: " + input);
    }
}
import com.embabel.agent.api.AgenticTool

@EmbabelComponent
class AgentToolProvider {

    fun createAgenticTools(): List<Tool> {
        return listOf(
            AgenticTool.fromAgent(DataAnalyzerAgent::class.java),
            AgenticTool.fromAgent("ReportGeneratorAgent"),
            AgenticTool.fromAgent(summarizerAgentInstance)
        )
    }

    @Action(description = "Complex processing with agent tools")
    fun processWithAgenticTools(
        input: Input,
        @Provided ai: Ai
    ): Result {
        val tools = createAgenticTools()

        return ai.withLlm(OpenAiModels.GPT_4_TURBO)
                 .withTools(tools)
                 .createObject("Process: $input")
    }
}

Tool Groups

Tool Group Definition

Organize related tools into groups for modular management and dependency declaration.

Usage:

import com.embabel.agent.api.annotation.ToolGroup;
import com.embabel.agent.api.Tool;

@EmbabelComponent
public class AnalysisToolGroups {

    @ToolGroup(role = "statistical-analysis")
    public List<Tool> getStatisticalTools() {
        return List.of(
            Tool.create("mean", "Calculate mean", this::calculateMean),
            Tool.create("median", "Calculate median", this::calculateMedian),
            Tool.create("std_dev", "Calculate standard deviation", this::calculateStdDev),
            Tool.create("correlation", "Calculate correlation", this::calculateCorrelation)
        );
    }

    @ToolGroup(role = "data-visualization")
    public List<Tool> getVisualizationTools() {
        return List.of(
            Tool.create("scatter_plot", "Create scatter plot", this::createScatterPlot),
            Tool.create("bar_chart", "Create bar chart", this::createBarChart),
            Tool.create("line_chart", "Create line chart", this::createLineChart)
        );
    }

    private double calculateMean(Map<String, Object> args) { /* ... */ }
    private double calculateMedian(Map<String, Object> args) { /* ... */ }
    private double calculateStdDev(Map<String, Object> args) { /* ... */ }
    private double calculateCorrelation(Map<String, Object> args) { /* ... */ }
    private String createScatterPlot(Map<String, Object> args) { /* ... */ }
    private String createBarChart(Map<String, Object> args) { /* ... */ }
    private String createLineChart(Map<String, Object> args) { /* ... */ }
}

Using Tool Groups in Actions

Actions can require and provide tool groups:

@Agent(description = "Data analyst")
public class DataAnalystAgent {

    @Action(
        description = "Perform statistical analysis",
        toolGroupRequirements = {"statistical-analysis"}
    )
    public StatisticalReport analyzeData(Dataset data, @Provided Ai ai) {
        return ai.createObject("Analyze this dataset: " + data);
    }

    @Action(
        description = "Create visualization",
        toolGroupRequirements = {"data-visualization"}
    )
    public Visualization visualizeData(Dataset data, @Provided Ai ai) {
        return ai.createObject("Create a visualization for: " + data);
    }

    @Action(
        description = "Full analysis with charts",
        toolGroupRequirements = {"statistical-analysis", "data-visualization"}
    )
    public FullReport fullAnalysis(Dataset data, @Provided Ai ai) {
        return ai.createObject("Perform full analysis with charts: " + data);
    }
}

Tool Parameters

ToolParameter

Define parameters with types, descriptions, and validation.

package com.embabel.agent.api

data class ToolParameter(
    val name: String,
    val type: Class<*>,
    val description: String,
    val required: Boolean = true,
    val defaultValue: Any? = null
)

Constructor Parameters:

  • name: String - Parameter name
  • type: Class<*> - Parameter type
  • description: String - Parameter description
  • required: Boolean - Required flag (default: true)
  • defaultValue: Any? - Default value (default: null)

Usage:

import com.embabel.agent.api.Tool;
import com.embabel.agent.api.ToolParameter;

public class ParameterizedToolFactory {

    public Tool createSearchTool() {
        List<ToolParameter> parameters = List.of(
            new ToolParameter("query", String.class, "Search query", true, null),
            new ToolParameter("maxResults", Integer.class, "Maximum results", false, 10),
            new ToolParameter("sortBy", String.class, "Sort field", false, "relevance")
        );

        return Tool.builder()
            .name("search")
            .description("Search for documents")
            .parameters(parameters)
            .function(this::performSearch)
            .build();
    }

    private List<Document> performSearch(Map<String, Object> args) {
        String query = (String) args.get("query");
        int maxResults = (Integer) args.getOrDefault("maxResults", 10);
        String sortBy = (String) args.getOrDefault("sortBy", "relevance");

        return searchService.search(query, maxResults, sortBy);
    }
}

Complete Integration Examples

Java - Custom Tool Suite

import com.embabel.agent.api.*;
import com.embabel.agent.api.annotation.*;

@Agent(description = "Data processing agent with custom tools")
public class DataProcessingAgent {

    @Action(
        description = "Process data with custom tools",
        toolGroups = {"data-tools"}
    )
    public ProcessedData processData(
        RawData data,
        @Provided Ai ai,
        @Provided ActionContext context
    ) {
        List<Tool> tools = createDataTools();

        context.updateProgress("Processing data with " + tools.size() + " tools");

        return ai.withLlm(OpenAiModels.GPT_4_TURBO)
                 .withTools(tools)
                 .createObject("Process and transform: " + data);
    }

    @ToolGroup(role = "data-tools")
    private List<Tool> createDataTools() {
        return List.of(
            Tool.create("validate", "Validate data format", this::validateData),
            Tool.create("normalize", "Normalize data values", this::normalizeData),
            Tool.create("aggregate", "Aggregate data points", this::aggregateData),

            MatryoshkaTool.fromInstance(new DataTransformTools()),

            AgenticTool.fromAgent(ValidationAgent.class),
            AgenticTool.fromAgent("EnrichmentAgent")
        );
    }

    private ValidationResult validateData(Map<String, Object> args) {
        RawData data = (RawData) args.get("data");
        return validator.validate(data);
    }

    private NormalizedData normalizeData(Map<String, Object> args) {
        RawData data = (RawData) args.get("data");
        return normalizer.normalize(data);
    }

    private AggregatedData aggregateData(Map<String, Object> args) {
        RawData data = (RawData) args.get("data");
        String method = (String) args.get("method");
        return aggregator.aggregate(data, method);
    }
}

@MatryoshkaTools(
    name = "data_transforms",
    description = "Data transformation operations - select: convert, reshape, or filter"
)
class DataTransformTools {

    @LlmTool(description = "Convert data format", category = "convert")
    public ConvertedData convert(
        @LlmTool.Param(description = "Source data") RawData data,
        @LlmTool.Param(description = "Target format") String format
    ) {
        return converter.convert(data, format);
    }

    @LlmTool(description = "Reshape data structure", category = "reshape")
    public ReshapedData reshape(
        @LlmTool.Param(description = "Source data") RawData data,
        @LlmTool.Param(description = "Target shape") String shape
    ) {
        return reshaper.reshape(data, shape);
    }

    @LlmTool(description = "Filter data by criteria", category = "filter")
    public FilteredData filter(
        @LlmTool.Param(description = "Source data") RawData data,
        @LlmTool.Param(description = "Filter expression") String expression
    ) {
        return filterer.filter(data, expression);
    }
}

Kotlin - Custom Tool Suite

import com.embabel.agent.api.*
import com.embabel.agent.api.annotation.*

@Agent(description = "Analysis agent with tool suite")
class AnalysisAgent {

    @Action(
        description = "Analyze data with specialized tools",
        toolGroups = ["analysis-tools"]
    )
    fun analyzeData(
        data: Dataset,
        @Provided ai: Ai,
        @Provided context: ActionContext
    ): AnalysisReport {
        val tools = createAnalysisTools()

        context.updateProgress("Analyzing with ${tools.size} specialized tools")

        return ai.withLlm(GeminiModels.GEMINI_2_5_PRO)
                 .withTools(tools)
                 .createObject("Analyze: $data")
    }

    @ToolGroup(role = "analysis-tools")
    fun createAnalysisTools(): List<Tool> {
        return listOf(
            Tool.create("summarize", "Summarize data", ::summarizeData),
            Tool.create("findOutliers", "Find outliers", ::findOutliers),
            Tool.create("detectTrends", "Detect trends", ::detectTrends),

            MatryoshkaTool.fromInstance(StatisticalTools()),

            AgenticTool.fromAgent(DeepAnalysisAgent::class.java)
        )
    }

    private fun summarizeData(args: Map<String, Any>): Summary {
        val data = args["data"] as Dataset
        return summarizer.summarize(data)
    }

    private fun findOutliers(args: Map<String, Any>): List<Outlier> {
        val data = args["data"] as Dataset
        return outlierDetector.detect(data)
    }

    private fun detectTrends(args: Map<String, Any>): List<Trend> {
        val data = args["data"] as Dataset
        return trendDetector.detect(data)
    }
}
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