The published package is @surrealdb/memory, a typed REST client for the SurrealDB Agent Memory end-user API. It uses platform fetch, ships no runtime dependencies, and aligns with SurrealDB Agent Memory’s OpenAPI specification.
npm: The client is published under the @surrealdb scope (@surrealdb/memory), so no third party can squat the namespace. It was previously published as @surrealdb/spectron; that package is deprecated.
Installation
npm install @surrealdb/memory
# or: pnpm / yarn / bun add @surrealdb/memoryNode.js 18+ or a modern bundler for browser use.
Client construction
import { AgentMemory } from "@surrealdb/memory";
const client = new AgentMemory({
endpoint: process.env.AGENT_MEMORY_ENDPOINT!,
context: "acme-prod",
apiKey: process.env.AGENT_MEMORY_API_KEY!,
});The client is async-only (all methods return Promises). It is pinned to one context and calls /api/v1/{context}/….
| Option | Default | Description |
|---|---|---|
context | required | Context id. |
endpoint | required | SurrealDB Agent Memory host URL. |
apiKey | required | Bearer token. |
timeoutMs | 30000 | Milliseconds per request. |
maxRetries | 3 | Retries for GETs and idempotent writes. |
Scope
On the wire, scope is a ScopeSet: an ordered array of slash-path strings (for example ["org/acme/user/alice"]). Register paths before first use; see Contexts and scope.
The TypeScript client accepts a path string or an array of paths, and both serialise to the wire ScopeSet. Writes, uploads and chat take the scopes option. recall and context take lens, which narrows the read to those paths.
Remember and recall
await client.remember("Alice was promoted to CTO.", {
infer: "full",
scopes: ["org/acme/user/alice"],
});
await client.rememberMany([
{ role: "user", content: "I was promoted to CTO." },
{ role: "assistant", content: "Congratulations!" },
], { scopes: ["org/acme/user/alice"] });
const hits = await client.recall("What is Alice's role?", { k: 10 });
const { context } = await client.context("What is Alice's role?", { k: 10 });context returns an object whose context field holds the rendered block. remember and rememberMany attach an Idempotency-Key header for safe retries within a 30-second window.
Documents and chat
const doc = await client.documents.upload({
file: documentFile,
title: "Returns policy",
scopes: ["org/acme/team/eng"],
labels: ["team=eng"],
});
await client.chat("Summarise what you know about Alice", {
scopes: ["user/alice"],
});
const stream = await client.chat("Tell me a story", { stream: true });
for await (const chunk of stream) {
process.stdout.write(chunk.delta);
}Other verbs and namespaces
Top-level: forget, consolidate, reflect, elaborate, state, profile, inspect, audit, fsck, health.
Namespaces: client.documents (including keywords), client.sessions, client.entities, client.scopes, client.principals, client.traces, client.lifecycle.
→ Full tables: JavaScript SDK reference
Errors and retries
The client throws typed errors so you can branch on failure precisely.
import {
AuthError,
ConnectionError,
NotFoundError,
RateLimitError,
ScopeError,
ServerError,
AgentMemoryError,
ValidationError,
} from "@surrealdb/memory";
try {
const hits = await client.recall("what is my name?", { lens: ["user/alice"] });
} catch (err) {
if (err instanceof AuthError) { /* 401 */ }
else if (err instanceof ScopeError) { /* 403 */ }
else if (err instanceof NotFoundError) { /* 404 */ }
else if (err instanceof ValidationError) { /* 400 / 422 */ }
else if (err instanceof RateLimitError) { console.log(err.retryAfter); }
else if (err instanceof ServerError) { /* 5xx after retries */ }
else if (err instanceof ConnectionError) { /* network / timeout */ }
else if (err instanceof AgentMemoryError) { /* other */ }
}| Exception | HTTP | When it occurs |
|---|---|---|
AgentMemoryError | n/a | Base class |
AuthError | 401 | Invalid or missing API key |
ScopeError | 403 | Scope or principal denial |
NotFoundError | 404 | Resource not found |
ValidationError | 400 / 422 | Malformed request |
RateLimitError | 429 | Rate or token budget exceeded (retryAfter when provided) |
ServerError | 5xx | Server error, retried for idempotent calls |
ConnectionError | n/a | Network failure or timeout |
GET requests and idempotent writes (remember, rememberMany) retry automatically on connection errors and 5xx responses: up to maxRetries attempts (default 3) with 250 ms, 500 ms, 1000 ms backoff. Other writes and 4xx responses are not retried. Tune or disable on the constructor:
const client = new AgentMemory({ ..., maxRetries: 0, timeoutMs: 10000 });The default timeout is 30,000 ms; streaming chat disables the read timeout while tokens arrive. On a 429, read RateLimitError.retryAfter and back off before retrying manually. Error bodies are a JSON object with a message field; see Errors.
Vercel AI SDK adapter
npm install @surrealdb/agent-memory-vercel-ai