stackbone.memory
Status: planned. This surface is already on the ambient
stackboneclient, but every method currently returnsnot_implemented. The shape on this page is the contract you can type against today. The backend will be mem0 (MEM0_API_KEY, optionalMEM0_BASE_URL), and every method goes live once that wiring lands — no code change on your side.
stackbone.memory is the long-term memory store for an agent. You reach
it through the ambient stackbone client from any
deep-agent tool or durable
workflow step:
import { stackbone } from '@stackbone/sdk';
await stackbone.memory.add('Prefers dark mode and Spanish UI.', { userId: 'user_42' });It is backed by the external mem0 service, so it
stands apart from the agent's own Postgres (stackbone.database)
and needs no special capability — just the MEM0_API_KEY the runtime
injects.
Memory vs. a deep-agent session
A deep agent already remembers a conversation across turns inside a single
session: that durable buffer comes for free with every
agent session. stackbone.memory
is different: it is for explicit facts you want to persist across
sessions and across users ("this customer is on the Pro plan",
"prefers Spanish"). Use the session for the live conversation; use
stackbone.memory for what should outlive it.
Scopes
Every memory belongs to a scope:
| Scope | Lifetime | Use it for |
|---|---|---|
'user' |
Long-term (default). | Facts about a specific end-user of the agent. |
'session' |
Short-lived; collapsed by endSession. |
Conversation buffer while a single chat is in flight. |
'agent' |
Shared across every user of the agent. | Global facts the agent should know regardless of caller. |
scope: 'session' requires a sessionId. The other scopes do not.
API
Every method returns the standard Result<T> envelope
({ data, error: null } | { data: null, error: SdkError }). Calls
happen from inside a deep-agent tool or a workflow step, where the
ambient stackbone handle is in scope.
add(content, request)
Stores a new memory. content is either a string (ingested verbatim)
or an OpenAI-shaped ChatCompletionMessageParam[] — message arrays
are summarised by mem0 into one or more facts.
import { tool } from '@langchain/core/tools';
import { stackbone, z } from '@stackbone/sdk';
const rememberFact = tool(
async ({ userId, fact }: { userId: string; fact: string }) => {
const { error } = await stackbone.memory.add(fact, { userId });
return error ? 'Could not remember that.' : 'Remembered.';
},
{
name: 'remember_fact',
description: 'Remember a fact about the current user.',
schema: z.object({ userId: z.string(), fact: z.string() }),
},
);A message array, scoped to a single session:
await stackbone.memory.add(
[
{ role: 'user', content: 'I need to switch my plan to Pro' },
{ role: 'assistant', content: 'Sure, I will upgrade your account now.' },
],
{ userId: 'user_42', sessionId: 'sess_abc', scope: 'session' },
);search(query, options?)
Semantic search across the configured scopes. Returns hits sorted by
descending cosine similarity, capped at limit (default 10) and
filtered by threshold if provided.
const { data } = await stackbone.memory.search('What plan is the user on?', {
userId: 'user_42',
limit: 5,
threshold: 0.7,
});
for (const hit of data) {
console.log(hit.score.toFixed(2), hit.content);
}filters AND-merge metadata predicates onto the semantic match.
includeScopes restricts the search (omit to search every scope).
get(memoryId)
Returns a single memory by id.
list(request)
Paginated list of memories for a userId.
const { data } = await stackbone.memory.list({ userId: 'user_42', limit: 50 });update(memoryId, options)
Updates the content and/or metadata of a memory. Metadata is shallow- merged (mem0 semantics).
await stackbone.memory.update('mem_123', { content: 'Prefers light mode now.' });delete(memoryId)
Deletes a single memory. Resolves to { id } — the id of the deleted
memory.
deleteAll(request)
Deletes every memory for a userId. Resolves to { deleted } — the
number of memories removed.
await stackbone.memory.deleteAll({ userId: 'user_42' });history(memoryId)
Returns the audit trail for a memory — every created, updated,
accessed or deleted event, with before and after content
snapshots where applicable.
const { data } = await stackbone.memory.history('mem_123');
for (const entry of data) {
console.log(entry.event, '@', entry.at, 'by', entry.actor);
}endSession(sessionId, options?)
Closes a session. By default, session-scoped memories are promoted
to long-term ('user') storage before the session is dropped. Pass
{ persist: false } to drop them outright.
const { data } = await stackbone.memory.endSession('sess_abc');
console.log(data.persisted, 'session facts promoted');Configuration
These env vars are injected by the runtime when your agent runs under
stackbone dev or in the workspace runtime — you do not wire a client
by hand.
| Config key | Falls back to env | Required when… |
|---|---|---|
mem0ApiKey |
MEM0_API_KEY |
Any stackbone.memory.* call. |
mem0BaseUrl |
MEM0_BASE_URL |
Optional. Point at a self-hosted mem0 deployment. Defaults to the mem0 cloud when unset. |
Errors
| Code | Meaning |
|---|---|
not_implemented |
Returned by every call until the mem0 wiring ships. |
mem0_unconfigured |
mem0ApiKey / MEM0_API_KEY is missing. |
memory_not_found |
The memoryId does not exist or has been deleted. |
Where to go next
stackbone.ai— the LLM client memories typically feed into via the conversation summarisation flow.requestApproval()— erasing a user's memory on request ("right to be forgotten") is a good fit for a workflow-level human approval gate rather than a fire-and-forgetdeleteAll. Seestackbone.approvalfor the underlying surface.stackbone.database— the Postgres the rest of the agent uses; mem0 lives outside it.- Concepts → Agents and sessions: how a deep agent's built-in session memory complements long-term memory.