[Skip to main content](/content/docs/reference/architecture/rasa-as-a2a-agent/#__docusaurus_skipToContent_fallback/index.html)

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).

On this page

When `a2a_server` is configured in `endpoints.yml`, Rasa registers A2A JSON-RPC routes on the same Sanic port as REST and channel webhooks.
An external orchestrator discovers capabilities via `AgentCard`, sends user turns, and receives task lifecycle updates mapped from Rasa's dialogue state.

This page describes the **sub-agent (server) architecture**. For Rasa as an orchestrator that calls external A2A agents, see [Integrating External Agents via A2A](/content/docs/pro/build/integrating-external-agents/index.html).

For configuration and operations, see [A2A Server](/content/docs/reference/integrations/a2a-server/index.html) and [Exposing Rasa as an A2A Sub-Agent](/content/docs/pro/build/exposing-rasa-as-a2a-sub-agent/index.html).

## Deployment topology [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#deployment-topology "Direct link to Deployment topology"/index.html)

Shaded regions show ownership: the orchestrator (A2A client) discovers skills, sends and receives turns over JSON-RPC, and optionally hosts a push callback URL. Rasa (A2A server) exposes public endpoints, runs flows, and POSTs task updates when push notifications are enabled (dashed arrow).

The orchestrator owns end-user routing and multi-agent coordination.
Rasa owns flow execution, slot collection, conversation repair, and NLG within its advertised skills.

## The governed agent contract [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#the-governed-agent-contract "Direct link to The governed agent contract"/index.html)

Rasa exposes a **bounded contract** to orchestrators. Internal dialogue machinery stays private.

### What Rasa exposes [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#what-rasa-exposes "Direct link to What Rasa exposes"/index.html)

| Surface | Description |
| --- | --- |
| **AgentCard** | Public capability advertisement. User flows become `AgentSkill` entries; pattern flows are included when `include_conversation_repair: true`. |
| **A2A task states** | `working`, `input_required`, `completed`, `failed`, `canceled`, `rejected`, `auth_required` — mapped from dialogue stack and tracker state after each turn. |
| **Structured `DataPart`** | Terminal and interactive-terminal payloads with `state`, `active_flow`, current `slots`, persisted slot values, and error/cancel metadata when applicable. |
| **User-visible `TextPart`** | Bot utterance in `status.message` so clients that only read text still receive NLG. |
| **`message/stream` artifacts** | `working` status updates and token/chunk deltas during streaming custom actions. |
| **Session continuity** | One Rasa conversation per orchestrator `contextId`; contexts stay resumable across turns and after inactivity (with `start_session_after_expiry: false`). |
| **Orchestrator auth** | Optional bearer JWT on JSON-RPC and AgentCard routes (validates the orchestrator, not the end user). |

### What Rasa keeps internal [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#what-rasa-keeps-internal "Direct link to What Rasa keeps internal"/index.html)

| Internal | Why it stays private |
| --- | --- |
| LLM prompts and command-generator internals | Implementation detail; orchestrator sends user text, receives commands' effects as task state. |
| Dialogue stack frames (`pattern_*`, flow stack) | Mapped to A2A states and summarized slots — raw stack is not exported. |
| Full tracker event history | Available only via separate REST/tracker APIs if configured; not part of the A2A task contract. |
| Channel connectors and REST webhook surface | Parallel ingress paths; orchestrator uses A2A JSON-RPC only. |
| Sub-agent orchestration (`sub_agents/`) | Separate concern; not part of the sub-agent server contract. |

End-user identity and backend context belong in A2A `message.metadata`, `DataPart` slot pre-seeding, or orchestrator-side session management — not in the sub-agent JWT.

## Context and task mapping [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#context-and-task-mapping "Direct link to Context and task mapping"/index.html)

Blue: identifiers the orchestrator supplies on each A2A message. Purple: how Rasa maps and tracks them server-side.

| A2A concept | Rasa mapping | Behaviour |
| --- | --- | --- |
| `contextId` | `sender_id` | One persistent Rasa conversation per orchestrator context. Slots and flow progress carry over across turns. |
| `messageId` | Dedup key `(contextId, messageId)` | Retries replay the cached terminal task. Concurrent duplicates while in flight return HTTP 409. |
| `task_id` | New per orchestrator message | Each turn is a distinct A2A task. A `completed` task on a context does not block the next message — a new task starts. |
| `input_required` | Context reservation | The context stays reserved until the orchestrator sends a follow-up or calls `tasks/cancel`. |

`ConversationInactive` and tracker inactivity do **not** release an `input_required` context.
With `start_session_after_expiry: false` (required for A2A), the next message on the same `contextId` resumes the flow without running `action_session_start`.

## Task state lifecycle [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#task-state-lifecycle "Direct link to Task state lifecycle"/index.html)

After each message is processed, `TaskStateMapper` derives the A2A task state from the dialogue stack and latest action.
Evaluation follows this priority order:

