Overview
- A distribution or client sends an A2A request into Aion Server.
- Aion exposes the request through
ctx.aion_runtime_context.inbox. - The agent yields events, optionally providing an explicit A2A outbox.
- Aion resolves those events into a final A2A
MessageorTask. - The caller or distribution delivers the response into the original context.
1. Inbound Messages
1.1 Agent Invocation
BothSendMessage and SendStreamingMessage use the same execution path: the agent’s
run_async() is always driven as an async event stream.
SendMessage(blocking=true) — collects all events and returns the finalTask.SendMessage(blocking=false) — returns after the first event, continues processing in background withstatus="working".SendStreamingMessage— yields events as they arrive and streams them to the client via SSE.
SendMessageRequest payload; only the response mode differs.
1.2 Part Type Mapping
Inbound A2A message parts are transformed into ADKContent as follows:
MIME type resolution order for file parts: explicit
mime_type attribute → guess from filename →
fallback to application/octet-stream.
Part conversion is additive, not authoritative. Messaging media keeps caption text, generated transcript text, a file
with MessageMediaPayload metadata, and normalized event data as separate ordered A2A parts. Inspect every part in
ctx.aion_runtime_context.inbox.message.parts when provenance matters, and associate file and transcript metadata by mediaId. A
file’s fileId is the stable Aion File Recording and fileVersionId is the exact immutable Recordable. Do not assume
that the first text part is the whole request.
If the message contains no usable parts, the plain text input from the request is used as a fallback.
1.3 Accessing Inbound Context — ctx.aion_runtime_context.inbox
When an inbound A2A Message arrives, Aion Server makes it available through
ctx.aion_runtime_context on the invocation context:
inbox contains:
1.4 Replying into the Inbound Context
Thread.from_context(...) wraps the inbound context, and thread.reply(...) builds its
routing from the inbound event, so the reply returns to the conversation the request arrived
from — the same DM, the same thread, the same shared conversation — without the agent
reconstructing that target. An agent that needs to send somewhere else passes an explicit
target to thread.post(...).
2. Outbound Messages
Valid responses to an A2ASendMessage call are a Message or a Task.
Aion Server constructs the response using the following precedence:
(1) SDK-managed response buffer (authoritative when populated)
The runtime maintains a request-scoped messaging buffer for the current turn. SDK helpers and ordinary ADK event content may populate that buffer, including partial stream output and final non-partial message content that is intended to become the durable reply. When this buffer is non-empty, it is the authoritative source for A2A response compilation.(2) a2a_outbox
Set a2a_outbox in event.actions.state_delta to provide an explicit A2A response. It must be an
A2AOutbox instance wrapping either a Message or a Task:
task_idandcontext_idare set to current values managed by Aion Server.- Metadata keys beginning with
aion:orhttps://docs.aion.toare reserved for the platform.aion:networkcarries routing and identity,aion:ephemeraldecides whether an event is persisted, and the extension URIs address extension payloads. Ask for that behaviour through the typed parameter that produces it —emit_message(..., ephemeral=True),routing=...— rather than by writing the key.
- If
a2a_outbox.messageis set → append to current Task history. - If
a2a_outbox.taskis set → treat as a patch to the server’s Task: server merges or extendshistoryandartifacts; providedmetadatamerges shallowly. Reserved keys are dropped from the patch — they reach neither the stored Task nor the wire.
(3) Framework-native fallback
If neither the SDK-managed response buffer nora2a_outbox is populated,
Aion Server falls back to framework-native output for the current turn:
- first, accumulated partial stream text
- then, if needed, the final non-partial agent-authored event content
- finally, deterministic final session/state inspection when the adapter exposes enough data to do so safely
If you need to return a comprehensive A2A response (e.g., data parts, rich metadata, multiple
artifacts), use a2a_outbox rather than relying on the streaming fallback.
When to Reach for a2a_outbox
An ordinary final ADK event is enough for a plain text reply. Reach for a2a_outbox when:
- you need structured parts rather than plain text
- you want to emit a provider-neutral card payload
- you need to override the default outbound target
- you want to return a task patch instead of a single message
3. Summary
- Read
ctx.aion_runtime_context.inboxto access the inbound A2A Task, Message, and metadata. - Prefer SDK helpers or normal ADK event content when you want to populate the shared runtime response buffer.
- Optionally set
a2a_outboxinevent.actions.state_deltaas anA2AOutboxinstance for full-fidelity A2A responses. - Yield partial events for real-time text streaming.