stackbone.memory

Status: planned. This surface is already on the ambient stackbone client, but every method currently returns not_implemented. The shape on this page is the contract you can type against today. The backend will be mem0 (MEM0_API_KEY, optional MEM0_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-forget deleteAll. See stackbone.approval for 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.

The platform for agent developers.Build, ship and observe agentsthat survive prod.

© 2026 · STACKBONEBUILT WITH ❤️ FROM CANADA AND SPAIN