1. `auth_required` — orchestrator bearer token missing or invalid
2. `rejected` — `CannotHandlePatternFlowStackFrame` active (outside jurisdiction)
3. `failed` — `InternalErrorPatternFlowStackFrame` active
4. `canceled` — `CancelPatternFlowStackFrame` active or orchestrator `tasks/cancel`
5. `completed` — user-facing flow emitted `FlowCompleted` this turn; no user flows remain on the stack; bot waits for user input (even when `pattern_completed` is active at `action_listen`)
6. `input_required` — `CompletedPatternFlowStackFrame` active; no user flows on stack; `include_conversation_repair` is `true`; bot waits for user input; no user flow completed this turn
7. `completed` — `CompletedPatternFlowStackFrame` active and no user flows on stack (including when conversation repair is disabled)
8. `input_required` — last action waits for user input (collect step, greet, etc.)
9. `working` — otherwise (processing or mid-turn streaming)

### State reference [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#state-reference "Direct link to State reference"/index.html)

| State | Meaning for orchestrator | Typical next action |
| --- | --- | --- |
| `working` | Turn in progress; `message/stream` may emit intermediate updates | Wait for terminal state |
| `input_required` | Flow needs more user input; `DataPart` includes `active_flow` and current `slots` | Show `TextPart` to user; send follow-up on same `contextId` |
| `completed` | Business flow finished; `DataPart` includes `persisted_slots` | Read structured output; may start a new task on same `contextId` |
| `rejected` | Request outside advertised skills (`reason` in `DataPart`) | Route to a different agent or handle in orchestrator |
| `failed` | Internal error (`error_type`, `error_info` in `DataPart`) | Retry, escalate, or fall back |
| `canceled` | Orchestrator or timeout cancelled the task | Clean up orchestrator-side state |
| `auth_required` | Missing or invalid orchestrator JWT | Refresh token and retry |

When `include_conversation_repair: false`, conversation-repair stack frames map to `completed` instead of `input_required`.

## Message processing path [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#message-processing-path "Direct link to Message processing path"/index.html)

Blue groups: orchestrator-side request, response, and optional push callback. Purple group: Rasa server processing from JSON-RPC ingress through CALM to task status and push transport.

On each turn:

1. Optional bearer JWT is validated (orchestrator auth).
2. Orchestrator slot pre-seeding is applied as `SetSlotCommand`s before dialogue processing.
3. Rasa executes flows via the standard CALM pipeline.
4. `A2AOutputChannel` maps tracker state to A2A task updates, including structured `DataPart` and `TextPart`.
5. Optional push notification POSTs fire on state transitions when enabled.

## Scaling constraints (in v3.17) [​](/content/docs/reference/architecture/rasa-as-a2a-agent/\#scaling-constraints-in-v317 "Direct link to Scaling constraints (in v3.17)")

Until persistent A2A task and message stores ship:

- **`SANIC_WORKERS=1`** per replica — idempotency, cancel, and `max_contexts` are per-worker.
- **Horizontal scaling** — add replicas with load balancer sticky routing keyed on `contextId` so the same orchestrator context hits the same pod. A2A task caches, deduplication, in-flight queues, and push config are in-memory per replica until persistent stores ship. Derive the routing key from the JSON body `contextId`, the `X-A2A-Context-Id` header, or an `a2a-context-id` cookie set by the ingress. See [Multi-replica load balancing](/content/docs/reference/integrations/a2a-server/#multi-replica-load-balancing/index.html).
- **Hot model reload** — `PUT /model` does not refresh the AgentCard or re-wire the A2A executor; restart after model deploys that change advertised skills.

Not tested for 3.17

Running Rasa as an A2A sub-agent **while also invoking external sub-agents** (`sub_agents/` with `protocol: a2a`) is **not tested for v3.17**.

- [Deployment topology](/content/docs/reference/architecture/rasa-as-a2a-agent/#deployment-topology/index.html)
- [The governed agent contract](/content/docs/reference/architecture/rasa-as-a2a-agent/#the-governed-agent-contract/index.html)
  - [What Rasa exposes](/content/docs/reference/architecture/rasa-as-a2a-agent/#what-rasa-exposes/index.html)
  - [What Rasa keeps internal](/content/docs/reference/architecture/rasa-as-a2a-agent/#what-rasa-keeps-internal/index.html)
- [Context and task mapping](/content/docs/reference/architecture/rasa-as-a2a-agent/#context-and-task-mapping/index.html)
- [Task state lifecycle](/content/docs/reference/architecture/rasa-as-a2a-agent/#task-state-lifecycle/index.html)
  - [State reference](/content/docs/reference/architecture/rasa-as-a2a-agent/#state-reference/index.html)
- [Message processing path](/content/docs/reference/architecture/rasa-as-a2a-agent/#message-processing-path/index.html)
- [Scaling constraints (in v3.17)](/content/docs/reference/architecture/rasa-as-a2a-agent/#scaling-constraints-in-v317/index.html)

Ask AI

## 🍪 Cookie settings

We use cookies to keep things running smoothly and improve your experience.

Customize settings

Accept allReject all
