diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae12427..9af8c37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,12 @@ jobs: release-build: name: Release Build (${{ matrix.target }}) runs-on: ${{ matrix.os }} - if: github.ref == 'refs/heads/main' + # Run on main pushes AND on PRs that touch workflows, Cargo manifests, or + # crate sources — so Intel Mac / Linux release targets are validated + # before merge, not after. + if: | + github.ref == 'refs/heads/main' || + github.event_name == 'pull_request' needs: [test] strategy: fail-fast: false @@ -59,9 +64,12 @@ jobs: - os: macos-latest target: aarch64-apple-darwin cargo_flags: "" - # x86_64-apple-darwin dropped: ort-sys has no prebuilt ONNX Runtime - # binaries for Intel Mac, and the codebase requires embeddings. - # Apple discontinued Intel Macs in 2020. Build from source if needed. + # Intel Mac builds against a system ONNX Runtime via ort-dynamic + # (ort-sys has no x86_64-apple-darwin prebuilts). Compile-only here; + # runtime linking is a user concern documented in INSTALL-INTEL-MAC.md. + - os: macos-latest + target: x86_64-apple-darwin + cargo_flags: "--no-default-features --features ort-dynamic,vector-search" - os: ubuntu-latest target: x86_64-unknown-linux-gnu cargo_flags: "" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1fb8639..6315588 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,17 +27,21 @@ jobs: os: ubuntu-latest archive: tar.gz cargo_flags: "" + needs_onnxruntime: false - target: x86_64-pc-windows-msvc os: windows-latest archive: zip cargo_flags: "" - # Intel Mac (x86_64-apple-darwin) is explicitly unsupported: the - # upstream ort-sys 2.0.0-rc.11 pinned by fastembed 5.13.2 does not - # ship Intel Mac prebuilts, and the v2.0.5 + v2.0.6 release - # workflows both failed this job. Matches ci.yml which already - # dropped the target. README documents the build-from-source path - # for Intel Mac users. When ort-sys ships Intel Mac prebuilts - # again, restore the entry. + needs_onnxruntime: false + # Intel Mac uses the ort-dynamic feature to runtime-link against a + # system libonnxruntime (Homebrew), sidestepping the missing + # x86_64-apple-darwin prebuilts in ort-sys 2.0.0-rc.11. Binary + # consumers must `brew install onnxruntime` before running — see + # INSTALL-INTEL-MAC.md bundled in the tarball. + - target: x86_64-apple-darwin + os: macos-latest + archive: tar.gz + cargo_flags: "--no-default-features --features ort-dynamic,vector-search" - target: aarch64-apple-darwin os: macos-latest archive: tar.gz @@ -58,8 +62,13 @@ jobs: - name: Package (Unix) if: matrix.os != 'windows-latest' run: | + cp docs/INSTALL-INTEL-MAC.md target/${{ matrix.target }}/release/ 2>/dev/null || true cd target/${{ matrix.target }}/release - tar -czf ../../../vestige-mcp-${{ matrix.target }}.tar.gz vestige-mcp vestige vestige-restore + if [ "${{ matrix.target }}" = "x86_64-apple-darwin" ]; then + tar -czf ../../../vestige-mcp-${{ matrix.target }}.tar.gz vestige-mcp vestige vestige-restore INSTALL-INTEL-MAC.md + else + tar -czf ../../../vestige-mcp-${{ matrix.target }}.tar.gz vestige-mcp vestige vestige-restore + fi - name: Package (Windows) if: matrix.os == 'windows-latest' diff --git a/README.md b/README.md index 33ab89b..3418ef3 100644 --- a/README.md +++ b/README.md @@ -80,12 +80,24 @@ curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige- sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/ ``` -**macOS (Intel) and Windows:** Prebuilt binaries aren't currently shipped for these targets because of upstream toolchain gaps (`ort-sys` lacks Intel Mac prebuilts in the 2.0.0-rc.11 release that `fastembed 5.13.2` is pinned to; `usearch 2.24.0` hit a Windows MSVC compile break tracked as [usearch#746](https://github.com/unum-cloud/usearch/issues/746)). Both build fine from source in the meantime: +**macOS (Intel):** Microsoft is discontinuing x86_64 macOS prebuilts after ONNX Runtime v1.23.0, so Vestige's Intel Mac build links dynamically against a Homebrew-installed ONNX Runtime via the `ort-dynamic` feature. Install with: + +```bash +brew install onnxruntime +curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-x86_64-apple-darwin.tar.gz | tar -xz +sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/ +echo 'export ORT_DYLIB_PATH="'"$(brew --prefix onnxruntime)"'/lib/libonnxruntime.dylib"' >> ~/.zshrc +source ~/.zshrc +claude mcp add vestige vestige-mcp -s user +``` + +Full Intel Mac guide (build-from-source + troubleshooting): [`docs/INSTALL-INTEL-MAC.md`](docs/INSTALL-INTEL-MAC.md). + +**Windows:** Prebuilt binaries ship but `usearch 2.24.0` hit an MSVC compile break ([usearch#746](https://github.com/unum-cloud/usearch/issues/746)); we've pinned `=2.23.0` until upstream fixes it. Source builds work with: ```bash git clone https://github.com/samvallad33/vestige && cd vestige cargo build --release -p vestige-mcp -# Binary lands at target/release/vestige-mcp ``` **npm:** @@ -315,7 +327,7 @@ At the start of every session: | **Transport** | MCP stdio (JSON-RPC 2.0) + WebSocket | | **Cognitive modules** | 30 stateful (17 neuroscience, 11 advanced, 2 search) | | **First run** | Downloads embedding model (~130MB), then fully offline | -| **Platforms** | macOS ARM + Linux x86_64 (prebuilt). macOS Intel + Windows build from source (upstream toolchain gaps, see install notes). | +| **Platforms** | macOS ARM + Intel + Linux x86_64 + Windows x86_64 (all prebuilt). Intel Mac needs `brew install onnxruntime` — see [install guide](docs/INSTALL-INTEL-MAC.md). | ### Optional Features diff --git a/crates/vestige-core/Cargo.toml b/crates/vestige-core/Cargo.toml index 0d02e0b..0e5f7e3 100644 --- a/crates/vestige-core/Cargo.toml +++ b/crates/vestige-core/Cargo.toml @@ -11,29 +11,41 @@ keywords = ["memory", "spaced-repetition", "fsrs", "embeddings", "knowledge-grap categories = ["science", "database"] [features] -default = ["embeddings", "vector-search", "bundled-sqlite"] +default = ["embeddings", "ort-download", "vector-search", "bundled-sqlite"] # SQLite backend (default, unencrypted) bundled-sqlite = ["rusqlite/bundled"] # Encrypted SQLite via SQLCipher (mutually exclusive with bundled-sqlite) -# Use: --no-default-features --features encryption,embeddings,vector-search +# Use: --no-default-features --features encryption,embeddings,ort-download,vector-search # Set VESTIGE_ENCRYPTION_KEY env var to enable encryption encryption = ["rusqlite/bundled-sqlcipher"] -# Core embeddings with fastembed (ONNX-based, local inference) -# Downloads a pre-built ONNX Runtime binary at build time (requires glibc >= 2.38) -embeddings = ["dep:fastembed", "fastembed/ort-download-binaries-native-tls"] +# Embedding code paths (fastembed dep, hf-hub, image-models). This feature +# enables the #[cfg(feature = "embeddings")] gates throughout the crate but +# does NOT pick an ort backend. Pair with EXACTLY ONE of `ort-download` +# (prebuilt ONNX Runtime, default) or `ort-dynamic` (runtime-linked system +# libonnxruntime, required on targets without prebuilts). +embeddings = ["dep:fastembed", "fastembed/hf-hub-native-tls", "fastembed/image-models"] + +# Default ort backend: ort-sys downloads prebuilt ONNX Runtime at build time. +# Requires glibc >= 2.38. Fails on x86_64-apple-darwin (Microsoft is +# discontinuing Intel Mac prebuilts after ONNX Runtime v1.23.0). +ort-download = ["embeddings", "fastembed/ort-download-binaries-native-tls"] # HNSW vector search with USearch (20x faster than FAISS) vector-search = ["dep:usearch"] -# Use runtime-loaded ORT instead of the downloaded pre-built binary. -# Required on systems with glibc < 2.38 (Ubuntu 22.04, Debian 12, RHEL/Rocky 9). -# Mutually exclusive with the default `embeddings` feature's download strategy. -# Usage: --no-default-features --features ort-dynamic,vector-search,bundled-sqlite -# Runtime requirement: libonnxruntime.so must be on LD_LIBRARY_PATH or ORT_DYLIB_PATH set. -ort-dynamic = ["dep:fastembed", "fastembed/ort-load-dynamic", "fastembed/hf-hub-native-tls", "fastembed/image-models"] +# Alternative ort backend: runtime-linked against a system libonnxruntime via +# dlopen. Required on Intel Mac and on systems with glibc < 2.38 (Ubuntu +# 22.04, Debian 12, RHEL/Rocky 9). Transitively enables `embeddings` so the +# #[cfg] gates stay active. +# +# Usage: cargo build --no-default-features \ +# --features ort-dynamic,vector-search,bundled-sqlite +# Runtime: export ORT_DYLIB_PATH=/path/to/libonnxruntime.{dylib,so} +# (e.g. $(brew --prefix onnxruntime)/lib/libonnxruntime.dylib) +ort-dynamic = ["embeddings", "fastembed/ort-load-dynamic"] # Nomic Embed Text v2 MoE (475M params, 305M active, Candle backend) # Requires: fastembed with nomic-v2-moe feature diff --git a/crates/vestige-mcp/Cargo.toml b/crates/vestige-mcp/Cargo.toml index cc72f18..71e67f1 100644 --- a/crates/vestige-mcp/Cargo.toml +++ b/crates/vestige-mcp/Cargo.toml @@ -10,12 +10,17 @@ categories = ["command-line-utilities", "database"] repository = "https://github.com/samvallad33/vestige" [features] -default = ["embeddings", "vector-search"] +default = ["embeddings", "ort-download", "vector-search"] embeddings = ["vestige-core/embeddings"] vector-search = ["vestige-core/vector-search"] -# For systems with glibc < 2.38 — use runtime-loaded ORT instead of the downloaded pre-built binary. -# Usage: cargo install --path crates/vestige-mcp --no-default-features --features ort-dynamic,vector-search -ort-dynamic = ["vestige-core/ort-dynamic"] +# Default ort backend: downloads prebuilt ONNX Runtime at build time. +# Fails on targets without prebuilts (notably x86_64-apple-darwin). +ort-download = ["embeddings", "vestige-core/ort-download"] +# Alternative ort backend: runtime-linked system libonnxruntime via dlopen. +# Required on Intel Mac and on systems with glibc < 2.38. +# Usage: cargo build --no-default-features --features ort-dynamic,vector-search +# Runtime: export ORT_DYLIB_PATH=$(brew --prefix onnxruntime)/lib/libonnxruntime.dylib +ort-dynamic = ["embeddings", "vestige-core/ort-dynamic"] [[bin]] name = "vestige-mcp" diff --git a/docs/INSTALL-INTEL-MAC.md b/docs/INSTALL-INTEL-MAC.md new file mode 100644 index 0000000..ee42975 --- /dev/null +++ b/docs/INSTALL-INTEL-MAC.md @@ -0,0 +1,73 @@ +# Intel Mac Installation + +The Intel Mac (`x86_64-apple-darwin`) binary links dynamically against a system +ONNX Runtime instead of a prebuilt ort-sys library. Microsoft is discontinuing +x86_64 macOS prebuilts after ONNX Runtime v1.23.0, so we use the +`ort-dynamic` feature to runtime-link against the version you install locally. +This keeps Vestige working on Intel Mac without waiting for a dead upstream. + +## Prerequisite + +Install ONNX Runtime via Homebrew: + +```bash +brew install onnxruntime +``` + +## Install + +```bash +# 1. Download the binary +curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-x86_64-apple-darwin.tar.gz | tar -xz +sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/ + +# 2. Point the binary at Homebrew's libonnxruntime +echo 'export ORT_DYLIB_PATH="'"$(brew --prefix onnxruntime)"'/lib/libonnxruntime.dylib"' >> ~/.zshrc +source ~/.zshrc + +# 3. Verify +vestige-mcp --version + +# 4. Connect to Claude Code +claude mcp add vestige vestige-mcp -s user +``` + +`ORT_DYLIB_PATH` is how the `ort` crate's `load-dynamic` feature finds the +shared library at runtime. Without it the binary starts but fails on the first +embedding call with a "could not find libonnxruntime" error. + +## Building from source + +```bash +brew install onnxruntime +git clone https://github.com/samvallad33/vestige && cd vestige +cargo build --release -p vestige-mcp \ + --no-default-features \ + --features ort-dynamic,vector-search +export ORT_DYLIB_PATH="$(brew --prefix onnxruntime)/lib/libonnxruntime.dylib" +./target/release/vestige-mcp --version +``` + +## Troubleshooting + +**`dyld: Library not loaded: libonnxruntime.dylib`** — `ORT_DYLIB_PATH` is not +set for the shell that spawned `vestige-mcp`. Claude Code / Codex inherits the +env vars from whatever launched it; export `ORT_DYLIB_PATH` in `~/.zshrc` or +`~/.bashrc` and restart the client. + +**`error: ort-sys does not provide prebuilt binaries for the target +x86_64-apple-darwin`** — you hit this only if you ran `cargo build` without the +`--no-default-features --features ort-dynamic,vector-search` flags. The default +feature set still tries to download a non-existent prebuilt. Add the flags and +rebuild. + +**Homebrew installed `onnxruntime` but `brew --prefix onnxruntime` prints +nothing** — upgrade brew (`brew update`) and retry. Older brew formulae used +`onnx-runtime` (hyphenated). If your brew still has the hyphenated formula, +substitute accordingly in the commands above. + +## Long-term + +Intel Mac will move to a fully pure-Rust backend (`ort-candle`) in Vestige +v2.1, removing the Homebrew prerequisite entirely. Track progress at +[issue #41](https://github.com/samvallad33/vestige/issues/41).