wavemind 2.2.4__tar.gz → 2.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. {wavemind-2.2.4 → wavemind-2.2.6}/PKG-INFO +30 -13
  2. {wavemind-2.2.4 → wavemind-2.2.6}/README.md +29 -12
  3. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/scale_readiness_benchmark.py +118 -2
  4. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/scale_readiness_results.json +22 -8
  5. {wavemind-2.2.4 → wavemind-2.2.6}/docker-compose.yml +1 -1
  6. {wavemind-2.2.4 → wavemind-2.2.6}/pyproject.toml +1 -1
  7. wavemind-2.2.6/tests/test_replication.py +286 -0
  8. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_scale_readiness_benchmark.py +7 -0
  9. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/__init__.py +3 -1
  10. wavemind-2.2.6/wavemind/replication.py +857 -0
  11. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind.egg-info/PKG-INFO +30 -13
  12. wavemind-2.2.4/tests/test_replication.py +0 -106
  13. wavemind-2.2.4/wavemind/replication.py +0 -399
  14. {wavemind-2.2.4 → wavemind-2.2.6}/CONTRIBUTING.md +0 -0
  15. {wavemind-2.2.4 → wavemind-2.2.6}/Dockerfile +0 -0
  16. {wavemind-2.2.4 → wavemind-2.2.6}/LICENSE +0 -0
  17. {wavemind-2.2.4 → wavemind-2.2.6}/MANIFEST.in +0 -0
  18. {wavemind-2.2.4 → wavemind-2.2.6}/SECURITY.md +0 -0
  19. {wavemind-2.2.4 → wavemind-2.2.6}/SUPPORT.md +0 -0
  20. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/BENCHMARK_LEADERBOARD.md +0 -0
  21. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/BENCHMARK_REPORT.md +0 -0
  22. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/agent_memory_benchmark.py +0 -0
  23. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/agent_memory_results.json +0 -0
  24. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/ann_index_curve_benchmark.py +0 -0
  25. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/ann_index_curve_results.json +0 -0
  26. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/benchmark_matrix_results.json +0 -0
  27. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/benchmark_registry.py +0 -0
  28. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/dynamic_memory_benchmark.py +0 -0
  29. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/dynamic_memory_results.json +0 -0
  30. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/field_memory_dynamics_benchmark.py +0 -0
  31. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/field_memory_dynamics_results.json +0 -0
  32. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/locomo_evidence_results.json +0 -0
  33. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/locomo_memory_benchmark.py +0 -0
  34. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/locomo_sentence_evidence_results.json +0 -0
  35. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/long_memory_evidence_benchmark.py +0 -0
  36. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/long_memory_evidence_results.json +0 -0
  37. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_answer_benchmark.py +0 -0
  38. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_answer_extractive_20_results.json +0 -0
  39. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_answer_qwen25_0_5b_50_results.json +0 -0
  40. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_answer_qwen25_1_5b_50_results.json +0 -0
  41. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_evidence_50_results.json +0 -0
  42. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_evidence_results.json +0 -0
  43. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/longmemeval_memory_benchmark.py +0 -0
  44. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/memory_competitor_benchmark.py +0 -0
  45. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/memory_competitor_results.json +0 -0
  46. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/nomiracl_russian_benchmark.py +0 -0
  47. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/nomiracl_russian_results.json +0 -0
  48. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/open_retrieval_benchmark.py +0 -0
  49. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/open_retrieval_scifact_results.json +0 -0
  50. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_index_profile_results.json +0 -0
  51. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_load_benchmark.py +0 -0
  52. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_load_qdrant_100k_tuned_results.json +0 -0
  53. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_load_qdrant_1m_ef_sweep_results.json +0 -0
  54. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_load_qdrant_1m_results.json +0 -0
  55. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_load_qdrant_1m_tuned_results.json +0 -0
  56. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/production_load_results.json +0 -0
  57. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/render_benchmark_charts.py +0 -0
  58. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/render_benchmark_leaderboard.py +0 -0
  59. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/render_benchmark_report.py +0 -0
  60. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/ru_sentences_benchmark.py +0 -0
  61. {wavemind-2.2.4 → wavemind-2.2.6}/benchmarks/wavemind_capacity_results.json +0 -0
  62. {wavemind-2.2.4 → wavemind-2.2.6}/docs/BENCHMARK_BRIEF.md +0 -0
  63. {wavemind-2.2.4 → wavemind-2.2.6}/docs/CHROMA_MIGRATION.md +0 -0
  64. {wavemind-2.2.4 → wavemind-2.2.6}/docs/DEMO_SCRIPT.md +0 -0
  65. {wavemind-2.2.4 → wavemind-2.2.6}/docs/LAUNCH_KIT.md +0 -0
  66. {wavemind-2.2.4 → wavemind-2.2.6}/docs/OBSERVABILITY.md +0 -0
  67. {wavemind-2.2.4 → wavemind-2.2.6}/docs/PROJECT_BOARD.md +0 -0
  68. {wavemind-2.2.4 → wavemind-2.2.6}/docs/RELEASE.md +0 -0
  69. {wavemind-2.2.4 → wavemind-2.2.6}/docs/ROADMAP.md +0 -0
  70. {wavemind-2.2.4 → wavemind-2.2.6}/docs/RU_LAUNCH_POSTS.md +0 -0
  71. {wavemind-2.2.4 → wavemind-2.2.6}/docs/USE_CASES.md +0 -0
  72. {wavemind-2.2.4 → wavemind-2.2.6}/docs/assets/benchmark-summary.svg +0 -0
  73. {wavemind-2.2.4 → wavemind-2.2.6}/docs/assets/wavemind-demo.gif +0 -0
  74. {wavemind-2.2.4 → wavemind-2.2.6}/docs/assets/wavemind-social-card.svg +0 -0
  75. {wavemind-2.2.4 → wavemind-2.2.6}/examples/agent_with_memory.py +0 -0
  76. {wavemind-2.2.4 → wavemind-2.2.6}/examples/chroma_migration.py +0 -0
  77. {wavemind-2.2.4 → wavemind-2.2.6}/examples/customer_support_memory.py +0 -0
  78. {wavemind-2.2.4 → wavemind-2.2.6}/examples/demo.py +0 -0
  79. {wavemind-2.2.4 → wavemind-2.2.6}/examples/dynamic_memory_demo.py +0 -0
  80. {wavemind-2.2.4 → wavemind-2.2.6}/examples/framework_integrations.py +0 -0
  81. {wavemind-2.2.4 → wavemind-2.2.6}/examples/langchain_memory.py +0 -0
  82. {wavemind-2.2.4 → wavemind-2.2.6}/examples/llamaindex_retriever.py +0 -0
  83. {wavemind-2.2.4 → wavemind-2.2.6}/examples/observability/README.md +0 -0
  84. {wavemind-2.2.4 → wavemind-2.2.6}/examples/observability/docker-compose.yml +0 -0
  85. {wavemind-2.2.4 → wavemind-2.2.6}/examples/observability/otel-collector.yaml +0 -0
  86. {wavemind-2.2.4 → wavemind-2.2.6}/examples/observability/prometheus-alerts.yml +0 -0
  87. {wavemind-2.2.4 → wavemind-2.2.6}/examples/observability/prometheus.yml +0 -0
  88. {wavemind-2.2.4 → wavemind-2.2.6}/examples/production-index-profile/README.md +0 -0
  89. {wavemind-2.2.4 → wavemind-2.2.6}/examples/production-index-profile/docker-compose.yml +0 -0
  90. {wavemind-2.2.4 → wavemind-2.2.6}/examples/research_notebook_memory.py +0 -0
  91. {wavemind-2.2.4 → wavemind-2.2.6}/examples/sharded_memory.py +0 -0
  92. {wavemind-2.2.4 → wavemind-2.2.6}/install.bat +0 -0
  93. {wavemind-2.2.4 → wavemind-2.2.6}/install.sh +0 -0
  94. {wavemind-2.2.4 → wavemind-2.2.6}/requirements-optional.txt +0 -0
  95. {wavemind-2.2.4 → wavemind-2.2.6}/requirements.txt +0 -0
  96. {wavemind-2.2.4 → wavemind-2.2.6}/setup.cfg +0 -0
  97. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_agent_memory_benchmark.py +0 -0
  98. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_ann_index_curve_benchmark.py +0 -0
  99. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_api.py +0 -0
  100. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_api_process_persistence.py +0 -0
  101. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_benchmark_brief.py +0 -0
  102. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_benchmark_charts.py +0 -0
  103. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_benchmark_leaderboard.py +0 -0
  104. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_benchmark_registry.py +0 -0
  105. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_benchmark_report.py +0 -0
  106. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_chroma_migration_example.py +0 -0
  107. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_cli_smoke.py +0 -0
  108. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_cluster.py +0 -0
  109. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_core_persistence.py +0 -0
  110. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_dynamic_memory_benchmark.py +0 -0
  111. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_examples.py +0 -0
  112. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_field_graph.py +0 -0
  113. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_field_graph_integration.py +0 -0
  114. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_field_memory_dynamics_benchmark.py +0 -0
  115. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_framework_adapters.py +0 -0
  116. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_import_benchmark.py +0 -0
  117. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_indexes_encoders.py +0 -0
  118. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_jobs.py +0 -0
  119. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_langchain_integration.py +0 -0
  120. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_locomo_memory_benchmark.py +0 -0
  121. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_long_memory_evidence_benchmark.py +0 -0
  122. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_longmemeval_answer_benchmark.py +0 -0
  123. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_longmemeval_memory_benchmark.py +0 -0
  124. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_memory_competitor_benchmark.py +0 -0
  125. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_multimodal.py +0 -0
  126. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_nomiracl_russian_benchmark.py +0 -0
  127. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_observability.py +0 -0
  128. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_observability_docs.py +0 -0
  129. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_open_retrieval_benchmark.py +0 -0
  130. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_packaging_files.py +0 -0
  131. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_postgres_storage.py +0 -0
  132. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_production_index_profile.py +0 -0
  133. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_production_load_benchmark.py +0 -0
  134. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_scale_plan.py +0 -0
  135. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_semantic_and_latency.py +0 -0
  136. {wavemind-2.2.4 → wavemind-2.2.6}/tests/test_sharding.py +0 -0
  137. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/__main__.py +0 -0
  138. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/api.py +0 -0
  139. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/benchmark.py +0 -0
  140. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/cli.py +0 -0
  141. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/cluster.py +0 -0
  142. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/core.py +0 -0
  143. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/encoders.py +0 -0
  144. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/field_graph.py +0 -0
  145. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/importers.py +0 -0
  146. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/indexes.py +0 -0
  147. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/integrations/__init__.py +0 -0
  148. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/integrations/autogen.py +0 -0
  149. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/integrations/crewai.py +0 -0
  150. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/integrations/langchain.py +0 -0
  151. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/integrations/langgraph.py +0 -0
  152. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/integrations/llamaindex.py +0 -0
  153. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/jobs.py +0 -0
  154. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/multimodal.py +0 -0
  155. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/observability.py +0 -0
  156. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/scale.py +0 -0
  157. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/sharding.py +0 -0
  158. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/storage.py +0 -0
  159. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind/studio.py +0 -0
  160. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind.egg-info/SOURCES.txt +0 -0
  161. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind.egg-info/dependency_links.txt +0 -0
  162. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind.egg-info/entry_points.txt +0 -0
  163. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind.egg-info/requires.txt +0 -0
  164. {wavemind-2.2.4 → wavemind-2.2.6}/wavemind.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wavemind
