ruvector 0.1.1__tar.gz → 0.1.2__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 (479) hide show
  1. {ruvector-0.1.1 → ruvector-0.1.2}/Cargo.lock +1 -1
  2. {ruvector-0.1.1 → ruvector-0.1.2}/PKG-INFO +12 -1
  3. {ruvector-0.1.1 → ruvector-0.1.2}/README.md +11 -0
  4. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/Cargo.toml +1 -1
  5. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/README.md +11 -0
  6. ruvector-0.1.2/crates/ruvector-py/tests/perf/bench_collection.py +84 -0
  7. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_cli.py +72 -0
  8. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_mcp_server.py +79 -0
  9. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_smoke.py +1 -1
  10. {ruvector-0.1.1 → ruvector-0.1.2}/pyproject.toml +1 -1
  11. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/cli.py +81 -7
  12. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/mcp_server.py +67 -3
  13. {ruvector-0.1.1 → ruvector-0.1.2}/Cargo.toml +0 -0
  14. {ruvector-0.1.1 → ruvector-0.1.2}/LICENSE +0 -0
  15. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/Cargo.toml +0 -0
  16. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/LICENSE +0 -0
  17. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/README.md +0 -0
  18. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/benches/attention_bench.rs +0 -0
  19. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/benches/attention_benchmarks.rs +0 -0
  20. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/docs/IMPLEMENTATION_SUMMARY.md +0 -0
  21. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/docs/SDK_GUIDE.md +0 -0
  22. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/examples/hyperbolic_bench.rs +0 -0
  23. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/flash.rs +0 -0
  24. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/kv_cache.rs +0 -0
  25. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/mla.rs +0 -0
  26. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/mod.rs +0 -0
  27. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/multi_head.rs +0 -0
  28. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/scaled_dot_product.rs +0 -0
  29. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/speculative.rs +0 -0
  30. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/ssm.rs +0 -0
  31. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/config.rs +0 -0
  32. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/component_quantizer.rs +0 -0
  33. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/fused_attention.rs +0 -0
  34. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/mod.rs +0 -0
  35. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/tangent_space.rs +0 -0
  36. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/error.rs +0 -0
  37. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/dual_space.rs +0 -0
  38. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/edge_featured.rs +0 -0
  39. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/mod.rs +0 -0
  40. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/rope.rs +0 -0
  41. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/hyperbolic_attention.rs +0 -0
  42. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/lorentz_cascade.rs +0 -0
  43. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/mixed_curvature.rs +0 -0
  44. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/mod.rs +0 -0
  45. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/poincare.rs +0 -0
  46. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/info_bottleneck/bottleneck.rs +0 -0
  47. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/info_bottleneck/kl_divergence.rs +0 -0
  48. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/info_bottleneck/mod.rs +0 -0
  49. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/info_geometry/fisher.rs +0 -0
  50. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/info_geometry/mod.rs +0 -0
  51. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/info_geometry/natural_gradient.rs +0 -0
  52. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/lib.rs +0 -0
  53. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/expert.rs +0 -0
  54. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/mod.rs +0 -0
  55. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/moe_attention.rs +0 -0
  56. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/router.rs +0 -0
  57. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/pde_attention/diffusion.rs +0 -0
  58. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/pde_attention/laplacian.rs +0 -0
  59. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/pde_attention/mod.rs +0 -0
  60. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/builder.rs +0 -0
  61. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/mod.rs +0 -0
  62. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/pipeline.rs +0 -0
  63. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/presets.rs +0 -0
  64. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/attention.rs +0 -0
  65. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/early_exit.rs +0 -0
  66. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/mod.rs +0 -0
  67. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/restriction.rs +0 -0
  68. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/router.rs +0 -0
  69. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/sparse.rs +0 -0
  70. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/flash.rs +0 -0
  71. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/linear.rs +0 -0
  72. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/local_global.rs +0 -0
  73. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/mask.rs +0 -0
  74. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/mod.rs +0 -0
  75. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/coherence.rs +0 -0
  76. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/gated_attention.rs +0 -0
  77. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/mod.rs +0 -0
  78. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/policy.rs +0 -0
  79. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/training/curriculum.rs +0 -0
  80. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/training/loss.rs +0 -0
  81. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/training/mining.rs +0 -0
  82. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/training/mod.rs +0 -0
  83. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/training/optimizer.rs +0 -0
  84. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/traits.rs +0 -0
  85. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/cached_projections.rs +0 -0
  86. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/centroid_ot.rs +0 -0
  87. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/mod.rs +0 -0
  88. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/sliced_wasserstein.rs +0 -0
  89. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/unified_report/metrics.rs +0 -0
  90. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/unified_report/mod.rs +0 -0
  91. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/unified_report/report.rs +0 -0
  92. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-attention/src/utils.rs +0 -0
  93. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/Cargo.toml +0 -0
  94. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/README.md +0 -0
  95. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/package.json +0 -0
  96. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/src/consensus.rs +0 -0
  97. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/src/discovery.rs +0 -0
  98. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/src/lib.rs +0 -0
  99. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/src/shard.rs +0 -0
  100. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster/tests/integration_tests.rs +0 -0
  101. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/Cargo.toml +0 -0
  102. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/README.md +0 -0
  103. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/bench.rs +0 -0
  104. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/bin/benchmark.rs +0 -0
  105. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/cluster.rs +0 -0
  106. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/dataset.rs +0 -0
  107. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/lib.rs +0 -0
  108. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/search.rs +0 -0
  109. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/tree.rs +0 -0
  110. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/Cargo.toml +0 -0
  111. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/README.md +0 -0
  112. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/batch_operations.rs +0 -0
  113. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/bench_memory.rs +0 -0
  114. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/bench_simd.rs +0 -0
  115. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/comprehensive_bench.rs +0 -0
  116. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/distance_metrics.rs +0 -0
  117. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/hnsw_search.rs +0 -0
  118. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/pdx_vs_rowmajor.rs +0 -0
  119. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/quantization_bench.rs +0 -0
  120. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/benches/real_benchmark.rs +0 -0
  121. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/docs/EMBEDDINGS.md +0 -0
  122. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/examples/embeddings_example.rs +0 -0
  123. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/examples/lattice_embedding_example.rs +0 -0
  124. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/examples/neon_benchmark.rs +0 -0
  125. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/hypergraph.rs +0 -0
  126. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/learned_index.rs +0 -0
  127. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/mod.rs +0 -0
  128. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/neural_hash.rs +0 -0
  129. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/tda.rs +0 -0
  130. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/compaction.rs +0 -0
  131. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/conformal_prediction.rs +0 -0
  132. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/diskann.rs +0 -0
  133. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/filtered_search.rs +0 -0
  134. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/graph_rag.rs +0 -0
  135. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/hybrid_search.rs +0 -0
  136. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/matryoshka.rs +0 -0
  137. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/mmr.rs +0 -0
  138. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/multi_vector.rs +0 -0
  139. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/opq.rs +0 -0
  140. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/product_quantization.rs +0 -0
  141. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/sparse_vector.rs +0 -0
  142. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features.rs +0 -0
  143. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/agenticdb.rs +0 -0
  144. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/arena.rs +0 -0
  145. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/cache_optimized.rs +0 -0
  146. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/distance.rs +0 -0
  147. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/embeddings.rs +0 -0
  148. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/encoding/codecs.rs +0 -0
  149. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/encoding.rs +0 -0
  150. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/error.rs +0 -0
  151. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/index/flat.rs +0 -0
  152. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/index/hnsw.rs +0 -0
  153. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/index/turbo4.rs +0 -0
  154. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/index.rs +0 -0
  155. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/integration.rs +0 -0
  156. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/lib.rs +0 -0
  157. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/lockfree.rs +0 -0
  158. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/memory.rs +0 -0
  159. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/pdx.rs +0 -0
  160. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/quantization.rs +0 -0
  161. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/simd_intrinsics.rs +0 -0
  162. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/storage.rs +0 -0
  163. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/storage_compat.rs +0 -0
  164. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/storage_memory.rs +0 -0
  165. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/types.rs +0 -0
  166. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/src/vector_db.rs +0 -0
  167. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/README.md +0 -0
  168. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/advanced_features_integration.rs +0 -0
  169. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/concurrent_tests.rs +0 -0
  170. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/embeddings_role_test.rs +0 -0
  171. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/embeddings_test.rs +0 -0
  172. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_773_recall_distributions.rs +0 -0
  173. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_integration_test.rs +0 -0
  174. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_issue_773_regression.rs +0 -0
  175. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_issue_773_structural.rs +0 -0
  176. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/integration_tests.rs +0 -0
  177. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/property_tests.rs +0 -0
  178. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/stress_tests.rs +0 -0
  179. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/test_memory_pool.rs +0 -0
  180. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/test_quantization.rs +0 -0
  181. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/test_simd_correctness.rs +0 -0
  182. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-core/tests/unit_tests.rs +0 -0
  183. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/Cargo.toml +0 -0
  184. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/examples/bench_delete_recall.rs +0 -0
  185. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/examples/bench_search_hot.rs +0 -0
  186. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/examples/mmap_674_bench.rs +0 -0
  187. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/distance.rs +0 -0
  188. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/error.rs +0 -0
  189. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/graph.rs +0 -0
  190. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/index.rs +0 -0
  191. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/lib.rs +0 -0
  192. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/pq.rs +0 -0
  193. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/src/reuse.rs +0 -0
  194. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-diskann/tests/search_allocations.rs +0 -0
  195. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/Cargo.toml +0 -0
  196. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/README.md +0 -0
  197. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/examples/diskann_real_trajectory.rs +0 -0
  198. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/examples/loss_demo.rs +0 -0
  199. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/examples/triggered_rebuild.rs +0 -0
  200. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/cold_tier.rs +0 -0
  201. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/compress.rs +0 -0
  202. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/error.rs +0 -0
  203. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/ewc.rs +0 -0
  204. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/graphmae.rs +0 -0
  205. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/layer.rs +0 -0
  206. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/lib.rs +0 -0
  207. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/mmap.rs +0 -0
  208. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/mmap_fixed.rs +0 -0
  209. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/query.rs +0 -0
  210. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/replay.rs +0 -0
  211. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/scheduler.rs +0 -0
  212. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/search.rs +0 -0
  213. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/tensor.rs +0 -0
  214. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/src/training.rs +0 -0
  215. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-gnn/tests/loss_verification.rs +0 -0
  216. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/ARCHITECTURE.md +0 -0
  217. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/Cargo.toml +0 -0
  218. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/README.md +0 -0
  219. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/cypher_parser.rs +0 -0
  220. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/distributed_query.rs +0 -0
  221. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/graph_bench.rs +0 -0
  222. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/graph_traversal.rs +0 -0
  223. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/hybrid_vector_graph.rs +0 -0
  224. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/new_capabilities_bench.rs +0 -0
  225. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/query_execution.rs +0 -0
  226. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/simd_operations.rs +0 -0
  227. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/benches/typed_graph_bench.rs +0 -0
  228. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/examples/test_cypher_parser.rs +0 -0
  229. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/bm25.rs +0 -0
  230. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/codegen.rs +0 -0
  231. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/README.md +0 -0
  232. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/ast.rs +0 -0
  233. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/lexer.rs +0 -0
  234. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/mod.rs +0 -0
  235. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/optimizer.rs +0 -0
  236. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/parser.rs +0 -0
  237. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/semantic.rs +0 -0
  238. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/coordinator.rs +0 -0
  239. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/federation.rs +0 -0
  240. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/gossip.rs +0 -0
  241. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/mod.rs +0 -0
  242. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/replication.rs +0 -0
  243. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/rpc.rs +0 -0
  244. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/shard.rs +0 -0
  245. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/edge.rs +0 -0
  246. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/embed.rs +0 -0
  247. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/error.rs +0 -0
  248. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/cache.rs +0 -0
  249. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/mod.rs +0 -0
  250. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/operators.rs +0 -0
  251. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/parallel.rs +0 -0
  252. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/pipeline.rs +0 -0
  253. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/plan.rs +0 -0
  254. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/stats.rs +0 -0
  255. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/graph.rs +0 -0
  256. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/cypher_extensions.rs +0 -0
  257. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/graph_neural.rs +0 -0
  258. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/mod.rs +0 -0
  259. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/rag_integration.rs +0 -0
  260. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/semantic_search.rs +0 -0
  261. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/vector_index.rs +0 -0
  262. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/hyperedge.rs +0 -0
  263. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/index.rs +0 -0
  264. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/lib.rs +0 -0
  265. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/node.rs +0 -0
  266. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/adaptive_radix.rs +0 -0
  267. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/bloom_filter.rs +0 -0
  268. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/cache_hierarchy.rs +0 -0
  269. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/index_compression.rs +0 -0
  270. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/memory_pool.rs +0 -0
  271. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/mod.rs +0 -0
  272. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/query_jit.rs +0 -0
  273. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/simd_traversal.rs +0 -0
  274. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/schema.rs +0 -0
  275. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/storage.rs +0 -0
  276. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/transaction.rs +0 -0
  277. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/typed_graph.rs +0 -0
  278. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/src/types.rs +0 -0
  279. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/compatibility_tests.rs +0 -0
  280. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/concurrent_tests.rs +0 -0
  281. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/cypher_execution_tests.rs +0 -0
  282. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/cypher_parser_integration.rs +0 -0
  283. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/cypher_parser_tests.rs +0 -0
  284. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/distributed_tests.rs +0 -0
  285. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/edge_tests.rs +0 -0
  286. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/README.md +0 -0
  287. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/expected_results.json +0 -0
  288. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/movie_database.json +0 -0
  289. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/social_network.json +0 -0
  290. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/hyperedge_tests.rs +0 -0
  291. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/node_tests.rs +0 -0
  292. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/performance_tests.rs +0 -0
  293. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-graph/tests/transaction_tests.rs +0 -0
  294. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/Cargo.toml +0 -0
  295. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/README.md +0 -0
  296. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/benches/information_geometry.rs +0 -0
  297. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/benches/optimal_transport.rs +0 -0
  298. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/benches/product_manifold.rs +0 -0
  299. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/benches/spectral.rs +0 -0
  300. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/benches/tropical.rs +0 -0
  301. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/error.rs +0 -0
  302. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/homology/distance.rs +0 -0
  303. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/homology/filtration.rs +0 -0
  304. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/homology/mod.rs +0 -0
  305. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/homology/persistence.rs +0 -0
  306. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/homology/simplex.rs +0 -0
  307. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/fisher.rs +0 -0
  308. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/kfac.rs +0 -0
  309. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/mod.rs +0 -0
  310. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/natural_gradient.rs +0 -0
  311. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/lib.rs +0 -0
  312. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/config.rs +0 -0
  313. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/gromov_wasserstein.rs +0 -0
  314. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/mod.rs +0 -0
  315. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/sinkhorn.rs +0 -0
  316. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/sliced_wasserstein.rs +0 -0
  317. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/certificates.rs +0 -0
  318. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/mod.rs +0 -0
  319. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/polynomial.rs +0 -0
  320. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/sdp.rs +0 -0
  321. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/sos.rs +0 -0
  322. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/config.rs +0 -0
  323. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/manifold.rs +0 -0
  324. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/mod.rs +0 -0
  325. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/operations.rs +0 -0
  326. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/chebyshev.rs +0 -0
  327. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/clustering.rs +0 -0
  328. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/graph_filter.rs +0 -0
  329. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/mod.rs +0 -0
  330. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/wavelets.rs +0 -0
  331. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/spherical/mod.rs +0 -0
  332. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/contraction.rs +0 -0
  333. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/cp_decomposition.rs +0 -0
  334. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/mod.rs +0 -0
  335. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/tensor_train.rs +0 -0
  336. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/tucker.rs +0 -0
  337. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/matrix.rs +0 -0
  338. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/mod.rs +0 -0
  339. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/neural_analysis.rs +0 -0
  340. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/polynomial.rs +0 -0
  341. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/semiring.rs +0 -0
  342. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/utils/mod.rs +0 -0
  343. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/utils/numerical.rs +0 -0
  344. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-math/src/utils/sorting.rs +0 -0
  345. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/.gitignore +0 -0
  346. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/LICENSE +0 -0
  347. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/benchmarks/bench_compare_rabitq.py +0 -0
  348. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/benchmarks/bench_hnsw_real_embeddings.py +0 -0
  349. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/scripts/check-release-version.sh +0 -0
  350. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/scripts/sdist-add-patches.sh +0 -0
  351. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/cluster.rs +0 -0
  352. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/error.rs +0 -0
  353. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/gnn.rs +0 -0
  354. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/graph/convert.rs +0 -0
  355. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/graph/cypher_bridge.rs +0 -0
  356. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/graph/cypher_eval.rs +0 -0
  357. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/graph/cypher_exec.rs +0 -0
  358. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/graph.rs +0 -0
  359. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/hnsw.rs +0 -0
  360. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/lib.rs +0 -0
  361. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/rabitq.rs +0 -0
  362. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/src/sona.rs +0 -0
  363. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_cluster.py +0 -0
  364. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_collection.py +0 -0
  365. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_gnn.py +0 -0
  366. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_graph.py +0 -0
  367. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_graph_cypher.py +0 -0
  368. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_langchain_integration.py +0 -0
  369. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_llamaindex_integration.py +0 -0
  370. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_salesforce_integration.py +0 -0
  371. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_salesforce_routes.py +0 -0
  372. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-py/tests/test_sona.py +0 -0
  373. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/BENCHMARK.md +0 -0
  374. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/Cargo.toml +0 -0
  375. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/benches/rabitq_bench.rs +0 -0
  376. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/error.rs +0 -0
  377. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/index.rs +0 -0
  378. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/kernel.rs +0 -0
  379. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/lib.rs +0 -0
  380. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/main.rs +0 -0
  381. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/persist.rs +0 -0
  382. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/quantize.rs +0 -0
  383. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/rotation.rs +0 -0
  384. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-rabitq/src/scan.rs +0 -0
  385. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/Cargo.toml +0 -0
  386. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/README.md +0 -0
  387. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/src/election.rs +0 -0
  388. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/src/lib.rs +0 -0
  389. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/src/log.rs +0 -0
  390. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/src/node.rs +0 -0
  391. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/src/rpc.rs +0 -0
  392. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/src/state.rs +0 -0
  393. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-raft/tests/integration_tests.rs +0 -0
  394. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/Cargo.toml +0 -0
  395. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/README.md +0 -0
  396. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/src/conflict.rs +0 -0
  397. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/src/failover.rs +0 -0
  398. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/src/lib.rs +0 -0
  399. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/src/replica.rs +0 -0
  400. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/src/stream.rs +0 -0
  401. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-replication/src/sync.rs +0 -0
  402. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/Cargo.toml +0 -0
  403. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/benches/kernels.rs +0 -0
  404. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/bits1.rs +0 -0
  405. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/codec.rs +0 -0
  406. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/lib.rs +0 -0
  407. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/rotation.rs +0 -0
  408. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/score.rs +0 -0
  409. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/simd.rs +0 -0
  410. {ruvector-0.1.1 → ruvector-0.1.2}/crates/ruvector-turboquant/src/tables.rs +0 -0
  411. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/Cargo.toml +0 -0
  412. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/LICENSE-APACHE +0 -0
  413. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/LICENSE-MIT +0 -0
  414. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/README.md +0 -0
  415. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/auto_tuner.rs +0 -0
  416. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/darwin_guard.rs +0 -0
  417. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/engine.rs +0 -0
  418. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/ewc.rs +0 -0
  419. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/export/dataset.rs +0 -0
  420. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/export/huggingface_hub.rs +0 -0
  421. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/export/mod.rs +0 -0
  422. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/export/pretrain.rs +0 -0
  423. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/export/safetensors.rs +0 -0
  424. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/lib.rs +0 -0
  425. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/loops/background.rs +0 -0
  426. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/loops/coordinator.rs +0 -0
  427. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/loops/instant.rs +0 -0
  428. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/loops/mod.rs +0 -0
  429. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/lora.rs +0 -0
  430. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/mod.rs +0 -0
  431. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/napi.rs +0 -0
  432. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/napi_simple.rs +0 -0
  433. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/reasoning_bank.rs +0 -0
  434. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/time_compat.rs +0 -0
  435. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/training/factory.rs +0 -0
  436. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/training/federated.rs +0 -0
  437. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/training/metrics.rs +0 -0
  438. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/training/mod.rs +0 -0
  439. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/training/pipeline.rs +0 -0
  440. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/training/templates.rs +0 -0
  441. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/trajectory.rs +0 -0
  442. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/types.rs +0 -0
  443. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/src/wasm.rs +0 -0
  444. {ruvector-0.1.1 → ruvector-0.1.2}/crates/sona/wasm-example/README.md +0 -0
  445. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/.gitignore +0 -0
  446. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/Cargo.toml +0 -0
  447. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/Changes.md +0 -0
  448. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/LICENSE-APACHE +0 -0
  449. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/LICENSE-MIT +0 -0
  450. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/README.md +0 -0
  451. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/ann-glove25-angular.rs +0 -0
  452. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/ann-mnist-784-euclidean.rs +0 -0
  453. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/ann-sift1m-128-euclidean.rs +0 -0
  454. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/levensthein.rs +0 -0
  455. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/random.rs +0 -0
  456. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/utils/annhdf5.rs +0 -0
  457. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/examples/utils/mod.rs +0 -0
  458. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/api.rs +0 -0
  459. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/datamap.rs +0 -0
  460. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/filter.rs +0 -0
  461. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/flatten.rs +0 -0
  462. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/hnsw.rs +0 -0
  463. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/hnswio.rs +0 -0
  464. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/lib.rs +0 -0
  465. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/libext.rs +0 -0
  466. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/src/prelude.rs +0 -0
  467. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/tests/deallocation_test.rs +0 -0
  468. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/tests/filtertest.rs +0 -0
  469. {ruvector-0.1.1 → ruvector-0.1.2}/patches/hnsw_rs/tests/serpar.rs +0 -0
  470. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/__init__.py +0 -0
  471. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/__init__.pyi +0 -0
  472. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/_native.pyi +0 -0
  473. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/collection.py +0 -0
  474. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/integrations/__init__.py +0 -0
  475. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/integrations/langchain.py +0 -0
  476. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/integrations/llamaindex.py +0 -0
  477. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/integrations/salesforce.py +0 -0
  478. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/py.typed +0 -0
  479. {ruvector-0.1.1 → ruvector-0.1.2}/python/ruvector/salesforce_routes.py +0 -0
@@ -10759,7 +10759,7 @@ dependencies = [
10759
10759
 
10760
10760
  [[package]]
10761
10761
  name = "ruvector-py"
10762
- version = "0.1.1"
10762
+ version = "0.1.2"
10763
10763
  dependencies = [
10764
10764
  "numpy",
10765
10765
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ruvector
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: 3
@@ -137,6 +137,7 @@ ruvector benchmark -n 100000 --dim 128 # in-process latency/QPS, no external
137
137
  ruvector serve # MCP server over stdio
138
138
  ruvector serve --http --port 8420 # MCP server over streamable-HTTP (loopback)
139
139
  ruvector serve --read-only # no create/insert/delete tools
140
+ ruvector serve --max-vectors 50000 # cap vectors per collection (default 1,000,000)
140
141
  ```
141
142
 
142
143
  `serve --http` on a non-loopback `--host` refuses to start unless
@@ -162,6 +163,16 @@ directory-traversal surface regardless of what a remote MCP client sends.
162
163
  See `ruvector/mcp_server.py`'s module docstring for the full security
163
164
  model.
164
165
 
166
+ Write size is capped. Per call: 10,000 rows, 2,000,000 floats in total, and
167
+ 64 KiB of serialized metadata per row. Per collection: 1,000,000 vectors by
168
+ default, counting deleted-but-not-vacuumed rows; `vector_insert` and
169
+ `vector_insert_batch` fail with a `ToolError` that names the limit once it
170
+ would be exceeded. Change it with `ruvector serve --max-vectors N` or
171
+ `RUVECTOR_MCP_MAX_VECTORS=N` (the option wins; a non-positive or non-integer
172
+ value stops the server at startup). The server re-saves the whole collection
173
+ on every write, so keep this cap well below what your disk and latency budget
174
+ can take.
175
+
165
176
  ```sh
166
177
  # point an MCP client at: ruvector serve (stdio)
167
178
  # or: ruvector serve --http --port 8420
@@ -88,6 +88,7 @@ ruvector benchmark -n 100000 --dim 128 # in-process latency/QPS, no external
88
88
  ruvector serve # MCP server over stdio
89
89
  ruvector serve --http --port 8420 # MCP server over streamable-HTTP (loopback)
90
90
  ruvector serve --read-only # no create/insert/delete tools
91
+ ruvector serve --max-vectors 50000 # cap vectors per collection (default 1,000,000)
91
92
  ```
92
93
 
93
94
  `serve --http` on a non-loopback `--host` refuses to start unless
@@ -113,6 +114,16 @@ directory-traversal surface regardless of what a remote MCP client sends.
113
114
  See `ruvector/mcp_server.py`'s module docstring for the full security
114
115
  model.
115
116
 
117
+ Write size is capped. Per call: 10,000 rows, 2,000,000 floats in total, and
118
+ 64 KiB of serialized metadata per row. Per collection: 1,000,000 vectors by
119
+ default, counting deleted-but-not-vacuumed rows; `vector_insert` and
120
+ `vector_insert_batch` fail with a `ToolError` that names the limit once it
121
+ would be exceeded. Change it with `ruvector serve --max-vectors N` or
122
+ `RUVECTOR_MCP_MAX_VECTORS=N` (the option wins; a non-positive or non-integer
123
+ value stops the server at startup). The server re-saves the whole collection
124
+ on every write, so keep this cap well below what your disk and latency budget
125
+ can take.
126
+
116
127
  ```sh
117
128
  # point an MCP client at: ruvector serve (stdio)
118
129
  # or: ruvector serve --http --port 8420
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "ruvector-py"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  edition = "2021"
5
5
  rust-version.workspace = true
6
6
  license = "MIT"
@@ -88,6 +88,7 @@ ruvector benchmark -n 100000 --dim 128 # in-process latency/QPS, no external
88
88
  ruvector serve # MCP server over stdio
89
89
  ruvector serve --http --port 8420 # MCP server over streamable-HTTP (loopback)
90
90
  ruvector serve --read-only # no create/insert/delete tools
91
+ ruvector serve --max-vectors 50000 # cap vectors per collection (default 1,000,000)
91
92
  ```
92
93
 
93
94
  `serve --http` on a non-loopback `--host` refuses to start unless
@@ -113,6 +114,16 @@ directory-traversal surface regardless of what a remote MCP client sends.
113
114
  See `ruvector/mcp_server.py`'s module docstring for the full security
114
115
  model.
115
116
 
117
+ Write size is capped. Per call: 10,000 rows, 2,000,000 floats in total, and
118
+ 64 KiB of serialized metadata per row. Per collection: 1,000,000 vectors by
119
+ default, counting deleted-but-not-vacuumed rows; `vector_insert` and
120
+ `vector_insert_batch` fail with a `ToolError` that names the limit once it
121
+ would be exceeded. Change it with `ruvector serve --max-vectors N` or
122
+ `RUVECTOR_MCP_MAX_VECTORS=N` (the option wins; a non-positive or non-integer
123
+ value stops the server at startup). The server re-saves the whole collection
124
+ on every write, so keep this cap well below what your disk and latency budget
125
+ can take.
126
+
116
127
  ```sh
117
128
  # point an MCP client at: ruvector serve (stdio)
118
129
  # or: ruvector serve --http --port 8420
@@ -0,0 +1,84 @@
1
+ """Micro-benchmark for Collection insert / insert_batch / search / save / load.
2
+
3
+ Not collected by pytest (no ``test_`` prefix). Run on a quiet machine:
4
+
5
+ python tests/perf/bench_collection.py --n 50000 --dim 256 --repeat 5
6
+
7
+ Each figure is the median of ``--repeat`` runs; the spread (min..max) is printed
8
+ beside it. Data is seeded, so runs are comparable across commits on one machine.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ import json
15
+ import statistics
16
+ import tempfile
17
+ import time
18
+ from pathlib import Path
19
+ from typing import Callable, Dict, List
20
+
21
+ import numpy as np
22
+
23
+ from ruvector.collection import Collection
24
+
25
+
26
+ def timed(fn: Callable[[], object]) -> float:
27
+ t0 = time.perf_counter()
28
+ fn()
29
+ return time.perf_counter() - t0
30
+
31
+
32
+ def summarize(samples: List[float]) -> str:
33
+ return f"{statistics.median(samples) * 1000:9.2f} ms [{min(samples) * 1000:.2f}..{max(samples) * 1000:.2f}]"
34
+
35
+
36
+ def bench_backend(backend: str, n: int, dim: int, repeat: int, with_meta: bool) -> Dict[str, List[float]]:
37
+ rng = np.random.default_rng(0)
38
+ vecs = rng.standard_normal((n, dim)).astype(np.float32)
39
+ queries = rng.standard_normal((200, dim)).astype(np.float32)
40
+ metas = [{"i": i, "tag": f"t{i % 50}", "txt": "x" * 40} for i in range(n)] if with_meta else None
41
+ n_single = min(2000, n)
42
+ out: Dict[str, List[float]] = {k: [] for k in ("insert_x2000", "insert_batch", "from_vectors", "search_x200", "save", "load")}
43
+ for _ in range(repeat):
44
+ c = Collection.create(dim=dim, backend=backend)
45
+ if backend == "rabitq": # first row builds; time the add() path after it
46
+ c.insert(vecs[0])
47
+ out["insert_x2000"].append(timed(lambda: [c.insert(vecs[i]) for i in range(1, n_single)]))
48
+ c = Collection.create(dim=dim, backend=backend)
49
+ out["insert_batch"].append(timed(lambda: c.insert_batch(vecs, metadatas=metas)))
50
+ out["from_vectors"].append(timed(lambda: Collection.from_vectors(vecs, backend=backend, metadatas=metas)))
51
+ if backend == "rabitq":
52
+ for i in range(0, n, 10): # 10% tombstones, so search exercises the filter path
53
+ c.delete(i)
54
+ out["search_x200"].append(timed(lambda: [c.search(q, 10) for q in queries]))
55
+ with tempfile.TemporaryDirectory() as d:
56
+ p = Path(d) / "c.idx"
57
+ out["save"].append(timed(lambda: c.save(p)))
58
+ out["load"].append(timed(lambda: Collection.load(p)))
59
+ return out
60
+
61
+
62
+ def main() -> None:
63
+ ap = argparse.ArgumentParser()
64
+ ap.add_argument("--n", type=int, default=50_000)
65
+ ap.add_argument("--dim", type=int, default=256)
66
+ ap.add_argument("--repeat", type=int, default=5)
67
+ ap.add_argument("--backends", default="hnsw,rabitq")
68
+ ap.add_argument("--no-metadata", action="store_true")
69
+ ap.add_argument("--json", action="store_true")
70
+ a = ap.parse_args()
71
+ results = {}
72
+ for backend in a.backends.split(","):
73
+ results[backend] = bench_backend(backend, a.n, a.dim, a.repeat, not a.no_metadata)
74
+ if a.json:
75
+ print(json.dumps({b: {k: statistics.median(v) for k, v in r.items()} for b, r in results.items()}))
76
+ return
77
+ print(f"n={a.n} dim={a.dim} repeat={a.repeat} metadata={'no' if a.no_metadata else 'yes'}")
78
+ for backend, r in results.items():
79
+ for name, samples in r.items():
80
+ print(f"{backend:7s} {name:14s} {summarize(samples)}")
81
+
82
+
83
+ if __name__ == "__main__":
84
+ main()
@@ -6,6 +6,7 @@ from __future__ import annotations
6
6
 
7
7
  import json
8
8
  from pathlib import Path
9
+ from typing import Any, List, Optional
9
10
 
10
11
  import numpy as np
11
12
  import pytest
@@ -165,6 +166,41 @@ def test_benchmark_human_readable_has_data(runner: CliRunner) -> None:
165
166
  assert "dim=16" in r.output
166
167
 
167
168
 
169
+ @pytest.mark.parametrize("backend", ["hnsw", "rabitq"])
170
+ def test_benchmark_reports_recall(runner: CliRunner, backend: str) -> None:
171
+ r = runner.invoke(
172
+ main, ["benchmark", "-n", "400", "--dim", "16", "--queries", "15", "--backend", backend, "--json"]
173
+ )
174
+ assert r.exit_code == 0, r.output
175
+ result = json.loads(r.output)
176
+ assert result["backend"] == backend
177
+ assert result["recall_k"] == 10
178
+ assert 0.5 <= result["recall_at_10"] <= 1.0
179
+ # the existing latency fields are unchanged
180
+ for key in ("n", "dim", "k", "queries", "build_seconds", "p50_ms", "p99_ms", "qps"):
181
+ assert key in result
182
+
183
+
184
+ def test_benchmark_recall_k_is_configurable_and_in_human_output(runner: CliRunner) -> None:
185
+ r = runner.invoke(main, ["benchmark", "-n", "300", "--dim", "8", "--queries", "10", "--recall-k", "5"])
186
+ assert r.exit_code == 0, r.output
187
+ assert "recall@5=" in r.output
188
+ j = json.loads(runner.invoke(main, ["benchmark", "-n", "300", "--dim", "8", "--queries", "10", "--recall-k", "5", "--json"]).output)
189
+ assert "recall_at_5" in j and "recall_at_10" not in j
190
+
191
+
192
+ def test_benchmark_recall_is_exact_for_tiny_corpus(runner: CliRunner) -> None:
193
+ # n <= recall-k: every vector is in the top-k, so recall must be exactly 1.0
194
+ r = runner.invoke(main, ["benchmark", "-n", "6", "--dim", "8", "--queries", "5", "--recall-k", "10", "--json"])
195
+ assert r.exit_code == 0, r.output
196
+ assert json.loads(r.output)["recall_at_10"] == 1.0
197
+
198
+
199
+ def test_benchmark_rejects_nonpositive_recall_k(runner: CliRunner) -> None:
200
+ r = runner.invoke(main, ["benchmark", "-n", "50", "--dim", "8", "--recall-k", "0"])
201
+ assert r.exit_code != 0
202
+
203
+
168
204
  def test_search_no_color_flag_forces_plain(runner: CliRunner, tmp_path: Path) -> None:
169
205
  """--no-color is a no-op in terms of data under CliRunner (already
170
206
  non-TTY => already plain), but exercise the flag itself end to end so
@@ -263,3 +299,39 @@ def test_serve_without_mcp_sdk_gives_install_hint(runner: CliRunner, monkeypatch
263
299
  assert result.exit_code != 0
264
300
  assert "ruvector[mcp]" in result.output
265
301
  assert "Traceback" not in result.output
302
+
303
+
304
+ # ── serve --max-vectors ─────────────────────────────────────────────────────
305
+
306
+
307
+ def test_serve_max_vectors_option_sets_cap(runner: CliRunner, monkeypatch: pytest.MonkeyPatch) -> None:
308
+ pytest.importorskip("mcp")
309
+ import ruvector.mcp_server as m
310
+
311
+ monkeypatch.delenv("RUVECTOR_MCP_MAX_VECTORS", raising=False)
312
+ monkeypatch.setattr(m.server, "run", lambda *a, **kw: None)
313
+ try:
314
+ result = runner.invoke(main, ["serve", "--max-vectors", "123"])
315
+ assert result.exit_code == 0, result.output
316
+ assert m.max_vectors() == 123
317
+ finally:
318
+ m.set_max_vectors(None)
319
+
320
+
321
+ @pytest.mark.parametrize("args,env", [(["--max-vectors", "0"], None), ([], "nope")])
322
+ def test_serve_rejects_bad_max_vectors(
323
+ runner: CliRunner, monkeypatch: pytest.MonkeyPatch, args: List[str], env: Optional[str]
324
+ ) -> None:
325
+ pytest.importorskip("mcp")
326
+ import ruvector.mcp_server as m
327
+
328
+ ran: List[Any] = []
329
+ monkeypatch.setattr(m.server, "run", lambda *a, **kw: ran.append(1))
330
+ if env is None:
331
+ monkeypatch.delenv("RUVECTOR_MCP_MAX_VECTORS", raising=False)
332
+ else:
333
+ monkeypatch.setenv("RUVECTOR_MCP_MAX_VECTORS", env)
334
+ result = runner.invoke(main, ["serve", *args])
335
+ assert result.exit_code != 0
336
+ assert "positive integer" in result.output
337
+ assert not ran
@@ -524,3 +524,82 @@ def test_validation_errors_reach_the_client():
524
524
  assert "no such collection" in str(e)
525
525
  else:
526
526
  raise AssertionError("expected ToolError")
527
+
528
+
529
+ # ── per-collection vector cap ────────────────────────────────────────────
530
+
531
+
532
+ @pytest.fixture
533
+ def capped(server_module: ModuleType, monkeypatch: pytest.MonkeyPatch) -> ModuleType:
534
+ monkeypatch.delenv("RUVECTOR_MCP_MAX_VECTORS", raising=False)
535
+ server_module.set_max_vectors(None)
536
+ yield server_module
537
+ server_module.set_max_vectors(None)
538
+
539
+
540
+ def test_default_vector_cap_is_one_million(capped: ModuleType) -> None:
541
+ assert capped.max_vectors() == 1_000_000
542
+
543
+
544
+ def test_env_var_sets_vector_cap_and_option_wins(capped: ModuleType, monkeypatch: pytest.MonkeyPatch) -> None:
545
+ monkeypatch.setenv("RUVECTOR_MCP_MAX_VECTORS", "7")
546
+ assert capped.max_vectors() == 7
547
+ capped.set_max_vectors(3)
548
+ assert capped.max_vectors() == 3
549
+ capped.set_max_vectors(None)
550
+ monkeypatch.setenv("RUVECTOR_MCP_MAX_VECTORS", " ")
551
+ assert capped.max_vectors() == 1_000_000 # blank counts as unset
552
+
553
+
554
+ @pytest.mark.parametrize("bad", ["0", "-5", "abc", "1.5"])
555
+ def test_invalid_vector_cap_is_rejected(capped: ModuleType, monkeypatch: pytest.MonkeyPatch, bad: str) -> None:
556
+ monkeypatch.setenv("RUVECTOR_MCP_MAX_VECTORS", bad)
557
+ with pytest.raises(ValueError, match="RUVECTOR_MCP_MAX_VECTORS"):
558
+ capped.max_vectors()
559
+ with pytest.raises(ValueError):
560
+ capped.set_max_vectors(int(bad) if bad.lstrip("-").isdigit() else 0)
561
+
562
+
563
+ def test_insert_stops_at_vector_cap(capped: ModuleType) -> None:
564
+ m = capped
565
+ m.set_max_vectors(2)
566
+ _call(m, "vector_create_collection", name="cap1", dim=2)
567
+ _call(m, "vector_insert", name="cap1", vector=[1.0, 0.0])
568
+ _call(m, "vector_insert", name="cap1", vector=[0.0, 1.0])
569
+ with _raises_chain(r"vector limit.*maximum of 2"):
570
+ _call(m, "vector_insert", name="cap1", vector=[1.0, 1.0])
571
+ assert _call(m, "vector_stats", name="cap1")["count"] == 2
572
+
573
+
574
+ def test_batch_insert_is_all_or_nothing_at_cap(capped: ModuleType) -> None:
575
+ m = capped
576
+ m.set_max_vectors(3)
577
+ _call(m, "vector_create_collection", name="cap2", dim=2)
578
+ _call(m, "vector_insert_batch", name="cap2", vectors=[[1.0, 0.0], [0.0, 1.0]])
579
+ with _raises_chain("maximum of 3"):
580
+ _call(m, "vector_insert_batch", name="cap2", vectors=[[1.0, 1.0], [2.0, 2.0]])
581
+ assert _call(m, "vector_stats", name="cap2")["count"] == 2 # nothing partially written
582
+ _call(m, "vector_insert_batch", name="cap2", vectors=[[1.0, 1.0]]) # exactly reaches the cap
583
+ assert _call(m, "vector_stats", name="cap2")["count"] == 3
584
+
585
+
586
+ def test_cap_message_is_a_tool_error(capped: ModuleType) -> None:
587
+ """mcp 2.x hides non-ToolError messages from the client; the cap text must survive."""
588
+ from mcp.server.mcpserver.exceptions import ToolError
589
+
590
+ m = capped
591
+ m.set_max_vectors(1)
592
+ _call(m, "vector_create_collection", name="cap3", dim=2)
593
+ _call(m, "vector_insert", name="cap3", vector=[1.0, 0.0])
594
+ with pytest.raises(ToolError, match="vector limit"):
595
+ asyncio.run(m.server.call_tool("vector_insert", {"name": "cap3", "vector": [0.0, 1.0]}))
596
+
597
+
598
+ @pytest.mark.parametrize("backend", ["hnsw", "rabitq"])
599
+ def test_deleted_rows_count_until_vacuumed(capped: ModuleType, backend: str) -> None:
600
+ m = capped
601
+ m.set_max_vectors(2)
602
+ _call(m, "vector_create_collection", name=f"cap4{backend}", dim=2, backend=backend)
603
+ ids = _call(m, "vector_insert_batch", name=f"cap4{backend}", vectors=[[1.0, 0.0], [0.0, 1.0]])["ids"]
604
+ _call(m, "vector_delete", name=f"cap4{backend}", id=ids[0], vacuum=True)
605
+ _call(m, "vector_insert", name=f"cap4{backend}", vector=[1.0, 1.0]) # vacuumed -> room again
@@ -26,7 +26,7 @@ import ruvector
26
26
  def test_version() -> None:
27
27
  assert ruvector.__version__
28
28
  # Cargo.toml ships 0.1.0; if you bump there, bump here.
29
- assert ruvector.__version__ == "0.1.1"
29
+ assert ruvector.__version__ == "0.1.2"
30
30
 
31
31
 
32
32
  def test_build_and_search() -> None:
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "ruvector"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Ultra-low-latency vector search (RaBitQ, Rust core) with a CLI and MCP server"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -335,18 +335,67 @@ def info(path: str, as_json: bool, no_color: bool) -> None:
335
335
  console.print(Panel(table, title=f"[bold]{p.name}[/bold]", expand=False))
336
336
 
337
337
 
338
+ def _recall_at_k(coll: "Collection", vecs: "NDArray[np.float32]", qs: "NDArray[np.float32]", k: int) -> float:
339
+ """Mean recall@k of ``coll.search`` against exact brute-force top-k.
340
+
341
+ Ground truth uses the collection's own metric (cosine, or squared L2 for
342
+ rabitq). Ids are row indices because the benchmark builds with the
343
+ default ``ids=range(n)``. Ties at the k-th distance are resolved by the
344
+ stable sort, so recall can differ from 1.0 only through the index.
345
+ """
346
+ import numpy as np
347
+
348
+ k = min(k, vecs.shape[0])
349
+ if coll.metric == "squared_l2":
350
+ # |v|^2 - 2 v.q (|q|^2 is constant per query and does not change the order)
351
+ scores = (vecs * vecs).sum(axis=1)[None, :] - 2.0 * (qs @ vecs.T)
352
+ else:
353
+ vn = vecs / np.maximum(np.linalg.norm(vecs, axis=1, keepdims=True), 1e-30)
354
+ scores = -(qs @ vn.T) # cosine order = order of v.q / |v|, |q| is per-query constant
355
+ truth = np.argsort(scores, axis=1, kind="stable")[:, :k]
356
+ total = 0.0
357
+ for i in range(qs.shape[0]):
358
+ got = {hit.id for hit in coll.search(qs[i], k)}
359
+ total += len(got.intersection(truth[i].tolist())) / k
360
+ return total / qs.shape[0]
361
+
362
+
338
363
  @main.command()
339
364
  @click.option("-n", default=10_000, show_default=True, type=int, help="Number of vectors.")
340
365
  @click.option("--dim", default=128, show_default=True, type=int)
341
366
  @click.option("--k", default=10, show_default=True, type=int)
342
367
  @click.option("--queries", default=100, show_default=True, type=int)
343
- @click.option("--rerank-factor", default=20, show_default=True, type=int)
368
+ @click.option("--rerank-factor", default=20, show_default=True, type=int, help="Only used by --backend rabitq.")
369
+ @click.option(
370
+ "--backend",
371
+ default="hnsw",
372
+ show_default=True,
373
+ type=click.Choice(["hnsw", "rabitq"]),
374
+ help="Index backend to benchmark.",
375
+ )
376
+ @click.option(
377
+ "--recall-k",
378
+ default=10,
379
+ show_default=True,
380
+ type=int,
381
+ help="k for recall@k, measured against exact brute-force search over the same vectors.",
382
+ )
344
383
  @click.option("--json", "as_json", is_flag=True, default=False)
345
- def benchmark(n: int, dim: int, k: int, queries: int, rerank_factor: int, as_json: bool) -> None:
346
- """Run an in-memory build+search latency benchmark (no comparator — see
347
- the ADR-352 benchmark methodology for a real side-by-side)."""
384
+ def benchmark(
385
+ n: int, dim: int, k: int, queries: int, rerank_factor: int, backend: str, recall_k: int, as_json: bool
386
+ ) -> None:
387
+ """Run an in-memory build+search benchmark: latency, QPS and recall@k
388
+ against exact brute-force search (no comparator — see the ADR-352
389
+ benchmark methodology for a real side-by-side).
390
+
391
+ Recall is computed on the same queries as the latency loop, using the
392
+ index's own distance (cosine for hnsw, squared L2 for rabitq), and is
393
+ not included in the timings."""
348
394
  import time
349
395
 
396
+ if n < 1 or dim < 1 or k < 1 or queries < 1 or recall_k < 1:
397
+ raise click.ClickException("-n, --dim, --k, --queries and --recall-k must all be >= 1")
398
+
350
399
  import numpy as np
351
400
 
352
401
  from ruvector.collection import Collection
@@ -355,7 +404,7 @@ def benchmark(n: int, dim: int, k: int, queries: int, rerank_factor: int, as_jso
355
404
  vecs = rng.standard_normal((n, dim)).astype(np.float32)
356
405
 
357
406
  t0 = time.perf_counter()
358
- coll = Collection.from_vectors(vecs, rerank_factor=rerank_factor)
407
+ coll = Collection.from_vectors(vecs, backend=backend, rerank_factor=rerank_factor)
359
408
  build_s = time.perf_counter() - t0
360
409
 
361
410
  qs = rng.standard_normal((queries, dim)).astype(np.float32)
@@ -368,8 +417,13 @@ def benchmark(n: int, dim: int, k: int, queries: int, rerank_factor: int, as_jso
368
417
  p50 = latencies[len(latencies) // 2]
369
418
  p99 = latencies[int(len(latencies) * 0.99) - 1]
370
419
 
420
+ recall = _recall_at_k(coll, vecs, qs, recall_k)
421
+
371
422
  result = {
372
423
  "n": n, "dim": dim, "k": k, "queries": queries, "rerank_factor": rerank_factor,
424
+ "backend": backend,
425
+ f"recall_at_{recall_k}": recall,
426
+ "recall_k": recall_k,
373
427
  "build_seconds": build_s,
374
428
  "p50_ms": p50 * 1000,
375
429
  "p99_ms": p99 * 1000,
@@ -381,7 +435,8 @@ def benchmark(n: int, dim: int, k: int, queries: int, rerank_factor: int, as_jso
381
435
  else:
382
436
  _secho(
383
437
  f"n={n} dim={dim} build={build_s:.3f}s p50={result['p50_ms']:.3f}ms "
384
- f"p99={result['p99_ms']:.3f}ms qps={result['qps']:.0f}",
438
+ f"p99={result['p99_ms']:.3f}ms qps={result['qps']:.0f} "
439
+ f"recall@{recall_k}={recall:.4f}",
385
440
  fg="cyan",
386
441
  )
387
442
 
@@ -396,7 +451,14 @@ def benchmark(n: int, dim: int, k: int, queries: int, rerank_factor: int, as_jso
396
451
  default=False,
397
452
  help="Do not register mutating tools (create/insert/insert_batch/delete) or the Salesforce upsert route.",
398
453
  )
399
- def serve(use_http: bool, host: str, port: int, read_only: bool) -> None:
454
+ @click.option(
455
+ "--max-vectors",
456
+ default=None,
457
+ type=int,
458
+ help="Maximum vectors per collection a client may write "
459
+ "(default 1000000; also settable with RUVECTOR_MCP_MAX_VECTORS; this option wins).",
460
+ )
461
+ def serve(use_http: bool, host: str, port: int, read_only: bool, max_vectors: Optional[int]) -> None:
400
462
  """Launch the ruvector MCP server (stdio by default).
401
463
 
402
464
  If ``RUVECTOR_ENABLE_SALESFORCE_ACTIONS`` is set, also mounts the
@@ -423,6 +485,18 @@ def serve(use_http: bool, host: str, port: int, read_only: bool) -> None:
423
485
  if read_only:
424
486
  apply_read_only()
425
487
 
488
+ try:
489
+ if max_vectors is not None:
490
+ from ruvector.mcp_server import set_max_vectors
491
+
492
+ set_max_vectors(max_vectors)
493
+ else:
494
+ from ruvector.mcp_server import max_vectors as _effective_max_vectors
495
+
496
+ _effective_max_vectors() # fail at startup, not on the first insert, if the env var is malformed
497
+ except ValueError as exc:
498
+ raise click.ClickException(str(exc)) from exc
499
+
426
500
  if use_http and os.environ.get("RUVECTOR_ENABLE_SALESFORCE_ACTIONS"):
427
501
  from ruvector.salesforce_routes import SalesforceAuthNotConfiguredError, maybe_register
428
502
 
@@ -78,7 +78,7 @@ import re
78
78
  import sys
79
79
  import threading
80
80
  from pathlib import Path
81
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
81
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
82
82
 
83
83
  from mcp.server.auth.middleware.auth_context import get_access_token
84
84
  from mcp.server.auth.provider import AccessToken, TokenVerifier
@@ -105,6 +105,13 @@ _NAME_RE = re.compile(r"^[A-Za-z0-9_-]{1,128}$")
105
105
  MAX_BATCH_ROWS = 10_000
106
106
  MAX_BATCH_ELEMENTS = 2_000_000 # rows * dim floats per insert_batch call (~8 MB as float32)
107
107
  MAX_METADATA_BYTES = 65_536 # serialized JSON, per row
108
+ # Total vectors a client may write into ONE collection (a cumulative cap, unlike
109
+ # the per-call caps above). Every write re-saves the whole collection, so an
110
+ # unbounded collection also makes each later write slower. Override with the
111
+ # RUVECTOR_MCP_MAX_VECTORS environment variable or `ruvector serve --max-vectors`.
112
+ DEFAULT_MAX_VECTORS = 1_000_000
113
+ _MAX_VECTORS_ENV_VAR = "RUVECTOR_MCP_MAX_VECTORS"
114
+ _max_vectors_override: Optional[int] = None
108
115
 
109
116
  _TOKEN_ENV_VAR = "RUVECTOR_MCP_TOKEN"
110
117
  # Self-referential placeholder — this design does not do real OAuth
@@ -263,6 +270,52 @@ def _save(name: str, coll: "Collection") -> None:
263
270
  _cache[name] = coll
264
271
 
265
272
 
273
+ def parse_max_vectors(raw: Union[str, int], source: str) -> int:
274
+ """Validate a vectors-per-collection cap; raises ``ValueError`` if not a positive int."""
275
+ try:
276
+ value = int(str(raw).strip())
277
+ except ValueError:
278
+ raise ValueError(f"{source} must be a positive integer, got {raw!r}") from None
279
+ if value < 1:
280
+ raise ValueError(f"{source} must be a positive integer, got {raw!r}")
281
+ return value
282
+
283
+
284
+ def set_max_vectors(value: Optional[int]) -> None:
285
+ """Set (or with ``None`` clear) the cap given on the command line; it wins over the environment."""
286
+ global _max_vectors_override
287
+ _max_vectors_override = None if value is None else parse_max_vectors(value, "max vectors")
288
+
289
+
290
+ def max_vectors() -> int:
291
+ """Effective per-collection cap: ``--max-vectors``, else the env var, else the default.
292
+
293
+ An empty env var counts as unset.
294
+ """
295
+ if _max_vectors_override is not None:
296
+ return _max_vectors_override
297
+ raw = os.environ.get(_MAX_VECTORS_ENV_VAR, "").strip()
298
+ return parse_max_vectors(raw, _MAX_VECTORS_ENV_VAR) if raw else DEFAULT_MAX_VECTORS
299
+
300
+
301
+ def _check_capacity(coll: "Collection", incoming: int) -> None:
302
+ """Reject a write that would take the collection past the cap.
303
+
304
+ Counts tombstoned rows too: they still occupy the index and the saved
305
+ files until ``vector_delete(..., vacuum=True)`` runs.
306
+ """
307
+ cap = max_vectors()
308
+ stats = coll.stats()
309
+ used = stats.count + stats.tombstoned
310
+ if used + incoming > cap:
311
+ raise ValueError(
312
+ f"collection is at its vector limit: it holds {used} vectors"
313
+ f"{f' ({stats.tombstoned} deleted, not yet vacuumed)' if stats.tombstoned else ''}, "
314
+ f"adding {incoming} would exceed the maximum of {cap} per collection "
315
+ f"(set {_MAX_VECTORS_ENV_VAR} or `ruvector serve --max-vectors` to change it)"
316
+ )
317
+
318
+
266
319
  def _check_vector_len(vec: "List[float]", what: str) -> None:
267
320
  if len(vec) > MAX_DIM:
268
321
  raise ValueError(f"{what} has {len(vec)} elements; the maximum dimension is {MAX_DIM}")
@@ -297,7 +350,7 @@ _token_verifier, _auth_settings = _build_auth()
297
350
  server = MCPServer(
298
351
  name="ruvector",
299
352
  title="RuVector",
300
- version="0.1.1",
353
+ version="0.1.2",
301
354
  instructions=(
302
355
  "ultra-low-latency vector search backed by a Rust RaBitQ core. "
303
356
  "Create a collection, insert vectors with optional metadata, search "
@@ -369,6 +422,7 @@ def vector_insert(name: str, vector: List[float], metadata: Optional[Dict[str, A
369
422
  _check_metadata(metadata)
370
423
  with _lock:
371
424
  coll = _load(name)
425
+ _check_capacity(coll, 1)
372
426
  new_id = coll.insert(np.asarray(vector, dtype=np.float32), metadata=metadata)
373
427
  _save(name, coll)
374
428
  return {"id": new_id, "count": len(coll)}
@@ -388,6 +442,7 @@ def vector_insert_batch(
388
442
  _check_batch(vectors, metadatas)
389
443
  with _lock:
390
444
  coll = _load(name)
445
+ _check_capacity(coll, len(vectors))
391
446
  ids = coll.insert_batch(np.asarray(vectors, dtype=np.float32), metadatas=metadatas)
392
447
  _save(name, coll)
393
448
  return {"ids": ids, "count": len(coll)}
@@ -619,4 +674,13 @@ def run_http(host: str = "127.0.0.1", port: int = 8420) -> None:
619
674
  server.run(transport="streamable-http", host=host, port=port)
620
675
 
621
676
 
622
- __all__ = ["server", "run_stdio", "run_http", "StaticTokenVerifier", "apply_read_only", "UnsafeBindError"]
677
+ __all__ = [
678
+ "server",
679
+ "run_stdio",
680
+ "run_http",
681
+ "StaticTokenVerifier",
682
+ "apply_read_only",
683
+ "UnsafeBindError",
684
+ "set_max_vectors",
685
+ "max_vectors",
686
+ ]
File without changes
File without changes