Skip to main content
API reference for the @enclave-vm/broker package - the orchestration layer for EnclaveJS.

Installation

npm install @enclave-vm/broker

EnclaveBroker Class

The main broker class for session management and tool orchestration.

Constructor

new EnclaveBroker(options: BrokerOptions)

BrokerOptions

interface BrokerOptions {
  // Session management
  redis?: Redis;
  sessionTimeout?: number;
  maxConcurrentSessions?: number;

  // Tool registry
  tools?: ToolRegistry;
  toolHandler?: ToolHandler;

  // Runtime pool
  runtimePool?: RuntimePoolOptions;

  // Security
  authentication?: AuthConfig;
  rateLimiting?: RateLimitConfig;

  // Logging
  logger?: Logger;
}
PropertyTypeDefaultDescription
redisRedisIn-memoryRedis client for distributed state
sessionTimeoutnumber300000Session timeout in ms (5 min)
maxConcurrentSessionsnumber1000Max concurrent sessions
toolsToolRegistryundefinedTool registry
toolHandlerToolHandlerundefinedTool execution handler

Methods

listen(port)

Start the HTTP server.
async listen(port: number): Promise<void>
Example:
const broker = new EnclaveBroker({ /* options */ });
await broker.listen(3001);
console.log('Broker listening on port 3001');

close()

Stop the server and clean up.
async close(): Promise<void>

execute(code, options?)

Execute code and return a stream.
execute(code: string, options?: ExecuteOptions): AsyncIterable<StreamEvent>
Options:
interface ExecuteOptions {
  timeout?: number;
  maxToolCalls?: number;
  context?: Record<string, unknown>;
  filter?: EventFilter;
}
Example:
const stream = broker.execute(code, { timeout: 30000 });

for await (const event of stream) {
  console.log(event.type, event.payload);
}

getSession(sessionId)

Get session information.
async getSession(sessionId: string): Promise<Session | null>

submitToolResult(sessionId, callId, result)

Submit a tool call result.
async submitToolResult(
  sessionId: string,
  callId: string,
  result: unknown
): Promise<void>

HTTP API Endpoints

POST /execute

Execute code with streaming response. Request:
{
  code: string;
  timeout?: number;
  maxToolCalls?: number;
  context?: Record<string, unknown>;
  filter?: {
    types?: string[];
    blockedTypes?: string[];
  };
}
Response: NDJSON stream of events Example:
curl -X POST http://localhost:3001/execute \
  -H "Content-Type: application/json" \
  -d '{"code": "return 1 + 2"}' \
  --no-buffer

GET /sessions/:sessionId

Get session status. Response:
{
  id: string;
  status: 'pending' | 'running' | 'completed' | 'error';
  createdAt: number;
  expiresAt: number;
}

POST /sessions/:sessionId/tool-result

Submit tool execution result. Request:
{
  callId: string;
  result: unknown;
  error?: {
    message: string;
    code?: string;
  };
}
Response:
{
  success: true;
}

GET /code/actions

Returns the current action catalog derived from connected OpenAPI sources. Response:
interface CatalogResponse {
  /** Available actions from all connected OpenAPI sources */
  actions: CatalogAction[];
  /** Connected OpenAPI service descriptors */
  services: CatalogService[];
  /** Catalog version — changes when actions are added or removed */
  version: string;
}

interface CatalogAction {
  /** Tool name (e.g., "user-service_listUsers") */
  name: string;
  /** Human-readable description from the OpenAPI spec */
  description?: string;
  /** JSON Schema for the tool's input parameters */
  inputSchema?: Record<string, unknown>;
  /** Name of the service this action belongs to */
  service: string;
  /** Tags from the OpenAPI operation */
  tags?: string[];
  /** Whether the operation is deprecated */
  deprecated?: boolean;
}

interface CatalogService {
  /** Service name (from OpenApiSourceConfig.name) */
  name: string;
  /** Internal spec URL */
  specUrl: string;
  /** ISO 8601 timestamp of the last successful spec poll */
  lastUpdated: string;
  /** Number of actions from this service */
  actionCount: number;
}
Version semantics: The version field is a deterministic hash of all source spec hashes. It changes whenever an OpenAPI spec is polled with additions or removals. Consumers can compare version strings to detect catalog changes. Example:
curl http://localhost:3001/code/actions
{
  "actions": [
    {
      "name": "user-service_listUsers",
      "description": "List all users",
      "service": "user-service"
    },
    {
      "name": "user-service_getUser",
      "description": "Get user by ID",
      "service": "user-service"
    }
  ],
  "services": [
    {
      "name": "user-service",
      "specUrl": "",
      "lastUpdated": "2026-03-31T12:00:00.000Z",
      "actionCount": 2
    }
  ],
  "version": "a1b2c3d4..."
}
Wiring: Use CatalogHandler to register this route:
import { CatalogHandler } from '@enclave-vm/broker';

