Camel Components

A2A Sub Task

The A2A Sub Task EIP groups route steps and emits A2A protocol progress events before, after, or when the grouped work fails.

This is useful for A2A consumer routes where you want to report scoped progress updates to the calling agent as the route processes different stages of work.

The emitBefore, emitAfter, and emitOnError fields are optional and are evaluated as Simple expressions against the current Exchange.

EIP options

The A2A Sub Task eip supports the following options which are listed below.

Name Description Default Type

note

The note for this node.

String

description

The description for this node.

String

disabled

Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime.

false

Boolean

emitBefore

Simple expression template to emit before the nested steps run.

String

emitAfter

Simple expression template to emit after the nested steps complete successfully.

String

emitOnError

Simple expression template to emit when the nested steps fail.

String

failIfNoTaskContext

Whether to fail if the current Exchange does not have an active A2A task context.

false

Boolean

outputs

Required

List

Message Body

The message body at each side of the A2A Sub Task EIP: EIP input is the body it needs, EIP output the body after it, and Steps the body its own steps start with.

Side Body Description

EIP output

what its steps end with

What its steps end with.

Steps

unchanged

The bodies are the ones with the default options. A side that is not listed is not known, and tooling does not guess it. The carriers are described in the Camel Catalog.

Example

In this example, the route groups two stages of work and emits progress events for each:

  • YAML

  • Java

- route:
    from:
      uri: a2a:classpath:agent-card.json
      steps:
        - a2aSubTask:
            id: search-docs-progress
            emitBefore: "Searching docs..."
            emitAfter: "Docs found: ${body.size()}"
            emitOnError: "Error searching docs: ${exception.message}"
            steps:
              - to:
                  uri: "elasticsearch:docs?operation=Search"
        - a2aSubTask:
            id: draft-answer-progress
            emitBefore: "Drafting answer..."
            emitAfter: "Answer drafted: ${body}"
            emitOnError: "Error drafting answer: ${exception.message}"
            steps:
              - bean:
                  ref: answerDraftingService
                  method: draft
        - setBody:
            simple: "Final answer: ${body}"
from("a2a:classpath:agent-card.json")
    .a2aSubTask()
        .id("search-docs-progress")
        .emitBefore("Searching docs...")
        .emitAfter("Docs found: ${body.size()}")
        .emitOnError("Error searching docs: ${exception.message}")
        .to("elasticsearch:docs?operation=Search")
    .end()
    .a2aSubTask()
        .id("draft-answer-progress")
        .emitBefore("Drafting answer...")
        .emitAfter("Answer drafted: ${body}")
        .emitOnError("Error drafting answer: ${exception.message}")
        .bean(answerDraftingService, "draft")
    .end()
    .setBody(simple("Final answer: ${body}"));

Behavior

  • The nested steps behave like normal Camel route steps.

  • If the nested steps fail, emitOnError can access the original exception via ${exception.message}, and the original exception continues to propagate through the route.

  • Failures while evaluating the emitBefore, emitAfter, or emitOnError expressions are route failures.

  • Failures while storing or notifying the resulting A2A progress event are best-effort: they are logged at debug level and do not stop nested work, fail an otherwise successful exchange, or replace the original nested-step exception.

  • By default, emitting progress outside an active A2A task context is a no-op. Set failIfNoTaskContext=true when a route should fail if the current Exchange does not carry an active A2A task.

  • Use stable id values on long-lived sub-tasks so route tracing and route-structure views keep stable node names.