Assembly LineDocs

Agent-To-Agent (A2A)

Expose Assembly Line agents and discover remote peers through the standard A2A v1.0 protocol.

Edit

@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 publishes GET /.well-known/agent-card.json and the A2A JSON-RPC binding at POST /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.

On this page