Supabase Memory
The @voltagent/supabase
package provides a SupabaseMemory
provider that uses a Supabase project (PostgreSQL database) for persistent storage of agent memory.
This is a good choice if your application is already built on Supabase or if you require a robust, scalable PostgreSQL backend with managed features like authentication, real-time subscriptions, and storage.
Setup​
Install Package​
First, install the necessary packages:
- npm
- yarn
- pnpm
npm install @voltagent/supabase @supabase/supabase-js
yarn add @voltagent/supabase @supabase/supabase-js
pnpm add @voltagent/supabase @supabase/supabase-js
Database Setup​
Unlike LibSQLStorage
, SupabaseMemory
does not automatically create database tables. You must run the following SQL commands in your Supabase project's SQL Editor (Dashboard -> SQL Editor -> New query) before using the provider.
Note: These commands use the default table prefix voltagent_memory
. If you provide a custom tableName
option when initializing SupabaseMemory
(e.g., new SupabaseMemory({ ..., tableName: 'my_custom_prefix' })
), you must replace voltagent_memory
with my_custom_prefix
in the SQL commands below.
Click to view Database Setup SQL
-- Conversations Table
CREATE TABLE IF NOT EXISTS voltagent_memory_conversations (
id TEXT PRIMARY KEY,
resource_id TEXT NOT NULL,
title TEXT,
metadata JSONB, -- Use JSONB for efficient querying
created_at TIMESTAMPTZ NOT NULL DEFAULT timezone('utc'::text, now()),
updated_at TIMESTAMPTZ NOT NULL DEFAULT timezone('utc'::text, now())
);
-- Index for faster lookup by resource_id
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_conversations_resource
ON voltagent_memory_conversations(resource_id);
-- Messages Table
CREATE TABLE IF NOT EXISTS voltagent_memory_messages (
user_id TEXT NOT NULL,
-- Add foreign key reference and cascade delete
conversation_id TEXT NOT NULL REFERENCES voltagent_memory_conversations(id) ON DELETE CASCADE,
message_id TEXT NOT NULL,
role TEXT NOT NULL,
content TEXT NOT NULL, -- Consider JSONB if content is often structured
type TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT timezone('utc'::text, now()),
-- Composite primary key to ensure message uniqueness within a conversation
PRIMARY KEY (user_id, conversation_id, message_id)
);
-- Index for faster message retrieval
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_messages_lookup
ON voltagent_memory_messages(user_id, conversation_id, created_at);
-- Agent History Table
CREATE TABLE IF NOT EXISTS voltagent_memory_agent_history (
key TEXT PRIMARY KEY,
value JSONB NOT NULL, -- Store the entry object as JSONB
agent_id TEXT NOT NULL
);
-- Index for faster lookup by agent_id
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_agent_history_agent_id
ON voltagent_memory_agent_history(agent_id);
-- Agent History Events Table
CREATE TABLE IF NOT EXISTS voltagent_memory_agent_history_events (
key TEXT PRIMARY KEY,
value JSONB NOT NULL, -- Store the event object as JSONB
-- Foreign key to history entry
history_id TEXT NOT NULL REFERENCES voltagent_memory_agent_history(key) ON DELETE CASCADE,
agent_id TEXT NOT NULL
);
-- Indexes for faster lookup
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_agent_history_events_history_id
ON voltagent_memory_agent_history_events(history_id);
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_agent_history_events_agent_id
ON voltagent_memory_agent_history_events(agent_id);
-- Agent History Steps Table
CREATE TABLE IF NOT EXISTS voltagent_memory_agent_history_steps (
key TEXT PRIMARY KEY,
value JSONB NOT NULL, -- Store the step object as JSONB
-- Foreign key to history entry
history_id TEXT NOT NULL REFERENCES voltagent_memory_agent_history(key) ON DELETE CASCADE,
agent_id TEXT NOT NULL
);
-- Indexes for faster lookup
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_agent_history_steps_history_id
ON voltagent_memory_agent_history_steps(history_id);
CREATE INDEX IF NOT EXISTS idx_voltagent_memory_agent_history_steps_agent_id
ON voltagent_memory_agent_history_steps(agent_id);
Alternatively, integrate these SQL statements into your Supabase migration workflow using the Supabase CLI.
Credentials​
You will need your Supabase project's URL and anon
key.
- Navigate to your project in the Supabase Dashboard.
- Go to Project Settings (the gear icon).
- Select the API section.
- Find your Project URL and the Project API key labelled
anon
(public).
Store these credentials securely, typically as environment variables (e.g., SUPABASE_URL
and SUPABASE_KEY
).
Configuration​
Import SupabaseMemory
and initialize it with your credentials:
import { Agent } from "@voltagent/core";
import { SupabaseMemory } from "@voltagent/supabase";
import { VercelAIProvider } from "@voltagent/vercel-ai";
import { openai } from "@ai-sdk/openai";
// Get credentials from environment variables
const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_KEY;
if (!supabaseUrl || !supabaseKey) {
throw new Error("Supabase URL and Key must be provided via environment variables.");
}
// Initialize SupabaseMemory
const memory = new SupabaseMemory({
supabaseUrl,
supabaseKey,
// Optional: Specify a custom base table name prefix
// This MUST match the prefix used in your SQL setup if customized.
// tableName: 'my_agent_memory', // Defaults to 'voltagent_memory'
});
const agent = new Agent({
name: "Supabase Memory Agent",
instructions: "An agent using Supabase for memory.",
llm: new VercelAIProvider(),
model: openai("gpt-4o"),
memory: memory, // Assign the memory provider instance
});
Configuration Options:
supabaseUrl
(string, required): Your Supabase project URL.supabaseKey
(string, required): Your Supabase projectanon
key (or a service role key if used in a secure backend environment, thoughanon
key with appropriate RLS policies is often sufficient).tableName
(string, optional): A prefix for the database table names. Defaults tovoltagent_memory
. If you change this, ensure your SQL table creation script uses the same prefix.
Row Level Security (RLS)​
For production applications, especially if using the anon
key, it is highly recommended to enable Row Level Security (RLS) on the VoltAgent memory tables (voltagent_memory_messages
, voltagent_memory_conversations
, etc.) and define appropriate policies. This ensures users can only access their own conversation data.
Refer to the Supabase RLS documentation for detailed guidance on setting up policies.
Use Cases​
- Applications already using Supabase for backend services.
- Projects requiring a scalable, managed PostgreSQL database.
- Scenarios where leveraging Supabase features like Auth, Realtime, or Storage alongside agent memory is beneficial.
- Production environments where robust data management and security policies (RLS) are essential.