Skip to main content
  ██╗  ██╗ ██╗   ██╗ ██████╗  ███████╗ ██████╗  ███╗   ███╗ ███████╗ ███╗   ███╗
  ██║  ██║ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝ ██╔══██╗ ████╗ ████║ ██╔════╝ ████╗ ████║
  ███████║  ╚████╔╝  ██████╔╝ █████╗   ██████╔╝ ██╔████╔██║ █████╗   ██╔████╔██║
  ██╔══██║   ╚═══╝   ██╔═══╝  ██╔══╝   ██╔══██╗ ██║╚██╔╝██║ ██╔══╝   ██║╚██╔╝██║
  ██║  ██║   ██╗     ██║      ███████╗ ██║  ██║ ██║ ╚═╝ ██║ ███████╗ ██║ ╚═╝ ██║
  ██║  ██║   ╚═╝     ╚═╝      ╚══════╝ ╚═╝  ╚═╝ ╚═╝     ╚═╝ ╚══════╝ ╚═╝     ╚═╝
              The AI memory layer for companions that actually remember

judge-classify · store verbatim · hybrid semantic recall · live world-state · LLM-agnostic · local-first · introspectable

CI PyPI License: Source-Available Python 3.10+ Ollama / OpenAI / Anthropic

Install · Proof · How it works · API · License


HyperMEM is the memory layer between "chat" and "a character that remembers you." It watches a conversation, decides what is worth remembering, stores it verbatim, and later injects the relevant memories back into the context window, so an AI companion can recall a fact told 10,000 messages ago as reliably as one from yesterday, without a growing context and without remembering the wrong things.

It is LLM-agnostic (Ollama, OpenAI, Anthropic, or any OpenAI-compatible endpoint) and ships with a Python engine, a REST server, live world-state tracking (worldIDA), and JSON persistence.

It is also register-agnostic: the judge classifies, the store is verbatim, and worldIDA tracks physical state. None of it filters or reshapes content, so it serves every roleplay type identically: SFW, suggestive, explicit. A companion app never has to run two memory stacks.

What it does

  • Judge-classify - the fact-checker decides what matters (JSON, robustly extracted) but never writes the memory text. Your words are the memory.
  • Verbatim store - the user's message is stored intact (capped at max_memory_chars), so the exact tokens survive for recall. No paraphrase drift.
  • Hybrid semantic recall - embedding + lexical + importance + recency, budgeted for the context window. No LLM re-ranking of the whole list.
  • Type-aware lifecycle - a newer fact about the same subject supersedes the old one; episodic events consolidate into durable knowledge; decay archives what stops mattering.
  • Live world-state (worldIDA) - one compact physical state object per session (scene, positions, physical state, feasibility), fully rewritten every turn, injected in full. Narrative time (time of day, elapsed story days) gets its own block.
  • Provenance - for any memory and any query, the live score breakdown. No magic, no black box.
  • REST + Python - same engine over HTTP (hypermem-server) or inline.
  • Local-first - runs against a local Ollama; your data stays on your machine.

How it works (30 seconds)

 Your companion app
   (chat bot, game, CLI, REST client, your own code...)
        |   messages (the conversation)
        v
    +------------------------------------------------------------------+
    |  HyperMEM   (runs locally, your data stays here)                 |
    |  --------------------------------------------------------------  |
    |  Judge (classify)  ->  Verbatim store  ->  Lifecycle             |
    |       (what matters)    (your words)      (supersede/consolidate)|
    |                                                                    |
    |  Recall (hybrid score)  ->  Inject into context  <-  worldIDA    |
    |       (embedding+lexical+                                        |
    |        importance+recency)                                        |
    +------------------------------------------------------------------+
        |   relevant memories + world state
        v
 LLM provider  (Ollama - OpenAI - Anthropic - any OpenAI-compatible)
  • Judge decides what is worth remembering (importance, type, subject, keywords) without rewriting it.
  • Verbatim store keeps the exact words, so recall can match them later.
  • Lifecycle supersedes changed facts, consolidates episodic events, and decays what stops mattering.
  • Recall ranks by a hybrid score and injects only what fits the context budget.
  • worldIDA tracks the live physical scene state, injected in full every turn; narrative time (morning/evening, elapsed days) rides alongside in its own block.

Get started (60 seconds)

# 1 - Install
pip install hypermem            # core (any LLM via Ollama/OpenAI/Anthropic)
pip install "hypermem[server]"  # + REST server (fastapi, uvicorn)
# or, from source:
# git clone https://github.com/4biddencode/hypermem.git && cd hypermem && pip install -e .

# 2 - Point it at your LLM (default: Ollama, qwen2.5:7b on localhost:11434)
ollama serve                # if you haven't already

