A2AMock

Mock A2A (Agent-to-Agent) protocol server for testing multi-agent systems. Implements the A2A JSON-RPC protocol with agent card discovery, message routing, task management, and SSE streaming.

Quick Start

Standalone mode typescript
import { A2AMock } from "@copilotkit/aimock";

const a2a = new A2AMock();

a2a.registerAgent({
  name: "translator",
  description: "Translates text between languages",
  skills: [{ id: "translate", name: "Translate" }],
});

a2a.onMessage("translator", "translate", [{ text: "Translated text" }]);

const url = await a2a.start();
// Agent card at: ${url}/.well-known/agent-card.json
// JSON-RPC at: ${url}/

Mounted Mode

Mount A2AMock onto an LLMock server to share a single port with LLM mocking and other services:

Mount on LLMock typescript
import { LLMock, A2AMock } from "@copilotkit/aimock";

const llm = new LLMock({ port: 5555 });
const a2a = new A2AMock();

a2a.registerAgent({ name: "assistant" });
a2a.onMessage("assistant", "hello", [{ text: "Hi!" }]);

llm.mount("/a2a", a2a);
await llm.start();
// A2A available at http://127.0.0.1:5555/a2a

Subpath Import

A2AMock is also available via a dedicated subpath import for tree-shaking:

Subpath import typescript
import { A2AMock } from "@copilotkit/aimock/a2a";

Agent Registration

Register agents with skills and capabilities:

Register agents typescript
a2a.registerAgent({
  name: "researcher",
  description: "Research assistant",
  version: "1.0.0",
  skills: [
    { id: "search", name: "Web Search", tags: ["research"] },
    { id: "summarize", name: "Summarize" },
  ],
  capabilities: { streaming: true },
});

Message Patterns

Route messages to responses using string or RegExp patterns:

Message patterns typescript
// String substring match
a2a.onMessage("agent", "hello", [{ text: "Hi there!" }]);

// RegExp match
a2a.onMessage("agent", /^translate\s+(.+)/i, [{ text: "Translation result" }]);

// Task with artifacts
a2a.onTask("agent", "compute", [
  { parts: [{ text: "42" }], name: "result" },
]);

Streaming Tasks

Simulate streaming responses with SSE events:

Streaming typescript
a2a.onStreamingTask("agent", "long-task", [
  { type: "status", state: "TASK_STATE_WORKING" },
  { type: "artifact", parts: [{ text: "partial result" }], name: "output" },
  { type: "artifact", parts: [{ text: "final result" }], lastChunk: true, name: "output" },
], 50); // 50ms delay between events

Config File

A2AMock can be configured via the aimock JSON config file:

aimock.json json
{
  "a2a": {
    "path": "/a2a",
    "agents": [
      {
        "name": "assistant",
        "description": "A helpful assistant",
        "skills": [{ "id": "chat", "name": "Chat" }],
        "messages": [
          { "pattern": "hello", "parts": [{ "text": "Hi there!" }] }
        ]
      }
    ]
  }
}

JSON-RPC Methods

Method Description
SendMessage Send a message, get a synchronous response
SendStreamingMessage Send a message, get an SSE stream of events
GetTask Retrieve a task by ID
ListTasks List tasks, optionally filtered by contextId
CancelTask Cancel a non-terminal task

Agent Card

The agent card is served at GET /.well-known/agent-card.json and includes all registered agents' skills and capabilities. The A2A-Version: 1.0 header is included on all responses.

Inspection

Inspection API typescript
a2a.health();  // { status: "ok", agents: 2, tasks: 5 }
a2a.reset();   // Clears all agents and tasks