# Build Your First Agent

Build your first agent in just a few minutes with [Rasa Copilot](https://hello.rasa.com/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta).

## New Beta Feature in 3.14

Rasa supports stateful execution of external agents via A2A protocol.  This feature is in a beta (experimental) stage and may change in future Rasa versions. We welcome your feedback on this feature.

External sub agents connected via the [A2A (Agent-to-Agent) protocol](https://a2a-protocol.org/latest/) operate as autonomous entities that can handle complex, multi-turn conversations independently. When invoked through a [`call` step](/content/docs/reference/primitives/flow-steps/#autonomous-steps/index.html) in your flows, these agents take control of the conversation and interact with users until their task is complete.

## A2A Protocol Connection

Rasa connects to external sub agents through the A2A (Agent-to-Agent) protocol, which provides a standardized way for different AI agents to communicate and collaborate. Here's how the connection process works:

### Connection Process

1. **Agent Card Resolution**: Rasa first retrieves the external sub agent's capabilities by loading its agent card, which can be either:
   - A local JSON file path
   - A remote URL pointing to the agent card
2. **Client Initialization**: Rasa creates an A2A client configured with:
   - Authentication credentials (if required)
   - Supported transport protocols (JSON-RPC, HTTP JSON, gRPC)
   - Streaming capabilities for real-time communication
   - Timeout and retry settings
3. **Health Check**: Before establishing the connection, Rasa performs a health check by sending a test message to verify that the external sub agent is responsive and properly configured.
4. **Message Exchange**: Once connected, Rasa communicates with the external sub agent by:
   - Sending user messages and conversation context
   - Receiving responses and structured data
   - Handling task status updates and completion signals

### Request Metadata on A2A Messages

Rasa forwards the entire `AgentInput.metadata` dictionary on each outgoing A2A user [`Message`](https://a2a-protocol.org/latest/specification/) as `Message.metadata`. That lets your remote agent read orchestration or backend-only data such as authentication tokens, tenant IDs, or feature flags without putting those values in the message parts that drive the language model.

Rasa also sets `Message.context_id` and `Message.task_id` from the metadata entries with keys `context_id` and `task_id`. Those keys are used for session continuity across turns; you can supply additional keys the same way.

For **per-conversation secrets** (tokens, customer credentials), configure `pre_call_hook` in the agent `configuration` section. Rasa invokes the hook before each outbound `message/send` or `message/stream` and merges the result into `Message.metadata` without writing secrets to slots or the tracker.

To attach other non-secret orchestration metadata, override `process_input` on a custom `A2AAgent` class and merge into `input.metadata` before returning the `AgentInput`. The default metadata already includes values the flow executor maintains.

### Call-time Credential Hooks (`pre_call_hook`)

Add `pre_call_hook` under `configuration` in the external sub agent's `config.yml`. The value is a dotted import path to a module-level sync or async function. Use `async def` when the hook performs I/O.

#### Example Configuration for Car Shopping Agent

```yaml
agent:
  name: car_shopping_agent
  protocol: A2A
  description: "Helps users shop for cars"

configuration:
  agent_card: ./sub_agents/car_shopping_agent/agent_card.json
  pre_call_hook: custom.call_time_credentials.resolve_a2a_shopping_meta
```

Rasa calls the hook as `hook(context)` before each outbound A2A message.

### Supported Transport Protocols

The A2A protocol supports multiple transport mechanisms:

- **JSON-RPC**: Lightweight remote procedure calls over HTTP
- **HTTP JSON**: Simple HTTP-based JSON messaging
- **gRPC**: High-performance RPC framework with streaming support

### Authentication

External sub agents can require authentication for secure communication. Rasa supports various authentication methods including API keys, OAuth 2.0, and pre-issued tokens, which are configured in the external sub agent's configuration file.

### Long-running Tasks with Push Notifications

Rasa can let long-running A2A tasks continue in the background when the external agent supports push notifications. This keeps the Rasa conversation responsive while the remote task is running. If a user sends another message before the external task finishes, Rasa triggers `pattern_external_agent_processing`.

### Intermediate Messages

External sub agents connected via the A2A protocol can send intermediate messages when task updates with status are received. Intermediate messages are immediately sent to the user and are tracked in conversation history.

### Background Task Cancellation

Long-running A2A operations run in the background and are cancelled automatically when the conversation reaches an inactive or terminal state.

### Best Practices

An A2A agent can respond with a `Task` or a `Message`. `Task`s should be used for long-running operations and `Message`s for immediate responses.

## Configuration

External sub agents extend the basic sub agent configuration with A2A protocol-specific settings. In addition to the required `agent` section, external sub agents support the following configuration options:

```yaml
# Basic agent information
agent:
  name: car_shopping_agent
  protocol: A2A
  description: "Helps users shop for cars"

# A2A-specific configuration
configuration:
  agent_card: ./sub_agents/car_shopping_agent/agent_card.json
  push_notification_url: https://rasa.example.com
  max_polling_time: 60
  polling_initial_delay: 0.5
  pre_call_hook: custom.call_time_credentials.resolve_a2a_shopping_meta
```

### Configuration Parameters

The configuration section in an external sub agent's `config.yml` must include the required field `agent_card`.  All other fields in this section are optional.