# 3 - Run the demo (real model, real numbers, no mocks)
python examples/demo.py

HyperMEM demo - real model, real output
Live: 8 facts planted, 40 filler messages, 8/8 recall, a changed fact superseded, provenance, worldIDA. Real Ollama, no mocks.

Or use it inline:

import asyncio
from hypermem import HyperMEM

hm = HyperMEM()  # defaults: Ollama, qwen2.5:7b on localhost:11434

async def main():
    # HyperMEM auto-tags important details as they arrive, stored verbatim
    await hm.add_message("user", "My name is Emanuel, I live in Vienna")
    await hm.add_message("user", "I'm planning a hike in the Alps next week")

    # Later, the relevant memories come back, even with different wording
    ctx = await hm.get_context("Where do I live?")
    print(ctx)

    # Why did that surface? Live score breakdown, no magic.
    await hm.explain_recall("Where do I live?", hm.memories()[0]["id"])

asyncio.run(main())

Output:

[RELEVANT MEMORIES]
- My name is Emanuel, I live in Vienna (importance: 100%)
[/RELEVANT MEMORIES]

Put ctx into your system prompt and your AI now answers with facts it was never given in the visible chat history.

Proof

Numbers are from the real benchmark (benchmarks/full_suite.py) against a real model (Ollama, qwen2.5:7b). No mocks, no cherry-picking. Low is better for latency, high is better for recall and contradiction handling.

Metric Result What it means
Recall @ 100 msgs ~0.9+ of 8 planted facts, ~7-8 come back after 40 filler messages
Paraphrase ~0.9+ "Where do I live?" still finds "my name is Emanuel, I live in Vienna"
Contradiction: new wins 1.0 a changed fact supersedes the old one, deterministically
Contradiction: stale leak 0.0 the superseded memory never resurfaces in recall
Judge latency ~1.4 s classify one message (LLM call, local model)
Recall latency ~0.2-0.5 s hybrid score, budgeted for the context window
worldIDA update ~3 s one compact state object, fully rewritten per turn

The point of the tables: HyperMEM does not hope to remember the right things - it is measured, and the numbers hold up across a real conversation.

When to use it

  • AI companions / roleplay - give the character a persistent memory of the user and the story, without a growing context window.
  • Chat agents & assistants - remember user preferences, facts, and project context across sessions.
  • Games with a narrative - the NPC remembers what happened, and what you told it.
  • Anything that talks to an LLM over multiple turns and wishes it could remember.

Integrations

HyperMEM is a library and a small REST server, not a plugin you install into a host app. You wire it in yourself, in a few lines:

  • Python - from hypermem import HyperMEM, then add_message / get_context.
  • REST - run hypermem-server, then:
    • POST /sessions - create a conversation
    • POST /sessions/{id}/messages - feed a message
    • GET /sessions/{id}/context?message=... - get relevant memories
    • GET /sessions/{id}/memories/{id}?query=... - provenance (why it surfaced)

Any language that can do HTTP can use HyperMEM. The server is stateless except for JSON files on disk, so you can run one instance for many conversations.

What's inside

  • hypermem/ - the engine
    • engine.py - the pipeline (judge -> store -> lifecycle -> recall -> context)
    • llm.py - robust JSON extraction, provider transport
    • world_ida.py - live world-state tracking
    • server.py - REST server
    • types.py - config, memory, persona
  • examples/demo.py - a real demo (facts planted, filler turns, recall)
  • benchmarks/ - the honest numbers, reproducible
  • tests/ - hermetic, no network

REST server

Run it, point any HTTP client at it, done:

pip install -e ".[server]"
hypermem-server --port 8080 --llm-provider ollama --llm-model qwen2.5:7b
# create a session
curl -X POST localhost:8080/sessions -d '{}'

# feed a message (judge decides if it matters, stores it verbatim)
curl -X POST localhost:8080/sessions/session_123/messages \
  -H 'content-type: application/json' \
  -d '{"role":"user","content":"My name is Emanuel, I live in Vienna"}'

# later, ask for relevant memories
curl "localhost:8080/sessions/session_123/context?message=Where%20do%20I%20live?"

Sessions are persisted as JSON on disk (.hypermem_data/ by default), so the server survives restarts. No database, no external service.

worldIDA (live world-state)

One compact state object per session tracking only the physical world - where the scene is, how each character is sitting, exactly where they are, whether a described action is physically possible. Fully rewritten every turn and injected in full. It is the "here and now" that episodic memories are too slow to capture:

