Memory handling

The Lillo Agent Memory System provides a multi-layered approach to state management and data persistence, combining short-term state tracking with long-term data storage.

Memory Architecture

1. State Management Layer

The state management system handles temporary agent states and creation flows:

interface AgentCreationState {
  userId: number;
  step: AgentCreationStep;
  data: {
    bioField?: BioFieldState;
    socialsField?: SocialsFieldState;
    cryptoField?: CryptoFieldState;
  };
  lastUpdated: number;
  isActive: boolean;
}

Key features:

  • TTL-based state expiration (24 hours)

  • State progression tracking

  • Multi-step process management

  • Automatic cleanup

2. Key-Value Store

The KV store provides fast access to frequently used data:

interface StorageData {
  [key: string]: unknown;
}

// Storage Operations
async function storeInKV(key: string, data: StorageData): Promise<void>;
async function invalidateCache(pattern: string): Promise<void>;

Use cases:

  • User session data

  • Agent configuration caching

  • Temporary state storage

  • Quick-access data

3. Persistent Storage

Long-term data storage in PostgreSQL:

-- Chat History
CREATE TABLE chat_messages (
  id SERIAL PRIMARY KEY,
  message_id BIGINT NOT NULL,
  chat_id BIGINT NOT NULL,
  user_id BIGINT NOT NULL,
  user_first_name VARCHAR(255) NOT NULL,
  username VARCHAR(255),
  role VARCHAR(50) NOT NULL,
  content TEXT NOT NULL,
  timestamp BIGINT NOT NULL,
  reply_to_message_id BIGINT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(chat_id, message_id)
);

-- Content History
CREATE TABLE posts (
  id SERIAL PRIMARY KEY,
  type VARCHAR(50) NOT NULL,
  content TEXT NOT NULL,
  timestamp BIGINT NOT NULL,
  location VARCHAR(255),
  prompt TEXT,
  image_url TEXT,
  tweet_id TEXT
);

Memory Types

1. Short-Term Memory

  • State Tracking

    // Initialize state
    await AgentStateManager.initState(userId);
    
    // Update state
    await AgentStateManager.setState(userId, {
      step: AgentCreationStep.PERSONALITY,
      isActive: true
    });
  • Session Data

    // Cache user data
    const userData = {
      walletAddress,
      telegramId,
      username,
      lastVerified: Date.now()
    };
    await storeInKV(`user:${walletAddress}`, userData);

2. Long-Term Memory

  • Chat History

    interface ChatHistoryEntry {
      messageId: number;
      chatId: number;
      userId: number;
      content: string;
      role: string;
      timestamp: number;
    }
  • Content History

    interface PostHistoryEntry {
      timestamp: string;
      message: string;
      type: string;
      location?: string;
      prompt?: string;
      imageUrl?: string;
    }

Memory Operations

1. State Management

class AgentStateManager {
  // Get current state
  static async getState(userId: number): Promise<AgentCreationState | null>;
  
  // Update state
  static async setState(userId: number, state: Partial<AgentCreationState>);
  
  // Clear state
  static async clearState(userId: number);
  
  // Initialize state
  static async initState(userId: number): Promise<AgentCreationState>;
  
  // Pause state
  static async pauseState(userId: number);
}

2. History Management

// Load post history
async function loadPostHistory(): Promise<PostHistory>;

// Save post history
async function savePostHistory(history: PostHistory): Promise<void>;

// Get recent locations
async function getRecentLocations(): Promise<Set<string>>;

3. User Data Management

// Update user data
async function updateUserData(data: Partial<UserData>): Promise<void>;

// Get user data
async function getUserData(walletAddress: string): Promise<UserData | null>;

// Clear user cache
function clearUserCache(walletAddress?: string): void;

Best Practices

  1. State Management

    • Clear states after completion

    • Handle state transitions gracefully

    • Implement proper error recovery

    • Use appropriate TTLs

  2. Data Persistence

    • Cache frequently accessed data

    • Implement proper invalidation

    • Use transactions for consistency

    • Handle concurrent access

  3. Memory Cleanup

    • Regular cache invalidation

    • State cleanup on completion

    • History pruning strategies

    • Error state recovery

Example Usage

// Managing agent creation state
async function handleAgentCreation(userId: number) {
  // Initialize state
  await AgentStateManager.initState(userId);
  
  try {
    // Update state with progress
    await AgentStateManager.setState(userId, {
      step: AgentCreationStep.PERSONALITY,
      data: {
        bioField: {
          agentId: 'agent123',
          field: 'background'
        }
      }
    });
    
    // Process creation steps...
    
  } catch (error) {
    // Handle error and cleanup
    await AgentStateManager.clearState(userId);
    throw error;
  }
  
  // Clear state on completion
  await AgentStateManager.clearState(userId);
}

Last updated