MemEX memory layer (Pydantic port) — Multi-session continuity for AI systems
Project description
memex-python
Structured, provenance-tracked memory for AI agents — a faithful Pydantic port of @ai2070/memex.
MemEX stores beliefs, evidence, conflicts, and updates — not just retrieved text. It separates three graphs (what is believed / wanted / done) and makes retrieval, contradiction, decay, and identity first-class. This is the Python implementation: every typed structure is a Pydantic v2 model, and behavior matches the TypeScript original (the full upstream test suite is ported — 575 tests).
- Pure & immutable — every mutation is
apply_command(state, cmd) -> (new_state, events). - Pydantic-native — models validate on construction; the discriminated-union commands are the schema.
- Wire-compatible — command tags, enum values, and JSON keys are byte-identical to the TS library, so a Python service and a TS service can share one event log.
Install
pip install memex-python # import name: `memex`
Only runtime dependency: pydantic>=2.6.
Quickstart (functional core)
from memex import create_graph_state, create_memory_item, apply_command, get_scored_items
state = create_graph_state()
obs = create_memory_item(
scope="user:laz/general",
kind="observation",
content={"key": "login_count", "value": 42},
author="agent:monitor",
source_kind="observed",
authority=0.9,
importance=0.7,
)
state, events = apply_command(state, {"type": "memory.create", "item": obs})
top = get_scored_items(state, {"authority": 1.0, "importance": 0.5})
Filters, options, and weights accept plain dicts or the typed models:
from memex import get_items, smart_retrieve
recent = get_items(state, {"kind": "observation", "range": {"authority": {"min": 0.5}}})
packed = smart_retrieve(
state,
budget=2000,
cost_fn=lambda item: len(str(item.content)),
weights={"authority": 0.6, "importance": 0.4},
contradictions="surface", # or "filter"
diversity={"author_penalty": 0.2},
)
Quickstart (MemexStore facade)
For a stateful, object-oriented surface that rebinds state for you:
from memex import MemexStore
store = MemexStore()
a = store.create(scope="user:laz", kind="observation", content={"v": 1},
author="agent:x", source_kind="observed", authority=0.9)
b = store.create(scope="user:laz", kind="assertion", content={"v": 2},
author="agent:y", source_kind="user_explicit", authority=0.4)
store.mark_contradiction(a.id, b.id, "system:detector")
store.resolve_contradiction(a.id, b.id, "system:resolver") # b's authority drops
intent = store.create_intent(label="find target", priority=0.9, owner="user:laz")
task = store.create_task(intent_id=intent.id, action="search", priority=0.8)
snapshot = store.dumps(pretty=True) # JSON; MemexStore.loads(...) restores
The three graphs
| Graph | Reducer | Core type | Holds |
|---|---|---|---|
| Memory | apply_command |
MemoryItem |
beliefs, evidence, contradictions, edges |
| Intent | apply_intent_command |
Intent |
active goals with a status machine |
| Task | apply_task_command |
Task |
units of work tied to intents |
Each item carries three orthogonal 0..1 scores — authority (trust), conviction (author confidence), importance (current salience) — plus kind, source_kind, parents (provenance), and typed edges (DERIVED_FROM, CONTRADICTS, SUPPORTS, ABOUT, SUPERSEDES, ALIAS).
Validating external input
from memex.schemas import validate_command
from memex import apply_command
cmd = validate_command(raw) # raises pydantic.ValidationError on a bad shape
state = apply_command(state, cmd).state
Intentional divergences from the TS library
- Always-on validation — constructing any model with an out-of-range score raises
pydantic.ValidationError(TS only validated inside the factories). UseModel.model_construct(...)to bypass for deliberately-invalid fixtures. - Error types — score-bound violations surface as
ValidationError;cost_fncontract violations and unknown sort/decay enums asValueError(the TSRangeError). - Frozen entities —
MemoryItem/Edge/Intent/Taskare immutable; "edits" produce new instances (model_copy(update=...)). from_field —fromis a Python keyword, soEdge.from_is the attribute; it serializes to"from"via its alias.
Everything else — command tags, JSON shape, scoring/decay math, contradiction determinism, replay tolerance, transplant re-id semantics — matches the TS library exactly.
Development
CI uses uv (see .github/workflows/):
uv sync --all-extras
uv run ruff check .
uv run mypy
uv run pytest # 582 tests
Or with plain pip:
pip install -e ".[dev]"
pytest
Releases publish to PyPI via release.yml (trusted publishing) on a published
GitHub release, or manually via workflow_dispatch.
License
Apache-2.0 (matching upstream).
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 Distribution
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 memex_python-0.13.0.tar.gz.
File metadata
- Download URL: memex_python-0.13.0.tar.gz
- Upload date:
- Size: 135.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72328fd2b5a014e93ae35af984f907f63454a003d0cb6ff1ec27d3465e1d50af
|
|
| MD5 |
7e343a61a3ab2b5947674a5184bf0ea2
|
|
| BLAKE2b-256 |
ab52c1213c98a0f9c4cef1fa2b80c1fce567bf4db6c5aeed2018e6109591bde8
|
Provenance
The following attestation bundles were made for memex_python-0.13.0.tar.gz:
Publisher:
release.yml on ai-2070/memex-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memex_python-0.13.0.tar.gz -
Subject digest:
72328fd2b5a014e93ae35af984f907f63454a003d0cb6ff1ec27d3465e1d50af - Sigstore transparency entry: 1905366390
- Sigstore integration time:
-
Permalink:
ai-2070/memex-python@410547be79a7b01f98166cf3c27a82d04719ce3f -
Branch / Tag:
refs/tags/v0.13.0 - Owner: https://github.com/ai-2070
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@410547be79a7b01f98166cf3c27a82d04719ce3f -
Trigger Event:
release
-
Statement type:
File details
Details for the file memex_python-0.13.0-py3-none-any.whl.
File metadata
- Download URL: memex_python-0.13.0-py3-none-any.whl
- Upload date:
- Size: 45.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b79c9c4e5b59b37a189ff2e441309366c3eac656687d0225543036beba7fae5c
|
|
| MD5 |
50a23e2d82ec020ea2f03a816ca5f0d5
|
|
| BLAKE2b-256 |
1cccc5c6b7f4f89bbdea5bf785944827c081d08ff84306e310146cc610b612e8
|
Provenance
The following attestation bundles were made for memex_python-0.13.0-py3-none-any.whl:
Publisher:
release.yml on ai-2070/memex-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memex_python-0.13.0-py3-none-any.whl -
Subject digest:
b79c9c4e5b59b37a189ff2e441309366c3eac656687d0225543036beba7fae5c - Sigstore transparency entry: 1905366491
- Sigstore integration time:
-
Permalink:
ai-2070/memex-python@410547be79a7b01f98166cf3c27a82d04719ce3f -
Branch / Tag:
refs/tags/v0.13.0 - Owner: https://github.com/ai-2070
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@410547be79a7b01f98166cf3c27a82d04719ce3f -
Trigger Event:
release
-
Statement type: