Published package: @surrealdb/spectron, 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.
Spectron was the project name for SurrealDB Agent Memory. These type names
will be renamed in a future release.
npm: The client is published under the
@surrealdbscope (@surrealdb/spectron), so no third party can squat the namespace. The bare namespectronon npm is unrelated.
Installation
npm install @surrealdb/spectron
# or: pnpm / yarn / bun add @surrealdb/spectronNode.js 18+ or a modern bundler for browser use.
Client construction
import { Spectron } from "@surrealdb/spectron";
const client = new Spectron({
endpoint: process.env.SPECTRON_ENDPOINT!,
context: "acme-prod",
apiKey: process.env.SPECTRON_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. |
timeout | 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.
Remember and recall
await client.remember("Alice was promoted to CTO.", {
infer: "full",
scope: ["org/acme/user/alice"],
});
await client.rememberMany([
{ role: "user", content: "I was promoted to CTO." },
{ role: "assistant", content: "Congratulations!" },
], { scope: ["org/acme/user/alice"] });
const hits = await client.recall("What is Alice's role?", { k: 10 });
const block = await client.context("What is Alice's role?", { k: 10 });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",
scope: ["org/acme/team/eng"],
labels: ["team=eng"],
});
await client.chat("Summarise what you know about Alice", {
scope: ["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,
SpectronError,
ValidationError,
} from "@surrealdb/spectron";
try {
const hits = await client.recall("what is my name?", { scope: ["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 SpectronError) { /* other */ }
}| Exception | HTTP | When it occurs |
|---|---|---|
SpectronError | 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 Spectron({ ..., maxRetries: 0, timeout: 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. All errors follow RFC 7807 Problem Details.
Vercel AI SDK adapter
npm install @surrealdb/spectron-vercel-ai