Interface AgentExecutor

All Known Implementing Classes:
MultiInstanceReplicationAgentExecutor, SimpleAgentExecutor

public interface AgentExecutor
Core business logic interface for implementing A2A agent functionality.

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

The DefaultRequestHandler executes AgentExecutor methods asynchronously in a background thread pool when requests arrive from transport layers. Your implementation should:

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
 
See Also:
  • Method Details

    • execute

      void execute(RequestContext context, AgentEmitter emitter) throws A2AError
      Executes the agent's business logic for a message.

      Called asynchronously by DefaultRequestHandler in 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 throw A2AError for truly exceptional conditions.

      Parameters:
      context - the request context containing the message, task state, and configuration
      emitter - the agent emitter for sending messages, updating status, and streaming artifacts
      Throws:
      A2AError - if execution fails catastrophically (exception propagates to client)
    • cancel

      void cancel(RequestContext context, AgentEmitter emitter) throws A2AError
      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 TaskNotCancelableError if your agent does not support cancellation at all (e.g., fire-and-forget agents)
      • Throw A2AError if 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 canceled
      emitter - the agent emitter for sending the cancellation event
      Throws:
      TaskNotCancelableError - if this agent does not support cancellation
      A2AError - if cancellation is supported but failed to execute