This file is a merged representation of a subset of the codebase, containing specifically included files and files not matching ignore patterns, combined into a single document by Repomix. The content has been processed where comments have been removed, empty lines have been removed, content has been compressed (code blocks are separated by ⋮---- delimiter). # File Summary ## Purpose This file contains a packed representation of the entire repository's contents. It is designed to be easily consumable by AI systems for analysis, code review, or other automated processes. ## File Format The content is organized as follows: 1. This summary section 2. Repository information 3. Directory structure 4. Multiple file entries, each consisting of: a. A header with the file path (## File: path/to/file) b. The full contents of the file in a code block ## Usage Guidelines - This file should be treated as read-only. Any changes should be made to the original repository files, not this packed version. - When processing this file, use the file path to distinguish between different files in the repository. - Be aware that this file may contain sensitive information. Handle it with the same level of security as you would the original repository. - Pay special attention to the Repository Description. These contain important context and guidelines specific to this project. - Pay special attention to the Repository Instruction. These contain important context and guidelines specific to this project. ## Notes - Some files may have been excluded based on .gitignore rules and Repomix's configuration - Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files - Only files matching these patterns are included: packages/docs/docs/core/overview.md, packages/docs/docs/quickstart.md, packages/docs/docs/core/actions.md, packages/docs/docs/core/agents.md, packages/docs/docs/core/database.md, packages/docs/docs/core/entities.md, packages/docs/docs/core/evaluators.md, packages/docs/docs/core/knowledge.md, packages/docs/docs/core/plugins.md, packages/docs/docs/core/project.md, packages/docs/docs/core/providers.md, packages/docs/docs/core/rooms.md, packages/docs/docs/core/services.md, packages/docs/docs/core/tasks.md, packages/docs/docs/core/worlds.md, packages/docs/src/openapi/eliza-v1.yaml, packages/core/src/types.ts, packages/core/src/runtime.ts, packages/core/src/bootstrap.ts, packages/core/src/database.ts, packages/core/src/actions.ts, packages/core/src/entities.ts, packages/core/src/prompts.ts, packages/core/src/uuid.ts, packages/core/src/logger.ts, packages/core/src/providers/actions.ts, packages/core/src/providers/character.ts, packages/core/src/providers/knowledge.ts, packages/core/src/providers/recentMessages.ts, packages/core/src/providers/relationships.ts, packages/core/src/providers/evaluators.ts, packages/core/src/providers/settings.ts, packages/core/src/actions/reply.ts, packages/core/src/actions/sendMessage.ts, packages/cli/src/index.ts, packages/cli/src/commands/agent.ts, packages/cli/src/commands/start.ts, packages/cli/src/commands/test.ts, packages/cli/src/commands/create.ts, packages/cli/src/commands/env.ts, packages/client/src/lib/api.ts, packages/client/src/types/index.ts, packages/client/src/hooks/use-agent-management.ts, README.md, package.json, .env.example - Files matching these patterns are excluded: **/*.test.ts, **/__tests__/**, **/node_modules/**, packages/docs/community/**, packages/docs/news/**, packages/plugin-*/**, **/*.ico, **/*.png, **/*.jpg, **/*.svg - Files matching patterns in .gitignore are excluded - Files matching default ignore patterns are excluded - Code comments have been removed from supported file types - Empty lines have been removed from all files - Content has been compressed - code blocks are separated by ⋮---- delimiter ## Additional Info ### User Provided Header ElizaOS Developer Context - Core technical components and implementation details # Directory Structure ``` packages/ cli/ src/ commands/ agent.ts create.ts env.ts start.ts test.ts index.ts client/ src/ hooks/ use-agent-management.ts lib/ api.ts types/ index.ts core/ src/ actions/ reply.ts sendMessage.ts providers/ actions.ts character.ts evaluators.ts knowledge.ts recentMessages.ts relationships.ts settings.ts actions.ts bootstrap.ts database.ts entities.ts logger.ts prompts.ts runtime.ts types.ts uuid.ts docs/ docs/ core/ actions.md agents.md database.md entities.md evaluators.md knowledge.md overview.md plugins.md project.md providers.md rooms.md services.md tasks.md worlds.md quickstart.md src/ openapi/ eliza-v1.yaml .env.example package.json README.md ``` # Files ## File: packages/cli/src/commands/agent.ts ````typescript import fs from 'node:fs'; import path from 'node:path'; import { checkServer, handleError } from '@/src/utils/handle-error'; import { displayAgent } from '@/src/utils/helpers'; import { logger } from '@elizaos/core'; import type { Agent } from '@elizaos/core'; import { Command } from 'commander'; ⋮---- // Define basic agent interface for type safety /** * Defines the structure of AgentBasic interface. * @property {string} id - The unique identifier of the agent. * @property {string} name - The name of the agent. * @property {string} [status] - The status of the agent (optional). * @property {unknown} [key] - Additional properties can be added dynamically using any key. */ interface AgentBasic { id: string; name: string; status?: string; [key: string]: unknown; } /** * Asynchronously fetches a list of basic agent information from the server. * @returns {Promise} A promise that resolves to an array of AgentBasic objects. * @throws {Error} If the fetch request fails. */ async function getAgents(): Promise // Utility function to resolve agent ID from name, index, or direct ID /** * Resolves the ID of an agent based on the provided name, ID, or index. * * @param {string} idOrNameOrIndex - The name, ID, or index of the agent to resolve. * @returns {Promise} The resolved ID of the agent. * @throws {Error} If the agent is not found. */ async function resolveAgentId(idOrNameOrIndex: string): Promise ⋮---- // First try to get all agents to find by name ⋮---- // Try to find agent by name ⋮---- // Try to find agent by ID ⋮---- // Try to find agent by index ⋮---- // If no agent is found, throw an error ⋮---- interface AgentStartPayload { characterPath?: string; characterJson?: Record; } interface ApiResponse { success: boolean; data?: T; error?: { code: string; message: string; details?: unknown; }; } ```` ## File: packages/cli/src/commands/create.ts ````typescript import { buildProject } from '@/src/utils/build-project'; import { copyTemplate } from '@/src/utils/copy-template'; import { checkServer, handleError } from '@/src/utils/handle-error'; import { runBunCommand } from '@/src/utils/run-bun'; import { logger } from '@elizaos/core'; import { Command } from 'commander'; import { execa } from 'execa'; import { existsSync, readFileSync } from 'node:fs'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import prompts from 'prompts'; import colors from 'yoctocolors'; import { z } from 'zod'; import { displayBanner } from '../displayBanner'; import { setupPgLite, promptAndStorePostgresUrl, getElizaDirectories } from '../utils/get-config'; ⋮---- async function getLocalAvailableDatabases(): Promise async function installDependencies(targetDir: string) ⋮---- // Prompt for project type if not specified ⋮---- // Move up one directory by getting the parent directory path // First get the directory containing the current .env file ⋮---- // Then move up one directory from there ```` ## File: packages/cli/src/commands/env.ts ````typescript import { existsSync } from 'node:fs'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { handleError } from '@/src/utils/handle-error'; import { logger } from '@elizaos/core'; import { Command } from 'commander'; import dotenv from 'dotenv'; import prompts from 'prompts'; import { rimraf } from 'rimraf'; import colors from 'yoctocolors'; ⋮---- async function getCustomEnvPath(): Promise async function saveCustomEnvPath(customPath: string): Promise export async function getGlobalEnvPath(): Promise function getLocalEnvPath(): string | null export async function parseEnvFile(filePath: string): Promise> async function writeEnvFile(filePath: string, envVars: Record): Promise async function listEnvVars(): Promise function maskedValue(value: string): string ⋮---- // If the value looks like a token/API key (longer than 20 chars, no spaces), mask it ⋮---- /** * Edit environment variables * @param scope Whether to edit global or local environment variables * @returns A boolean indicating whether the user wants to go back to the main menu */ async function editEnvVars(scope: 'global' | 'local', fromMainMenu = false): Promise async function addNewVariable(envPath: string, envVars: Record): Promise async function resetEnv(): Promise async function setEnvPath(customPath: string): Promise ⋮---- async function showMainMenu(): Promise ```` ## File: packages/cli/src/commands/start.ts ````typescript import { buildProject } from '@/src/utils/build-project'; import { AgentRuntime, type Character, type IAgentRuntime, type Plugin, logger, stringToUuid, encryptedCharacter, } from '@elizaos/core'; import { Command } from 'commander'; import fs from 'node:fs'; import path, { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { character, character as defaultCharacter } from '../characters/eliza'; import { AgentServer } from '../server/index'; import { jsonToCharacter, loadCharacterTryPath } from '../server/loader'; import { loadConfig, saveConfig } from '../utils/config-manager.js'; import { promptForEnvVars } from '../utils/env-prompt.js'; import { configureDatabaseSettings, loadEnvironment } from '../utils/get-config'; import { handleError } from '../utils/handle-error'; import { installPlugin } from '../utils/install-plugin'; import { displayBanner } from '../displayBanner'; ⋮---- export const wait = (minTime = 1000, maxTime = 3000) => export async function promptForProjectPlugins( project: any, pluginToLoad?: { name: string } ): Promise ⋮---- // Prompt for each identified plugin ⋮---- /** * Starts an agent with the given character, agent server, initialization function, plugins, and options. * * @param character The character object representing the agent. * @param server The agent server where the agent will be registered. * @param init Optional initialization function to be called with the agent runtime. * @param plugins An array of plugins to be used by the agent. * @param options Additional options for starting the agent, such as data directory and postgres URL. * @returns A promise that resolves to the agent runtime object. */ export async function startAgent( character: Character, server: AgentServer, init?: (runtime: IAgentRuntime) => void, plugins: Plugin[] = [], options: { dataDir?: string; postgresUrl?: string; isPluginTestMode?: boolean; } = {} ): Promise ⋮---- // For ESM modules we need to use import.meta.url instead of __dirname ⋮---- // Find package.json relative to the current file ⋮---- async function stopAgent(runtime: IAgentRuntime, server: AgentServer) const startAgents = async (options: { configure?: boolean; port?: number; characters?: Character[]; }) => ⋮---- export default function registerCommand(cli: Command) ```` ## File: packages/cli/src/commands/test.ts ````typescript import { buildProject } from '@/src/utils/build-project'; import { type IAgentRuntime, type ProjectAgent, logger } from '@elizaos/core'; import { Command } from 'commander'; ⋮---- import { existsSync } from 'node:fs'; ⋮---- import path from 'node:path'; import { loadProject } from '../project.js'; import { AgentServer } from '../server/index.js'; import { jsonToCharacter, loadCharacterTryPath } from '../server/loader'; import { TestRunner } from '../testRunner.js'; import { promptForEnvVars } from '../utils/env-prompt.js'; import { startAgent } from './start.js'; async function checkPortAvailable(port: number): Promise function checkIfLikelyPluginDir(dir: string): boolean const runAgentTests = async (options: { port?: number; plugin?: string; skipPlugins?: boolean; skipProjectTests?: boolean; skipBuild?: boolean; }) => ⋮---- export default function registerCommand(cli: Command) ```` ## File: packages/cli/src/index.ts ````typescript import fs from 'node:fs'; import path from 'node:path'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { logger } from '@elizaos/core'; import { Command } from 'commander'; import { agent } from './commands/agent'; import { create } from './commands/create'; import { dev } from './commands/dev'; import { env } from './commands/env'; import { plugin } from './commands/plugin'; import { project } from './commands/project'; import { publish } from './commands/publish'; import { start } from './commands/start'; import { teeCommand as tee } from './commands/tee'; import { test } from './commands/test'; import { update } from './commands/update'; import { loadEnvironment } from './utils/get-config'; import { displayBanner } from './displayBanner'; ⋮---- async function main() ```` ## File: packages/client/src/hooks/use-agent-management.ts ````typescript import type { Agent, UUID } from '@elizaos/core'; import { useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useStartAgent, useStopAgent } from './use-query-hooks'; import { useToast } from './use-toast'; export function useAgentManagement() ⋮---- const startAgent = async (agent: Agent) => const stopAgent = async (agent: Agent) => const isAgentStarting = (agentId: UUID | undefined | null) => const isAgentStopping = (agentId: UUID | undefined | null) => ```` ## File: packages/client/src/lib/api.ts ````typescript import type { Agent, Character, UUID, Memory } from '@elizaos/core'; import { WorldManager } from './world-manager'; ⋮---- const fetcher = async ({ url, method, body, headers, }: { url: string; method?: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH'; body?: object | FormData; headers?: HeadersInit; }) => interface LogEntry { level: number; time: number; msg: string; [key: string]: string | number | boolean | null | undefined; } interface LogResponse { logs: LogEntry[]; count: number; total: number; level: string; levels: string[]; } interface AgentLog { id?: string; type?: string; timestamp?: number; message?: string; details?: string; roomId?: string; [key: string]: any; } ```` ## File: packages/client/src/types/index.ts ````typescript export interface IAttachment { url: string; contentType: string; title: string; } ```` ## File: packages/core/src/actions/reply.ts ````typescript import { composePromptFromState, parseJSONObjectFromText } from '../prompts'; import { type Action, type ActionExample, type Content, type HandlerCallback, type IAgentRuntime, type Memory, ModelType, type State, } from '../types'; ```` ## File: packages/core/src/actions/sendMessage.ts ````typescript import { findEntityByName } from '../entities'; import { logger } from '../logger'; import { composePromptFromState, parseJSONObjectFromText } from '../prompts'; import { type Action, type ActionExample, type HandlerCallback, type IAgentRuntime, type Memory, ModelType, type State, } from '../types'; ```` ## File: packages/core/src/providers/actions.ts ````typescript import { composeActionExamples, formatActionNames, formatActions } from '../actions'; import { addHeader } from '../prompts'; import type { Action, IAgentRuntime, Memory, Provider, State } from '../types'; ⋮---- // Combine all text sections ```` ## File: packages/core/src/providers/character.ts ````typescript import { addHeader } from '../prompts'; import { ChannelType, type IAgentRuntime, type Memory, type Provider, type State } from '../types'; ⋮---- // System prompt ⋮---- // Select random topic if available ⋮---- // Format topics list ⋮---- // Select random adjective if available ⋮---- // Format post examples ⋮---- // Format message examples ⋮---- // Style directions ⋮---- // Combine all text sections ```` ## File: packages/core/src/providers/evaluators.ts ````typescript import { names, uniqueNamesGenerator } from 'unique-names-generator'; import { addHeader } from '../prompts'; import type { ActionExample, State } from '../types'; import type { Evaluator, IAgentRuntime, Memory, Provider } from '../types'; export function formatEvaluatorNames(evaluators: Evaluator[]) export function formatEvaluatorExamples(evaluators: Evaluator[]) export function formatEvaluators(evaluators: Evaluator[]) ⋮---- // Combine all text sections ```` ## File: packages/core/src/providers/knowledge.ts ````typescript import { addHeader } from '../prompts'; import type { IAgentRuntime, Memory, Provider } from '../types'; ```` ## File: packages/core/src/providers/recentMessages.ts ````typescript import { getEntityDetails } from '../entities'; import { addHeader, formatMessages, formatPosts } from '../prompts'; import { ChannelType, CustomMetadata, type Entity, type IAgentRuntime, type Memory, type Provider, type UUID, } from '../types'; const getRecentInteractions = async ( runtime: IAgentRuntime, sourceEntityId: UUID, targetEntityId: UUID, excludeRoomId: UUID ): Promise => ⋮---- // Preload all necessary entities for both types of interactions ⋮---- // Only proceed if there are interactions to process ⋮---- // Get unique entity IDs that aren't the runtime agent ⋮---- // Create a Set for faster lookup ⋮---- // Add entities already fetched in entitiesData to the map ⋮---- // Get the remaining entities that weren't already loaded // Use Set difference for efficient filtering ⋮---- // Only fetch the entities we don't already have ⋮---- // Format recent message interactions const getRecentMessageInteractions = async ( recentInteractionsData: Memory[] ): Promise => ⋮---- // Format messages using the pre-fetched entities ⋮---- const getRecentPostInteractions = async ( recentInteractionsData: Memory[], entities: Entity[] ): Promise => ```` ## File: packages/core/src/providers/relationships.ts ````typescript import type { Entity, IAgentRuntime, Memory, Provider, Relationship, UUID } from '../types'; async function formatRelationships(runtime: IAgentRuntime, relationships: Relationship[]) ⋮---- // Deduplicate target entity IDs to avoid redundant fetches ⋮---- // Fetch all required entities in a single batch operation ⋮---- // Create a lookup map for efficient access ⋮---- const formatMetadata = (metadata: any) => // Format relationships using the entity map ```` ## File: packages/core/src/providers/settings.ts ````typescript import { logger } from '../logger'; import { findWorldForOwner } from '../roles'; import { getWorldSettings } from '../settings'; import { ChannelType, type IAgentRuntime, type Memory, type Provider, type ProviderResult, type Setting, type State, type WorldSettings, } from '../types'; const formatSettingValue = (setting: Setting, isOnboarding: boolean): string => function generateStatusMessage( runtime: IAgentRuntime, worldSettings: WorldSettings, isOnboarding: boolean, state?: State ): string ⋮---- // Skip settings that should be hidden based on visibility function ⋮---- // Count required settings that are not configured ⋮---- // Generate appropriate message ⋮---- /** * Creates an settings provider with the given configuration * Updated to use world metadata instead of cache */ ⋮---- // Parallelize the initial database operations to improve performance // These operations can run simultaneously as they don't depend on each other ⋮---- // In onboarding mode, use the user's world directly ⋮---- // Fetch world settings based on the server ID ⋮---- // For non-onboarding, we need to get the world associated with the room ⋮---- // Once we have the serverId, get the settings ⋮---- // If no server found after recovery attempts ```` ## File: packages/core/src/actions.ts ````typescript import { names, uniqueNamesGenerator } from 'unique-names-generator'; import type { Action, ActionExample } from './types'; export const composeActionExamples = (actionsData: Action[], count: number) => /** * Formats the names of the provided actions into a comma-separated string. * @param actions - An array of `Action` objects from which to extract names. * @returns A comma-separated string of action names. */ export function formatActionNames(actions: Action[]) export function formatActions(actions: Action[]) ```` ## File: packages/core/src/bootstrap.ts ````typescript import type { UUID } from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; import { v4 } from 'uuid'; import { choiceAction } from './actions/choice'; import { followRoomAction } from './actions/followRoom'; import { ignoreAction } from './actions/ignore'; import { muteRoomAction } from './actions/muteRoom'; import { noneAction } from './actions/none'; import { replyAction } from './actions/reply'; import updateRoleAction from './actions/roles'; import { sendMessageAction } from './actions/sendMessage'; import updateSettingsAction from './actions/settings'; import { unfollowRoomAction } from './actions/unfollowRoom'; import { unmuteRoomAction } from './actions/unmuteRoom'; import { updateEntityAction } from './actions/updateEntity'; import { createUniqueUuid } from './entities'; import { reflectionEvaluator } from './evaluators/reflection'; import { logger } from './logger'; import { composePrompt, composePromptFromState, messageHandlerTemplate, parseJSONObjectFromText, postCreationTemplate, shouldRespondTemplate, truncateToCompleteSentence, } from './prompts'; import { actionsProvider } from './providers/actions'; import { anxietyProvider } from './providers/anxiety'; import { attachmentsProvider } from './providers/attachments'; import { capabilitiesProvider } from './providers/capabilities'; import { characterProvider } from './providers/character'; import { choiceProvider } from './providers/choice'; import { entitiesProvider } from './providers/entities'; import { evaluatorsProvider } from './providers/evaluators'; import { factsProvider } from './providers/facts'; import { knowledgeProvider } from './providers/knowledge'; import { providersProvider } from './providers/providers'; import { recentMessagesProvider } from './providers/recentMessages'; import { relationshipsProvider } from './providers/relationships'; import { roleProvider } from './providers/roles'; import { settingsProvider } from './providers/settings'; import { timeProvider } from './providers/time'; import { ScenarioService } from './services/scenario'; import { TaskService } from './services/task'; import { type ActionEventPayload, ChannelType, type Content, type Entity, type EntityPayload, type EvaluatorEventPayload, EventType, type HandlerCallback, type IAgentRuntime, type InvokePayload, type Media, type Memory, type MessagePayload, ModelType, type MessageReceivedHandlerParams, type Plugin, type WorldPayload, asUUID, } from './types'; type MediaData = { data: Buffer; mediaType: string; }; ⋮---- export async function fetchMediaData(attachments: Media[]): Promise const messageReceivedHandler = async ({ runtime, message, callback, onComplete, }: MessageReceivedHandlerParams): Promise => const reactionReceivedHandler = async ({ runtime, message, }: { runtime: IAgentRuntime; message: Memory; }) => const postGeneratedHandler = async ({ runtime, callback, worldId, userId, roomId, }: InvokePayload) => ⋮---- function cleanupTweetText(text: string): string ⋮---- // Fix newlines ⋮---- // Truncate to Twitter's character limit (280) ⋮---- // Cleanup the tweet text ⋮---- // Prepare media if included // const mediaData: MediaData[] = []; // if (jsonResponse.imagePrompt) { // const images = await runtime.useModel(ModelType.IMAGE, { // prompt: jsonResponse.imagePrompt, // output: "no-schema", ⋮---- const syncSingleUser = async ( entityId: UUID, runtime: IAgentRuntime, serverId: string, channelId: string, type: ChannelType, source: string ) => const handleServerSync = async ( ```` ## File: packages/core/src/database.ts ````typescript import type { Agent, Component, Entity, IDatabaseAdapter, Log, Memory, Participant, Relationship, Room, Task, UUID, World, MemoryMetadata, } from './types'; export abstract class DatabaseAdapter implements IDatabaseAdapter ⋮---- abstract init(): Promise; abstract close(): Promise; abstract getEntityById(entityId: UUID): Promise; abstract getEntitiesForRoom(roomId: UUID, includeComponents?: boolean): Promise; abstract createEntity(entity: Entity): Promise; abstract updateEntity(entity: Entity): Promise; abstract getComponent( entityId: UUID, type: string, worldId?: UUID, sourceEntityId?: UUID ): Promise; abstract getComponents( entityId: UUID, worldId?: UUID, sourceEntityId?: UUID ): Promise; abstract createComponent(component: Component): Promise; abstract updateComponent(component: Component): Promise; abstract deleteComponent(componentId: UUID): Promise; abstract getMemories(params: { entityId?: UUID; agentId?: UUID; roomId?: UUID; count?: number; unique?: boolean; tableName: string; start?: number; end?: number; }): Promise; abstract getMemoriesByRoomIds(params: { roomIds: UUID[]; tableName: string; limit?: number; }): Promise; abstract getMemoryById(id: UUID): Promise; abstract getMemoriesByIds(memoryIds: UUID[], tableName?: string): Promise; abstract getCachedEmbeddings( abstract log(params: { body: { [key: string]: unknown }; entityId: UUID; roomId: UUID; type: string; }): Promise; abstract getLogs(params: { entityId: UUID; roomId?: UUID; type?: string; count?: number; offset?: number; }): Promise; abstract deleteLog(logId: UUID): Promise; abstract searchMemories(params: { tableName: string; roomId: UUID; embedding: number[]; match_threshold: number; count: number; unique: boolean; }): Promise; abstract createMemory(memory: Memory, tableName: string, unique?: boolean): Promise; abstract updateMemory( memory: Partial & { id: UUID; metadata?: MemoryMetadata } ): Promise; abstract deleteMemory(memoryId: UUID): Promise; abstract deleteAllMemories(roomId: UUID, tableName: string): Promise; abstract countMemories(roomId: UUID, unique?: boolean, tableName?: string): Promise; abstract getWorld(id: UUID): Promise; abstract getAllWorlds(): Promise; abstract createWorld(world: World): Promise; abstract updateWorld(world: World): Promise; abstract removeWorld(id: UUID): Promise; abstract getRoom(roomId: UUID): Promise; abstract getRooms(worldId: UUID): Promise; abstract createRoom( abstract updateRoom(room: Room): Promise; abstract deleteRoom(roomId: UUID): Promise; abstract getRoomsForParticipant(entityId: UUID): Promise; abstract getRoomsForParticipants(userIds: UUID[]): Promise; abstract addParticipant(entityId: UUID, roomId: UUID): Promise; abstract removeParticipant(entityId: UUID, roomId: UUID): Promise; abstract getParticipantsForEntity(entityId: UUID): Promise; abstract getParticipantsForRoom(roomId: UUID): Promise; abstract getParticipantUserState( roomId: UUID, entityId: UUID ): Promise<'FOLLOWED' | 'MUTED' | null>; abstract setParticipantUserState( roomId: UUID, entityId: UUID, state: 'FOLLOWED' | 'MUTED' | null ): Promise; abstract createRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; tags?: string[]; metadata?: Record; }): Promise; abstract getRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; }): Promise; abstract getRelationships(params: abstract updateRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; tags?: string[]; metadata?: Record; }): Promise; abstract getAgent(agentId: UUID): Promise; abstract getAgents(): Promise; abstract createAgent(agent: Partial): Promise; abstract updateAgent(agentId: UUID, agent: Partial): Promise; abstract deleteAgent(agentId: UUID): Promise; abstract ensureAgentExists(agent: Partial): Promise; abstract ensureEmbeddingDimension(dimension: number): Promise; abstract getCache(key: string): Promise; abstract setCache(key: string, value: T): Promise; abstract deleteCache(key: string): Promise; abstract createTask(task: Task): Promise; abstract getTasks(params: abstract getTask(id: UUID): Promise; abstract getTasksByName(name: string): Promise; abstract updateTask(id: UUID, task: Partial): Promise; abstract deleteTask(id: UUID): Promise; ```` ## File: packages/core/src/entities.ts ````typescript import { logger, stringToUuid } from './index'; import { composePrompt, parseJSONObjectFromText } from './prompts'; import { type Entity, type IAgentRuntime, type Memory, ModelType, type Relationship, type State, type UUID, } from './types'; ⋮---- async function getRecentInteractions( runtime: IAgentRuntime, sourceEntityId: UUID, candidateEntities: Entity[], roomId: UUID, relationships: Relationship[] ): Promise< export async function findEntityByName( runtime: IAgentRuntime, message: Memory, state: State ): Promise export const createUniqueUuid = (runtime, baseUserId: UUID | string): UUID => export async function getEntityDetails({ runtime, roomId, }: { runtime: IAgentRuntime; roomId: UUID; }) export function formatEntities( ```` ## File: packages/core/src/logger.ts ````typescript import pino, { type LogFn, type DestinationStream } from 'pino'; function parseBooleanFromText(value: string | undefined | null): boolean interface LogEntry { time?: number; [key: string]: unknown; } class InMemoryDestination implements DestinationStream ⋮---- constructor(stream: DestinationStream | null) write(data: string | LogEntry): void ⋮---- // Filter only service/agent registration logs, not all agent logs ⋮---- recentLogs(): LogEntry[] clear(): void ⋮---- const createPrettyConfig = () => ( const createStream = async () => ⋮---- logMethod(inputArgs: [string | Record, ...unknown[]], method: LogFn): void ⋮---- const formatError = (err: Error) => ( ⋮---- interface LoggerWithClear extends pino.Logger { clear: () => void; } ```` ## File: packages/core/src/prompts.ts ````typescript import handlebars from 'handlebars'; import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter'; import { names, uniqueNamesGenerator } from 'unique-names-generator'; import logger from './logger'; import type { Content, Entity, IAgentRuntime, Memory, State, TemplateType } from './types'; import { ModelType } from './types'; export const composePrompt = ({ state, template, }: { state: { [key: string]: string }; template: TemplateType; }) => export const composePromptFromState = ({ state, template, }: { state: State; template: TemplateType; }) => export const addHeader = (header: string, body: string) => /** * Generates a string with random user names populated in a template. * * This function generates random user names and populates placeholders * in the provided template with these names. Placeholders in the template should follow the format `{{userX}}` * where `X` is the position of the user (e.g., `{{name1}}`, `{{name2}}`). * * @param {string} template - The template string containing placeholders for random user names. * @param {number} length - The number of random user names to generate. * @returns {string} The template string with placeholders replaced by random user names. * * @example * // Given a template and a length * const template = "Hello, {{name1}}! Meet {{name2}} and {{name3}}."; * const length = 3; * * // Composing the random user string will result in: * // "Hello, John! Meet Alice and Bob." * const result = composeRandomUser(template, length); */ export const composeRandomUser = (template: string, length: number) => export const formatPosts = ({ messages, entities, conversationHeader = true, }: { messages: Memory[]; entities: Entity[]; conversationHeader?: boolean; }) => ⋮---- // Group messages by roomId ⋮---- // Sort messages within each roomId by createdAt (oldest to newest) ⋮---- // Sort rooms by the newest message's createdAt ⋮---- /** * Format messages into a string * @param {Object} params - The formatting parameters * @param {Memory[]} params.messages - List of messages to format * @param {Entity[]} params.entities - List of entities for name resolution * @returns {string} Formatted message string with timestamps and user information */ export const formatMessages = ({ messages, entities, }: { messages: Memory[]; entities: Entity[]; }) => ⋮---- // const shortId = message.entityId.slice(-5); ⋮---- // for each thought, action, text or attachment, add a new line, with text first, then thought, then action, then attachment ⋮---- export const formatTimestamp = (messageDate: number) => ⋮---- /** * Parses a string to determine its boolean equivalent. * * Recognized affirmative values: "YES", "Y", "TRUE", "T", "1", "ON", "ENABLE" * Recognized negative values: "NO", "N", "FALSE", "F", "0", "OFF", "DISABLE" * * @param {string | undefined | null} value - The input text to parse * @returns {boolean} - Returns `true` for affirmative inputs, `false` for negative or unrecognized inputs */ export function parseBooleanFromText(value: string | undefined | null): boolean ⋮---- export function parseJsonArrayFromText(text: string) ⋮---- // Only replace quotes that are actually being used for string delimitation ⋮---- export function parseJSONObjectFromText(text: string): Record | null export function extractAttributes( response: string, attributesToExtract?: string[] ): export const normalizeJsonString = (str: string) => ⋮---- // "key": someWord → "key": "someWord" ⋮---- // Replace adjacent quote pairs with a single double quote ⋮---- /** * Cleans a JSON-like response string by removing unnecessary markers, line breaks, and extra whitespace. * This is useful for handling improperly formatted JSON responses from external sources. * * @param response - The raw JSON-like string response to clean. * @returns The cleaned string, ready for parsing or further processing. */ export function cleanJsonResponse(response: string): string ⋮---- .replace(/```json\s*/g, '') // Remove ```json .replace(/```\s*/g, '') // Remove any remaining ``` .replace(/(\r\n|\n|\r)/g, '') // Remove line breaks ⋮---- type ActionResponse = { like: boolean; retweet: boolean; quote?: boolean; reply?: boolean; }; export const parseActionResponseFromText = (text: string): ⋮---- // Regex patterns ⋮---- // Check with regex ⋮---- // Also do line by line parsing as backup ⋮---- export function truncateToCompleteSentence(text: string, maxLength: number): string ⋮---- export async function splitChunks(content: string, chunkSize = 512, bleed = 20): Promise export async function trimTokens(prompt: string, maxTokens: number, runtime: IAgentRuntime) ```` ## File: packages/core/src/runtime.ts ````typescript import { v4 as uuidv4 } from 'uuid'; import { bootstrapPlugin } from './bootstrap'; import { createUniqueUuid } from './entities'; import { decryptSecret, getSalt, handlePluginImporting } from './index'; import logger from './logger'; import { splitChunks } from './prompts'; import { ChannelType, MemoryType, ModelType } from './types'; import type { Action, Agent, Character, Component, Entity, Evaluator, HandlerCallback, IAgentRuntime, IDatabaseAdapter, KnowledgeItem, Log, Memory, MemoryMetadata, ModelParamsMap, ModelResultMap, ModelTypeName, Participant, Plugin, Provider, Relationship, Room, Route, Service, ServiceTypeName, State, Task, TaskWorker, UUID, World, } from './types'; import { stringToUuid } from './uuid'; import fs from 'node:fs'; import path from 'node:path'; interface Settings { [key: string]: string | undefined; } interface NamespacedSettings { [namespace: string]: Settings; } ⋮---- export function loadEnvConfig(): Settings ⋮---- function findNearestEnvFile(startDir = process.cwd()) ⋮---- function parseNamespacedSettings(env: Settings): NamespacedSettings export class Semaphore ⋮---- constructor(count: number) async acquire(): Promise release(): void ⋮---- export class AgentRuntime implements IAgentRuntime ⋮---- constructor(opts: { conversationLength?: number; agentId?: UUID; character?: Character; plugins?: Plugin[]; fetch?: typeof fetch; adapter?: IDatabaseAdapter; events?: async registerPlugin(plugin: Plugin): Promise getAllServices(): Map async stop() async initialize() private async handleProcessingError(error: any, context: string) private async checkExistingKnowledge(knowledgeId: UUID): Promise async getKnowledge(message: Memory): Promise async addKnowledge( item: KnowledgeItem, options = { targetTokens: 3000, overlap: 200, modelContextSize: 4096, } ) async processCharacterKnowledge(items: string[]) setSetting(key: string, value: string | boolean | null | any, secret = false) getSetting(key: string): string | boolean | null | any /** * Get the number of messages that are kept in the conversation buffer. * @returns The number of recent messages to be kept in memory. */ getConversationLength() registerDatabaseAdapter(adapter: IDatabaseAdapter) /** * Register a provider for the agent to use. * @param provider The provider to register. */ registerProvider(provider: Provider) /** * Register an action for the agent to perform. * @param action The action to register. */ registerAction(action: Action) ⋮---- // if an action with the same name already exists, throw a warning and don't add the new action ⋮---- /** * Register an evaluator to assess and guide the agent's responses. * @param evaluator The evaluator to register. */ registerEvaluator(evaluator: Evaluator) /** * Register a context provider to provide context for message generation. * @param provider The context provider to register. */ registerContextProvider(provider: Provider) /** * Process the actions of a message. * @param message The message to process. * @param responses The array of response memories to process actions from. * @param state Optional state object for the action processing. * @param callback Optional callback handler for action results. */ async processActions( message: Memory, responses: Memory[], state?: State, callback?: HandlerCallback ): Promise ⋮---- function normalizeAction(action: string) ⋮---- normalizeAction(a.name).includes(normalizedResponseAction) || // the || is kind of a fuzzy match normalizedResponseAction.includes(normalizeAction(a.name)) // ⋮---- // log to database ⋮---- /** * Evaluate the message and state using the registered evaluators. * @param message The message to evaluate. * @param state The state of the agent. * @param didRespond Whether the agent responded to the message.~ * @param callback The handler callback * @returns The results of the evaluation. */ async evaluate( message: Memory, state: State, didRespond?: boolean, callback?: HandlerCallback, responses?: Memory[] ) ⋮---- // get the evaluators that were chosen by the response handler ⋮---- // log to database ⋮---- async ensureConnection({ entityId, roomId, userName, name, source, type, channelId, serverId, worldId, }: { entityId: UUID; roomId: UUID; userName?: string; name?: string; source?: string; type?: ChannelType; channelId?: string; serverId?: string; worldId?: UUID; }) ⋮---- // Step 1: Handle entity creation/update with proper error handling ⋮---- // First check if the entity exists ⋮---- // Try to create the entity ⋮---- // If we get a duplicate key error, the entity exists in the database but isn't // associated with this agent - this is expected in multi-agent scenarios ⋮---- // For any other errors, re-throw ⋮---- // Entity exists for this agent, update if needed ⋮---- // Step 2: Ensure world exists ⋮---- // Step 3: Ensure room exists ⋮---- // Step 4: Add participants to the room // For the user entity, we'll try even if we couldn't retrieve it ⋮---- // If the normal flow fails because the entity isn't found, // try direct participant addition as a clean fallback ⋮---- async ensureParticipantInRoom(entityId: UUID, roomId: UUID) async removeParticipant(entityId: UUID, roomId: UUID): Promise async getParticipantsForEntity(entityId: UUID): Promise async getParticipantsForRoom(roomId: UUID): Promise async addParticipant(entityId: UUID, roomId: UUID): Promise async ensureWorldExists( async ensureRoomExists( async composeState( message: Memory, filterList: string[] | null = null, includeList: string[] | null = null ): Promise ⋮---- // Get existing provider names from cache (if any) ⋮---- // Step 1: Determine base set of providers to fetch ⋮---- // If filter list provided, start with just those providers ⋮---- // Otherwise, start with all non-private, non-dynamic providers that aren't cached ⋮---- // Prepare final values ⋮---- // Safely merge all provider values ⋮---- getService(service: ServiceTypeName): T | null async registerService(service: typeof Service): Promise registerModel(modelType: ModelTypeName, handler: (params: any) => Promise) getModel( modelType: ModelTypeName ): ((runtime: IAgentRuntime, params: any) => Promise) | undefined async useModel( modelType: T, params: Omit | any ): Promise registerEvent(event: string, handler: (params: any) => Promise) getEvent(event: string): ((params: any) => Promise)[] | undefined async emitEvent(event: string | string[], params: any) async ensureEmbeddingDimension() registerTaskWorker(taskHandler: TaskWorker): void getTaskWorker(name: string): TaskWorker | undefined get db(): any async init(): Promise async close(): Promise async getAgent(agentId: UUID): Promise async getAgents(): Promise async createAgent(agent: Partial): Promise async updateAgent(agentId: UUID, agent: Partial): Promise async deleteAgent(agentId: UUID): Promise async ensureAgentExists(agent: Partial): Promise async getEntityById(entityId: UUID): Promise async getEntitiesForRoom(roomId: UUID, includeComponents?: boolean): Promise async createEntity(entity: Entity): Promise async updateEntity(entity: Entity): Promise async getComponent( entityId: UUID, type: string, worldId?: UUID, sourceEntityId?: UUID ): Promise async getComponents(entityId: UUID, worldId?: UUID, sourceEntityId?: UUID): Promise async createComponent(component: Component): Promise async updateComponent(component: Component): Promise async deleteComponent(componentId: UUID): Promise async addEmbeddingToMemory(memory: Memory): Promise async getMemories(params: { entityId?: UUID; agentId?: UUID; roomId?: UUID; count?: number; unique?: boolean; tableName: string; start?: number; end?: number; }): Promise async getMemoryById(id: UUID): Promise async getMemoriesByIds(ids: UUID[], tableName?: string): Promise async getMemoriesByRoomIds(params: { tableName: string; roomIds: UUID[]; limit?: number; }): Promise async getCachedEmbeddings(params: { query_table_name: string; query_threshold: number; query_input: string; query_field_name: string; query_field_sub_name: string; query_match_count: number; }): Promise< async log(params: { body: { [key: string]: unknown }; entityId: UUID; roomId: UUID; type: string; }): Promise async searchMemories(params: { embedding: number[]; match_threshold?: number; count?: number; roomId?: UUID; unique?: boolean; tableName: string; }): Promise async createMemory(memory: Memory, tableName: string, unique?: boolean): Promise async updateMemory( memory: Partial & { id: UUID; metadata?: MemoryMetadata } ): Promise async deleteMemory(memoryId: UUID): Promise async deleteAllMemories(roomId: UUID, tableName: string): Promise async countMemories(roomId: UUID, unique?: boolean, tableName?: string): Promise async getLogs(params: { entityId: UUID; roomId?: UUID; type?: string; count?: number; offset?: number; }): Promise async deleteLog(logId: UUID): Promise async createWorld(world: World): Promise async getWorld(id: UUID): Promise async getAllWorlds(): Promise async updateWorld(world: World): Promise async getRoom(roomId: UUID): Promise async createRoom( async deleteRoom(roomId: UUID): Promise async updateRoom(room: Room): Promise async getRoomsForParticipant(entityId: UUID): Promise async getRoomsForParticipants(userIds: UUID[]): Promise async getRooms(worldId: UUID): Promise async getParticipantUserState( roomId: UUID, entityId: UUID ): Promise<'FOLLOWED' | 'MUTED' | null> async setParticipantUserState( roomId: UUID, entityId: UUID, state: 'FOLLOWED' | 'MUTED' | null ): Promise async createRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; tags?: string[]; metadata?: { [key: string]: any }; }): Promise async updateRelationship(relationship: Relationship): Promise async getRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; }): Promise async getRelationships(params: async getCache(key: string): Promise async setCache(key: string, value: T): Promise async deleteCache(key: string): Promise async createTask(task: Task): Promise async getTasks(params: async getTask(id: UUID): Promise async getTasksByName(name: string): Promise async updateTask(id: UUID, task: Partial): Promise async deleteTask(id: UUID): Promise on(event: string, callback: (data: any) => void): void off(event: string, callback: (data: any) => void): void emit(event: string, data: any): void ```` ## File: packages/core/src/types.ts ````typescript import type { Readable } from 'node:stream'; export type UUID = `${string}-${string}-${string}-${string}-${string}`; export function asUUID(id: string): UUID export interface Content { thought?: string; text?: string; actions?: string[]; providers?: string[]; source?: string; url?: string; inReplyTo?: UUID; attachments?: Media[]; [key: string]: unknown; } export interface ActionExample { name: string; content: Content; } export type ModelTypeName = (typeof ModelType)[keyof typeof ModelType] | string; ⋮---- export type ServiceTypeName = (typeof ServiceType)[keyof typeof ServiceType]; ⋮---- export interface State { [key: string]: any; values: { [key: string]: any; }; data: { [key: string]: any; }; text: string; } export type MemoryTypeAlias = string; export enum MemoryType { DOCUMENT = 'document', FRAGMENT = 'fragment', MESSAGE = 'message', DESCRIPTION = 'description', CUSTOM = 'custom', } export type MemoryScope = 'shared' | 'private' | 'room'; export interface BaseMetadata { type: MemoryTypeAlias; source?: string; sourceId?: UUID; scope?: MemoryScope; timestamp?: number; tags?: string[]; } export interface DocumentMetadata extends BaseMetadata { type: MemoryType.DOCUMENT; } export interface FragmentMetadata extends BaseMetadata { type: MemoryType.FRAGMENT; documentId: UUID; position: number; } export interface MessageMetadata extends BaseMetadata { type: MemoryType.MESSAGE; } export interface DescriptionMetadata extends BaseMetadata { type: MemoryType.DESCRIPTION; } export interface CustomMetadata extends BaseMetadata { [key: string]: unknown; } export type MemoryMetadata = | DocumentMetadata | FragmentMetadata | MessageMetadata | DescriptionMetadata | CustomMetadata; export interface Memory { id?: UUID; entityId: UUID; agentId?: UUID; createdAt?: number; content: Content; embedding?: number[]; roomId: UUID; unique?: boolean; similarity?: number; metadata?: MemoryMetadata; } export interface Log { id?: UUID; entityId: UUID; roomId?: UUID; body: { [key: string]: unknown }; type: string; createdAt: Date; } export interface MessageExample { name: string; content: Content; } export type Handler = ( runtime: IAgentRuntime, message: Memory, state?: State, options?: { [key: string]: unknown }, callback?: HandlerCallback, responses?: Memory[] ) => Promise; export type HandlerCallback = (response: Content, files?: any) => Promise; export type Validator = ( runtime: IAgentRuntime, message: Memory, state?: State ) => Promise; export interface Action { similes?: string[]; description: string; examples?: ActionExample[][]; handler: Handler; name: string; validate: Validator; } export interface EvaluationExample { prompt: string; messages: Array; outcome: string; } export interface Evaluator { alwaysRun?: boolean; description: string; similes?: string[]; examples: EvaluationExample[]; handler: Handler; name: string; validate: Validator; } export interface ProviderResult { values?: { [key: string]: any; }; data?: { [key: string]: any; }; text?: string; } export interface Provider { name: string; description?: string; dynamic?: boolean; position?: number; private?: boolean; get: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; } export interface Relationship { id: UUID; sourceEntityId: UUID; targetEntityId: UUID; agentId: UUID; tags: string[]; metadata: { [key: string]: any; }; createdAt?: string; } export interface Component { id: UUID; entityId: UUID; agentId: UUID; roomId: UUID; worldId: UUID; sourceEntityId: UUID; type: string; data: { [key: string]: any; }; } export interface Entity { id?: UUID; names: string[]; metadata?: { [key: string]: any }; agentId: UUID; components?: Component[]; } export type World = { id: UUID; name?: string; agentId: UUID; serverId: string; metadata?: { ownership?: { ownerId: string; }; roles?: { [entityId: UUID]: Role; }; [key: string]: unknown; }; }; export type Room = { id: UUID; name?: string; agentId?: UUID; source: string; type: ChannelType; channelId?: string; serverId?: string; worldId?: UUID; metadata?: Record; }; export interface Participant { id: UUID; entity: Entity; } export type Media = { id: string; url: string; title: string; source: string; description: string; text: string; contentType?: string; }; export enum ChannelType { SELF = 'SELF', DM = 'dm', GROUP = 'group', VOICE_DM = 'VOICE_DM', VOICE_GROUP = 'VOICE_GROUP', FEED = 'FEED', THREAD = 'THREAD', WORLD = 'WORLD', FORUM = 'FORUM', API = 'API', } export abstract class Service ⋮---- constructor(runtime?: IAgentRuntime) abstract stop(): Promise; ⋮---- static async start(_runtime: IAgentRuntime): Promise static async stop(_runtime: IAgentRuntime): Promise ⋮---- export type Route = { type: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'STATIC'; path: string; filePath?: string; handler?: (req: any, res: any, runtime: IAgentRuntime) => Promise; }; export interface Plugin { name: string; description: string; init?: (config: Record, runtime: IAgentRuntime) => Promise; config?: { [key: string]: any }; services?: (typeof Service)[]; componentTypes?: { name: string; schema: Record; validator?: (data: any) => boolean; }[]; actions?: Action[]; providers?: Provider[]; evaluators?: Evaluator[]; adapter?: IDatabaseAdapter; models?: { [key: string]: (...args: any[]) => Promise; }; events?: { [K in keyof EventPayloadMap]?: EventHandler[]; } & { [key: string]: ((params: EventPayload) => Promise)[]; }; routes?: Route[]; tests?: TestSuite[]; } export interface ProjectAgent { character: Character; init?: (runtime: IAgentRuntime) => Promise; plugins?: Plugin[]; tests?: TestSuite | TestSuite[]; } export interface Project { agents: ProjectAgent[]; } export type TemplateType = | string | ((options: { state: State | { [key: string]: string } }) => string); export interface Character { id?: UUID; name: string; username?: string; system?: string; templates?: { [key: string]: TemplateType; }; bio: string | string[]; messageExamples?: MessageExample[][]; postExamples?: string[]; topics?: string[]; adjectives?: string[]; knowledge?: (string | { path: string; shared?: boolean })[]; plugins?: string[]; settings?: { [key: string]: any | string | boolean | number; }; secrets?: { [key: string]: string | boolean | number; }; style?: { all?: string[]; chat?: string[]; post?: string[]; }; } export enum AgentStatus { ACTIVE = 'active', INACTIVE = 'inactive', } export interface Agent extends Character { enabled?: boolean; status?: AgentStatus; createdAt: number; updatedAt: number; } export interface IDatabaseAdapter { db: any; init(): Promise; close(): Promise; getAgent(agentId: UUID): Promise; getAgents(): Promise; createAgent(agent: Partial): Promise; updateAgent(agentId: UUID, agent: Partial): Promise; deleteAgent(agentId: UUID): Promise; ensureAgentExists(agent: Partial): Promise; ensureEmbeddingDimension(dimension: number): Promise; getEntityById(entityId: UUID): Promise; getEntitiesForRoom(roomId: UUID, includeComponents?: boolean): Promise; createEntity(entity: Entity): Promise; updateEntity(entity: Entity): Promise; getComponent( entityId: UUID, type: string, worldId?: UUID, sourceEntityId?: UUID ): Promise; getComponents(entityId: UUID, worldId?: UUID, sourceEntityId?: UUID): Promise; createComponent(component: Component): Promise; updateComponent(component: Component): Promise; deleteComponent(componentId: UUID): Promise; getMemories(params: { entityId?: UUID; agentId?: UUID; roomId?: UUID; count?: number; unique?: boolean; tableName: string; start?: number; end?: number; }): Promise; getMemoryById(id: UUID): Promise; getMemoriesByIds(ids: UUID[], tableName?: string): Promise; getMemoriesByRoomIds(params: { tableName: string; roomIds: UUID[]; limit?: number; }): Promise; getCachedEmbeddings(params: { query_table_name: string; query_threshold: number; query_input: string; query_field_name: string; query_field_sub_name: string; query_match_count: number; }): Promise<{ embedding: number[]; levenshtein_score: number }[]>; log(params: { body: { [key: string]: unknown }; entityId: UUID; roomId: UUID; type: string; }): Promise; getLogs(params: { entityId: UUID; roomId?: UUID; type?: string; count?: number; offset?: number; }): Promise; deleteLog(logId: UUID): Promise; searchMemories(params: { embedding: number[]; match_threshold?: number; count?: number; roomId?: UUID; unique?: boolean; tableName: string; }): Promise; createMemory(memory: Memory, tableName: string, unique?: boolean): Promise; updateMemory(memory: Partial & { id: UUID; metadata?: MemoryMetadata }): Promise; deleteMemory(memoryId: UUID): Promise; deleteAllMemories(roomId: UUID, tableName: string): Promise; countMemories(roomId: UUID, unique?: boolean, tableName?: string): Promise; createWorld(world: World): Promise; getWorld(id: UUID): Promise; getAllWorlds(): Promise; updateWorld(world: World): Promise; getRoom(roomId: UUID): Promise; createRoom({ id, name, source, type, channelId, serverId, worldId }: Room): Promise; deleteRoom(roomId: UUID): Promise; updateRoom(room: Room): Promise; getRoomsForParticipant(entityId: UUID): Promise; getRoomsForParticipants(userIds: UUID[]): Promise; getRooms(worldId: UUID): Promise; addParticipant(entityId: UUID, roomId: UUID): Promise; removeParticipant(entityId: UUID, roomId: UUID): Promise; getParticipantsForEntity(entityId: UUID): Promise; getParticipantsForRoom(roomId: UUID): Promise; getParticipantUserState(roomId: UUID, entityId: UUID): Promise<'FOLLOWED' | 'MUTED' | null>; setParticipantUserState( roomId: UUID, entityId: UUID, state: 'FOLLOWED' | 'MUTED' | null ): Promise; createRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; tags?: string[]; metadata?: { [key: string]: any }; }): Promise; updateRelationship(relationship: Relationship): Promise; getRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; }): Promise; getRelationships(params: { entityId: UUID; tags?: string[] }): Promise; ensureEmbeddingDimension(dimension: number): Promise; getCache(key: string): Promise; setCache(key: string, value: T): Promise; deleteCache(key: string): Promise; createTask(task: Task): Promise; getTasks(params: { roomId?: UUID; tags?: string[] }): Promise; getTask(id: UUID): Promise; getTasksByName(name: string): Promise; updateTask(id: UUID, task: Partial): Promise; deleteTask(id: UUID): Promise; } ⋮---- init(): Promise; close(): Promise; getAgent(agentId: UUID): Promise; getAgents(): Promise; createAgent(agent: Partial): Promise; updateAgent(agentId: UUID, agent: Partial): Promise; deleteAgent(agentId: UUID): Promise; ensureAgentExists(agent: Partial): Promise; ensureEmbeddingDimension(dimension: number): Promise; getEntityById(entityId: UUID): Promise; getEntitiesForRoom(roomId: UUID, includeComponents?: boolean): Promise; createEntity(entity: Entity): Promise; updateEntity(entity: Entity): Promise; getComponent( entityId: UUID, type: string, worldId?: UUID, sourceEntityId?: UUID ): Promise; getComponents(entityId: UUID, worldId?: UUID, sourceEntityId?: UUID): Promise; createComponent(component: Component): Promise; updateComponent(component: Component): Promise; deleteComponent(componentId: UUID): Promise; getMemories(params: { entityId?: UUID; agentId?: UUID; roomId?: UUID; count?: number; unique?: boolean; tableName: string; start?: number; end?: number; }): Promise; getMemoryById(id: UUID): Promise; getMemoriesByIds(ids: UUID[], tableName?: string): Promise; getMemoriesByRoomIds(params: { tableName: string; roomIds: UUID[]; limit?: number; }): Promise; getCachedEmbeddings(params: { query_table_name: string; query_threshold: number; query_input: string; query_field_name: string; query_field_sub_name: string; query_match_count: number; }): Promise< log(params: { body: { [key: string]: unknown }; entityId: UUID; roomId: UUID; type: string; }): Promise; getLogs(params: { entityId: UUID; roomId?: UUID; type?: string; count?: number; offset?: number; }): Promise; deleteLog(logId: UUID): Promise; searchMemories(params: { embedding: number[]; match_threshold?: number; count?: number; roomId?: UUID; unique?: boolean; tableName: string; }): Promise; createMemory(memory: Memory, tableName: string, unique?: boolean): Promise; updateMemory(memory: Partial & deleteMemory(memoryId: UUID): Promise; deleteAllMemories(roomId: UUID, tableName: string): Promise; countMemories(roomId: UUID, unique?: boolean, tableName?: string): Promise; createWorld(world: World): Promise; getWorld(id: UUID): Promise; getAllWorlds(): Promise; updateWorld(world: World): Promise; getRoom(roomId: UUID): Promise; createRoom( deleteRoom(roomId: UUID): Promise; updateRoom(room: Room): Promise; getRoomsForParticipant(entityId: UUID): Promise; getRoomsForParticipants(userIds: UUID[]): Promise; getRooms(worldId: UUID): Promise; addParticipant(entityId: UUID, roomId: UUID): Promise; removeParticipant(entityId: UUID, roomId: UUID): Promise; getParticipantsForEntity(entityId: UUID): Promise; getParticipantsForRoom(roomId: UUID): Promise; getParticipantUserState(roomId: UUID, entityId: UUID): Promise<'FOLLOWED' | 'MUTED' | null>; setParticipantUserState( roomId: UUID, entityId: UUID, state: 'FOLLOWED' | 'MUTED' | null ): Promise; createRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; tags?: string[]; metadata?: { [key: string]: any }; }): Promise; updateRelationship(relationship: Relationship): Promise; getRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; }): Promise; getRelationships(params: ⋮---- getCache(key: string): Promise; setCache(key: string, value: T): Promise; deleteCache(key: string): Promise; createTask(task: Task): Promise; getTasks(params: getTask(id: UUID): Promise; getTasksByName(name: string): Promise; updateTask(id: UUID, task: Partial): Promise; deleteTask(id: UUID): Promise; ⋮---- export interface EmbeddingSearchResult { embedding: number[]; levenshtein_score: number; } export interface MemoryRetrievalOptions { roomId: UUID; count?: number; unique?: boolean; start?: number; end?: number; agentId?: UUID; } export interface MemorySearchOptions { embedding: number[]; match_threshold?: number; count?: number; roomId: UUID; agentId?: UUID; unique?: boolean; metadata?: Partial; } export interface MultiRoomMemoryOptions { roomIds: UUID[]; limit?: number; agentId?: UUID; } export interface UnifiedMemoryOptions { roomId: UUID; limit?: number; agentId?: UUID; unique?: boolean; start?: number; end?: number; } export interface UnifiedSearchOptions extends UnifiedMemoryOptions { embedding: number[]; similarity?: number; } export type CacheOptions = { expires?: number; }; export interface IAgentRuntime extends IDatabaseAdapter { agentId: UUID; character: Character; providers: Provider[]; actions: Action[]; evaluators: Evaluator[]; plugins: Plugin[]; services: Map; events: Map Promise)[]>; fetch?: typeof fetch | null; routes: Route[]; registerPlugin(plugin: Plugin): Promise; initialize(): Promise; getKnowledge(message: Memory): Promise; addKnowledge( item: KnowledgeItem, options: { targetTokens: number; overlap: number; modelContextSize: number; } ): Promise; getService(service: ServiceTypeName | string): T | null; getAllServices(): Map; registerService(service: typeof Service): void; registerDatabaseAdapter(adapter: IDatabaseAdapter): void; setSetting(key: string, value: string | boolean | null | any, secret: boolean): void; getSetting(key: string): string | boolean | null | any; getConversationLength(): number; processActions( message: Memory, responses: Memory[], state?: State, callback?: HandlerCallback ): Promise; evaluate( message: Memory, state?: State, didRespond?: boolean, callback?: HandlerCallback, responses?: Memory[] ): Promise; registerProvider(provider: Provider): void; registerAction(action: Action): void; registerEvaluator(evaluator: Evaluator): void; ensureConnection({ entityId, roomId, userName, name, source, channelId, serverId, type, worldId, }: { entityId: UUID; roomId: UUID; userName?: string; name?: string; source?: string; channelId?: string; serverId?: string; type: ChannelType; worldId?: UUID; }): Promise; ensureParticipantInRoom(entityId: UUID, roomId: UUID): Promise; ensureWorldExists(world: World): Promise; ensureRoomExists(room: Room): Promise; composeState(message: Memory, filterList?: string[], includeList?: string[]): Promise; useModel( modelType: T, params: Omit | any ): Promise; registerModel(modelType: ModelTypeName | string, handler: (params: any) => Promise): void; getModel( modelType: ModelTypeName | string ): ((runtime: IAgentRuntime, params: any) => Promise) | undefined; registerEvent(event: string, handler: (params: any) => Promise): void; getEvent(event: string): ((params: any) => Promise)[] | undefined; emitEvent(event: string | string[], params: any): Promise; registerTaskWorker(taskHandler: TaskWorker): void; getTaskWorker(name: string): TaskWorker | undefined; stop(): Promise; addEmbeddingToMemory(memory: Memory): Promise; } ⋮---- registerPlugin(plugin: Plugin): Promise; initialize(): Promise; getKnowledge(message: Memory): Promise; addKnowledge( item: KnowledgeItem, options: { targetTokens: number; overlap: number; modelContextSize: number; } ): Promise; getService(service: ServiceTypeName | string): T | null; getAllServices(): Map; registerService(service: typeof Service): void; registerDatabaseAdapter(adapter: IDatabaseAdapter): void; setSetting(key: string, value: string | boolean | null | any, secret: boolean): void; getSetting(key: string): string | boolean | null | any; getConversationLength(): number; processActions( message: Memory, responses: Memory[], state?: State, callback?: HandlerCallback ): Promise; evaluate( message: Memory, state?: State, didRespond?: boolean, callback?: HandlerCallback, responses?: Memory[] ): Promise; registerProvider(provider: Provider): void; registerAction(action: Action): void; registerEvaluator(evaluator: Evaluator): void; ensureConnection({ entityId, roomId, userName, name, source, channelId, serverId, type, worldId, }: { entityId: UUID; roomId: UUID; userName?: string; name?: string; source?: string; channelId?: string; serverId?: string; type: ChannelType; worldId?: UUID; }): Promise; ensureParticipantInRoom(entityId: UUID, roomId: UUID): Promise; ensureWorldExists(world: World): Promise; ensureRoomExists(room: Room): Promise; composeState(message: Memory, filterList?: string[], includeList?: string[]): Promise; useModel( modelType: T, params: Omit | any ): Promise; registerModel(modelType: ModelTypeName | string, handler: (params: any) getModel( modelType: ModelTypeName | string ): ((runtime: IAgentRuntime, params: any) registerEvent(event: string, handler: (params: any) getEvent(event: string): ((params: any) emitEvent(event: string | string[], params: any): Promise; registerTaskWorker(taskHandler: TaskWorker): void; getTaskWorker(name: string): TaskWorker | undefined; stop(): Promise; addEmbeddingToMemory(memory: Memory): Promise; ⋮---- export type KnowledgeItem = { id: UUID; content: Content; metadata?: MemoryMetadata; }; export enum KnowledgeScope { SHARED = 'shared', PRIVATE = 'private', } export enum CacheKeyPrefix { KNOWLEDGE = 'knowledge', } export interface DirectoryItem { directory: string; shared?: boolean; } export interface ChunkRow { id: string; } export type GenerateTextParams = { runtime: IAgentRuntime; prompt: string; modelType: ModelTypeName; maxTokens?: number; temperature?: number; frequencyPenalty?: number; presencePenalty?: number; stopSequences?: string[]; }; export interface TokenizeTextParams { prompt: string; modelType: ModelTypeName; } export interface DetokenizeTextParams { tokens: number[]; modelType: ModelTypeName; } export interface IVideoService extends Service { isVideoUrl(url: string): boolean; fetchVideoInfo(url: string): Promise; downloadVideo(videoInfo: Media): Promise; processVideo(url: string, runtime: IAgentRuntime): Promise; } ⋮---- isVideoUrl(url: string): boolean; fetchVideoInfo(url: string): Promise; downloadVideo(videoInfo: Media): Promise; processVideo(url: string, runtime: IAgentRuntime): Promise; ⋮---- export interface IBrowserService extends Service { getPageContent( url: string, runtime: IAgentRuntime ): Promise<{ title: string; description: string; bodyContent: string }>; } ⋮---- getPageContent( url: string, runtime: IAgentRuntime ): Promise< ⋮---- export interface IPdfService extends Service { convertPdfToText(pdfBuffer: Buffer): Promise; } ⋮---- convertPdfToText(pdfBuffer: Buffer): Promise; ⋮---- export interface IFileService extends Service { uploadFile( imagePath: string, subDirectory: string, useSignedUrl: boolean, expiresIn: number ): Promise<{ success: boolean; url?: string; error?: string; }>; generateSignedUrl(fileName: string, expiresIn: number): Promise; } ⋮---- uploadFile( imagePath: string, subDirectory: string, useSignedUrl: boolean, expiresIn: number ): Promise< generateSignedUrl(fileName: string, expiresIn: number): Promise; ⋮---- export interface TestCase { name: string; fn: (runtime: IAgentRuntime) => Promise | void; } export interface TestSuite { name: string; tests: TestCase[]; } export interface TeeAgent { id: string; agentId: string; agentName: string; createdAt: number; publicKey: string; attestation: string; } export enum TEEMode { OFF = 'OFF', LOCAL = 'LOCAL', DOCKER = 'DOCKER', PRODUCTION = 'PRODUCTION', } export interface RemoteAttestationQuote { quote: string; timestamp: number; } export interface DeriveKeyAttestationData { agentId: string; publicKey: string; subject?: string; } export interface RemoteAttestationMessage { agentId: string; timestamp: number; message: { entityId: string; roomId: string; content: string; }; } export enum TeeType { TDX_DSTACK = 'tdx_dstack', } export interface TeeVendorConfig { [key: string]: unknown; } export interface TeePluginConfig { vendor?: string; vendorConfig?: TeeVendorConfig; } export interface TaskWorker { name: string; execute: ( runtime: IAgentRuntime, options: { [key: string]: unknown }, task: Task ) => Promise; validate?: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; } export interface Task { id?: UUID; name: string; updatedAt?: number; metadata?: { updateInterval?: number; options?: { name: string; description: string; }[]; [key: string]: unknown; }; description: string; roomId?: UUID; worldId?: UUID; tags: string[]; } export enum Role { OWNER = 'OWNER', ADMIN = 'ADMIN', NONE = 'NONE', } export interface Setting { name: string; description: string; usageDescription: string; value: string | boolean | null; required: boolean; public?: boolean; secret?: boolean; validation?: (value: any) => boolean; dependsOn?: string[]; onSetAction?: (value: any) => string; visibleIf?: (settings: { [key: string]: Setting }) => boolean; } export interface WorldSettings { [key: string]: Setting; } export interface OnboardingConfig { settings: { [key: string]: Omit; }; } export interface BaseModelParams { runtime: IAgentRuntime; } export interface TextGenerationParams extends BaseModelParams { prompt: string; temperature?: number; maxTokens?: number; stopSequences?: string[]; frequencyPenalty?: number; presencePenalty?: number; } export interface TextEmbeddingParams extends BaseModelParams { text: string; } export interface TokenizeTextParams extends BaseModelParams { prompt: string; modelType: ModelTypeName; } export interface DetokenizeTextParams extends BaseModelParams { tokens: number[]; modelType: ModelTypeName; } export interface ImageGenerationParams extends BaseModelParams { prompt: string; size?: string; count?: number; } export interface ImageDescriptionParams extends BaseModelParams { imageUrl: string; prompt?: string; } export interface TranscriptionParams extends BaseModelParams { audioUrl: string; prompt?: string; } export interface TextToSpeechParams extends BaseModelParams { text: string; voice?: string; speed?: number; } export interface AudioProcessingParams extends BaseModelParams { audioUrl: string; processingType: string; } export interface VideoProcessingParams extends BaseModelParams { videoUrl: string; processingType: string; } export type JSONSchema = { type: string; properties?: Record; required?: string[]; items?: JSONSchema; [key: string]: any; }; export interface ObjectGenerationParams extends BaseModelParams { prompt: string; schema?: JSONSchema; output?: 'object' | 'array' | 'enum'; enumValues?: string[]; modelType?: ModelTypeName; temperature?: number; stopSequences?: string[]; } export interface ModelParamsMap { [ModelType.TEXT_SMALL]: TextGenerationParams; [ModelType.TEXT_LARGE]: TextGenerationParams; [ModelType.TEXT_EMBEDDING]: TextEmbeddingParams | string | null; [ModelType.TEXT_TOKENIZER_ENCODE]: TokenizeTextParams; [ModelType.TEXT_TOKENIZER_DECODE]: DetokenizeTextParams; [ModelType.TEXT_REASONING_SMALL]: TextGenerationParams; [ModelType.TEXT_REASONING_LARGE]: TextGenerationParams; [ModelType.IMAGE]: ImageGenerationParams; [ModelType.IMAGE_DESCRIPTION]: ImageDescriptionParams | string; [ModelType.TRANSCRIPTION]: TranscriptionParams | Buffer | string; [ModelType.TEXT_TO_SPEECH]: TextToSpeechParams | string; [ModelType.AUDIO]: AudioProcessingParams; [ModelType.VIDEO]: VideoProcessingParams; [ModelType.OBJECT_SMALL]: ObjectGenerationParams; [ModelType.OBJECT_LARGE]: ObjectGenerationParams; [key: string]: BaseModelParams | any; } export interface ModelResultMap { [ModelType.TEXT_SMALL]: string; [ModelType.TEXT_LARGE]: string; [ModelType.TEXT_EMBEDDING]: number[]; [ModelType.TEXT_TOKENIZER_ENCODE]: number[]; [ModelType.TEXT_TOKENIZER_DECODE]: string; [ModelType.TEXT_REASONING_SMALL]: string; [ModelType.TEXT_REASONING_LARGE]: string; [ModelType.IMAGE]: { url: string }[]; [ModelType.IMAGE_DESCRIPTION]: { title: string; description: string }; [ModelType.TRANSCRIPTION]: string; [ModelType.TEXT_TO_SPEECH]: Readable | Buffer; [ModelType.AUDIO]: any; [ModelType.VIDEO]: any; [ModelType.OBJECT_SMALL]: any; [ModelType.OBJECT_LARGE]: any; [key: string]: any; } export enum EventType { WORLD_JOINED = 'WORLD_JOINED', WORLD_CONNECTED = 'WORLD_CONNECTED', WORLD_LEFT = 'WORLD_LEFT', ENTITY_JOINED = 'ENTITY_JOINED', ENTITY_LEFT = 'ENTITY_LEFT', ENTITY_UPDATED = 'ENTITY_UPDATED', ROOM_JOINED = 'ROOM_JOINED', ROOM_LEFT = 'ROOM_LEFT', MESSAGE_RECEIVED = 'MESSAGE_RECEIVED', MESSAGE_SENT = 'MESSAGE_SENT', VOICE_MESSAGE_RECEIVED = 'VOICE_MESSAGE_RECEIVED', VOICE_MESSAGE_SENT = 'VOICE_MESSAGE_SENT', REACTION_RECEIVED = 'REACTION_RECEIVED', POST_GENERATED = 'POST_GENERATED', INTERACTION_RECEIVED = 'INTERACTION_RECEIVED', RUN_STARTED = 'RUN_STARTED', RUN_ENDED = 'RUN_ENDED', RUN_TIMEOUT = 'RUN_TIMEOUT', ACTION_STARTED = 'ACTION_STARTED', ACTION_COMPLETED = 'ACTION_COMPLETED', EVALUATOR_STARTED = 'EVALUATOR_STARTED', EVALUATOR_COMPLETED = 'EVALUATOR_COMPLETED', } export enum PlatformPrefix { DISCORD = 'DISCORD', TELEGRAM = 'TELEGRAM', TWITTER = 'TWITTER', } export interface EventPayload { runtime: IAgentRuntime; source: string; } export interface WorldPayload extends EventPayload { world: World; rooms: Room[]; entities: Entity[]; } export interface EntityPayload extends EventPayload { entityId: UUID; worldId?: UUID; roomId?: UUID; metadata?: { orginalId: string; username: string; displayName?: string; [key: string]: any; }; } export interface MessagePayload extends EventPayload { message: Memory; callback?: HandlerCallback; onComplete?: () => void; } export interface InvokePayload extends EventPayload { worldId: UUID; userId: string; roomId: UUID; callback?: HandlerCallback; } export interface RunEventPayload extends EventPayload { runId: UUID; messageId: UUID; roomId: UUID; entityId: UUID; startTime: number; status: 'started' | 'completed' | 'timeout'; endTime?: number; duration?: number; error?: string; } export interface ActionEventPayload extends EventPayload { actionId: UUID; actionName: string; startTime?: number; completed?: boolean; error?: Error; } export interface EvaluatorEventPayload extends EventPayload { evaluatorId: UUID; evaluatorName: string; startTime?: number; completed?: boolean; error?: Error; } export type MessageReceivedHandlerParams = { runtime: IAgentRuntime; message: Memory; callback: HandlerCallback; onComplete?: () => void; }; export interface EventPayloadMap { [EventType.WORLD_JOINED]: WorldPayload; [EventType.WORLD_CONNECTED]: WorldPayload; [EventType.WORLD_LEFT]: WorldPayload; [EventType.ENTITY_JOINED]: EntityPayload; [EventType.ENTITY_LEFT]: EntityPayload; [EventType.ENTITY_UPDATED]: EntityPayload; [EventType.MESSAGE_RECEIVED]: MessagePayload; [EventType.MESSAGE_SENT]: MessagePayload; [EventType.REACTION_RECEIVED]: MessagePayload; [EventType.POST_GENERATED]: InvokePayload; [EventType.INTERACTION_RECEIVED]: MessagePayload; [EventType.RUN_STARTED]: RunEventPayload; [EventType.RUN_ENDED]: RunEventPayload; [EventType.RUN_TIMEOUT]: RunEventPayload; [EventType.ACTION_STARTED]: ActionEventPayload; [EventType.ACTION_COMPLETED]: ActionEventPayload; [EventType.EVALUATOR_STARTED]: EvaluatorEventPayload; [EventType.EVALUATOR_COMPLETED]: EvaluatorEventPayload; } export type EventHandler = ( payload: EventPayloadMap[T] ) => Promise; export enum SOCKET_MESSAGE_TYPE { ROOM_JOINING = 1, SEND_MESSAGE = 2, MESSAGE = 3, ACK = 4, THINKING = 5, } export interface MessageMemory extends Memory { metadata: MessageMetadata; content: Content & { text: string; }; } export function createMessageMemory(params: { id?: UUID; entityId: UUID; agentId?: UUID; roomId: UUID; content: Content & { text: string }; embedding?: number[]; }): MessageMemory export interface TypedService extends Service { config: ConfigType; process(input: unknown): Promise; } ⋮---- process(input: unknown): Promise; ⋮---- export function getTypedService>( runtime: IAgentRuntime, serviceType: ServiceTypeName ): T | null export function isDocumentMetadata(metadata: MemoryMetadata): metadata is DocumentMetadata export function isFragmentMetadata(metadata: MemoryMetadata): metadata is FragmentMetadata export function isMessageMetadata(metadata: MemoryMetadata): metadata is MessageMetadata export function isDescriptionMetadata(metadata: MemoryMetadata): metadata is DescriptionMetadata export function isCustomMetadata(metadata: MemoryMetadata): metadata is CustomMetadata export interface ServiceError { code: string; message: string; details?: unknown; cause?: Error; } export function getVideoService(runtime: IAgentRuntime): IVideoService | null export function getBrowserService(runtime: IAgentRuntime): IBrowserService | null export function getPdfService(runtime: IAgentRuntime): IPdfService | null export function getFileService(runtime: IAgentRuntime): IFileService | null export function isDocumentMemory( memory: Memory ): memory is Memory & export function isFragmentMemory( memory: Memory ): memory is Memory & export function getMemoryText(memory: Memory, defaultValue = ''): string /** * Safely create a ServiceError from any caught error */ export function createServiceError(error: unknown, code = 'UNKNOWN_ERROR'): ServiceError export type StateValue = string | number | boolean | null | StateObject | StateArray; export interface StateObject { [key: string]: StateValue; } export type StateArray = StateValue[]; export interface EnhancedState { values: StateObject; data: StateObject; text: string; [key: string]: StateValue; } export type ComponentData = Record; export type EventDataObject = Record; export type TypedEventHandler = (data: EventDataObject) => Promise | void; export type DbConnection = unknown; export type MetadataObject = Record; export type ModelHandler = ( runtime: IAgentRuntime, params: Record ) => Promise; export type ServiceConfig = Record; ```` ## File: packages/core/src/uuid.ts ````typescript import { sha1 } from 'js-sha1'; import { z } from 'zod'; import type { UUID } from './types'; ⋮---- export function validateUuid(value: unknown): UUID | null export function stringToUuid(target: string | number): UUID ⋮---- const _uint8ToHex = (ubyte: number): string => const _uint8ArrayToHex = (buf: Uint8Array): string => ```` ## File: packages/docs/docs/core/actions.md ````markdown --- sidebar_position: 6 --- # ⚡ Actions Actions define how agents respond to and interact with messages. They enable agents to perform tasks beyond simple message responses by integrating with external systems and modifying behavior. ## Overview Actions are core components that define an agent's capabilities and how it can respond to conversations. Each action represents a distinct operation that an agent can perform, ranging from simple replies to complex interactions with external systems. 1. Structure: An Action consists of: - `name`: Unique identifier - `similes`: Alternative names/triggers - `description`: Purpose and usage explanation - `validate`: Function to check if action is appropriate - `handler`: Core implementation logic - `examples`: Sample usage patterns - `suppressInitialMessage`: Optional flag to suppress initial response 2. Agent Decision Flow: When a message is received: - The agent evaluates all available actions using their validation functions - Valid actions are provided to the LLM via the `actionsProvider` - The LLM decides which action(s) to execute - Each action's handler generates a response including a "thought" component (agent's internal reasoning) - The response is processed and sent back to the conversation 3. Integration: Actions work in concert with: - **Providers** - Supply context before the agent decides what action to take - **Evaluators** - Process conversations after actions to extract insights and update memory - **Services** - Enable actions to interact with external systems --- ## Implementation The core Action interface includes the following components: ```typescript interface Action { name: string; // Unique identifier similes: string[]; // Alternative names/triggers description: string; // Purpose and usage explanation validate: (runtime: IAgentRuntime, message: Memory, state?: State) => Promise; handler: ( runtime: IAgentRuntime, message: Memory, state?: State, options?: any, callback?: HandlerCallback ) => Promise; examples: ActionExample[][]; suppressInitialMessage?: boolean; // Optional flag } // Handler callback for generating responses type HandlerCallback = (content: Content) => Promise; // Response content structure interface Content { text: string; thought?: string; // Internal reasoning (not shown to users) actions?: string[]; // List of action names being performed action?: string; // Legacy single action name attachments?: Attachment[]; // Optional media attachments } ``` ### Basic Action Template Here's a simplified template for creating a custom action: ```typescript const customAction: Action = { name: 'CUSTOM_ACTION', similes: ['ALTERNATE_NAME', 'OTHER_TRIGGER'], description: 'Detailed description of when and how to use this action', validate: async (runtime: IAgentRuntime, message: Memory, state?: State) => { // Logic to determine if this action applies to the current message // Should be efficient and quick to check return true; // Return true if action is valid for this message }, handler: async ( runtime: IAgentRuntime, message: Memory, state?: State, options?: any, callback?: HandlerCallback ) => { // Implementation logic - what the action actually does // Generate a response with thought and text components const responseContent = { thought: 'Internal reasoning about what to do (not shown to users)', text: 'The actual message to send to the conversation', actions: ['CUSTOM_ACTION'], // List of actions being performed }; // Send the response using the callback if (callback) { await callback(responseContent); } return true; // Return true if action executed successfully }, examples: [ [ { name: '{{name1}}', content: { text: 'Trigger message' }, }, { name: '{{name2}}', content: { text: 'Response', thought: 'Internal reasoning', actions: ['CUSTOM_ACTION'], }, }, ], ], }; ``` ### Character File Example Actions can be referenced in character files to define how an agent should respond to specific types of messages: ```json "messageExamples": [ [ { "user": "{{user1}}", "content": { "text": "Can you help transfer some SOL?" } }, { "user": "SBF", "content": { "text": "yeah yeah for sure, sending SOL is pretty straightforward. just need the recipient and amount. everything else is basically fine, trust me.", "actions": ["SEND_SOL"] } } ] ] ``` ### The Reply Action The most fundamental action is the `REPLY` action, which allows agents to respond to messages with text. It serves as the default action when no specialized behavior is needed: ```typescript const replyAction: Action = { name: 'REPLY', similes: ['GREET', 'REPLY_TO_MESSAGE', 'SEND_REPLY', 'RESPOND', 'RESPONSE'], description: 'Replies to the current conversation with the text from the generated message.', validate: async (_runtime: IAgentRuntime) => true, // Always valid handler: async ( runtime: IAgentRuntime, message: Memory, state: State, _options: any, callback: HandlerCallback ) => { // Compose state with necessary providers state = await runtime.composeState(message, [ ...(message.content.providers ?? []), 'RECENT_MESSAGES', ]); // Generate response using LLM const response = await runtime.useModel(ModelType.TEXT_SMALL, { prompt: composePromptFromState({ state, template: replyTemplate, }), }); // Parse and format response const responseContentObj = parseJSONObjectFromText(response); const responseContent = { thought: responseContentObj.thought, text: responseContentObj.message || '', actions: ['REPLY'], }; // Send response via callback await callback(responseContent); return true; }, examples: [ /* Examples omitted for brevity */ ], }; ``` --- ## Actions Provider Integration The actions provider is responsible for making valid actions available to the agent's reasoning process. When a message is received: 1. The provider validates all available actions against the current message 2. It formats the valid actions for inclusion in the agent context 3. This formatted information is used by the agent to decide which action(s) to take ```typescript const actionsProvider: Provider = { name: 'ACTIONS', description: 'Possible response actions', position: -1, // High priority provider get: async (runtime: IAgentRuntime, message: Memory, state: State) => { // Validate all actions for this message const actionPromises = runtime.actions.map(async (action: Action) => { const result = await action.validate(runtime, message, state); return result ? action : null; }); const resolvedActions = await Promise.all(actionPromises); const actionsData = resolvedActions.filter(Boolean); // Format action information for the agent const values = { actionNames: `Possible response actions: ${formatActionNames(actionsData)}`, actions: formatActions(actionsData), actionExamples: composeActionExamples(actionsData, 10), }; // Return data, values, and text representation return { data: { actionsData }, values, text: [values.actionNames, values.actionExamples, values.actions] .filter(Boolean) .join('\n\n'), }; }, }; ``` ## Example Implementations ElizaOS includes a wide variety of predefined actions across various plugins in the ecosystem. Here are some key categories: ### Communication Actions - **REPLY**: Standard text response - **CONTINUE**: Extend the conversation - **IGNORE**: End the conversation or ignore irrelevant messages ### Blockchain and Token Actions - **SEND_TOKEN**: Transfer cryptocurrency - **CREATE_TOKEN**: Create a new token on a blockchain - **READ_CONTRACT/WRITE_CONTRACT**: Interact with smart contracts ### Media and Content Generation - **GENERATE_IMAGE**: Create images from text descriptions - **SEND_GIF**: Share animated content - **GENERATE_3D**: Create 3D content ### AI and Agent Management - **LAUNCH_AGENT**: Create and start a new agent - **START_SESSION**: Begin an interactive session - **GENERATE_MEME**: Create humorous content ### Example Image Generation Action Here's a more detailed example of an image generation action: ```typescript const generateImageAction: Action = { name: 'GENERATE_IMAGE', similes: ['CREATE_IMAGE', 'MAKE_IMAGE', 'DRAW'], description: "Generates an image based on the user's description", suppressInitialMessage: true, // Don't send initial text response validate: async (runtime: IAgentRuntime, message: Memory) => { const text = message.content.text.toLowerCase(); return ( text.includes('generate') || text.includes('create') || text.includes('draw') || text.includes('make an image') ); }, handler: async ( runtime: IAgentRuntime, message: Memory, state?: State, _options?: any, callback?: HandlerCallback ) => { try { // Get appropriate service const imageService = runtime.getService(ServiceType.IMAGE_GENERATION); // Generate the response with thought component const responseContent = { thought: "This request is asking for image generation. I'll use the image service to create a visual based on the user's description.", text: "I'm generating that image for you now...", actions: ['GENERATE_IMAGE'], }; // Send initial response if callback provided if (callback) { await callback(responseContent); } // Generate image const imageUrl = await imageService.generateImage(message.content.text); // Create follow-up message with the generated image await runtime.createMemory( { id: generateId(), content: { text: "Here's the image I generated:", attachments: [ { type: 'image', url: imageUrl, }, ], }, agentId: runtime.agentId, roomId: message.roomId, }, 'messages' ); return true; } catch (error) { console.error('Image generation failed:', error); // Send error response if callback provided if (callback) { await callback({ thought: 'The image generation failed due to an error.', text: "I'm sorry, I wasn't able to generate that image. There was a technical problem.", actions: ['REPLY'], }); } return false; } }, examples: [ /* Examples omitted for brevity */ ], }; ``` ## Action-Evaluator-Provider Cycle Actions are part of a larger cycle in ElizaOS agents: 1. **Providers** fetch relevant context for decision-making 2. **Actions** execute the agent's chosen response 3. **Evaluators** process the conversation to extract insights 4. These insights are stored in memory 5. Future **Providers** can access these insights 6. This informs future **Actions** For example: - The FACTS provider retrieves relevant facts about users - The agent uses this context to decide on an appropriate action - After the action, the reflection evaluator extracts new facts and relationships - These are stored in memory and available for future interactions - This creates a virtuous cycle of continuous learning and improvement --- ## FAQ ### What are Actions in ElizaOS? Actions are core components that define how agents respond to messages and perform tasks. They encapsulate specific behaviors and capabilities, ranging from simple text replies to complex interactions with external systems. ### How do Actions work? When a message is received, the agent evaluates all available actions using their validation functions. The agent then decides which action(s) to execute based on the message content and context. Each action's handler generates a response, which may include text, thought processes, and attachments. ### What's the difference between actions and evaluators? Actions are executed during an agent's response to perform tasks and generate content. Evaluators run after responses to analyze conversations, extract information, and update the agent's memory. Actions are about doing, evaluators are about learning. ### What role do "thoughts" play in actions? The thought component provides an internal reasoning process for the agent, explaining its decision-making. These thoughts aren't shown to users but help with debugging and understanding the agent's behavior. They're similar to the self-reflection component in evaluators. ### How do I create a custom action? Define an action object with a name, similes, description, validation function, handler function, and examples. The validation function determines when the action should be used, while the handler contains the implementation logic and generates a response. ### Can actions be chained together? Yes! Actions can call other actions or services as part of their implementation. This allows for complex workflows that combine multiple capabilities. For example, an action might first reply to a user, then generate an image, and finally store data in a database. ### How does an agent choose which action to use? The agent uses the following process: 1. All actions are validated against the current message 2. Valid actions are formatted and included in the agent's context 3. The LLM decides which action(s) to execute based on the message and context 4. The chosen action's handler is executed to generate a response ### How do actions integrate with services? Actions often use services to interact with external systems. The action handler can retrieve a service from the runtime (e.g., `imageService = runtime.getService(ServiceType.IMAGE_GENERATION)`) and then call methods on that service to perform operations. ### What's the difference between `actions` and `action` in responses? The `actions` array is the modern way to specify multiple actions being performed in a single response. The singular `action` field is maintained for backward compatibility but is deprecated in favor of the array format. ### Can I add custom actions to an existing agent? Yes! You can create a plugin that defines new actions and then add that plugin to your agent's configuration. This allows you to extend the agent's capabilities without modifying its core implementation. ## Further Reading - [Evaluators](./evaluators.md) - [Providers](./providers.md) - [Services](./services.md) ```` ## File: packages/docs/docs/core/agents.md ````markdown # 🤖 Agent Runtime The `AgentRuntime` is the core runtime environment for Eliza agents. It handles message processing, state management, plugin integration, and interaction with external services. You can think of it as the brains that provide the high-level orchestration layer for Eliza agents. ```mermaid sequenceDiagram actor User participant Platform as Platform participant Runtime as Runtime participant State as State participant P as Providers participant A as Actions participant M as Models participant E as Evaluators participant DB as Database User->>Platform: Message Platform->>Runtime: Forward %% Context building (condensed) Runtime->>State: Get context State->>P: Gather data Note over P: Character, Knowledge,
Messages, Time, etc. P-->>State: Context data State-->>Runtime: Assembled context %% Action flow (condensed) Runtime->>A: Execute action A->>M: Generate content M-->>A: Generated text A-->>Runtime: Result %% Evaluation (condensed) Runtime->>E: Analyze E->>DB: Store insights E-->>Runtime: Evaluation %% Delivery Runtime->>Platform: Response Platform->>User: Deliver %% Background (simplified) par Background Runtime->>Runtime: Tasks & Events end ``` The runtime follows this general flow: 1. **Initial Reception**: The user sends a message which is received by the Platform Services 2. **Context Building**: - The Runtime Core requests context from the State Composition system - State gathers data from various Providers (Character, Knowledge, Recent Messages, etc.) - The complete context is returned to the Runtime 3. **Action Processing**: - The Runtime determines applicable actions and selects the optimal one - The selected action may request content generation from Models - The action result is returned to the Runtime 4. **Learning & Persistence**: - The conversation is analyzed by Evaluators for insights and facts - Knowledge updates are sent to the Memory System - All relevant data is persisted to the Database 5. **Response Delivery**: - The final response is sent back to the user through Platform Services --- ## Overview The [AgentRuntime](/api/classes/AgentRuntime) class is the primary implementation of the [IAgentRuntime](/api/interfaces/IAgentRuntime) interface, which manages the agent's core functions, including: | Component | Description | API Reference | Related Files | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Services** | Supports multiple communication platforms and specialized functionalities for seamless interaction. | [Services API](/api/interfaces/IAgentRuntime/#services) | [`service.ts`](https://github.com/elizaOS/eliza/tree/develop/packages/core/src/service.ts), [`Discord`](https://github.com/elizaos-plugins/plugin-discord), [`Telegram`](https://github.com/elizaos-plugins/plugin-telegram), [`Twitter`](https://github.com/elizaos-plugins/plugin-twitter), [`Farcaster`](https://github.com/elizaos-plugins/plugin-farcaster), [`Lens`](https://github.com/elizaos-plugins/plugin-lens), [`Slack`](https://github.com/elizaos-plugins/plugin-slack), [`Auto`](https://github.com/elizaos-plugins/plugin-auto), [`GitHub`](https://github.com/elizaos-plugins/plugin-github) | | **State** | Maintains context for coherent cross-platform interactions, updates dynamically. Also tracks goals, knowledge, and recent interactions | [State API](/api/interfaces/State) | [`state.ts`](https://github.com/elizaos/runtime/state.ts) | | **Plugins** | Dynamic extensions of agent functionalities using custom actions, evaluators, providers, and adapters | [Plugins API](/api/type-aliases/Plugin/) | [`plugins.ts`](https://github.com/elizaos/runtime/plugins.ts), [actions](../actions), [evaluators](../evaluators), [providers](../providers) | | **Services** | Connects with external services for `IMAGE_DESCRIPTION`, `TRANSCRIPTION`, `TEXT_GENERATION`, `SPEECH_GENERATION`, `VIDEO`, `PDF`, `BROWSER`, `WEB_SEARCH`, `EMAIL_AUTOMATION`, and more | [Services API](/api/interfaces/IAgentRuntime/#services) | [`services.ts`](https://github.com/elizaos/runtime/services.ts) | | **Memory Systems** | Creates, retrieves, and embeds memories and manages conversation history. | [Memory API](/api/interfaces/IMemoryManager) | [`memory.ts`](https://github.com/elizaos/runtime/memory.ts) | | **Database Adapters** | Persistent storage and retrieval for memories and knowledge | [databaseAdapter](api/interfaces/IAgentRuntime/#databaseAdapter) | [`MongoDB`](https://github.com/elizaos-plugins/adapter-mongodb), [`PostgreSQL`](https://github.com/elizaos-plugins/adapter-postgres), [`SQLite`](https://github.com/elizaos-plugins/adapter-sqlite), [`Supabase`](https://github.com/elizaos-plugins/adapter-supabase), [`PGLite`](https://github.com/elizaos-plugins/adapter-pglite), [`Qdrant`](https://github.com/elizaos-plugins/adapter-qdrant), [`SQL.js`](https://github.com/elizaos-plugins/adapter-sqljs) | | **Cache Management** | Provides flexible storage and retrieval via various caching methods. | [Cache API](/api/interfaces/ICacheManager) | [`cache.ts`](https://github.com/elizaos/runtime/cache.ts) |
Advanced: IAgentRuntime Interface ```typescript interface IAgentRuntime { // Core identification agentId: UUID; // Configuration character: Character; // Personality and behavior settings // Components plugins: Plugin[]; // Additional capabilities services: Map; // Platform connections and functionality providers: Provider[]; // Real-time data sources actions: Action[]; // Available behaviors evaluators: Evaluator[]; // Analysis & learning routes: Route[]; // API endpoints // Memory Management getMemories(...): Promise; // Retrieve conversation history createMemory(...): Promise; // Store new memories searchMemories(...): Promise; // Semantic search // State Composition composeState(...): Promise; // Gather data from providers // Plugin Management registerPlugin(...): Promise; // Register plugins // Service Management getService(...): T | null; // Access services registerService(...): Promise; // Register services // Model Integration useModel(...): Promise; // Use AI models // Additional Utilities getSetting(...): any; // Access settings setSetting(...): void; // Configure settings getCache(...): Promise; // Access cached data setCache(...): Promise; // Store cached data } ``` Source: [/api/interfaces/IAgentRuntime/](/api/interfaces/IAgentRuntime/)
--- ### **Key Methods** - **`initialize()`**: Sets up the agent's runtime environment, including services, plugins, and knowledge processing. - **`processActions()`**: Executes actions based on message content and state. - **`evaluate()`**: Assesses messages and state using registered evaluators. - **`composeState()`**: Constructs the agent's state object for response generation. - **`registerService()`**: Adds a service to the runtime. - **`getService()`**: Retrieves a registered service by type. - **`useModel()`**: Utilizes AI models with typesafe parameters and results. - **`ensureRoomExists()` / `ensureConnection()`**: Ensures the existence of communication channels and connections. ## Service System Services provide specialized functionality with standardized interfaces that can be accessed cross-platform: ```typescript // Speech Generation const speechService = runtime.getService('speech_generation'); const audioStream = await speechService.process(text); // PDF Processing const pdfService = runtime.getService('pdf'); const textContent = await pdfService.convertPdfToText(pdfBuffer); // Discord Integration const discordService = runtime.getService('discord'); await discordService.sendMessage(channelId, content); ``` --- ## State Management The runtime maintains comprehensive state through the State interface: ```typescript interface State { // Core state data values: { [key: string]: any; }; data: { [key: string]: any; }; text: string; } // State composition example async function manageState() { // Initial state composition with all regular providers const state = await runtime.composeState(message); // State with specific providers only const filteredState = await runtime.composeState(message, ['timeProvider', 'recentMessages']); // Include private or dynamic providers const enhancedState = await runtime.composeState(message, null, [ 'weatherProvider', 'portfolioProvider', ]); } ``` --- ## Plugin System Plugins extend agent functionality through a modular interface. The runtime supports various types of plugins including services, adapters, actions, and more: ```typescript interface Plugin { name: string; description: string; init?: (config: Record, runtime: IAgentRuntime) => Promise; // Components services?: (typeof Service)[]; // Communication platforms and external integrations actions?: Action[]; // Custom behaviors providers?: Provider[]; // Data providers evaluators?: Evaluator[]; // Response assessment adapters?: Adapter[]; // Database/cache adapters routes?: Route[]; // API endpoints tests?: TestSuite[]; // Testing utilities } ``` Plugins can be configured through [characterfile](./characterfile) settings: ```json { "name": "MyAgent", "plugins": ["@elizaos/plugin-solana", "@elizaos/plugin-twitter"], "settings": { "twitter": { "shouldRespondToMentions": true }, "solana": { "enableAutoTrading": false } } } ``` For detailed information about plugin development and usage, see the [ElizaOS Registry](https://github.com/elizaos-plugins/registry). --- ## Running Multiple Agents To run multiple agents: ```bash bun start --characters="characters/agent1.json,characters/agent2.json" ``` Or use environment variables: ``` REMOTE_CHARACTER_URLS=https://example.com/characters.json ``` --- ## FAQ ### What's the difference between an agent and a character? A character defines personality and knowledge, while an agent provides the runtime environment and capabilities to bring that character to life. ### How do I choose the right database adapter? Choose based on your needs: - MongoDB: For scalable, document-based storage - PostgreSQL: For relational data with complex queries - SQLite: For simple, file-based storage - Qdrant: For vector search capabilities ### How do I implement custom plugins? Create a plugin that follows the plugin interface and register it with the runtime. See the plugin documentation for detailed examples. ### Do agents share memory across platforms? By default, agents maintain separate memory contexts for different platforms to avoid mixing conversations. Use the memory management system and database adapters to persist and retrieve state information. ### How do I handle multiple authentication methods? Use the character configuration to specify different authentication methods for different services. The runtime will handle the appropriate authentication flow. ### How do I manage environment variables? Use a combination of: - `.env` files for local development - Character-specific settings for per-agent configuration - Environment variables for production deployment ### Can agents communicate with each other? Yes, through the message system and shared memory spaces when configured appropriately. ```` ## File: packages/docs/docs/core/database.md ````markdown --- sidebar_position: 7 --- # 💾 Database System The ElizaOS database system provides persistent storage capabilities for agents. It handles memory storage, entity relationships, knowledge management, and more through a flexible adapter-based architecture. ## Overview ```mermaid graph TB %% Main Components Runtime([Agent Runtime]) DbAdapter([Database Adapter]) DbConnection[("Database (PGLite/PostgreSQL)")] %% Data Models in compact form DataModels["Data Models: Entities, Components, Memories, Relationships, Rooms, Worlds, Tasks Cache"] %% Vector Search VectorStore[(Vector Store)] %% Memories Knowledge MemoriesKnowledge[(Memories / Knowledge)] %% Connection flow Runtime -->|Uses| DbAdapter DbAdapter -->|Connects to| DbConnection DbConnection -->|Stores & Retrieves| DataModels %% Connect Vector Store DbConnection -->|Utilizes| VectorStore VectorStore -->|Enables Search on| MemoriesKnowledge %% Styling classDef default fill:#f0f4f8,stroke:#2c3e50,stroke-width:1px; classDef runtime fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff; classDef adapter fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff; classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff; classDef datamodels fill:#52be80,stroke:#2c3e50,stroke-width:1px,color:#fff; classDef memories fill:#2c5e1a,stroke:#2c3333,stroke-width:1px,color:#fff; class Runtime runtime; class DbAdapter adapter; class DbConnection,VectorStore db; class DataModels datamodels; class MemoriesKnowledge memories; ``` ElizaOS uses a unified database architecture based on Drizzle ORM with adapters that implement the [`IDatabaseAdapter`](/api/interfaces/IDatabaseAdapter) interface. The current release includes support for: | Adapter | Best For | Key Features | | -------------- | --------------------------- | ----------------------------------------------------------------- | | **PGLite** | Local development & testing | Lightweight PostgreSQL implementation running in Node.js process | | **PostgreSQL** | Production deployments | Full PostgreSQL with vector search, scaling, and high reliability | Additional database adapters will be supported in future releases as ElizaOS continues to evolve. ## Core Functionality All database adapters extend the `BaseDrizzleAdapter` abstract class, which provides a comprehensive set of methods for managing all aspects of agent data: ### Entity System | Method | Description | | ---------------------- | ------------------------------------- | | `createEntity()` | Create a new entity | | `getEntityById()` | Retrieve an entity by ID | | `getEntitiesForRoom()` | Get all entities in a room | | `updateEntity()` | Update entity attributes | | `getComponent()` | Get a specific component of an entity | | `getComponents()` | Get all components for an entity | | `createComponent()` | Add a component to an entity | | `updateComponent()` | Update a component | | `deleteComponent()` | Remove a component | ### Memory Management | Method | Description | | ----------------------------- | ------------------------------------ | | `createMemory()` | Store a new memory with metadata | | `getMemoryById()` | Retrieve a specific memory | | `getMemories()` | Get memories matching criteria | | `getMemoriesByIds()` | Get multiple memories by IDs | | `getMemoriesByRoomIds()` | Get memories from multiple rooms | | `searchMemories()` | Search memories by vector similarity | | `searchMemoriesByEmbedding()` | Search using raw embedding vector | | `deleteMemory()` | Remove a specific memory | | `deleteAllMemories()` | Remove all memories in a room | | `countMemories()` | Count memories matching criteria | ### Room & Participant Management | Method | Description | | ---------------------------- | ------------------------------- | | `createRoom()` | Create a new conversation room | | `getRoom()` | Get room by ID | | `getRooms()` | Get all rooms in a world | | `updateRoom()` | Update room attributes | | `deleteRoom()` | Remove a room | | `addParticipant()` | Add entity to room | | `removeParticipant()` | Remove entity from room | | `getParticipantsForEntity()` | Get all rooms an entity is in | | `getParticipantsForRoom()` | List entities in a room | | `getParticipantUserState()` | Get entity's state in a room | | `setParticipantUserState()` | Update entity's state in a room | ### Relationship Management | Method | Description | | ---------------------- | -------------------------------------- | | `createRelationship()` | Create a relationship between entities | | `updateRelationship()` | Update relationship attributes | | `getRelationship()` | Get a specific relationship | | `getRelationships()` | Get all relationships for an entity | ### Caching System | Method | Description | | --------------- | ---------------------- | | `getCache()` | Retrieve cached data | | `setCache()` | Store data in cache | | `deleteCache()` | Remove data from cache | ### World & Task Management | Method | Description | | ------------------ | --------------------------- | | `createWorld()` | Create a new world | | `getWorld()` | Get world by ID | | `getAllWorlds()` | List all worlds | | `updateWorld()` | Update world attributes | | `removeWorld()` | Delete a world | | `createTask()` | Create a new task | | `getTasks()` | Get tasks matching criteria | | `getTasksByName()` | Find tasks by name | | `getTask()` | Get task by ID | | `updateTask()` | Update task attributes | | `deleteTask()` | Remove a task | ### Agent Management | Method | Description | | --------------- | ------------------------- | | `createAgent()` | Create a new agent record | | `getAgent()` | Get agent by ID | | `getAgents()` | List all agents | | `updateAgent()` | Update agent attributes | | `deleteAgent()` | Remove an agent | | `countAgents()` | Count total agents | ### Embedding & Search | Method | Description | | ----------------------------- | ------------------------------ | | `ensureEmbeddingDimension()` | Configure embedding dimensions | | `getCachedEmbeddings()` | Retrieve cached embeddings | | `searchMemories()` | Vector search for memories | | `searchMemoriesByEmbedding()` | Advanced vector search | ## Architecture ElizaOS uses a singleton pattern for database connections to ensure efficient resource usage: ``` ┌─────────────────────────────────────┐ │ AgentRuntime │ └───────────────┬─────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ IDatabaseAdapter │ └───────────────┬─────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ BaseDrizzleAdapter │ └───────────────┬─────────────────────┘ │ ┌───────┴───────┐ ▼ ▼ ┌───────────────┐ ┌─────────────────┐ │ PGLiteAdapter │ │ PostgresAdapter │ └───────┬───────┘ └────────┬────────┘ │ │ ▼ ▼ ┌───────────────┐ ┌─────────────────┐ │PGLiteManager │ │PostgresManager │ │ (Singleton) │ │ (Singleton) │ └───────────────┘ └─────────────────┘ ``` Each adapter is associated with a singleton connection manager that ensures only one database connection is maintained per process, regardless of how many agents are running. ## Implementation ### Initialization The database adapter is initialized through the SQL plugin: ```typescript // Plugin registration in project configuration const project = { plugins: ['@elizaos/plugin-sql'], // ... }; ``` The SQL plugin automatically selects and initializes the appropriate database adapter based on environment settings: ```typescript function createDatabaseAdapter( config: { dataDir?: string; postgresUrl?: string; }, agentId: UUID ): IDatabaseAdapter { if (config.postgresUrl) { return new PgDatabaseAdapter(agentId, postgresConnectionManager); } // Default to PGLite return new PgliteDatabaseAdapter(agentId, pgLiteClientManager); } ``` ### Configuration Configure the database adapter using environment variables or settings: ```typescript // For PostgreSQL process.env.POSTGRES_URL = 'postgresql://username:password@localhost:5432/elizaos'; // For PGLite (default) process.env.PGLITE_DATA_DIR = './elizadb'; // Optional, defaults to './pglite' ``` ### Retry Logic & Error Handling The database system includes built-in retry logic with exponential backoff and jitter: ```typescript protected async withRetry(operation: () => Promise): Promise { let attempt = 0; let lastError: Error | null = null; while (attempt < this.maxRetries) { try { return await operation(); } catch (error) { lastError = error as Error; const isRetryable = this.isRetryableError(error); if (!isRetryable) { break; } // Calculate delay with exponential backoff and jitter const delay = Math.min( this.baseDelay * Math.pow(2, attempt) + Math.random() * this.jitterMax, this.maxDelay ); await new Promise(resolve => setTimeout(resolve, delay)); attempt++; } } throw lastError; } ``` ## Example Usage Here are examples of common database operations: ### Store a Memory ```typescript await runtime.createMemory( { entityId: message.entityId, agentId: runtime.agentId, content: { text: 'Important information to remember' }, roomId: message.roomId, embedding: await runtime.useModel(ModelType.TEXT_EMBEDDING, { text: 'Important information to remember', }), }, 'facts' ); ``` ### Search for Memories ```typescript const embedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, { text: 'What did we discuss about databases?', }); const relevantMemories = await runtime.searchMemories({ tableName: 'messages', embedding, roomId: message.roomId, count: 5, }); ``` ### Manage Entity Relationships ```typescript // Create a relationship between entities await runtime.createRelationship({ sourceEntityId: userEntityId, targetEntityId: agentEntityId, tags: ['friend', 'frequent_interaction'], metadata: { interactions: 42, trust_level: 'high', }, }); // Retrieve relationships const relationships = await runtime.getRelationships({ entityId: userEntityId, tags: ['friend'], }); ``` ## Database Schema The schema is managed by Drizzle ORM and includes the following key tables: ### Core Tables - **entities**: The fundamental objects in the system (users, agents, etc.) - **components**: Modular data attached to entities (profiles, settings, etc.) - **memories**: Conversation history and other remembered information - **relationships**: Connections between entities - **rooms**: Conversation channels - **participants**: Entity participation in rooms - **worlds**: Container for multiple rooms - **tasks**: Scheduled or queued operations - **cache**: Temporary key-value storage - **agents**: Agent configuration and state ### Entity-Component System ElizaOS uses an entity-component architecture where: - Entities are the base objects (users, agents, etc.) - Components are pieces of data attached to entities - This allows for flexible data modeling and extension For example, a user entity might have profile, preferences, and authentication components. ## Vector Search Both adapters support vector-based semantic search with some differences: - **PostgreSQL**: Uses pgvector extension for optimized vector operations - **PGLite**: Implements vector search in JavaScript with an efficient algorithm The embedding dimension is configurable based on the model used: ```typescript await adapter.ensureEmbeddingDimension(1536); // For OpenAI embeddings ``` ## FAQ ### How do I choose between PGLite and PostgreSQL? - Use **PGLite** for: - Local development and testing - Single-user deployments - Situations where installing PostgreSQL is impractical - Use **PostgreSQL** for: - Production deployments - Multi-user systems - High-volume data - When you need advanced scaling features ### How do I configure the database connection? For PostgreSQL, set the `POSTGRES_URL` environment variable: ``` POSTGRES_URL=postgresql://username:password@localhost:5432/elizaos ``` For PGLite, set the data directory (optional): ``` PGLITE_DATA_DIR=./my-data ``` ### How can I inspect the database contents? For PostgreSQL, use standard PostgreSQL tools like pgAdmin or psql. For PGLite, the data is stored in the specified data directory as files. You can use tools like DB Browser for SQLite to inspect the SQLite files that PGLite generates. ### How do I migrate between different database adapters? Currently, there's no built-in migration tool between adapters. For production systems, it's recommended to start with PostgreSQL if you anticipate needing its features. ### What about vector embedding dimension mismatches? The system automatically handles embedding dimensions based on the model used. If you change embedding models, make sure to: 1. Set the correct dimension with `ensureEmbeddingDimension()` 2. Be aware that mixing different dimensions in the same database can cause issues ### How does the entity-component system work? The entity-component system (ECS) provides a flexible way to model data: - **Entities** are base objects with unique IDs - **Components** are pieces of data attached to entities - This allows for dynamic composition of objects without complex inheritance For example, a user entity might have profile, preferences, and authentication components. ### How can I improve database performance? - For **PostgreSQL**: - Ensure the pgvector extension is properly installed - Index frequently queried fields - Use connection pooling - Consider partitioning for large datasets - For **PGLite**: - Keep database size reasonable (under 1GB) - Regularly clean up old memories - Limit the number of concurrent operations ### Will other database adapters be supported in the future? Yes, future releases will add support for additional databases such as: - MongoDB - SQLite - Supabase - Qdrant - SQL.js The adapter interface is designed to be extensible to support a wide range of storage solutions. ## Further Reading - [Entity System](./entities.md) - [Agent Runtime](./agents.md) ```` ## File: packages/docs/docs/core/entities.md ````markdown --- sidebar_position: 9 --- # Entities Entities in ElizaOS represent users, agents, or any participant that can interact within the system. They form the basis of the entity-component architecture, allowing for flexible data modeling and relationships across the platform. ![](/img/entities-component-architecture.svg) ## Entity Structure An entity in ElizaOS has the following properties: ```typescript interface Entity { /** Unique identifier, optional on creation */ id?: UUID; /** Names of the entity */ names: string[]; /** Optional additional metadata */ metadata?: { [key: string]: any }; /** Agent ID this account is related to, for agents should be themselves */ agentId: UUID; /** Optional array of components */ components?: Component[]; } ``` | Property | Description | | ------------ | -------------------------------------------------------- | | `id` | Unique identifier for the entity (optional on creation) | | `names` | Array of names the entity is known by | | `metadata` | Additional information about the entity | | `agentId` | ID of the agent related to this entity | | `components` | Array of modular data components attached to this entity | ## Components Components are modular pieces of data attached to entities with the following structure: ```typescript interface Component { id: UUID; entityId: UUID; agentId: UUID; roomId: UUID; worldId: UUID; sourceEntityId: UUID; type: string; data: { [key: string]: any; }; } ``` | Property | Description | | ---------------- | ------------------------------------------------- | | `id` | Unique identifier for the component | | `entityId` | ID of the entity this component belongs to | | `agentId` | ID of the agent managing this component | | `roomId` | ID of the room this component is associated with | | `worldId` | ID of the world this component is associated with | | `sourceEntityId` | ID of the entity that created this component | | `type` | Type of component (e.g., "profile", "settings") | | `data` | Additional data specific to this component type | ## Entity Creation and Management ### Creating an Entity ```typescript const entityId = await runtime.createEntity({ names: ['John Doe', 'JohnD'], agentId: runtime.agentId, metadata: { discord: { username: 'john_doe', name: 'John Doe', }, }, }); ``` ### Retrieving an Entity ```typescript // Get an entity by ID const entity = await runtime.getEntityById(entityId); // Get all entities in a room const entitiesInRoom = await runtime.getEntitiesForRoom(roomId, true); // true to include components ``` ### Updating an Entity ```typescript await runtime.updateEntity({ id: entityId, names: [...entity.names, 'Johnny'], metadata: { ...entity.metadata, customProperty: 'value', }, }); ``` ## Component Management Components allow for flexible data modeling by attaching different types of data to entities. ### Creating a Component ```typescript await runtime.createComponent({ id: componentId, entityId: entityId, agentId: runtime.agentId, roomId: roomId, worldId: worldId, sourceEntityId: creatorEntityId, type: 'profile', data: { bio: 'Software developer interested in AI', location: 'San Francisco', website: 'https://example.com', }, }); ``` ### Retrieving Components ```typescript // Get a specific component type const profileComponent = await runtime.getComponent( entityId, 'profile', worldId, // optional filter by world sourceEntityId // optional filter by source ); // Get all components for an entity const allComponents = await runtime.getComponents(entityId, worldId, sourceEntityId); ``` ### Updating Components ```typescript await runtime.updateComponent({ id: profileComponent.id, data: { ...profileComponent.data, bio: 'Updated bio information', }, }); ``` ### Deleting Components ```typescript await runtime.deleteComponent(componentId); ``` ## Entity Relationships Entities can have relationships with other entities, stored in the database: ```typescript // Create a relationship between entities await runtime.createRelationship({ sourceEntityId: entityId1, targetEntityId: entityId2, tags: ['friend', 'collaborator'], metadata: { interactions: 5, lastInteraction: Date.now(), }, }); // Get relationships for an entity const relationships = await runtime.getRelationships({ entityId: entityId1, tags: ['friend'], // optional filter by tags }); // Get a specific relationship const relationship = await runtime.getRelationship({ sourceEntityId: entityId1, targetEntityId: entityId2, }); // Update a relationship await runtime.updateRelationship({ ...relationship, metadata: { ...relationship.metadata, interactions: relationship.metadata.interactions + 1, lastInteraction: Date.now(), }, }); ``` ## Entity Resolution ElizaOS includes a system for resolving entity references from messages and context. This is particularly useful for determining which entity is being referenced in a conversation. ```typescript // Find an entity by name or reference const entity = await findEntityByName(runtime, message, state); ``` The entity resolution system considers: 1. Exact matches by ID or username 2. Contextual matches from recent conversations 3. Relationship strength between entities 4. Role-based permissions in worlds ## Entity Details To get formatted information about entities in a room: ```typescript // Get detailed information about entities in a room const entityDetails = await getEntityDetails({ runtime, roomId, }); // Format entities into a string representation const formattedEntities = formatEntities({ entities: entitiesInRoom }); ``` ## Relationship with Rooms and Worlds Entities participate in rooms and, by extension, in worlds: ```typescript // Add an entity as a participant in a room await runtime.addParticipant(entityId, roomId); // Get all rooms where an entity is a participant const entityRooms = await runtime.getRoomsForParticipant(entityId); // Get all participants in a room const participants = await runtime.getParticipantsForRoom(roomId); ``` When an entity is a participant in a room that belongs to a world, the entity has an implicit relationship with that world. ## Creating Unique Entity IDs For situations where you need to create deterministic, unique IDs for entity-agent pairs: ```typescript const uniqueId = createUniqueUuid(runtime, baseUserId); ``` This ensures that each user-agent interaction has a consistent, unique identifier. ## Best Practices 1. **Use meaningful names**: Provide descriptive names in the `names` array to make entity identification easier 2. **Structure metadata carefully**: Organize metadata by source (e.g., `discord`, `telegram`) for clarity 3. **Component segregation**: Use components to separate different aspects of entity data rather than storing everything in metadata 4. **Permission checking**: Always verify permissions before accessing components created by other entities 5. **Relationship maintenance**: Update relationship metadata regularly to reflect recent interactions 6. **Entity resolution**: Use the entity resolution system to correctly identify entities in conversations 7. **Deterministic IDs**: Use `createUniqueUuid` for consistent entity identification across sessions ```` ## File: packages/docs/docs/core/evaluators.md ````markdown --- sidebar_position: 7 --- # 🧠 Evaluators Evaluators are cognitive components in the ElizaOS framework that enable agents to process conversations, extract knowledge, and build understanding - similar to how humans form memories after interactions. They provide a structured way for agents to introspect, learn from interactions, and evolve over time. ## Understanding Evaluators Evaluators are specialized functions that work with the [`AgentRuntime`](/api/classes/AgentRuntime) to analyze conversations after a response has been generated. Unlike actions that create responses, evaluators perform background cognitive tasks that enable numerous advanced capabilities: - **Knowledge Building**: Automatically extract and store facts from conversations - **Relationship Tracking**: Identify connections between entities - **Conversation Quality**: Perform self-reflection on interaction quality - **Goal Tracking**: Determine if conversation objectives are being met - **Tone Analysis**: Evaluate emotional content and adjust future responses - **User Profiling**: Build understanding of user preferences and needs over time - **Performance Metrics**: Gather data on agent effectiveness and learn from interactions ### Core Structure ```typescript interface Evaluator { name: string; // Unique identifier similes?: string[]; // Alternative names/triggers description: string; // Purpose explanation examples: EvaluationExample[]; // Sample usage patterns handler: Handler; // Implementation logic validate: Validator; // Execution criteria check alwaysRun?: boolean; // Run regardless of validation } ``` ### Evaluator Execution Flow The agent runtime executes evaluators as part of its cognitive cycle: 1. Agent processes a message and generates a response 2. Runtime calls `evaluate()` after response generation 3. Each evaluator's `validate()` method determines if it should run 4. For each valid evaluator, the `handler()` function is executed 5. Results are stored in memory and inform future responses --- ## Fact Evaluator: Memory Formation System The Fact Evaluator serves as the agent's "episodic memory formation" system - similar to how humans process conversations and form memories. Just as you might reflect after a conversation "Oh, I learned something new about Sarah today", the Fact Evaluator systematically processes conversations to build up the agent's understanding of the world and the people in it. ### How It Works #### 1. Triggering (The "When to Reflect" System) ```typescript validate: async (runtime: IAgentRuntime, message: Memory): Promise => { const messageCount = await runtime.messageManager.countMemories(message.roomId); const reflectionCount = Math.ceil(runtime.getConversationLength() / 2); return messageCount % reflectionCount === 0; }; ``` Just like humans don't consciously analyze every single word in real-time, the Fact Evaluator runs periodically rather than after every message. It triggers a "reflection" phase every few messages to process what's been learned. #### 2. Fact Extraction (The "What Did I Learn?" System) The evaluator uses a template-based approach to extract three types of information: - **Facts**: Unchanging truths about the world or people - "Bob lives in New York" - "Sarah has a degree in Computer Science" - **Status**: Temporary or changeable states - "Bob is currently working on a new project" - "Sarah is visiting Paris this week" - **Opinions**: Subjective views, feelings, or non-factual statements - "Bob thinks the project will be successful" - "Sarah loves French cuisine" #### 3. Memory Deduplication (The "Is This New?" System) ```typescript const filteredFacts = facts.filter((fact) => { return ( !fact.already_known && fact.type === 'fact' && !fact.in_bio && fact.claim && fact.claim.trim() !== '' ); }); ``` Just as humans don't need to consciously re-learn things they already know, the Fact Evaluator: - Checks if information is already known - Verifies if it's in the agent's existing knowledge (bio) - Filters out duplicate or corrupted facts #### 4. Memory Storage (The "Remember This" System) ```typescript const factMemory = await factsManager.addEmbeddingToMemory({ userId: agentId!, agentId, content: { text: fact }, roomId, createdAt: Date.now(), }); ``` Facts are stored with embeddings to enable: - Semantic search of related facts - Context-aware recall - Temporal tracking (when the fact was learned) ### Example Processing Given this conversation: ``` User: "I just moved to Seattle last month!" Agent: "How are you finding the weather there?" User: "It's rainy, but I love my new job at the tech startup" ``` The Fact Evaluator might extract: ```json [ { "claim": "User moved to Seattle last month", "type": "fact", "in_bio": false, "already_known": false }, { "claim": "User works at a tech startup", "type": "fact", "in_bio": false, "already_known": false }, { "claim": "User enjoys their new job", "type": "opinion", "in_bio": false, "already_known": false } ] ``` ### Key Design Considerations 1. **Episodic vs Semantic Memory** - Facts build up the agent's semantic memory (general knowledge) - The raw conversation remains in episodic memory (specific experiences) 2. **Temporal Awareness** - Facts are timestamped to track when they were learned - Status facts can be updated as they change 3. **Confidence and Verification** - Multiple mentions of a fact increase confidence - Contradictory facts can be flagged for verification 4. **Privacy and Relevance** - Only stores relevant, conversation-appropriate facts - Respects explicit and implicit privacy boundaries --- ## Reflection Evaluator: Self-Awareness System The reflection evaluator extends beyond fact extraction to enable agents to develop a form of "self-awareness" about their conversational performance. It allows agents to: 1. Generate self-reflective thoughts about the conversation quality 2. Extract factual information from conversations (similar to the Fact Evaluator) 3. Identify and track relationships between entities ### How Reflections Work When triggered, the reflection evaluator: 1. Analyzes recent conversations and existing knowledge 2. Generates structured reflection output with: - Self-reflective thoughts about conversation quality - New facts extracted from conversation - Identified relationships between entities 3. Stores this information in the agent's memory for future reference ### Example Reflection Output ```json { "thought": "I'm engaging appropriately with John, maintaining a welcoming and professional tone. My questions are helping learn more about him as a new community member.", "facts": [ { "claim": "John is new to the community", "type": "fact", "in_bio": false, "already_known": false }, { "claim": "John found the community through a friend interested in AI", "type": "fact", "in_bio": false, "already_known": false } ], "relationships": [ { "sourceEntityId": "sarah-agent", "targetEntityId": "user-123", "tags": ["group_interaction"] }, { "sourceEntityId": "user-123", "targetEntityId": "sarah-agent", "tags": ["group_interaction"] } ] } ``` ### Implementation Details The reflection evaluator uses a defined schema to ensure consistent output: ```typescript const reflectionSchema = z.object({ facts: z.array( z.object({ claim: z.string(), type: z.string(), in_bio: z.boolean(), already_known: z.boolean(), }) ), relationships: z.array(relationshipSchema), }); const relationshipSchema = z.object({ sourceEntityId: z.string(), targetEntityId: z.string(), tags: z.array(z.string()), metadata: z .object({ interactions: z.number(), }) .optional(), }); ``` ### Validation Logic The reflection evaluator includes validation logic that determines when reflection should occur: ```typescript validate: async (runtime: IAgentRuntime, message: Memory): Promise => { const lastMessageId = await runtime.getCache( `${message.roomId}-reflection-last-processed` ); const messages = await runtime.getMemories({ tableName: 'messages', roomId: message.roomId, count: runtime.getConversationLength(), }); if (lastMessageId) { const lastMessageIndex = messages.findIndex((msg) => msg.id === lastMessageId); if (lastMessageIndex !== -1) { messages.splice(0, lastMessageIndex + 1); } } const reflectionInterval = Math.ceil(runtime.getConversationLength() / 4); return messages.length > reflectionInterval; }; ``` This ensures reflections occur at appropriate intervals, typically after a set number of messages have been exchanged. ## Common Memory Formation Patterns 1. **Progressive Learning** ```typescript // First conversation "I live in Seattle" -> Stores as fact // Later conversation "I live in the Ballard neighborhood" -> Updates/enhances existing fact ``` 2. **Fact Chaining** ```typescript // Original facts 'Works at tech startup'; 'Startup is in Seattle'; // Inference potential 'Works in Seattle tech industry'; ``` 3. **Temporal Tracking** ```typescript // Status tracking t0: 'Looking for a job'(status); t1: 'Got a new job'(fact); t2: 'Been at job for 3 months'(status); ``` 4. **Relationship Building** ```typescript // Initial relationship { "sourceEntityId": "user-123", "targetEntityId": "sarah-agent", "tags": ["new_interaction"] } // Evolving relationship { "sourceEntityId": "user-123", "targetEntityId": "sarah-agent", "tags": ["frequent_interaction", "positive_sentiment"], "metadata": { "interactions": 15 } } ``` ## Integration with Other Systems Evaluators work alongside other components: - **Goal Evaluator**: Facts and reflections may influence goal progress - **Trust Evaluator**: Fact consistency affects trust scoring - **Memory Manager**: Facts enhance context for future conversations - **Providers**: Facts inform response generation --- ## Creating Custom Evaluators You can create your own evaluators by implementing the `Evaluator` interface: ```typescript const customEvaluator: Evaluator = { name: 'CUSTOM_EVALUATOR', similes: ['ANALYZE', 'ASSESS'], description: 'Performs custom analysis on conversations', validate: async (runtime: IAgentRuntime, message: Memory): Promise => { // Your validation logic here return true; }, handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => { // Your evaluation logic here // Example of storing evaluation results await runtime.addEmbeddingToMemory({ entityId: runtime.agentId, content: { text: 'Evaluation result' }, roomId: message.roomId, createdAt: Date.now(), }); return { result: 'evaluation complete' }; }, examples: [ { prompt: `Example context`, messages: [ { name: 'User', content: { text: 'Example message' } }, { name: 'Agent', content: { text: 'Example response' } }, ], outcome: `{ "result": "example outcome" }`, }, ], }; ``` ### Registering Custom Evaluators Custom evaluators can be registered with the agent runtime: ```typescript // In your plugin's initialization export default { name: 'custom-evaluator-plugin', description: 'Adds custom evaluation capabilities', init: async (config: any, runtime: IAgentRuntime) => { // Register your custom evaluator runtime.registerEvaluator(customEvaluator); }, // Include the evaluator in the plugin exports evaluators: [customEvaluator], }; ``` ## Best Practices for Memory Formation 1. **Validate Facts** - Cross-reference with existing knowledge - Consider source reliability - Track fact confidence levels 2. **Manage Memory Growth** - Prioritize important facts - Consolidate related facts - Archive outdated status facts 3. **Handle Contradictions** - Flag conflicting facts - Maintain fact history - Update based on newest information 4. **Respect Privacy** - Filter sensitive information - Consider contextual appropriateness - Follow data retention policies 5. **Balance Reflection Frequency** - Too frequent: Computational overhead - Too infrequent: Missing important information - Adapt based on conversation complexity and pace --- ## FAQ ### What's the difference between actions and evaluators? Actions are triggered during response generation and create visible outputs, while evaluators run after responses and perform background cognitive tasks without direct user visibility. ### When should I use the Fact Evaluator vs. the Reflection Evaluator? Use the Fact Evaluator when you only need to extract and store factual information. Use the Reflection Evaluator when you need both fact extraction and relationship tracking, along with self-reflective assessment. ### How often do evaluators run? By default, evaluators run at intervals based on conversation length, typically after every few messages, to avoid unnecessary processing while still capturing important information. ### Can evaluators affect future responses? Yes! Facts and relationships stored by evaluators become part of the agent's memory and context, influencing future responses through the retrieval-augmented generation system. ### How do I debug evaluator issues? Use the logger to inspect evaluator execution and output. The most common issues involve entity resolution failures or schema validation errors. ### Can evaluators work across different platforms? Yes, evaluators are platform-agnostic and work the same way regardless of whether your agent is deployed on Discord, Twitter, Telegram, or web interfaces. ## Related Resources - [Actions Documentation](./actions.md) - [Providers Documentation](./providers.md) - [Agent Runtime](./agents.md) ```` ## File: packages/docs/docs/core/knowledge.md ````markdown # Knowledge Management ## Overview The Knowledge Management system in ElizaOS is a powerful Retrieval-Augmented Generation (RAG) feature that enables agents to process, store, and retrieve information from various sources. This allows agents to provide contextually relevant responses by leveraging stored knowledge during conversations. ## Adding Knowledge to Agents ElizaOS provides multiple ways to add knowledge to your agents, both during initialization and at runtime. ### Adding Knowledge During Runtime Creation #### 1. Via Character Definition The simplest approach is to define knowledge directly in your character configuration: ```typescript const character: Character = { name: 'My Agent', // Other character properties... knowledge: [ // Direct string knowledge 'Important fact: ElizaOS supports multiple knowledge formats', // File references { path: 'knowledge/documentation.md', shared: false }, // Directory references { directory: 'knowledge/guides', shared: true }, ], }; ``` The knowledge array supports three formats: - String literals for direct knowledge - File objects pointing to specific files - Directory objects for entire folders of content #### 2. Programmatically Before Runtime Initialization You can dynamically load knowledge before creating your runtime: ```typescript // Load knowledge from files or other sources const knowledge = []; // Example: Recursively load documentation files function loadDocumentation(directoryPath) { const files = getFilesRecursively(directoryPath, ['.md']); return files.map((filePath) => { const relativePath = path.relative(basePath, filePath); const content = fs.readFileSync(filePath, 'utf-8'); return `Path: ${relativePath}\n\n${content}`; }); } // Load documentation const docKnowledge = loadDocumentation('./docs'); knowledge.push(...docKnowledge); // Then include in your character definition const character: Character = { // Other character properties... knowledge: knowledge, }; ``` ### Adding Knowledge After Runtime Creation #### 1. Using the `addKnowledge` Method Add knowledge programmatically after the runtime is initialized: ```typescript // Import needed utilities import { createUniqueUuid } from '@elizaos/core'; // Create a knowledge item const knowledgeItem = { id: createUniqueUuid(runtime, 'unique-knowledge-identifier'), content: { text: 'Important information the agent should know...', }, }; // Add to runtime with default chunking settings await runtime.addKnowledge(knowledgeItem); // Or with custom chunking settings await runtime.addKnowledge(knowledgeItem, { targetTokens: 1500, // Target chunk size (default: 3000) overlap: 100, // Overlap between chunks (default: 200) modelContextSize: 8192, // Context size of your model (default: 4096) }); ``` #### 2. Processing Files at Runtime You can dynamically process files at runtime: ```typescript // For PDF files, use the PDF service const pdfService = runtime.getService('pdf'); if (pdfService) { const pdfBuffer = fs.readFileSync('./knowledge/document.pdf'); const textContent = await pdfService.convertPdfToText(pdfBuffer); const knowledgeItem = { id: createUniqueUuid(runtime, 'document.pdf'), content: { text: textContent }, }; await runtime.addKnowledge(knowledgeItem); } ``` ## Directory Structure ElizaOS expects knowledge files to be organized in the following structure: ``` knowledge/ # Root knowledge directory ├── shared/ # Shared knowledge accessible to all agents └── {agent-name}/ # Agent-specific knowledge directories ``` ## Supported File Types - PDF files (`.pdf`) - Markdown files (`.md`) - Text files (`.txt`) ## Knowledge Modes ElizaOS supports two knowledge modes: ### Classic Mode (Default) - Direct string knowledge added to character's context - No chunking or semantic search - Enabled by default (`settings.ragKnowledge: false`) - Only processes string knowledge entries - Simpler but less sophisticated ### RAG Mode - Advanced knowledge processing with semantic search - Chunks content and uses embeddings - Must be explicitly enabled (`settings.ragKnowledge: true`) - Supports three knowledge types: 1. Direct string knowledge 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` - Supported file types: .md, .txt, .pdf - Optional `shared` flag for knowledge reuse across characters To enable RAG mode, add this to your character settings: ```typescript const character: Character = { // Other character properties... settings: { ragKnowledge: true, }, }; ``` ## How Knowledge Processing Works ### Document Processing Flow The RAG system processes documents through several stages: 1. **Directory Processing** - The system scans configured directories in `knowledge/` - Files are processed based on their shared/private status and file type 2. **File Processing Pipeline** - **Preprocessing**: Reading, cleaning, and normalizing text - **Document-level Processing**: Generating embeddings for the entire document - **Chunk Processing**: Splitting content into manageable chunks and generating embeddings for each 3. **Retrieval Process** - When a user message is received, its embedding is generated - This embedding is compared to stored knowledge embeddings - The most semantically similar chunks are retrieved - Retrieved knowledge is incorporated into the agent's context This multi-level approach enables: - Broad document-level semantic search - Fine-grained chunk-level retrieval for specific information - Efficient parallel processing of large documents - Maintenance of document context through metadata linking ### Knowledge Processing Flow Diagram ```mermaid graph TB subgraph Directory_Processing A[Read Files from Directory] --> B[File Content] end subgraph Preprocessing B --> C[Clean & Normalize Text] end subgraph Document_Processing C --> D[Generate Document Embedding] D --> E[Store Full Document] E --> |Metadata| F[File Path] E --> |Metadata| G[File Type] E --> |Metadata| H[Shared Status] end subgraph Chunk_Processing C --> I[Split into Chunks] I --> |512 tokens| J[Chunk 1] I --> |20 token overlap| K[...] I --> L[Chunk N] subgraph Parallel_Processing J --> M1[Generate Embedding] K --> M2[Generate Embedding] L --> M3[Generate Embedding] end subgraph Chunk_Storage M1 --> N1[Store Chunk] M2 --> N2[Store Chunk] M3 --> N3[Store Chunk] N1 --> |Metadata| O[Original Doc Reference] N1 --> |Metadata| P[Chunk Index] N2 --> |Metadata| O N2 --> |Metadata| P N3 --> |Metadata| O N3 --> |Metadata| P end end style Directory_Processing fill:#f9f,stroke:#333,stroke-width:2px style Preprocessing fill:#bbf,stroke:#333,stroke-width:2px style Document_Processing fill:#bfb,stroke:#333,stroke-width:2px style Chunk_Processing fill:#fbf,stroke:#333,stroke-width:2px style Parallel_Processing fill:#fbb,stroke:#333,stroke-width:2px style Chunk_Storage fill:#bff,stroke:#333,stroke-width:2px ``` ### Processing Parameters - **Chunk Size**: 512 tokens (default, configurable when adding knowledge) - **Chunk Overlap**: 20 tokens (default, configurable) - **Processing Batch Size**: 10 chunks processed concurrently - **Default Similarity Threshold**: 0.85 for retrieval - **Default Match Count**: 5 results returned ## Best Practices for Knowledge Management ### Content Organization 1. **Document Structure** - Use clear section headings and hierarchical organization - Break large documents into logical smaller files - Include metadata and context in markdown files - Structure information from general to specific 2. **File Management** - Use descriptive filenames that reflect content - Group related files in subdirectories - Keep paths short and meaningful - Avoid special characters in filenames 3. **Knowledge Optimization** - Keep individual documents focused on specific topics - For very detailed information, use smaller chunks (200-300 tokens) by setting `targetTokens` - Balance the total number of knowledge items for performance - Prefer markdown (.md) files for best processing results ### Processing Large Knowledge Bases When adding many knowledge items at once, consider implementing a semaphore pattern: ```typescript import { Semaphore } from '@elizaos/core'; // Create semaphore to limit concurrent processing const semaphore = new Semaphore(10); // Process items with controlled concurrency await Promise.all( items.map(async (item) => { await semaphore.acquire(); try { await runtime.addKnowledge(item); } finally { semaphore.release(); } }) ); ``` ### Knowledge ID Management When adding knowledge programmatically, use consistent ID generation: ```typescript import { createUniqueUuid } from '@elizaos/core'; const knowledgeId = createUniqueUuid(runtime, 'my-content'); ``` This ensures deterministic IDs that remain stable across sessions. ## Troubleshooting ### Common Issues and Solutions 1. **Knowledge Not Being Retrieved**: - Verify the file is in a supported format (PDF, MD, TXT) - Check if embeddings were properly generated - Ensure similarity threshold isn't too high (default: 0.85) - Test retrieval with more specific queries - Verify RAG mode is enabled if using file/directory references 2. **Poor Quality Retrievals**: - Break down large documents into smaller, focused files - Ensure document content is clear and well-structured - Review the chunking size and overlap settings - Check if the query contains too many common words 3. **Performance Issues**: - Monitor the total number of knowledge items - Consider reducing the match count for faster retrieval - Check embedding processing time for large documents - Use shared knowledge efficiently across agents 4. **File Processing Errors**: - Verify file permissions - Check if paths are correctly structured - Ensure PDF files are readable and not password-protected - Validate that text encoding is UTF-8 ## Technical Implementation Details ### Knowledge ID Relationships The RAG system uses a hierarchical ID structure to maintain relationships: ```mermaid classDiagram class Document { +UUID id +String filePath +String fileType +Boolean isShared +Float32Array embedding +String content } class Fragment { +UUID id +UUID originalId +Number chunkIndex +String content +Float32Array embedding +String originalPath } Document "1" --> "*" Fragment : generates ``` #### ID Generation and Linking Documents IDs are generated using `createUniqueUuid(runtime, path, isShared)`, making them deterministic. Fragment IDs follow the format `${documentId}-chunk-${index}` to maintain the relationship to their source document. ## API Reference ### Key Methods #### `runtime.addKnowledge(item: KnowledgeItem, options?): Promise` Adds new knowledge to the agent. - Parameters: - `item`: A knowledge item containing: - `id`: UUID - `content`: Object with `text` property - `options`: Optional processing configuration: - `targetTokens`: Number (default: 3000) - `overlap`: Number (default: 200) - `modelContextSize`: Number (default: 4096) #### `runtime.getKnowledge(message: Memory): Promise` Retrieves knowledge based on a message's content. - Parameters: - `message`: Memory object containing user message - Returns: Array of matching KnowledgeItem objects ### Knowledge Item Definition ```typescript interface KnowledgeItem { id: UUID; content: { text: string; // Optional additional metadata [key: string]: any; }; } ``` ## Security Considerations 1. **Access Control**: - Use the `shared` flag appropriately to control document access - Keep sensitive information in agent-specific directories - Regularly audit knowledge access patterns 2. **Data Privacy**: - Do not store sensitive personal information in knowledge files - Review documents for potentially sensitive content before adding - Implement appropriate backup and recovery procedures ## Future Considerations 1. **Scalability**: - Monitor knowledge base size and performance - Plan for regular maintenance and cleanup - Consider implementing document versioning 2. **Integration**: - Document integration points with other systems - Plan for potential future file format support - Consider implementing knowledge base analytics ## Support and Resources - Review the implementation in `packages/core/src/ragknowledge.ts` - Check the issue tracker for known issues and solutions - Contribute improvements and bug fixes through pull requests ```` ## File: packages/docs/docs/core/overview.md ````markdown --- sidebar_position: 1 title: ElizaOS Documentation slug: / description: Comprehensive framework for building AI agents with persistent personalities across multiple platforms --- # ElizaOS Documentation Welcome to ElizaOS - a comprehensive framework for building AI agents with persistent personalities across multiple platforms. ElizaOS provides the architecture, tools, and systems needed to create sophisticated agents that maintain consistent behavior, learn from interactions, and seamlessly integrate with a variety of services. > **New to ElizaOS?** Check out [What's new in ElizaOS V2](https://eliza.how/blog/v1-v2) to understand how it compares to previous versions. ## System Architecture ElizaOS uses a modular architecture that separates concerns while providing a cohesive framework for AI agent development: ```mermaid graph TB %% Main Components with vertical orientation User((User)):::user %% First Level - Services PlatformServices[Services]:::services %% Second Level - Runtime AgentRuntime[Agent Runtime]:::core %% Core Processing Components - Side by side subgraph "Core Processing" direction LR Providers[Providers]:::int Actions[Actions]:::int Evaluators[Evaluators]:::int end %% Knowledge and DB - Side by side subgraph "Knowledge & Storage" direction LR Knowledge[Knowledge]:::int DB[(Database)]:::db end %% Organization Components - Vertical layout subgraph "Organization" direction TB Worlds[Worlds]:::struct Rooms[Rooms]:::struct Entities[Entities]:::struct end %% Development Components - Side by side subgraph "Development & Integration" direction LR Plugins[Plugins]:::dev Projects[Projects]:::dev Tasks[Tasks]:::dev end %% Main Flow - Vertical emphasis User <-->|Interaction| PlatformServices PlatformServices -->|Process| AgentRuntime %% Runtime connections - Simplified AgentRuntime ---|Context| Providers AgentRuntime ---|Behavior| Actions AgentRuntime ---|Analysis| Evaluators %% Data connections AgentRuntime <-->|Storage| DB Knowledge -->|Informs| Providers %% Structure connections - Clean vertical hierarchy AgentRuntime -->|Manages| Worlds Worlds -->|Contains| Rooms Rooms -->|Has| Entities %% Development connections Projects -->|Configure| AgentRuntime Plugins -->|Extend| AgentRuntime Tasks -->|Scheduled by| AgentRuntime %% Clickable nodes with links to docs click AgentRuntime "/docs/core/agents" "Learn about Agent Runtime" click PlatformServices "/docs/core/services" "Learn about Services" click DB "/docs/core/database" "Learn about Database Systems" click Actions "/docs/core/actions" "Learn about Actions" click Providers "/docs/core/providers" "Learn about Providers" click Evaluators "/docs/core/evaluators" "Learn about Evaluators" click Knowledge "/docs/core/knowledge" "Learn about Knowledge System" click Worlds "/docs/core/worlds" "Learn about Worlds" click Rooms "/docs/core/rooms" "Learn about Rooms" click Entities "/docs/core/entities" "Learn about Entities" click Plugins "/docs/core/plugins" "Learn about Plugins" click Projects "/docs/core/project" "Learn about Projects" click Tasks "/docs/core/tasks" "Learn about Tasks" %% Styling classDef core fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold classDef services fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold classDef int fill:#e74c3c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold classDef struct fill:#f39c12,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold classDef dev fill:#1abc9c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold classDef user fill:#ecf0f1,stroke:#2c3e50,stroke-width:2px,color:#2c3e50,font-weight:bold,border-radius:50% ``` ### How ElizaOS Works When a user message is received: 1. **Service Reception**: Platform service (Discord, Telegram, etc.) receives the message 2. **Runtime Processing**: Agent runtime coordinates the response generation 3. **Context Building**: Providers supply relevant context (time, recent messages, knowledge) 4. **Action Selection**: The agent evaluates and selects appropriate actions 5. **Response Generation**: The chosen action generates a response 6. **Learning & Reflection**: Evaluators analyze the conversation for insights and learning 7. **Memory Storage**: New information is stored in the database 8. **Response Delivery**: The response is sent back through the service This creates a continuous cycle of interaction, reflection, and improvement that allows agents to maintain consistent personalities while adapting to new information. ## Core Components
Overview

🤖 Agent Runtime

The central system that orchestrates agent behavior, processes messages, manages state, and coordinates all other components.

Overview

📚 Services

Platform-specific integrations that enable agents to communicate across Discord, Twitter, Telegram, and other channels.

Overview

💾 Database

Persistent storage for memories, entity data, relationships, and configuration using vector search capabilities.

## Intelligence & Behavior
Overview

⚡ Actions

Executable capabilities that define how agents respond to messages and interact with external systems.

Overview

🔌 Providers

Data sources that supply contextual information to inform agent decision-making in real-time.

Overview

📊 Evaluators

Analytical systems that process conversations to extract insights, learn facts, and improve future responses.

Overview

🧠 Knowledge

RAG system for document processing, semantic search, and context-aware memory retrieval.

## Structure & Organization
Overview

🌐 Worlds

Collection spaces that organize entities and rooms into coherent environments (like a Discord server).

Overview

💬 Rooms

Conversation spaces where entities interact through messages (channels, DMs, threads).

Overview

👤 Entities

Representation of users, agents, and other participants using a flexible entity-component architecture.

## Development & Integration
Overview

🧩 Plugins

Modular extensions that add new capabilities, integrations, and behaviors to agents.

Overview

📝 Projects

Organizational structure for defining and deploying one or more agents with their configuration.

Overview

📋 Tasks

System for managing deferred, scheduled, and repeating operations across conversations.

--- ## Key Concepts ### Action-Provider-Evaluator Cycle The core of the ElizaOS system operates as a continuous cycle: 1. **Providers** gather context before response generation 2. **Actions** determine what the agent can do and are executed to generate responses 3. **Evaluators** analyze conversations after responses to extract insights 4. These insights become part of the agent's memory 5. Future **Providers** access this memory to inform new responses This creates a virtuous cycle where agents continuously learn and improve from interactions. ### Entity-Component Architecture ElizaOS uses an entity-component architecture for flexible data modeling: - **Entities** are base objects with unique IDs (users, agents, etc.) - **Components** are pieces of data attached to entities (profiles, settings, etc.) - This approach allows for dynamic composition without complex inheritance hierarchies ### Memory System The memory system in ElizaOS provides: - **Vector-based semantic search** for finding relevant memories - **Multi-level memory types** (messages, facts, knowledge) - **Temporal awareness** through timestamped memories - **Cross-platform continuity** while maintaining appropriate context boundaries ## Getting Started If you're new to ElizaOS, we recommend this learning path: 1. Start with this overview to understand the system architecture 2. Explore the [Agent Runtime](/docs/core/agents) to understand the core system 3. Learn about [Projects](/docs/core/project) to set up your development environment 4. Understand how [Actions](/docs/core/actions) and [Providers](/docs/core/providers) work together 5. Explore [Services](/docs/core/services) to connect with external platforms 6. Dive into [Plugins](/docs/core/plugins) to extend functionality ## FAQ **What's the difference between Actions, Evaluators, and Providers?** Actions define what an agent can do and are executed during response generation. Evaluators analyze conversations after they happen to extract insights and improve future responses. Providers supply contextual information before the agent decides how to respond. **How does ElizaOS handle cross-platform conversation context?** ElizaOS maintains separate conversation contexts for different platforms by default, but shares entity relationships and learned facts across platforms. This ensures agents maintain a consistent understanding of users while respecting platform-specific conversation boundaries. **How does the memory system work?** Memory is organized into different types (messages, facts, knowledge) and stored with vector embeddings for semantic search. This allows agents to retrieve relevant memories based on context rather than just recency, creating more natural conversations. **What's the relationship between Worlds, Rooms, and Entities?** Worlds are container spaces (like a Discord server) that can have multiple Rooms (channels, DMs). Entities (users, agents) participate in Rooms within Worlds. This hierarchical structure mirrors real-world platforms while providing a consistent abstraction. **How extensible is ElizaOS?** ElizaOS is highly extensible through its plugin system. You can create custom actions, providers, evaluators, services, and more to extend functionality. The architecture is designed to be modular and composable at every level. ## Additional Resources - [API Reference](/api) - Detailed API documentation for developers - [GitHub Repository](https://github.com/elizaos/eliza) - Source code and contributions - [Package Showcase](/packages) - Explore available plugins and extensions ```` ## File: packages/docs/docs/core/plugins.md ````markdown # Plugins import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; Plugins are modular extensions that enhance the capabilities of ElizaOS agents. They provide a flexible way to add new functionality, integrate external services, and customize agent behavior across different platforms. :::info Key Improvements in V2 1. **Unified API**: Almost everything is accessible via `runtime.methodName()` in the agent runtime for simpler development 2. **Enhanced Model System**: The new `useModel` approach allows for flexible model provider registration 3. **Events System**: Formal support for event-based programming 4. **Plugin Creation Workflow**: Simplified creation and testing via CLI 5. **Testing Infrastructure**: Built-in support for plugin testing 6. **No Monorepo Required**: Complete plugin development without touching the core codebase 7. **Plugin Registry**: Manages the catalog of available plugins and handles their registration with the runtime 8. **Bootstrap Plugin**: Initializes core functionality required for all agents to operate ::: The ElizaOS plugin system maintains the same basic concept as previous versions, with several new extension points (events, routes, tests, models) and features that significantly improve the developer experience. **Browse plugins the elizaOS community made here: [Package Showcase](/packages)** [![](/img/plugins.png)](/packages) > elizaOS maintains an official package registry at [github.com/elizaos-plugins/registry](https://github.com/elizaos-plugins/registry). --- ## Quick Start The new CLI tool introduces a streamlined workflow for plugin development without ever needing to touch the ElizaOS monorepo directly: 1. **Create**: `npm create eliza` - Initialize a new plugin project with proper structure 2. **Develop**: Edit the plugin code in the generated project structure 3. **Test**: `npx elizaos test` - Test the plugin functionality 4. **Run**: `npx elizaos start` - Run the plugin with a default agent 5. **Publish**: `npx elizaos publish` - Share your plugin with others > Note: at time of publishing, use `npm create eliza@beta` until main version is uploaded ### Creating a New Plugin You can create a new ElizaOS plugin using the CLI: ```bash # Using npm npm create eliza@beta # Or using npx npx @elizaos/cli@beta create ``` When prompted, select "Plugin" as the type to create. The CLI will guide you through the setup process, creating a plugin with the proper structure and dependencies. --- ### Managing Plugins There are several ways to add plugins to your ElizaOS project: ```json { "dependencies": { "@elizaos/plugin-solana": "github:elizaos-plugins/plugin-solana", "@elizaos/plugin-twitter": "github:elizaos-plugins/plugin-twitter" } } ``` ```typescript // In src/index.ts export const character: Character = { name: 'MyAgent', plugins: ['@elizaos/plugin-twitter', '@elizaos/plugin-example'], // ... }; ``` ```bash # Add a plugin npx @elizaos/cli plugins add @elizaos/plugin-twitter # Remove a plugin npx @elizaos/cli plugins remove @elizaos/plugin-twitter # List available plugins npx @elizaos/cli plugins list ``` --- ### Plugin Configuration Configure plugin settings in your character definition: ```json { "name": "MyAgent", "plugins": ["@elizaos/plugin-example"], "settings": { "example": { "enableFeatureX": true // Plugin-specific configuration } } } ``` ### Plugin Loading Process The AgentRuntime automatically loads the Bootstrap Plugin during initialization, before any other plugins: ```typescript async initialize() { // Register bootstrap plugin await this.registerPlugin(bootstrapPlugin); // Then register additional plugins for (const plugin of this.plugins) { await this.registerPlugin(plugin); } // Initialize other components // ... } ``` --- ### Publishing Plugins If you're a plugin developer, you can publish your plugin to make it available to others. The ElizaOS CLI provides several options for publishing your plugin depending on your needs. First, make sure your plugin is built and ready for distribution: ```bash # Navigate to your plugin directory cd my-eliza-plugin # Build your plugin npm run build ``` Publishing to GitHub is the recommended approach for sharing your plugin with the ElizaOS community: ```bash # Publish to GitHub npx @elizaos/cli publish ``` This will: 1. Build and package your plugin 2. Create or update a GitHub repository in the elizaos-plugins organization 3. Add your plugin to the ElizaOS registry (if you're a registry maintainer) For first-time publishers, the CLI will guide you through setting up GitHub credentials for publishing. GitHub publishing is ideal for open-source plugins that you want to share with the community and have listed in the official registry. You can also publish your plugin to npm: ```bash # Publish to npm npx @elizaos/cli publish --npm ``` This allows users to install your plugin using standard npm commands: ```bash npm install @your-scope/plugin-name ``` npm publishing is useful when you want to: - Maintain your own package namespace - Integrate with existing npm workflows - Set up automated versioning and releases Make sure your package.json is properly configured with the correct name, version, and access permissions. Before publishing, you can validate the process without making any external changes: ```bash # Test the publish process npx @elizaos/cli publish --test ``` This runs through all the packaging and validation steps without actually publishing anything. Test mode is helpful for: - Verifying your plugin structure is correct - Ensuring all required files are present - Checking that dependencies are properly configured - Validating that your plugin can be built successfully Always run in test mode before your first public release to avoid issues. The publish command supports several additional options to customize the publishing process: ```bash # Specify platform compatibility npx @elizaos/cli publish --platform node # Set custom version number npx @elizaos/cli publish --version 1.2.3 # Provide a custom registry URL npx @elizaos/cli publish --registry https://custom-registry.com # Publish with public access npx @elizaos/cli publish --access public ``` These options give you fine-grained control over how and where your plugin is published. Refer to `npx @elizaos/cli publish --help` for a complete list of options. :::info When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: 1. **Working Demo**: Screenshots or video of your plugin in action 2. **Test Results**: Evidence of successful integration and error handling 3. **Configuration Example**: Show how to properly configure your plugin ::: --- ## Plugin Architecture Eliza uses a unified plugin architecture where everything is a plugin - including services, adapters, actions, evaluators, and providers. This approach ensures consistent behavior and better extensibility. ### Plugin Components Each plugin can provide one or more of the following components: | Component | Purpose | | ------------------ | ------------------------------------------------------------------------------- | | **Services** | Platform integrations (Discord, Twitter, etc.) or specialized capabilities | | **Actions** | Executable functions triggered by the agent (reply, generate content, etc.) | | **Providers** | Context providers that supply info to the agent during decision making | | **Evaluators** | Analyze conversations to extract insights and improve future interactions | | **Adapters** | Database or storage system integrations | | **Model Handlers** | Register handlers for different model types (text generation, embeddings, etc.) | | **Event Handlers** | React to system events like messages, connections, or actions | | **API Routes** | Add custom REST endpoints to the agent's HTTP interface | | **Tests** | Include test suites to verify plugin functionality | ### Plugin Interface All plugins implement the core Plugin interface: ```typescript interface Plugin { name: string; description: string; config?: { [key: string]: any }; // Optional initialization method init?: (config: Record, runtime: IAgentRuntime) => Promise; // Components services?: (typeof Service)[]; actions?: Action[]; providers?: Provider[]; evaluators?: Evaluator[]; adapters?: Adapter[]; // Additional features routes?: Route[]; tests?: TestSuite[]; events?: { [key: string]: ((params: any) => Promise)[] }; } ``` ### Service Implementation Services are the core integration points for external platforms. A properly implemented service: ```typescript import { Service, IAgentRuntime } from '@elizaos/core'; export class ExampleService extends Service { // Required: Define the service type (used for runtime registration) static serviceType = 'example'; // Required: Describe what this service enables the agent to do capabilityDescription = 'Enables the agent to interact with the Example platform'; // Store runtime for service operations constructor(protected runtime: IAgentRuntime) { super(); // Initialize connections, setup event handlers, etc. } // Required: Static method to create and initialize service instance static async start(runtime: IAgentRuntime): Promise { const service = new ExampleService(runtime); // Additional initialization if needed return service; } // Required: Clean up resources when service is stopped async stop(): Promise { // Close connections, release resources } // Optional: Custom methods for your service functionality async sendMessage(content: string, channelId: string): Promise { // Implementation } } ``` ## Plugin Structure Each plugin repository should follow this structure: ``` plugin-name/ ├── images/ # Branding assets │ ├── logo.png # Square logo (400x400px) │ ├── banner.png # Banner image (1280x640px) │ └── screenshots/ # Feature screenshots ├── src/ │ ├── index.ts # Main plugin entry point │ ├── service.ts # Service implementation │ ├── actions/ # Plugin-specific actions │ ├── providers/ # Data providers │ ├── types.ts # Type definitions │ └── environment.ts # Configuration validation ├── tests/ # Test suite ├── package.json # Plugin configuration and dependencies └── README.md # Plugin documentation ``` ### Plugin Entry Point Your plugin's `index.ts` should export a Plugin object: ```typescript // Example plugin implementation import { type Plugin } from '@elizaos/core'; import { ExampleService } from './service'; import { searchAction } from './actions/search'; import { statusProvider } from './providers/status'; const examplePlugin: Plugin = { name: 'example', description: 'Example platform integration for ElizaOS', services: [ExampleService], actions: [searchAction], providers: [statusProvider], init: async (config, runtime) => { // Perform any necessary initialization const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); if (!apiKey) { console.warn('EXAMPLE_API_KEY not provided'); } }, }; export default examplePlugin; ``` ### Plugin Configuration Your plugin's `package.json` should include an `agentConfig` section: ```json { "name": "@elizaos/plugin-example", "version": "1.0.0", "agentConfig": { "pluginType": "elizaos:plugin:1.0.0", "pluginParameters": { "API_KEY": { "type": "string", "description": "API key for the Example service" } } } } ``` ### Environment Variables and Secrets Plugins access configuration through the runtime with the following precedence: 1. Character settings secrets (highest priority) 2. Character settings 3. Global environment settings #### Access Pattern ```typescript // In your service implementation const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); const debugMode = runtime.getSetting('EXAMPLE_DEBUG_MODE'); // Returns boolean for "true"/"false" strings ``` #### Configuration in Character File ```json { "name": "MyAgent", "plugins": ["@elizaos/plugin-example"], "settings": { "example": { "enableFeatureX": true }, "secrets": { "EXAMPLE_API_KEY": "your-api-key-here" } } } ``` --- ## Bootstrap Plugin The Bootstrap Plugin is a foundational component of ElizaOS that initializes the core functionality required for agents to operate. It's automatically loaded as part of the initialization process, establishing the minimum viable capabilities that all agents need. ```typescript export const bootstrapPlugin: Plugin = { name: 'bootstrap', description: 'Agent bootstrap with basic actions and evaluators', actions: [...], events: {...}, evaluators: [...], providers: [...], services: [TaskService, ScenarioService], }; ``` The Bootstrap Plugin registers essential components across several categories to provide a foundation for all agents. These components can be extended by custom plugins. | Action | Description | | ---------------------- | ----------------------------------------------- | | `replyAction` | Generates and sends a response to a message | | `followRoomAction` | Enables an agent to actively follow a room | | `unfollowRoomAction` | Stops an agent from following a room | | `muteRoomAction` | Mutes notifications from a room | | `unmuteRoomAction` | Unmutes notifications from a room | | `sendMessageAction` | Sends a message to a specific room | | `ignoreAction` | Explicitly ignores a message | | `noneAction` | Acknowledges a message without taking action | | `updateEntityAction` | Updates properties of an entity | | `choiceAction` | Presents choices to users and handles responses | | `updateRoleAction` | Updates a user's role in a world | | `updateSettingsAction` | Updates agent or world settings | | Provider | Description | | ------------------------ | ---------------------------------------------------------- | | `characterProvider` | Provides the agent's personality and configuration | | `recentMessagesProvider` | Retrieves recent conversation history | | `knowledgeProvider` | Supplies factual information from the knowledge base | | `timeProvider` | Provides awareness of current time and date | | `entitiesProvider` | Supplies information about entities in the current context | | `relationshipsProvider` | Provides information about entity relationships | | `factsProvider` | Retrieves relevant facts from memory | | `roleProvider` | Provides role information within worlds | | `settingsProvider` | Supplies configured settings | | `anxietyProvider` | Informs agent of potential issues to be careful about | | `attachmentsProvider` | Handles media and file attachments | | `providersProvider` | Meta-provider with information about available providers | | `actionsProvider` | Meta-provider with information about available actions | | `evaluatorsProvider` | Meta-provider with information about available evaluators | | `choiceProvider` | Manages choice-based interactions | | `capabilitiesProvider` | Provides information about agent capabilities | **Services:** | Service | Purpose | | ----------------- | ------------------------------------------------ | | `TaskService` | Manages deferred, scheduled, and repeating tasks | | `ScenarioService` | Handles scenario-based interactions and testing | **Evaluators:** | Evaluator | Description | | --------------------- | ----------------------------------------------------- | | `reflectionEvaluator` | Enables self-awareness and learning from interactions | The Bootstrap Plugin registers handlers for key system events that enable the core message processing flow: **Core Events:** - `MESSAGE_RECEIVED` - Processes new messages and generates responses - `REACTION_RECEIVED` - Tracks reactions to messages - `VOICE_MESSAGE_RECEIVED` - Handles audio messages - `POST_GENERATED` - Creates social media content - `MESSAGE_SENT` - Logs outgoing messages **World Events:** - `WORLD_JOINED` / `WORLD_CONNECTED` - Synchronizes data when joining worlds - `ENTITY_JOINED` / `ENTITY_LEFT` - Manages entity presence **Lifecycle Events:** - `ACTION_STARTED` / `ACTION_COMPLETED` - Tracks action execution - `EVALUATOR_STARTED` / `EVALUATOR_COMPLETED` - Monitors evaluator processing - `RUN_STARTED` / `RUN_ENDED` / `RUN_TIMEOUT` - Manages message processing lifecycle The message processing flow follows these steps: 1. Receive message via `MESSAGE_RECEIVED` event 2. Save message to memory 3. Check if agent should respond 4. If responding, compose state from providers 5. Generate a response using the language model 6. Process any actions specified in the response 7. Run evaluators on the conversation 8. Emit lifecycle events throughout the process ### Extending Bootstrap Functionality While the Bootstrap Plugin provides core functionality, it's designed to be extended by other plugins. Custom plugins can: 1. **Add new actions** - Extend the agent's capabilities 2. **Register additional providers** - Supply more contextual information 3. **Add evaluators** - Create new ways to analyze and learn from interactions 4. **Handle additional events** - React to more system events 5. **Initialize custom services** - Provide new functionality When working with plugins in relation to the Bootstrap Plugin: 1. **Don't modify bootstrap directly** - Instead, create custom plugins to extend functionality 2. **Understand provider contribution** - Know how each provider contributes to the agent's context 3. **Learn the core actions** - Become familiar with the actions that all agents can perform 4. **Leverage event handlers** - Use the event system for reactive behavior 5. **Extend, don't replace** - Build on top of bootstrap functionality rather than replacing it --- ## Developing a Plugin When developing a new plugin, focus on these key aspects: 1. **Service Implementation**: Create a solid service class following the pattern above 2. **Proper Error Handling**: Handle API failures gracefully 3. **Type Definitions**: Define clear interfaces and types 4. **Documentation**: Include detailed setup instructions 5. **Tests**: Add test cases for your functionality ### Testing Your Plugin During development, you can test your plugin locally: ```bash # Start with your plugin npx @elizaos/cli start --plugin=./path/to/plugin # Or with a specific character npx @elizaos/cli start --character=./characters/test.character.json --plugin=./path/to/plugin ``` ### Distribution & PR Requirements When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: 1. **Working Demo**: Screenshots or video of your plugin in action 2. **Test Results**: Evidence of successful integration and error handling 3. **Configuration Example**: Show how to properly configure your plugin 4. **Quality Checklist**: - [ ] Plugin follows the standard structure - [ ] Required branding assets are included - [ ] Documentation is complete - [ ] GitHub topics properly set - [ ] Tests are passing - [ ] Includes error handling --- ## FAQ ### What exactly is a plugin in ElizaOS? A plugin is a modular extension that adds new capabilities to ElizaOS agents, such as API integrations, custom actions, or platform connections. Plugins allow you to expand agent functionality and share reusable components with other developers. ### When should I create a plugin versus using existing ones? Create a plugin when you need custom functionality not available in existing plugins, want to integrate with external services, or plan to share reusable agent capabilities with the community. ### How do I manage plugin dependencies? Plugin dependencies are managed through your project's `package.json`. You can add plugins directly using npm or the ElizaOS CLI, and they will be automatically loaded when your project starts. ### Can I use a plugin in development before publishing? Yes, you can use the `--plugin` flag with the `start` command to include local plugins during development: ```bash npx @elizaos/cli start --plugin=./path/to/plugin ``` ### What's the difference between Actions and Services? Actions handle specific agent responses or behaviors, while Services provide platform integrations (like Discord or Twitter) or ongoing background functionality that multiple actions might use. ### How do I handle rate limits with external APIs? Implement proper backoff strategies in your service implementation and consider using a queue system for message handling to respect platform rate limits. ## Additional Resources - [ElizaOS Registry](https://github.com/elizaos-plugins/registry) - [Example Plugins](https://github.com/elizaos-plugins) - [Discord Community](https://discord.gg/elizaos) ```` ## File: packages/docs/docs/core/project.md ````markdown # 📝 ElizaOS Projects Projects are the main organizational structure in ElizaOS, containing all the necessary components to create and deploy AI agents. A project can include one or more agents, each with their own character definition, plugins, and configurations. ## Project Structure A typical ElizaOS project structure: ``` my-eliza-project/ ├── src/ │ └── index.ts # Main entry point ├── knowledge/ # Knowledge base files ├── package.json # Dependencies and scripts └── tsconfig.json # TypeScript configuration ``` ## Creating a New Project You can create a new ElizaOS project using: ```bash # Using npm npm create eliza@beta # Or using npx npx @elizaos/cli@beta create ``` The CLI will guide you through the setup process, including: - Project name - Database selection (pglite, postgres, etc.) - Initial configuration ## Project Configuration The main project file (`src/index.ts`) exports a default project object: ```typescript import type { Character, IAgentRuntime, Project, ProjectAgent } from '@elizaos/core'; import customPlugin from './plugin'; // Define the character export const character: Character = { name: 'Agent Name', plugins: ['@elizaos/plugin-discord', '@elizaos/plugin-direct'], // Other character properties }; // Create a ProjectAgent that includes the character export const projectAgent: ProjectAgent = { character, init: async (runtime: IAgentRuntime) => { // Initialize agent-specific functionality console.log('Initializing agent:', character.name); }, plugins: [customPlugin], tests: [], // Optional tests for your agent }; // Export the full project with all agents const project: Project = { agents: [projectAgent], }; export default project; ``` ## Character Configuration Each agent in your project requires a character definition that controls its personality, knowledge, and behavior. ### Required Character Fields ```typescript { name: "agent_name", // Character's display name plugins: ["@elizaos/plugin-discord"], // Example plugins settings: { // Configuration settings secrets: {}, // API keys and sensitive data voice: {}, // Voice configuration }, bio: [], // Character background as a string or array of statements style: { // Interaction style guide all: [], // General style rules chat: [], // Chat-specific style post: [] // Post-specific style } } ``` ### Plugins Plugins provide your agent with capabilities and integrations: - `@elizaos/plugin-discord`: Discord integration - `@elizaos/plugin-telegram`: Telegram integration - `@elizaos/plugin-twitter`: Twitter/X integration - `@elizaos/plugin-slack`: Slack integration - `@elizaos/plugin-direct`: Direct chat interface - `@elizaos/plugin-simsai`: SimsAI platform integration View all available plugins: https://github.com/elizaos-plugins/registry ### Settings Configuration The `settings` object supports various configurations: ```typescript { "settings": { "ragKnowledge": false, // Enable RAG knowledge mode "voice": { "model": "string", // Voice synthesis model "url": "string" // Optional voice API URL }, "secrets": { // API keys (use env vars in production) "API_KEY": "string" }, } } ``` ### Bio & Style Define your agent's personality and communication style: ```typescript { "bio": ["Expert in blockchain development", "Specializes in DeFi protocols"], "style": { "all": [ // Applied to all interactions "Keep responses clear", "Maintain professional tone" ], "chat": [ // Chat-specific style "Engage with curiosity", "Provide explanations" ], "post": [ // Social post style "Keep posts informative", "Focus on key points" ] } } ``` **Style Tips** - Be specific about tone and mannerisms - Include platform-specific guidance - Define clear boundaries and limitations ### Optional Character Fields ```typescript { "username": "handle", // Character's username/handle "system": "System prompt text", // Custom system prompt "lore": [], // Additional background/history "knowledge": [ // Knowledge base entries "Direct string knowledge", { "path": "file/path.md", "shared": false }, { "directory": "knowledge/path", "shared": false } ], "messageExamples": [], // Example conversations "postExamples": [], // Example social posts "topics": [], // Areas of expertise "adjectives": [] // Character traits } ``` ## Knowledge Management ElizaOS supports two knowledge modes: ### Classic Mode (Default) - Direct string knowledge added to character's context - No chunking or semantic search - Enabled by default (`settings.ragKnowledge: false`) - Only processes string knowledge entries - Simpler but less sophisticated ### RAG Mode - Advanced knowledge processing with semantic search - Chunks content and uses embeddings - Must be explicitly enabled (`settings.ragKnowledge: true`) - Supports three knowledge types: 1. Direct string knowledge 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` - Supported file types: .md, .txt, .pdf - Optional `shared` flag for knowledge reuse across characters ### Knowledge Path Configuration - Knowledge files are relative to the project's `knowledge` directory - Paths should not contain `../` (sanitized for security) - Both shared and private knowledge supported - Files automatically reloaded if content changes ## Example Project Here's a complete example of a project configuration: ```typescript import type { Character, IAgentRuntime, Project, ProjectAgent } from '@elizaos/core'; export const character: Character = { name: 'Tech Helper', plugins: ['@elizaos/plugin-discord', '@elizaos/plugin-direct'], settings: { ragKnowledge: true, voice: { model: 'en_US-male-medium', }, discord: { shouldRespondOnlyToMentions: false, allowedChannelIds: ['123456789012345678'], }, }, bio: ['Friendly technical assistant', 'Specializes in explaining complex topics simply'], lore: ['Pioneer in open-source AI development', 'Advocate for AI accessibility'], messageExamples: [ [ { name: 'user1', content: { text: 'Can you explain how AI models work?' }, }, { name: 'TechAI', content: { text: 'Think of AI models like pattern recognition systems.', }, }, ], ], topics: ['artificial intelligence', 'machine learning', 'technology education'], knowledge: [ { directory: 'tech_guides', shared: true, }, ], style: { all: ['Clear', 'Patient', 'Educational'], chat: ['Interactive', 'Supportive'], post: ['Concise', 'Informative'], }, }; export const projectAgent: ProjectAgent = { character, init: async (runtime: IAgentRuntime) => { console.log('Initializing Tech Helper agent'); }, plugins: [], // Project-specific plugins }; const project: Project = { agents: [projectAgent], }; export default project; ``` ## Character File Export While projects are the primary structure in ElizaOS, you can still export standalone character files for compatibility with other systems or sharing character definitions: ```typescript import fs from 'fs'; import { character } from './src/index'; // Export character to JSON file fs.writeFileSync('character.json', JSON.stringify(character, null, 2)); ``` ## Managing Multiple Agents A project can contain multiple agents, each with its own character and plugins: ```typescript const project: Project = { agents: [ { character: technicalSupportCharacter, init: async (runtime) => { /* init code */ }, plugins: [customSupportPlugin], }, { character: communityManagerCharacter, init: async (runtime) => { /* init code */ }, plugins: [communityPlugin], }, ], }; ``` Each agent operates independently but can share the same database and resources. ## Running Your Project After configuring your project, you can run it using: ```bash npx @elizaos/cli start ``` This will start your agents according to your project configuration. ```` ## File: packages/docs/docs/core/providers.md ````markdown # 🔌 Providers [Providers](/packages/core/src/providers.ts) are the sources of information for the agent. They provide data or state while acting as the agent's "senses", injecting real-time information into the agent's context. They serve as the eyes, ears, and other sensory inputs that allow the agent to perceive and interact with its environment, like a bridge between the agent and various external systems such as market data, wallet information, sentiment analysis, and temporal context. Anything that the agent knows is either coming from like the built-in context or from a provider. For more info, see the [providers API page](/api/interfaces/provider). Here's an example of how providers work within ElizaOS: - A news provider could fetch and format news. - A computer terminal provider in a game could feed the agent information when the player is near a terminal. - A wallet provider can provide the agent with the current assets in a wallet. - A time provider injects the current date and time into the context. --- ## Overview A provider's primary purpose is to supply dynamic contextual information that integrates with the agent's runtime. They format information for conversation templates and maintain consistent data access. For example: - **Function:** Providers run during or before an action is executed. - **Purpose:** They allow for fetching information from other APIs or services to provide different context or ways for an action to be performed. - **Example:** Before a "Mars rover action" is executed, a provider could fetch information from another API. This fetched information can then be used to enrich the context of the Mars rover action. The provider interface is defined in [types.ts](/packages/core/src/types.ts): ```typescript interface Provider { /** Provider name */ name: string; /** Description of the provider */ description?: string; /** Whether the provider is dynamic */ dynamic?: boolean; /** Position of the provider in the provider list, positive or negative */ position?: number; /** * Whether the provider is private * * Private providers are not displayed in the regular provider list, they have to be called explicitly */ private?: boolean; /** Data retrieval function */ get: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; } ``` The `get` function takes: - `runtime`: The agent instance calling the provider - `message`: The last message received - `state`: Current conversation state It returns a `ProviderResult` object that contains: ```typescript interface ProviderResult { values?: { [key: string]: any; }; data?: { [key: string]: any; }; text?: string; } ``` - `values`: Key-value pairs to be merged into the agent's state values - `data`: Additional structured data that can be used by the agent but not directly included in the context - `text`: String that gets injected into the agent's context --- ## Provider Types and Properties Providers come with several properties that control how and when they are used: ### Dynamic Providers Dynamic providers are not automatically included in the context. They must be explicitly requested either in the filter list or include list when composing state. ```typescript const dynamicProvider: Provider = { name: 'dynamicExample', description: 'A dynamic provider example', dynamic: true, get: async (runtime, message, state) => { // ...implementation return { text: 'Dynamic information fetched on demand', values: { /* key-value pairs */ }, }; }, }; ``` ### Private Providers Private providers are not included in the regular provider list and must be explicitly included in the include list when composing state. ```typescript const privateProvider: Provider = { name: 'privateExample', description: 'A private provider example', private: true, get: async (runtime, message, state) => { // ...implementation return { text: 'Private information only available when explicitly requested', values: { /* key-value pairs */ }, }; }, }; ``` ### Provider Positioning The `position` property determines the order in which providers are processed. Lower numbers are processed first. ```typescript const earlyProvider: Provider = { name: 'earlyExample', description: 'Runs early in the provider chain', position: -100, get: async (runtime, message, state) => { // ...implementation return { text: 'Early information', values: { /* key-value pairs */ }, }; }, }; const lateProvider: Provider = { name: 'lateExample', description: 'Runs late in the provider chain', position: 100, get: async (runtime, message, state) => { // ...implementation return { text: 'Late information that might depend on earlier providers', values: { /* key-value pairs */ }, }; }, }; ``` --- ## State Composition with Providers The runtime composes state by gathering data from enabled providers. When calling `composeState`, you can control which providers are used: ```typescript // Get state with all non-private, non-dynamic providers const state = await runtime.composeState(message); // Get state with specific providers only const filteredState = await runtime.composeState( message, ['timeProvider', 'factsProvider'], // Only include these providers null ); // Include private or dynamic providers const enhancedState = await runtime.composeState( message, null, ['privateExample', 'dynamicExample'] // Include these private/dynamic providers ); ``` The system caches provider results to optimize performance. When a provider is called multiple times with the same message, the cached result is used unless you explicitly request a new evaluation. --- ## Examples ElizaOS providers typically fall into these categories, with examples from the ecosystem: ### System & Integration - **Time Provider**: Injects current date/time for temporal awareness - **Giphy Provider**: Provides GIF responses using Giphy API - **GitBook Provider**: Supplies documentation context from GitBook - **Topics Provider**: Caches and serves Allora Network topic information ### Blockchain & DeFi - **Wallet Provider**: Portfolio data from Zerion, balances and prices - **DePIN Provider**: Network metrics via DePINScan API - **Chain Providers**: Data from Abstract, Fuel, ICP, EVM networks - **Market Provider**: Token data from DexScreener, Birdeye APIs ### Knowledge & Data - **DKG Provider**: OriginTrail decentralized knowledge integration - **News Provider**: Current events via NewsAPI - **Trust Provider**: Calculates and injects trust scores Visit the [ElizaOS Plugin Registry](https://github.com/elizaos-plugins/registry) for a complete list of available plugins and providers. ### Time Provider Example ```typescript const timeProvider: Provider = { name: 'time', description: 'Provides the current date and time', position: -10, // Run early to ensure time is available for other providers get: async (_runtime: IAgentRuntime, _message: Memory) => { const currentDate = new Date(); const options = { timeZone: 'UTC', dateStyle: 'full' as const, timeStyle: 'long' as const, }; const humanReadable = new Intl.DateTimeFormat('en-US', options).format(currentDate); return { text: `The current date and time is ${humanReadable}. Please use this as your reference for any time-based operations or responses.`, values: { currentDate: currentDate.toISOString(), humanReadableDate: humanReadable, }, }; }, }; ``` ### Dynamic Provider Example ```typescript const weatherProvider: Provider = { name: 'weather', description: 'Provides weather information for a location', dynamic: true, // Only used when explicitly requested get: async (runtime: IAgentRuntime, message: Memory, state: State) => { // Extract location from state if available const location = state?.values?.location || 'San Francisco'; try { // Fetch weather data from an API const weatherData = await fetchWeatherData(location); return { text: `The current weather in ${location} is ${weatherData.description} with a temperature of ${weatherData.temperature}°C.`, values: { weather: { location, temperature: weatherData.temperature, description: weatherData.description, humidity: weatherData.humidity, }, }, data: { // Additional detailed data that doesn't go into the context weatherDetails: weatherData, }, }; } catch (error) { // Handle errors gracefully return { text: `I couldn't retrieve weather information for ${location} at this time.`, values: { weather: { error: true }, }, }; } }, }; ``` --- ## Best Practices ### 1. Optimize for Efficiency - Return both structured data (`values`) and formatted text (`text`) - Use caching for expensive operations - Include a clear provider name and description ```typescript const efficientProvider: Provider = { name: 'efficientExample', description: 'Efficiently provides cached data', get: async (runtime, message) => { // Check for cached data const cacheKey = `data:${message.roomId}`; const cachedData = await runtime.getCache(cacheKey); if (cachedData) { return cachedData; } // Fetch fresh data if not cached const result = { text: 'Freshly generated information', values: { /* key-value pairs */ }, data: { /* structured data */ }, }; // Cache the result with appropriate TTL await runtime.setCache(cacheKey, result, { expires: 30 * 60 * 1000 }); // 30 minutes return result; }, }; ``` ### 2. Handle Errors Gracefully Always handle errors without throwing exceptions that would interrupt the agent's processing: ```typescript try { // Risky operation } catch (error) { return { text: "I couldn't retrieve that information right now.", values: { error: true }, }; } ``` ### 3. Use Position for Optimal Order Position providers according to their dependencies: - Negative positions: Fundamental information providers (time, location) - Zero (default): Standard information providers - Positive positions: Providers that depend on other information ### 4. Structure Return Values Consistently Maintain a consistent structure in your provider's return values to make data easier to use across the system. --- ## FAQ ### What's the difference between values, data, and text? - `values`: These are merged into the agent state and can be accessed by other providers - `data`: Structured data stored in state.data.providers but not directly exposed to the agent - `text`: Formatted text that's directly injected into the agent's context ### When should I use a dynamic provider? Use dynamic providers when the information is expensive to compute, only relevant in specific situations, or requires explicit triggering rather than being included in every context. ### How do I explicitly include a private provider? Private providers must be included in the `includeList` parameter when calling `composeState`: ```typescript const state = await runtime.composeState(message, null, ['privateProviderName']); ``` ### Can providers access service functionality? Yes, providers can use services through the runtime. For example, a wallet provider might use a blockchain service to fetch data: ```typescript const walletProvider: Provider = { name: 'wallet', get: async (runtime, message) => { const solanaService = runtime.getService('solana'); if (!solanaService) { return { text: '' }; } const walletData = await solanaService.getCachedData(); // Process and return wallet data }, }; ``` ### How should providers handle failures? Providers should handle failures gracefully and return valid ProviderResult objects with appropriate error information. Never throw errors that would break the agent's context composition. ### Can providers maintain state between calls? While providers can maintain internal state (e.g., through closures), it's better to use the runtime's cache system for persistence: ```typescript // Store data await runtime.setCache('myProvider:someKey', dataToStore); // Retrieve data later const storedData = await runtime.getCache('myProvider:someKey'); ``` --- ## Further Reading - [Provider Implementation](/packages/core/src/providers.ts) - [Types Reference](/packages/core/src/types.ts) - [Runtime Integration](/packages/core/src/runtime.ts) ```` ## File: packages/docs/docs/core/rooms.md ````markdown --- sidebar_position: 8 --- # Rooms Rooms in ElizaOS represent individual interaction spaces within a world. A room can be a conversation, a channel, a thread, or any other defined space where entities can exchange messages and interact. Rooms are typically contained within a world, though they can also exist independently. ![](/img/elizaos-rooms-simplified.svg) ## Room Structure A room in ElizaOS has the following properties: ```typescript type Room = { id: UUID; name?: string; agentId?: UUID; source: string; type: ChannelType; channelId?: string; serverId?: string; worldId?: UUID; metadata?: Record; }; ``` | Property | Description | | ----------- | ---------------------------------------------------------------- | | `id` | Unique identifier for the room | | `name` | Optional display name for the room | | `agentId` | Optional ID of the agent associated with this room | | `source` | The platform or origin of the room (e.g., 'discord', 'telegram') | | `type` | Type of room (DM, GROUP, THREAD, etc.) | | `channelId` | External system channel identifier | | `serverId` | External system server identifier | | `worldId` | Optional ID of the parent world | | `metadata` | Additional room configuration data | ## Room Types ElizaOS supports several room types, defined in the `ChannelType` enum: | Type | Description | | ------------- | ----------------------------------------- | | `SELF` | Messages to self | | `DM` | Direct messages between two participants | | `GROUP` | Group messages with multiple participants | | `VOICE_DM` | Voice direct messages | | `VOICE_GROUP` | Voice channels with multiple participants | | `FEED` | Social media feed | | `THREAD` | Threaded conversation | | `WORLD` | World channel | | `FORUM` | Forum discussion | | `API` | Legacy type - Use DM or GROUP instead | ## Room Creation and Management ### Creating a Room You can create a new room using the AgentRuntime: ```typescript const roomId = await runtime.createRoom({ name: 'general-chat', source: 'discord', type: ChannelType.GROUP, channelId: 'external-channel-id', serverId: 'external-server-id', worldId: parentWorldId, }); ``` ### Ensuring a Room Exists To create a room if it doesn't already exist: ```typescript await runtime.ensureRoomExists({ id: roomId, name: 'general-chat', source: 'discord', type: ChannelType.GROUP, channelId: 'external-channel-id', serverId: 'external-server-id', worldId: parentWorldId, }); ``` ### Retrieving Room Information ```typescript // Get a specific room const room = await runtime.getRoom(roomId); // Get all rooms in a world const worldRooms = await runtime.getRooms(worldId); ``` ### Updating Room Properties ```typescript await runtime.updateRoom({ id: roomId, name: 'renamed-channel', metadata: { ...room.metadata, customProperty: 'value', }, }); ``` ### Deleting a Room ```typescript await runtime.deleteRoom(roomId); ``` ## Participants in Rooms Rooms can have multiple participants (entities) that can exchange messages. ### Managing Room Participants ```typescript // Add a participant to a room await runtime.addParticipant(entityId, roomId); // Remove a participant from a room await runtime.removeParticipant(entityId, roomId); // Get all participants in a room const participants = await runtime.getParticipantsForRoom(roomId); // Get all rooms where an entity is a participant const entityRooms = await runtime.getRoomsForParticipant(entityId); ``` ### Participant States Participants can have different states in a room: ```typescript // Get a participant's state in a room const state = await runtime.getParticipantUserState(roomId, entityId); // Returns: 'FOLLOWED', 'MUTED', or null // Set a participant's state in a room await runtime.setParticipantUserState(roomId, entityId, 'FOLLOWED'); ``` The participant states are: | State | Description | | ---------- | ----------------------------------------------------------------------------------------- | | `FOLLOWED` | The agent actively follows the conversation and responds without being directly mentioned | | `MUTED` | The agent ignores messages in this room | | `null` | Default state - the agent responds only when directly mentioned | ## Following and Unfollowing Rooms ElizaOS allows agents to "follow" rooms to actively participate in conversations without being explicitly mentioned. This functionality is managed through the `FOLLOW_ROOM` and `UNFOLLOW_ROOM` actions. ```typescript // Follow a room (typically triggered by an action) await runtime.setParticipantUserState(roomId, runtime.agentId, 'FOLLOWED'); // Unfollow a room await runtime.setParticipantUserState(roomId, runtime.agentId, null); ``` ## Memory and Messages in Rooms Rooms store messages as memories in the database: ```typescript // Create a new message in a room const messageId = await runtime.createMemory( { entityId: senderEntityId, agentId: runtime.agentId, roomId: roomId, content: { text: 'Hello, world!', source: 'discord', }, metadata: { type: 'message', }, }, 'messages' ); // Retrieve recent messages from a room const messages = await runtime.getMemories({ roomId: roomId, count: 10, unique: true, }); ``` ## Events Related to Rooms ElizaOS emits events related to room activities: | Event | Description | | ------------------ | -------------------------------------------- | | `ROOM_JOINED` | Emitted when an entity joins a room | | `ROOM_LEFT` | Emitted when an entity leaves a room | | `MESSAGE_RECEIVED` | Emitted when a message is received in a room | | `MESSAGE_SENT` | Emitted when a message is sent to a room | ### Handling Room Events ```typescript // Register event handlers in your plugin const myPlugin: Plugin = { name: 'my-room-plugin', description: 'Handles room events', events: { [EventTypes.ROOM_JOINED]: [ async (payload) => { const { runtime, entityId, roomId } = payload; console.log(`Entity ${entityId} joined room ${roomId}`); }, ], [EventTypes.MESSAGE_RECEIVED]: [ async (payload: MessagePayload) => { const { runtime, message } = payload; console.log(`Message received in room ${message.roomId}`); }, ], }, }; ``` ## Room Connection with External Systems When integrating with external platforms, rooms are typically mapped to channels, conversations, or other interaction spaces: ```typescript // Ensure the connection exists for a room from an external system await runtime.ensureConnection({ entityId: userEntityId, roomId: roomId, userName: 'username', name: 'display-name', source: 'discord', channelId: 'external-channel-id', serverId: 'external-server-id', type: ChannelType.GROUP, worldId: parentWorldId, }); ``` ## Best Practices 1. **Use appropriate room types**: Select the most appropriate room type for each interaction context 2. **Follow relationship order**: Create worlds before creating rooms, as rooms often have a parent world 3. **Use ensureRoomExists**: Use this method to avoid duplicate rooms when syncing with external systems 4. **Clean up rooms**: Delete rooms when they're no longer needed to prevent database bloat 5. **Room metadata**: Use metadata for room-specific configuration that doesn't fit into the standard properties 6. **Follow state management**: Implement clear rules for when agents should follow or unfollow rooms 7. **Handle participants carefully**: Ensure that participant management aligns with external platform behavior ```` ## File: packages/docs/docs/core/services.md ````markdown --- sidebar_position: 3 --- # 🔌 Services Services are core components in Eliza that enable AI agents to interact with external platforms and services. Each service provides a specialized interface for communication while maintaining consistent agent behavior across different platforms. --- ## Supported Services | Service | Type | Key Features | Use Cases | | ---------------------------------------------------------------------------------- | ------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | | [Discord](https://github.com/elizaos-plugins/plugin-discord) | Communication | • Voice channels • Server management • Moderation tools • Channel management | • Community management • Gaming servers • Event coordination | | [Twitter](https://github.com/elizaos-plugins/plugin-twitter) | Social Media | • Post scheduling • Timeline monitoring • Engagement analytics • Content automation | • Brand management • Content creation • Social engagement | | [Telegram](https://github.com/elizaos-plugins/plugin-telegram) | Messaging | • Bot API • Group chat • Media handling • Command system | • Customer support • Community engagement • Broadcast messaging | | [Direct](https://github.com/elizaOS/eliza/tree/develop/packages/plugin-direct/src) | API | • REST endpoints • Web integration • Custom applications • Real-time communication | • Backend integration • Web apps • Custom interfaces | | [GitHub](https://github.com/elizaos-plugins/plugin-github) | Development | • Repository management • Issue tracking • Pull requests • Code review | • Development workflow • Project management • Team collaboration | | [Slack](https://github.com/elizaos-plugins/plugin-slack) | Enterprise | • Channel management • Conversation analysis • Workspace tools • Integration hooks | • Team collaboration • Process automation • Internal tools | | [Lens](https://github.com/elizaos-plugins/plugin-lens) | Web3 | • Decentralized networking • Content publishing • Memory management • Web3 integration | • Web3 social networking • Content distribution • Decentralized apps | | [Farcaster](https://github.com/elizaos-plugins/plugin-farcaster) | Web3 | • Decentralized social • Content publishing • Community engagement | • Web3 communities • Content creation • Social networking | | [Auto](https://github.com/elizaos-plugins/plugin-auto) | Automation | • Workload management • Task scheduling • Process automation | • Background jobs • Automated tasks • System maintenance | **\*Additional services**: - Instagram: Social media content and engagement - XMTP: Web3 messaging and communications - Alexa: Voice interface and smart device control - Home Assistant: Home automation OS - Devai.me: AI first social service - Simsai: Jeeter / Social media platform for AI --- ## System Overview Services serve as bridges between Eliza agents and various platforms, providing core capabilities: 1. **Message Processing** - Platform-specific message formatting and delivery - Media handling and attachments via [`Memory`](/api/interfaces/Memory) objects - Reply threading and context management - Support for different content types 2. **State & Memory Management** - Each service maintains independent state to prevent cross-platform contamination - Integrates with runtime memory managers for different types of content: - Messages processed by one service don't automatically appear in other services' contexts - [`State`](/api/interfaces/State) persists across agent restarts through the database adapter 3. **Platform Integration** - Authentication and API compliance - Event processing and webhooks - Rate limiting and cache management - Platform-specific feature support ## Service Configuration Services are configured through the [`Character`](/api/type-aliases/Character) configuration's `settings` property: ```typescript export type Character = { // ... other properties ... settings?: { discord?: { shouldIgnoreBotMessages?: boolean; shouldIgnoreDirectMessages?: boolean; shouldRespondOnlyToMentions?: boolean; messageSimilarityThreshold?: number; isPartOfTeam?: boolean; teamAgentIds?: string[]; teamLeaderId?: string; teamMemberInterestKeywords?: string[]; allowedChannelIds?: string[]; autoPost?: { enabled?: boolean; monitorTime?: number; inactivityThreshold?: number; mainChannelId?: string; announcementChannelIds?: string[]; minTimeBetweenPosts?: number; }; }; telegram?: { shouldIgnoreBotMessages?: boolean; shouldIgnoreDirectMessages?: boolean; shouldRespondOnlyToMentions?: boolean; shouldOnlyJoinInAllowedGroups?: boolean; allowedGroupIds?: string[]; messageSimilarityThreshold?: number; // ... other telegram-specific settings }; slack?: { shouldIgnoreBotMessages?: boolean; shouldIgnoreDirectMessages?: boolean; }; // ... other service configs }; }; ``` ## Service Implementation Each service manages its own: - Platform-specific message formatting and delivery - Event processing and webhooks - Authentication and API integration - Message queueing and rate limiting - Media handling and attachments - State management and persistence Example of a basic service implementation: ```typescript import { Service, IAgentRuntime } from '@elizaos/core'; export class CustomService extends Service { static serviceType = 'custom'; capabilityDescription = 'The agent is able to interact with the custom platform'; constructor(protected runtime: IAgentRuntime) { super(); // Initialize platform connection // Set up event handlers // Configure message processing } static async start(runtime: IAgentRuntime): Promise { const service = new CustomService(runtime); // Additional initialization if needed return service; } async stop(): Promise { // Cleanup resources // Close connections } } ``` ### Runtime Integration Services interact with the agent runtime through the [`IAgentRuntime`](api/interfaces/IAgentRuntime/) interface, which provides: - Memory managers for different types of data storage - Service access for capabilities like transcription or image generation - State management and composition - Message processing and action handling ### Memory System Integration Services use the runtime's memory managers to persist conversation data (source: [`memory.ts`](/api/interfaces/Memory)). - `messageManager` Chat messages - `documentsManager` File attachments - `descriptionManager` Media descriptions
See example ```typescript // Store a new message await runtime.messageManager.createMemory({ id: messageId, content: { text: message.content }, userId: userId, roomId: roomId, agentId: runtime.agentId }); // Retrieve recent messages const recentMessages = await runtime.messageManager.getMemories({ roomId: roomId, count: 10 }); ```
--- ## FAQ ### What can services actually do? Services handle platform-specific communication (like Discord messages or Twitter posts), manage memories and state, and execute actions like processing media or handling commands. Each service adapts these capabilities to its platform while maintaining consistent agent behavior. ### Can multiple services be used simultaneously? Yes, Eliza supports running multiple services concurrently while maintaining consistent agent behavior across platforms. ### How are service-specific features handled? Each service implements platform-specific features through its capabilities system, while maintaining a consistent interface for the agent. ### How do services handle rate limits? Services implement platform-specific rate limiting with backoff strategies and queue management. ### How is service state managed? Services maintain their own connection state while integrating with the agent's runtime database adapter and memory / state management system. ### How do services handle messages? Services translate platform messages into Eliza's internal format, process any attachments (images, audio, etc.), maintain conversation context, and manage response queuing and rate limits. ### How are messages processed across services? Each service processes messages independently in its platform-specific format, while maintaining conversation context through the shared memory system. V2 improves upon this architecture. ### How is state managed between services? Each service maintains separate state to prevent cross-contamination, but can access shared agent state through the runtime. ### How do services integrate with platforms? Each service implements platform-specific authentication, API compliance, webhook handling, and follows the platform's rules for rate limiting and content formatting. ### How do services manage memory? Services use Eliza's memory system to track conversations, user relationships, and state, enabling context-aware responses and persistent interactions across sessions. ``` ```` ## File: packages/docs/docs/core/tasks.md ````markdown --- sidebar_position: 9 --- # Tasks Tasks in ElizaOS provide a powerful way to manage deferred, scheduled, and interactive operations. The Task system allows agents to queue work for later execution, repeat actions at defined intervals, await user input, and implement complex workflows across multiple interactions. ## Task Structure A task in ElizaOS has the following properties: ```typescript interface Task { id?: UUID; // Unique identifier (auto-generated if not provided) name: string; // Name of the task (must match a registered task worker) updatedAt?: number; // Timestamp when the task was last updated metadata?: { // Optional additional configuration updateInterval?: number; // For repeating tasks: milliseconds between executions options?: { // For choice tasks: options for user selection name: string; description: string; }[]; [key: string]: unknown; // Additional custom metadata }; description: string; // Human-readable description of the task roomId?: UUID; // Optional room association (for room-specific tasks) worldId?: UUID; // Optional world association (for world-specific tasks) tags: string[]; // Tags for categorizing and filtering tasks } ``` ## Task Workers Task workers define the actual logic that executes when a task runs. Each task worker is registered with the runtime and is identified by name. ```typescript interface TaskWorker { name: string; // Matches the name in the Task execute: ( runtime: IAgentRuntime, options: { [key: string]: unknown }, // Options passed during execution task: Task // The task being executed ) => Promise; validate?: ( // Optional validation before execution runtime: IAgentRuntime, message: Memory, state: State ) => Promise; } ``` ## Creating and Managing Tasks ### Registering a Task Worker Before creating tasks, you must register a worker to handle the execution: ```typescript runtime.registerTaskWorker({ name: 'SEND_REMINDER', validate: async (runtime, message, state) => { // Optional validation logic return true; }, execute: async (runtime, options, task) => { // Task execution logic const { roomId } = task; const { reminder, userId } = options; await runtime.createMemory( { entityId: runtime.agentId, roomId, content: { text: `Reminder for <@${userId}>: ${reminder}`, }, }, 'messages' ); // Delete the task after it's completed await runtime.deleteTask(task.id); }, }); ``` ### Creating a One-time Task Create a task that will execute once: ```typescript await runtime.createTask({ name: 'SEND_REMINDER', description: 'Send a reminder message to the user', roomId: currentRoomId, tags: ['reminder', 'one-time'], metadata: { userId: message.entityId, reminder: 'Submit your weekly report', scheduledFor: Date.now() + 86400000, // 24 hours from now }, }); ``` ### Creating a Recurring Task Create a task that repeats at regular intervals: ```typescript await runtime.createTask({ name: 'DAILY_REPORT', description: 'Generate and post the daily report', roomId: announcementChannelId, worldId: serverWorldId, tags: ['report', 'repeat', 'daily'], metadata: { updateInterval: 86400000, // 24 hours in milliseconds updatedAt: Date.now(), // When the task was last updated/executed }, }); ``` ### Creating a Task Awaiting User Choice Create a task that presents options and waits for user input: ```typescript await runtime.createTask({ name: 'CONFIRM_ACTION', description: 'Confirm the requested action', roomId: message.roomId, tags: ['confirmation', 'AWAITING_CHOICE'], metadata: { options: [ { name: 'confirm', description: 'Proceed with the action' }, { name: 'cancel', description: 'Cancel the action' }, ], action: 'DELETE_FILES', files: ['document1.txt', 'document2.txt'], }, }); ``` ### Managing Tasks Retrieve, update, and delete tasks as needed: ```typescript // Get tasks by specific criteria const reminderTasks = await runtime.getTasks({ roomId: currentRoomId, tags: ['reminder'], }); // Get tasks by name const reportTasks = await runtime.getTasksByName('DAILY_REPORT'); // Get a specific task const task = await runtime.getTask(taskId); // Update a task await runtime.updateTask(taskId, { description: 'Updated description', metadata: { ...task.metadata, priority: 'high', }, }); // Delete a task await runtime.deleteTask(taskId); ``` ## Task Processing Tasks are processed based on their configuration: ### One-time Tasks Tasks without an `updateInterval` are executed once when triggered by your code. You are responsible for scheduling their execution by checking for pending tasks in appropriate contexts. ### Recurring Tasks Tasks with an `updateInterval` are automatically considered for re-execution when: 1. The current time exceeds `updatedAt + updateInterval` 2. Your code explicitly checks for pending recurring tasks To process recurring tasks, implement logic like this: ```typescript // In an initialization function or periodic check async function processRecurringTasks() { const now = Date.now(); const recurringTasks = await runtime.getTasks({ tags: ['repeat'], }); for (const task of recurringTasks) { if (!task.metadata?.updateInterval) continue; const lastUpdate = task.metadata.updatedAt || 0; const interval = task.metadata.updateInterval; if (now >= lastUpdate + interval) { const worker = runtime.getTaskWorker(task.name); if (worker) { try { await worker.execute(runtime, {}, task); // Update the task's last update time await runtime.updateTask(task.id, { metadata: { ...task.metadata, updatedAt: now, }, }); } catch (error) { logger.error(`Error executing task ${task.name}: ${error}`); } } } } } ``` ### Tasks Awaiting User Input Tasks tagged with `AWAITING_CHOICE` are presented to users and wait for their input. These tasks use: 1. The `choice` provider to display available options to users 2. The `CHOOSE_OPTION` action to process user selections ## Common Task Patterns ### Deferred Follow-ups Create a task to follow up with a user later: ```typescript runtime.registerTaskWorker({ name: 'FOLLOW_UP', execute: async (runtime, options, task) => { const { roomId } = task; const { userId, topic } = task.metadata; await runtime.createMemory( { entityId: runtime.agentId, roomId, content: { text: `Hi <@${userId}>, I'm following up about ${topic}. Do you have any updates?`, }, }, 'messages' ); await runtime.deleteTask(task.id); }, }); // Create a follow-up task for 2 days later await runtime.createTask({ name: 'FOLLOW_UP', description: 'Follow up with user about project status', roomId: message.roomId, tags: ['follow-up', 'one-time'], metadata: { userId: message.entityId, topic: 'the project timeline', scheduledFor: Date.now() + 2 * 86400000, // 2 days }, }); ``` ### Multi-step Workflows Implement complex workflows that span multiple interactions: ```typescript // First step: Gather requirements runtime.registerTaskWorker({ name: 'GATHER_REQUIREMENTS', execute: async (runtime, options, task) => { // Ask user for requirements and create a new task for the next step await runtime.createTask({ name: 'CONFIRM_REQUIREMENTS', description: 'Confirm gathered requirements', roomId: task.roomId, tags: ['workflow', 'AWAITING_CHOICE'], metadata: { previousStep: 'GATHER_REQUIREMENTS', requirements: options.requirements, options: [ { name: 'confirm', description: 'Confirm requirements are correct' }, { name: 'revise', description: 'Need to revise requirements' }, ], }, }); await runtime.deleteTask(task.id); }, }); // Second step: Confirm requirements runtime.registerTaskWorker({ name: 'CONFIRM_REQUIREMENTS', execute: async (runtime, options, task) => { if (options.option === 'confirm') { // Move to the next step await runtime.createTask({ name: 'GENERATE_SOLUTION', description: 'Generate solution based on requirements', roomId: task.roomId, tags: ['workflow'], metadata: { previousStep: 'CONFIRM_REQUIREMENTS', requirements: task.metadata.requirements, }, }); } else { // Go back to requirements gathering await runtime.createTask({ name: 'GATHER_REQUIREMENTS', description: 'Revise requirements', roomId: task.roomId, tags: ['workflow'], metadata: { previousStep: 'CONFIRM_REQUIREMENTS', previousRequirements: task.metadata.requirements, }, }); } await runtime.deleteTask(task.id); }, }); ``` ### Scheduled Reports Create tasks that generate and post reports on a schedule: ```typescript runtime.registerTaskWorker({ name: 'GENERATE_WEEKLY_REPORT', execute: async (runtime, options, task) => { const { roomId } = task; // Generate report content const reportData = await generateWeeklyReport(runtime); // Post the report await runtime.createMemory( { entityId: runtime.agentId, roomId, content: { text: `# Weekly Report\n\n${reportData}`, }, }, 'messages' ); // The task stays active for next week (updateInterval handles timing) }, }); // Create a weekly report task await runtime.createTask({ name: 'GENERATE_WEEKLY_REPORT', description: 'Generate and post weekly activity report', roomId: reportChannelId, worldId: serverWorldId, tags: ['report', 'repeat', 'weekly'], metadata: { updateInterval: 7 * 86400000, // 7 days updatedAt: Date.now(), format: 'markdown', }, }); ``` ## Task Events and Monitoring ElizaOS doesn't currently provide built-in events for task lifecycle, so implement your own monitoring if needed: ```typescript // Custom monitoring for task execution async function executeTaskWithMonitoring(runtime, taskWorker, task) { try { // Create a start log await runtime.log({ body: { taskId: task.id, action: 'start' }, entityId: runtime.agentId, roomId: task.roomId, type: 'TASK_EXECUTION', }); // Execute the task await taskWorker.execute(runtime, {}, task); // Create a completion log await runtime.log({ body: { taskId: task.id, action: 'complete', success: true }, entityId: runtime.agentId, roomId: task.roomId, type: 'TASK_EXECUTION', }); } catch (error) { // Create an error log await runtime.log({ body: { taskId: task.id, action: 'error', error: error.message }, entityId: runtime.agentId, roomId: task.roomId, type: 'TASK_EXECUTION', }); } } ``` ## Best Practices 1. **Use descriptive names and descriptions**: Make tasks easily identifiable with clear names and descriptions 2. **Clean up completed tasks**: Delete one-time tasks after execution to prevent database bloat 3. **Add error handling**: Implement robust error handling in task workers to prevent failures from breaking workflows 4. **Use appropriate tags**: Tag tasks effectively for easy retrieval and categorization 5. **Validate carefully**: Use the `validate` function to ensure tasks only execute in appropriate contexts 6. **Keep tasks atomic**: Design tasks to perform specific, well-defined operations rather than complex actions 7. **Provide clear choices**: When creating choice tasks, make option names and descriptions clear and unambiguous 8. **Manage task lifecycles**: Have a clear strategy for when tasks are created, updated, and deleted 9. **Set reasonable intervals**: For recurring tasks, choose appropriate update intervals that balance timeliness and resource usage 10. **Handle concurrent execution**: Ensure task execution is idempotent to handle potential concurrent executions ```` ## File: packages/docs/docs/core/worlds.md ````markdown --- sidebar_position: 7 --- # Worlds Worlds in ElizaOS are collections of entities (users, agents) and rooms (conversations, channels) that form a cohesive environment for interactions. Think of a world as a virtual space, like a Discord server, Slack workspace, or 3D MMO environment, where entities can communicate across multiple channels or areas. ![](/img/elizaos-worlds-cosmic-clean.svg) Within each world you can have rooms, which are akin to individual threads or channels in a server. ![](/img/elizaos-worlds-simplified.svg) ## World Structure A world in ElizaOS has the following properties: ```typescript type World = { id: UUID; name?: string; agentId: UUID; serverId: string; metadata?: { ownership?: { ownerId: string; }; roles?: { [entityId: UUID]: Role; }; [key: string]: unknown; }; }; ``` | Property | Description | | ---------- | ---------------------------------------------------- | | `id` | Unique identifier for the world | | `name` | Optional display name | | `agentId` | ID of the agent managing this world | | `serverId` | External system identifier (e.g., Discord server ID) | | `metadata` | Additional world configuration data | The metadata can store custom information, including ownership details and role assignments for entities within the world. ## World Creation and Management ### Creating a World You can create a new world using the AgentRuntime: ```typescript const worldId = await runtime.createWorld({ name: 'My Project Space', agentId: runtime.agentId, serverId: 'external-system-id', metadata: { ownership: { ownerId: ownerEntityId, }, }, }); ``` For many integrations, worlds are automatically created during connection setup with external platforms like Discord or Slack. ### Ensuring a World Exists If you're not sure if a world exists, you can use `ensureWorldExists()`: ```typescript await runtime.ensureWorldExists({ id: worldId, name: 'My Project Space', agentId: runtime.agentId, serverId: 'external-system-id', }); ``` ### Retrieving World Information ```typescript // Get a specific world const world = await runtime.getWorld(worldId); // Get all worlds const allWorlds = await runtime.getAllWorlds(); ``` ### Updating World Properties ```typescript await runtime.updateWorld({ id: worldId, name: 'Updated Name', metadata: { ...world.metadata, customProperty: 'value', }, }); ``` ## World Roles System Worlds support a role-based permission system with the following roles: | Role | Description | | ------- | ----------------------------------------------------- | | `OWNER` | Full control over the world, can assign any roles | | `ADMIN` | Administrative capabilities, can manage most settings | | `NONE` | Standard participant with no special permissions | ### Managing Roles Roles are stored in the world's metadata and can be updated: ```typescript // Get existing world const world = await runtime.getWorld(worldId); // Ensure roles object exists if (!world.metadata) world.metadata = {}; if (!world.metadata.roles) world.metadata.roles = {}; // Assign a role to an entity world.metadata.roles[entityId] = Role.ADMIN; // Save the world await runtime.updateWorld(world); ``` For programmatic role management, you can use role-related utilities: ```typescript import { canModifyRole, findWorldForOwner } from '@elizaos/core'; // Check if user can modify roles if (canModifyRole(userRole, targetRole, newRole)) { // Allow role change } // Find world where user is owner const userWorld = await findWorldForOwner(runtime, entityId); ``` ## World Settings Worlds support configurable settings that can be stored and retrieved: ```typescript // Get settings for a world const worldSettings = await getWorldSettings(runtime, serverId); // Update world settings worldSettings.MY_SETTING = { name: 'My Setting', description: 'Description for users', value: 'setting-value', required: false, }; // Save settings await updateWorldSettings(runtime, serverId, worldSettings); ``` ## World Events ElizaOS emits events related to world activities: | Event | Description | | ----------------- | ---------------------------------------------- | | `WORLD_JOINED` | Emitted when an agent joins a world | | `WORLD_CONNECTED` | Emitted when a world is successfully connected | | `WORLD_LEFT` | Emitted when an agent leaves a world | ### Handling World Events ```typescript // Register event handlers in your plugin const myPlugin: Plugin = { name: 'my-world-plugin', description: 'Handles world events', events: { [EventTypes.WORLD_JOINED]: [ async (payload: WorldPayload) => { const { world, runtime } = payload; console.log(`Joined world: ${world.name}`); }, ], [EventTypes.WORLD_LEFT]: [ async (payload: WorldPayload) => { const { world, runtime } = payload; console.log(`Left world: ${world.name}`); }, ], }, }; ``` ## Relationship with Rooms A world contains multiple rooms that entities can interact in. Each room points back to its parent world via the `worldId` property. ```typescript // Get all rooms in a world const worldRooms = await runtime.getRooms(worldId); ``` See the [Rooms](./rooms.md) documentation for more details on managing rooms within worlds. ## Best Practices 1. **Always check permissions**: Before performing administrative actions, verify the user has appropriate roles 2. **Handle world metadata carefully**: The metadata object can contain critical configuration, so modify it with care 3. **World-room syncing**: When syncing with external platforms, keep world and room structures in alignment 4. **Event-driven architecture**: Use events to respond to world changes rather than polling for updates 5. **Default settings**: Provide sensible defaults for world settings to make configuration easier ```` ## File: packages/docs/docs/quickstart.md ````markdown --- sidebar_position: 2 title: Quickstart Guide description: Get started quickly with Eliza, from basic setup to advanced development --- # Quickstart Guide ## Installing the CLI Tool The fastest way to get started with ElizaOS is using the CLI: ```bash # Install globally (optional but recommended) npm install -g @elizaos/cli@beta # Or use directly with npx npx @elizaos/cli@beta start ``` This will: 1. Start ElizaOS with default settings 2. Load the default character 3. Make the agent accessible via terminal and REST API > **Note:** If you encounter any errors on first startup, try running the start command again. The initial startup sometimes needs a second attempt to properly initialize all components. ### Chat with your agent: Visit https://localhost:3000 to interact with your agent through a web interface. ## 2. Creating a Project If you want to create a custom ElizaOS project with your own characters and configurations: ```bash # Create a new project with the interactive wizard elizaos create # Or specify project type directly elizaos create --type project ``` Follow the interactive prompts to configure your project. Once created: ```bash # Navigate to your project directory cd my-project-name # Start your project elizaos start ``` > If it fails the first time try the start command again ### Project Structure A typical ElizaOS project structure looks like this: ``` my-project/ ├── src/ │ └── index.ts # Main entry point with character definitions ├── knowledge/ # Knowledge files for RAG ├── package.json # Project configuration and dependencies └── tsconfig.json # TypeScript configuration ``` The character definition is located in `src/index.ts` where you can modify the agent's personality, plugins, and settings. This is the core file for customizing your agent's behavior. ### Add plugins to your project: ```bash # List available plugins elizaos project list-plugins # Add a plugin elizaos project add-plugin @elizaos/plugin-discord ``` ### Working with Character Files You can import or export character files using the CLI: ```bash # Export character to a JSON file elizaos character export --output my-character.json # Import character from a JSON file elizaos character import --file my-character.json ``` This is particularly useful for those migrating from v1 who are used to working with standalone character files. ## 3. Creating a Plugin Want to extend ElizaOS with custom functionality? ```bash # Create a new plugin project elizaos create --type plugin ``` Develop your plugin following the structure in your generated project: ```bash # Test your plugin elizaos start # Publish your plugin when ready elizaos plugin publish ``` ### Publishing options: ```bash # Test publish without making changes elizaos plugin publish --test # Publish to npm elizaos plugin publish --npm # Specify platform compatibility elizaos plugin publish --platform node ``` ## 4. Contributing to ElizaOS If you want to add features or fix bugs in the ElizaOS core: ```bash # Clone the repository git clone git@github.com:elizaOS/eliza.git cd eliza # Switch to development branch git checkout v2-develop # Install dependencies bun install # Build the project bun run build # Start ElizaOS bun start ``` Visit https://localhost:3000 to interact with your agent through a web interface. --- ## Troubleshooting ### Node Version - Use Node.js 23.3.0+ (`node -v` to check) - Try using NVM: `nvm use 23` ### Installation Problems ```bash # Clean and reinstall bun clean bun install --no-frozen-lockfile bun build ``` ### Plugin Issues ```bash # Rebuild problematic packages bun rebuild better-sqlite3 ``` ### Docker Issues ```bash # Clean up Docker environment docker rmi -f $(docker images -aq) docker builder prune -a -f ``` ### First-time Startup Issues If your agent fails to start on the first attempt: - Run the start command again - Check logs for specific errors - Ensure all dependencies are properly installed - Verify that your database configuration is correct --- ## Next Steps Once you have your agent running, explore: - 🤖 [Understand Agents](./core/agents.md) - ⚡ [Add Custom Actions](./core/actions.md) - 🧠 [Configure Knowledge](./core/knowledge.md) - 🔌 [Add Services](./core/services.md) Join the [Discord community](https://discord.gg/elizaOS) for support and to share what you're building! ```` ## File: packages/docs/src/openapi/eliza-v1.yaml ````yaml openapi: 3.0.0 info: title: Eliza OS API description: |- API documentation for Eliza OS v1.0.0-alpha - A flexible and scalable AI agent framework. This API is designed to be used with a locally running Eliza instance. Endpoints allow for creating, managing, and interacting with AI agents through a REST interface. version: 1.0.0-alpha contact: name: Eliza OS Community url: https://github.com/elizaos/eliza servers: - url: http://localhost:3000 description: Local development server tags: - name: system description: System-wide operations - name: agents description: Operations for managing AI agents - name: rooms description: Operations for managing conversation rooms - name: messages description: Operations for interacting with agents via text messages - name: memories description: Operations for accessing agent memories - name: logs description: Operations for accessing system and agent logs - name: speech description: Operations for speech and audio processing - name: tee description: Trusted Execution Environment operations paths: /api/hello: get: tags: - system summary: Basic health check description: Simple hello world test endpoint operationId: getHello responses: '200': description: Hello world response content: application/json: schema: type: object properties: message: type: string example: 'Hello World!' /api/status: get: tags: - system summary: Get system status description: Returns the current status of the system with agent count and timestamp operationId: getStatus responses: '200': description: System status information content: application/json: schema: type: object properties: status: type: string example: 'ok' agentCount: type: integer description: Number of active agents timestamp: type: string format: date-time description: Current timestamp /api/health: get: tags: - system summary: Health check endpoint description: Detailed health check for the system operationId: getHealth responses: '200': description: System is healthy content: application/json: schema: type: object properties: status: type: string example: 'OK' version: type: string timestamp: type: string format: date-time dependencies: type: object properties: agents: type: string example: 'healthy' '503': description: System is unhealthy content: application/json: schema: $ref: '#/components/schemas/Error' /api/logs: get: tags: - logs summary: Get system logs description: Retrieve system logs with optional filtering operationId: getLogs parameters: - name: since in: query schema: type: integer description: Timestamp (ms) to get logs from - name: level in: query schema: type: string enum: [all, trace, debug, info, warn, error, fatal] default: info - name: agentName in: query schema: type: string - name: agentId in: query schema: type: string format: uuid - name: limit in: query schema: type: integer default: 100 maximum: 1000 responses: '200': description: System logs content: application/json: schema: type: object properties: logs: type: array items: $ref: '#/components/schemas/LogEntry' count: type: integer total: type: integer level: type: string levels: type: array items: type: string '500': description: Error retrieving logs content: application/json: schema: $ref: '#/components/schemas/Error' post: tags: - logs summary: Get system logs (POST) description: Retrieve system logs with optional filtering using POST method operationId: postLogs requestBody: content: application/json: schema: type: object properties: since: type: integer description: Timestamp (ms) to get logs from level: type: string enum: [all, trace, debug, info, warn, error, fatal] default: info agentName: type: string agentId: type: string format: uuid limit: type: integer default: 100 maximum: 1000 responses: '200': description: System logs content: application/json: schema: type: object properties: logs: type: array items: $ref: '#/components/schemas/LogEntry' count: type: integer total: type: integer level: type: string levels: type: array items: type: string '500': description: Error retrieving logs content: application/json: schema: $ref: '#/components/schemas/Error' /api/stop: get: tags: - system summary: Stop the server description: Initiates server shutdown operationId: stopServer responses: '200': description: Server is shutting down content: application/json: schema: type: object properties: message: type: string example: 'Server stopping...' /api/agents: get: tags: - agents summary: List all agents description: Returns a list of all available agents operationId: listAgents responses: '200': description: List of agents content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: agents: type: array items: $ref: '#/components/schemas/AgentInfo' '500': description: Error retrieving agents content: application/json: schema: $ref: '#/components/schemas/Error' post: tags: - agents summary: Create a new agent description: Creates a new agent from character configuration operationId: createAgent requestBody: required: true content: application/json: schema: type: object properties: characterPath: type: string description: Path to a character file characterJson: type: object description: Character configuration in JSON format responses: '201': description: Agent created successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: character: $ref: '#/components/schemas/Character' '400': description: Error creating agent content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}: get: tags: - agents summary: Get agent details description: Returns detailed information about a specific agent operationId: getAgent parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent to retrieve responses: '200': description: Agent details content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/AgentInfo' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Server error content: application/json: schema: $ref: '#/components/schemas/Error' post: tags: - agents summary: Start an agent description: Starts an existing agent operationId: startAgent parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent to start responses: '200': description: Agent started successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: id: type: string format: uuid name: type: string status: type: string enum: [active] '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error starting agent content: application/json: schema: $ref: '#/components/schemas/Error' patch: tags: - agents summary: Update agent description: Update an existing agent operationId: updateAgent parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent to update requestBody: required: true content: application/json: schema: type: object description: Agent updates responses: '200': description: Agent updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/AgentInfo' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error updating agent content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - agents summary: Stop an agent description: Stops a running agent operationId: stopAgent parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent to stop responses: '200': description: Agent stopped successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: message: type: string example: 'Agent stopped' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - agents summary: Delete an agent description: Deletes an agent from the system operationId: deleteAgent parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent to delete responses: '204': description: Agent deleted successfully '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error deleting agent content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/logs: get: tags: - logs - agents summary: Get agent logs description: Retrieves logs for a specific agent operationId: getAgentLogs parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: roomId in: query schema: type: string format: uuid description: Filter logs by room ID - name: type in: query schema: type: string description: Filter logs by type - name: count in: query schema: type: integer description: Maximum number of logs to return - name: offset in: query schema: type: integer description: Log offset for pagination responses: '200': description: Agent logs content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/LogEntry' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/logs/{logId}: delete: tags: - logs - agents summary: Delete an agent log description: Deletes a specific log entry for an agent operationId: deleteAgentLog parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: logId in: path required: true schema: type: string format: uuid description: ID of the log to delete responses: '204': description: Log deleted successfully '400': description: Invalid agent ID or log ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or log not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/memories: get: tags: - memories - agents summary: Get agent memories description: Retrieves all memories for a specific agent operationId: getAgentMemories parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent responses: '200': description: Agent memories content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/Memory' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/memories/{memoryId}: patch: tags: - memories - agents summary: Update a memory description: Updates a specific memory for an agent operationId: updateMemory parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: memoryId in: path required: true schema: type: string format: uuid description: ID of the memory to update requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Memory' responses: '200': description: Memory updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: id: type: string format: uuid message: type: string example: 'Memory updated successfully' '400': description: Invalid agent ID or memory ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or memory not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error updating memory content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - memories - agents summary: Delete a memory description: Deletes a specific memory for an agent operationId: deleteMemory parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: memoryId in: path required: true schema: type: string format: uuid description: ID of the memory to delete responses: '204': description: Memory deleted successfully '400': description: Invalid agent ID or memory ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or memory not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/rooms: get: tags: - rooms - agents summary: Get agent rooms description: Retrieves all rooms for a specific agent operationId: getAgentRooms parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: worldId in: query schema: type: string format: uuid description: Filter rooms by world ID responses: '200': description: Agent rooms content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/Room' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error retrieving rooms content: application/json: schema: $ref: '#/components/schemas/Error' post: tags: - rooms - agents summary: Create a room description: Creates a new room for an agent operationId: createRoom parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: Name of the room worldId: type: string format: uuid description: ID of the world roomId: type: string format: uuid description: Optional custom room ID entityId: type: string format: uuid description: Entity ID to add to the room responses: '201': description: Room created successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/Room' '400': description: Invalid agent ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error creating room content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/rooms/{roomId}: get: tags: - rooms - agents summary: Get room details description: Retrieves details about a specific room operationId: getRoom parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: roomId in: path required: true schema: type: string format: uuid description: ID of the room responses: '200': description: Room details content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/Room' '400': description: Invalid agent ID or room ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or room not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error retrieving room content: application/json: schema: $ref: '#/components/schemas/Error' patch: tags: - rooms - agents summary: Update a room description: Updates a specific room operationId: updateRoom parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: roomId in: path required: true schema: type: string format: uuid description: ID of the room to update requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: New name for the room responses: '200': description: Room updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/Room' '400': description: Invalid agent ID or room ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or room not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error updating room content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - rooms - agents summary: Delete a room description: Deletes a specific room operationId: deleteRoom parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: roomId in: path required: true schema: type: string format: uuid description: ID of the room to delete responses: '204': description: Room deleted successfully '400': description: Invalid agent ID or room ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or room not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error deleting room content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/rooms/{roomId}/memories: get: tags: - memories - rooms - agents summary: Get room memories description: Retrieves memories for a specific room operationId: getRoomMemories parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent - name: roomId in: path required: true schema: type: string format: uuid description: ID of the room - name: limit in: query schema: type: integer default: 20 description: Maximum number of memories to return - name: before in: query schema: type: integer description: Return memories created before this timestamp - name: worldId in: query schema: type: string format: uuid description: Filter memories by world ID responses: '200': description: Room memories content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: memories: type: array items: $ref: '#/components/schemas/Memory' '400': description: Invalid agent ID or room ID content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent or room not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error retrieving memories content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/message: post: tags: - messages - agents summary: Send a message to an agent description: Sends a message to an agent and receives a response operationId: sendMessage parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: application/json: schema: type: object properties: senderId: type: string description: ID of the sender roomId: type: string description: ID of the room text: type: string description: Message text source: type: string description: Source of the message responses: '201': description: Message sent and processed successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: message: $ref: '#/components/schemas/Content' messageId: type: string format: uuid name: type: string roomId: type: string source: type: string '400': description: Invalid agent ID or request body content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error processing message content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/audio-messages: post: tags: - speech - agents summary: Send an audio message description: Sends an audio message to an agent for processing operationId: sendAudioMessage parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Audio file responses: '201': description: Audio message processed successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: message: $ref: '#/components/schemas/Content' '400': description: Invalid agent ID or missing audio file content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error processing audio content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/audio-messages/synthesize: post: tags: - speech - agents summary: Convert text to speech description: Converts text to speech using the agent's voice operationId: synthesizeSpeech parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: application/json: schema: type: object properties: text: type: string description: Text to convert to speech responses: '200': description: Audio stream with synthesized speech content: audio/mpeg: schema: type: string format: binary '400': description: Invalid agent ID or missing text content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error generating speech content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/speech/generate: post: tags: - speech - agents summary: Generate speech from text description: Generates speech from text using the agent's voice operationId: generateSpeech parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: application/json: schema: type: object properties: text: type: string description: Text to convert to speech responses: '200': description: Audio stream with generated speech content: audio/mpeg: schema: type: string format: binary '400': description: Invalid agent ID or missing text content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error generating speech content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/speech/conversation: post: tags: - speech - agents summary: Process conversation and return speech description: Processes a conversational message and returns synthesized speech operationId: conversationToSpeech parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: application/json: schema: type: object properties: text: type: string description: Text message roomId: type: string description: Room ID entityId: type: string description: Entity ID userName: type: string description: User name name: type: string description: Entity name responses: '200': description: Audio stream with synthesized speech content: audio/mpeg: schema: type: string format: binary '400': description: Invalid agent ID or missing text content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error processing conversation content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{agentId}/transcriptions: post: tags: - speech - agents summary: Transcribe audio to text description: Transcribes an audio file to text operationId: transcribeAudio parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the agent requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Audio file to transcribe responses: '200': description: Transcription result content: application/json: schema: type: object properties: success: type: boolean example: true data: type: object properties: text: type: string description: Transcribed text '400': description: Invalid agent ID or missing audio file content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error transcribing audio content: application/json: schema: $ref: '#/components/schemas/Error' /api/tee/agents: get: tags: - tee summary: List TEE agents description: Lists all agents with TEE (Trusted Execution Environment) support operationId: listTeeAgents responses: '200': description: TEE agent list with attestation content: application/json: schema: type: object properties: agents: type: array items: $ref: '#/components/schemas/TeeAgent' attestation: type: string description: TEE attestation '500': description: Error retrieving TEE agents content: application/json: schema: $ref: '#/components/schemas/Error' /api/tee/agents/{agentId}: get: tags: - tee summary: Get TEE agent details description: Gets details about a specific TEE agent with attestation operationId: getTeeAgent parameters: - name: agentId in: path required: true schema: type: string format: uuid description: ID of the TEE agent responses: '200': description: TEE agent details with attestation content: application/json: schema: type: object properties: agent: $ref: '#/components/schemas/TeeAgent' attestation: type: string description: TEE attestation '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Error retrieving TEE agent content: application/json: schema: $ref: '#/components/schemas/Error' /api/tee/logs: post: tags: - tee - logs summary: Query TEE logs description: Queries logs from the Trusted Execution Environment operationId: queryTeeLogs requestBody: required: true content: application/json: schema: type: object properties: query: type: object properties: agentId: type: string format: uuid roomId: type: string format: uuid entityId: type: string format: uuid type: type: string containsContent: type: string startTimestamp: type: integer format: int64 endTimestamp: type: integer format: int64 page: type: integer default: 1 pageSize: type: integer default: 10 responses: '200': description: TEE logs with attestation content: application/json: schema: type: object properties: logs: type: object description: Log query results attestation: type: string description: TEE attestation '500': description: Error retrieving TEE logs content: application/json: schema: $ref: '#/components/schemas/Error' components: schemas: Error: type: object properties: success: type: boolean example: false error: type: object properties: code: type: string description: Error code message: type: string description: Error message details: type: string description: Detailed error information AgentInfo: type: object properties: id: type: string format: uuid description: Unique identifier for the agent name: type: string description: Name of the agent status: type: string enum: [active, inactive] description: Current status of the agent Character: type: object required: - name properties: id: type: string format: uuid description: Unique identifier for the character name: type: string description: Name of the character bio: type: string description: Short biography of the character settings: type: object description: Character-specific settings system: type: string description: System prompt for the character style: type: object description: Character's communication style lore: type: array items: type: string description: Extended lore and background information messageExamples: type: array items: type: string description: Example messages for character training topics: type: array items: type: string description: Topics the character is knowledgeable about plugins: type: array items: type: string description: Plugins used by the character Content: type: object properties: text: type: string description: Text content of the message thought: type: string description: Agent's internal thought process plan: type: string description: Agent's plan or reasoning actions: type: array items: type: string description: Actions the agent wants to take source: type: string description: Source of the message inReplyTo: type: string format: uuid description: ID of the message this is in reply to Memory: type: object properties: id: type: string format: uuid description: Unique identifier for the memory entityId: type: string format: uuid description: ID of the entity associated with this memory agentId: type: string format: uuid description: ID of the agent associated with this memory roomId: type: string format: uuid description: ID of the room this memory belongs to createdAt: type: integer format: int64 description: Unix timestamp when the memory was created content: $ref: '#/components/schemas/Content' Room: type: object properties: id: type: string format: uuid description: Unique identifier for the room name: type: string description: Name of the room source: type: string description: Source of the room worldId: type: string format: uuid description: ID of the world this room belongs to entities: type: array items: type: object properties: id: type: string format: uuid name: type: string description: Entities in this room LogEntry: type: object properties: level: type: number description: Log level time: type: number format: int64 description: Timestamp of the log entry msg: type: string description: Log message agentId: type: string format: uuid description: ID of the related agent (if applicable) agentName: type: string description: Name of the related agent (if applicable) TeeAgent: type: object properties: id: type: string format: uuid description: Unique identifier for the TEE agent name: type: string description: Name of the TEE agent attestation: type: object description: TEE attestation data ```` ## File: .env.example ```` # Logging Configuration (supported: fatal, error, warn, info, debug, trace | default: info) LOG_LEVEL= # OpenAI Configuration OPENAI_API_KEY= # Anthropic Configuration ANTHROPIC_API_KEY= # Fill these out if you want to use Discord DISCORD_APPLICATION_ID= DISCORD_API_TOKEN= # Fill these out if you want to use Postgres POSTGRES_URL= # Fill these out if you want to use Telegram TELEGRAM_BOT_TOKEN= # Fill these out if you want to use Twitter TWITTER_USERNAME= TWITTER_PASSWORD= TWITTER_EMAIL= # Fill these out if you want to use EVM EVM_PRIVATE_KEY= EVM_CHAINS=mainnet,sepolia,base,arbitrum,polygon EVM_PROVIDER_URL= # Fill these out if you want to use Solana SOLANA_PUBLIC_KEY= SOLANA_PRIVATE_KEY= BIRDEYE_API_KEY= # Local AI Configuration USE_LOCAL_AI= USE_STUDIOLM_TEXT_MODELS= USE_OLLAMA_TEXT_MODELS= # Ollama Configuration OLLAMA_SERVER_URL= OLLAMA_MODEL= USE_OLLAMA_EMBEDDING= OLLAMA_EMBEDDING_MODEL= SMALL_OLLAMA_MODEL= MEDIUM_OLLAMA_MODEL= LARGE_OLLAMA_MODEL= # StudioLM Configuration STUDIOLM_SERVER_URL= STUDIOLM_SMALL_MODEL= STUDIOLM_MEDIUM_MODEL= STUDIOLM_EMBEDDING_MODEL= # Settings for The Org COMMUNITY_MANAGER_DISCORD_APPLICATION_ID= COMMUNITY_MANAGER_DISCORD_API_TOKEN= SOCIAL_MEDIA_MANAGER_DISCORD_APPLICATION_ID= SOCIAL_MEDIA_MANAGER_DISCORD_API_TOKEN= LIAISON_DISCORD_APPLICATION_ID= LIAISON_DISCORD_API_TOKEN= PROJECT_MANAGER_DISCORD_APPLICATION_ID= PROJECT_MANAGER_DISCORD_API_TOKEN= DEV_REL_DISCORD_APPLICATION_ID= DEV_REL_DISCORD_API_TOKEN= DEVREL_IMPORT_KNOWLEDGE=true INVESTMENT_MANAGER_DISCORD_APPLICATION_ID= INVESTMENT_MANAGER_DISCORD_API_TOKEN= # Settings for Investment Manager plugins BIRDEYE_API_KEY= JUPITER_API_KEY= HELIUS_API_KEY= COINMARKETCAP_API_KEY= ZEROEX_API_KEY= COINGECKO_API_KEY= ```` ## File: package.json ````json { "name": "eliza", "scripts": { "preinstall": "only-allow bun", "start": "cd ./packages/the-org && bun run start", "start-cli": "cd ./packages/cli && bun run cli start", "start:debug": "cross-env NODE_NO_WARNINGS=1 LOG_LEVEL=debug elizaos start", "start:app": "turbo run start --filter=./packages/app", "dev": "turbo run dev --filter=./packages/the-org", "build:docs": "turbo run build --filter=@elizaos/docs", "build": "turbo run build --filter=@elizaos/client && turbo run build --filter=!@elizaos/docs", "clean": "turbo run clean --filter=./packages/* && rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo bun.lock*", "build:cli": "turbo run build --filter=@elizaos/cli --no-cache", "build:core": "turbo run build --filter=@elizaos/core --no-cache", "lint": "turbo run lint --filter=./packages/* && prettier --write . && prettier --check .", "pre-commit": "bun run scripts/pre-commit-lint.js", "release": "bun run build && bun lint && lerna publish --no-private --force-publish && bun lint", "release:alpha": "lerna publish prerelease --preid alpha --dist-tag alpha --no-private --force-publish --loglevel verbose", "release:beta": "lerna publish prerelease --preid beta --dist-tag beta --no-private --force-publish --loglevel verbose", "migrate": "turbo run migrate --filter=./packages/plugin-sql --force", "migrate:generate": "turbo run migrate:generate --filter=./packages/plugin-sql", "docker:build": "bash ./scripts/docker.sh build", "docker:run": "bash ./scripts/docker.sh run", "docker:bash": "bash ./scripts/docker.sh bash", "docker:start": "bash ./scripts/docker.sh start", "docker": "bun docker:build && bun docker:run && bun docker:bash", "test": "turbo run test --concurrency 20 --filter=!./packages/plugin-starter --filter=!./packages/project-starter --filter=!./packages/the-org --filter=!./packages/docs --filter=!./packages/plugin-video-understanding", "test:app": "turbo run test --concurrency 20 --filter=./packages/app", "prepare": "husky" }, "devDependencies": { "@types/bun": "latest", "@types/node": "^22.13.10", "@types/uuid": "^9.0.8", "@vitest/eslint-plugin": "1.0.1", "bun": "1.2.5", "concurrently": "9.1.0", "cross-env": "7.0.3", "husky": "^9.1.7", "lerna": "8.1.4", "lint-staged": "^15.5.0", "only-allow": "^1.2.1", "sharp": "0.33.5", "tsup": "8.4.0", "turbo": "^2.4.4", "typedoc": "0.27.9", "typescript": "^5.8.2", "vite": "5.4.12", "vitest": "3.0.5" }, "bun": { "overrides": { "cookie": "0.7.0", "bs58": "5.0.0", "secp256k1": "5.0.1", "minipass": "7.1.2", "form-data": "4.0.2", "eslint": "9.22.0", "react": "19.0.0", "react-dom": "19.0.0", "got": "12.6.1" } }, "engines": { "node": "23.3.0" }, "dependencies": { "@anthropic-ai/sdk": "^0.39.0", "@babel/generator": "^7.26.10", "@hapi/shot": "^6.0.1", "@types/hapi": "^18.0.14", "@types/hapi__shot": "^6.0.0", "node-opus": "^0.3.3", "opusscript": "^0.1.1", "vittest": "^1.0.2", "zod": "3.24.1" }, "packageManager": "bun@1.2.5", "workspaces": [ "packages/*" ], "module": "index.ts", "type": "module", "resolutions": { "@nrwl/devkit": "19.8.13", "@nrwl/tao": "19.8.13", "zod": "3.24.1", "eslint": "9.22.0", "react": "19.0.0", "react-dom": "19.0.0", "vitest": "3.0.5", "@metaplex-foundation/umi": "0.9.2", "typedoc-plugin-markdown": "4.2.10", "buffer": "6.0.3", "@solana/spl-token": "0.4.9", "solana-bankrun": "0.3.1", "got": "12.6.1", "form-data": "4.0.2" }, "trustedDependencies": [ "@swc/core", "bigint-buffer", "bufferutil", "bun", "canvas", "esbuild", "husky", "node-llama-cpp", "protobufjs", "sharp", "utf-8-validate" ] } ```` ## File: README.md ````markdown # Eliza 🤖
Eliza Banner
📑 [Technical Report](https://arxiv.org/pdf/2501.06781) | 📖 [Documentation](https://elizaos.github.io/eliza/) | 🎯 [Examples](https://github.com/thejoven/awesome-eliza)
## 🌍 README Translations [中文说明](packages/docs/i18n/readme/README_CN.md) | [日本語の説明](packages/docs/i18n/readme/README_JA.md) | [한국어 설명](packages/docs/i18n/readme/README_KOR.md) | [Persian](packages/docs/i18n/readme/README_FA.md) | [Français](packages/docs/i18n/readme/README_FR.md) | [Português](packages/docs/i18n/readme/README_PTBR.md) | [Türkçe](packages/docs/i18n/readme/README_TR.md) | [Русский](packages/docs/i18n/readme/README_RU.md) | [Español](packages/docs/i18n/readme/README_ES.md) | [Italiano](packages/docs/i18n/readme/README_IT.md) | [ไทย](packages/docs/i18n/readme/README_TH.md) | [Deutsch](packages/docs/i18n/readme/README_DE.md) | [Tiếng Việt](packages/docs/i18n/readme/README_VI.md) | [עִברִית](packages/docs/i18n/readme/README_HE.md) | [Tagalog](packages/docs/i18n/readme/README_TG.md) | [Polski](packages/docs/i18n/readme/README_PL.md) | [Arabic](packages/docs/i18n/readme/README_AR.md) | [Hungarian](packages/docs/i18n/readme/README_HU.md) | [Srpski](packages/docs/i18n/readme/README_RS.md) | [Română](packages/docs/i18n/readme/README_RO.md) | [Nederlands](packages/docs/i18n/readme/README_NL.md) | [Ελληνικά](packages/docs/i18n/readme/README_GR.md) ## 🚩 Overview
Eliza Diagram
## ✨ Features - 🛠️ Full-featured Discord, X (Twitter) and Telegram connectors - 🔗 Support for every model (Llama, Grok, OpenAI, Anthropic, Gemini, etc.) - 👥 Multi-agent and room support - 📚 Easily ingest and interact with your documents - 💾 Retrievable memory and document store - 🚀 Highly extensible - create your own actions and clients - 📦 Just works! ## Video Tutorials [AI Agent Dev School](https://www.youtube.com/watch?v=ArptLpQiKfI&list=PLx5pnFXdPTRzWla0RaOxALTSTnVq53fKL) ## 🎯 Use Cases - 🤖 Chatbots - 🕵️ Autonomous Agents - 📈 Business Process Handling - 🎮 Video Game NPCs - 🧠 Trading ## 🚀 Quick Start ### Prerequisites - [Python 2.7+](https://www.python.org/downloads/) - [Node.js 23+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [bun](https://bun.sh/docs/installation) > **Note for Windows Users:** [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install-manual) is required. ### Use the Starter (Recommended) ```bash git clone https://github.com/elizaos/eliza-starter.git cd eliza-starter cp .env.example .env bun i && bun run build && bun start ``` ### Manually Start Eliza (Only recommended if you know what you are doing) #### Checkout the latest release ```bash # Clone the repository git clone https://github.com/elizaos/eliza.git # This project iterates fast, so we recommend checking out the latest release git checkout $(git describe --tags --abbrev=0) # If the above doesn't checkout the latest release, this should work: # git checkout $(git describe --tags `git rev-list --tags --max-count=1`) ``` #### Edit the .env file Copy .env.example to .env and fill in the appropriate values. ``` cp .env.example .env ``` Note: .env is optional. If you're planning to run multiple distinct agents, you can pass secrets through the character JSON #### Start Eliza Important! We now use Bun. If you are using npm, you will need to install Bun: https://bun.sh/docs/installation ```bash bun install bun run build # npm will work too bun start # npm will work too ``` ### Interact via Browser Once the agent is running, you can visit http://localhost:3000 to interact with your agent through a web interface. The interface provides: - Real-time chat with your agent - Character configuration options - Plugin management - Memory and conversation history --- ### Automatically Start Eliza The start script provides an automated way to set up and run Eliza: ## Citation We now have a [paper](https://arxiv.org/pdf/2501.06781) you can cite for the Eliza OS: ```bibtex @article{walters2025eliza, title={Eliza: A Web3 friendly AI Agent Operating System}, author={Walters, Shaw and Gao, Sam and Nerd, Shakker and Da, Feng and Williams, Warren and Meng, Ting-Chien and Han, Hunter and He, Frank and Zhang, Allen and Wu, Ming and others}, journal={arXiv preprint arXiv:2501.06781}, year={2025} } ``` ## Contributors Eliza project contributors ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=elizaos/eliza&type=Date)](https://star-history.com/#elizaos/eliza&Date) ## Git Hooks This project uses git hooks to ensure code quality: - **pre-commit**: Automatically formats staged files using Prettier before committing To run the pre-commit hook manually: ```bash bun run pre-commit ``` ```` # Instruction # ElizaOS Developer Context This file contains the core technical aspects of ElizaOS, focusing on its architecture, implementation, and developer-facing components. The codebase is organized as a monorepo with several key packages: ## Key Components 1. **Core Package**: The foundation of ElizaOS with the agent runtime, entity management, actions, and database interactions 2. **CLI Package**: Command-line interface for managing agents, projects, and development tasks 3. **Client Package**: Frontend interface components and API interactions 4. **SQL/Database**: Database adapters and schema management 5. **Autodoc**: Documentation generation tools ## Technical Goals When analyzing this codebase: - Focus on the architecture and relationships between components - Identify core abstractions and design patterns - Understand the runtime execution flow - Analyze how agents, actions, and providers work together - Look for opportunities to improve code organization and performance - Consider modular extension points and plugin architecture ## Output Guidance - When suggesting improvements, focus on technical aspects like code structure, performance optimizations, and architectural changes - Include specific code examples when proposing changes - Consider backwards compatibility and migration paths for any proposed changes - Highlight innovative technical approaches used in the system - When asked about implementation details, provide comprehensive technical explanations