Agent Registry
Agent Registry
The AgentRegistry is a global static registry that automatically tracks all active Agent instances. It provides observability, deep inspection, parent/child relationship tracking, event fan-in, and external control — all from one central place.
Automatic Tracking
Every agent auto-registers on creation and auto-unregisters on destroy. No setup required:
import { Agent, AgentRegistry } from 'oneringai';
const agent = Agent.create({ connector: 'openai', model: 'gpt-4.1', name: 'assistant' });
AgentRegistry.count; // 1
AgentRegistry.has(agent.registryId); // true
agent.destroy();
AgentRegistry.count; // 0
Each agent gets a unique registryId (UUID) on creation. Agent names are NOT unique — multiple agents can share a name.
Query
// By unique ID
AgentRegistry.get(agent.registryId);
// By name (returns array — names aren't unique)
AgentRegistry.getByName('assistant');
// Filter with AND logic
AgentRegistry.filter({ model: 'gpt-4.1', status: 'running' });
AgentRegistry.filter({ status: ['idle', 'running'] }); // match any of these statuses
AgentRegistry.filter({ connector: 'openai', parentAgentId: parentAgent.registryId });
// Lightweight info snapshots
const infos = AgentRegistry.listInfo(); // AgentInfo[]
// Each: { id, name, model, connector, status, createdAt, parentAgentId, childAgentIds }
// Aggregate stats
const stats = AgentRegistry.getStats();
// { total, byStatus: { idle, running, paused, cancelled, destroyed }, byModel, byConnector }
// Aggregate metrics across all agents
const metrics = AgentRegistry.getAggregateMetrics();
// { totalAgents, activeExecutions, totalTokens, totalToolCalls, totalErrors, byModel, byConnector }
Deep Inspection
The inspect() method returns everything about an agent — full context snapshot, conversation history, plugin states, tools, execution metrics, audit trail, and circuit breaker states:
const inspection = await AgentRegistry.inspect(agent.registryId);
// Context snapshot (from agent.getSnapshot())
inspection.context.plugins; // IPluginSnapshot[] — all plugin states
inspection.context.tools; // IToolSnapshot[] — all tools with call counts
inspection.context.budget; // ContextBudget — token usage breakdown
inspection.context.systemPrompt; // string | null
inspection.context.features; // { workingMemory, inContextMemory, ... }
// Full conversation
inspection.conversation; // ReadonlyArray<InputItem>
inspection.currentInput; // ReadonlyArray<InputItem> — pending input
// Execution state
inspection.execution.id; // current executionId or null
inspection.execution.iteration; // current iteration
inspection.execution.metrics; // ExecutionMetrics (tokens, tool calls, durations, errors)
inspection.execution.auditTrail; // AuditEntry[] (hook executions, tool skips, permissions)
// Tool manager
inspection.toolStats; // ToolManagerStats
inspection.circuitBreakers; // Map<string, CircuitState>
// Children
inspection.children; // AgentInfo[] — child agent snapshots
// Bulk inspection
const all = await AgentRegistry.inspectAll();
const filtered = await AgentRegistry.inspectMatching({ model: 'gpt-4.1' });
Parent/Child Hierarchy
Agents can track parent/child relationships for hierarchical agent architectures:
// Create parent
const orchestrator = Agent.create({ connector: 'openai', model: 'gpt-4.1', name: 'orchestrator' });
// Create children linked to parent
const researcher = Agent.create({
connector: 'openai', model: 'gpt-4.1', name: 'researcher',
parentAgentId: orchestrator.registryId,
});
const writer = Agent.create({
connector: 'anthropic', model: 'claude-sonnet-4-6', name: 'writer',
parentAgentId: orchestrator.registryId,
});
// Query relationships
AgentRegistry.getChildren(orchestrator.registryId); // [researcher, writer]
AgentRegistry.getParent(researcher.registryId); // orchestrator
// Recursive tree (for visualization/dashboards)
const tree = AgentRegistry.getTree(orchestrator.registryId);
// { info: orchestratorInfo, children: [
// { info: researcherInfo, children: [] },
// { info: writerInfo, children: [] },
// ]}
// Filter by parent
AgentRegistry.filter({ parentAgentId: orchestrator.registryId });
Events
Registry lifecycle events:
// Agent registered/unregistered
AgentRegistry.on('agent:registered', ({ agent, info }) => {
console.log(`New agent: ${info.name} (${info.id})`);
});
AgentRegistry.on('agent:unregistered', ({ id, name, reason }) => {
console.log(`Agent removed: ${name} (${reason})`);
});
// Status changes (tracked via agent's own EventEmitter)
AgentRegistry.on('agent:statusChanged', ({ id, name, previous, current }) => {
console.log(`${name}: ${previous} -> ${current}`);
});
// Registry empty
AgentRegistry.on('registry:empty', () => {
console.log('All agents destroyed');
});
Event Fan-In
Receive ALL events from ALL agents through a single callback — ideal for dashboards, logging pipelines, and monitoring:
AgentRegistry.onAgentEvent((agentId, agentName, event, data) => {
console.log(`[${agentName}] ${event}`, data);
// "[researcher] execution:start" { executionId, config, timestamp }
// "[researcher] tool:complete" { executionId, iteration, toolCall, result, timestamp }
// "[writer] llm:response" { executionId, iteration, response, timestamp, duration }
});
// Stop listening
AgentRegistry.offAgentEvent(myListener);
Forwarded events include all agent events: execution:*, iteration:*, llm:*, tool:*, hook:error, circuit:*, async:*.
External Control
Control agents without holding a direct reference:
// Individual control
AgentRegistry.pauseAgent(id);
AgentRegistry.resumeAgent(id);
AgentRegistry.cancelAgent(id, 'timeout');
AgentRegistry.destroyAgent(id);
// Bulk control with filters
AgentRegistry.pauseMatching({ model: 'gpt-4.1' });
AgentRegistry.cancelMatching({ status: 'running' }, 'shutting down');
AgentRegistry.destroyMatching({ connector: 'openai' });
// Nuclear
AgentRegistry.pauseAll();
AgentRegistry.cancelAll('emergency shutdown');
AgentRegistry.destroyAll();
Full API Reference
| Category | Method | Returns | Description |
|---|---|---|---|
| Query | get(id) |
IRegistrableAgent? |
Get agent by unique ID |
getByName(name) |
IRegistrableAgent[] |
Get all agents with name | |
has(id) |
boolean |
Check if agent exists | |
list() |
string[] |
All registry IDs | |
filter(filter) |
IRegistrableAgent[] |
Agents matching filter | |
count |
number |
Total tracked agents | |
| Info | listInfo() |
AgentInfo[] |
Lightweight snapshots |
filterInfo(filter) |
AgentInfo[] |
Filtered snapshots | |
| Inspection | inspect(id) |
Promise<AgentInspection?> |
Deep inspection |
inspectAll() |
Promise<AgentInspection[]> |
Inspect all agents | |
inspectMatching(filter) |
Promise<AgentInspection[]> |
Filtered inspection | |
| Aggregates | getStats() |
AgentRegistryStats |
Counts by status/model/connector |
getAggregateMetrics() |
AggregateMetrics |
Tokens, tool calls, errors | |
| Hierarchy | getChildren(parentId) |
IRegistrableAgent[] |
Child agents |
getParent(childId) |
IRegistrableAgent? |
Parent agent | |
getTree(rootId) |
AgentTreeNode? |
Recursive tree | |
| Events | on(event, listener) |
void |
Subscribe to lifecycle events |
off(event, listener) |
void |
Unsubscribe | |
once(event, listener) |
void |
Subscribe once | |
onAgentEvent(listener) |
void |
Fan-in: all agent events | |
offAgentEvent(listener) |
void |
Remove fan-in listener | |
| Control | pauseAgent(id) |
boolean |
Pause agent |
resumeAgent(id) |
boolean |
Resume agent | |
cancelAgent(id, reason?) |
boolean |
Cancel agent | |
destroyAgent(id) |
boolean |
Destroy agent | |
pauseMatching(filter) |
number |
Bulk pause | |
cancelMatching(filter, reason?) |
number |
Bulk cancel | |
destroyMatching(filter) |
number |
Bulk destroy | |
pauseAll() |
number |
Pause all | |
cancelAll(reason?) |
number |
Cancel all | |
destroyAll() |
number |
Destroy all | |
| Housekeeping | clear() |
void |
Clear registry (testing) |