iglegais
memory that remembers why, not just what.
most memory tools keep your stuff as a flat pile of vectors. you ask something, they hand back the most similar chunk of text and call it a day. they cannot tell you why something happened, or how it changed over time.
iglegais stores each memory as a node with a vector and typed edges (caused_by, contradicts, follows). so recall does two things a flat store simply cannot:
- vector search to find the memory you actually mean
- walk the graph to hand you its cause, its contradictions, and how it evolved
it answers two questions similarity search cannot: why did something happen (walk the causal chain to the root), and what is still true (when a newer memory contradicts an older one, return the current belief, not the stale one).
the diet coke problem
you say "i like diet coke" in january and "i don't like diet coke" in may. what
should a memory return today? similarity search is helpless here: to an
embedding model, i like x and i don't like x are almost identical (they
score ~0.87 similar), because embeddings are blind to negation. so it cannot
tell which one is current.
iglegais keys the memory to a subject. a later memory on the same subject supersedes the earlier one, deterministically, no llm and no fuzzy matching:
mg.add("I like diet coke", subject="diet coke")
mg.add("I don't like diet coke anymore", subject="diet coke")
mg.what_is_true(subject="diet coke") # -> "I don't like diet coke anymore"
mg.what_is_true(subject="diet coke", as_of=jan_ts) # -> "I like diet coke" (true back then)
mg.belief_history("diet coke") # -> the full timeline, oldest to newest
it survives oscillation too (like -> dislike -> like again, latest wins) and
keeps every subject isolated. belief_history answers a question no flat memory
store can: how did my opinion on something change over time.
the demo
Q: why did the pipeline go down?
closest memory:
"ops got paged at 2am: the zorbex-9 pipeline went completely down."
caused by:
"the zorbex-9 module leaked memory and crashed the data pipeline."
later fixed by:
"patched the zorbex-9 memory leak and the pipeline recovered."
a flat store gives you the first line and shrugs. the graph is what finds the root cause.
real world test
two totally separate incidents (an auth outage and a caching bug) jumbled into one graph. the hard part is telling them apart and blaming the right thing:
Q: why were users getting logged out?
root cause: migrated the auth service to a new jwt library (correct)
Q: why was the dashboard showing old numbers?
root cause: enabled a new caching layer (correct)
both passed. it kept the incidents straight.
runs on your machine, costs nothing
everything lives in a single local file. local embeddings, no server to run, no cloud, no bill. your memories never leave the machine.
use it
pip install iglegais
that's it. no database to install, nothing to start. add it to your assistant:
claude mcp add iglegais -- iglegais
your assistant now has four tools: remember, recall, why, whats_true.
it stores plain text, walks a chain of causes when you ask why something
happened, and tracks what is still true when a newer memory retracts an older
one.
you: remember: the deploy failed because of a race in migrations
you: why did the deploy fail?
you: remember: the primary database is postgres
you: remember: we migrated the primary database to mysql
you: whats true about the primary database? -> mysql (postgres is retracted)
memories are kept in ~/.iglegais/memory.db (override with IGLEGAIS_DB).
library use
from iglegais import MemoryGraph
mg = MemoryGraph()
mg.setup()
mg.add("the deploy had a race condition") # or explicit edges
mg.recall("why did the service fail to boot?") # cause + contradictions
mg.root_cause("why did the service fail to boot?") # full chain to the root
it builds the graph itself
with a free CEREBRAS_API_KEY set, remember() reads plain text and infers the
edges and the subject in one call, so nobody wires anything by hand:
mg.remember("I really like diet coke")
mg.remember("actually I don't like diet coke anymore") # inferred: same subject, contradicts
mg.what_is_true(query="do I like diet coke?") # -> "...don't like diet coke anymore"
without a key it still stores everything; you just pass edges/subjects yourself.
many users, one instance
every call takes a namespace so one database serves many users or agents with
zero bleed between them:
mg.add("my favorite language is python", subject="language", namespace="alice")
mg.add("my favorite language is rust", subject="language", namespace="bob")
mg.what_is_true(subject="language", namespace="alice") # -> python
mg.what_is_true(subject="language", namespace="bob") # -> rust
automatic edge inference (optional)
remember(content) can infer caused_by / contradicts / follows edges from
plain text using a hosted model. set a free CEREBRAS_API_KEY in the
environment or ~/.iglegais/.env to turn it on. without a key, use add() with
explicit edges (shown above); everything else works the same.
bigger datasets (optional)
for very large memory sets you can point iglegais at a graph+vector server
instead of the local file: set IGLEGAIS_BACKEND=helix (and HELIX_URL if not
localhost:6969). the local file is the default and is plenty for personal use.
run the tests
python verify_local.py # local backend, no server: asserts the root cause is found
python stress_test.py # brutal suite: cycles, deep chains, discrimination under noise, scale
python temporal_test.py # current-truth recall and point-in-time as-of queries
python belief_test.py # the diet coke problem: preference reversal, oscillation, timelines
python namespace_test.py # multi-user isolation: no bleed between namespaces
the stress suite tries to break the engine: causal loops and self loops (must not hang), a 15 hop chain, six separate incidents jumbled with 120 noise memories (must keep every root straight), persistence across reopen, unicode and 20k char memories, and a needle in a 400 memory haystack.
benchmark: root-cause retrieval
python benchmark.py
this measures the one thing this is built for: given a symptom question, return the root cause, which sits several hops away and is worded nothing like the symptom. same corpus, three systems:
corpus: 8 incidents, 224 total memories
A. flat vector top-1 root-cause accuracy: 0%
B. flat vector top-3 root-cause recall : 0%
C. iglegais root_cause accuracy : 100% (median ~15 ms/query)
it also measures temporal current-truth retrieval, where a fact is later contradicted by an updated one:
flat vector top-1 current-truth accuracy: 0%
iglegais what_is_true accuracy : 100%
similarity search lands on the symptom (or the stale fact) because it is worded just like the query. walking the causal graph recovers the actual root, and the contradiction edges plus timestamps recover the current truth. this is not a general memory database benchmark, it is the two slices this is built for. run it yourself.
how it works
add(content, ...)embeds the text and stores a memory node with optionalcaused_by/contradicts/followsedges to earlier memories.recall(query)vector searches to the closest memory, then walks the edges to give you the reasoning around it.root_cause(query)keeps walkingcaused_byhops until it hits the root.
a few hundred lines of python: memories are rows, edges are rows, vector search is a dot product over normalized embeddings. small on purpose.
where it goes next
- per user memory spaces
- dedup on ingest
- flag stale memories when a newer one contradicts them
- a visual graph of your memory
built by @Cintu07.
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 iglegais-0.6.0-py3-none-any.whl.
File metadata
- Download URL: iglegais-0.6.0-py3-none-any.whl
- Upload date:
- Size: 46.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f581296bdeecae16b7ba6e136ccb35bef7b0d8e6af556af7833aeee08e6ba3ee
|
|
| MD5 |
505919b493c6424655d69e2f4fcd28e3
|
|
| BLAKE2b-256 |
c7e7138d2be9a0bf6018ac28d76307d956232a4ba54a8eeedab207fcbcb3baad
|