3
- Version: 2.2.4
3
+ Version: 2.2.6
4
4
  Summary: Local-first dynamic memory field with vector search and wave-field re-ranking
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/CaspianG/wavemind
@@ -543,13 +543,15 @@ Checked-in result:
543
543
  |---|---:|
544
544
  | Cluster planner | 4096 namespaces, 4 nodes, replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, write quorum `2`. |
545
545
  | Hot cache | 2000 lookups, hit rate `0.920`, p99 lookup `0.01 ms`. |
546
- | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, p99 query-after-loss `1.16 ms`. |
547
- | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.69 ms`. |
546
+ | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, tombstone repair deleted `1` stale record, p99 query-after-loss `1.33 ms`. |
547
+ | Active-active delta sync | 2 regions, bidirectional convergence `true`, stale import suppressed after delete `true`, tombstone convergence `true`, sync `120.19 ms`. |
548
+ | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.62 ms`. |
548
549
 
549
550
  This profile validates routing, quorum-replicated runtime behavior, cache
550
- behavior, and structured payload handling. It is not a 10M-vector load test.
551
- Real 100k, 1M, and 10M latency claims should come from service-backed
552
- FAISS/Qdrant/pgvector load tests on production-like hardware.
551
+ behavior, active-active namespace delta sync, and structured payload handling.
552
+ It is not a 10M-vector load test. Real 100k, 1M, and 10M latency claims should
553
+ come from service-backed FAISS/Qdrant/pgvector load tests on production-like
554
+ hardware.
553
555
 
