Interface AgentExecutor
- All Known Implementing Classes:
MultiInstanceReplicationAgentExecutor,SimpleAgentExecutor
This is the primary extension point where agent developers implement their agent's behavior -
LLM interactions, data processing, external API calls, or any custom logic. Along with an
AgentCard, implementing this interface is the minimum requirement to
create a functioning A2A agent.
Lifecycle
TheDefaultRequestHandler executes AgentExecutor methods
asynchronously in a background thread pool when requests arrive from transport layers.
Your implementation should:
- Use the
AgentEmitterto send messages, update task status, and stream artifacts - Handle cancellation via the
cancel(RequestContext, AgentEmitter)method - Be thread-safe if maintaining state across invocations
Threading Model
execute()runs in the agent-executor thread pool (background thread)- Events are consumed by Vert.x worker threads that return responses to clients
- Don't block waiting for events to be consumed - enqueue and return
- Multiple
execute()calls may run concurrently for different tasks
CDI Integration
Provide your AgentExecutor via CDI producer:
@ApplicationScoped
public class MyAgentExecutorProducer {
@Inject
MyService myService; // Your business logic
@Produces
public AgentExecutor agentExecutor() {
return new MyAgentExecutor(myService);
}
}
Example Implementation
public class WeatherAgentExecutor implements AgentExecutor {
private final WeatherService weatherService;
public WeatherAgentExecutor(WeatherService weatherService) {
this.weatherService = weatherService;
}
@Override
public void execute(RequestContext context, AgentEmitter emitter) {
// Initialize task if this is a new conversation
if (context.getTask() == null) {
emitter.submit();
}
emitter.startWork();
// Extract user input from the message
String userMessage = context.getUserInput("\n");
// Process request (your business logic)
String weatherData = weatherService.getWeather(userMessage);
// Return result as artifact
emitter.addArtifact(List.of(new TextPart(weatherData, null)));
emitter.complete();
}
@Override
public void cancel(RequestContext context, AgentEmitter emitter) {
// Clean up resources and mark as canceled
emitter.cancel();
}
}
Streaming Results
For long-running operations or LLM streaming, enqueue multiple artifacts:
emitter.startWork();
for (String chunk : llmService.stream(userInput)) {
emitter.addArtifact(List.of(new TextPart(chunk, null)));
}
emitter.complete(); // Final event closes the queue
-
Method Summary
Modifier and TypeMethodDescriptionvoidcancel(RequestContext context, AgentEmitter emitter) Cancels an ongoing agent execution.voidexecute(RequestContext context, AgentEmitter emitter) Executes the agent's business logic for a message.
-
Method Details
-
execute
Executes the agent's business logic for a message.Called asynchronously by
DefaultRequestHandlerin a background thread when a client sends a message. Enqueue events to the queue as processing progresses. The queue remains open until you enqueue a final event (COMPLETED, FAILED, or CANCELED state).Important: Don't throw exceptions for business logic errors. Instead, use
emitter.fail(errorMessage)to communicate failures to the client gracefully. Only throwA2AErrorfor truly exceptional conditions.- Parameters:
context- the request context containing the message, task state, and configurationemitter- the agent emitter for sending messages, updating status, and streaming artifacts- Throws:
A2AError- if execution fails catastrophically (exception propagates to client)
-
cancel
Cancels an ongoing agent execution.Called when a client requests task cancellation via the cancelTask operation. You should:
- Stop any ongoing work (interrupt LLM calls, cancel API requests)
- Enqueue a CANCELED status event (typically via
emitter.cancel()) - Clean up resources (close connections, release locks)
Note: The
execute(RequestContext, AgentEmitter)method may still be running on another thread. Use appropriate synchronization or interruption mechanisms if your agent maintains cancellable state.Error Handling:
- Throw
TaskNotCancelableErrorif your agent does not support cancellation at all (e.g., fire-and-forget agents) - Throw
A2AErrorif cancellation is supported but failed to execute (e.g., unable to interrupt running operation) - Return normally after enqueueing CANCELED event if cancellation succeeds
- Parameters:
context- the request context for the task being canceledemitter- the agent emitter for sending the cancellation event- Throws:
TaskNotCancelableError- if this agent does not support cancellationA2AError- if cancellation is supported but failed to execute
-