> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aion.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Welcome Message

> Request an agent-generated opening message in an ordinary A2A conversation.

**Metadata**

| Field | Value |
| - | - |
| Canonical URI | `https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0` |
| Issuer | `aion` |
| Version | `1.0.0` |
| Activation | This extension will only activate when specified. |
| Related Extensions | [Distribution][distribution], [Distribution/Messaging][messaging] |

[distribution]: /a2a/extensions/aion/distribution/1.0.0

[messaging]: /a2a/extensions/aion/distribution/messaging/1.0.0

## Overview

Welcome Message requests an opening response from an agent. The request and response belong to the ordinary
conversation and its history. Fetching an Agent Card, opening existing history, or reconnecting does not invoke it.

The agent decides how to generate the welcome, including which tools or capabilities to use. Personalization and
provider context continue to use the [Distribution extension](/a2a/extensions/aion/distribution/1.0.0).

## Agent Card Declaration

Receivers implementing this contract advertise optional support:

```json theme={null}
{
  "capabilities": {
    "extensions": [
      {
        "uri": "https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0",
        "description": "Generate an opening message for a new conversation.",
        "required": false
      }
    ]
  }
}
```

Aion advertises this extension for A2A, Aion Chat, Slack, and Telegram Bot distribution routes only when a middleware
or terminal behavior on that route implements it. A distribution declaration alone does not establish support.
Slack and Telegram retain internal capability metadata without becoming public A2A endpoints.

Clients use the card for their selected route. GraphQL chat clients resolve `a2aAgentCardUrl` with the same `target`
and `principal` used for messaging. An identity's preferred card URL may represent a different distribution.

Voice does not advertise or dispatch this extension. It continues speaking its separately configured distribution
`welcomeMessage` through the voice session's existing playback path.

## Activation

Producers send both the request-scoped `A2A-Extensions` header and the URI in `message.extensions`:

```http theme={null}
A2A-Extensions: https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0
```

For GraphQL, put the URI in `serviceParameters.extensions` and in `message.extensions`.
Receivers recognize either explicit activation signal. A data part or metadata key alone does not activate welcome.
Do not retain this activation on subsequent ordinary user requests.

## Payloads

### WelcomeRequestPayload

Schema URI:
`https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0#WelcomeRequestPayload`

An activated welcome request contains exactly one welcome-owned data part and no nonblank text part. Other
extension-owned parts, including provider events, may accompany it. There are no personalization fields.

Placement summary:

* `WelcomeURI`: `https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0`
* Payload location: `message.parts[i].data`
* Schema location: `message.parts[i].metadata[WelcomeURI].schema`
* Activation locations: `A2A-Extensions` and `message.extensions`

For JSON-RPC, `message` is inside `params`; for HTTP+JSON, it is in the request body. Do not place this payload in
request-level `metadata` or `message.metadata`. Both `SendMessage` and `SendStreamingMessage` use this shape.

#### Payload Shape

```json theme={null}
{
  "type": "welcome-request"
}
```

#### Fields

| Field | Type | Required | Description |
| - | - | - | - |
| `type` | `String` | required | Must be `welcome-request`; requests an opening conversation message. |

The enclosing part's `metadata[WelcomeURI].schema` must equal the Schema URI above. The schema reference identifies
the part's extension ownership; `data.type` alone is insufficient. Neither field activates the extension by itself.

## Processing Rules

1. If the request contains nonblank user text, answer that text normally. This takes precedence even if welcome
   metadata is malformed or welcome support is disabled. Do not mark that ordinary response as a welcome.
2. Otherwise, an explicitly activated request must have the valid schema-tagged data part and an enabled receiver.
   Reject invalid or disabled welcome requests through the normal invalid-parameters error path before agent execution.
3. Generate the welcome through the agent implementation. Keep the ordinary context and response persistence.
4. Complete a successful welcome task. It must not remain waiting for user input; the user's next message continues
   the conversation through the normal task lifecycle.
5. Explicitly mark every response message intended as welcome output, as shown below.

Activation acknowledgment and message provenance are distinct. An `A2A-Extensions` response header can acknowledge
activation, but does not identify a particular message as intentional welcome output. Generic response processing
must not add this URI to every message simply because the request activated it.

### Response Message

Return an ordinary Message or completed Task. Each intentional welcome Message carries the URI in its own
`extensions`, including messages within a Task's history or status. No separate response payload is required.
Preserve these message annotations through adapters, delivery, history, and replay. Do not relabel earlier messages.

## Example: Welcome SendMessage

This A2A 1.0 JSON-RPC request uses a client-assigned context before any request is dispatched. The URL and token are
placeholders; apply the receiver's normal authentication in addition to extension activation.

