Docs/Core SDK/Multi-Agent Clients

Multi-Agent Clients

Create agent-scoped clients with their own signing keys, typed action maps, and allow/deny policies for multi-agent architectures.

import { Invariance, action } from '@invariance/sdk';
Prerequisites: Initialization, Sessions & Receipts

Overview

The `inv.agent()` method creates a scoped client for a specific agent. Each agent gets its own Ed25519 signing key, optional typed action definitions via the `action()` helper, and allow/deny lists for action enforcement.

Typed actions provide compile-time type safety for action inputs and outputs. Agent clients create sessions automatically scoped to the agent ID.

Quick Example

Create typed multi-agent clientstypescript
import { Invariance, action } from '@invariance/sdk';

const inv = Invariance.init({ apiKey: 'dev_...' });

const traderActions = {
  swap: action<{ from: string; to: string; amount: string }, { txHash: string }>(),
  quote: action<{ pair: string }, { price: number }>(),
};

const trader = inv.agent({
  id: 'trader-1',
  privateKey: '...',
  actions: traderActions,
  allowActions: ['swap', 'quote'],
});

const session = trader.session({ name: 'morning-trades' });
await session.record('swap', { from: 'ETH', to: 'USDC', amount: '10' }, { txHash: '0x...' });
session.end();

API Reference

agent
Create an agent-scoped client with its own signing key and optional typed actions.
agent<TActions>(opts: { id: string; privateKey: string; actions?: TActions; allowActions?: string[]; denyActions?: string[] }): AgentClient
Parameters
idstringUnique agent identifier
privateKeystringAgent's Ed25519 private key (hex)
actionsTActionsTyped action map created with action()
allowActionsstring[]Whitelist of allowed action names
denyActionsstring[]Blacklist of denied action names
ReturnsAgentClient<TActions>
agentClient.session
Create a session scoped to this agent (lazy).
session(input: { name: string }): AgentSession<TActions>
Parameters
namestringSession name
ReturnsAgentSession<TActions>
agentSession.record
Record a typed action with compile-time type checking.
async record<K>(action: K, input: InputOf<TActions[K]>, output?: OutputOf<TActions[K]>): Promise<Receipt>
Parameters
actionKAction name (type-checked)
inputInputOf<TActions[K]>Action input (type-checked)
outputOutputOf<TActions[K]>Action output (type-checked)
ReturnsPromise<Receipt>

Walkthrough

Building a typed multi-agent system
1
Define action schemas
Use the action() helper to define typed action schemas for each agent.
typescript
import { Invariance, action } from '@invariance/sdk';

const traderActions = {
  swap: action<{ from: string; to: string; amount: string }, { txHash: string }>(),
  quote: action<{ pair: string }, { price: number }>(),
};

const analystActions = {
  analyze: action<{ symbol: string }, { signal: 'buy' | 'sell' | 'hold' }>(),
};
2
Create agent clients
Create agent-scoped clients with their own signing keys and typed actions.
typescript
const inv = Invariance.init({ apiKey: process.env.INVARIANCE_KEY! });

const trader = inv.agent({
  id: 'trader-1',
  privateKey: process.env.TRADER_KEY!,
  actions: traderActions,
  allowActions: ['swap', 'quote'],
});

const analyst = inv.agent({
  id: 'analyst-1',
  privateKey: process.env.ANALYST_KEY!,
  actions: analystActions,
});
3
Run typed sessions
Create sessions and record type-checked actions.
typescript
const session = trader.session({ name: 'morning-trades' });

// Type-checked — 'swap' input must match { from, to, amount }
await session.record('swap',
  { from: 'ETH', to: 'USDC', amount: '10' },
  { txHash: '0xabc...' },
);

// Type error if you pass wrong fields:
// await session.record('swap', { wrong: 'field' });

session.end();
await inv.shutdown();

Error Handling

Error handling patterntypescript
import { InvarianceError } from '@invariance/sdk';

try {
  const agent = inv.agent({
    id: 'trader',
    privateKey: '...',
    denyActions: ['transfer'],
  });
  const session = agent.session({ name: 'run' });
  // This will throw because 'transfer' is denied
  await session.record('transfer', { to: '0x...', amount: '1' });
} catch (err) {
  if (err instanceof InvarianceError) {
    console.error(err.code);    // 'POLICY_DENIED'
    console.error(err.message); // 'Action transfer is denied'
  }
}

Use Cases

  • Run multiple specialized agents under one SDK instance
  • Enforce per-agent action policies with allow/deny lists
  • Get compile-time type safety for action inputs and outputs
  • Isolate signing keys so each agent has its own cryptographic identity
On this page
OverviewQuick ExampleAPI ReferenceWalkthroughError HandlingUse CasesRelated Modules