{
  "scene": {"location": "tavern", "sub_location": "corner booth",
            "ongoing_action": "drinking ale"},
  "user": {"physical_state": "seated at the table", "position": "left of the booth"},
  "character": {"physical_state": "leaning forward", "position": "across from you"},
  "meta": {"physically_possible": true}
}

Emotional/social state (mood, relationship) is deliberately not tracked - worldIDA is physical-only. Narrative time (time of day + how many in-story days have passed, via a monotonic counter) is a separate [NARRATIVE TIME] context block, so the AI still knows it's morning of day 3 without polluting the physical state.

Persona isolation

Each HyperMEM instance holds its own memories, its own world-state, and its own persona. Two sessions never share memory unless you wire them to. The persona (name, description, traits, backstory, boundaries) is stored with the session and injected with context, so the same engine can power two very different characters without cross-contamination.

Configuration

Everything is configurable via HyperMemConfig (Python) or CLI flags (server). The important ones:

Option Default What it does
llm_provider auto ollama | openai | anthropic
llm_model qwen2.5:7b which model judges / recalls
llm_endpoint http://localhost:11434 provider base URL
auto_tag_threshold 0.4 minimum importance to store a memory
max_active_memories 100 cap on active (non-archived) memories
max_memory_chars 1000 verbatim content cap per memory
embedding_provider auto ollama | openai | none

API

The public surface is small on purpose. Everything else is internal.

Python

hm = HyperMEM(config)                      # engine, one per session

await hm.add_message(role, content)        # judge -> store -> lifecycle -> recall
await hm.remember(content, memory_type)    # store a memory directly
await hm.recall(query)                     # rank memories for a query
await hm.get_context(message)              # recall, formatted for the context window
await hm.explain_recall(query, memory_id)  # live score breakdown (provenance)

hm.memories()                              # list active memories
hm.set_persona(Persona(...))               # persona for this session
await hm.update_world_ida(user, ai)        # refresh world-state

hm.save(path) / hm.load(path)              # JSON persistence

REST

Method Endpoint Purpose
POST /sessions create a session
GET /sessions list sessions
DELETE /sessions/{id} delete a session
POST /sessions/{id}/messages feed a message
POST /sessions/{id}/remember store a memory directly
GET /sessions/{id}/recall?query= rank memories
GET /sessions/{id}/context?message= get context for a message
GET /sessions/{id}/memories list memories
GET /sessions/{id}/memories/{id}?query= provenance
PUT /sessions/{id}/persona set persona
GET /sessions/{id}/world-ida get world-state
POST /sessions/{id}/world-ida/update update world-state
GET /health liveness

Repo layout

hypermem/
  engine.py        # the pipeline
  llm.py           # provider + robust JSON
  world_ida.py     # live world-state
  server.py        # REST server
  types.py         # config, memory, persona
examples/
  demo.py          # real, reproducible demo
benchmarks/
  full_suite.py    # the numbers in "Proof"
tests/             # hermetic, no network

Contributing

HyperMEM is source-available. You are welcome to read it, run it, and contribute fixes and improvements. Please open an issue or PR - see CONTRIBUTING for the details, and the license below for what you can and cannot do with the code.

License

Source-Available License - you can read, run, and modify the code for your own use, and contribute back. Redistributing a competing hosted service built on it requires attribution. See the full license for the exact terms.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hypermem-1.0.1.tar.gz (48.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hypermem-1.0.1-py3-none-any.whl (51.2 kB view details)

Uploaded Python 3

File details

Details for the file hypermem-1.0.1.tar.gz.

File metadata

  • Download URL: hypermem-1.0.1.tar.gz
  • Upload date:
  • Size: 48.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hypermem-1.0.1.tar.gz
Algorithm Hash digest
SHA256 8ca198bb0bc38152992c842b1487a1050c184c7214eae32f8e0773a257fc860a
MD5 0f1ea1006ee00851861956b3345c3c07
BLAKE2b-256 577f937f20ee8c752532f813bb9d2dba5ef76e57c20700a0f2d188cde9cb4ac0

See more details on using hashes here.

Provenance

The following attestation bundles were made for hypermem-1.0.1.tar.gz:

Publisher: publish.yml on 4biddencode/hypermem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hypermem-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: hypermem-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 51.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hypermem-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e3e021f906caf99d6d67f1161e03cf22f8afa573f202f49fa4d66bbb171074b0
MD5 b488d663592a425f7abf4a286eab558e
BLAKE2b-256 d063d5beca73ace795d3c9bb67f44e3cc231e04f5247530f0cfe9fc7e4f7f194

See more details on using hashes here.

Provenance

The following attestation bundles were made for hypermem-1.0.1-py3-none-any.whl:

Publisher: publish.yml on 4biddencode/hypermem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.0.2

2 files

This release

1.0.1 This release

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page