PeerAgent

A full-duplex peer that can both host an A2A agent (inbound) and send trust-verified requests to other agents (outbound). PeerAgent composes AletheiaAgent (server) + AletheiaA2A (client) into a single unified interface.

Import

import { PeerAgent } from "@a2aletheia/a2a";

Constructor

new PeerAgent(config: PeerAgentConfig)

Creates a new PeerAgent instance with the specified configuration.

PeerAgentConfig

Property Type Required Description
Shared      
registryUrl string No URL of the Aletheia registry for discovery
Server-side (Inbound)      
name string Yes Agent name displayed in registry
version string Yes Agent version (semver)
url string Yes Base URL where agent is hosted
description string Yes Agent description for registry
skills AgentSkill[] Yes List of capabilities this agent provides
defaultInputModes string[] No Default input content types
defaultOutputModes string[] No Default output content types
capabilities Partial<AgentCapabilities> No Agent capabilities (streaming, push notifications, etc.)
iconUrl string No URL to agent icon
documentationUrl string No URL to agent documentation
provider { organization: string; url: string } No Provider information
aletheiaExtensions AletheiaExtensions No Aletheia-specific extensions
taskStore TaskStore No Custom task storage backend
Client-side (Outbound)      
agentSelector AgentSelector No Custom agent selection strategy
minTrustScore number No Minimum trust score for agent selection
requireLive boolean No Require agents to be live
livenessCheckBeforeSend boolean No Check liveness before sending
verifyIdentity boolean No Verify agent identity via DID
authToken string No Authentication token for outbound requests
Observability      
logger AletheiaLogger No Custom logger implementation (BYOL)
logLevel AletheiaLogLevel No Log level threshold

Example

const peer = new PeerAgent({
  registryUrl: "https://registry.aletheia.dev",
  name: "Orchestrator",
  version: "1.0.0",
  url: "https://orchestrator.example.com",
  description: "Routes work to specialist agents",
  skills: [
    { id: "orchestrate", name: "orchestrate", description: "Orchestrate tasks", tags: [] }
  ],
  minTrustScore: 0.7,
  requireLive: true,
});

Inbound Methods (Server-side)

These methods configure how your agent handles incoming requests from other agents.

handle()

Register the message handler for incoming requests.

Signature

handle(handler: AgentHandler): this

Parameters

Name Type Description
handler AgentHandler Async function receiving (context, response) for processing requests

Return Type

this - Returns the PeerAgent instance for method chaining.

Example

peer.handle(async (context, response) => {
  const result = await processRequest(context.textContent);
  response.text(result);
});

onCancel()

Register an optional cancel handler for when clients request task cancellation.

Signature

onCancel(handler: CancelHandler): this

Parameters

Name Type Description
handler CancelHandler Async function called when a task is cancelled

Return Type

this - Returns the PeerAgent instance for method chaining.

Example

peer.onCancel(async (taskId, reason) => {
  console.log(`Task ${taskId} cancelled: ${reason}`);
  await cleanupResources(taskId);
});

handleRequest()

Handle a JSON-RPC request body directly. This is a framework-agnostic method for integrating with custom HTTP frameworks.

Signature

async handleRequest(
  body: unknown
): Promise<A2AResponse | AsyncGenerator<A2AResponse, void, undefined>>

Parameters

Name Type Description
body unknown JSON-RPC request body

Return Type

Promise<A2AResponse | AsyncGenerator<A2AResponse, void, undefined>> - Response or async generator for streaming.

Example

// Custom Fastify integration
app.post('/a2a', async (request, reply) => {
  const result = await peer.handleRequest(request.body);
  
  if (isAsyncGenerator(result)) {
    reply.type('application/jsonl');
    for await (const chunk of result) {
      reply.raw.write(JSON.stringify(chunk) + '\n');
    }
    reply.raw.end();
  } else {
    return result;
  }
});

Outbound Methods (Client-side)

These methods enable your agent to discover and communicate with other trusted agents.

discover()

Discover agents by capability, query, or trust criteria. Delegates to the underlying AletheiaA2A client.

Signature

async discover(params: {
  capability?: string;
  query?: string;
  isLive?: boolean;
  minTrustScore?: number;
  limit?: number;
}): Promise<Agent[]>

Parameters

Name Type Description
params.capability string Filter by capability/skill
params.query string Free-text search query
params.isLive boolean Filter for live agents only
params.minTrustScore number Minimum trust score threshold
params.limit number Maximum number of results

Return Type

Promise<Agent[]> - Array of matching agents from the registry.

Example

const agents = await peer.discover({
  capability: "translation",
  minTrustScore: 0.8,
  isLive: true,
  limit: 5
});

for (const agent of agents) {
  console.log(`${agent.name} (trust: ${agent.trustScore})`);
}

connect()

Connect to an agent by DID with trust verification.

Signature

async connect(did: string): Promise<TrustedAgent>

Parameters

Name Type Description
did string Decentralized identifier of the target agent

Return Type

Promise<TrustedAgent> - A trusted agent instance for secure communication.

Example

const translator = await peer.connect("did:aletheia:translator.example.com");
const response = await translator.send("Hello, world!");

connectByUrl()

Resolve a registered agent by URL through the Aletheia registry, then connect with the same trust checks used by connect().

Signature

async connectByUrl(url: string): Promise<TrustedAgent>

Parameters

Name Type Description
url string Registered base URL of the target agent

Return Type

Promise<TrustedAgent> - A trusted agent instance.

Example

const agent = await peer.connectByUrl("https://agent.example.com");
const response = await agent.send("Test message");

sendByCapability()

Discover, select, and send a message to an agent by capability in one operation.

Signature

async sendByCapability(
  capability: string,
  input: string | MessageInput,
  options?: SendOptions
): Promise<TrustedResponse>

Parameters

Name Type Description
capability string Capability/skill to discover agents by
input string \| MessageInput Message content (string or structured input)
options SendOptions Optional send configuration

SendOptions

Property Type Description
acceptedOutputModes string[] Accepted response content types
blocking boolean Wait for complete response
contextId string Conversation context ID
taskId string Existing task ID to continue
timeoutMs number Request timeout in milliseconds

Return Type

Promise<TrustedResponse> - Response with trust verification metadata.

TrustedResponse

Property Type Description
response Task \| Message The A2A response
trustInfo TrustInfo Trust verification details
agentDid string \| null DID of responding agent
agentName string Name of responding agent
duration number Request duration in ms

Example

// Simple string input
const result = await peer.sendByCapability("translation", "Hello, world!");
console.log(result.response);
console.log(`Trust score: ${result.trustInfo.trustScore}`);

// Structured input with options
const result = await peer.sendByCapability(
  "analysis",
  { text: "Analyze this data", data: { metrics: [1, 2, 3] } },
  { blocking: true, timeoutMs: 30000 }
);

streamByCapability()

Discover, select, and stream a response by capability. Useful for long-running tasks or real-time updates.

Signature

async *streamByCapability(
  capability: string,
  input: string | MessageInput,
  options?: SendOptions
): AsyncGenerator<TrustedStreamEvent>

Parameters

Name Type Description
capability string Capability/skill to discover agents by
input string \| MessageInput Message content
options SendOptions Optional send configuration

Return Type

AsyncGenerator<TrustedStreamEvent> - Async generator yielding stream events.

TrustedStreamEvent

Property Type Description
event A2AStreamEventData The stream event data
kind "message" \| "task" \| "status-update" \| "artifact-update" Event type
agentDid string \| null DID of responding agent
trustInfo TrustInfo Trust verification details

Example

for await (const event of peer.streamByCapability("code-generation", prompt)) {
  switch (event.kind) {
    case "status-update":
      console.log(`Status: ${event.event.status.state}`);
      break;
    case "artifact-update":
      console.log(`Artifact: ${event.event.artifact.name}`);
      break;
    case "message":
      console.log(`Message: ${event.event}`);
      break;
  }
}

