Memory & Sessions
ArchadiAgent separates three layers of state:
- Agent configuration — the
Agentobject itself (instructions, tools, model). Immutable, shared across every run. - Current run state — held only for the duration of one
Runner.run()call (the in-flightmessagesarray, the active agent during handoffs, the trace). Never persisted. - Persistent session state — the conversation transcript, via a
SessionStore, keyed bysessionId, surviving across runs/process restarts.
Sessions (raw transcript)
import { FileSessionStore, InMemorySessionStore } from "archadi-agent";
const sessionStore = new FileSessionStore(".archadi/sessions.json"); // zero-dependency, durable
// or: new InMemorySessionStore() // fast, lost on restart
const agent = Agent.builder().name("Assistant").instructions("...").model(target).sessionStore(sessionStore).build();
await runner.run(agent, "my name is Aditya", { sessionId: "user-42" });
await runner.run(agent, "what's my name?", { sessionId: "user-42" }); // remembers, same sessionImplement the SessionStore interface yourself to back it with Redis, SQLite, Postgres, etc:
interface SessionStore {
getHistory(sessionId: string): Promise<ChatMessage[]>;
appendMessages(sessionId: string, messages: ChatMessage[]): Promise<void>;
clear(sessionId: string): Promise<void>;
listSessions(): Promise<string[]>;
}Long-term memory (semantic, cross-session)
A SessionStore replays the entire transcript every run — fine for one conversation, wasteful across months of usage. LongTermMemory instead extracts and retrieves only what's relevant to the current message, using mem0:
import { Mem0Memory } from "archadi-agent";
const memory = new Mem0Memory({ apiKey: process.env.MEM0_API_KEY! }); // hosted
// or: new Mem0Memory({ mode: "local", localConfig: { /* vector store config */ } })
const agent = Agent.builder().name("Assistant").instructions("...").model(target).longTermMemory(memory).build();
await runner.run(agent, "I prefer TypeScript over Python", { userId: "aditya" });
// ... weeks later, a different session ...
await runner.run(agent, "what language should I use for this script?", { userId: "aditya" });
// -> the Runner recalls relevant facts and injects them into the system prompt automaticallymem0ai is an optional peer dependency — install it only if you use Mem0Memory:
npm install mem0aiNo mem0 account yet? SimpleLongTermMemory is a zero-setup, in-process fallback with the same interface — the CLI's --memory flag uses it by default.
How the Runner uses both together
Each run() call:
- Loads the session transcript (
sessionStore.getHistory) and prepends it to the prompt. - Recalls relevant long-term facts (
longTermMemory.recall) and injects them into the system message. - After a successful run, appends the new turn to the session store and long-term memory (
longTermMemory.remember).
SQLite storage
For production durability without running a separate database server, use the built-in SQLite adapter:
npm install better-sqlite3import { SqliteSessionStore } from "archadi-agent";
const sessionStore = new SqliteSessionStore("./data/sessions.db");
const agent = Agent.builder()
.name("Assistant")
.instructions("...")
.model(target)
.sessionStore(sessionStore)
.build();The SQLite store auto-creates the database file and table on first use, uses WAL mode for performance, and wraps batch writes in transactions. Call sessionStore.close() during graceful shutdown.
Custom storage adapters
Implement the SessionStore interface to back sessions with Redis, Postgres, DynamoDB, or anything else:
class RedisSessionStore implements SessionStore {
async getHistory(sessionId: string): Promise<ChatMessage[]> { /* ... */ }
async appendMessages(sessionId: string, messages: ChatMessage[]): Promise<void> { /* ... */ }
async clear(sessionId: string): Promise<void> { /* ... */ }
async listSessions(): Promise<string[]> { /* ... */ }
}