Core Concepts
This document provides an in-depth exploration of ElizaOS's fundamental concepts and architectural decisions.
π§ Agent-Centric Architectureβ
The Agent Modelβ
In ElizaOS, everything revolves around the concept of an Agent - an autonomous AI entity with:
- Identity: Unique personality and behavioral traits
- Memory: Persistent knowledge and conversation history
- Goals: Objectives and intentions
- Capabilities: Actions it can perform via plugins
interface Agent {
id: UUID;
character: Character;
runtime: AgentRuntime;
memory: IMemoryManager;
state: State;
}
Character Definitionβ
Characters define an agent's personality and behavior:
interface Character {
// Identity
name: string;
bio: string[];
description: string;
// Personality
style: {
all: string[];
chat: string[];
post: string[];
};
// Behavior
topics: string[];
adjectives: string[];
// Examples
messageExamples: [string, string][];
postExamples: string[];
// Configuration
settings: {
model: string;
temperature?: number;
maxTokens?: number;
};
}
πΊοΈ Room/World Abstractionβ
Understanding Roomsβ
ElizaOS abstracts all communication channels into "Rooms":
- Discord Channel β Room
- Twitter DM Thread β Room
- Telegram Chat β Room
- Direct Web Chat β Room
This abstraction enables platform-agnostic agent behavior.
interface Room {
id: UUID; // Internal ElizaOS ID
platformId: string; // Platform-specific ID
type: 'discord' | 'twitter' | 'telegram' | 'direct';
name?: string;
description?: string;
members: UUID[]; // User IDs in this room
metadata: Map<string, any>; // Platform-specific data
}
UUID Swizzlingβ
ElizaOS uses deterministic UUID generation to maintain consistency:
// Each agent sees the same room with a different UUID
const roomUUID = generateDeterministicUUID(agentId, platformRoomId);
// This ensures:
// 1. Agent memories are isolated
// 2. Cross-agent communication is possible
// 3. Platform IDs remain stable
πΎ Memory Architectureβ
Memory Typesβ
ElizaOS implements a sophisticated memory system inspired by human cognition:
1. Short-term Memory (Working Memory)β
- Recent messages (last 10-20)
- Current conversation context
- Temporary facts
interface ShortTermMemory {
messages: Message[];
context: string;
temporaryFacts: Map<string, any>;
ttl: number; // Time to live
}
2. Long-term Memory (Persistent Storage)β
- Important facts and relationships
- Learned patterns
- User preferences
interface LongTermMemory {
facts: Fact[];
relationships: Relationship[];
preferences: UserPreference[];
embedding?: number[]; // For similarity search
}
3. Episodic Memory (Event Storage)β
- Specific conversation events
- Outcomes of actions
- Temporal sequences
interface EpisodicMemory {
event: string;
participants: UUID[];
timestamp: Date;
outcome?: string;
emotionalValence?: number;
}
Memory Formationβ
Memory Retrievalβ
Memory retrieval uses multiple strategies:
- Recency: Recent messages have higher weight
- Relevance: Embedding similarity search
- Importance: Manually marked important memories
- Frequency: Often-accessed memories
async function retrieveMemories(query: string, count: number): Promise<Memory[]> {
const embedding = await createEmbedding(query);
const memories = await Promise.all([
getRecentMemories(count / 3),
searchByEmbedding(embedding, count / 3),
getImportantMemories(count / 3),
]);
return deduplicate(memories.flat())
.sort((a, b) => calculateRelevance(b, query) - calculateRelevance(a, query))
.slice(0, count);
}
π Message Processing Pipelineβ
Pipeline Stagesβ
Context Assemblyβ
Context is assembled from multiple sources:
interface Context {
// Message context
messages: Message[];
currentMessage: Message;
// Memory context
shortTermMemory: Memory[];
relevantMemories: Memory[];
// State context
user: User;
room: Room;
agent: Agent;
// Provider context
time: string;
platformInfo: any;
customProviders: Map<string, string>;
// Execution context
runtime: AgentRuntime;
services: Map<string, IService>;
}
π― Action Systemβ
Action Lifecycleβ
Actions are discrete behaviors agents can perform:
Action Examplesβ
const followAction: Action = {
name: 'FOLLOW_USER',
description: 'Follow a user on the platform',
examples: [
['user', 'Follow @alice'],
['agent', "I'll follow @alice for you!"],
['user', 'Can you follow bob?'],
['agent', 'Following bob now!'],
],
validate: async (context: Context) => {
// Check if platform supports following
const transport = context.runtime.getService<ITransportService>('transport');
return transport.supportsFeature('follow');
},
execute: async (context: Context) => {
const username = extractUsername(context.currentMessage.content);
const transport = context.runtime.getService<ITransportService>('transport');
await transport.follow(username);
return {
content: `Successfully followed ${username}!`,
action: 'FOLLOW_USER',
data: { username },
};
},
};
π Plugin Systemβ
Plugin Architectureβ
Plugins extend agent capabilities through a standardized interface:
interface Plugin {
name: string;
description: string;
version: string;
// Components
actions?: Action[];
providers?: Provider[];
evaluators?: Evaluator[];
tasks?: Task[];
services?: IService[];
// Lifecycle
initialize?: (runtime: AgentRuntime) => Promise<void>;
shutdown?: () => Promise<void>;
}
Plugin Loading Orderβ
Plugin loading follows a deterministic order:
- Core Plugins: Database, essential services
- AI Providers: Text generation, embeddings
- Platform Adapters: Discord, Twitter, etc.
- Feature Plugins: Custom capabilities
- Bootstrap: Default handlers (loaded last)
const pluginOrder = [
'@elizaos/plugin-sql', // Core database
'@elizaos/plugin-openai', // AI provider
'@elizaos/plugin-discord', // Platform
'@elizaos/custom-plugin', // Custom features
'@elizaos/plugin-bootstrap', // Defaults
];
π State Managementβ
State Hierarchyβ
State in ElizaOS follows a hierarchical model:
Global State
βββ Agent State
βββ Room State
βββ Conversation State
βββ Message State
State Persistenceβ
State is persisted at different levels:
- In-Memory: Current conversation state
- Cache: Recent interactions
- Database: Long-term state
- Disk: Configuration and characters
class StateManager {
// Layered state storage
private memoryState: Map<string, any>;
private cacheState: ICacheService;
private dbState: IDatabaseService;
async getState(key: string): Promise<any> {
// Check layers in order
return (
this.memoryState.get(key) || (await this.cacheState.get(key)) || (await this.dbState.get(key))
);
}
async setState(key: string, value: any, ttl?: number): Promise<void> {
// Write to appropriate layer
this.memoryState.set(key, value);
if (ttl) {
await this.cacheState.set(key, value, ttl);
} else {
await this.dbState.set(key, value);
}
}
}
π Security Modelβ
Permission Systemβ
ElizaOS implements a capability-based security model:
interface Permission {
resource: string; // What resource
action: string; // What action
constraint?: any; // Additional constraints
}
// Example permissions
const permissions = [
{ resource: 'memory', action: 'read', constraint: { own: true } },
{ resource: 'twitter', action: 'post', constraint: { rateLimit: 10 } },
{ resource: 'admin', action: '*' },
];
Sandboxingβ
Plugins run in sandboxed environments:
- Resource Isolation: Limited access to system resources
- API Restrictions: Only approved APIs available
- Memory Limits: Bounded memory usage
- Time Limits: Execution timeouts
π Event Systemβ
Event-Driven Architectureβ
ElizaOS uses events for loose coupling:
// Core events
runtime.on('message:received', handler);
runtime.on('message:sent', handler);
runtime.on('memory:created', handler);
runtime.on('goal:completed', handler);
runtime.on('error:occurred', handler);
// Plugin events
runtime.on('plugin:loaded', handler);
runtime.on('action:executed', handler);
runtime.on('provider:called', handler);
Event Flowβ
π Learning Systemβ
Continuous Learningβ
Agents learn through evaluators:
interface LearningCycle {
// Observe
observation: Message | Action;
// Evaluate
evaluation: {
success: boolean;
feedback: string;
score: number;
};
// Update
updates: {
memories: Memory[];
weights: Map<string, number>;
patterns: Pattern[];
};
}
Pattern Recognitionβ
Agents recognize and learn patterns:
interface Pattern {
trigger: string; // What triggers this pattern
response: string; // How to respond
confidence: number; // How confident in this pattern
frequency: number; // How often it occurs
lastSeen: Date; // When last observed
}
π Next Stepsβ
Now that you understand the core concepts: