ruvector 0.1.0__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.0 → ruvector-0.1.2}/Cargo.lock +1 -1
  2. {ruvector-0.1.0 → ruvector-0.1.2}/PKG-INFO +13 -1
  3. {ruvector-0.1.0 → ruvector-0.1.2}/README.md +11 -0
  4. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/Cargo.toml +1 -1
  5. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/README.md +11 -0
  6. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/rabitq.rs +94 -8
  7. ruvector-0.1.2/crates/ruvector-py/tests/perf/bench_collection.py +84 -0
  8. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_cli.py +72 -0
  9. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_mcp_server.py +104 -0
  10. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_smoke.py +87 -1
  11. {ruvector-0.1.0 → ruvector-0.1.2}/pyproject.toml +2 -1
  12. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/_native.pyi +7 -4
  13. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/cli.py +81 -7
  14. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/mcp_server.py +103 -7
  15. {ruvector-0.1.0 → ruvector-0.1.2}/Cargo.toml +0 -0
  16. {ruvector-0.1.0 → ruvector-0.1.2}/LICENSE +0 -0
  17. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/Cargo.toml +0 -0
  18. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/LICENSE +0 -0
  19. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/README.md +0 -0
  20. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/benches/attention_bench.rs +0 -0
  21. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/benches/attention_benchmarks.rs +0 -0
  22. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/docs/IMPLEMENTATION_SUMMARY.md +0 -0
  23. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/docs/SDK_GUIDE.md +0 -0
  24. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/examples/hyperbolic_bench.rs +0 -0
  25. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/flash.rs +0 -0
  26. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/kv_cache.rs +0 -0
  27. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/mla.rs +0 -0
  28. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/mod.rs +0 -0
  29. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/multi_head.rs +0 -0
  30. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/scaled_dot_product.rs +0 -0
  31. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/speculative.rs +0 -0
  32. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/attention/ssm.rs +0 -0
  33. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/config.rs +0 -0
  34. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/component_quantizer.rs +0 -0
  35. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/fused_attention.rs +0 -0
  36. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/mod.rs +0 -0
  37. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/curvature/tangent_space.rs +0 -0
  38. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/error.rs +0 -0
  39. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/dual_space.rs +0 -0
  40. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/edge_featured.rs +0 -0
  41. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/mod.rs +0 -0
  42. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/graph/rope.rs +0 -0
  43. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/hyperbolic_attention.rs +0 -0
  44. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/lorentz_cascade.rs +0 -0
  45. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/mixed_curvature.rs +0 -0
  46. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/mod.rs +0 -0
  47. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/hyperbolic/poincare.rs +0 -0
  48. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/info_bottleneck/bottleneck.rs +0 -0
  49. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/info_bottleneck/kl_divergence.rs +0 -0
  50. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/info_bottleneck/mod.rs +0 -0
  51. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/info_geometry/fisher.rs +0 -0
  52. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/info_geometry/mod.rs +0 -0
  53. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/info_geometry/natural_gradient.rs +0 -0
  54. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/lib.rs +0 -0
  55. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/expert.rs +0 -0
  56. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/mod.rs +0 -0
  57. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/moe_attention.rs +0 -0
  58. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/moe/router.rs +0 -0
  59. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/pde_attention/diffusion.rs +0 -0
  60. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/pde_attention/laplacian.rs +0 -0
  61. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/pde_attention/mod.rs +0 -0
  62. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/builder.rs +0 -0
  63. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/mod.rs +0 -0
  64. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/pipeline.rs +0 -0
  65. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sdk/presets.rs +0 -0
  66. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/attention.rs +0 -0
  67. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/early_exit.rs +0 -0
  68. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/mod.rs +0 -0
  69. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/restriction.rs +0 -0
  70. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/router.rs +0 -0
  71. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sheaf/sparse.rs +0 -0
  72. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/flash.rs +0 -0
  73. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/linear.rs +0 -0
  74. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/local_global.rs +0 -0
  75. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/mask.rs +0 -0
  76. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/sparse/mod.rs +0 -0
  77. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/coherence.rs +0 -0
  78. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/gated_attention.rs +0 -0
  79. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/mod.rs +0 -0
  80. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/topology/policy.rs +0 -0
  81. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/training/curriculum.rs +0 -0
  82. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/training/loss.rs +0 -0
  83. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/training/mining.rs +0 -0
  84. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/training/mod.rs +0 -0
  85. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/training/optimizer.rs +0 -0
  86. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/traits.rs +0 -0
  87. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/cached_projections.rs +0 -0
  88. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/centroid_ot.rs +0 -0
  89. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/mod.rs +0 -0
  90. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/transport/sliced_wasserstein.rs +0 -0
  91. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/unified_report/metrics.rs +0 -0
  92. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/unified_report/mod.rs +0 -0
  93. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/unified_report/report.rs +0 -0
  94. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-attention/src/utils.rs +0 -0
  95. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/Cargo.toml +0 -0
  96. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/README.md +0 -0
  97. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/package.json +0 -0
  98. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/src/consensus.rs +0 -0
  99. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/src/discovery.rs +0 -0
  100. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/src/lib.rs +0 -0
  101. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/src/shard.rs +0 -0
  102. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster/tests/integration_tests.rs +0 -0
  103. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/Cargo.toml +0 -0
  104. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/README.md +0 -0
  105. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/bench.rs +0 -0
  106. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/bin/benchmark.rs +0 -0
  107. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/cluster.rs +0 -0
  108. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/dataset.rs +0 -0
  109. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/lib.rs +0 -0
  110. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/search.rs +0 -0
  111. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-cluster-rag/src/tree.rs +0 -0
  112. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/Cargo.toml +0 -0
  113. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/README.md +0 -0
  114. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/batch_operations.rs +0 -0
  115. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/bench_memory.rs +0 -0
  116. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/bench_simd.rs +0 -0
  117. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/comprehensive_bench.rs +0 -0
  118. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/distance_metrics.rs +0 -0
  119. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/hnsw_search.rs +0 -0
  120. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/pdx_vs_rowmajor.rs +0 -0
  121. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/quantization_bench.rs +0 -0
  122. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/benches/real_benchmark.rs +0 -0
  123. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/docs/EMBEDDINGS.md +0 -0
  124. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/examples/embeddings_example.rs +0 -0
  125. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/examples/lattice_embedding_example.rs +0 -0
  126. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/examples/neon_benchmark.rs +0 -0
  127. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/hypergraph.rs +0 -0
  128. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/learned_index.rs +0 -0
  129. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/mod.rs +0 -0
  130. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/neural_hash.rs +0 -0
  131. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced/tda.rs +0 -0
  132. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/compaction.rs +0 -0
  133. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/conformal_prediction.rs +0 -0
  134. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/diskann.rs +0 -0
  135. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/filtered_search.rs +0 -0
  136. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/graph_rag.rs +0 -0
  137. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/hybrid_search.rs +0 -0
  138. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/matryoshka.rs +0 -0
  139. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/mmr.rs +0 -0
  140. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/multi_vector.rs +0 -0
  141. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/opq.rs +0 -0
  142. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/product_quantization.rs +0 -0
  143. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features/sparse_vector.rs +0 -0
  144. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/advanced_features.rs +0 -0
  145. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/agenticdb.rs +0 -0
  146. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/arena.rs +0 -0
  147. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/cache_optimized.rs +0 -0
  148. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/distance.rs +0 -0
  149. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/embeddings.rs +0 -0
  150. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/encoding/codecs.rs +0 -0
  151. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/encoding.rs +0 -0
  152. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/error.rs +0 -0
  153. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/index/flat.rs +0 -0
  154. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/index/hnsw.rs +0 -0
  155. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/index/turbo4.rs +0 -0
  156. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/index.rs +0 -0
  157. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/integration.rs +0 -0
  158. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/lib.rs +0 -0
  159. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/lockfree.rs +0 -0
  160. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/memory.rs +0 -0
  161. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/pdx.rs +0 -0
  162. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/quantization.rs +0 -0
  163. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/simd_intrinsics.rs +0 -0
  164. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/storage.rs +0 -0
  165. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/storage_compat.rs +0 -0
  166. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/storage_memory.rs +0 -0
  167. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/types.rs +0 -0
  168. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/src/vector_db.rs +0 -0
  169. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/README.md +0 -0
  170. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/advanced_features_integration.rs +0 -0
  171. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/concurrent_tests.rs +0 -0
  172. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/embeddings_role_test.rs +0 -0
  173. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/embeddings_test.rs +0 -0
  174. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_773_recall_distributions.rs +0 -0
  175. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_integration_test.rs +0 -0
  176. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_issue_773_regression.rs +0 -0
  177. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/hnsw_issue_773_structural.rs +0 -0
  178. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/integration_tests.rs +0 -0
  179. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/property_tests.rs +0 -0
  180. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/stress_tests.rs +0 -0
  181. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/test_memory_pool.rs +0 -0
  182. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/test_quantization.rs +0 -0
  183. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/test_simd_correctness.rs +0 -0
  184. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-core/tests/unit_tests.rs +0 -0
  185. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/Cargo.toml +0 -0
  186. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/examples/bench_delete_recall.rs +0 -0
  187. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/examples/bench_search_hot.rs +0 -0
  188. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/examples/mmap_674_bench.rs +0 -0
  189. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/distance.rs +0 -0
  190. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/error.rs +0 -0
  191. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/graph.rs +0 -0
  192. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/index.rs +0 -0
  193. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/lib.rs +0 -0
  194. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/pq.rs +0 -0
  195. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/src/reuse.rs +0 -0
  196. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-diskann/tests/search_allocations.rs +0 -0
  197. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/Cargo.toml +0 -0
  198. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/README.md +0 -0
  199. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/examples/diskann_real_trajectory.rs +0 -0
  200. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/examples/loss_demo.rs +0 -0
  201. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/examples/triggered_rebuild.rs +0 -0
  202. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/cold_tier.rs +0 -0
  203. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/compress.rs +0 -0
  204. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/error.rs +0 -0
  205. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/ewc.rs +0 -0
  206. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/graphmae.rs +0 -0
  207. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/layer.rs +0 -0
  208. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/lib.rs +0 -0
  209. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/mmap.rs +0 -0
  210. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/mmap_fixed.rs +0 -0
  211. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/query.rs +0 -0
  212. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/replay.rs +0 -0
  213. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/scheduler.rs +0 -0
  214. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/search.rs +0 -0
  215. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/tensor.rs +0 -0
  216. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/src/training.rs +0 -0
  217. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-gnn/tests/loss_verification.rs +0 -0
  218. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/ARCHITECTURE.md +0 -0
  219. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/Cargo.toml +0 -0
  220. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/README.md +0 -0
  221. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/cypher_parser.rs +0 -0
  222. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/distributed_query.rs +0 -0
  223. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/graph_bench.rs +0 -0
  224. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/graph_traversal.rs +0 -0
  225. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/hybrid_vector_graph.rs +0 -0
  226. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/new_capabilities_bench.rs +0 -0
  227. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/query_execution.rs +0 -0
  228. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/simd_operations.rs +0 -0
  229. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/benches/typed_graph_bench.rs +0 -0
  230. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/examples/test_cypher_parser.rs +0 -0
  231. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/bm25.rs +0 -0
  232. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/codegen.rs +0 -0
  233. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/README.md +0 -0
  234. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/ast.rs +0 -0
  235. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/lexer.rs +0 -0
  236. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/mod.rs +0 -0
  237. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/optimizer.rs +0 -0
  238. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/parser.rs +0 -0
  239. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/cypher/semantic.rs +0 -0
  240. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/coordinator.rs +0 -0
  241. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/federation.rs +0 -0
  242. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/gossip.rs +0 -0
  243. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/mod.rs +0 -0
  244. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/replication.rs +0 -0
  245. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/rpc.rs +0 -0
  246. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/distributed/shard.rs +0 -0
  247. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/edge.rs +0 -0
  248. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/embed.rs +0 -0
  249. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/error.rs +0 -0
  250. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/cache.rs +0 -0
  251. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/mod.rs +0 -0
  252. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/operators.rs +0 -0
  253. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/parallel.rs +0 -0
  254. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/pipeline.rs +0 -0
  255. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/plan.rs +0 -0
  256. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/executor/stats.rs +0 -0
  257. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/graph.rs +0 -0
  258. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/cypher_extensions.rs +0 -0
  259. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/graph_neural.rs +0 -0
  260. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/mod.rs +0 -0
  261. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/rag_integration.rs +0 -0
  262. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/semantic_search.rs +0 -0
  263. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hybrid/vector_index.rs +0 -0
  264. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/hyperedge.rs +0 -0
  265. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/index.rs +0 -0
  266. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/lib.rs +0 -0
  267. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/node.rs +0 -0
  268. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/adaptive_radix.rs +0 -0
  269. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/bloom_filter.rs +0 -0
  270. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/cache_hierarchy.rs +0 -0
  271. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/index_compression.rs +0 -0
  272. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/memory_pool.rs +0 -0
  273. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/mod.rs +0 -0
  274. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/query_jit.rs +0 -0
  275. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/optimization/simd_traversal.rs +0 -0
  276. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/schema.rs +0 -0
  277. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/storage.rs +0 -0
  278. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/transaction.rs +0 -0
  279. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/typed_graph.rs +0 -0
  280. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/src/types.rs +0 -0
  281. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/compatibility_tests.rs +0 -0
  282. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/concurrent_tests.rs +0 -0
  283. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/cypher_execution_tests.rs +0 -0
  284. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/cypher_parser_integration.rs +0 -0
  285. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/cypher_parser_tests.rs +0 -0
  286. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/distributed_tests.rs +0 -0
  287. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/edge_tests.rs +0 -0
  288. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/README.md +0 -0
  289. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/expected_results.json +0 -0
  290. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/movie_database.json +0 -0
  291. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/fixtures/social_network.json +0 -0
  292. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/hyperedge_tests.rs +0 -0
  293. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/node_tests.rs +0 -0
  294. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/performance_tests.rs +0 -0
  295. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-graph/tests/transaction_tests.rs +0 -0
  296. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/Cargo.toml +0 -0
  297. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/README.md +0 -0
  298. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/benches/information_geometry.rs +0 -0
  299. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/benches/optimal_transport.rs +0 -0
  300. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/benches/product_manifold.rs +0 -0
  301. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/benches/spectral.rs +0 -0
  302. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/benches/tropical.rs +0 -0
  303. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/error.rs +0 -0
  304. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/homology/distance.rs +0 -0
  305. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/homology/filtration.rs +0 -0
  306. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/homology/mod.rs +0 -0
  307. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/homology/persistence.rs +0 -0
  308. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/homology/simplex.rs +0 -0
  309. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/fisher.rs +0 -0
  310. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/kfac.rs +0 -0
  311. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/mod.rs +0 -0
  312. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/information_geometry/natural_gradient.rs +0 -0
  313. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/lib.rs +0 -0
  314. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/config.rs +0 -0
  315. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/gromov_wasserstein.rs +0 -0
  316. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/mod.rs +0 -0
  317. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/sinkhorn.rs +0 -0
  318. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimal_transport/sliced_wasserstein.rs +0 -0
  319. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/certificates.rs +0 -0
  320. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/mod.rs +0 -0
  321. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/polynomial.rs +0 -0
  322. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/sdp.rs +0 -0
  323. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/optimization/sos.rs +0 -0
  324. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/config.rs +0 -0
  325. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/manifold.rs +0 -0
  326. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/mod.rs +0 -0
  327. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/product_manifold/operations.rs +0 -0
  328. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/chebyshev.rs +0 -0
  329. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/clustering.rs +0 -0
  330. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/graph_filter.rs +0 -0
  331. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/mod.rs +0 -0
  332. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/spectral/wavelets.rs +0 -0
  333. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/spherical/mod.rs +0 -0
  334. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/contraction.rs +0 -0
  335. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/cp_decomposition.rs +0 -0
  336. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/mod.rs +0 -0
  337. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/tensor_train.rs +0 -0
  338. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tensor_networks/tucker.rs +0 -0
  339. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/matrix.rs +0 -0
  340. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/mod.rs +0 -0
  341. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/neural_analysis.rs +0 -0
  342. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/polynomial.rs +0 -0
  343. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/tropical/semiring.rs +0 -0
  344. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/utils/mod.rs +0 -0
  345. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/utils/numerical.rs +0 -0
  346. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-math/src/utils/sorting.rs +0 -0
  347. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/.gitignore +0 -0
  348. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/LICENSE +0 -0
  349. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/benchmarks/bench_compare_rabitq.py +0 -0
  350. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/benchmarks/bench_hnsw_real_embeddings.py +0 -0
  351. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/scripts/check-release-version.sh +0 -0
  352. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/scripts/sdist-add-patches.sh +0 -0
  353. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/cluster.rs +0 -0
  354. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/error.rs +0 -0
  355. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/gnn.rs +0 -0
  356. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/graph/convert.rs +0 -0
  357. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/graph/cypher_bridge.rs +0 -0
  358. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/graph/cypher_eval.rs +0 -0
  359. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/graph/cypher_exec.rs +0 -0
  360. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/graph.rs +0 -0
  361. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/hnsw.rs +0 -0
  362. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/lib.rs +0 -0
  363. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/src/sona.rs +0 -0
  364. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_cluster.py +0 -0
  365. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_collection.py +0 -0
  366. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_gnn.py +0 -0
  367. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_graph.py +0 -0
  368. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_graph_cypher.py +0 -0
  369. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_langchain_integration.py +0 -0
  370. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_llamaindex_integration.py +0 -0
  371. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_salesforce_integration.py +0 -0
  372. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_salesforce_routes.py +0 -0
  373. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-py/tests/test_sona.py +0 -0
  374. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/BENCHMARK.md +0 -0
  375. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/Cargo.toml +0 -0
  376. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/benches/rabitq_bench.rs +0 -0
  377. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/error.rs +0 -0
  378. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/index.rs +0 -0
  379. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/kernel.rs +0 -0
  380. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/lib.rs +0 -0
  381. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/main.rs +0 -0
  382. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/persist.rs +0 -0
  383. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/quantize.rs +0 -0
  384. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/rotation.rs +0 -0
  385. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-rabitq/src/scan.rs +0 -0
  386. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/Cargo.toml +0 -0
  387. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/README.md +0 -0
  388. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/src/election.rs +0 -0
  389. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/src/lib.rs +0 -0
  390. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/src/log.rs +0 -0
  391. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/src/node.rs +0 -0
  392. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/src/rpc.rs +0 -0
  393. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/src/state.rs +0 -0
  394. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-raft/tests/integration_tests.rs +0 -0
  395. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/Cargo.toml +0 -0
  396. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/README.md +0 -0
  397. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/src/conflict.rs +0 -0
  398. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/src/failover.rs +0 -0
  399. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/src/lib.rs +0 -0
  400. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/src/replica.rs +0 -0
  401. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/src/stream.rs +0 -0
  402. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-replication/src/sync.rs +0 -0
  403. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/Cargo.toml +0 -0
  404. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/benches/kernels.rs +0 -0
  405. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/bits1.rs +0 -0
  406. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/codec.rs +0 -0
  407. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/lib.rs +0 -0
  408. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/rotation.rs +0 -0
  409. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/score.rs +0 -0
  410. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/simd.rs +0 -0
  411. {ruvector-0.1.0 → ruvector-0.1.2}/crates/ruvector-turboquant/src/tables.rs +0 -0
  412. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/Cargo.toml +0 -0
  413. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/LICENSE-APACHE +0 -0
  414. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/LICENSE-MIT +0 -0
  415. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/README.md +0 -0
  416. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/auto_tuner.rs +0 -0
  417. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/darwin_guard.rs +0 -0
  418. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/engine.rs +0 -0
  419. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/ewc.rs +0 -0
  420. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/export/dataset.rs +0 -0
  421. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/export/huggingface_hub.rs +0 -0
  422. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/export/mod.rs +0 -0
  423. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/export/pretrain.rs +0 -0
  424. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/export/safetensors.rs +0 -0
  425. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/lib.rs +0 -0
  426. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/loops/background.rs +0 -0
  427. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/loops/coordinator.rs +0 -0
  428. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/loops/instant.rs +0 -0
  429. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/loops/mod.rs +0 -0
  430. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/lora.rs +0 -0
  431. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/mod.rs +0 -0
  432. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/napi.rs +0 -0
  433. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/napi_simple.rs +0 -0
  434. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/reasoning_bank.rs +0 -0
  435. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/time_compat.rs +0 -0
  436. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/training/factory.rs +0 -0
  437. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/training/federated.rs +0 -0
  438. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/training/metrics.rs +0 -0
  439. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/training/mod.rs +0 -0
  440. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/training/pipeline.rs +0 -0
  441. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/training/templates.rs +0 -0
  442. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/trajectory.rs +0 -0
  443. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/types.rs +0 -0
  444. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/src/wasm.rs +0 -0
  445. {ruvector-0.1.0 → ruvector-0.1.2}/crates/sona/wasm-example/README.md +0 -0
  446. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/.gitignore +0 -0
  447. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/Cargo.toml +0 -0
  448. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/Changes.md +0 -0
  449. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/LICENSE-APACHE +0 -0
  450. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/LICENSE-MIT +0 -0
  451. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/README.md +0 -0
  452. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/ann-glove25-angular.rs +0 -0
  453. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/ann-mnist-784-euclidean.rs +0 -0
  454. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/ann-sift1m-128-euclidean.rs +0 -0
  455. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/levensthein.rs +0 -0
  456. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/random.rs +0 -0
  457. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/utils/annhdf5.rs +0 -0
  458. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/examples/utils/mod.rs +0 -0
  459. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/api.rs +0 -0
  460. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/datamap.rs +0 -0
  461. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/filter.rs +0 -0
  462. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/flatten.rs +0 -0
  463. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/hnsw.rs +0 -0
  464. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/hnswio.rs +0 -0
  465. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/lib.rs +0 -0
  466. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/libext.rs +0 -0
  467. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/src/prelude.rs +0 -0
  468. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/tests/deallocation_test.rs +0 -0
  469. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/tests/filtertest.rs +0 -0
  470. {ruvector-0.1.0 → ruvector-0.1.2}/patches/hnsw_rs/tests/serpar.rs +0 -0
  471. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/__init__.py +0 -0
  472. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/__init__.pyi +0 -0
  473. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/collection.py +0 -0
  474. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/integrations/__init__.py +0 -0
  475. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/integrations/langchain.py +0 -0
  476. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/integrations/llamaindex.py +0 -0
  477. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/integrations/salesforce.py +0 -0
  478. {ruvector-0.1.0 → ruvector-0.1.2}/python/ruvector/py.typed +0 -0
  479. {ruvector-0.1.0 → 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.0"
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.0
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
@@ -9,6 +9,7 @@ Classifier: Programming Language :: Python :: 3.10
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
11
  Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
12
13
  Classifier: Programming Language :: Python :: Implementation :: CPython
13
14
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
15
  Classifier: Topic :: Database :: Database Engines/Servers
@@ -136,6 +137,7 @@ ruvector benchmark -n 100000 --dim 128 # in-process latency/QPS, no external
136
137
  ruvector serve # MCP server over stdio
137
138
  ruvector serve --http --port 8420 # MCP server over streamable-HTTP (loopback)
138
139
  ruvector serve --read-only # no create/insert/delete tools
140
+ ruvector serve --max-vectors 50000 # cap vectors per collection (default 1,000,000)
139
141
  ```
140
142
 
141
143
  `serve --http` on a non-loopback `--host` refuses to start unless
@@ -161,6 +163,16 @@ directory-traversal surface regardless of what a remote MCP client sends.
161
163
  See `ruvector/mcp_server.py`'s module docstring for the full security
162
164
  model.
163
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
+
164
176
  ```sh
165
177
  # point an MCP client at: ruvector serve (stdio)
166
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.0"
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
@@ -12,6 +12,7 @@
12
12
  //! and `RabitqAsymIndex` as separate Python classes per the surface sketch in
13
13
  //! `docs/sdk/03-api-surface.md`. M1 ships exactly one class.
14
14
 
15
+ use std::collections::HashSet;
15
16
  use std::fs::File;
16
17
  use std::io::{BufReader, BufWriter};
17
18
 
@@ -50,6 +51,53 @@ pub struct RabitqIndex {
50
51
  // to keep a redundant copy here. The seed lives separately because
51
52
  // `RabitqPlusIndex` doesn't expose its own seed field.
52
53
  seed: u64,
54
+ // Ids currently in the index, so `add`/`add_batch` can reject a duplicate in O(1).
55
+ ids: HashSet<u32>,
56
+ }
57
+
58
+ /// Describe a Python object for an error message (dtype and ndim when it is an array).
59
+ fn describe(obj: &Bound<'_, PyAny>) -> String {
60
+ match (obj.getattr("dtype"), obj.getattr("ndim")) {
61
+ (Ok(d), Ok(n)) => format!("dtype={d}, ndim={n}"),
62
+ _ => obj
63
+ .get_type()
64
+ .name()
65
+ .map(|n| n.to_string())
66
+ .unwrap_or_else(|_| "an unknown object".into()),
67
+ }
68
+ }
69
+
70
+ fn arr1<'py>(obj: &Bound<'py, PyAny>, name: &str) -> PyResult<PyReadonlyArray1<'py, f32>> {
71
+ obj.extract().map_err(|_| {
72
+ PyTypeError::new_err(format!(
73
+ "{name} must be a 1D float32 NumPy array, got {}; convert with np.ascontiguousarray(x, dtype=np.float32)",
74
+ describe(obj)
75
+ ))
76
+ })
77
+ }
78
+
79
+ fn arr2<'py>(obj: &Bound<'py, PyAny>, name: &str) -> PyResult<PyReadonlyArray2<'py, f32>> {
80
+ obj.extract().map_err(|_| {
81
+ PyTypeError::new_err(format!(
82
+ "{name} must be a 2D float32 NumPy array, got {}; convert with np.ascontiguousarray(x, dtype=np.float32)",
83
+ describe(obj)
84
+ ))
85
+ })
86
+ }
87
+
88
+ /// Reject NaN and infinity, which would otherwise be indexed or searched and yield NaN scores.
89
+ fn check_finite(data: &[f32], dim: usize, name: &str) -> PyResult<()> {
90
+ match data.iter().position(|x| !x.is_finite()) {
91
+ None => Ok(()),
92
+ Some(i) if dim > 0 && data.len() > dim => Err(PyValueError::new_err(format!(
93
+ "{name} contains a non-finite value (NaN or inf) at row {}, column {}",
94
+ i / dim,
95
+ i % dim
96
+ ))),
97
+ Some(i) => Err(PyValueError::new_err(format!(
98
+ "{name} contains a non-finite value (NaN or inf) at position {i}"
99
+ ))),
100
+ }
53
101
  }
