Memory Hooks

Intercept and modify memory operations with pre/post hooks

Intercept memory operations with hooks. Log access, validate data, encrypt content, and implement custom caching.

Diagram

Memory

Memory Hooks

Operations

Quick Start

  1. Simple Usage
    typescript
    import { MemoryHooks, createMemoryHooks } from 'praisonai';
    
    const hooks = createMemoryHooks({
      beforeStore: async (key, value, metadata) => {
        console.log(`Storing: ${key}`);
        // Can modify or cancel
        return { key, value, metadata };
      },
    
      afterStore: async (key, value) => {
        console.log(`Stored: ${key}`);
      },
    
      beforeRetrieve: async (key) => {
        console.log(`Retrieving: ${key}`);
        return key;  // Can modify key
      },
    
      afterRetrieve: async (key, value) => {
        console.log(`Retrieved: ${key}`);
        return value;  // Can modify value
      }
    });
  2. With Configuration
    typescript
    const hooks = createMemoryHooks({
      beforeStore: async (key, value, metadata) => ({ key, value, metadata }),
      verbose: true,
    });

Logging Hooks

typescript
import { createLoggingHooks } from 'praisonai';

// Create hooks that log all operations
const loggingHooks = createLoggingHooks((msg) => {
  console.log(`[Memory] ${msg}`);
});

// All memory operations will be logged:
// [Memory] Storing: user-preferences
// [Memory] Stored: user-preferences
// [Memory] Retrieving: user-preferences
// [Memory] Retrieved: user-preferences (found)

Validation Hooks

typescript
import { createValidationHooks } from 'praisonai';

// Create hooks that validate before storing
const validationHooks = createValidationHooks((key, value) => {
  // Reject empty values
  if (!value || value.trim() === '') {
    return { valid: false, reason: 'Empty values not allowed' };
  }

  // Reject keys with special characters
  if (/[^a-zA-Z0-9_-]/.test(key)) {
    return { valid: false, reason: 'Invalid key format' };
  }

  return { valid: true };
});

Encryption Hooks

typescript
import { createEncryptionHooks } from 'praisonai';
import crypto from 'crypto';

const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

function encrypt(data: any): string {
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  const json = JSON.stringify(data);
  return cipher.update(json, 'utf8', 'hex') + cipher.final('hex');
}

function decrypt(data: string): any {
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  const json = decipher.update(data, 'hex', 'utf8') + decipher.final('utf8');
  return JSON.parse(json);
}

const encryptionHooks = createEncryptionHooks(encrypt, decrypt);

// All stored values are encrypted, all retrieved values are decrypted

Use with Memory

typescript
import { Memory, MemoryHooks } from 'praisonai';

const hooks = new MemoryHooks({
  logging: true,  // Enable built-in logging

  beforeStore: async (key, value) => {
    // Add timestamp to all stored values
    return {
      key,
      value: { ...value, storedAt: Date.now() }
    };
  }
});

const memory = new Memory({
  hooks,
  maxSize: 1000
});

await memory.set('user', { name: 'John' });
// Logged: [MemoryHooks] beforeStore: user
// Logged: [MemoryHooks] afterStore: user

Dynamic Hook Management

typescript
import { MemoryHooks } from 'praisonai';

const hooks = new MemoryHooks();

// Add hooks dynamically
hooks.addHook('beforeStore', async (key, value) => {
  console.log(`Dynamic hook: ${key}`);
  return { key, value };
});

// Remove hooks
hooks.removeHook('beforeStore');

// Enable/disable logging
hooks.setLogging(true);

// Get current configuration
const config = hooks.getConfig();

Hook Types

HookWhen CalledCan Modify
beforeStoreBefore storing valueKey, value, metadata, or cancel
afterStoreAfter successful storeNothing (side effects only)
beforeRetrieveBefore retrieving valueKey or cancel
afterRetrieveAfter retrievalReturn value
beforeDeleteBefore deleting valueProceed or cancel
afterDeleteAfter deletionNothing (side effects only)
beforeSearchBefore search queryQuery and options
afterSearchAfter searchResults

Complete Example

typescript
import { Agent, Memory, MemoryHooks, createLoggingHooks } from 'praisonai';

// Combine multiple hook behaviors
const hooks = new MemoryHooks({
  logging: true,

  beforeStore: async (key, value) => {
    // Validate
    if (typeof value !== 'string' && typeof value !== 'object') {
      console.warn(`Invalid value type for ${key}`);
      return null;  // Cancel store
    }
    return { key, value };
  },

  afterRetrieve: async (key, value) => {
    // Track access
    console.log(`Memory accessed: ${key}`);
    return value;
  }
});

const memory = new Memory({ hooks });

const agent = new Agent({
  name: 'Hooked Agent',
  instructions: 'You use memory with full hooks.',
  memory
});

Related