Class AgentEmitter

java.lang.Object
org.a2aproject.sdk.server.tasks.AgentEmitter

public class AgentEmitter extends Object
Helper for emitting events from AgentExecutor implementations.

AgentEmitter provides a simplified API for agents to communicate with clients through the A2A protocol. It handles both task lifecycle management and direct message sending, automatically populating events with correct task and context IDs from the RequestContext.

Core Capabilities

Usage Patterns

Simple Message Response (No Task)


 public void execute(RequestContext context, AgentEmitter emitter) {
     String response = processRequest(context.getUserInput("\n"));
     emitter.sendMessage(response);
 }
 

Task Lifecycle with Artifacts


 public void execute(RequestContext context, AgentEmitter emitter) {
     if (context.getTask() == null) {
         emitter.submit();  // Create task in SUBMITTED state
     }
     emitter.startWork();  // Transition to WORKING

     // Process and stream results
     List<Part<?>> results = doWork(context.getUserInput("\n"));
     emitter.addArtifact(results);

     emitter.complete();  // Mark as COMPLETED
 }
 

Streaming Response (LLM)


 public void execute(RequestContext context, AgentEmitter emitter) {
     emitter.startWork();

     for (String chunk : llmService.stream(context.getUserInput("\n"))) {
         emitter.addArtifact(List.of(new TextPart(chunk)));
     }

     emitter.complete();
 }
 

Event ID Management

All emitted events are automatically populated with:
  • taskId: From RequestContext (may be null for message-only responses)
  • contextId: From RequestContext
  • messageId: Generated UUID for messages
  • artifactId: Generated UUID for artifacts (unless explicitly provided)