554
556
  Cluster placement planning:
555
557
 
@@ -1041,7 +1043,7 @@ Current read:
1041
1043
  | LongMemEval 50-query smoke | On the first 50 non-abstention LongMemEval-S questions, WaveMind reaches `evidence_recall@5 0.920`, `precision@1 0.760`, and `MRR@5 0.827`; Chroma/Qdrant static reach `0.600`, `0.260`, and `0.385`. | This is the fast regression profile for checking current changes before rerunning the full LongMemEval profile. WaveMind wins on quality; latency still needs work. |
1042
1044
  | ANN/index curve | At 50000 generated 128-d vectors, NumPy exact keeps `recall@10 1.000` at `6.49 ms`; quantized int8 keeps `0.934` at `24.92 ms`; Annoy is faster at `4.92 ms` but drops to `0.730` recall; Qdrant local keeps `1.000` recall at `43.49 ms`. | Current local scale boundary is clear: quantized search needs kernel work, Annoy needs tuning/FAISS, and Qdrant should be tested in service mode for a fair production comparison. |
1043
1045
  | Production load | At 100000 generated 128-d vectors, service-mode Qdrant reaches `recall@10 1.000`, avg `10.28 ms`, p99 `21.26 ms`. At 1M, tuned Qdrant reaches `recall@10 0.984`, avg `116.80 ms`, p99 `209.28 ms`; an EF sweep finds `recall@10 0.977`, avg `64.76 ms`, p99 `103.77 ms` at `hnsw_ef=2048` on 30 queries. | 100k is production-grade on the tested machine. 1M recall is now strong, but p99 still needs tuning before claiming a stable sub-100 ms SLO. |
