npm.io
0.2.1 • Published yesterday

@a2a-lib/registry-client-ts

Licence
Apache-2.0
Version
0.2.1
Deps
1
Size
58 kB
Vulns
0
Weekly
0

A2A Registry TypeScript Client

Typed client and managed lease helper for a2a-registry-server 0.2 and later. It discovers logical agents with multiple independently leased runtime instances, using the standard Fetch API and the official @a2a-js/sdk Agent Card type.

Install

npm install @a2a-lib/registry-client-ts

Node.js 22 or newer is required.

Server information

Use getServerInfo() to inspect the connected server without making a registry mutation. It returns the server version, API version, readiness status, backing store, documentation URL, and advertised endpoint paths.

const info = await registry.getServerInfo();
console.log(info.version, info.apiVersion, info.status, info.store);

Discover agents

import { RegistryClient } from "@a2a-lib/registry-client-ts";

const registry = new RegistryClient("http://localhost:3003");
const page = await registry.listAgents({
  skill: "weather",
  capability: "streaming",
  limit: 25,
});

for (const agent of page.agents) {
  console.log(agent.id, agent.instanceCount);
  for (const instance of agent.instances) {
    console.log(instance.instanceId, instance.endpoint, instance.metadata);
  }
}

For the common single-match case, use findAgentBySkill("weather"). The top-level agent.endpoint and lease fields remain compatibility projections; new code should select an active entry from agent.instances.

Maintain an agent registration

maintainA2ARegistryRegistration is based on the helper previously kept in website/agents/shared/a2a-registry.ts. It registers immediately, renews the lease every one-third of its TTL, re-registers after expiry, and unregisters on shutdown.

import type { AgentCard } from "@a2a-js/sdk";
import { maintainA2ARegistryRegistration } from "@a2a-lib/registry-client-ts";

const card: AgentCard = createAgentCard();
const lease = maintainA2ARegistryRegistration({
  id: "weather-agent",
  instanceId: "eu-west-1a",
  endpoint: "http://localhost:3002/v1/tasks",
  agentCard: card,
  ttlSeconds: 60,
  metadata: { role: "weather" },
  logPrefix: "[Weather Agent]",
});

await lease.ready;

process.once("SIGTERM", () => {
  void lease.stop().finally(() => process.exit(0));
});

The helper reads A2A_REGISTRY_URL (or REGISTRY_URL) and A2A_REGISTRY_WRITE_TOKEN (or REGISTRY_WRITE_TOKEN) when the corresponding options are omitted. Pass an existing leaseToken when reclaiming a live instance after a process restart. Omit instanceId to use the server's backward-compatible default instance.

Multiple instances

Every instance under one logical agent ID must publish exactly the same Agent Card. Each instance has its own endpoint, metadata, TTL, lease token, heartbeat, and expiry:

const first = await registry.registerAgentInstance("weather-agent", {
  instanceId: "eu-west-1a",
  endpoint: "https://weather-a.example/a2a",
  agentCard: card,
  ttlSeconds: 60,
  metadata: { zone: "eu-west-1a" },
});

const second = await registry.registerAgentInstance("weather-agent", {
  instanceId: "eu-west-1b",
  endpoint: "https://weather-b.example/a2a",
  agentCard: card,
  ttlSeconds: 60,
  metadata: { zone: "eu-west-1b" },
});

const { instances } = await registry.listAgentInstances("weather-agent");
const instance = await registry.getAgentInstance("weather-agent", "eu-west-1b");

await registry.heartbeatInstance("weather-agent", "eu-west-1b", {
  leaseToken: second.leaseToken,
});

await registry.unregisterAgentInstance("weather-agent", "eu-west-1a", {
  leaseToken: first.leaseToken,
});

Use putAgentInstance(id, instanceId, input, options) to update an existing instance using its lease token. An Agent Card that differs from active sibling instances is rejected by the server with 409 agent_card_mismatch.

Direct lease operations

const registry = new RegistryClient({
  baseUrl: "http://localhost:3003",
  writeToken: process.env.A2A_REGISTRY_WRITE_TOKEN,
});

const registration = await registry.registerAgent({
  id: "weather-agent",
  endpoint: "http://localhost:3002/v1/tasks",
  agentCard: card,
  ttlSeconds: 60,
});

await registry.heartbeat("weather-agent", {
  leaseToken: registration.leaseToken,
});

await registry.unregisterAgent("weather-agent", {
  leaseToken: registration.leaseToken,
});

These methods operate on the compatibility default instance. Named instances use registerAgentInstance, putAgentInstance, heartbeatInstance, and unregisterAgentInstance.

Keywords