Agent Plugin
Core orchestration system for creating and managing AI agents with tools, commands, hooks, state persistence, and sub-agent support.
Overview
The @tokenring-ai/agent
package enables creation and management of AI agents that execute commands, use tools, run hooks, maintain state, and communicate through asynchronous events. Agents operate within teams (AgentTeam) that share registries of tools, commands, hooks, and services. Supports interactive and background agent types, sub-agent creation, state persistence via checkpoints, and human interaction requests.
Key Features
- AgentTeam orchestration: Manage multiple agents with shared registries
- State management: StateManager with serializable state slices
- Event-driven architecture: Real-time event streaming for agent interactions
- Sub-agent support: Create child agents with inherited state
- Human interaction: Request user input with typed responses
- Extensible system: Tools, commands, hooks via TokenRingPackage
- State persistence: Checkpoint and restore agent state
Core Components
AgentTeam
Central orchestrator managing agents, packages, and shared registries.
Key Methods:
addPackages(packages: TokenRingPackage[])
- Install and start packagescreateAgent(type: string): Promise<Agent>
- Create agent by typegetAgents(): Agent[]
- Get all active agentsdeleteAgent(agent: Agent): Promise<void>
- Shutdown and remove agentgetConfigSlice<T>(key: string, schema: T)
- Get validated configaddAgentConfig(name: string, config: AgentConfig)
- Register agent type
Registries:
packages
- TokenRing packagesservices
- Shared services (typed registry)chatCommands
- Chat commandstools
- Available toolshooks
- Lifecycle hooks
Agent
Individual AI agent with state management, event emission, and command processing.
Core Methods:
initialize(): Promise<void>
- Attach services, run initial commandshandleInput({message: string}): Promise<void>
- Process user inputrunCommand(message: string): Promise<void>
- Execute command or chatcreateSubAgent(agentType: string): Promise<Agent>
- Create child agent
State Management:
initializeState<T>(ClassType, props)
- Add state slicegetState<T>(ClassType): T
- Retrieve state slicemutateState<T>(ClassType, callback)
- Modify state slicegenerateCheckpoint(): AgentCheckpointData
- Serialize staterestoreCheckpoint(data: AgentCheckpointData)
- Restore statereset(what: ResetWhat[])
- Reset state slices
Event System:
events(signal: AbortSignal): AsyncGenerator<AgentEventEnvelope>
- Event streamchatOutput(content: string)
- Emit chat outputreasoningOutput(content: string)
- Emit reasoning outputsystemMessage(message: string, level?)
- Emit system messagesetBusy(message: string)
/setNotBusy()
/setIdle()
- State changes
Human Interaction:
askHuman<T>(request: HumanInterfaceRequest): Promise<T>
- Request inputsendHumanResponse(sequence: number, response: any)
- Resolve request
StateManager
Manages state slices with serialization/deserialization.
Methods:
initializeState<T>(ClassType, props)
- Register state slicegetState<T>(ClassType): T
- Get state slicemutateState<T>(ClassType, callback)
- Modify stateserialize(): Record<string, object>
- Serialize all slicesdeserialize(data, onMissing?)
- Restore statereset(what: ResetWhat[])
- Reset slices
Built-in Commands
/debug [on|off]
- Toggle debug logging/hooks [list|enable|disable] [hookName]
- Manage hooks/reset [chat|memory|settings|all]
- Reset state/settings
- Show active services and tools/tools [enable|disable|set] <tool1> <tool2>
- Manage tools/work [message]
- Invoke agent's work handler
Built-in Tools
agent/run
- Create sub-agent, send message, wait for response, cleanup
Event Types
output.chat
- Chat outputoutput.reasoning
- Reasoning outputoutput.system
- System messages (info/warning/error)state.busy
- Agent busystate.notBusy
- Agent not busystate.idle
- Agent idle and readystate.aborted
- Operation abortedstate.exit
- Exit requestedinput.received
- Input receivedhuman.request
- Human input requestedhuman.response
- Human response providedreset
- State reset
Usage Examples
Creating an Agent Team
import { AgentTeam, packageInfo } from '@tokenring-ai/agent';
const team = new AgentTeam({ /* config */ });
await team.addPackages([packageInfo]);
team.addAgentConfig('myAgent', {
name: 'My Agent',
description: 'Custom agent',
visual: { color: 'blue' },
ai: { /* AI config */ },
initialCommands: [],
type: 'interactive'
});
const agent = await team.createAgent('myAgent');
await agent.initialize();
Processing Events
const controller = new AbortController();
for await (const event of agent.events(controller.signal)) {
switch (event.type) {
case 'output.chat':
console.log('Chat:', event.data.content);
break;
case 'state.idle':
console.log('Agent ready');
break;
case 'human.request':
const response = await getUserInput(event.data.request);
agent.sendHumanResponse(event.data.sequence, response);
break;
}
}
await agent.handleInput({ message: '/tools enable myTool' });
Creating Sub-Agents
const subAgent = await agent.createSubAgent('backgroundWorker');
// Persistent state is copied to sub-agent
await team.deleteAgent(subAgent); // Cleanup
State Management
class MyState implements StateSlice {
name = 'MyState';
data: string[] = [];
reset(what: ResetWhat[]) {
if (what.includes('chat')) this.data = [];
}
serialize() { return { data: this.data }; }
deserialize(obj: any) { this.data = obj.data || []; }
}
agent.initializeState(MyState, {});
agent.mutateState(MyState, state => state.data.push('item'));
const state = agent.getState(MyState);
const checkpoint = agent.generateCheckpoint();
agent.restoreCheckpoint(checkpoint);
Configuration
AgentConfig:
{
name: string; // Agent identifier
description: string; // Purpose
visual: { color: string }; // UI color
ai: any; // AI configuration
initialCommands: string[]; // Startup commands
persistent?: boolean; // Enable checkpointing
storagePath?: string; // Storage location
type: 'interactive' | 'background'; // Agent type
workHandler?: (msg: string, agent: Agent) => Promise<void>; // Custom work handler
}
Human Interface Requests
Supported request types:
askForConfirmation
- Yes/no promptopenWebPage
- Open URLaskForSelection
- Single choiceask
- Text inputaskForPassword
- Password inputaskForMultipleSelections
- Multiple choicesaskForSingleTreeSelection
- Tree navigation (single)askForMultipleTreeSelection
- Tree navigation (multiple)
Dependencies
@tokenring-ai/utility
(^0.1.0): Registries and utilitieseventemitter3
(^5.0.1): Event handlingglob-gitignore
(^1.0.15): File pattern matchinguuid
(^13.0.0): ID generation