Skip to main content

Bridge native-chat conversations to an A2A agent

This guide wires the dashboard’s native chat widget to an A2A agent that runs outside Orbit. The agent receives a push event when a customer sends a message, reads the conversation, drafts a response with an LLM, and writes the reply back to the same native-chat thread. For the console side of the widget, see the Native Chat channel configuration guide. For the federation handshake, see Set up A2A federation between tenants and A2A push notifications.

1. When to use native chat vs. A2A

Both surfaces can host an AI agent, but they differ in who owns the runtime. You can also combine them: the widget captures the conversation in Orbit, and an A2A agent subscribed to push events handles the reply logic remotely.

2. Register the A2A agent and subscribe to pushes

2.1 Register the agent

Follow Set up A2A federation between tenants to register your external agent as a peer. The short version:
  1. In Orbit, set your A2A agent’s discovery mode to public or tenant.
  2. Copy its AgentCard share URL from Agents → → A2A → Copy share URL.
  3. On your worker side, register that URL as a peer.

2.2 Subscribe to push events

When your worker sends a task to the Orbit agent, attach a pushNotification block so every lifecycle update is POSTed to your worker. See A2A push notifications for the full contract.
Orbit POSTs a JSON-RPC envelope to your callback on every task-state change:
Verify the signature before acting on the payload. Orbit signs with X-Orbit-A2A-Push-Signature (Ed25519 JWS) when a signing key is provisioned, and falls back to X-A2A-Signature (HMAC-SHA256) otherwise.

3. Customer-side worker: receive, draft, and reply

3.1 Read the conversation

The push payload does not include the full conversation. Use the task id or the metadata you passed at send time to look up the source conversation_id, then call the Orbit API to fetch recent messages.
Keep the conversation_id from the original send. You can thread it through the task metadata field:

3.2 Send the reply back over native chat

Post the drafted reply to the conversation reply endpoint. The channel override must be web_chat (the API value for the dashboard’s native-chat widget).
The reply endpoint returns 202 and the message is delivered to the visitor’s widget on the next poll. The web_chat channel is loopback delivery: persistence in the messages table is the delivery event, so there is no carrier DLR.

4. Failure handling

4.1 Delivery retries

A2A push delivery is best-effort and does not retry. Your worker must tolerate missed callbacks: poll GET /api/v1/agents/{agentId}/a2a/tasks/{taskId} after a silence window to catch up. For the native-chat reply itself, handle these synchronous errors:

4.2 Dedupe on event id

A2A push callbacks may arrive more than once during network blips. Store the taskId/status pair you have already processed and return 200 early for duplicates. Do not replay the native-chat reply for the same task transition.

4.3 Replay from the DLQ

If your worker is down when a push arrives, the task state is still recorded on the Orbit side. When your worker recovers:
  1. List recent tasks: GET /api/v1/agents/{agentId}/a2a/tasks.
  2. Filter for tasks your worker owns and has not yet processed.
  3. Re-fetch the conversation, draft the reply, and call POST /conversations/{id}/reply with channel: "web_chat".
There is no separate A2A DLQ to drain — the task ledger is the source of truth.

5. E2E code sample: minimal Node worker

This sample receives an A2A push, reads the conversation, drafts a response with an LLM, and writes it back to native chat. It skips signature verification for brevity; production code must verify X-Orbit-A2A-Push-Signature or X-A2A-Signature.
Key points in the sample:
  • The push callback is verified before use in production.
  • processed dedupes on taskId so a retry does not double-reply.
  • The reply is sent with channel: "web_chat", which is the API value for the dashboard native-chat channel.
  • If the LLM or reply call fails, the worker returns a non-2xx status and relies on polling the task ledger on recovery.

6. Dashboard wiring

In the dashboard:
  1. Enable native chat under Settings → Channels → Native Chat. See Native Chat channel configuration.
  2. Create an AI agent or use an existing one.
  3. Open Agents → → A2A, set discovery to public or tenant, and copy the share URL.
  4. Register the share URL as a peer from your worker.
  5. Send tasks from your worker with pushNotification.url pointing at your callback endpoint.

7. Security and compliance notes

  • Sign and verify A2A callbacks. An unverified push endpoint is a write primitive into your agent.
  • Keep conversation_id scoped to the tenant that owns it. Your worker should not accept a conversation id from an unauthenticated source.
  • The native-chat widget is an owned channel: replies are loopback-delivered through Orbit, so no third-party carrier handles the egress. This is the web_chat channel in the API.
  • Tenant-owned controls govern AI disclosure, quiet hours, and data retention. Configure them in the dashboard; your worker should not attempt to bypass them.

See also