54
102
 
55
103
  #[pymethods]
@@ -61,8 +109,15 @@ impl RabitqIndex {
61
109
  /// silently copying — silent copies would be an O(n·dim) surprise on a
62
110
  /// "fast" build call.
63
111
  ///
64
- /// `rerank_factor` defaults to 20 per `docs/sdk/03-api-surface.md`'s
65
- /// "100% recall@10 at D=128" recommendation citing ADR-154.
112
+ /// `rerank_factor` defaults to 20. Recall depends on the data: ADR-154
113
+ /// reports 100% recall@10 at D=128 on clustered, embedding-like data, but
114
+ /// on isotropic Gaussian vectors (D=128, n=10k) a rerank_factor of 20 gives
115
+ /// about 0.63 recall@10 and 500 is needed for 1.0. Raise `rerank_factor`
116
+ /// (here or per `search` call) for hard distributions and measure recall
117
+ /// against brute force on your own data.
118
+ ///
119
+ /// Raises `ValueError` if `vectors` contains NaN or infinity, or if `ids`
120
+ /// contains a duplicate.
66
121
  ///
67
122
  /// `seed` defaults to 42 to keep the build deterministic out-of-the-box —
68
123
  /// the doc-comment guarantee on `ruvector_rabitq` is that
@@ -81,11 +136,12 @@ impl RabitqIndex {
81
136
  #[pyo3(signature = (vectors, *, ids = None, rerank_factor = 20, seed = 42))]
82
137
  fn build(
83
138
  py: Python<'_>,
84
- vectors: PyReadonlyArray2<'_, f32>,
139
+ vectors: &Bound<'_, PyAny>,
85
140
  ids: Option<PyReadonlyArray1<'_, u64>>,
86
141
  rerank_factor: u32,
87
142
  seed: u64,
88
143
  ) -> PyResult<Self> {
144
+ let vectors = arr2(vectors, "vectors")?;
89
145
  // Validate the dtype/contig invariants up front. `PyReadonlyArray2`
90
146
  // already guarantees the dtype is f32 (otherwise the conversion at
91
147
  // the call site fails with `TypeError`). What it does NOT guarantee
@@ -122,6 +178,7 @@ impl RabitqIndex {
122
178
  // across rayon workers. PyO3 cannot give us mutable owned access
123
179
  // to NumPy storage without breaking the readonly contract.
124
180
  let slice = vectors.as_slice()?; // contiguous view, len = n*dim
181
+ check_finite(slice, dim, "vectors")?;
125
182
  let mut items: Vec<(usize, Vec<f32>)> = Vec::with_capacity(n);
126
183
  match ids {
127
184
  Some(ids_arr) => {
@@ -145,6 +202,12 @@ impl RabitqIndex {
145
202
  )));
146
203
  }
147
204
  }
205
+ let mut seen = HashSet::with_capacity(ids_slice.len());
206
+ for &id in ids_slice {
207
+ if !seen.insert(id) {
208
+ return Err(PyValueError::new_err(format!("duplicate id {id} in ids")));
209
+ }
210
+ }
148
211
  for (i, &id) in ids_slice.iter().enumerate() {
149
212
  let row = &slice[i * dim..(i + 1) * dim];
150
213
  items.push((id as usize, row.to_vec()));
@@ -168,7 +231,8 @@ impl RabitqIndex {
168
231
  })
169
232
  .map_err(to_pyerr)?;
170
233
 
171
- Ok(Self { inner, seed })
234
+ let ids = inner.ids_u64().into_iter().map(|i| i as u32).collect();
235
+ Ok(Self { inner, seed, ids })
172
236
  }
173
237
 
174
238
  /// Search for the `k` nearest neighbours of a single `query` vector.
@@ -185,10 +249,11 @@ impl RabitqIndex {
185
249
  fn search(
186
250
  &self,
187
251
  py: Python<'_>,
188
- query: PyReadonlyArray1<'_, f32>,
252
+ query: &Bound<'_, PyAny>,
189
253
  k: usize,
190
254
  rerank_factor: Option<u32>,
191
255
  ) -> PyResult<Vec<(u32, f32)>> {
256
+ let query = arr1(query, "query")?;
192
257
  if !query.is_c_contiguous() {
193
258
  return Err(PyTypeError::new_err(
194
259
  "query must be C-contiguous; pass np.ascontiguousarray(...) first",
@@ -198,6 +263,7 @@ impl RabitqIndex {
198
263
  return Err(PyValueError::new_err("k must be > 0"));
199
264
  }
200
265
  let q = query.as_slice()?;
266
+ check_finite(q, 0, "query")?;
201
267
 
202
268
  // `search_with_rerank` is the right entry point even when no
203
269
  // override is requested, because it is the common path the
@@ -263,7 +329,8 @@ impl RabitqIndex {
263
329
  let seed = u64::from_le_bytes(header[16..24].try_into().unwrap());
264
330
 
265
331
  let inner = persist::load_index(&mut r).map_err(to_pyerr)?;
266
- Ok(Self { inner, seed })
332
+ let ids = inner.ids_u64().into_iter().map(|i| i as u32).collect();
333
+ Ok(Self { inner, seed, ids })
267
334
  }
268
335
 
269
336
  /// Number of indexed vectors (matches `AnnIndex::len`).
@@ -303,7 +370,8 @@ impl RabitqIndex {
303
370
  /// release/reacquire cost itself (same call made for `RabitqPlusIndex.add`
304
371
  /// in `docs/sdk/02-strategy.md`'s GIL table). Use `add_batch` for bulk
305
372
  /// inserts, which does release the GIL.
306
- fn add(&mut self, id: u32, vector: PyReadonlyArray1<'_, f32>) -> PyResult<()> {
373
+ fn add(&mut self, id: u32, vector: &Bound<'_, PyAny>) -> PyResult<()> {
374
+ let vector = arr1(vector, "vector")?;
307
375
  if !vector.is_c_contiguous() {
308
376
  return Err(PyTypeError::new_err(
309
377
  "vector must be C-contiguous; pass np.ascontiguousarray(...) first",
@@ -317,7 +385,14 @@ impl RabitqIndex {
317
385
  v.len()
318
386
  )));
319
387
  }
388
+ check_finite(v, 0, "vector")?;
389
+ if self.ids.contains(&id) {
390
+ return Err(PyValueError::new_err(format!(
391
+ "id {id} is already in the index; ids must be unique"
392
+ )));
393
+ }
320
394
  self.inner.add(id as usize, v.to_vec()).map_err(to_pyerr)?;
395
+ self.ids.insert(id);
321
396
  Ok(())
322
397
  }
323
398
 
@@ -328,8 +403,9 @@ impl RabitqIndex {
328
403
  &mut self,
329
404
  py: Python<'_>,
330
405
  ids: PyReadonlyArray1<'_, u64>,
331
- vectors: PyReadonlyArray2<'_, f32>,
406
+ vectors: &Bound<'_, PyAny>,
332
407
  ) -> PyResult<()> {
408
+ let vectors = arr2(vectors, "vectors")?;
333
409
  if !vectors.is_c_contiguous() {
334
410
  return Err(PyTypeError::new_err(
335
411
  "vectors must be C-contiguous; pass np.ascontiguousarray(...) first",
@@ -371,6 +447,15 @@ impl RabitqIndex {
371
447
  }
372
448
  }
373
449
  let vecs_slice = vectors.as_slice()?;
450
+ check_finite(vecs_slice, dim, "vectors")?;
451
+ let mut batch_ids = HashSet::with_capacity(ids_slice.len());
452
+ for &id in &ids_slice {
453
+ if self.ids.contains(&(id as u32)) || !batch_ids.insert(id) {
454
+ return Err(PyValueError::new_err(format!(
455
+ "id {id} is already in the index or repeated in the batch; ids must be unique"
456
+ )));
457
+ }
458
+ }
374
459
  let rows: Vec<(usize, Vec<f32>)> = (0..n)
375
460
  .map(|i| {
376
461
  (
@@ -387,6 +472,7 @@ impl RabitqIndex {
387
472
  Ok(())
388
473
  })
389
474
  .map_err(to_pyerr)?;
475
+ self.ids.extend(batch_ids.into_iter().map(|i| i as u32));
390
476
  Ok(())
391
477
  }
392
478
 
@@ -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
@@ -499,3 +499,107 @@ def test_apply_read_only_removes_mutating_tools(tmp_path: Path, monkeypatch: pyt
499
499
  _call(m, gone, name="x")
500
500
  finally:
501
501
  importlib.reload(m)
502
+
503
+
504
+ def test_validation_errors_reach_the_client():
505
+ """mcp 2.x masks non-ToolError exceptions; our validation messages must get through (issue #1134)."""
506
+ import asyncio
507
+
508
+ from mcp.server.mcpserver.exceptions import ToolError
509
+
510
+ from ruvector import mcp_server as m
511
+
512
+ async def call(name, args):
513
+ return await m.server.call_tool(name, args)
514
+
515
+ try:
516
+ asyncio.run(call("vector_create_collection", {"name": "../escape", "dim": 4}))
517
+ except ToolError as e:
518
+ assert "invalid collection name" in str(e)
519
+ else:
520
+ raise AssertionError("expected ToolError")
521
+ try:
522
+ asyncio.run(call("vector_search", {"name": "no-such-collection", "query": [1.0, 2.0, 3.0, 4.0], "k": 1}))
523
+ except ToolError as e:
524
+ assert "no such collection" in str(e)
525
+ else:
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