A memory store that flags its own conflicts before your agent does.
Project description
atlaso
A memory store that flags its own conflicts before your agent does.
from atlaso import Memory
m = Memory()
m.add("Alice prefers dark mode in the UI", user_id="alice")
for hit in m.recall("dark mode", user_id="alice"):
print(hit.content, "confident:", hit.is_confident)
That is_confident flag — and its siblings has_disagreement, agreement_score, conflict_peers — are why this library exists. Every recall() result tells you whether to trust it.
Atlaso v0.1's retrieval is lexical (BM25 over your text), not semantic — so recall("dark mode") matches "dark mode in the UI" but not "theme preferences". v0.2 adds optional embedding-based recall.
What Atlaso is
Atlaso is a memory store for AI agents built around Field 3.0 — an append-only, dispersion-aware knowledge model where every saved fact carries:
- Polarity —
positive/negative/cautionary/open— the stance of the claim. - Evidence grade —
anecdotal/observed/replicated/verified— gated by the breadth of the claim. - Scope — six experimental facets (note, model, dataset, env, version, n, seed) telling you under what conditions the claim holds.
- Contradictions — first-class edges, not metadata. Revising a fact deposits a new finding with
contradicts=[old_id].
When an agent calls m.recall(...), the result set is grouped by scope, and every hit is annotated with whether it agrees with its neighbors, whether its scope-bag has internal disagreement, and whether the SDK considers it safe to act on. Your agent gets data back; it also gets a verdict on whether the data is settled.
That's the whole pitch.
Full docs: rendered at https://atlaso.ai/docs · plain Markdown in
./docs/for offline / on-github reading.
Install
pip install atlaso # core library
pip install atlaso[mcp] # + MCP server (Claude Code, Cursor, Codex, Windsurf)
Python 3.10+. No phone-home, no analytics, no signup. The library runs entirely in your process against on-disk SQLite.
Quickstart — single user
from atlaso import Memory
m = Memory()
m.add("I prefer oat milk in lattes", user_id="me")
hits = m.recall("oat milk", user_id="me")
print(hits[0].content)
SaaS — multi-tenant
from atlaso import AsyncMemory
from fastapi import FastAPI, Depends
memory = AsyncMemory()
app = FastAPI()
@app.post("/remember")
async def remember(text: str, user = Depends(current_user)):
handle = memory.for_user(user.id) # bind to authenticated identity
return await handle.add(text)
The for_user(user.id) pattern is the recommended path. The lower-level memory.add(text, user_id="alice") exists for admin tooling but is the wrong shape for request handlers — see Authorization.
Recall with conflict awareness
results = m.recall("what does Alice eat?", user_id="alice")
print(results.explain())
# → "5 matching memories disagree. Read both groups before using as fact."
for r in results:
if r.has_disagreement:
print(f"⚠ {r.content} conflicts with {r.conflict_peers}")
elif r.is_confident:
print(f"✓ {r.content}")
else:
print(f"? unconfirmed: {r.content}")
results.explain() is action language, not internals. Empty / confident / disagreement / thin-evidence each get their own one-sentence verdict.
Memory health
print(m.health(user_id="alice").explain())
# → "Memory is healthy (FMI 82/100). Searches are returning confident answers."
The Field Maturity Index is a 0–100 geometric mean of Coverage × Precision × Resolution × Density — a single readable number for "how settled is what I know about this user?"
Retract, don't delete
m.retract(deposit_id, user_id="alice", reason="this fact was wrong")
Soft tombstone by default — the row stays citable in contradicts=. hard_delete=True is the GDPR/PII escape. reason= is required because Atlaso keeps a retraction trail.
What we deliberately don't ship
- No
update(). Atlaso deposits are immutable evidence. To revise an earlier finding, deposit a new one withcontradicts=[old_id]. The audit trail is the point. - No telemetry. Atlaso never phones home.
- No required LLM.
add()andrecall()work with pure SQL + lexical retrieval. Bring your own embedder/extractor only if you want them. - No cross-tenant footguns on autocomplete. Cross-tenant operations live in
from atlaso.admin import ...behind aconfirm="I_UNDERSTAND_THIS_CROSSES_TENANTS"literal. They never appear onm.<TAB>.
Framework integrations
atlaso[mcp] covers Claude Code, Cursor, Codex, Windsurf, Cline via MCP — zero per-framework code.
For Python agents, see the recipes in docs/recipes/:
pip install atlaso[langchain] and the four other framework extras are reserved namespaces — they install only atlaso core today and emit a one-line FrameworkExtraReservedWarning when the SDK detects the framework is installed alongside it. Real adapters land in v0.1.x.
Inspect what you have
m.peek("alice")
# PeekView(user_id='alice', showing 4 of 4, FMI 0/100):
# · [open ] Alice prefers dark mode in the UI
# · [open ] Alice's preferred coffee is oat-milk lattes
# · [open ] Alice's birthday is March 15
# · [open ] Alice usually wakes up around 7am
(The default polarity is open — undecided / observed-but-not-stance-claimed. Stronger polarities like positive or negative require corresponding evidence. See the Glossary below.)
m.peek(user_id) is the "show me what's stored without writing a query" primitive. It returns a PeekView that iterates like a list but renders as a compact table in your REPL or notebook.
Debug a recall
hits = m.recall("dark mode", user_id="alice")
print(hits[0].explain())
# Returned because the text matched (BM25 score 1.842).
# Polarity: open. Evidence: anecdotal.
# This bag has only one deposit on the context (no scope facets set).
# Treat as a lead, not a settled finding.
hit.explain() answers "why did I get this result and should I act on it?" in plain language — no Field 3.0 jargon leaks. Useful for production-debugging unexpected retrievals.
Use it from bash — atlaso CLI
Once pip install atlaso lands, the atlaso command is on PATH and every Memory verb has a CLI mirror. Same vocabulary as the Python API, same vocabulary as the MCP tools — one mental model:
atlaso add "Alice prefers oat milk" --user alice
atlaso recall "coffee" --user alice
atlaso peek alice
atlaso health alice
atlaso list-recent --user alice --limit 5
atlaso get <deposit_id> --user alice
atlaso contradict "Alice moved to Brooklyn" <old_id> --user alice --reason "user moved"
atlaso retract <deposit_id> --user alice --reason "wrong fact" # soft tombstone
atlaso retract <deposit_id> --user alice --reason "GDPR" --hard # purges FTS index too
Add --json to add / recall / get / list-recent / peek / health / contradict / retract to get machine-parseable output for piping into jq or shell scripts:
atlaso list-recent --user alice --limit 100 --json | jq '.[] | select(.polarity == "negative")'
atlaso recall "milk preferences" --user alice --json | jq '.is_confident'
atlaso --help lists every subcommand. Each subcommand has -h for its own usage. Errors print as atlaso <cmd>: <ErrorType>: <message> (no stack traces) so they're shell-friendly.
Health-check the install
$ atlaso doctor
atlaso doctor
──────────────────────────────────────────────────
✓ atlaso 0.1.0a3 importable
✓ Field 3.0 engine vendored
✓ storage path: /Users/me/work/.atlaso (auto-resolved)
✓ engine round-trip (add → recall → retract)
✓ atlaso[mcp] installed (run: python -m atlaso mcp)
──────────────────────────────────────────────────
OK — atlaso is healthy.
End-to-end install + path + engine sanity check in five seconds. Returns 0 on healthy, 1 if anything's broken.
Glossary
If the words below feel unfamiliar, read this once. Five sentences each.
- Deposit — a single saved fact. Immutable; revise by depositing a new one with
contradicts=[old_id]. - Polarity — the stance of the deposit:
positive(supported),negative(refuted),cautionary(works under conditions),open(undecided / question / hypothesis — this is the default). - Evidence grade — how strong the support is:
anecdotal(one source, no measurement),observed(one careful measurement),replicated(multiple independent measurements agree),verified(independently checked against ground truth). - Scope — the experimental facets describing under what conditions the claim holds:
note,model,dataset,env,version,n,seed. All optional. - Bag — deposits that share the same scope facets are in one "scope-bag." The dispersion signals (
is_confident,has_disagreement,agreement_score) are computed per-bag. - Contradicts — a list of deposit ids this finding supersedes. The new deposit + the contradiction edges are committed atomically.
- FMI — Field Maturity Index, a 0–100 health score. Geometric mean of Coverage × Precision × Resolution × Density. Returned by
m.health(); the four components are interpretable separately.
License
Apache 2.0.
Status
v0.1.0a3 — research preview. The SDK surface is fresh; please file issues.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file atlaso-0.1.0-py3-none-any.whl.
File metadata
- Download URL: atlaso-0.1.0-py3-none-any.whl
- Upload date:
- Size: 80.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b232c855a15dc60012e7452e9d9059a9a9beb7c052815be38415cf589dabd769
|
|
| MD5 |
a35d052530f797cb49d934976ee1cc95
|
|
| BLAKE2b-256 |
b1a350e3f8b2bc7336441ad1e091e031fd077bfa1c65771e5861353bfd84ea5e
|