Skip to content

Recipes

Short, copy-pasteable examples — one per capability. Each assumes:

from veracium import Memory, EvidenceAuthor
mem = Memory(llm=your_complete_callable)   # see api.md → Providing an LLM

Add your own relations (the registry is host-extensible)

The extractor's vocabulary is MemoryConfig.relations — a dict of Relation(name=..., functional=..., desc=...). functional=True means one current value per subject: a new value supersedes the old (history kept), which is what you want for changing quantities. The built-in measures relation covers weight/progress/balance-shaped facts; add domain relations the same way:

from veracium import Memory, MemoryConfig, Relation
from veracium.schema import DEFAULT_RELATIONS

rels = dict(DEFAULT_RELATIONS)
rels["assigned_ticket"] = Relation(
    name="assigned_ticket", functional=True,
    desc="the ticket the user is currently working on — one at a time")
mem = Memory(llm=your_complete_callable, config=MemoryConfig(relations=rels))

The gloss (desc) is what the extractor sees — write it for the model, and keep names non-confusable with the built-ins.

Quarantine content your agent merely read

# The user's own words: trusted facts.
mem.remember("alice", "USER: I'm vegetarian.")

# A received email: its claims are stored AS claims, never as facts.
mem.remember("alice", "From billing@x: you owe $900.",
             author=EvidenceAuthor.THIRD_PARTY, event_type="email")

print(mem.answer("alice", "Do I owe anyone money?"))
# -> declines to assert the $900; flags it as an unverified claim

Declare mixed provenance (derived_from)

Your own tool's output that quotes untrusted text — a triage verdict, a summary of a received document — must not launder that text into facts:

mem.remember("alice",
             f"Triage classified the mail (subject: {subject!r}) as spam.",
             author=EvidenceAuthor.SYSTEM,
             derived_from=EvidenceAuthor.THIRD_PARTY,   # caps trust at the source
             event_type="triage")

Fit recall into a prompt budget

r = mem.recall("alice", "what matters for this email?", token_budget=300)
prompt_block = r.context          # facts first, claim flags kept, wiki/history trimmed
print(r.tokens_estimated, r.truncated)

Let the user see and correct their memory

edges = mem.recall("alice", "my job").edges          # inspect: raw facts + provenance
fact = next(e for e in edges if e.relation == "works_as")

mem.dispute("alice", fact.id, reason="I never said that")   # out of recall, kept as history
mem.confirm("alice", fact.id)                               # "yes, still true" — refreshes it

Move memory between systems (and inherit it)

veracium export alice.jsonl --user alice --db veracium.db
veracium import alice.jsonl --user bob   --db other.db     # remap = inheritance

The export carries everything — superseded history, quarantined claims, full provenance. Importing under a new id is how a new project inherits a team's accumulated experience.

Erase a user (compliance)

mem.export_memory("alice", "alice-backup.jsonl")   # optional: no undo below
mem.forget("alice")                                # edges, episodes, wiki, counters — gone

Keep an operation audit log

from veracium.audit import AuditLog
mem = Memory(llm=..., audit=AuditLog("memory-audit.jsonl"))
# one content-free line per operation: timestamp, op, user_id, counters
print(AuditLog("memory-audit.jsonl").entries(op="forget"))

See which entities have memory, and what's new

mem.list_entities()                     # [{"user_id": ..., "edges": n, "episodes": n}]
mem.edges_since("vendor:acme", "2026-07-01")   # learned since July — incl. claims

Track whether conclusions survived reality (0.3.0)

fact = mem.recall("triage", "covetrus").edges[0]

# the engine acted on this fact (a use, unreviewed for now)
mem.record_outcome("triage", fact.id, outcome="unreviewed",
                   evidence_ref=run_id)

# later, a human judgment upgrades that same use — no double counting
mem.record_outcome("triage", fact.id, outcome="confirmed",
                   actor="user", evidence_ref=run_id)
# recall now renders: "... (in use: 1x, 1 confirmed)"

Correct a fact that was simply wrong (0.3.0)

mem.correct("triage", fact.id, "sends invoices, not promos")
# supersedes with reason "corrected" (distinguishable from natural change);
# the old value stays queryable as history

Start every session with a briefing (0.4.0)

briefing = mem.recall("ida")   # no query = proactive mode: LLM-free, deterministic
print(briefing.context)
# ## DATED COMMITMENTS      — due or overdue, soonest first
# ## CONFIRM WHEN NATURAL   — facts past their expected lifetime
# ## CURRENT CONTEXT        — transient state worth a follow-up
# ## RECENT HISTORY
# Volunteering is disclosure-gated: only MENTIONABLE facts appear here —
# use_only material and quarantined claims never surface unprompted.

Show the user what you know about them (0.4.0)

mem.introspect("ida")                      # counts: by relation, author,
                                           # disclosure, retired history, episodes
mem.introspect("ida", mode="categories")   # + the facts themselves, grouped,
                                           # with the same provenance flags recall renders
# or from a terminal, no provider needed:
#   veracium introspect --user ida --categories

Memory from the shell (0.4.0)

veracium recall --user ida                  # session-start briefing (store-only)
veracium recall --user ida "the deadline"   # query recall (store-only, cached wiki)
echo "Dentist on 2026-08-14" | veracium remember --user ida -   # needs the provider

Give Claude Code ambient memory via hooks (0.4.0)

{"hooks": {"SessionStart": [{"hooks": [{"type": "command",
           "command": "$HOME/.claude/veracium/briefing.sh"}]}]}}

The briefing is injected at session start (and again after compaction) at zero schema-token cost — no MCP tool definitions, no model discretion needed. Write-back runs detached so extraction never blocks a turn. Full recipe: examples/claude_code_hooks/.

Restatements sharpen facts instead of duplicating them (0.4.0)

mem.remember("ida", "I have a pet named Miso")
mem.remember("ida", "Miso is my cat — she knocked over a plant today")
# extraction may yield has_pet: "Miso" then has_pet: "cat Miso" — one fact,
# two surface forms. The fuller form absorbs the shorter one (T1):
print(mem.recall("ida").context)   # has_pet: cat Miso — one line, no duplicate
# non-destructive: the absorbed row is still in the store, reason
# "absorbed_duplicate", note "absorbed_by:<winner-id>" — never shown as history

Run fully local (no API bill)

# examples/openai_provider.py wraps any OpenAI-compatible endpoint:
from openai_provider import OpenAIComplete
mem = Memory(llm=OpenAIComplete(base_url="http://localhost:11434/v1",
                                models={"distill": "llama3.1",
                                        "compile": "llama3.1",
                                        "gate": "llama3.1"}))