Lifecycle Methods

on()

Subscribe to lifecycle events. Returns an unsubscribe function.

Signature

on(
  event: AletheiaEventType | "*",
  handler: AletheiaEventHandler
): () => void

Parameters

Name Type Description
event AletheiaEventType \| "*" Event type to subscribe to (or "*" for all)
handler AletheiaEventHandler Callback function for the event

Return Type

() => void - Unsubscribe function.

Example

const unsubscribe = peer.on("task:created", (event) => {
  console.log(`Task created: ${event.taskId}`);
});

// Later: unsubscribe();

start()

Start a standalone Express server for the agent.

Signature

async start(port: number): Promise<void>

Parameters

Name Type Description
port number Port number to listen on

Return Type

Promise<void>

Example

await peer.start(4000);
console.log("PeerAgent running on port 4000");

stop()

Stop the standalone server if running.

Signature

stop(): void

Return Type

void

Example

// Graceful shutdown
process.on("SIGTERM", () => {
  peer.stop();
  process.exit(0);
});

Accessor Methods

getAgentCard()

Get the agent’s AgentCard (public metadata).

Signature

getAgentCard(): AgentCard

Return Type

AgentCard - The agent’s public metadata card.

Example

const card = peer.getAgentCard();
console.log(`Agent: ${card.name} v${card.version}`);

getRequestHandler()

Get the underlying A2A request handler for custom integrations.

Signature

getRequestHandler(): A2ARequestHandler

Return Type

A2ARequestHandler - The internal request handler.

Example

const handler = peer.getRequestHandler();
// Use with custom routing or middleware

getTaskStore()

Get the task store instance.

Signature

getTaskStore(): TaskStore

Return Type

TaskStore - The task storage backend.

Example

const store = peer.getTaskStore();
const task = await store.get(taskId);

getAletheiaExtensions()

Get Aletheia-specific extensions from the agent configuration.

Signature

getAletheiaExtensions(): AletheiaExtensions | undefined

Return Type

AletheiaExtensions | undefined - Extensions if configured, otherwise undefined.

Example

const extensions = peer.getAletheiaExtensions();
if (extensions?.trustEndpoint) {
  console.log(`Trust endpoint: ${extensions.trustEndpoint}`);
}

getAgent()

Get the underlying AletheiaAgent instance (escape hatch for advanced use cases).

Signature

getAgent(): AletheiaAgent

Return Type

AletheiaAgent - The internal server instance.

Example

const agent = peer.getAgent();
// Access low-level server APIs

getClient()

Get the underlying AletheiaA2A client instance (escape hatch for advanced use cases).

Signature

getClient(): AletheiaA2A

Return Type

AletheiaA2A - The internal client instance.

Example

const client = peer.getClient();
// Access low-level client APIs

Full Example

import { PeerAgent } from "@a2aletheia/a2a";

const peer = new PeerAgent({
  registryUrl: "https://registry.aletheia.dev",
  name: "Orchestrator",
  version: "1.0.0",
  url: "https://orchestrator.example.com",
  description: "Routes work to specialist agents",
  skills: [
    { id: "orchestrate", name: "orchestrate", description: "Orchestrate tasks", tags: ["workflow"] }
  ],
  minTrustScore: 0.7,
  requireLive: true,
});

// Handle incoming requests
peer.handle(async (context, response) => {
  // Use outbound client inside the handler
  const result = await peer.sendByCapability("translate", context.textContent);
  response.text(result.response);
});

// Handle cancellation
peer.onCancel(async (taskId) => {
  console.log(`Task ${taskId} cancelled`);
});

// Subscribe to events
peer.on("task:completed", (event) => {
  console.log(`Task completed: ${event.taskId}`);
});

// Start the server
await peer.start(4000);
console.log("PeerAgent listening on port 4000");

This site uses Just the Docs, a documentation theme for Jekyll.