Skip to content

Vigilo WASMIn-browser AI exam proctoring

YuNet face detection, head pose, gaze, prohibited objects, and temporal fusion engine compiled to WebAssembly with WebGPU acceleration.

Vigilo WASM Logo

Quick installation ​

Choose between the CPU build (WASM SIMD) or GPU build (WebGPU hardware acceleration):

bash
bun add vigilo-wasm
bash
bun add vigilo-wasm-gpu
bash
npm install vigilo-wasm
bash
npm install vigilo-wasm-gpu
bash
# CPU build
pnpm add vigilo-wasm
# GPU build
pnpm add vigilo-wasm-gpu

Example: In-browser live exam proctoring ​

ts
import { initVigilo, CameraSource, loadModels, VigiloBrowser } from 'vigilo-wasm';

// 1. Initialize WebAssembly module (idempotent)
await initVigilo();

// 2. Open camera (ideal 1280x720, unbuffered drop-not-queue)
const camera = await CameraSource.open();

// 3. Load ONNX models (cached automatically in Cache API)
const models = await loadModels({
  face:    '/models/face_detection_yunet_2023mar.onnx',
  pose:    '/models/headpose_mobilenetv3_small.onnx',
  gaze:    '/models/mobileone_s0_gaze.onnx',
  objects: '/models/yolox_nano.onnx',
}, {
  executionProviders: ['webgpu', 'wasm'],
});

// 4. Create browser runtime and listen for events
const vigilo = await VigiloBrowser.create({
  camera,
  models,
  faceHz: 10,     // 10 Hz face pacing
  objectHz: 1,    // 1 Hz background object scan
  gazeEvery: 2,   // Gaze evaluation every 2nd face frame
});

vigilo.onViolationStarted((v) => {
  console.warn(`[VIOLATION START] ${v.kind}: ${v.subject ?? ''} (confidence: ${v.confidence})`);
});

vigilo.onViolationEnded((v) => {
  console.info(`[VIOLATION END] ${v.kind} lasted ${v.t_end_ms! - v.t_start_ms}ms`);
});

vigilo.onFrame(({ signals, active, total_ms, stages }) => {
  // Draw bounding boxes, 3D pose gizmos, gaze rays, and violation pills
  drawHud(signals, active, stages);
});

// Start detection loop
vigilo.start();

// Later when exam finishes, resolve remaining open violations:
// const finalEvents = vigilo.finish();

Released under the AGPL-3.0 License.