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.
Complete API reference for programmatic agent invocation and execution management.
Primary interface for invoking agents and receiving typed results.
package com.embabel.agent.api
interface AgentInvocation<T : Any> {
companion object {
fun <T : Any> create(platform: AgentPlatform, resultClass: Class<T>): AgentInvocation<T>
inline fun <reified T : Any> create(platform: AgentPlatform): AgentInvocation<T>
fun builder(platform: AgentPlatform): Builder
fun on(platform: AgentPlatform): AgentInvocation<Any>
}
fun withAgentPlatform(platform: AgentPlatform): AgentInvocation<T>
fun <U : Any> returning(resultClass: Class<U>): AgentInvocation<U>
fun invoke(...): T
fun invokeAsync(...): CompletableFuture<T>
interface Builder {
fun withContext(...): Builder
fun withBlackboard(...): Builder
fun withVerbosity(...): Builder
fun withBudget(...): Builder
fun withPolicies(...): Builder
fun <T : Any> build(resultClass: Class<T>): AgentInvocation<T>
}
}Factory Methods:
create(platform: AgentPlatform, resultClass: Class<T>): AgentInvocation<T> - Create typed invocation with result classcreate<T>(platform: AgentPlatform): AgentInvocation<T> - Kotlin reified generics variantbuilder(platform: AgentPlatform): Builder - Create builder for advanced configurationon(platform: AgentPlatform): AgentInvocation<Any> - Create untyped invocationConfiguration Methods:
withAgentPlatform(platform: AgentPlatform): AgentInvocation<T> - Set platformreturning<U>(resultClass: Class<U>): AgentInvocation<U> - Change result typeExecution Methods:
invoke(...): T - Synchronous invocationinvokeAsync(...): CompletableFuture<T> - Asynchronous invocationUsage:
@Service
public class OrderService {
private final AgentPlatform platform;
public OrderService(AgentPlatform platform) {
this.platform = platform;
}
public OrderResult processOrder(Order order) {
AgentInvocation<OrderResult> invocation =
AgentInvocation.create(platform, OrderResult.class);
return invocation.invoke(order);
}
}@Service
class DataService(private val platform: AgentPlatform) {
fun processData(input: DataInput): ProcessedData {
val invocation = AgentInvocation.create<ProcessedData>(platform)
return invocation.invoke(input)
}
}Builder for advanced invocation configuration.
Configuration Methods:
withContext(...): Builder - Set execution contextwithBlackboard(...): Builder - Initialize blackboard statewithVerbosity(...): Builder - Set logging verbositywithBudget(...): Builder - Set time/step budgetwithPolicies(...): Builder - Configure retry/timeout policiesbuild<T>(resultClass: Class<T>): AgentInvocation<T> - Build configured invocationUsage:
public class AdvancedService {
private final AgentPlatform platform;
public AnalysisResult analyzeWithContext(
Dataset dataset,
Map<String, Object> initialState
) {
AgentInvocation<AnalysisResult> invocation = AgentInvocation.builder(platform)
.withContext(new ExecutionContext("analysis-session"))
.withBlackboard(Blackboard.fromMap(initialState))
.withVerbosity(Verbosity.DETAILED)
.withBudget(Budget.of(1000, TimeUnit.SECONDS))
.build(AnalysisResult.class);
return invocation.invoke(dataset);
}
}class AdvancedService(private val platform: AgentPlatform) {
fun performAnalysis(dataset: Dataset): AnalysisResult {
val invocation = AgentInvocation.builder(platform)
.withContext(ExecutionContext("analysis-${UUID.randomUUID()}"))
.withBlackboard(Blackboard.fromMap(mapOf(
"dataset" to dataset,
"analysisType" to "comprehensive",
"outputFormat" to "json"
)))
.withVerbosity(Verbosity.DETAILED)
.withBudget(Budget.of(120, TimeUnit.SECONDS))
.withPolicies(PolicySet.builder()
.withRetryPolicy(RetryPolicy.exponential(3, 1000))
.withTimeoutPolicy(TimeoutPolicy.of(90, TimeUnit.SECONDS))
.build())
.build(AnalysisResult::class.java)
return invocation.invoke(dataset)
}
}Async Usage:
public class AsyncService {
public CompletableFuture<Report> generateReportAsync(RequestData data) {
AgentInvocation<Report> invocation =
AgentInvocation.create(platform, Report.class);
return invocation.invokeAsync(data)
.thenApply(report -> enhance(report))
.exceptionally(error -> fallbackReport(error));
}
}Specialized invocation for utility agents (task-specific, non-planning agents).
package com.embabel.agent.api
interface UtilityInvocation<T : Any> : AgentInvocation<T> {
// Utility-specific configuration and methods
}Usage:
public class UtilityService {
public String formatData(RawData data) {
UtilityInvocation<String> invocation =
UtilityInvocation.create(platform, String.class);
return invocation.invoke(data);
}
}Specialized invocation for supervisor agents (coordinate multiple subagents).
package com.embabel.agent.api
interface SupervisorInvocation<T : Any> : AgentInvocation<T> {
// Supervisor-specific configuration and methods
}Usage:
public class WorkflowService {
public WorkflowResult executeWorkflow(WorkflowSpec spec) {
SupervisorInvocation<WorkflowResult> invocation =
SupervisorInvocation.create(platform, WorkflowResult.class);
return invocation.invoke(spec);
}
}Invocation for executing agents within a specific scope (isolation/resource management).
package com.embabel.agent.api
interface ScopedInvocation<T : Any> : AgentInvocation<T> {
// Scope-specific configuration and methods
}Usage:
class IsolatedService(private val platform: AgentPlatform) {
fun executeInScope(input: Input, scope: String): Result {
val invocation = ScopedInvocation.create<Result>(platform)
.withScope(scope)
return invocation.invoke(input)
}
}Reference to a subagent for resolution and invocation during execution.
package com.embabel.agent.api
class Subagent {
constructor(agent: Agent)
constructor(agentName: String)
constructor(agentClass: Class<*>)
fun resolve(platform: AgentPlatform): Agent
}Constructors:
Subagent(agent: Agent) - Create from agent instanceSubagent(agentName: String) - Create from agent nameSubagent(agentClass: Class<*>) - Create from agent classMethods:
resolve(platform: AgentPlatform): Agent - Resolve subagent reference to agent instanceUsage:
@Agent(description = "Coordinator agent")
public class CoordinatorAgent {
@Action(description = "Process data using subagents")
public ProcessedData processWithSubagents(
RawData data,
@Provided AgentPlatform platform
) {
Subagent validatorAgent = new Subagent("ValidatorAgent");
Subagent transformerAgent = new Subagent(TransformerAgent.class);
Agent validator = validatorAgent.resolve(platform);
Agent transformer = transformerAgent.resolve(platform);
ValidationResult validated = invokeSubagent(validator, data);
return invokeSubagent(transformer, validated);
}
}@Agent(description = "Orchestrator")
class OrchestratorAgent {
@Action(description = "Orchestrate multiple agents")
fun orchestrate(
request: Request,
@Provided platform: AgentPlatform
): Response {
val analyzer = Subagent(AnalyzerAgent::class.java)
val generator = Subagent("GeneratorAgent")
val analyzerInstance = analyzer.resolve(platform)
val generatorInstance = generator.resolve(platform)
val analysis = invokeSubagent(analyzerInstance, request)
return invokeSubagent(generatorInstance, analysis)
}
}Context and utilities during action execution (available as @Provided parameter).
package com.embabel.agent.api
interface ActionContext : OperationContext {
// Message handling
fun sendMessage(message: Message)
fun sendAndSave(message: Message)
// Progress updates
fun updateProgress(message: String)
// Output channels
fun sendOutputChannelEvent(event: OutputChannelEvent)
// Subprocess execution
fun <O : Any> asSubProcess(
outputClass: Class<O>,
builder: TypedAgentScopeBuilder<O>
): O
fun <O : Any> asSubProcess(
outputClass: Class<O>,
agent: Agent
): O
}Methods:
sendMessage(message: Message) - Send message (info, warning, error, progress)sendAndSave(message: Message) - Send and persist messageupdateProgress(message: String) - Update progress with messagesendOutputChannelEvent(event: OutputChannelEvent) - Send structured output eventasSubProcess<O>(outputClass: Class<O>, builder: TypedAgentScopeBuilder<O>): O - Execute subprocess with builderasSubProcess<O>(outputClass: Class<O>, agent: Agent): O - Execute subprocess with agentUsage:
@Agent(description = "Report generator")
public class ReportAgent {
@Action(description = "Generate comprehensive report")
public Report generateReport(
DataSet data,
@Provided ActionContext context
) {
context.updateProgress("Loading data...");
context.sendMessage(Message.info("Processing " + data.size() + " records"));
context.updateProgress("Analyzing data...");
Analysis analysis = analyze(data);
context.updateProgress("Running specialized analysis...");
DetailedAnalysis detailed = context.asSubProcess(
DetailedAnalysis.class,
DetailedAnalyzerAgent.class
);
context.updateProgress("Generating report...");
return createReport(analysis, detailed);
}
}@Agent(description = "Data processor")
class DataProcessorAgent {
@Action(description = "Process data with progress tracking")
fun processData(
input: DataInput,
@Provided context: ActionContext
): ProcessedOutput {
context.updateProgress("Starting data processing...")
context.sendMessage(Message.info("Input size: ${input.records.size}"))
context.updateProgress("Stage 1: Validation")
val validated = validate(input)
context.updateProgress("Stage 2: Transformation")
val transformed = transform(validated)
context.updateProgress("Stage 3: Enrichment (subprocess)")
val enriched = context.asSubProcess(
EnrichedData::class.java,
EnrichmentAgent::class.java
)
context.updateProgress("Complete!")
return ProcessedOutput(enriched)
}
}.withContext(new ExecutionContext("session-id"))Create execution context with session identifier.
.withBlackboard(Blackboard.fromMap(Map.of(
"config", configObject,
"credentials", credentials
)))Initialize blackboard with state map.
.withVerbosity(Verbosity.DETAILED)Set logging verbosity level:
SILENT - No loggingMINIMAL - Minimal loggingNORMAL - Normal logging (default)DETAILED - Detailed loggingDEBUG - Debug-level logging.withBudget(Budget.of(60, TimeUnit.SECONDS)) // Time budget
.withBudget(Budget.ofSteps(1000)) // Step budget
.withBudget(Budget.unlimited()) // No budget limitsSet execution budget (time or steps).
.withPolicies(PolicySet.builder()
.withRetryPolicy(RetryPolicy.exponential(3, 1000))
.withTimeoutPolicy(TimeoutPolicy.of(30, TimeUnit.SECONDS))
.build())Configure retry and timeout policies.
import com.embabel.agent.api.*;
import java.util.concurrent.TimeUnit;
@Service
public class AdvancedAgentService {
private final AgentPlatform platform;
public AdvancedAgentService(AgentPlatform platform) {
this.platform = platform;
}
public AnalysisResult performAnalysis(Dataset dataset) {
AgentInvocation<AnalysisResult> invocation = AgentInvocation.builder(platform)
.withContext(new ExecutionContext("analysis-" + UUID.randomUUID()))
.withBlackboard(Blackboard.fromMap(Map.of(
"dataset", dataset,
"analysisType", "comprehensive",
"outputFormat", "json"
)))
.withVerbosity(Verbosity.DETAILED)
.withBudget(Budget.of(120, TimeUnit.SECONDS))
.withPolicies(PolicySet.builder()
.withRetryPolicy(RetryPolicy.exponential(3, 1000))
.withTimeoutPolicy(TimeoutPolicy.of(90, TimeUnit.SECONDS))
.build())
.build(AnalysisResult.class);
return invocation.invoke(dataset);
}
public CompletableFuture<AnalysisResult> performAnalysisAsync(Dataset dataset) {
AgentInvocation<AnalysisResult> invocation = AgentInvocation.builder(platform)
.withContext(new ExecutionContext("async-analysis"))
.withVerbosity(Verbosity.NORMAL)
.build(AnalysisResult.class);
return invocation.invokeAsync(dataset)
.thenApply(this::postProcessResult)
.exceptionally(this::handleError);
}
private AnalysisResult postProcessResult(AnalysisResult result) {
return result;
}
private AnalysisResult handleError(Throwable error) {
return AnalysisResult.error(error.getMessage());
}
}import com.embabel.agent.api.*
import java.util.concurrent.TimeUnit
@Service
class AdvancedAgentService(private val platform: AgentPlatform) {
fun performAnalysis(dataset: Dataset): AnalysisResult {
val invocation = AgentInvocation.builder(platform)
.withContext(ExecutionContext("analysis-${UUID.randomUUID()}"))
.withBlackboard(Blackboard.fromMap(mapOf(
"dataset" to dataset,
"analysisType" to "comprehensive",
"outputFormat" to "json"
)))
.withVerbosity(Verbosity.DETAILED)
.withBudget(Budget.of(120, TimeUnit.SECONDS))
.withPolicies(PolicySet.builder()
.withRetryPolicy(RetryPolicy.exponential(3, 1000))
.withTimeoutPolicy(TimeoutPolicy.of(90, TimeUnit.SECONDS))
.build())
.build(AnalysisResult::class.java)
return invocation.invoke(dataset)
}
suspend fun performAnalysisAsync(dataset: Dataset): AnalysisResult {
val invocation = AgentInvocation.builder(platform)
.withContext(ExecutionContext("async-analysis"))
.withVerbosity(Verbosity.NORMAL)
.build(AnalysisResult::class.java)
return invocation.invokeAsync(dataset).await()
}
}tessl i tessl/maven-com-embabel-agent--embabel-agent-starter@0.3.1docs