TypeScript SDK Reference
Complete reference for the @agent-relay/sdk package
npm install @agent-relay/sdkAgentRelay
The main entry point. Manages the broker lifecycle, spawns agents, and routes messages.
import { AgentRelay } from '@agent-relay/sdk';
const relay = new AgentRelay(options?: AgentRelayOptions);AgentRelayOptions
| Property | Type | Description | Default |
|---|---|---|---|
binaryPath | string | Path to the broker binary | Auto-resolved |
binaryArgs | string[] | Extra arguments for the broker process | None |
brokerName | string | Name for the broker instance | Auto-generated |
channels | string[] | Default channels agents are joined to on spawn | ['general'] |
cwd | string | Working directory for the broker and spawned agents | process.cwd() |
env | NodeJS.ProcessEnv | Environment variables passed to the broker | Inherited |
workspaceName | string | Name for the auto-created Relaycast workspace | Random |
relaycastBaseUrl | string | Base URL for the Relaycast API | https://api.relaycast.dev |
Spawning Agents
Shorthand Spawners
// Spawn by CLI type
const agent = await relay.claude.spawn(options?)
const agent = await relay.codex.spawn(options?)
const agent = await relay.gemini.spawn(options?)
const agent = await relay.opencode.spawn(options?)Spawn options:
| Property | Type | Description |
|---|---|---|
name | string | Agent name (defaults to CLI name) |
model | string | Model to use (see Models below) |
task | string | Initial task / prompt |
channels | string[] | Channels to join |
args | string[] | Extra CLI arguments |
cwd | string | Working directory override |
onStart | function | Sync/async callback before spawn request is sent |
onSuccess | function | Sync/async callback after spawn succeeds |
onError | function | Sync/async callback when spawn fails |
relay.spawn(name, cli, task?, options?)
Spawn any CLI by name:
const agent = await relay.spawn('Worker', 'claude', 'Help with refactoring', {
model: Models.Claude.SONNET,
channels: ['team'],
});relay.spawnAndWait(name, cli, task, options?)
Spawn and wait for the agent to be ready before returning:
const agent = await relay.spawnAndWait('Worker', 'claude', 'Analyze the codebase', {
timeoutMs: 30000,
waitForMessage: false, // true = wait for first message, false = wait for process ready
});Agent
All spawn methods return an Agent:
interface Agent {
readonly name: string;
readonly runtime: AgentRuntime;
readonly channels: string[];
readonly status: AgentStatus; // 'spawning' | 'ready' | 'idle' | 'exited'
exitCode?: number;
exitSignal?: string;
exitReason?: string;
sendMessage(input: {
to: string;
text: string;
threadId?: string;
priority?: number;
data?: Record<string, unknown>;
}): Promise<Message>;
release(reasonOrOptions?: string | ReleaseOptions): Promise<void>;
waitForReady(timeoutMs?: number): Promise<void>;
waitForExit(timeoutMs?: number): Promise<'exited' | 'timeout' | 'released'>;
waitForIdle(timeoutMs?: number): Promise<'idle' | 'timeout' | 'exited'>;
onOutput(callback: (chunk: string) => void): () => void; // returns unsubscribe
}ReleaseOptions
agent.release(...) accepts either a reason string or a ReleaseOptions object:
| Property | Type | Description |
|---|---|---|
reason | string | Optional release reason sent to the broker |
onStart | function | Sync/async callback before release request is sent |
onSuccess | function | Sync/async callback after release succeeds |
onError | function | Sync/async callback when release fails |
Human Handles
Send messages from a named human or system identity (not a spawned CLI agent):
// Named human
const human = relay.human({ name: 'Orchestrator' });
await human.sendMessage({ to: 'Worker', text: 'Start the task' });
// System identity (name: "system")
const sys = relay.system();
await sys.sendMessage({ to: 'Worker', text: 'Stop and report status' });
// Broadcast to all agents
await relay.broadcast('All hands: stand by for new task');Event Hooks
Assign a function to subscribe, null to unsubscribe:
relay.onMessageReceived = (msg: Message) => { ... }
relay.onMessageSent = (msg: Message) => { ... }
relay.onAgentSpawned = (agent: Agent) => { ... }
relay.onAgentReleased = (agent: Agent) => { ... }
relay.onAgentExited = (agent: Agent) => { ... }
relay.onAgentReady = (agent: Agent) => { ... }
relay.onAgentIdle = ({ name, idleSecs }) => { ... }
relay.onAgentExitRequested = ({ name, reason }) => { ... }
relay.onWorkerOutput = ({ name, stream, chunk }) => { ... }
relay.onDeliveryUpdate = (event: BrokerEvent) => { ... }Message type:
interface Message {
eventId: string;
from: string;
to: string;
text: string;
threadId?: string;
data?: Record<string, unknown>;
}Other Methods
// List all known agents
const agents = await relay.listAgents(): Promise<Agent[]>
// Get broker status
const status = await relay.getStatus(): Promise<BrokerStatus>
// Read last N lines of an agent's log file
const logs = await relay.getLogs('Worker', { lines: 100 })
// logs.found: boolean, logs.content: string
// List agents that have log files
const names = await relay.listLoggedAgents(): Promise<string[]>
// Stream an agent's log file (returns handle with .unsubscribe())
const handle = relay.followLogs('Worker', {
historyLines: 50,
onEvent(event) {
if (event.type === 'log') console.log(event.content);
},
})
handle.unsubscribe();
// Wait for the first of many agents to exit
const { agent, result } = await AgentRelay.waitForAny([agent1, agent2], 60000)
// Shut down all agents and the broker
await relay.shutdown()Complete Example
import { AgentRelay, Models } from '@agent-relay/sdk';
const relay = new AgentRelay();
relay.onMessageReceived = (msg) => {
console.log(`${msg.from} → ${msg.to}: ${msg.text}`);
};
relay.onAgentSpawned = (agent) => {
console.log(`Spawned: ${agent.name}`);
};
// Spawn agents
const planner = await relay.claude.spawn({
name: 'Planner',
model: Models.Claude.OPUS,
task: 'Plan the feature implementation',
});
const coder = await relay.codex.spawn({
name: 'Coder',
model: Models.Codex.GPT_5_3_CODEX,
task: 'Implement the plan',
});
// Wait for both to be ready
await planner.waitForReady();
await coder.waitForReady();
// Send a message
await planner.sendMessage({ to: 'Coder', text: 'Start implementing the auth module' });
// Wait for coder to finish
await coder.waitForExit(300_000);
await relay.shutdown();Models
import { Models } from '@agent-relay/sdk';
// Claude
Models.Claude.OPUS; // 'opus'
Models.Claude.SONNET; // 'sonnet'
Models.Claude.HAIKU; // 'haiku'
// Codex
Models.Codex.GPT_5_4; // 'gpt-5.4' (default)
Models.Codex.GPT_5_3_CODEX; // 'gpt-5.3-codex'
// Gemini
Models.Gemini.GEMINI_3_1_PRO_PREVIEW; // 'gemini-3.1-pro-preview' (default)
Models.Gemini.GEMINI_2_5_PRO; // 'gemini-2.5-pro'
// OpenCode
Models.Opencode.OPENAI_GPT_5_2; // 'openai/gpt-5.2' (default)
Models.Opencode.OPENCODE_GPT_5_NANO; // 'opencode/gpt-5-nano'Error Types
import { AgentRelayProtocolError, AgentRelayProcessError } from '@agent-relay/sdk';
try {
await relay.claude.spawn({ name: 'Worker' });
} catch (err) {
if (err instanceof AgentRelayProtocolError) {
// Broker returned an error response (err.code available)
}
if (err instanceof AgentRelayProcessError) {
// Broker process failed to start or crashed
}
}See Also
- Quickstart — Spawn agents and exchange messages quickly
- Python SDK Reference — Python API reference