1044
- | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, replica repair, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, and replicated-runtime foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
1046
+ | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, missing-record repair, tombstone repair, active-active delta sync, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, replicated-runtime, and namespace-delta foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
1045
1047
  | Memory competitor adapters | WaveMind reaches `precision@1 0.80`, `precision@3 1.00`, stale suppression `1.00` on the small adapter profile. Mem0, Zep, and LangGraph are listed as skipped unless their real packages/services are configured. | This prevents fake competitor claims. The adapter harness is ready; real Mem0/Zep/LangGraph results still need configured installs. |
1046
1048
  | LongMemEval local answer generation | With the same local Ollama `qwen2.5:1.5b`, WaveMind reaches `exact_match 0.240`, `contains_answer 0.380`, `token_f1 0.333`, and `evidence_recall@5 0.920`; Chroma and Qdrant static both reach `0.120`, `0.160`, `0.170`, and `0.600`. | This is the first checked-in end-to-end answer benchmark against Chroma/Qdrant. It is still a 50-question lightweight smoke run, not a full LongMemEval leaderboard score. |
1047
1049
 
@@ -1060,7 +1062,7 @@ Current read:
1060
1062
  | Production index profile | Docker-backed 50000-vector profile for persisted FAISS, Qdrant service, and PostgreSQL/pgvector HNSW. | implemented | FAISS / Qdrant service / pgvector | Keep service-mode candidate generation above `0.95` recall@10 and below 10 ms average query latency at 50000 vectors. |
1061
1063
  | Production load profile | 100k and 1M service-backed candidate-index checks with p95/p99 latency. | implemented | Qdrant service / pgvector HNSW / FAISS persisted | Keep 100k at recall@10 `1.000`; push 1M p99 below 100 ms with recall@10 >= 0.95. |
1062
1064
  | Qdrant 1M HNSW ef sweep | One 1M Qdrant collection queried with multiple `hnsw_ef` values. | implemented | Qdrant service | Repeat with 100+ queries and collection-level HNSW build parameters before claiming a stable 1M SLO. |
1063
- | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication and repair green while adding larger service-backed 10M load tests. |
1065
+ | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, active-active delta sync, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication, namespace-delta sync, and repair green while adding larger service-backed 10M load tests. |
1064
1066
  | Memory competitor adapter profile | Dynamic-memory scenario wired for external memory frameworks. | implemented | Mem0 / Zep / LangGraph persistent memory | Report real competitor results only when their packages/services are explicitly configured. |
