Metadata-Version: 2.4
Name: atlaso
Version: 0.1.0a5
Summary: A memory store that flags its own conflicts before your agent does.
Project-URL: Homepage, https://atlaso.ai
Project-URL: Documentation, https://docs.atlaso.dev/sdk
Project-URL: Repository, https://github.com/imashishkh21/atlaso
Project-URL: Issues, https://github.com/imashishkh21/atlaso/issues
Author-email: Atlaso <support@atlaso.ai>
License: Apache-2.0
License-File: LICENSE
Keywords: agents,ai,atlaso,field-3.0,memory
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<0.29,>=0.27
Provides-Extra: crewai
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: dspy
Provides-Extra: langchain
Provides-Extra: llamaindex
Provides-Extra: mcp
Requires-Dist: fastmcp<0.4,>=0.2; extra == 'mcp'
Provides-Extra: openai-agents
Description-Content-Type: text/markdown

# atlaso

<!--
  mcp-name: io.github.imashishkh21/atlaso
  Verified by the official Model Context Protocol Registry
  (https://registry.modelcontextprotocol.io) against the published
  PyPI metadata. Don't remove without updating server.json.
-->

**A memory store that flags its own conflicts before your agent does.**

```python
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/`](./docs/README.md) for offline / on-github reading.

---

## Install

```bash
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

```python
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

```python
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](https://docs.atlaso.dev/sdk/authorization).

## Recall with conflict awareness

```python
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

```python
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

```python
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 with `contradicts=[old_id]`. The audit trail is the point.
- **No telemetry.** Atlaso never phones home.
- **No required LLM.** `add()` and `recall()` 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 a `confirm="I_UNDERSTAND_THIS_CROSSES_TENANTS"` literal. They never appear on `m.<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/`:
- [LangChain](docs/recipes/langchain.md)
- [LlamaIndex](docs/recipes/llamaindex.md)
- [CrewAI](docs/recipes/crewai.md)
- [OpenAI Agents SDK](docs/recipes/openai-agents.md)
- [DSPy](docs/recipes/dspy.md)

`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

```python
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

```python
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:

```bash
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:

```bash
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

```bash
$ 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.