const catalog = new CatalogHandler(toolRegistry, openApiSources);
for (const route of catalog.getRoutes()) {
  app[route.method.toLowerCase()](route.path, route.handler);
}
The types CatalogAction, CatalogService, CatalogResponse, and CatalogHandler are all exported from the @enclave-vm/broker package.

GET /health

Health check endpoint. Response:
{
  status: 'ok';
  uptime: number;
  sessions: {
    active: number;
    total: number;
  };
}

ToolRegistry Class

Registry for managing tools.

Constructor

new ToolRegistry()

Methods

register(tool)

Register a tool.
register(tool: ToolDefinition): void
interface ToolDefinition {
  name: string;
  description: string;
  parameters: Record<string, ParameterDef>;
  handler: ToolHandler;
}

interface ParameterDef {
  type: 'string' | 'number' | 'boolean' | 'object' | 'array';
  description: string;
  required?: boolean;
  default?: unknown;
}

type ToolHandler = (
  args: Record<string, unknown>,
  context?: ExecutionContext
) => Promise<unknown>;
Example:
const registry = new ToolRegistry();

registry.register({
  name: 'users:list',
  description: 'List all users',
  parameters: {
    limit: {
      type: 'number',
      description: 'Max users to return',
      default: 10,
    },
  },
  handler: async (args) => {
    return db.users.findAll({ limit: args.limit });
  },
});

get(name)

Get a tool by name.
get(name: string): ToolDefinition | undefined

list()

List all registered tools.
list(): ToolDefinition[]

getDocumentation()

Get tool documentation for LLM prompts.
getDocumentation(): string

RuntimePoolOptions

interface RuntimePoolOptions {
  minSize: number;
  maxSize: number;
  scaleUpThreshold: number;
  scaleDownThreshold: number;
  scaleInterval: number;
}

Authentication

interface AuthConfig {
  type: 'bearer' | 'api-key' | 'custom';
  validate: (token: string) => Promise<AuthResult>;
}

interface AuthResult {
  valid: boolean;
  userId?: string;
  tenantId?: string;
  permissions?: string[];
}
Example:
const broker = new EnclaveBroker({
  authentication: {
    type: 'bearer',
    validate: async (token) => {
      const decoded = verifyJWT(token);
      return {
        valid: true,
        userId: decoded.sub,
        permissions: decoded.permissions,
      };
    },
  },
});

Rate Limiting

interface RateLimitConfig {
  windowMs: number;
  maxRequests: number;
  keyGenerator?: (req: Request) => string;
}
Example:
const broker = new EnclaveBroker({
  rateLimiting: {
    windowMs: 60000,
    maxRequests: 100,
    keyGenerator: (req) => req.headers['x-api-key'] || req.ip,
  },
});

Events

BrokerEvents

broker.on('session:created', (session) => { });
broker.on('session:completed', (session, result) => { });
broker.on('session:error', (session, error) => { });
broker.on('tool:called', (session, tool, args) => { });
broker.on('tool:completed', (session, tool, result) => { });

Complete Example

import { EnclaveBroker, ToolRegistry } from '@enclave-vm/broker';
import Redis from 'ioredis';

// Create tool registry
const tools = new ToolRegistry();

tools.register({
  name: 'users:list',
  description: 'List users',
  parameters: {
    limit: { type: 'number', description: 'Max results' },
  },
  handler: async (args) => {
    return [
      { id: '1', name: 'Alice' },
      { id: '2', name: 'Bob' },
    ].slice(0, args.limit || 10);
  },
});

tools.register({
  name: 'users:get',
  description: 'Get user by ID',
  parameters: {
    id: { type: 'string', description: 'User ID', required: true },
  },
  handler: async (args) => {
    return { id: args.id, name: 'Alice' };
  },
});

// Create broker
const broker = new EnclaveBroker({
  redis: new Redis(process.env.REDIS_URL),
  tools,
  sessionTimeout: 300000,
  maxConcurrentSessions: 1000,
  rateLimiting: {
    windowMs: 60000,
    maxRequests: 100,
  },
});

// Event handlers
broker.on('session:created', (session) => {
  console.log('Session created:', session.id);
});

broker.on('tool:called', (session, tool, args) => {
  console.log(`Tool called: ${tool}`, args);
});

// Start server
await broker.listen(3001);
console.log('Broker running on port 3001');

// Graceful shutdown
process.on('SIGTERM', async () => {
  await broker.close();
  process.exit(0);
});