A2A External Gateway¶
The A2A gateway is an optional external interface that enables SynthOrg agents to
federate with agents in other A2A-compatible systems. It is disabled by default
(a2a.enabled: false). Internal communication is unchanged; the MessageBus remains the
sole transport for intra-organisation messages.
See also: Communication (transport), Coordination (loop prevention referenced below), Event Stream (SSE hub).
Architecture¶
The gateway sits at the organisation boundary and handles two directions:
- Inbound (external -> internal)
- External A2A clients discover SynthOrg agents via Agent Cards, then call one of the
gateway's five JSON-RPC methods:
message/send(create a task),tasks/get,tasks/cancel,skills/query(find learned peers advertising a skill), andskills/negotiate(confirm a named peer still serves a skill).tasks/get/tasks/cancelenforce per-peer ownership (a task is stamped with its originating peer; a cross-peer access 404s). The gateway translates A2A requests into internal MessageBus messages and applies DelegationGuard + A2A-specific security checks before admission. - Outbound (internal -> external)
- SynthOrg agents can delegate tasks to external A2A agents. The A2A client discovers
external agents via their Agent Card URLs (pinning the SSRF-validated IP to close the
DNS-rebind window), creates tasks, and maps external task states back to internal
states.
PeerDiscoveryClientfetches and registers remote Agent Cards (streamed and byte-bounded) into thePeerRegistrythat the inbound skill methods resolve against.
Agent Card Projection¶
When the gateway is enabled, SynthOrg serves an Agent Card at
/.well-known/agent-card.json per the A2A specification. The card is a safe projection
of AgentIdentity; only fields relevant to external capability discovery are exposed:
| AgentIdentity Field | Agent Card Field | Included | Rationale |
|---|---|---|---|
name |
name |
Yes | Public identity |
role |
description (partial) |
Yes | Capability context |
skills (SkillSet) |
skills (AgentSkill[]) |
Yes | Lossless mapping via Skill model |
department |
metadata | Optional | Organisational context |
personality |
- | No | Internal behavioural tuning |
level (seniority) |
- | No | Internal authority hierarchy |
authority |
- | No | Internal delegation rules |
model (ModelConfig) |
- | No | Internal infrastructure |
tools |
- | No | Security-sensitive capability list |
budget_limit |
- | No | Internal financial data |
The Skill model is A2A AgentSkill-aligned on the shared
capability fields (id, name, description, tags, input_modes,
output_modes). Those fields project losslessly in both directions. The
SynthOrg-only proficiency field has no A2A counterpart, so:
- SynthOrg -> A2A:
proficiencyis dropped from the projectedAgentSkill. - A2A -> SynthOrg: imported
AgentSkillobjects populateproficiencyfrom the internal default (1.0) since the wire format does not carry it.
Concept Mapping¶
SynthOrg and A2A use different terminology for overlapping concepts. This table provides a bidirectional reference for the gateway translation layer.
Task State Mapping¶
| SynthOrg State | A2A State | Direction | Notes |
|---|---|---|---|
CREATED |
submitted |
Bidirectional | Initial task creation |
ASSIGNED |
working |
SynthOrg -> A2A | Agent has accepted the task |
IN_PROGRESS |
working |
Bidirectional | Active execution |
IN_REVIEW |
working |
SynthOrg -> A2A | Internal review stage, opaque externally |
BLOCKED |
input-required |
Bidirectional | Waiting for external input |
AUTH_REQUIRED |
auth-required |
SynthOrg -> A2A | Mid-execution approval park; returns to ASSIGNED on approval, CANCELLED on timeout |
SUSPENDED |
input-required |
SynthOrg -> A2A | Checkpointed (graceful-shutdown) tasks; resume from checkpoint returns to ASSIGNED |
INTERRUPTED |
failed |
SynthOrg -> A2A | Interrupted execution; externally indistinguishable from failure |
COMPLETED |
completed |
Bidirectional | Successful completion |
FAILED |
failed |
Bidirectional | Unrecoverable failure |
CANCELLED |
canceled |
Bidirectional | Client-initiated cancellation |
REJECTED |
rejected |
Bidirectional | Task refused by agent or guard |
Gate verdict mapping (not a task state):
| SynthOrg Verdict | A2A State | Direction | Notes |
|---|---|---|---|
Verdict ESCALATED |
auth-required |
SynthOrg -> A2A | The ESCALATED verdict is what parks the task in the AUTH_REQUIRED state above; both surface to A2A as auth-required (one is the task state, this row is the verdict that produces it). External client must provide additional credentials |
Identity Mapping¶
| SynthOrg | A2A | Direction | Notes |
|---|---|---|---|
AgentIdentity |
AgentCard |
SynthOrg -> A2A | One-way projection (safe subset) |
Skill |
AgentSkill |
Bidirectional | Lossless on shared capability fields; internal-only proficiency is dropped outbound and defaulted to 1.0 on inbound |
SkillSet.primary |
AgentCard.skills (tagged primary) |
SynthOrg -> A2A | Primary/secondary distinction preserved via tags |
SkillSet.secondary |
AgentCard.skills (tagged secondary) |
SynthOrg -> A2A | Primary/secondary distinction preserved via tags |
Message and Task Lifecycle Mapping¶
| SynthOrg | A2A | Notes |
|---|---|---|
Message (internal) |
Message + Part[] (A2A) |
Internal message content maps to A2A text parts |
DelegationRequest |
message/send (JSON-RPC) |
Task creation |
DelegationResult |
tasks/get response |
Task completion/status |
TaskExecution state |
Task object + status |
Ongoing task tracking |
| MessageBus channels | - | No A2A equivalent; internal routing only |
| Meeting protocols | - | No A2A equivalent; internal coordination only |
SSE Streaming¶
External task update delivery uses Server-Sent Events per the A2A specification. The dashboard also uses SSE for observability and the HITL interrupt/resume protocol (see Event Stream and HITL Surface).
| Consumer | Transport | Protocol | Use Case |
|---|---|---|---|
| Web dashboard | SSE | AG-UI projected events | Observability + HITL interrupt/resume |
| Web dashboard | WebSocket | Custom events | Bidirectional UI actions (chat, settings) |
| External A2A client | SSE | message/stream |
Task progress streaming |
The EventStreamHub is the single event source for all SSE consumers (hub-driven
architecture). Both the AG-UI dashboard and the A2A gateway subscribe
to the hub and apply per-consumer projection layers. The gateway applies an A2A
projection that filters to task-related events for explicitly subscribed tasks and
formats payloads per the A2A specification; no internal channel traffic leaks to
external consumers.
A2A Client (Outbound)¶
SynthOrg agents can delegate tasks to external A2A agents through the outbound client:
- Discovery: Fetch the external agent's Agent Card from its well-known URL
- Skill import: Deserialise
AgentSkill[]into internalSkillmodel (lossless) - Task creation: Send
message/sendJSON-RPC request with auth credentials - Monitoring: Subscribe to task updates via SSE or poll via
tasks/get - State mapping: Map external A2A task states back to internal states (see table above)
The outbound client authenticates using the a2a.auth.outbound configuration (see
A2A Security). Outbound delegations pass through the
DelegationGuard for loop-prevention checks (ancestry, depth,
deduplication, rate limiting, circuit breaker) before dispatch.