Events are validated by the EventQueue to ensure taskId correctness.
Since:
1.0.0
See Also:
  • Constructor Summary

    Constructors
    Constructor
    Description
    AgentEmitter(RequestContext context, EventQueue eventQueue)
    Creates a new AgentEmitter for the given request context and event queue.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    addArtifact(List<Part<?>> parts)
    Adds an artifact with the given parts to the task.
    void
    addArtifact(List<Part<?>> parts, @Nullable String artifactId, @Nullable String name, @Nullable Map<String,Object> metadata)
    Adds an artifact with the given parts, artifact ID, name, and metadata.
    void
    addArtifact(List<Part<?>> parts, @Nullable String artifactId, @Nullable String name, @Nullable Map<String,Object> metadata, @Nullable Boolean append, @Nullable Boolean lastChunk)
    Adds an artifact with all optional parameters.
    void
    addTask(Task task)
    Adds a custom Task object to be sent to the client.
    void
    Marks the task as CANCELED.
    void
    cancel(@Nullable Message message)
    Marks the task as CANCELED with an optional message.
    void
    Marks the task as COMPLETED.
    void
    complete(@Nullable Message message)
    Marks the task as COMPLETED with an optional message.
    void
    Emits a custom Event object to the client.
    void
    Marks the task as FAILED.
    void
    fail(@Nullable Message message)
    Marks the task as FAILED with an optional message.
    void
    fail(A2AError error)
    Enqueues an A2A error event which will automatically transition the task to FAILED.
    @Nullable String
    Returns the context ID for this emitter.
    @Nullable String
    Returns the task ID for this emitter.
    Creates a Message.Builder pre-populated with agent defaults.
    newAgentMessage(List<Part<?>> parts, @Nullable Map<String,Object> metadata)
    Creates a new agent message with the given parts and metadata.
    void
    Marks the task as REJECTED.
    void
    reject(@Nullable Message message)
    Marks the task as REJECTED with an optional message.
    void
    Marks the task as AUTH_REQUIRED, indicating the agent needs authentication to continue.
    void
    requiresAuth(boolean isFinal)
    Marks the task as AUTH_REQUIRED with a finality flag.
    void
    requiresAuth(@Nullable Message message)
    Marks the task as AUTH_REQUIRED with an optional message.
    void
    requiresAuth(@Nullable Message message, boolean isFinal)
    Marks the task as AUTH_REQUIRED with an optional message and finality flag.
    void
    Marks the task as INPUT_REQUIRED, indicating the agent needs user input to continue.
    void
    requiresInput(boolean isFinal)
    Marks the task as INPUT_REQUIRED with a finality flag.
    void
    requiresInput(@Nullable Message message)
    Marks the task as INPUT_REQUIRED with an optional message.
    void
    requiresInput(@Nullable Message message, boolean isFinal)
    Marks the task as INPUT_REQUIRED with an optional message and finality flag.
    void
    Sends a simple text message to the client.
    void
    sendMessage(List<Part<?>> parts)
    Sends a message with custom parts (text, images, etc.) to the client.
    void
    sendMessage(List<Part<?>> parts, @Nullable Map<String,Object> metadata)
    Sends a message with parts and metadata to the client.
    void
    Sends an existing Message object directly to the client.
    void
    Marks the task as WORKING (actively being processed).
    void
    startWork(@Nullable Message message)
    Marks the task as WORKING with an optional message.
    void
    Marks the task as SUBMITTED.
    void
    submit(@Nullable Message message)
    Marks the task as SUBMITTED with an optional message.
    Creates a Task.Builder pre-populated with the correct task and context IDs.
    void
    updateStatus(TaskState taskState, @Nullable Message message)
    Updates the task status to the given state with an optional message.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • AgentEmitter

      public AgentEmitter(RequestContext context, EventQueue eventQueue)
      Creates a new AgentEmitter for the given request context and event queue.
      Parameters:
      context - the request context containing task and context IDs
      eventQueue - the event queue for enqueueing events
  • Method Details

    • updateStatus

      public void updateStatus(TaskState taskState, @Nullable Message message)
      Updates the task status to the given state with an optional message.
      Parameters:
      taskState - the new task state
      message - optional message to include with the status update
    • getContextId

      public @Nullable String getContextId()
      Returns the context ID for this emitter.
      Returns:
      the context ID, or null if not available
    • getTaskId

      public @Nullable String getTaskId()
      Returns the task ID for this emitter.
      Returns:
      the task ID, or null if no task is associated
    • addArtifact

      public void addArtifact(List<Part<?>> parts)
      Adds an artifact with the given parts to the task.
      Parameters:
      parts - the parts to include in the artifact
    • addArtifact

      public void addArtifact(List<Part<?>> parts, @Nullable String artifactId, @Nullable String name, @Nullable Map<String,Object> metadata)
      Adds an artifact with the given parts, artifact ID, name, and metadata.
      Parameters:
      parts - the parts to include in the artifact
      artifactId - optional artifact ID (generated if null)
      name - optional artifact name
      metadata - optional metadata map
    • addArtifact

      public void addArtifact(List<Part<?>> parts, @Nullable String artifactId, @Nullable String name, @Nullable Map<String,Object> metadata, @Nullable Boolean append, @Nullable Boolean lastChunk)
      Adds an artifact with all optional parameters.
      Parameters:
      parts - the parts to include in the artifact
      artifactId - optional artifact ID (generated if null)
      name - optional artifact name
      metadata - optional metadata map
      append - whether to append to an existing artifact
      lastChunk - whether this is the last chunk in a streaming sequence
    • complete

      public void complete()
      Marks the task as COMPLETED.
    • complete

      public void complete(@Nullable Message message)
      Marks the task as COMPLETED with an optional message.
      Parameters:
      message - optional message to include with completion
    • fail

      public void fail()
      Marks the task as FAILED.
    • fail

      public void fail(@Nullable Message message)
      Marks the task as FAILED with an optional message.
      Parameters:
      message - optional message to include with failure
    • fail

      public void fail(A2AError error)
      Enqueues an A2A error event which will automatically transition the task to FAILED.

      Use this when you need to fail the task with a specific A2A error (such as UnsupportedOperationError, InvalidRequestError, TaskNotFoundError, etc.) that should be sent to the client.

      The error event is enqueued and the MainEventBusProcessor will automatically transition the task to FAILED state. This ensures thread-safe state transitions without race conditions, as the single-threaded MainEventBusProcessor handles all state updates.

      Error events are terminal (stop event consumption) and trigger automatic FAILED state transition. The error details are sent to the originating client only, while the FAILED status is replicated to all nodes in multi-instance deployments.

      Example usage:

      
       public void execute(RequestContext context, AgentEmitter emitter) {
           if (!isSupported(context.getMessage())) {
               emitter.fail(new UnsupportedOperationError("Feature not supported"));
               return;
           }
           // ... normal processing
       }
       
      Parameters:
      error - the A2A error to enqueue and send to the client
      Since:
      1.0.0
    • submit

      public void submit()
      Marks the task as SUBMITTED.
    • submit

      public void submit(@Nullable Message message)
      Marks the task as SUBMITTED with an optional message.
      Parameters:
      message - optional message to include
    • startWork

      public void startWork()
      Marks the task as WORKING (actively being processed).
    • startWork

      public void startWork(@Nullable Message message)
      Marks the task as WORKING with an optional message.
      Parameters:
      message - optional message to include
    • cancel

      public void cancel()
      Marks the task as CANCELED.
    • cancel

      public void cancel(@Nullable Message message)
      Marks the task as CANCELED with an optional message.
      Parameters:
      message - optional message to include
    • reject

      public void reject()
      Marks the task as REJECTED.
    • reject

      public void reject(@Nullable Message message)
      Marks the task as REJECTED with an optional message.
      Parameters:
      message - optional message to include
    • requiresInput

      public void requiresInput()
      Marks the task as INPUT_REQUIRED, indicating the agent needs user input to continue.
    • requiresInput

      public void requiresInput(@Nullable Message message)
      Marks the task as INPUT_REQUIRED with an optional message.
      Parameters:
      message - optional message to include
    • requiresInput

      public void requiresInput(boolean isFinal)
      Marks the task as INPUT_REQUIRED with a finality flag.
      Parameters:
      isFinal - whether this is a final status (prevents further updates)
    • requiresInput

      public void requiresInput(@Nullable Message message, boolean isFinal)
      Marks the task as INPUT_REQUIRED with an optional message and finality flag.
      Parameters:
      message - optional message to include
      isFinal - whether this is a final status (prevents further updates)
    • requiresAuth

      public void requiresAuth()
      Marks the task as AUTH_REQUIRED, indicating the agent needs authentication to continue.
    • requiresAuth

      public void requiresAuth(@Nullable Message message)
      Marks the task as AUTH_REQUIRED with an optional message.
      Parameters:
      message - optional message to include
    • requiresAuth

      public void requiresAuth(boolean isFinal)
      Marks the task as AUTH_REQUIRED with a finality flag.
      Parameters:
      isFinal - whether this is a final status (prevents further updates)
    • requiresAuth

      public void requiresAuth(@Nullable Message message, boolean isFinal)
      Marks the task as AUTH_REQUIRED with an optional message and finality flag.
      Parameters:
      message - optional message to include
      isFinal - whether this is a final status (prevents further updates)
    • newAgentMessage

      public Message newAgentMessage(List<Part<?>> parts, @Nullable Map<String,Object> metadata)
      Creates a new agent message with the given parts and metadata. Pre-populates the message with agent role, task ID, context ID, and a generated message ID.
      Parameters:
      parts - the parts to include in the message
      metadata - optional metadata to attach to the message
      Returns:
      a new Message object ready to be sent
    • sendMessage

      public void sendMessage(String text)
      Sends a simple text message to the client. Convenience method for agents that respond with plain text without creating a task.
      Parameters:
      text - the text content to send
    • sendMessage

      public void sendMessage(List<Part<?>> parts)
      Sends a message with custom parts (text, images, etc.) to the client. Use this for rich responses that don't require task lifecycle management.
      Parameters:
      parts - the message parts to send
    • sendMessage

      public void sendMessage(List<Part<?>> parts, @Nullable Map<String,Object> metadata)
      Sends a message with parts and metadata to the client. Creates an agent message with the current task and context IDs (if available) and enqueues it to the event queue.
      Parameters:
      parts - the message parts to send
      metadata - optional metadata to attach to the message
    • sendMessage

      public void sendMessage(Message message)
      Sends an existing Message object directly to the client.

      Use this when you need to forward or echo an existing message without creating a new one. The message is enqueued as-is, preserving its messageId, metadata, and all other fields.

      Note: This is typically used for forwarding user messages or preserving specific message properties. For most cases, prefer sendMessage(String) or sendMessage(List) which create new agent messages with generated IDs.

      Example usage:

      
       public void execute(RequestContext context, AgentEmitter emitter) {
           // Echo the user's message back
           emitter.sendMessage(context.getMessage());
       }
       
      Parameters:
      message - the message to send to the client
      Since:
      1.0.0
    • addTask

      public void addTask(Task task)
      Adds a custom Task object to be sent to the client.

      Use this when you need to create a Task with specific fields (history, artifacts, etc.) that the convenience methods like submit(), startWork(), or complete() don't provide.

      Typical usage pattern: Build a task with taskBuilder(), customize it, then add it with this method.

      Example usage:

      
       public void execute(RequestContext context, AgentEmitter emitter) {
           // Create a task with specific status and history
           Task task = emitter.taskBuilder()
               .status(new TaskStatus(TaskState.SUBMITTED))
               .history(List.of(context.getMessage()))
               .build();
           emitter.addTask(task);
       }
       
      Parameters:
      task - the task to add
      Since:
      1.0.0
    • emitEvent

      public void emitEvent(Event event)
      Emits a custom Event object to the client.

      This is a general-purpose method for emitting any Event type. Most agents should use the convenience methods (sendMessage(String), addTask(Task), addArtifact(List), complete(), etc.), but this method provides flexibility for agents that need to create and emit custom events using the event builders.

      Example usage:

      
       public void execute(RequestContext context, AgentEmitter emitter) {
           // Create a custom TaskStatusUpdateEvent
           TaskStatusUpdateEvent event = TaskStatusUpdateEvent.builder()
               .taskId(context.getTaskId())
               .contextId(context.getContextId())
               .status(new TaskStatus(TaskState.WORKING))
               .isFinal(false)
               .build();
           emitter.emitEvent(event);
       }
       
      Parameters:
      event - the event to emit
      Since:
      1.0.0
    • taskBuilder

      public Task.Builder taskBuilder()
      Creates a Task.Builder pre-populated with the correct task and context IDs. Agents can customize other Task fields (status, artifacts, etc.) before calling build().

      Example usage:

      
       Task task = emitter.taskBuilder()
           .status(new TaskStatus(TaskState.WORKING))
           .build();
       
      Returns:
      a Task.Builder with id and contextId already set
    • messageBuilder

      public Message.Builder messageBuilder()
      Creates a Message.Builder pre-populated with agent defaults. Sets taskId only if non-null (messages can exist independently of tasks).

      Pre-populated fields:

      • taskId - set only if this AgentEmitter has a non-null taskId
      • contextId - current context ID
      • role - Message.Role.AGENT
      • messageId - generated UUID

      Example usage:

      
       Message msg = emitter.messageBuilder()
           .parts(List.of(new TextPart("Hello")))
           .metadata(Map.of("key", "value"))
           .build();
       
      Returns:
      a Message.Builder with common agent fields already set