mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-05-25 15:03:46 +00:00
First milestone of the ruvector Python SDK per
docs/sdk/04-milestones.md § "M1 — RaBitQ-only Python wheel". A new
workspace crate `crates/ruvector-py/` exposes ruvector-rabitq as a
Python extension module via PyO3 + maturin with an abi3-py39 wheel
target.
## Surface
```python
import numpy as np
import ruvector
vectors = np.random.randn(10_000, 768).astype(np.float32)
idx = ruvector.RabitqIndex.build(vectors, rerank_factor=20)
results = idx.search(vectors[0], k=10) # → list[(id, distance)]
idx.save("vectors.rbpx")
idx2 = ruvector.RabitqIndex.load("vectors.rbpx")
```
## What ships
- `Cargo.toml`: cdylib crate, pyo3 0.22 with `extension-module` +
`abi3-py39`, numpy 0.22, path dep on `ruvector-rabitq`.
- `pyproject.toml`: maturin build backend, `python-source = "python"`,
`module-name = "ruvector._native"`. PyPI name: `ruvector`.
- `src/lib.rs`: defines the `_native` Python module, registers the
`RabitqIndex` class and `RuVectorError` exception.
- `src/rabitq.rs`: `RabitqIndex` wrapping `RabitqPlusIndex` with
`build` / `search` / `save` / `load` / `__len__` / `__repr__`.
All hot paths release the GIL via `py.allow_threads`.
- `src/error.rs`: maps `RabitqError` → `RuVectorError(PyException)`.
- `python/ruvector/__init__.py`: thin re-export shim from `_native`.
- `python/ruvector/py.typed`: PEP 561 marker.
- Type stubs: `python/ruvector/__init__.pyi` + `stubs/ruvector/__init__.pyi`.
- `tests/test_smoke.py`: pytest coverage of build/search/save/load,
dimension-mismatch error, len/repr, abi3 marker.
- `README.md`: install instructions + 30-second example.
## Real ruvector-rabitq API used
The plan's M1 sketch matched closely. Concrete surface:
- `RabitqPlusIndex::from_vectors_parallel(dim, seed, rerank_factor, items)`
— used in `build()`. Added `seed` kwarg (default 42) since the ctor
requires it.
- `idx.search_with_rerank(query, k, rerank_factor) -> Vec<SearchResult>`
— used in `search()`.
- `persist::save_index` / `persist::load_index` / `persist::MAGIC`
— `.rbpx` v1 wire format. `load()` peeks the 24-byte header to
recover the seed before calling `load_index`.
- `idx.export_items()` — used in `save()` because the seed-based
format needs the items handed back; `RabitqPlusIndex` doesn't
expose `originals_flat` directly.
## Verification
cargo build -p ruvector-py → clean
cargo clippy -p ruvector-py --all-targets --no-deps -- -D warnings → exit 0
cargo test -p ruvector-py → 0 tests, 0 failed (no Rust unit
tests yet; logic is in PyO3
methods that need the Python
interpreter)
`maturin develop` + `pytest` + `mypy --strict` not run — the
sandbox doesn't have those binaries. The Python tests are written
to the M1 acceptance shape and will run as soon as maturin is
present in the dev env.
## Deviations from the M1 plan (docs/sdk/04-milestones.md)
1. One `RabitqIndex` class instead of the plan's four
(`FlatF32Index`, `RabitqIndex`, `RabitqPlusIndex`, `RabitqAsymIndex`).
Adding the others is mechanical follow-up — same register pattern.
2. Single `RuVectorError` exception instead of the subclass tree
(`DimensionMismatch`, `EmptyIndex`, `PersistError`). Subclasses
are M2+ scope per the plan.
3. No `_typing.py`, no `_version.py`. `__version__` sourced from
`env!("CARGO_PKG_VERSION")` via the compiled module.
4. No CI workflow, no Sphinx, no notebook — deferred. Scoped to
"everything needed for pip install to work".
5. `build()` takes a `seed` kwarg (default 42) — not in the M1
sketch but required by the underlying ctor.
## Two pyo3 0.22 quirks worth flagging
- `pyo3::create_exception!` macro emits `cfg(feature = "gil-refs")`
unexpected_cfg warnings. Worked around with `#![allow(unexpected_cfgs)]`
at crate root, comment explains the upstream issue.
- `#[pymethods]` macro expansion triggers
`clippy::useless_conversion` false-positives on `?`-on-PyResult.
Suppressed at crate root with comment.
LoC total: 881 (Cargo.lock excluded; 768 source + 113 lockfile drift).
M1 plan budgeted ~1300 — under because we shipped the user-requested
single-class scope, not the plan's full surface.
Refs: docs/sdk/04-milestones.md M1, docs/sdk/02-strategy.md
Co-Authored-By: claude-flow <ruv@ruv.net>
306 lines
10 KiB
TOML
306 lines
10 KiB
TOML
[workspace]
|
|
exclude = ["crates/micro-hnsw-wasm", "crates/ruvector-hyperbolic-hnsw", "crates/ruvector-hyperbolic-hnsw-wasm", "examples/ruvLLM/esp32", "examples/ruvLLM/esp32-flash", "examples/edge-net", "examples/data", "examples/ruvLLM", "examples/delta-behavior", "crates/rvf", "crates/rvf/*", "crates/rvf/*/*", "examples/rvf-desktop", "crates/mcp-brain-server",
|
|
# ruvector-postgres is a pgrx-based PostgreSQL extension. Its build script
|
|
# requires `$PGRX_HOME` set up via `cargo install cargo-pgrx --version 0.12.9`
|
|
# and `cargo pgrx init`, which downloads and builds multiple Postgres
|
|
# versions. Keep it out of default workspace builds so `cargo build --workspace`
|
|
# works in stock environments. Build it explicitly with `cargo build -p ruvector-postgres`
|
|
# after running pgrx init.
|
|
"crates/ruvector-postgres"]
|
|
members = [
|
|
"crates/ruvector-rabitq",
|
|
"crates/ruvector-rulake",
|
|
"crates/ruvector-core",
|
|
"crates/ruvector-node",
|
|
"crates/ruvector-wasm",
|
|
"crates/ruvector-cli",
|
|
"crates/ruvector-bench",
|
|
"crates/ruvector-metrics",
|
|
"crates/ruvector-filter",
|
|
"crates/ruvector-router-core",
|
|
"crates/ruvector-router-cli",
|
|
"crates/ruvector-router-ffi",
|
|
"crates/ruvector-router-wasm",
|
|
"crates/ruvector-server",
|
|
"crates/ruvector-snapshot",
|
|
"crates/ruvector-tiny-dancer-core",
|
|
"crates/ruvector-tiny-dancer-wasm",
|
|
"crates/ruvector-tiny-dancer-node",
|
|
"crates/ruvector-collections",
|
|
"crates/ruvector-cluster",
|
|
"crates/ruvector-raft",
|
|
"crates/ruvector-replication",
|
|
"crates/ruvector-graph",
|
|
"crates/ruvector-graph-node",
|
|
"crates/ruvector-graph-wasm",
|
|
"crates/ruvector-gnn",
|
|
"crates/ruvector-gnn-node",
|
|
"crates/ruvector-gnn-wasm",
|
|
"crates/ruvector-attention",
|
|
"crates/ruvector-attention-wasm",
|
|
"crates/ruvector-attention-node",
|
|
"crates/ruvector-cnn",
|
|
"crates/ruvector-cnn-wasm",
|
|
"crates/ruvector-mincut",
|
|
"crates/ruvector-mincut-wasm",
|
|
"crates/ruvector-mincut-node",
|
|
"crates/ruvector-mincut-gated-transformer",
|
|
"crates/ruvector-mincut-gated-transformer-wasm",
|
|
# NOTE: ruvector-postgres is in workspace `exclude` (pgrx env requirement).
|
|
"crates/ruvector-nervous-system",
|
|
"examples/refrag-pipeline",
|
|
"examples/scipix",
|
|
"examples/google-cloud",
|
|
"examples/subpolynomial-time",
|
|
"crates/sona",
|
|
"crates/rvlite",
|
|
"crates/ruvector-nervous-system",
|
|
"crates/ruvector-dag",
|
|
"crates/ruvector-dag-wasm",
|
|
"crates/ruvector-nervous-system-wasm",
|
|
"crates/ruvector-economy-wasm",
|
|
"crates/ruvector-learning-wasm",
|
|
"crates/ruvector-exotic-wasm",
|
|
"crates/ruvector-attention-unified-wasm",
|
|
"crates/ruvector-fpga-transformer",
|
|
"crates/ruvector-fpga-transformer-wasm",
|
|
"crates/ruvector-sparse-inference",
|
|
"crates/ruvector-math",
|
|
"crates/ruvector-math-wasm",
|
|
"examples/benchmarks",
|
|
"crates/cognitum-gate-kernel",
|
|
"crates/cognitum-gate-tilezero",
|
|
"crates/mcp-gate",
|
|
"crates/mcp-brain",
|
|
"crates/mcp-brain-server",
|
|
"crates/ruQu",
|
|
"crates/ruvllm",
|
|
"crates/ruvllm-cli",
|
|
"crates/ruvllm-wasm",
|
|
"crates/prime-radiant",
|
|
"crates/ruvector-delta-core",
|
|
"crates/ruvector-delta-wasm",
|
|
"crates/ruvector-delta-index",
|
|
"crates/ruvector-delta-graph",
|
|
"crates/ruvector-delta-consensus",
|
|
"crates/ruvector-crv",
|
|
"crates/ruvector-temporal-tensor",
|
|
"crates/ruqu-core",
|
|
"crates/ruqu-algorithms",
|
|
"crates/ruqu-wasm",
|
|
"crates/ruqu-exotic",
|
|
"crates/ruvector-domain-expansion",
|
|
"crates/ruvector-domain-expansion-wasm",
|
|
"crates/ruvector-solver",
|
|
"crates/ruvector-solver-wasm",
|
|
"crates/ruvector-solver-node",
|
|
"examples/dna",
|
|
"examples/OSpipe",
|
|
"crates/ruvector-coherence",
|
|
"crates/ruvector-profiler",
|
|
# Python SDK — M1 (RaBitQ-only). See docs/sdk/04-milestones.md.
|
|
"crates/ruvector-py",
|
|
"crates/ruvector-attn-mincut",
|
|
"crates/ruvector-cognitive-container",
|
|
"crates/ruvector-verified",
|
|
"crates/ruvector-verified-wasm",
|
|
"crates/ruvector-graph-transformer",
|
|
"crates/ruvector-graph-transformer-wasm",
|
|
"crates/ruvector-graph-transformer-node",
|
|
"examples/rvf-kernel-optimized",
|
|
"examples/verified-applications",
|
|
"crates/thermorust",
|
|
"crates/ruvector-dither",
|
|
"crates/ruvector-robotics",
|
|
"examples/robotics",
|
|
"crates/neural-trader-core",
|
|
"crates/neural-trader-coherence",
|
|
"crates/neural-trader-replay",
|
|
"crates/neural-trader-wasm",
|
|
# Kalshi integration (ADR-153)
|
|
"crates/ruvector-kalshi",
|
|
"crates/neural-trader-strategies",
|
|
# RuVix Cognition Kernel (organized under crates/ruvix/)
|
|
"crates/ruvix/crates/types",
|
|
"crates/ruvix/crates/region",
|
|
"crates/ruvix/crates/queue",
|
|
"crates/ruvix/crates/cap",
|
|
"crates/ruvix/crates/proof",
|
|
"crates/ruvix/crates/sched",
|
|
"crates/ruvix/crates/boot",
|
|
"crates/ruvix/crates/vecgraph",
|
|
"crates/ruvix/crates/nucleus",
|
|
# Phase B: Bare metal AArch64 support
|
|
"crates/ruvix/crates/hal",
|
|
"crates/ruvix/crates/aarch64",
|
|
"crates/ruvix/crates/drivers",
|
|
"crates/ruvix/tests",
|
|
"crates/ruvix/benches",
|
|
"crates/ruvix/examples/cognitive_demo",
|
|
# rvAgent — AI Agent Framework (DeepAgents Rust conversion)
|
|
"crates/rvAgent/rvagent-core",
|
|
"crates/rvAgent/rvagent-backends",
|
|
"crates/rvAgent/rvagent-middleware",
|
|
"crates/rvAgent/rvagent-tools",
|
|
"crates/rvAgent/rvagent-subagents",
|
|
"crates/rvAgent/rvagent-cli",
|
|
"crates/rvAgent/rvagent-acp",
|
|
"crates/rvAgent/rvagent-mcp",
|
|
"crates/rvAgent/rvagent-wasm",
|
|
"crates/rvAgent/rvagent-a2a",
|
|
# ADR-159 a2a-swarm demo
|
|
"examples/a2a-swarm",
|
|
# ETL pipeline example
|
|
"examples/train-discoveries",
|
|
# Spectral graph sparsification
|
|
"crates/ruvector-sparsifier",
|
|
"crates/ruvector-sparsifier-wasm",
|
|
# Consciousness metrics (IIT Φ, causal emergence)
|
|
"crates/ruvector-consciousness",
|
|
"crates/ruvector-consciousness-wasm",
|
|
"examples/cmb-consciousness",
|
|
"examples/gw-consciousness",
|
|
"examples/ecosystem-consciousness",
|
|
"examples/quantum-consciousness",
|
|
"examples/gene-consciousness",
|
|
"examples/climate-consciousness",
|
|
# JS bundle decompiler (ADR-135)
|
|
"crates/ruvector-decompiler",
|
|
"crates/ruvector-decompiler-wasm",
|
|
# DiskANN / Vamana (ADR-143)
|
|
"crates/ruvector-diskann",
|
|
"crates/ruvector-diskann-node",
|
|
# Boundary-first scientific discovery PoC
|
|
"examples/boundary-discovery",
|
|
# CMB Cold Spot boundary-first discovery
|
|
"examples/cmb-boundary-discovery",
|
|
# FRB population boundary discovery (CHIME-like data)
|
|
"examples/frb-boundary-discovery",
|
|
# Cosmic void boundary information content
|
|
"examples/void-boundary-discovery",
|
|
# Multi-regime temporal attractor boundary detection
|
|
"examples/temporal-attractor-discovery",
|
|
# Music genre boundary discovery via spectral graph bisection
|
|
"examples/music-boundary-discovery",
|
|
# Weather regime boundary detection (variance/correlation precedes temperature)
|
|
"examples/weather-boundary-discovery",
|
|
# Market regime boundary discovery via correlation structure
|
|
"examples/market-boundary-discovery",
|
|
# Health state boundary detection from wearable sensor data
|
|
"examples/health-boundary-discovery",
|
|
# SETI exotic signals gallery: boundary-first detection of sub-threshold signals
|
|
"examples/seti-exotic-signals",
|
|
# SETI boundary-first discovery: sub-noise signal detection via coherence graphs
|
|
"examples/seti-boundary-discovery",
|
|
# Earthquake precursor detection via inter-station correlation boundary shifts
|
|
"examples/earthquake-boundary-discovery",
|
|
# Pandemic outbreak detection 60 days before case counts via correlation boundaries
|
|
"examples/pandemic-boundary-discovery",
|
|
# Infrastructure failure prediction via sensor correlation boundaries
|
|
"examples/infrastructure-boundary-discovery",
|
|
# Pre-seizure detection via brain correlation boundary shifts
|
|
"examples/brain-boundary-discovery",
|
|
# Clinical-publication-grade pre-seizure detection report with CSV output
|
|
"examples/seizure-clinical-report",
|
|
# Closed-loop seizure detection + therapeutic response simulation
|
|
"examples/seizure-therapeutic-sim",
|
|
# Real EEG analysis: CHB-MIT PhysioNet data with boundary-first detection
|
|
"examples/real-eeg-analysis",
|
|
# Multi-seizure cross-patient analysis: all 7 chb01 seizures
|
|
"examples/real-eeg-multi-seizure",
|
|
]
|
|
resolver = "2"
|
|
|
|
[workspace.package]
|
|
version = "2.2.0"
|
|
edition = "2021"
|
|
rust-version = "1.77"
|
|
license = "MIT"
|
|
authors = ["Ruvector Team"]
|
|
repository = "https://github.com/ruvnet/ruvector"
|
|
|
|
[workspace.dependencies]
|
|
# Core functionality
|
|
redb = "2.1"
|
|
memmap2 = "0.9"
|
|
hnsw_rs = "0.3"
|
|
simsimd = "5.9"
|
|
rayon = "1.10"
|
|
crossbeam = "0.8"
|
|
|
|
# Serialization
|
|
rkyv = "0.8"
|
|
bincode = { version = "2.0.0-rc.3", features = ["serde"] }
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
|
|
# Node.js bindings
|
|
napi = { version = "2.16", default-features = false, features = ["napi9", "async", "tokio_rt"] }
|
|
napi-derive = "2.16"
|
|
|
|
# WASM
|
|
wasm-bindgen = "0.2"
|
|
wasm-bindgen-futures = "0.4"
|
|
js-sys = "0.3"
|
|
web-sys = { version = "0.3", features = ["Worker", "MessagePort", "console"] }
|
|
getrandom = { version = "0.3", features = ["wasm_js"] }
|
|
|
|
# Async runtime
|
|
tokio = { version = "1.41", features = ["rt-multi-thread", "sync", "macros"] }
|
|
futures = "0.3"
|
|
|
|
# Error handling and utilities
|
|
thiserror = "2.0"
|
|
anyhow = "1.0"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
|
|
# Math and numerics
|
|
nalgebra = { version = "0.33", default-features = false, features = ["std"] }
|
|
ndarray = "0.16"
|
|
rand = "0.8"
|
|
rand_distr = "0.4"
|
|
|
|
# Time and UUID
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
uuid = { version = "1.11", features = ["v4", "serde", "js"] }
|
|
|
|
# CLI
|
|
clap = { version = "4.5", features = ["derive", "cargo"] }
|
|
indicatif = "0.17"
|
|
console = "0.15"
|
|
|
|
# Testing and benchmarking
|
|
criterion = { version = "0.5", features = ["html_reports"] }
|
|
proptest = "1.5"
|
|
mockall = "0.13"
|
|
|
|
# Formal verification
|
|
lean-agentic = "=0.1.0"
|
|
|
|
# Performance
|
|
dashmap = "6.1"
|
|
parking_lot = "0.12"
|
|
once_cell = "1.20"
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "fat"
|
|
codegen-units = 1
|
|
strip = true
|
|
panic = "unwind"
|
|
|
|
[profile.bench]
|
|
inherits = "release"
|
|
debug = true
|
|
|
|
[profile.dev]
|
|
opt-level = 0
|
|
debug = true
|
|
|
|
[profile.test]
|
|
|
|
# Patch hnsw_rs to use rand 0.8 instead of 0.9 for WASM compatibility
|
|
# This resolves the getrandom version conflict (0.2 vs 0.3)
|
|
[patch.crates-io]
|
|
hnsw_rs = { path = "./patches/hnsw_rs" }
|