Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

@ai-sdk-tools/memory

Persistent memory system for AI agents with built-in providers for development and production.

Features

  • Simple API - Just 4 methods to implement
  • Built-in Providers - InMemory, Drizzle ORM, Redis, and Upstash included
  • TypeScript-first - Full type safety
  • Flexible Scopes - Chat-level or user-level memory
  • Conversation History - Optional message tracking
  • Database Agnostic - Works with PostgreSQL, MySQL, and SQLite via Drizzle

Installation

npm install @ai-sdk-tools/memory
# or
yarn add @ai-sdk-tools/memory
# or
pnpm add @ai-sdk-tools/memory
# or
bun add @ai-sdk-tools/memory

Optional Dependencies

# For Drizzle ORM provider (PostgreSQL, MySQL, or SQLite)
npm install drizzle-orm

# For Upstash Redis provider (serverless/edge)
npm install @upstash/redis

# For standard Redis provider (self-hosted/traditional)
npm install redis
# or
npm install ioredis

Quick Start

InMemory Provider (Development)

Perfect for local development - works immediately, no setup needed.

import { InMemoryProvider } from "@ai-sdk-tools/memory";

const memory = new InMemoryProvider();

// Use with agents
const context = buildAppContext({
  // ...
  memory: {
    provider: memory,
    workingMemory: {
      enabled: true,
      scope: "chat",
    },
  },
});

Drizzle Provider (Production - Any SQL Database)

Works with PostgreSQL, MySQL, and SQLite via Drizzle ORM. Perfect if you already use Drizzle in your project.

import { drizzle } from "drizzle-orm/vercel-postgres";
import { sql } from "@vercel/postgres";
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
import { DrizzleProvider } from "@ai-sdk-tools/memory";

// Define your schema
const workingMemory = pgTable("working_memory", {
  id: text("id").primaryKey(),
  scope: text("scope").notNull(),
  chatId: text("chat_id"),
  userId: text("user_id"),
  content: text("content").notNull(),
  updatedAt: timestamp("updated_at").notNull(),
});

const messages = pgTable("conversation_messages", {
  id: serial("id").primaryKey(),
  chatId: text("chat_id").notNull(),
  userId: text("user_id"),
  role: text("role").notNull(),
  content: text("content").notNull(),
  timestamp: timestamp("timestamp").notNull(),
});

// Initialize
const db = drizzle(sql);
const memory = new DrizzleProvider(db, {
  workingMemoryTable: workingMemory,
  messagesTable: messages,
});

Full Drizzle documentation → - Includes PostgreSQL, MySQL, SQLite/Turso examples

Redis Provider (Production - Self-Hosted)

Perfect for traditional Redis instances (self-hosted, Redis Cloud, AWS ElastiCache, etc.). Supports both ioredis and redis npm packages.

With ioredis:

import Redis from "ioredis";
import { RedisProvider } from "@ai-sdk-tools/memory/redis";

const redis = new Redis(process.env.REDIS_URL);
const memory = new RedisProvider(redis);

With redis package:

import { createClient } from "redis";
import { RedisProvider } from "@ai-sdk-tools/memory/redis";

const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();
const memory = new RedisProvider(redis, {
  prefix: "my-app:memory:",
  messageTtl: 60 * 60 * 24 * 30, // Optional: 30 days TTL for messages (default: no expiration)
});

Upstash Provider (Production - Serverless)

Perfect for edge and serverless environments. Uses HTTP REST API instead of direct TCP connection.

import { Redis } from "@upstash/redis";
import { UpstashProvider } from "@ai-sdk-tools/memory/upstash";

const redis = Redis.fromEnv();
const memory = new UpstashProvider(redis, {
  prefix: "my-app:memory:",
  messageTtl: 60 * 60 * 24 * 30, // Optional: 30 days TTL for messages (default: no expiration)
});

When to use Redis vs Upstash:

  • Redis Provider: Use when you have a traditional Redis instance (self-hosted, Redis Cloud, AWS ElastiCache, etc.)
  • Upstash Provider: Use for serverless/edge environments where HTTP REST API is preferred

Usage with Agents

import { InMemoryProvider } from "@ai-sdk-tools/memory";

const appContext = buildAppContext({
  userId: "user-123",
  // ... other context
  metadata: {
    chatId: "chat_abc123",
    userId: "user-123",
  },
  memory: {
    provider: new InMemoryProvider(),
    workingMemory: {
      enabled: true,
      scope: "chat", // or 'user'
      template: `# Working Memory

## Key Facts
- [Important information]

## Preferences
- [User preferences]
`,
    },
    history: {
      enabled: true,
      limit: 10,
    },
  },
});

// Agent automatically:
// 1. Loads working memory into system prompt
// 2. Injects updateWorkingMemory tool
// 3. Captures conversation messages

Memory Scopes

Chat Scope (Recommended)

Memory is tied to a specific conversation.

workingMemory: {
  enabled: true,
  scope: 'chat',
}

User Scope

Memory persists across all conversations for a user.

workingMemory: {
  enabled: true,
  scope: 'user',
}

Custom Provider

Implement the MemoryProvider interface:

import type {
  MemoryProvider,
  WorkingMemory,
  ConversationMessage,
  MemoryScope,
} from "@ai-sdk-tools/memory";

class MyProvider implements MemoryProvider {
  async getWorkingMemory(params: {
    chatId?: string;
    userId?: string;
    scope: MemoryScope;
  }): Promise<WorkingMemory | null> {
    // Your implementation
  }

  async updateWorkingMemory(params: {
    chatId?: string;
    userId?: string;
    scope: MemoryScope;
    content: string;
  }): Promise<void> {
    // Your implementation
  }

  // Optional methods
  async saveMessage(message: ConversationMessage): Promise<void> {
    // Your implementation
  }

  async getMessages(params: {
    chatId: string;
    limit?: number;
  }): Promise<ConversationMessage[]> {
    // Your implementation
  }
}

API Reference

Types

WorkingMemory

interface WorkingMemory {
  content: string;
  updatedAt: Date;
}

MemoryScope

type MemoryScope = "chat" | "user";

ConversationMessage

interface ConversationMessage {
  chatId: string;
  userId?: string;
  role: "user" | "assistant" | "system";
  content: string;
  timestamp: Date;
}

MemoryProvider

interface MemoryProvider {
  getWorkingMemory(params: {
    chatId?: string;
    userId?: string;
    scope: MemoryScope;
  }): Promise<WorkingMemory | null>;

  updateWorkingMemory(params: {
    chatId?: string;
    userId?: string;
    scope: MemoryScope;
    content: string;
  }): Promise<void>;

  saveMessage?(message: ConversationMessage): Promise<void>;

  getMessages?(params: {
    chatId: string;
    limit?: number;
  }): Promise<ConversationMessage[]>;
}

License

MIT