What are Services?
Services are long-running background tasks that extend agent functionality beyond request-response patterns.
Service Interface
abstract class Service {
static serviceType: ServiceType;
constructor(runtime?: IAgentRuntime) {}
abstract capabilityDescription: string;
config?: ServiceConfig;
static async start(runtime: IAgentRuntime): Promise<Service> {
// Return new instance of service
}
abstract stop(): Promise<void>;
}
Service Types
// Core service types (from @elizaos/core)
const ServiceType = {
// Define core service types
} as const;
// Plugins extend service types through module augmentation
declare module '@elizaos/core' {
interface ServiceTypeRegistry {
DISCORD: 'discord';
TELEGRAM: 'telegram';
TWITTER: 'twitter';
// ... other plugin-specific types
}
}
Common Service Patterns
class DiscordService extends Service {
static serviceType = 'discord' as const;
capabilityDescription = 'Discord bot integration';
private client: Discord.Client;
constructor(private runtime: IAgentRuntime) {
super(runtime);
}
static async start(runtime: IAgentRuntime): Promise<Service> {
const service = new DiscordService(runtime);
await service.initialize();
return service;
}
private async initialize() {
this.client = new Discord.Client();
this.client.on('messageCreate', async (message) => {
// Convert to Memory format
const memory = await this.convertMessage(message);
// Process through runtime
await this.runtime.processActions(memory, []);
});
await this.client.login(process.env.DISCORD_TOKEN);
}
async stop() {
await this.client.destroy();
}
}
Background Task Service
class TaskService extends Service {
name = ServiceType.TASK;
private interval: NodeJS.Timer;
async start(runtime: IAgentRuntime) {
// Check for scheduled tasks every minute
this.interval = setInterval(async () => {
const tasks = await runtime.databaseAdapter.getTasks({
status: 'pending',
scheduledFor: { $lte: new Date() }
});
for (const task of tasks) {
await this.executeTask(task, runtime);
}
}, 60000);
}
async stop() {
clearInterval(this.interval);
}
}
Model Service Pattern
// Model services typically implement model providers instead
class OpenAIModelProvider implements ModelProvider {
async generateText(params: GenerateTextParams) {
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
const response = await client.chat.completions.create({
model: params.model || "gpt-4",
messages: params.messages
});
return response.choices[0].message;
}
async embed(params: EmbedParams) {
// Implementation for embeddings
}
}
Service Lifecycle
Service Registration
// In a plugin
export const discordPlugin: Plugin = {
name: 'discord',
services: [DiscordService],
init: async (config, runtime) => {
// Services auto-registered and started
}
};
Service Communication
Services can interact with the runtime and other services:
class NotificationService extends Service {
static serviceType = 'notification' as const;
capabilityDescription = 'Cross-platform notifications';
async notify(message: string) {
// Get service by type
const discord = this.runtime.getService('discord');
if (discord) {
await discord.sendMessage(channelId, message);
}
// Check all registered services
const services = this.runtime.getAllServices();
// Coordinate across services
}
}
Best Practices
- Implement graceful shutdown in
stop()
- Handle errors without crashing
- Use environment variables for config
- Avoid blocking operations
- Clean up resources properly
Common Services
Service | Purpose | Example Plugin |
---|
Platform Services | Connect to chat platforms | Discord, Telegram |
Model Services | AI model providers | OpenAI, Anthropic |
Data Services | External data sources | Web search, SQL |
Media Services | Process media | TTS, image gen |
Background Services | Scheduled tasks | Task runner |
Next Steps