ruvector/crates/ruvector-tiny-dancer-wasm
rUv eafba64fa5
fix(security): RUSTSEC advisories + clippy hardening in RuVector (#504)
* fix(security): RUSTSEC advisories + clippy hardening in RuVector

- Replace all bare `partial_cmp().unwrap()` calls on f32/f64 with
  `.unwrap_or(Ordering::Equal)` to prevent panics on NaN values in
  sorting/max-by operations across ruvllm, ruvector-dag, prime-radiant,
  and rvagent-wasm (12 sites in production code).
- Add input validation guards to the HTTP search endpoint: reject k=0,
  k > 10_000, empty vectors, and vectors exceeding 65_536 dimensions,
  preventing memory exhaustion via unbounded allocations.
- Harden LocalFsBackend::execute in rvagent-cli with env_clear() +
  safe-env allowlist (SEC-005), deadline-based timeout enforcement, and
  1 MB output truncation, matching the security posture of LocalShellBackend.
- Remove 129 occurrences of the deprecated `unused_unit = "allow"` lint
  and 3 occurrences of the removed `clippy::match_on_vec_items` lint from
  Cargo.toml files workspace-wide; both are no-ops in current Rust/Clippy.
- All 653+ tests across ruvector-core, ruvector-server, ruvector-dag,
  rvagent-cli, and prime-radiant pass with zero failures.

Note: `bytes` is already at 1.11.1 (>= 1.10.0); `paste` 1.0.15 is a
transitive dependency with no semver fix available upstream; `cargo audit`
returns clean.

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix(ci): cargo fmt + restore workspace unused_unit lint allow

- Run cargo fmt --all across all 9 files that drifted from rustfmt style
  (prime-radiant/energy.rs, ruvector-dag/bottleneck.rs+reasoning_bank.rs,
   ruvector-server/points.rs, ruvllm/pretrain_pipeline.rs+report.rs+registry.rs,
   rvagent-cli/app.rs, rvagent-wasm/gallery.rs)
- Add [workspace.lints.clippy] unused_unit = "allow" to root Cargo.toml;
  the per-crate entries removed in the security commit were still needed —
  moving to workspace-level is cleaner and restores -D warnings CI pass

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix(ci): remove unneeded unit return type in ruvix bench

Removes `-> ()` from the Fn bound in run_benchmark_with_kernel
(crates/ruvix/benches/src/ruvix.rs:50) — triggers clippy::unused_unit
under -D warnings. Clippy prefers `Fn(&mut Kernel)` without explicit
unit return.

Co-Authored-By: claude-flow <ruv@ruv.net>

* fix(ci): resolve rustfmt and clippy unused_unit failures

- Run cargo fmt --all to fix long closure formatting in 9 files
  (energy.rs, bottleneck.rs, reasoning_bank.rs, points.rs,
  pretrain_pipeline.rs, report.rs, registry.rs, app.rs, gallery.rs)
- Add unused_unit = "allow" to [lints.clippy] in ruvix-bench and
  ruvector-mincut Cargo.toml files to suppress the unused_unit lint
  that was previously suppressed globally and now fires on two
  Fn(&mut T) -> () and FnMut() -> () function bounds

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-23 05:40:24 -04:00
..
src fix: Resolve CI build failures 2025-11-26 15:25:47 +00:00
Cargo.toml fix(security): RUSTSEC advisories + clippy hardening in RuVector (#504) 2026-05-23 05:40:24 -04:00
package.json feat: Publish 8 new npm packages 2025-12-02 18:44:00 +00:00
README.md docs: Add README files for all crates and update root README with crates table 2025-11-26 18:15:05 +00:00

Ruvector Tiny Dancer WASM

npm Crates.io License: MIT

WebAssembly bindings for Tiny Dancer neural routing.

ruvector-tiny-dancer-wasm brings production-grade AI agent routing to the browser with WebAssembly. Run FastGRNN neural inference for intelligent request routing directly in client-side applications. Part of the Ruvector ecosystem.

Why Tiny Dancer WASM?

  • Browser Native: Run neural routing in any browser
  • Low Latency: Sub-millisecond inference times
  • Small Bundle: Optimized WASM binary (~100KB gzipped)
  • Offline Capable: No server required for inference
  • Privacy First: Route decisions stay client-side

Features

Core Capabilities

  • Neural Inference: FastGRNN model execution
  • Feature Engineering: Request feature extraction
  • Multi-Agent Routing: Score and rank agent candidates
  • Model Loading: Load pre-trained models
  • Batch Inference: Process multiple requests

Advanced Features

  • Web Workers: Background inference threads
  • Streaming: Process streaming requests
  • Model Caching: IndexedDB model persistence
  • Quantization: INT8 models for smaller size
  • SIMD: Hardware acceleration when available

Installation

npm install @ruvector/tiny-dancer-wasm
# or
yarn add @ruvector/tiny-dancer-wasm

Quick Start

Basic Usage

import init, { TinyDancer, RouteRequest } from '@ruvector/tiny-dancer-wasm';

// Initialize WASM module
await init();

// Create router instance
const router = new TinyDancer();

// Load pre-trained model
await router.loadModel('/models/router-v1.bin');

// Create routing request
const request: RouteRequest = {
  query: "What is the weather like today?",
  context: {
    userId: "user-123",
    sessionLength: 5,
    previousAgent: "general",
  },
  agents: ["weather", "general", "calendar", "search"],
};

// Get routing decision
const result = await router.route(request);
console.log(`Route to: ${result.agent} (confidence: ${result.confidence})`);

With Web Workers

import { TinyDancerWorker } from '@ruvector/tiny-dancer-wasm/worker';

// Create worker-based router (non-blocking)
const router = new TinyDancerWorker();

// Initialize in background
await router.init();
await router.loadModel('/models/router-v1.bin');

// Route without blocking main thread
const result = await router.route(request);

Feature Engineering

import { FeatureExtractor } from '@ruvector/tiny-dancer-wasm';

const extractor = new FeatureExtractor();

// Extract features from request
const features = extractor.extract({
  query: "Book a flight to Paris",
  tokens: 6,
  language: "en",
  sentiment: 0.7,
  entities: ["Paris"],
});

console.log(`Feature vector: ${features.length} dimensions`);

API Reference

TinyDancer Class

class TinyDancer {
  constructor();

  // Model management
  loadModel(url: string): Promise<void>;
  loadModelFromBuffer(buffer: Uint8Array): void;

  // Routing
  route(request: RouteRequest): Promise<RouteResult>;
  routeBatch(requests: RouteRequest[]): Promise<RouteResult[]>;

  // Scoring
  scoreAgents(request: RouteRequest): Promise<AgentScore[]>;

  // Info
  getModelInfo(): ModelInfo;
  isReady(): boolean;
}

Types

interface RouteRequest {
  query: string;
  context?: Record<string, any>;
  agents: string[];
  constraints?: RouteConstraints;
}

interface RouteResult {
  agent: string;
  confidence: number;
  scores: Record<string, number>;
  latencyMs: number;
}

interface AgentScore {
  agent: string;
  score: number;
  features: number[];
}

interface RouteConstraints {
  excludeAgents?: string[];
  minConfidence?: number;
  timeout?: number;
}

Bundle Optimization

Tree Shaking

// Import only what you need
import { TinyDancer } from '@ruvector/tiny-dancer-wasm/core';
import { FeatureExtractor } from '@ruvector/tiny-dancer-wasm/features';

CDN Usage

<script type="module">
  import init, { TinyDancer } from 'https://unpkg.com/@ruvector/tiny-dancer-wasm';

  await init();
  const router = new TinyDancer();
</script>

Performance

Benchmarks (Chrome 120, M1 Mac)

Operation           Latency (p50)
────────────────────────────────
Model load          ~50ms
Single inference    ~0.5ms
Batch (10)          ~2ms
Feature extraction  ~0.1ms

Bundle Size

Format              Size
────────────────────────
WASM binary         ~100KB gzipped
JS glue             ~5KB gzipped
Total               ~105KB gzipped

Browser Support

Browser Version SIMD
Chrome 89+
Firefox 89+
Safari 15+
Edge 89+

Documentation

License

MIT License - see LICENSE for details.


Part of Ruvector - Built by rUv

Star on GitHub

Documentation | npm | GitHub