Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CI

# Build and test on every push and pull request to main.
on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always

jobs:
test:
name: test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Cache cargo registry and build
uses: Swatinem/rust-cache@v2

- name: Build
run: cargo build --locked --verbose

- name: Test
run: cargo test --locked --verbose

- name: Clippy (no warnings as errors; informational)
run: cargo clippy --all-targets || true
94 changes: 94 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: Release

# Build optimized `lume` binaries for all major platforms and attach them to a
# GitHub Release. Triggers on a pushed version tag (e.g. `v0.12.0`), or manually
# against an existing tag via the Actions tab.
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Existing tag to build and release (e.g. v0.12.0)"
required: true

permissions:
contents: write

jobs:
build:
name: ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
linker: gcc-aarch64-linux-gnu
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc

steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag || github.ref }}

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Cache cargo registry and build
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}

- name: Install cross linker (Linux aarch64)
if: matrix.linker != ''
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.linker }}
mkdir -p .cargo
echo "[target.aarch64-unknown-linux-gnu]" >> .cargo/config.toml
echo "linker = \"aarch64-linux-gnu-gcc\"" >> .cargo/config.toml

- name: Build release binary
run: cargo build --release --locked --target ${{ matrix.target }}

- name: Package (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
VERSION="${{ github.event.inputs.tag || github.ref_name }}"
ARCHIVE="lume-${VERSION}-${{ matrix.target }}.tar.gz"
tar -czf "$ARCHIVE" -C "target/${{ matrix.target }}/release" lume
sha256sum "$ARCHIVE" > "$ARCHIVE.sha256"
echo "ASSET=$ARCHIVE" >> "$GITHUB_ENV"

- name: Package (Windows)
if: runner.os == 'Windows'
shell: bash
run: |
VERSION="${{ github.event.inputs.tag || github.ref_name }}"
ARCHIVE="lume-${VERSION}-${{ matrix.target }}.zip"
7z a "$ARCHIVE" "./target/${{ matrix.target }}/release/lume.exe"
certutil -hashfile "$ARCHIVE" SHA256 > "$ARCHIVE.sha256"
echo "ASSET=$ARCHIVE" >> "$GITHUB_ENV"

- name: Upload to release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.event.inputs.tag || github.ref_name }}
files: |
${{ env.ASSET }}
${{ env.ASSET }}.sha256
fail_on_unmatched_files: true
generate_release_notes: true
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ crawl_cache/
# Local evaluation scratch (corpus copy + tag dictionary)
eval-tmp/

# Viz app build output and deps
viz/node_modules/
viz/dist/

# Secrets (NUTS_SERVICES_TOKEN, etc.) — never commit
.env

# Build and archive directories
target/
target-cli/
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
co-occur with everything are damped toward zero; genuine associations rise.
Computed directly from the roaring-bitmap intersection counts already used for
Jaccard (no extra scan). New `cooccurrence_relatedness` in `semantic_mesh.rs`.
The z-score is log-compressed before the tanh bound so strong edges on large
corpora keep their gradation instead of all saturating at ±1.
- **`--scoring` flag** on `lume search` (and `lume eval`): choose `relatedness`
(significance, default) or `jaccard` (raw overlap) for the SKG walk. The graph
walk and edge sort now key on significance by default, Jaccard as tie-breaker.
Expand All @@ -22,6 +24,28 @@
modes and prints the delta. New `src/eval.rs` (pure, unit-tested) plus
`handle_eval` wiring. UTF-8-tolerant Q&A loading (cp1252 files don't abort).

### Agentic answering
- **`lume answer` + viz "Ask" mode**: an agentic plan → retrieve → evaluate →
refine → answer loop over a local Ollama model (default gpt-4o-mini). The model
plans search queries, the field is retrieved and animated, the model judges
whether the passages suffice and refines the queries if not (up to N rounds),
then synthesizes a **cited** answer. Streams NDJSON events (`question`, `plan`,
`evaluate`, relaxation frames, `answer`) through the same bridge. In the viz,
the answer panel shows the per-round plan log and the answer; nodes fed to the
model get a soft halo, the ones it **cited** glow, and clicking a source chip
highlights its orb. New `src/answer.rs`.

### Visualization
- **`lume stream` + `viz/`**: live 3D visualizer for the search dynamics.
`lume stream <query>` runs a phase-binding + Weber relaxation over the query's
top-K candidates (shivvr embeddings, read-only) and emits one NDJSON frame per
step on stdout — each node's 3D PCA position, velocity, **acceleration**, phase,
cluster, and **approach-acceleration toward the query** (the `d̈` static cosine
discards). `viz/` is a Node WebSocket bridge + React/three.js app that renders
it: candidates as a force field, green/red arrows for accelerating toward/away
from the query, emergent phase clusters, and a Kuramoto coherence meter. New
`src/stream.rs`; no new Rust dependencies (std + existing serde_json).

### Tests
- New unit tests for the significance function, hub down-weighting (significance
flips a ranking Jaccard gets wrong), and the eval metrics/relevance judging.
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name = "lume"
version = "0.12.0"
edition = "2021"
description = "Lume: A high-performance, zero-dependency, FST-backed tagger and on-demand BM25 hybrid search engine."
license = "BSD-3-Clause"

[dependencies]
tantivy-fst = "0.5"
Expand Down
28 changes: 28 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License

Copyright (c) 2026, DeepBlue Dynamics

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Loading
Loading