LiticaLitica
Docs/Writing Memories

Python SDK

Writing Memories

Three ways in: one memory, a batch, or a whole document. All three share the same rule — the server accepts writes instantly and makes them searchable shortly after.

Add one memory

add_memory queues a single memory in the scope of the call (client defaults, unless overridden — see Configuration):

ack = client.add_memory(
    "Sam owns the Atlas pricing page.",
    session_id="conv-42",   # optional: correlates calls on the audit trail
)
ack.queued   # True — accepted, not yet searchable

session_id is recorded on the write-side audit trail so you can group related calls later. It never affects retrieval.

Add a batch

add_memories_batch queues several memories in one HTTP call. The namespace write check runs once for the whole batch, and enqueue order is persist order:

ack = client.add_memories_batch([
    "The Atlas launch slipped to March.",
    "Priya approved the new pricing tiers.",
    "Support volume doubles on Mondays.",
])
ack.queued   # 3 — how many the server accepted

An empty list raises LiticaValidationError before any request is made. The server caps batch size; a batch over the cap comes back as a 422.

Ingest a document

add_document uploads a PDF, DOCX, PPTX, or text file. The server extracts the text at the edge, then decomposes it into many individual memories in the background:

ack = client.add_document("q3-report.pdf")
ack.filename   # "q3-report.pdf"
ack.chars      # how much text the server extracted
  • A file type the server cannot parse raises LiticaUnsupportedMediaError (415).
  • A file with no extractable text raises LiticaValidationError (422).
  • A path that does not exist raises a plain FileNotFoundError before anything is sent.
  • The upload uses its own HTTP timeout (default 120 seconds, set with timeout=) because large files take a while to transfer and parse.

One document fans out into many memories, so expect a longer gap than a single write before everything is retrievable.

Writes are queued, not instant

All three write methods return as soon as the server has accepted the write (HTTP 202). Decomposition, embedding, and persistence happen in the background — that queue is part of Litica's human-inspired memory design, not an implementation accident. A naive write-then-read will surprise you:

client.add_memory("Sam owns pricing.")
client.search_memories("pricing")   # probably [] — the write hasn't landed yet

There is no wait= flag in v0.1.0: the server exposes no signal that reliably says “this specific write has landed.” So poll for the thing you actually care about:

A reusable read-your-writes helper
import time

def wait_for(client, query, needle, timeout=90):
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        hits = client.search_memories(query, top_k=10)
        if any(needle in h.text for h in hits):
            return hits
        time.sleep(3)
    raise TimeoutError(f"{needle!r} never became searchable")

client.add_memory("Sam owns the Atlas pricing page.")
hits = wait_for(client, "who owns pricing?", "Sam")

If you just need to know whether the pipeline has drained — rather than whether one specific write landed — viz_pending() reports the queue depth for an agent. See Inspection.

Deleting

client.delete_memory(1042)       # one memory, by id
client.clear_memories()          # every memory for the client's agent
client.clear_memories(agent_id="old-bot")   # or another agent's

clear_memories has no undo

It deletes every memory for the agent and returns the count removed. There is no confirmation step and no recovery path.

A note on provenance

The MCP tools can record where a fact came from (source, confidence, verification). The HTTP route the SDK wraps does not accept provenance yet, so memories written through the SDK carry no source attribution. This is a documented gap, tracked as a follow-up.

Next steps