Skip to content

SDKs

JavaScript and TypeScript SDK

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.

Note

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.

npm install @surrealdb/memory
# or: pnpm / yarn / bun add @surrealdb/memory

Node.js 18+ or a modern bundler for browser use.

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}/….

OptionDefaultDescription
contextrequiredContext id.
endpointrequiredSurrealDB Agent Memory host URL.
apiKeyrequiredBearer token.
timeoutMs30000Milliseconds per request.
maxRetries3Retries for GETs and idempotent writes.

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.

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.

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);
}

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

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 */ }
}
ExceptionHTTPWhen it occurs
AgentMemoryErrorn/aBase class
AuthError401Invalid or missing API key
ScopeError403Scope or principal denial
NotFoundError404Resource not found
ValidationError400 / 422Malformed request
RateLimitError429Rate or token budget exceeded (retryAfter when provided)
ServerError5xxServer error, retried for idempotent calls
ConnectionErrorn/aNetwork 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.

npm install @surrealdb/agent-memory-vercel-ai

→ Vercel AI SDK

JavaScript SDK reference · REST API

Was this page helpful?