1065
1067
  | [BEIR](https://github.com/beir-cellar/beir) | Standard zero-shot information retrieval quality. | planned | Chroma / Qdrant / FAISS | Stay within 0.02 `nDCG@10` on identical embeddings. |
1066
1068
  | [MTEB Retrieval](https://github.com/embeddings-benchmark/mteb) | Separates encoder quality from retrieval-store quality. | planned | Chroma / Qdrant / FAISS | Prove WaveMind does not reduce same-embedding retrieval quality. |
@@ -1213,11 +1215,26 @@ print(memory.query("support replies", namespace="tenant:a", top_k=3))
1213
1215
  memory.close()
1214
1216
  ```
1215
1217
 
1216
- The runtime uses separate durable stores per node, quorum writes, quorum reads,
1217
- merged replica results, and `repair_namespace()` for recovered replicas. It is
1218
- the production foundation for namespace-level HA; for full consensus across
1219
- independent network services, deploy WaveMind with Postgres/Qdrant/ops-layer
1220
- replication.
1218
+ The runtime uses separate durable stores per node, stable replica keys, operation
1219
+ metadata, quorum writes, quorum reads, merged replica results, tombstone-aware
1220
+ delete propagation, and `repair_namespace()` for recovered replicas. It is the
1221
+ production foundation for namespace-level HA and eventual-consistency behavior;
1222
+ for full consensus across independent network services, deploy WaveMind with
1223
+ Postgres/Qdrant/ops-layer replication.
1224
+
1225
+ For multi-region active-active experiments, export and import namespace deltas:
1226
+
1227
+ ```python
1228
+ region_a.remember("Tenant A billing preference.", namespace="tenant:a")
1229
+ delta = region_a.export_namespace_delta("tenant:a")
1230
+ region_b.import_namespace_delta(delta)
1231
+
1232
+ region_a.forget(text="Tenant A billing preference.", namespace="tenant:a")
1233
+ region_b.import_namespace_delta(region_a.export_namespace_delta("tenant:a"))
1234
+ ```
1235
+
1236
+ The delta contains active records plus tombstones. Import is idempotent and
1237
+ tombstone-aware, so a stale region export cannot resurrect a deleted memory.
1221
1238
 
1222
1239
  Checked-in official LoCoMo retrieval result:
1223
1240
 
@@ -490,13 +490,15 @@ Checked-in result:
490
490
  |---|---:|
491
491
  | Cluster planner | 4096 namespaces, 4 nodes, replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, write quorum `2`. |
492
492
  | Hot cache | 2000 lookups, hit rate `0.920`, p99 lookup `0.01 ms`. |
493
- | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, p99 query-after-loss `1.16 ms`. |
494
- | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.69 ms`. |
493
+ | Replicated runtime | 3 physical WaveMind stores, replication factor 3, write quorum 2, node-loss recall `true`, repair copied `1` missing record, tombstone repair deleted `1` stale record, p99 query-after-loss `1.33 ms`. |
494
+ | Active-active delta sync | 2 regions, bidirectional convergence `true`, stale import suppressed after delete `true`, tombstone convergence `true`, sync `120.19 ms`. |
495
+ | Structured payloads | image/audio/table/event retrieval, precision@1 `1.000`, p99 `0.62 ms`. |
495
496
 
496
497
  This profile validates routing, quorum-replicated runtime behavior, cache
497
- behavior, and structured payload handling. It is not a 10M-vector load test.
498
- Real 100k, 1M, and 10M latency claims should come from service-backed
499
- FAISS/Qdrant/pgvector load tests on production-like hardware.
498
+ behavior, active-active namespace delta sync, and structured payload handling.
499
+ It is not a 10M-vector load test. Real 100k, 1M, and 10M latency claims should
500
+ come from service-backed FAISS/Qdrant/pgvector load tests on production-like
501
+ hardware.
500
502
 
501
503
  Cluster placement planning:
502
504
 
@@ -988,7 +990,7 @@ Current read:
988
990
  | LongMemEval 50-query smoke | On the first 50 non-abstention LongMemEval-S questions, WaveMind reaches `evidence_recall@5 0.920`, `precision@1 0.760`, and `MRR@5 0.827`; Chroma/Qdrant static reach `0.600`, `0.260`, and `0.385`. | This is the fast regression profile for checking current changes before rerunning the full LongMemEval profile. WaveMind wins on quality; latency still needs work. |
989
991
  | ANN/index curve | At 50000 generated 128-d vectors, NumPy exact keeps `recall@10 1.000` at `6.49 ms`; quantized int8 keeps `0.934` at `24.92 ms`; Annoy is faster at `4.92 ms` but drops to `0.730` recall; Qdrant local keeps `1.000` recall at `43.49 ms`. | Current local scale boundary is clear: quantized search needs kernel work, Annoy needs tuning/FAISS, and Qdrant should be tested in service mode for a fair production comparison. |
990
992
  | Production load | At 100000 generated 128-d vectors, service-mode Qdrant reaches `recall@10 1.000`, avg `10.28 ms`, p99 `21.26 ms`. At 1M, tuned Qdrant reaches `recall@10 0.984`, avg `116.80 ms`, p99 `209.28 ms`; an EF sweep finds `recall@10 0.977`, avg `64.76 ms`, p99 `103.77 ms` at `hnsw_ef=2048` on 30 queries. | 100k is production-grade on the tested machine. 1M recall is now strong, but p99 still needs tuning before claiming a stable sub-100 ms SLO. |
991
- | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, replica repair, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, and replicated-runtime foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
993
+ | Scale readiness | Deterministic 1M-memory simulation validates 4096 namespace placements over 4 nodes with replication factor 2, node-loss availability `1.000`, zone-loss availability `1.000`, hot-cache hit rate `0.920`, quorum-replicated runtime recall after node loss, missing-record repair, tombstone repair, active-active delta sync, and structured payload precision@1 `1.000`. | This proves routing, cache, payload, replicated-runtime, and namespace-delta foundations. It is not a 10M-vector latency claim; real 10M latency still needs service-backed load tests on larger hardware. |
992
994
  | Memory competitor adapters | WaveMind reaches `precision@1 0.80`, `precision@3 1.00`, stale suppression `1.00` on the small adapter profile. Mem0, Zep, and LangGraph are listed as skipped unless their real packages/services are configured. | This prevents fake competitor claims. The adapter harness is ready; real Mem0/Zep/LangGraph results still need configured installs. |
993
995
  | LongMemEval local answer generation | With the same local Ollama `qwen2.5:1.5b`, WaveMind reaches `exact_match 0.240`, `contains_answer 0.380`, `token_f1 0.333`, and `evidence_recall@5 0.920`; Chroma and Qdrant static both reach `0.120`, `0.160`, `0.170`, and `0.600`. | This is the first checked-in end-to-end answer benchmark against Chroma/Qdrant. It is still a 50-question lightweight smoke run, not a full LongMemEval leaderboard score. |
994
996
 
@@ -1007,7 +1009,7 @@ Current read:
1007
1009
  | Production index profile | Docker-backed 50000-vector profile for persisted FAISS, Qdrant service, and PostgreSQL/pgvector HNSW. | implemented | FAISS / Qdrant service / pgvector | Keep service-mode candidate generation above `0.95` recall@10 and below 10 ms average query latency at 50000 vectors. |
1008
1010
  | Production load profile | 100k and 1M service-backed candidate-index checks with p95/p99 latency. | implemented | Qdrant service / pgvector HNSW / FAISS persisted | Keep 100k at recall@10 `1.000`; push 1M p99 below 100 ms with recall@10 >= 0.95. |
1009
1011
  | Qdrant 1M HNSW ef sweep | One 1M Qdrant collection queried with multiple `hnsw_ef` values. | implemented | Qdrant service | Repeat with 100+ queries and collection-level HNSW build parameters before claiming a stable 1M SLO. |
1010
- | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication and repair green while adding larger service-backed 10M load tests. |
1012
+ | Scale readiness profile | Cluster placement, node/zone-loss simulation, quorum report, replicated runtime, active-active delta sync, hot-cache behavior, and structured/multimodal payload retrieval. | implemented | Mem0 / Zep / LangGraph persistent memory / GraphRAG target adapters | Keep quorum replication, namespace-delta sync, and repair green while adding larger service-backed 10M load tests. |
1011
1013
  | Memory competitor adapter profile | Dynamic-memory scenario wired for external memory frameworks. | implemented | Mem0 / Zep / LangGraph persistent memory | Report real competitor results only when their packages/services are explicitly configured. |
1012
1014
  | [BEIR](https://github.com/beir-cellar/beir) | Standard zero-shot information retrieval quality. | planned | Chroma / Qdrant / FAISS | Stay within 0.02 `nDCG@10` on identical embeddings. |
1013
1015
  | [MTEB Retrieval](https://github.com/embeddings-benchmark/mteb) | Separates encoder quality from retrieval-store quality. | planned | Chroma / Qdrant / FAISS | Prove WaveMind does not reduce same-embedding retrieval quality. |
@@ -1160,11 +1162,26 @@ print(memory.query("support replies", namespace="tenant:a", top_k=3))
1160
1162
  memory.close()
1161
1163
  ```
1162
1164
 
1163
- The runtime uses separate durable stores per node, quorum writes, quorum reads,
1164
- merged replica results, and `repair_namespace()` for recovered replicas. It is
1165
- the production foundation for namespace-level HA; for full consensus across
1166
- independent network services, deploy WaveMind with Postgres/Qdrant/ops-layer
1167
- replication.
1165
+ The runtime uses separate durable stores per node, stable replica keys, operation
1166
+ metadata, quorum writes, quorum reads, merged replica results, tombstone-aware
1167
+ delete propagation, and `repair_namespace()` for recovered replicas. It is the
1168
+ production foundation for namespace-level HA and eventual-consistency behavior;
1169
+ for full consensus across independent network services, deploy WaveMind with
1170
+ Postgres/Qdrant/ops-layer replication.
1171
+
1172
+ For multi-region active-active experiments, export and import namespace deltas:
1173
+
1174
+ ```python
1175
+ region_a.remember("Tenant A billing preference.", namespace="tenant:a")
1176
+ delta = region_a.export_namespace_delta("tenant:a")
1177
+ region_b.import_namespace_delta(delta)
1178
+
1179
+ region_a.forget(text="Tenant A billing preference.", namespace="tenant:a")
1180
+ region_b.import_namespace_delta(region_a.export_namespace_delta("tenant:a"))
1181
+ ```
1182
+
1183
+ The delta contains active records plus tombstones. Import is idempotent and
1184
+ tombstone-aware, so a stale region export cannot resurrect a deleted memory.
1168
1185
 
1169
1186
  Checked-in official LoCoMo retrieval result:
1170
1187
 
@@ -184,6 +184,41 @@ def run_replication_runtime_profile() -> dict[str, object]:
184
184
  finally:
185
185
  partial.close()
186
186
 
187
+ tombstone = ReplicatedWaveMind(
188
+ root_path=Path(directory) / "tombstone",
189
+ nodes=[
190
+ {"id": "node-a", "address": "127.0.0.1:8101", "zone": "zone-a"},
191
+ {"id": "node-b", "address": "127.0.0.1:8102", "zone": "zone-b"},
192
+ {"id": "node-c", "address": "127.0.0.1:8103", "zone": "zone-c"},
193
+ ],
194
+ replication_factor=3,
195
+ width=16,
196
+ height=16,
197
+ layers=1,
198
+ encoder=HashingTextEncoder(vector_dim=64),
199
+ )
200
+ try:
201
+ tombstone_placement = tombstone.placement(namespace)
202
+ missed_delete = tombstone_placement.replicas[-1]
203
+ tombstone.remember("repair must not resurrect deleted memory", namespace=namespace)
204
+ tombstone.set_node_available(missed_delete, False)
205
+ tombstone.forget(
206
+ text="repair must not resurrect deleted memory",
207
+ namespace=namespace,
208
+ )
209
+ tombstone.set_node_available(missed_delete, True)
210
+ suppressed_before_repair = (
211
+ tombstone.query("resurrect deleted memory", namespace=namespace, top_k=1)
212
+ == []
213
+ )
214
+ tombstone_repair = tombstone.repair_namespace(namespace)
215
+ suppressed_after_repair = (
216
+ tombstone.query("resurrect deleted memory", namespace=namespace, top_k=1)
217
+ == []
218
+ )
219
+ finally:
220
+ tombstone.close()
221
+
187
222
  return {
188
223
  "engine": "WaveMind replicated runtime",
189
224
  "nodes": 3,
@@ -193,6 +228,9 @@ def run_replication_runtime_profile() -> dict[str, object]:
193
228
  "writes": len(write.writes),
194
229
  "recalled_after_node_loss": recalled_after_loss,
195
230
  "repair_copied_records": repair.copied_records,
231
+ "tombstone_suppressed_before_repair": suppressed_before_repair,
232
+ "tombstone_suppressed_after_repair": suppressed_after_repair,
233
+ "tombstone_repair_deleted_records": tombstone_repair.deleted_records,
196
234
  "avg_query_after_loss_ms": statistics.mean(latencies),
197
235
  "p99_query_after_loss_ms": percentile(latencies, 99),
198
236
  }
@@ -200,6 +238,79 @@ def run_replication_runtime_profile() -> dict[str, object]:
200
238
  memory.close()
201
239
 
202
240
 
241
+ def run_active_active_delta_profile() -> dict[str, object]:
242
+ with tempfile.TemporaryDirectory() as directory:
243
+ kwargs = {
244
+ "replication_factor": 3,
245
+ "width": 16,
246
+ "height": 16,
247
+ "layers": 1,
248
+ "encoder": HashingTextEncoder(vector_dim=64),
249
+ }
250
+ region_a = ReplicatedWaveMind(
251
+ root_path=Path(directory) / "region-a",
252
+ nodes=[
253
+ {"id": "region-a-1", "address": "127.0.0.1:8101", "zone": "zone-a"},
254
+ {"id": "region-a-2", "address": "127.0.0.1:8102", "zone": "zone-b"},
255
+ {"id": "region-a-3", "address": "127.0.0.1:8103", "zone": "zone-c"},
256
+ ],
257
+ **kwargs,
258
+ )
259
+ region_b = ReplicatedWaveMind(
260
+ root_path=Path(directory) / "region-b",
261
+ nodes=[
262
+ {"id": "region-b-1", "address": "127.0.0.1:8201", "zone": "zone-a"},
263
+ {"id": "region-b-2", "address": "127.0.0.1:8202", "zone": "zone-b"},
264
+ {"id": "region-b-3", "address": "127.0.0.1:8203", "zone": "zone-c"},
265
+ ],
266
+ **kwargs,
267
+ )
268
+ try:
269
+ namespace = "tenant:active-active"
270
+ region_a.remember("region a billing preference", namespace=namespace)
271
+ region_b.remember("region b support preference", namespace=namespace)
272
+ sync_started = time.perf_counter()
273
+ import_b = region_b.import_namespace_delta(
274
+ region_a.export_namespace_delta(namespace)
275
+ )
276
+ import_a = region_a.import_namespace_delta(
277
+ region_b.export_namespace_delta(namespace)
278
+ )
279
+ sync_ms = (time.perf_counter() - sync_started) * 1000.0
280
+ converged = (
281
+ region_a.query("support preference", namespace=namespace, top_k=1)
282
+ and region_b.query("billing preference", namespace=namespace, top_k=1)
283
+ )
284
+
285
+ stale_delta = region_b.export_namespace_delta(namespace)
286
+ region_a.forget(text="region a billing preference", namespace=namespace)
287
+ region_a.import_namespace_delta(stale_delta)
288
+ suppressed_stale_import = all(
289
+ result.text != "region a billing preference"
290
+ for result in region_a.query("billing preference", namespace=namespace, top_k=3)
291
+ )
292
+ tombstone_delta = region_a.export_namespace_delta(namespace)
293
+ tombstone_report = region_b.import_namespace_delta(tombstone_delta)
294
+ tombstone_converged = all(
295
+ result.text != "region a billing preference"
296
+ for result in region_b.query("billing preference", namespace=namespace, top_k=3)
297
+ )
298
+ return {
299
+ "engine": "WaveMind active-active delta sync",
300
+ "regions": 2,
301
+ "replication_factor_per_region": 3,
302
+ "records_imported": import_a.imported_records + import_b.imported_records,
303
+ "converged_after_bidirectional_sync": bool(converged),
304
+ "sync_ms": sync_ms,
305
+ "suppressed_stale_import_after_delete": suppressed_stale_import,
306
+ "tombstone_deleted_records": tombstone_report.deleted_records,
307
+ "tombstone_converged": tombstone_converged,
308
+ }
309
+ finally:
310
+ region_a.close()
311
+ region_b.close()
312
+
313
+
203
314
  def run_multimodal_profile() -> dict[str, object]:
204
315
  with tempfile.TemporaryDirectory() as directory:
205
316
  memory = WaveMind(
@@ -287,6 +398,7 @@ def run_benchmark(
287
398
  ),
288
399
  run_cache_profile(queries=cache_queries, capacity=cache_capacity),
289
400
  run_replication_runtime_profile(),
401
+ run_active_active_delta_profile(),
290
402
  run_multimodal_profile(),
291
403
  ]
292
404
  return {
@@ -299,8 +411,8 @@ def run_benchmark(
299
411
  "description": (
300
412
  "Deterministic scale-readiness profile for cluster placement, "
301
413
  "node/zone loss simulation, quorum-replicated runtime behavior, "
302
- "hot-cache behavior, and structured payload retrieval. This is "
303
- "not a 10M-vector database load test."
414
+ "active-active delta sync, hot-cache behavior, and structured "
415
+ "payload retrieval. This is not a 10M-vector database load test."
304
416
  ),
305
417
  },
306
418
  "results": results,
@@ -340,6 +452,10 @@ def main() -> int:
340
452
  elif result["engine"] == "WaveMind replicated runtime":
341
453
  print(f"| replicated runtime | recalled_after_node_loss | {result['recalled_after_node_loss']} |")
342
454
  print(f"| replicated runtime | repair_copied_records | {result['repair_copied_records']} |")
455
+ print(f"| replicated runtime | tombstone_repair_deleted_records | {result['tombstone_repair_deleted_records']} |")
456
+ elif result["engine"] == "WaveMind active-active delta sync":
457
+ print(f"| active-active delta | converged | {result['converged_after_bidirectional_sync']} |")
458
+ print(f"| active-active delta | tombstone_converged | {result['tombstone_converged']} |")
343
459
  else:
344
460
  print(f"| structured payloads | precision@1 | {result['precision_at_1']:.3f} |")
345
461
  print(f"\nWrote {args.output}")
@@ -5,7 +5,7 @@
5
5
  "namespace_count": 4096,
6
6
  "node_count": 4,
7
7
  "replication_factor": 2,
8
- "description": "Deterministic scale-readiness profile for cluster placement, node/zone loss simulation, quorum-replicated runtime behavior, hot-cache behavior, and structured payload retrieval. This is not a 10M-vector database load test."
8
+ "description": "Deterministic scale-readiness profile for cluster placement, node/zone loss simulation, quorum-replicated runtime behavior, active-active delta sync, hot-cache behavior, and structured payload retrieval. This is not a 10M-vector database load test."
9
9
  },
10
10
  "results": [
11
11
  {
@@ -14,7 +14,7 @@
14
14
  "namespaces": 4096,
15
15
  "nodes": 4,
16
16
  "replication_factor": 2,
17
- "placement_ms": 62.52979999408126,
17
+ "placement_ms": 55.97210000269115,
18
18
  "max_replica_load": 2413,
19
19
  "min_replica_load": 1728,
20
20
  "replica_load_stdev": 316.54462560593254,
@@ -32,8 +32,8 @@
32
32
  "capacity": 512,
33
33
  "hit_rate": 0.92,
34
34
  "evictions": 0,
35
- "avg_lookup_ms": 0.0015143999480642378,
36
- "p99_lookup_ms": 0.006199989002197981
35
+ "avg_lookup_ms": 0.001386649877531454,
36
+ "p99_lookup_ms": 0.0026999623514711857
37
37
  },
38
38
  {
39
39
  "engine": "WaveMind replicated runtime",
@@ -44,8 +44,22 @@
44
44
  "writes": 3,
45
45
  "recalled_after_node_loss": true,
46
46
  "repair_copied_records": 1,
47
- "avg_query_after_loss_ms": 0.9093000553548336,
48
- "p99_query_after_loss_ms": 0.9093000553548336
47
+ "tombstone_suppressed_before_repair": true,
48
+ "tombstone_suppressed_after_repair": true,
49
+ "tombstone_repair_deleted_records": 1,
50
+ "avg_query_after_loss_ms": 1.3324000174179673,
51
+ "p99_query_after_loss_ms": 1.3324000174179673
52
+ },
53
+ {
54
+ "engine": "WaveMind active-active delta sync",
55
+ "regions": 2,
56
+ "replication_factor_per_region": 3,
57
+ "records_imported": 6,
58
+ "converged_after_bidirectional_sync": true,
59
+ "sync_ms": 120.19369995687157,
60
+ "suppressed_stale_import_after_delete": true,
61
+ "tombstone_deleted_records": 3,
62
+ "tombstone_converged": true
49
63
  },
50
64
  {
51
65
  "engine": "WaveMind structured payloads",
@@ -57,8 +71,8 @@
57
71
  ],
58
72
  "queries": 4,
59
73
  "precision_at_1": 1.0,
60
- "avg_latency_ms": 0.5151500226929784,
61
- "p99_latency_ms": 0.7709000492468476
74
+ "avg_latency_ms": 0.4274749953765422,
75
+ "p99_latency_ms": 0.6231999723240733
62
76
  }
63
77
  ]
64
78
  }
@@ -4,7 +4,7 @@ services:
4
4
  context: .
5
5
  args:
6
6
  INSTALL_OPTIONAL: "false"
7
- image: wavemind:2.2.4
7
+ image: wavemind:2.2.6
8
8
  restart: unless-stopped
9
9
  environment:
10
10
  WAVEMIND_DB: /data/wavemind.sqlite3
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wavemind"
7
- version = "2.2.4"
7
+ version = "2.2.6"
8
8
  description = "Local-first dynamic memory field with vector search and wave-field re-ranking"
9
9
  readme = "README.md"
10
10
  license = "MIT"