Adaptive memory infrastructure for agents and applications that need to learn from experience.
WaveMind gives long-running software a durable, inspectable memory layer. It remembers facts, preferences, state changes, workflows, errors, and feedback; returns a compact relevant context; reinforces what works; suppresses stale information; and forgets on purpose.
PyPI · Build status · Latest release · Python >=3.10 · MIT
Quick Start · Documentation · Studio · Benchmarks · Roadmap · Contributing
Vector stores answer what is similar? Agent memory must also answer what still matters now?
| Capability | What WaveMind adds |
|---|---|
| Adaptive recall | Hotness, decay, priority, TTL, feedback, and correction handling around vector candidates. |
| Durable state | SQLite by default; PostgreSQL, Redis coordination, and service-backed vector indexes for production paths. |
| Explicit control | Namespaces, provenance, audit events, backup/restore, inspection, and deliberate deletion. |
| Small integration surface | Python API, CLI, FastAPI HTTP service, LangChain memory, and framework adapters. |
| Evidence-first releases | Public JSON artifacts, admission gates, reproducible commands, and locked claims when proof is missing. |
WaveMind complements FAISS, Qdrant, pgvector, Chroma, and other candidate indexes. It is the memory policy and lifecycle around retrieval, not another claim that one vector database should replace every other system.
| Proof | Current checked result | Source |
|---|---|---|
| Production Memory OS | admitted, 13/13 requirements |
memory_os_admission_results.json |
| Remote Redis/worker soak | 6 hours, 500/500 cycles, 2,500 attempts, zero failures or state corruption | memory_os_remote_worker_soak_results.json |
| Core production readiness | pass, 39/39 criteria |
production_readiness_results.json |
| Public package | PyPI and GitHub release v2.6.3 |
PyPI / release |
Remote multi-region, managed serverless, 100M service evidence, and universal multimodal admission remain explicitly gated. See Known Limitations and the evidence dashboard.
The shortest path from install to first recall:
python -m pip install wavemind
wavemind remember "Andrey is a trader" --namespace demo
wavemind query "What does Andrey do?" --namespace demoNeed a reminder after install?
wavemind quickstartWant to see and manage memory in a browser?
wavemind studioBy default, WaveMind creates wavemind.sqlite3 in the current working
directory. That file is the local source of truth. Keep it out of git and back
it up like application state.
Start here if you only want to use WaveMind from the terminal:
| Goal | Command |
|---|---|
| Show first-run help | wavemind quickstart |
| Store a memory | wavemind remember "Andrey prefers short answers" --namespace user:42 |
| Search memory | wavemind query "answer style" --namespace user:42 |
| Consolidate active patterns | wavemind consolidate --namespace user:42 --seed "Rust compiler systems" |
| Open local dashboard | wavemind studio |
| See stored state | wavemind stats --namespace user:42 |
| Delete a namespace | wavemind forget --namespace user:42 |
| Import notes | wavemind import ./notes.txt --namespace project:alpha |
| Use another database file | wavemind --db ./state/memory.sqlite3 query "budget" --namespace user:42 |
| Start the HTTP API | wavemind --db ./state/memory.sqlite3 serve --host 127.0.0.1 --port 8000 |
After this point, choose the integration path you need: Python, HTTP, LangChain, framework adapters, benchmarks, or production deployment.
WaveMind Studio is the built-in local dashboard. It runs on top of the same FastAPI app and SQLite database as the CLI:
wavemind studioIt opens http://127.0.0.1:8000/studio and gives you:
| View | What it is for |
|---|---|
| Memory map | See field energy as a heatmap. |
| Namespace explorer | Inspect memories per user, project, agent, or tenant. |
| Live query tester | Test recall before wiring it into an app. |
| Feedback buttons | Mark recalled memories as useful or not useful. |
| Import/export | Import local files and export a namespace snapshot. |
| Backup | Create SQLite backups from the browser. |
| Conflict visualizer | Inspect correction groups when memories disagree. |
| Memory OS Insights | See read-only hot-query, policy, execution-plan, and architecture suggestions before running background workers. |
For a server-safe local bind:
wavemind --db ./state/wavemind.sqlite3 studio --host 127.0.0.1 --port 8000from wavemind import WaveMind
memory = WaveMind(db_path="./state/wavemind.sqlite3")
memory.remember(
"The user prefers short practical answers.",
namespace="user:42",
tags=["preference"],
)
hits = memory.query("How should I answer this user?", namespace="user:42", top_k=3)
for hit in hits:
print(hit.score, hit.text)The integration pattern is intentionally small:
- Call
query()before your app, agent, tool, or UI needs context. - Pass the returned memories into your prompt, screen, search result, or decision function.
- Call
remember()after something worth keeping happens.
The FastAPI server is included in the base install:
wavemind --db ./state/wavemind.sqlite3 serve --host 127.0.0.1 --port 8000Then use WaveMind from any language:
curl -X POST http://127.0.0.1:8000/remember \
-H "Content-Type: application/json" \
-d "{\"text\":\"Andrey prefers short answers\",\"namespace\":\"user:42\",\"tags\":[\"preference\"]}"
curl -X POST http://127.0.0.1:8000/query \
-H "Content-Type: application/json" \
-d "{\"query\":\"How should I answer?\",\"namespace\":\"user:42\",\"top_k\":3}"
curl -X POST http://127.0.0.1:8000/feedback \
-H "Content-Type: application/json" \
-d "{\"id\":1,\"namespace\":\"user:42\",\"useful\":true,\"strength\":0.5,\"reason\":\"used in answer\"}"
curl -X POST http://127.0.0.1:8000/feedback/batch \
-H "Content-Type: application/json" \
-d "{\"namespace\":\"user:42\",\"items\":[{\"id\":1,\"useful\":true,\"strength\":0.5},{\"id\":2,\"useful\":false,\"strength\":0.25}]}"
curl -X POST http://127.0.0.1:8000/forget/batch \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"text\":\"Andrey prefers short answers\",\"namespace\":\"user:42\"}]}"The same feedback loop is available from the CLI:
wavemind --db ./state/wavemind.sqlite3 feedback --id 1 --namespace user:42 --strength 0.5 --reason "used in answer"
wavemind --db ./state/wavemind.sqlite3 feedback-batch --file feedback.jsonWaveMind is local-first. The SQLite database stores memories, vectors, metadata, namespaces, tags, TTL, hotness, priority, and audit events.
| runtime | Suggested database path |
|---|---|
| quick CLI experiment | ./wavemind.sqlite3 |
| Python app or agent | ./state/wavemind.sqlite3 |
| desktop app | user data directory, for example %APPDATA% or ~/.local/share |
| server daemon | /var/lib/wavemind/wavemind.sqlite3 |
| Docker | mounted volume, for example /data/wavemind.sqlite3 |
Explicit path:
wavemind --db ./state/app_memory.sqlite3 remember "Andrey prefers short answers" --namespace user:42
wavemind --db ./state/app_memory.sqlite3 query "answer style" --namespace user:42| You are building... | Start with... |
|---|---|
| Python app | from wavemind import WaveMind |
| LangChain agent | WaveMindMemory from wavemind.integrations.langchain |
| LangGraph workflow | make_recall_node() and make_persist_node() |
| LlamaIndex pipeline | WaveMindRetriever |
| CrewAI or AutoGen loop | The adapters in wavemind.integrations |
| Node, Go, Ruby, PHP, or no-code app | wavemind serve and the HTTP API |
| Personal knowledge base | Store notes by project namespace and query locally |
| Support or CRM workflow | Customer issues, resolutions, preferences, corrections, TTL, and namespace isolation. See examples/customer_support_memory.py. |
| Research or analyst notebook | Findings, hypotheses, decisions, source metadata, TTL, and project isolation. See examples/research_notebook_memory.py. |
For migrations from existing local vector memory, start with
docs/CHROMA_MIGRATION.md. The guide has a tested
offline fixture at examples/chroma_migration.py.
from wavemind import WaveMind
memory = WaveMind(db_path="./state/agent.sqlite3")
def run_turn(user_id: str, user_text: str) -> str:
namespace = f"user:{user_id}"
hits = memory.query(user_text, namespace=namespace, top_k=5, min_score=0.25)
recalled = "\n".join(f"- {hit.text}" for hit in hits)
answer = call_your_llm(f"Relevant memory:\n{recalled}\n\nUser: {user_text}")
memory.remember(f"User said: {user_text}", namespace=namespace, tags=["conversation"])
memory.remember(f"Assistant answered: {answer}", namespace=namespace, tags=["conversation"])
return answerFrom a cloned repository:
$ python examples/demo.py
[ok] Remembered: "Andrey is a trader who tracks market breakouts."
[ok] Remembered: "Andrey prefers short practical answers about product decisions."
Query: "Andrey trader preferences"
-> Result 1 (0.60): "Andrey is a trader who tracks market breakouts."
-> Result 2 (0.30): "Andrey prefers short practical answers about product decisions."
The demo is offline, keyless, and uses the built-in hash encoder.
To see the behavior that plain vector search does not provide:
python examples/dynamic_memory_demo.pyThat demo shows corrected facts outranking stale facts, temporary memory expiring, namespace isolation, and index-health reporting.
To see the same behavior in a practical support/CRM workflow:
python examples/customer_support_memory.pyThat demo stores customer preferences, billing tickets, stale CRM data, temporary discount codes, and separate customer namespaces.
To see source-aware research memory:
python examples/research_notebook_memory.pyThat demo stores analyst findings, temporary hypotheses, decisions, source metadata, and isolated project namespaces.
flowchart LR
A["Text, event, note, document, or agent turn"] --> S["remember()"]
S --> D[("SQLite: text + metadata + vectors + memory state")]
Q["query()"] --> K["k-NN candidate search"]
D --> K
K --> W["wave-field re-rank"]
W --> R["small ranked recall set"]
R --> P["app, search UI, prompt, API, or tool"]
P --> F["recall feedback updates hotness / priority"]
F --> D
F --> C["consolidate active clusters"]
C --> D
The wave field is the dynamic layer around stored memories. It is not a replacement for embeddings; it is the policy that decides which candidate memories should still matter.
| signal | Plain meaning | Effect |
|---|---|---|
| vector similarity | This text is semantically close to the query. | Gets into the candidate set. |
| hotness | This memory has been useful before. | Moves upward during recall. |
| decay | This memory has not mattered recently. | Slowly loses influence. |
| priority | The app says this fact is important. | Raises ranking even before repetition. |
| TTL | This fact is temporary. | Drops out after expiry. |
| namespace and tags | This belongs to one user/project/type. | Prevents cross-user or cross-topic leakage. |
| graph dynamics | Related memories can excite or inhibit each other. | Helps clusters and corrections behave like memory, not a flat list. |
| consolidation | Active clusters can become durable concept memories. | Turns repeated patterns into inspectable higher-level memories with provenance. |
Technically, the current MemoryFieldGraph is a discrete graph over stored
memories, not a continuous mathematical physics field. That honesty matters:
WaveMind is useful today as a dynamic memory engine, while the research path is
to make the field dynamics more explicit, measurable, and scalable.
Self-organization is now part of the core surface. consolidate_concepts(),
wavemind consolidate, and POST /consolidate can turn an active graph cluster
into a new stored memory such as Consolidated memory: systems... without an
LLM call. The generated memory keeps the source memory ids in metadata, so it is
auditable instead of being a hidden summary.
The base install is offline and keyless. Add sentence-transformers when you need semantic embeddings:
python -m pip install "wavemind[sentence]"
wavemind --encoder sentence remember "Andrey is a trader" --namespace demo
wavemind --encoder sentence query "What does Andrey do?" --namespace demoWaveMind separates durable state from candidate generation:
| index | Install | Notes |
|---|---|---|
numpy |
default | Exact cosine search, local, linear scan. |
quantized |
default | Local int8-compressed candidate index with int32-safe scoring. Useful for memory-footprint experiments; approximate recall and latency must still be measured per workload. |
annoy |
pip install "wavemind[indexes]" |
Local ANN. Faster at larger N, but recall must be checked. |
faiss / faiss-persisted |
pip install "wavemind[indexes]" |
Local FAISS, with an optional validated persisted snapshot. |
pgvector |
pip install "wavemind[postgres]" |
PostgreSQL/pgvector service candidate index. |
qdrant |
pip install "wavemind[indexes]" |
Qdrant service or local-mode candidate index. |
SQLite or PostgreSQL remains the source of truth. Missing service configuration fails clearly instead of silently switching backends. See Embeddings And Index Backends for setup, tuning, health checks, and persistence rules.
WaveMind ships local and service-backed storage, namespace sharding, replication,
Kubernetes/operator manifests, serverless lifecycle checks, backup/restore
drills, and strict evidence gates. The current production evidence gate passes
5/8 requirements; remote active-active, managed serverless telemetry, and a
real 100M sharded run remain explicitly locked.
The Checked-in production 50000-vector point covers
WaveMind faiss-persisted, Qdrant service, and pgvector tuning with
WAVEMIND_PGVECTOR_EF_SEARCH=400, pgvector-exact, and
pgvector-iterative.
Deployment references use ghcr.io/caspiang/wavemind. The
deploy/cloud/gcp-managed-serverless module creates billable Google Cloud
resources. deploy/cloud/gcp-remote-active-active also creates billable
infrastructure and does not unlock a production claim by itself.
deploy/cloud/gcp-qdrant-100m creates eight billable VMs; planning or applying
that module does not unlock the 100M claim without the measured artifact.
See Scale And Production for deployment modes, failure drills, strict claim boundaries, and exact reproduction commands. See Observability for metrics, traces, dashboards, and alerts.
WaveMind supports typed image, audio, video, 3D, table, temporal-event, and knowledge-graph payloads. Current checked evidence proves the structured contract and the explicitly precomputed-vector storage path. Precomputed vectors do not prove encoder quality and cannot unlock production multimodal admission.
The production gate requires real local text, image, audio, video, and 3D encoders over at least 1000 real or publicly licensed assets and 200 independent queries. It also requires explicit compatible shared spaces, bidirectional cross-modal checks, per-modality quality and encoding budgets, stable repeated verdicts, and a verified S3-compatible lifecycle. Local MinIO is valid; descriptor, filename, metadata, OCR-only, synthetic-vector, and precomputed shortcuts are rejected as encoder evidence.
See Multimodal And Storage for payload schemas, cross-modal retrieval, temporal and graph queries, storage backends, object lifecycles, backup/restore, and API details.
Start the API with:
wavemind serve --host 127.0.0.1 --port 8000The service exposes memory, feedback, lifecycle, health, metrics, cluster, and Memory OS routes. Production deployments should enable authentication, rate limits, TLS termination, durable storage, and monitoring. The complete route reference is in Multimodal And Storage.
For contributors installing from a local clone:
git clone https://github.com/CaspianG/wavemind.git
cd wavemind
python -m pip install -e ".[sentence]"One-file setup scripts are also included in the repository:
sh install.shinstall.batWaveMind includes package adapters for LangChain, LangGraph, LlamaIndex, CrewAI, and AutoGen. The adapters preserve namespaces and use the same durable memory API as the CLI and HTTP service.
See Framework Integrations for complete examples, OpenClaw/Hermes guidance, and custom agent loops.
Experimental work stays isolated from release claims. In particular,
research/crypto-pattern-memory is an evidence-gated research branch and is
not part of the stable package or current production claims.
WaveMind publishes checked-in JSON and Markdown artifacts for dynamic-memory, long-term-memory, indexing, scale, Memory OS, and production-evidence profiles. The public leaderboard separates implemented, runner-ready, planned, local, loopback, and production evidence.
| Evidence | Current checked result |
|---|---|
| Memory OS admission | admitted, 13/13 requirements |
| Memory OS remote soak | 6 hours, 500 cycles, 2500 attempts, zero corruption |
| Strict production evidence | 5/8 requirements |
| LongMemEval evidence retrieval | WaveMind recall@5 0.782 |
| Large-N profiles | 10M Qdrant, 10M sharded Qdrant, 10M pgvector, 50M FAISS |
These results do not claim universal vector-database leadership or completed remote 100M/multi-region proof. See the full Benchmark Guide, living dashboard, and Benchmark Brief for methods, commands, limitations, and machine-readable artifacts.
| feature | WaveMind | Chroma | Qdrant |
|---|---|---|---|
| Primary role | Dynamic memory engine | Embedding database | Production vector database |
| Local SQLite persistence | Yes | Yes | No, separate service/storage |
| HTTP API | FastAPI included | Included | Included |
| Audit log / metrics | SQLite audit events plus /metrics |
App-layer only | App-layer / service metrics |
| Dynamic memory priority | Wave-field hotness, TTL, priority | Metadata/filter driven | Payload/filter driven |
| Built-in forgetting | TTL and explicit forget | Manual delete/filtering | Manual delete/filtering |
| Best fit | Small to medium memory streams with dynamic recall | Local RAG apps and prototypes | Large-scale vector search |
| Scale target today | Local exact mode for small streams; FAISS/Qdrant/pgvector plus replicated namespaces for production paths | Larger than WaveMind local exact mode | Production vector scale |
WaveMind is not trying to replace dedicated vector databases at scale. The intended product gap is dynamic priority: frequently used memories can become hotter while old or low-priority memories fade. For static RAG over large document collections, use a mature vector database. For memory that needs persistence, scoped recall, TTL, forgetting, and reinforcement, WaveMind is designed to sit above or beside the vector index.
If you already use Chroma for local memory, see the practical migration guide:
docs/CHROMA_MIGRATION.md.
- The default NumPy exact index is intended for local memory streams. Run
wavemind scale-planand move to FAISS, Qdrant, or pgvector before treating it as a large-N production index. - Dynamic memory policy adds latency compared with static nearest-neighbor retrieval. The value is stale suppression, reinforcement, TTL, scoped recall, and consolidation rather than winning every pure ANN latency test.
MemoryFieldGraphis a discrete graph over stored memories, not a continuous physics field.- Production Memory OS is admitted for its documented remote Redis/worker topology. The broader cluster gate remains 5/8: remote multi-region, managed serverless telemetry, and 100M service evidence are not yet admitted.
- Real universal text/image/audio/video/3D encoding and cross-modal quality are
still behind
multimodal-admission; precomputed vectors and descriptors do not unlock that claim. - Large-N Qdrant and pgvector artifacts prove their stated GitHub-hosted service topologies, not independent multi-host or multi-region production.
Read the complete Known Limitations And Claim Boundaries before publishing performance, scale, or multimodal claims.
Full roadmap: docs/ROADMAP.md.
Launch and positioning kit: docs/LAUNCH_KIT.md.
Documentation map: docs/README.md.
Release history: CHANGELOG.md.
Near-term priorities:
- Finish real local text, image, audio, video, and 3D encoders and pass the strict multimodal admission gate without descriptor or synthetic-vector fallbacks.
- Run Memory OS directly inside LoCoMo, LongMemEval, and LongMemEval-V2 evaluations and prove agent-quality lift against reproducible local baselines.
- Improve dynamic re-ranking latency, context efficiency, and cost without weakening stale suppression, provenance, or recall quality.
- Expand production operations with stronger index-health metrics, alerting examples, and externally executed disaster-recovery evidence.
- Complete the remaining cluster evidence on real non-loopback infrastructure: multi-region active-active, managed serverless telemetry, and 100M service load.
Longer-term direction:
- make adaptive memory improve real agent workflows, not only retrieval metrics;
- preserve one provenance-aware lifecycle across text, media, structured data, temporal events, and knowledge graphs;
- scale from a private local database to replicated production deployments without changing the application-level memory contract;
- keep every public capability tied to a reproducible artifact, gate, or clearly locked claim.
Contributing guide: CONTRIBUTING.md.
Community participation follows the
CODE_OF_CONDUCT.md.
Useful contribution paths:
- add reproducible benchmark adapters and checked-in result JSON;
- improve FAISS, Qdrant, pgvector, or other candidate-index backends;
- add examples for LangGraph, LlamaIndex, CrewAI, AutoGen, OpenClaw, and HTTP-only sidecar deployments;
- improve dynamic memory behavior around TTL, corrections, namespaces, graph excitation/inhibition, and consolidation;
- harden production operations: backups, audit logs, metrics, tracing, and migration tools.
GitHub issue templates are included for bugs, features, benchmarks, and integrations. Benchmark claims need a reproduction command and committed result artifact before they are added to README.
MIT. See LICENSE.

