Skip to content

Typed memory blocks

Beyond the auto-extracted world / experience / observation facts, you can store five first-class typed blocks directly. Each is a fact_type and is retrievable with the matching types filter on recall.

BlockHoldsWritten by
procedureHow a task was done — distilled steps + rationalethe agent, at save time
reasoningWhy a decision was made on a taskthe agent, per task
preferenceA conditional rule ("for day-planning, use personal Gmail")corrections + explicit statements
correctionA raw "no, do it this way" signal (highest-signal)user or agent
profileThe apps/tools/access a user hasverified on use

Storing a typed block

Typed blocks are stored verbatim (no LLM rewrite), so put the bank in chunks mode first — the SDK helpers do this for you.

python
cm.retain_procedure("jane@acme.com",
    ["make build", "kubectl apply -f prod.yaml", "curl /health"],
    rationale="standard prod deploy")
cm.retain_reasoning("jane@acme.com", "Chose gRPC over REST: p99 latency mattered more.")
cm.retain_preference("jane@acme.com", "For day-planning, use personal Gmail, never work mail.")
cm.retain_correction("jane@acme.com", "No — drain the pod before restart.")
cm.update_profile("jane@acme.com", "Has admin on AWS, GitHub, and Grafana.")

# or set the type directly on retain:
cm.retain(bank_id="jane@acme.com", content="Acme HQ is in Berlin.", fact_type="world")
typescript
await cm.retainProcedure("jane@acme.com",
    ["make build", "kubectl apply -f prod.yaml", "curl /health"],
    { rationale: "standard prod deploy" });
await cm.retainReasoning("jane@acme.com", "Chose gRPC over REST: p99 latency mattered more.");
await cm.retainPreference("jane@acme.com", "For day-planning, use personal Gmail, never work mail.");
await cm.retainCorrection("jane@acme.com", "No — drain the pod before restart.");
await cm.updateProfile("jane@acme.com", "Has admin on AWS, GitHub, and Grafana.");

await cm.retain("jane@acme.com", "Acme HQ is in Berlin.", { factType: "world" });

Recalling by type

python
# Only procedures
cm.recall("jane@acme.com", "how do I deploy?", types=["procedure"])
# Preferences + corrections
cm.recall("jane@acme.com", "how should I handle this?", types=["preference", "correction"])
# Everything (default)
cm.recall("jane@acme.com", "deploy")

The correction loop

Corrections are the highest-signal input — store them raw as they happen. A consolidation pass distills repeated or explicit corrections into preference blocks (and, when a correction targets a procedure step, into a repair on that procedure). Conflict rule: explicit correction > repeated pattern > one-off inference, recency-tiebroken.