Skip to content

SDKs

Python SDK

The SurrealDB Agent Memory client ships as its own distribution, surrealdb-memory, pulled in through the surrealdb[memory] extra. It is versioned independently of the database driver and imported as surrealdb.memory.

Note

Package naming: On PyPI, the client is surrealdb-memory, installed through the surrealdb[memory] extra rather than by name. The SDK lands in the 3.x line, which is still prerelease, so the install needs --pre - a bare pip install surrealdb resolves to the 2.x stable release, which has no memory extra.

pip install --pre 'surrealdb[memory]'

# Using uv
uv add --prerelease=allow 'surrealdb[memory]'

Python 3.10+ recommended.

Memory is synchronous (uses requests). AsyncMemory is async (uses aiohttp). Both expose the same method names; add await on the async client.

from surrealdb.memory import Memory, AsyncMemory

with Memory(
    context="acme-prod",
    endpoint="https://api.memory.example",
    api_key="sk-spec-...",
) as memory:
    memory.remember("Alice was promoted to CTO.")
    hits = memory.recall("What is Alice's role?", k=10)
    for hit in hits.hits:
        print(hit.score, hit.text)

async with AsyncMemory(
    context="acme-prod",
    endpoint="https://api.memory.example",
    api_key="sk-spec-...",
) as memory:
    await memory.remember("Alice was promoted to CTO.")
    hits = await memory.recall("What is Alice's role?", k=10)

Both clients are pinned to one context and call /api/v1/{context}/…. Pass context, endpoint, and api_key explicitly; the SDK does not read environment variables.

On the wire, scope is a ScopeSet: an ordered array of slash-path strings (for example ["org/acme/user/alice"]). Register paths with agent-memory scopes create before first use; see Contexts and scope.

The Python client accepts:

  • A single path: scope="org/acme/user/alice"

  • A list of paths: scope=["org/acme/user/alice"]

ArgumentDefaultDescription
contextrequiredContext id, e.g. "acme-prod".
endpointrequiredSurrealDB Agent Memory host URL, e.g. "https://api.memory.example".
api_keyrequiredBearer token (Authorization: Bearer …).
timeout30.0Per-request timeout in seconds.
max_retries3Retries for GETs and idempotent writes.
memory.remember("Alice was promoted to CTO.", infer="full", scopes=["org/acme/user/alice"])
memory.remember("Q3 board notes", labels=["topic=board"], memory_category="context")

memory.remember_many(
    [
        {"role": "user", "content": "I was promoted to CTO."},
        {"role": "assistant", "content": "Congratulations!"},
    ],
    extract="whole_conversation",
    scopes=["org/acme/user/alice"],
)

remember and remember_many send an Idempotency-Key header (derived from method, path, body, and a 30-second bucket) so safe retries collapse server-side.

result = memory.recall(
    "What is Alice's role?",
    k=10,
    mode="hybrid",
    lens=["org/acme/user/alice"],
)

block = memory.query_context(
    "What is Alice's role?",
    k=10,
    lens=["org/acme/user/alice"],
)

Optional filters include labels, lens, scope_view (strict | merged | crossTeam), temporal bounds (as_of, valid_from, …), and geo location.

upload = memory.documents.upload(
    "policy.pdf",
    content_type="application/pdf",
    title="Returns policy",
    scope=["org/acme/team/eng"],
    labels=["team=eng"],
)
doc = memory.documents.get(upload.id)
hits = memory.documents.query("refund window", k=5, mode="hybrid")
chunks = memory.documents.chunks(upload.id)
memory.documents.keywords.search("returns policy", k=10)
reply = memory.chat("Summarise what you know about Alice", scopes=["user/alice"])
print(reply.reply)

for chunk in memory.chat("Summarise what you know about Alice", stream=True):
    if chunk.delta:
        print(chunk.delta, end="", flush=True)
    if chunk.done:
        print("\n[trace]", chunk.trace_id)

Top-level methods: consolidate, reflect, elaborate, forget, state, whoami, profile, inspect, audit, health.

Grouped resources: memory.documents, memory.sessions, memory.entities, memory.scopes, memory.principals, memory.keys, memory.traces, memory.lifecycle.

→ Full method tables: Python SDK reference

The SDK raises typed exceptions so you can handle auth, scope, and not-found cases precisely.

from surrealdb.memory import MemoryAPIError, MemoryAuthError, MemoryNotFoundError, MemoryScopeError

try:
    hits = memory.recall("what is my name?", lens=["user/alice"])
except MemoryAuthError as exc:
    print(exc.status_code, exc.message)
except MemoryScopeError as exc:
    print(exc.status_code, exc.message)
except MemoryNotFoundError as exc:
    print(exc.status_code, exc.message)
except MemoryAPIError as exc:
    print(exc.status_code, exc.message, exc.trace_id, exc.body)
ExceptionHTTPWhen it occurs
MemoryServiceErrorn/aBase class
MemoryAPIErrorOther non-2xxGeneric API failure; carries status_code, message, trace_id, body
MemoryAuthError401Missing or invalid API key
MemoryScopeError403Scope floor or principal rejects the call
MemoryNotFoundError404Context, session, document, or other resource not found

Responses of 400, 422, 429, and 5xx that are not mapped to a subclass surface as MemoryAPIError. Inspect status_code and body (RFC 7807 problem details) for validation and rate-limit information. The async client raises the same exceptions.

GET requests and idempotent writes (remember, remember_many) retry automatically on connection errors and 5xx responses: up to max_retries 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:

memory = Memory(..., max_retries=0, timeout=10.0)

The default timeout is 30 seconds; streaming chat disables the read timeout while tokens arrive. On a 429, read the problem-detail body and back off before retrying manually. All errors follow RFC 7807 Problem Details.

Typed dataclasses include RememberResponse, RecallResponse, RecallHit, ChatResponse, Document, Chunk, StateResponse, and others. Import from surrealdb.memory when you need explicit types:

from surrealdb.memory import RecallResponse, RecallHit

For agent frameworks that should auto-record every turn, SurrealDB Agent Memory ships Python adapters that build on this SDK:

pip install agent-memory-crew-ai              # CrewAI
pip install agent-memory-openai-agents-sdk    # OpenAI Agents SDK
pip install agent-memory-strands-agents       # Strands Agents
pip install agent-memory-google-adk           # Google ADK

Agent frameworks

The spectron binary exposes the same operations without the SDK:

agent-memory remember "Alice was promoted to CTO."
agent-memory recall "What is Alice's role?" --json

CLI reference · REST API

Was this page helpful?