Skip to content

Live 3D vector-field visualizer + agentic answering + retrieval/SKG improvements#2

Merged
kordless merged 12 commits into
mainfrom
feature/live-vector-viz
Jun 19, 2026
Merged

Live 3D vector-field visualizer + agentic answering + retrieval/SKG improvements#2
kordless merged 12 commits into
mainfrom
feature/live-vector-viz

Conversation

@kordless

@kordless kordless commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Brings the live 3D vector-field visualizer and agentic answering to Lume, plus retrieval-quality improvements, a documentation series, and licensing.

What's included

Visualizer (lume stream + viz/)

  • Live 3D field: candidate orbs sized by weight, colored per query, laid out by a phase-binding + Weber/Kuramoto relaxation streamed as NDJSON over a WebSocket bridge to a React/Three.js front end.
  • Additive multi-query search with gold overlap halos, results list, cluster spread, Ctrl-drag pan, hover-for-passage.
  • Hyperspace warp-in: orbs streak in radially and ease into place on each new field.

Agentic answering (lume answer + Ask mode)

  • Plan → retrieve → evaluate → refine → cited-answer loop with provenance orbs.
  • Retrieval-quality fix: diversify planner/evaluator queries so event-phrased passages surface (not just the question's proper nouns); scale n_feed with -k; set num_ctx and widen snippets so multi-passage prompts aren't truncated. Fixes the "provided passages do not contain" false-negative.

Retrieval core

  • SKG significance scoring (log-compressed z-score, hub-resistant) + a retrieval evaluation harness.

Docs

  • docs/blog/ — "How Lume Works" Part 1 (retrieval primitives) & Part 2 (the visualization), plus a narrative post. Fact-checked against source.

Licensing / CI

  • BSD 3-Clause LICENSE + license field in Cargo.toml.
  • Release + CI GitHub Actions workflows.

Notes

  • .env (holds NUTS_SERVICES_TOKEN) is gitignored and not committed.
  • Copyright holder in LICENSE is "DeepBlue Dynamics" — easy to change if a different entity is preferred.

🤖 Generated with Claude Code

Antigravity and others added 12 commits June 19, 2026 10:11
…ong edges

Raw z-scores explode on large corpora (strong edges reach z=50-100+), so the
prior tanh(z/3) saturated every real association at +1.0 and discarded all
gradation. Log-compress first — sign(z)*ln(1+|z|) — then bound with tanh, so a
z of 10 and a z of 100 stay distinguishable while the score still passes through
0 at independence and goes negative for avoidance.

On the Monte Cristo graph, edges now spread from +0.78 (Noirtier–Valentine) down
through the mid-range to meaningful negatives (Monte Cristo–Villefort = -0.48:
adversaries who co-occur below chance, which Jaccard naively rates +0.12).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
release.yml: on a pushed `v*` tag (or manual dispatch against a tag), builds
optimized `lume` binaries for all major platforms and attaches them, with
SHA-256 sums, to the GitHub Release:
  - x86_64-unknown-linux-gnu
  - aarch64-unknown-linux-gnu (cross-linked)
  - x86_64-apple-darwin (Intel macOS)
  - aarch64-apple-darwin (Apple Silicon)
  - x86_64-pc-windows-msvc

ci.yml: build + test on ubuntu/macos/windows for every push and PR to main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The thing static embedding layouts (UMAP/t-SNE) throw away: the *acceleration*
of vectors toward each other. This streams Lume's phase-binding + Weber search
relaxation and renders it live in 3D.

Rust (src/stream.rs, `lume stream <query>`):
- Retrieves the query's top-K candidates (BM25 + SKG), embeds them via shivvr
  (read-only), fits a fixed top-3 PCA frame, and runs a Kuramoto-phase × Weber ×
  in-phase-vector-warp relaxation (mirrors the psyche/gte_weber_teacher dynamics).
- Emits one NDJSON frame per step on stdout: per node — 3D pos, velocity,
  acceleration, phase, cluster, cosine-to-query, and approach-velocity/
  acceleration toward the query (d̈ of cosine distance). Diagnostics on stderr so
  stdout stays a clean frame channel. No new Rust deps (std + serde_json).

Front-end (viz/):
- server.js — Node WebSocket bridge: spawns `lume stream`, relays NDJSON frames
  to the browser, serves the built app.
- React + three.js (@react-three/fiber) — candidates as a force field; sphere
  size/glow = cosine-to-query; green/red arrows = accelerating toward/away from
  the query; colors = emergent phase clusters; Kuramoto coherence (R) meter;
  scrub/play/speed playback with frame interpolation.

Verified end-to-end headless: `lume stream` emits correct frames (candidates for
"Dantès escapes the prison and finds the treasure" resolve to Chapter 18 "The
Treasure"; phase coherence climbs as assemblies bind), the React app builds, and
a WebSocket client drives the bridge through a full meta→frames→done relay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Feedback from running it live:
- Nodes labeled with the retrieval **weight** (BM25+SKG score) instead of the
  long passage title — far less clutter. Full passage text now appears on
  **hover** (tooltip shows weight, cosine-to-query, and live approach d̈).
- **Declutter**: near-identical candidate vectors (adjacent parts of the same
  chapter projected to nearly the same point) were stacking. Added a constant
  per-section display jitter (kinematics still use the true projection, so
  velocity/acceleration are unaffected) and widened the PCA spread.
- **Ctrl-drag pans** the camera (left=rotate normally; hold Ctrl to pan);
  right-drag also pans, scroll zooms. Smaller spheres so arrows read clearly.

stream.rs now forwards `score` + a longer `text` excerpt in the meta frame and
applies the jitter to the emitted position only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses live-viewing feedback:
- **Full-spectrum colors**: each result gets a distinct hue ordered by cosine-to-
  query (warm = most related), so relevance-neighbours sit next to each other on
  the rainbow instead of everything collapsing to one cluster color. Arrows and
  labels take the node's hue.
- **Warped orbs**: each sphere is stretched into an ellipsoid along its velocity
  (with an acceleration pulse), so a vector being strongly warped through the
  space visibly elongates toward where it's heading. New "orb warp" slider.
- **Varying sizes**: candidate radius scales with retrieval weight; the query orb
  is shrunk so it no longer dominates.
- **Physics separation**: a position-based collision-resolution pass pushes any
  overlapping orbs apart along their centre line (12 iterations, query immovable)
  so results never intersect and are all visible.
- **Shading**: meshPhysicalMaterial (clearcoat) under a key + fill directional
  light, so the warped orbs read as solid 3D. Dropped the CDN Environment HDR to
  keep it offline-safe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…query

- **Results cluster around the query**: candidates now orbit their anchor query
  on a fixed ray at a radius that shrinks with cosine-similarity, so nearest =
  most relevant and binding visibly pulls them inward (acc arrows read as true
  approach). Was previously raw PCA position, which didn't track relevance.
- **Additive search**: `lume stream <q> --add <q2> …` runs one relaxation over
  the union of all queries' top-K in a shared PCA frame. `Add` button (Ctrl-
  Enter) unions a new query into the live field; each query is its own coloured
  anchor with a halo.
- **Overlap detection**: candidates retrieved by 2+ queries carry `members` and
  render gold with a halo — you can see which results the searches share.
- **Halos** on query orbs (and overlaps) via an additive radial sprite.
- **Smaller labels**; query/overlap colours matched to side-panel chips.

Rust: stream::run takes `&[String]` queries + `&[Candidate]` (with member sets);
handle_stream unions per-query BM25+SKG hits and records overlap membership.
Verified end-to-end through the bridge: 2 queries → 15 union candidates → 9
overlaps flagged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- **Results panel** (right): scrollable list of every result with its colour dot,
  weight, label, relevance bar, and approach indicator. Re-sorts live by the
  values shown — relevance / weight / binding / overlap. Hovering a row highlights
  its orb (and vice-versa) via shared hover state.
- **Delete a query**: each search chip has an × that removes it and reruns over
  the remaining queries.
- **Cluster spread** slider: scales each cluster outward from its query so you can
  pull overlapping groups apart for viewing.
- **Colours vary by search**: per-query hue families (matched to the chips); a
  single search keeps the full-relevance spectrum; overlaps stay gold.
- **No-overlap**: separation pass strengthened — 26 iterations, padded collision
  radius (covers the warp ellipsoids), early-out on convergence.
- Shared colour logic factored into colors.js so the list and orbs always agree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
VectorField's node map still referenced the removed internal setHovered. Route
hover through the controlled onHover prop, adapting the Node's (node|null) signal
to the parent's id-based setter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
You can now ask a question and see the answer AND the exact nodes behind it.

Rust (src/answer.rs, `lume answer <question>`):
- Agentic loop over a local Ollama model (default gpt-4o-mini): plan search
  queries → retrieve + animate the field → evaluate sufficiency → refine queries
  (lume_not_found-style, up to --rounds) → synthesize a cited answer.
- Streams NDJSON events through the same bridge: question, plan (per round),
  evaluate, the relaxation frames, and answer {text, used:[node ids],
  cites:[node ids]}. Citations map [n] markers back to specific orbs.
- Reuses the agent.rs Ollama pattern; retrieve_union factored out and shared
  with `lume stream`. stream::run gains an emit_done flag for multi-round use.

Viz:
- "Ask" button runs the agentic loop; answer panel shows the question, the
  per-round plan/evaluate log, the answer text, and clickable source chips that
  highlight their orb. Cited nodes glow (icy blue), "considered" nodes get a soft
  halo. Query orbs are now translucent.

Verified end-to-end through the bridge: "How did Dantès escape the Château d'If?"
→ 3 plan rounds (3→5→6 queries) → cited answer mapping to nodes [27,13,7].
answer.rs unit tests for JSON-span extraction + citation parsing pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
answer agent: diversify the planner/evaluator queries so event-phrased
passages (e.g. a death described as "died of starvation", not "death")
actually surface instead of anchoring on the question's proper nouns;
scale n_feed with -k so raising candidates feeds the model more; set
num_ctx=16384 and widen snippets to 180 words so multi-passage prompts
aren't silently truncated. Fixes the "provided passages do not contain"
false-negative on questions whose answer uses different vocabulary.

viz: orbs warp in from hyperspace on each new field — each orb is flung
out along its radial line, stretched into a thin streak, and eased back
with easeOutExpo in a staggered cascade, driven by a per-orb useFrame so
it plays even before relaxation frames finish streaming.

.gitignore: ignore .env (holds NUTS_SERVICES_TOKEN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three posts in docs/blog/:
- how-lume-works-part1-primitives.md — Part 1: retrieval primitives
  (field-aware BM25, two-stage roaring/Gödel pruning, local GTR-T5
  vectors, significance-scored entity graph, the blend, tuning knobs),
  with the retrieval-bug case study.
- hyperspace-search-deep-dive.md — Part 2: the visualization (PCA +
  Weber/Kuramoto relaxation, NDJSON over the WebSocket bridge, the
  Three.js warp-in renderer).
- hyperspace-search.md — narrative story post.

Annealed for accuracy against source; code refs are plain path:line,
inter-post links relative.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
LICENSE file (copyright DeepBlue Dynamics) and license = "BSD-3-Clause"
in Cargo.toml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kordless kordless changed the title Live 3D search-dynamics visualizer (lume stream + viz/) Live 3D vector-field visualizer + agentic answering + retrieval/SKG improvements Jun 19, 2026
@kordless kordless merged commit 606095e into main Jun 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant