The integration suite loaded the real WASM model for every test, so a full run
took ~hours and reliably aborted (vitest reporter timeout) — which is why it was
never gated and silently rotted. Brainy already separates the embedder from all
other logic, so running integration with a deterministic embedder keeps every
code path real (HNSW build+search, graph traversal, metadata filtering,
transactions, storage/sharding, VFS, aggregation, import) while making the suite
complete in ~2 min on ANY machine — no GPU, no 16 GB requirement.
- Add isDeterministicEmbedMode() — a single source of truth for the test-embedder
switch (BRAINY_DETERMINISTIC_EMBEDDINGS, plus the legacy BRAINY_UNIT_TEST alias),
used by EmbeddingManager (init/embed/embedBatch) and brainy's eager-init guard.
- setup-integration.ts opts into it: Tier 1 = functional end-to-end. Real-model
semantic quality + the real embedding pipeline move to a Tier-2 suite.
Full integration now runs 482 passing / 583 in ~2 min (was un-completable). The
remaining failures are pre-existing test rot, fixed next. Unit 1414 green.
Brainy 8.0 is server-only. This commit takes the consequences seriously and
removes everything that was only there to keep browser/cloud/threading
surfaces alive.
Browser support drop (per the @deprecated notes in environment.ts):
- isBrowser, isWebWorker, areWebWorkersAvailable, navigator.deviceMemory
paths, window/document/self.onmessage code.
- browser console.log in unified.ts, the 'browser' branch in
autoConfiguration.ts (env enum + scaleUp cases), 'browser-cache' model
path, MCP service environment value.
- package.json browser field.
- src/worker.ts (Web Worker entrypoint) deleted.
Cloud SDK removal (the four adapters were dropped in Phase 7; the SDKs
were the lingering tax):
- @aws-sdk/client-s3, @azure/identity, @azure/storage-blob, and
@google-cloud/storage removed from package.json. Lockfile drops the
entire @aws/@azure/@google-cloud/@smithy transitive tree.
- EnhancedS3Clear class deleted from enhancedClearOperations.ts (the
only @aws-sdk/client-s3 consumer; the dynamic import sites went with
it). EnhancedFileSystemClear stays.
- src/utils/adaptiveSocketManager.ts deleted entirely (474 LOC of HTTPS
socket-pool management for the dropped cloud HTTP handler).
performanceMonitor.ts no longer reports a socketConfig; socket
utilization is fixed at 0.
Dead threading subsystem:
- executeInThread was imported by distance.ts and hnswIndex.ts but
never called. It was scaffolding for a future "off-main-thread
distance batch" optimization that never shipped.
- src/utils/workerUtils.ts deleted (Web Worker code path + an
unreachable Node Worker Threads code path).
- environment.ts loses isThreadingAvailable, isThreadingAvailableAsync,
areWorkerThreadsAvailable, areWorkerThreadsAvailableSync. All exports
purged from index.ts and unified.ts.
- autoConfiguration.ts drops AutoConfigResult.threadingAvailable.
Legacy plugin/augmentation pipeline:
- src/pipeline.ts deleted. The whole file was a no-op stub for
backwards compat — Pipeline class had no methods, no lifecycle hooks,
no before/after callbacks. AugmentationPipeline, augmentationPipeline,
createPipeline, createStreamingPipeline, StreamlinedPipelineOptions,
StreamlinedPipelineResult, StreamlinedExecutionMode were all aliases
for the same stub.
- src/mcp/mcpAugmentationToolset.ts deleted. executePipeline always
threw "deprecated", isValidAugmentationType always returned false,
getAvailableTools always returned []. Dead surface.
- BrainyMCPService no longer instantiates a toolset. TOOL_EXECUTION
requests now return the standard UNSUPPORTED_REQUEST_TYPE error.
'availableTools' system-info returns [] (was the same in practice).
Net: 22 files changed, ~6400 LOC deleted (including legacy code +
mechanical lockfile churn). Build clean, 1409/1409 tests pass.
EmbeddingManager constructor logged 'Using Q8 precision (WASM)' before
plugins had a chance to register a native embedder. Deferred logging to
init() so the startup message reflects the actual embedding engine.
Add a write-time incremental aggregation engine that maintains running
totals on every add/update/delete for O(1) read performance. Integrates
into brain.find({ aggregate }) for a unified query API.
Core features:
- AggregationIndex with defineAggregate()/removeAggregate() API
- Five aggregation operations: SUM, COUNT, AVG, MIN, MAX
- GROUP BY with multiple dimensions including time windows
- Time window bucketing: hour, day, week, month, quarter, year, custom
- Materialization of results as NounType.Measurement entities
- Debounced persistence of definitions and state to storage
- Definition change detection via FNV-1a hashing with auto-rebuild
- Infinite loop prevention for materialized entities
- 'aggregation' plugin provider key for native acceleration
- Lazy initialization (created on first defineAggregate() call)
- 73 tests (unit + integration) covering all functionality
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Wire PluginRegistry into Brainy init() with provider resolution for distance,
metadataIndex, graphIndex, embeddings, roaring, msgpack, and storage adapters
- Add setupStorage() factory that resolves storage:* providers from plugins before
falling back to built-in createStorage()
- Export internals API (setGlobalCache, UnifiedCache, EntityIdMapper, etc.) for
cortex plugin consumption
- Add plugin.test.ts verifying registration, activation, and provider resolution
- Deprecate browser support (OPFS, Web Workers, WASM embeddings) with warnings
in preparation for v8.0 server-only release
- FileSystemStorage: fix setupStorage resolution for mmap-filesystem provider
highlight() used Promise.race with a 10s timeout, but the losing
semantic phase promise continued running 25 WASM micro-batches,
saturating the event loop and degrading all subsequent operations
(find() going from ~200ms to ~10,000ms).
Add AbortController to highlight() so the semantic phase stops
immediately on timeout or error. Pass abort signal through
embedBatch() → EmbeddingManager → micro-batch loop.
Also add defensive hardening:
- CandleEmbeddingEngine: try/catch around WASM calls resets engine
state on failure so next call triggers re-initialization
- WASMEmbeddingEngine: initialize() now checks underlying Candle
engine state, not just its own flag, completing the recovery chain
embedBatch() with large inputs (e.g. 500 chunks from highlight()) runs
a single synchronous WASM forward pass that blocks the event loop for
200-500ms. Split large batches into micro-batches of 20 with setTimeout(0)
yields between each, keeping max blocking per batch to ~10-30ms.
Also change Cargo.toml opt-level from "z" (size) to 3 (speed) for
~15-20% faster WASM inference. Requires WASM rebuild to take effect.
Fix highlight() hanging on structured text input by addressing 3 root causes:
1. embedBatch() now uses native WASM batch API (single forward pass instead
of N individual embed() calls via Promise.all)
2. highlight() auto-detects content type (plain text, rich-text JSON, HTML,
Markdown) and extracts meaningful text segments. Supports TipTap, Slate.js,
Lexical, Draft.js, and Quill Delta formats. New contentType hint and
contentExtractor callback for custom parsers.
3. Semantic matching phase has 10s timeout - falls back to text-only matches
instead of hanging indefinitely.
Also fixes extractTextContent() array check: uses type-based detection
(typeof data[0] === 'number') instead of length-based (data.length > 10)
so arrays of objects are properly indexed for text search.
New types: ContentType, ContentCategory, ExtractedSegment
New fields: HighlightParams.contentType, HighlightParams.contentExtractor,
Highlight.contentCategory
- Remove @huggingface/transformers dependency (539MB native binaries)
- Add direct ONNX Runtime Web embedding engine
- Bundle all-MiniLM-L6-v2-q8 model (24MB, no runtime downloads)
- Works with Node.js, Bun, and bun build --compile
- Air-gap compatible: fully self-contained, no internet required
New WASM embedding components:
- WASMEmbeddingEngine: Main integration class
- WordPieceTokenizer: Pure TypeScript tokenizer
- EmbeddingPostProcessor: Mean pooling + L2 normalization
- ONNXInferenceEngine: Direct ONNX Runtime Web wrapper
- AssetLoader: Model file loading
Tests added:
- 11 WASM embedding integration tests
- 8 Bun compatibility tests
New npm scripts:
- test:wasm - Run WASM embedding tests
- test:bun - Run tests with Bun
- test:bun:compile - Build and run compiled binary
- Add importFile() method for single file imports
- Implement entity helper methods (linkEntities, findEntityOccurrences)
- Fix critical embedding tokenizer bug (char.charCodeAt error)
- Fix removeRelationship to actually remove using brain.unrelate()
- Add setMetadata/getMetadata methods
- Fix GitBridge to query real relationships and events
- Enable background Knowledge Layer processing
- Rewrite README to emphasize knowledge over files
- Add comprehensive VFS documentation (core, knowledge layer, examples)
- Add complete test suite covering all VFS methods
This completes the VFS implementation with full Knowledge Layer support,
enabling files as living knowledge that understand themselves, evolve
over time, and connect to everything related.
- Remove Node.js-specific imports from module level
- Use dynamic imports with isNode() environment checks
- Wrap all file system operations in conditional blocks
- Add fallback values for browser environments
- Ensure code works in both Node.js and browser contexts
This change enables Brainy to run in browser environments without
requiring Node.js polyfills, making it truly universal.
Co-Authored-By: dpsifr <noreply@dpsifr.com>
- Updated all fs, path, crypto, os, url, util, events, http, https, net, child_process, stream, and zlib imports
- Changed both static imports and dynamic imports to use node: protocol
- This makes Brainy more bundler-friendly by explicitly marking Node.js built-ins
- Prevents bundlers from attempting to polyfill or bundle these modules
- Reduces bundle size for web applications using Brainy
- Improves tree-shaking and dead code elimination
Benefits for external bundlers:
- Clear distinction between Node.js built-ins and external dependencies
- No ambiguity about what needs polyfilling
- Smaller bundles for browser builds
- Better compatibility with modern bundlers (Webpack 5, Vite, Rollup, esbuild)
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Unified embedding system with single EmbeddingManager
- Q8 model support with 75% smaller footprint (23MB vs 90MB)
- Intelligent precision auto-selection based on environment
- Clean cached embeddings with TTL and memory management
- Zero-config setup with smart defaults
- Complete storage structure documentation
- Removed legacy worker and hybrid managers
- Streamlined model configuration and precision management