Agent-To-Agent (A2A)
Expose Assembly Line agents and discover remote peers through the standard A2A v1.0 protocol.
@assemblyline-agents/a2a implements the A2A v1.0 protocol with the official
@a2a-js/sdk. It is not the runtime's direct /runs API and it is not a
private webhook envelope.
The integration has two deliberately separate sides:
- A receiving agent uses
defineA2AChannel(). It publishesGET /.well-known/agent-card.jsonand the A2A JSON-RPC binding atPOST /a2a. - A calling agent uses
defineA2AConnection(). The runtime fetches the allowlisted Agent Card, validates its advertised interface origins, and turns its skills into normal deferred connection tools.
Local filesystem subagent composition remains separate. A subagent is a compiled child inside one Assembly Line deployment; A2A is for independently deployed agents with their own identity, policy, state, and lifecycle.
Expose An Agent
Select and configure the built-in A2A channel profile in agent.md:
channels:
a2a:
name: Reviewer
description: Independent review of exact committed change sets.
version: 1.0.0
skills:
- id: code_review
name: Code review
description: Review a baseline, diff, requirements, and test evidence.
tags: [review, verification]
inputModes: [text/plain, application/json]
outputModes: [application/json]Set:
A2A_PUBLIC_URL=https://reviewer.example.com
A2A_PEER_TOKENS={"coder":"one-long-random-peer-token"}A2A_PEER_TOKENS is a JSON object from stable peer id to opaque bearer token.
Use a different credential per calling agent. The Node host treats the A2A
routes as provider ingress and lets the channel authenticate them; callers do
not receive or reuse ASSEMBLY_LINE_ADMIN_TOKEN.
The helper advertises JSON-RPC v1.0, text and JSON parts, no push
notifications, and no streaming. It supports blocking and immediate-return
SendMessage, task get/list, follow-up messages, and cancellation. A2A task
state is backed by durable Assembly Line runs rather than an in-memory task
map.
Only explicit skills are public. Local tools, connections, instructions, and
subagents never appear in the Agent Card automatically.
Connect To A Peer
// plugins/reviewer/ai.assemblyline/reviewer.ts
import { defineA2AConnection } from "@assemblyline-agents/a2a";
export default defineA2AConnection({
agentCardUrl: "https://reviewer.example.com/.well-known/agent-card.json",
tokenEnv: "REVIEWER_A2A_TOKEN",
skills: { allow: ["code_review"] },
access: { read: true, write: false },
subject: "environment"
});Declare that module as the reviewer connection in the local plugin's
ai.assemblyline entry. The plugin is active by presence and records the peer
authority in plugins.lock; no root connection file or agent.md plugin entry
is required.
At runtime the agent learns what peers are available from its compiled
connection set. connection_search fetches each Agent Card lazily and returns
the advertised skill descriptions. A skill id becomes the qualified tool
<connection>__<sanitized-skill-id>; the standard get_task and list_tasks
tools are also exposed. cancel_task is available only when that connection
explicitly enables its write authority.
Agent Card URLs are static application configuration, not model-selected URLs.
By default every advertised interface must have the same origin as the card.
Use allowedOrigins only when a known peer intentionally serves its card and
protocol binding from different origins.
Authored Policy Wrappers
Some handoffs need local policy before delegation. For example, a coding agent
may need to prepare a committed diff, bind approval to its hash, and enforce a
two-review limit. Keep that logic in an authored tool, then call
createA2AClient() from this package. That preserves the standard discovery,
authentication, message, and task wire contract without pretending the domain
policy itself is a generic A2A feature.
Discovery Scope
Assembly Line currently uses direct, allowlisted Agent Card configuration.
This makes the peer set auditable in the plugin entry, plugins.lock, and the
compiled manifest. A future organization registry can resolve those card URLs, but it
should remain a trusted control-plane source; models should not discover and
contact arbitrary internet agents by URL.