```http theme={null}
POST /a2a HTTP/1.1
Host: agent.example.com
Content-Type: application/json
Authorization: Bearer <aion-token>
A2A-Extensions: https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0
```

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": "welcome-1",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "welcome-request-001",
      "contextId": "chat-context-001",
      "role": "ROLE_USER",
      "extensions": [
        "https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0"
      ],
      "parts": [
        {
          "data": {
            "type": "welcome-request"
          },
          "metadata": {
            "https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0": {
              "schema": "https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0#WelcomeRequestPayload"
            }
          }
        }
      ]
    }
  }
}
```

In the 0.3 representation, use `role: "user"`, `kind: "message"`, and `kind: "data"` on the corresponding objects.
The extension URI, schema reference, and context ID stay the same. Both unary and streaming receivers can handle
welcome intent; Aion's chat clients initiate welcomes with unary `SendMessage`.

### Response Example

The response uses the normal A2A result envelope. Its Message carries the welcome annotation:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": "welcome-1",
  "result": {
    "message": {
      "messageId": "welcome-response-001",
      "contextId": "chat-context-001",
      "role": "ROLE_AGENT",
      "extensions": [
        "https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0"
      ],
      "parts": [
        {
          "text": "Hello! How can I help?"
        }
      ]
    }
  }
}
```

For 0.3, use `role: "agent"`, `kind: "message"`, and `kind: "text"`.

## Agent Implementations

### Control Plane Agents

The following control plane agents implement this extension:

* **Prompt Agent** uses the configured content or instructions alongside its ordinary system prompt to generate
  the welcome response.
* **Hello World** returns the configured text directly for protocol and UI testing. Ordinary text requests keep
  its configured echo behavior.

Configure `WelcomeMessage` on either agent:

| Property | Value |
| - | - |
| Key | `WelcomeMessage` |
| Type | `String` |
| Required | No; nullable, with no default. |
| Maximum Length | 5,000 characters. |
| Description | Content or instructions for the agent's opening message when a new conversation starts. |

A nonblank value enables support and advertises the extension. Missing or blank values disable support. Both
implementations trim surrounding whitespace and preserve Markdown inside the value.

In both cases, the response is part of the conversation, not a static client banner.

### Python SDK

Opt in through `aion.yaml`:

```yaml theme={null}
enabled_extensions:
  - https://docs.aion.to/a2a/extensions/aion/welcome-message/1.0.0
```

The runtime validates the payload and exposes `WelcomeRequestPayload` through `context.extensions.get(uri)`.
The implementer decides how to respond and completes through the existing task API. The SDK does not generate a
welcome automatically. Use `context.extensions.is_active(uri)` to recognize validated welcome intent; actual user
text follows ordinary handling. Set the URI explicitly on the response Message's `extensions` before emitting it.

## Client And Provider Triggers

| Surface | Trigger and behavior |
| - | - |
| Aion Chat React | Explicit new conversation creation checks the selected route card and sends one unary welcome. |
| Python SDK terminal chat | `/clear` creates a context and sends one unary welcome if the connected card supports it. |
| Slack | `im_created` for a new DM requests a welcome when the current downstream route supports it. |
| Telegram Bot | Every distinct private, parameterless `/start` requests a welcome on a supporting route. |

Chat clients allocate the context before sending. An immediate user message uses that same context while the welcome
is pending. Ordinary chat remains available; welcome and user responses may arrive out of order. A late welcome
stays in its original conversation and does not change the foreground request's task state.

The synthetic, schema-tagged request is hidden from the chat transcript, while protocol inspection and stored
history retain it. Real user text remains visible. There is no separate welcome-disable setting and no client retry.
Restoration, reconnect, and capability refresh do not send another welcome.

### Slack

Only `im_created` triggers this feature. `im_open`, `app_home_opened`, and `assistant_thread_started` do not.
The event uses the existing authenticated, deduplicated event ingress and normal DM response delivery. No separate
initialization marker is stored, and no source-message timestamp is fabricated for the channel-creation event.

The generated app manifest includes `im_created`; its `im:read` scope is already part of Aion's baseline.
For an existing app, add `im_created` to its bot event subscriptions or apply the updated manifest before expecting
welcomes. Projection checks detect the outdated subscription; automatic manifest updates are not performed by the
current managed-app reconciler. Verify delivery in the installed workspace during rollout.

See Slack's [im\_created reference](https://docs.slack.dev/reference/events/im_created/).

### Telegram Bot

Bare `/start`, correctly bot-addressed `/start@BotUsername`, and trailing whitespace are accepted. Commands with
parameters, group commands, and unsupported downstream routes keep their ordinary command handling. Commands addressed
to another bot keep the existing rejection behavior.

Repeated distinct starts reuse the existing chat context; they do not reset it. Provider redelivery is handled by
existing update deduplication. Merely opening or deleting a chat does not trigger this feature.
See Telegram's [bot commands](https://core.telegram.org/bots/features#commands).
