Remember & recall.
PAMbase gives the user one persistent AI agent — a light identity plus a memory that follows them across every app. Memory is natural language: your app writes plain text; an LLM is what later reads it and decides what to do. This page is the whole read/write loop.
memory:write:<scope> to write and memory:read:<scope> to read.Write: remember()
Any app can remember something — no LLM required, because it's just text. Pass a string, or an object with a kind and a scope so other apps' agents can find it later.
// Shorthand: just text (defaults to kind "event", scope "general").await pambase.remember("Prefers window seats; dislikes spicy food.");// Better: categorize it so it's recallable across apps.await pambase.remember({content: "Finished a 5km run in 28:10.",kind: "event", // advisory hint; common kinds autocomplete, any string is finescope: "fitness.running", // top-level must be a standard namespace; sub-scopes are freeimportance: 50, // 0–100, optional});// Batch several at once (kind is free-form — use your own when none fit):await pambase.remember([{ content: "Saving for a house down payment.", scope: "finance" },{ content: "Sister Maya lives in Toronto; they talk weekly.", kind: "relationship", scope: "family" },{ content: "Draft the Q3 roadmap before the offsite.", kind: "task", scope: "note.work" },]);// → { accepted: true, memoryIds: ["mem_…", "mem_…"] }
Where memories go: kind × scope
A memory is a kind (an advisory structural hint) plus a scope (its domain). The two are not symmetric: kind is free-form — the common values just autocomplete and help the reading LLM — while scope is controlled. The scope's top-level namespace must come from the standard taxonomy (so a fitness app and a health app write to the same places and a wellness agent can recall across them); sub-scopes like fitness.running are free. An unknown top-level scope is rejected — use general if nothing fits.
| Field | What it is |
|---|---|
kind | An advisory hint — commonly fact, preference, event, relationship, emotion, goal, world, or summary, but free-form (e.g. task). Defaults to event. |
scope | A domain from the taxonomy (e.g. health, finance, travel, learning) + an optional sub-scope. |
content | The natural-language text itself — what an LLM reads. |
Read: recall()
To use memory, bring an LLM. recall() returns the memories most relevant to a query (hybrid semantic + keyword + recency + importance) as natural language — your agent interprets them and decides the next move.
const { memories } = await pambase.recall({ query: "what should they read next?", limit: 5 });// memories[]: { id, type, scope, content, importance, occurredAt, sourceApp }const system = "You are a reading companion. What's known about the user:\n" +memories.map((m) => "- " + m.content).join("\n");const reply = await yourLLM.chat({ system, messages: [{ role: "user", content: "Recommend a book." }] });
No model of your own? Host the agent — PAMbase's chat is already grounded in this memory and records new memories from the conversation automatically. For a one-line portrait of the user, use the brief.
Permission filtering on writes
A memory whose scope isn't covered by one of your memory:write:* grants is silently dropped before it persists. The response's memoryIds reflects only what actually landed — it's the ground truth for what your write stored.
Next
- Signals & reacting — notify other apps and react to theirs.
- Host the agent — memory-grounded chat with no model of your own.
- Catalog — the full scope taxonomy (where your memory goes).