Commit graph

9 commits

Author SHA1 Message Date
ed178e2ce9 fix(ci): commit the prebuilt wasm pkg + build before test:bun (green CI on fresh clone)
The Phase-0 CI was red on all three runtimes: `src/embeddings/wasm/pkg/` (the
wasm-pack output the dynamic `import('./pkg/candle_embeddings.js')` resolves) was
gitignored + untracked, so tsc failed to resolve it on a fresh clone (TS2307), and
the Bun job ran test:bun without building dist first.

Fixes:
- Track the 3.1 MB prebuilt pkg (candle_embeddings.js/.d.ts + _bg.wasm/.d.ts). It
  ships in the npm tarball anyway; versioning it lets consumers + CI build without
  a Rust/wasm-pack toolchain and makes the shipped artifact reproducible (closes
  the "publish ships whatever the maintainer last built" supply-chain gap). The
  top-level .gitignore intended this (`!*.wasm` etc.) but excluded the whole dir,
  so the re-includes were dead, and a nested wasm-pack `.gitignore *` also masked
  it — force-added past both.
- CI Bun job: `npm run build` before `test:bun` (it imports the built dist/).

Verified against a tracked-files-only tree (fresh-clone sim): typecheck 0, build 0,
test:bun 8/8.
2026-07-01 14:40:11 -07:00
cb16a39a0c chore(8.0): Phase A + B — purge all @deprecated APIs + cacheManager dead branches
PHASE A — every @deprecated marker resolved (~25 removed)

src/coreTypes.ts
- GraphVerb: dropped the "@deprecated Will be replaced by HNSWVerbWithMetadata"
  note. GraphVerb IS the canonical contract — every public API path speaks
  it. Removed the `source` and `target` legacy alias fields (renamed `from`
  / `to` callers years ago; no consumers remain).
- StorageAdapter: dropped the "@deprecated Use getNouns() with filter" notes
  from `getNounsByNounType`, `getVerbsBySource`, `getVerbsByTarget`,
  `getVerbsByType`. They were never deprecated in spirit — they're useful
  non-paginated convenience wrappers over the paginated `getNouns()` /
  `getVerbs()` surface. Refreshed JSDoc to explain the role.

src/types/graphTypes.ts
- Mirrored the GraphVerb cleanup: dropped `source` + `target` legacy aliases.
  sourceId + targetId are the canonical fields.

src/import/ImportCoordinator.ts
- Deleted the entire DeprecatedImportOptions interface block (130 LOC). It
  was a v3 → v4 migration tool using the `?: never` trick to force
  compile errors on dropped options. Five major versions in, the
  forced-error gate is no longer pulling its weight.

src/triple/TripleIntelligence.ts
- Deleted `TripleIntelligenceEngine = any` alias. No consumers; superseded
  by `TripleIntelligenceSystem`.

src/storage/cow/binaryDataCodec.ts
- Deleted `wrapBinaryData()`. The COW dispatch layer in `baseStorage.ts`
  routes by key-prefix convention; the old guess-by-JSON-parse codec was
  fragile (compressed bytes can accidentally parse as JSON) and unused.

src/storage/baseStorage.ts
- Refreshed JSDoc on `convertHNSWVerbToGraphVerb()` — the method is alive
  and used internally; the deprecation note was stale.

src/embeddings/wasm/AssetLoader.ts → DELETED
- File was @deprecated since model weights moved into the Candle WASM
  bundle. No consumers. Removed from `embeddings/wasm/index.ts` exports.

src/embeddings/wasm/types.ts
- Dropped @deprecated tags on `TokenizerConfig` + `TokenizedInput` — still
  used by `WordPieceTokenizer` (auxiliary tokenization). Deleted
  `InferenceConfig` (truly dead). Updated `embeddings/wasm/index.ts`
  exports.

src/utils/metadataIndex.ts
- Deleted `getIdsForCriteria()` — pure alias for `getIdsForFilter()`, no
  consumers.

src/interfaces/IIndex.ts
- Removed RebuildOptions.lazy (deprecated and unused; lazy mode is auto-
  selected by available-memory detection).

src/hnsw/hnswIndex.ts
- Removed `getNouns()` (returned a full Map; deprecated in favor of
  pagination years ago and no consumers in src/ or tests/).

PHASE B — cacheManager dead StorageType branches

src/storage/cacheManager.ts
- Collapsed the `isRemoteStorage` flag and its 15 dead conditional branches
  spanning calculateOptimalCacheSize() and calculateOptimalBatchSize().
  After dropping cloud adapters in step 7, `coldStorageType` is never S3
  or REMOTE_API; the branches were dead. Cache sizing and batch sizing now
  honor the filesystem-only reality with simpler heuristics.
- Collapsed `detectWarmStorageType()` + `detectColdStorageType()` from
  ~40 LOC of environment-+-availability branching to 2-line returns of
  `StorageType.FILESYSTEM`. Brainy 8.0 ships filesystem + memory only.

NOT YET — Phases C-G in follow-up commits

C: storageAutoConfig.ts + zeroConfig + extensibleConfig + sharedConfigManager
D: TODO/FIXME sweep across src/
E: skipped tests + the parallel-test race condition
F: docs deep clean (BATCHING, augmentations, READMEs)
G: browser support drop (the last 2 @deprecated)

VERIFICATION

- npx tsc --noEmit: clean
- npm test: 1408 / 1409 (same pre-existing race-condition outstanding)
2026-06-09 15:33:56 -07:00
f8dd93c93c fix: cancel abandoned highlight() semantic work and harden WASM engine recovery
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
2026-01-27 18:26:37 -08:00
364360d447 fix: exclude __words__ keyword index from corruption detection and getStats()
The __words__ keyword index stores 50-5000 entries per entity (one per
word), which inflated avg entries/entity well above the corruption
threshold of 100. This caused:

1. validateConsistency() to falsely detect corruption on every startup,
   triggering unnecessary clearAllIndexData() + rebuild() cycles
2. getStats() to log false "Metadata index may be corrupted" warnings
   and report inflated totalEntries/totalIds stats

Both methods now skip __words__ when counting, so stats and health
checks reflect metadata fields only (noun, type, createdAt, etc.).
Keyword search is unaffected since the __words__ field index itself
is not modified.
2026-01-27 15:38:21 -08:00
e62e74819e fix: bun --compile model loading with fallback paths
In bun --compile binaries, import.meta.url resolves to virtual paths.
Added fallback strategies to find model assets:

1. Pre-resolved paths (Bun runtime)
2. ./node_modules/@soulcraft/brainy/assets/ (npm installed)
3. ./assets/ (local development)

For Docker/Cloud Run deployment:
- Copy assets folder alongside binary
- Or keep node_modules structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 18:00:37 -08:00
677e2d6624 perf: 580x faster embedding init - separate model from WASM
Cloud Run cold starts taking 139 seconds due to 90MB WASM file with
embedded 87MB model weights. WASM compilation scales with file size.

Solution: Split into 2.4MB WASM (code only) + external model files.
- WASM compile: 139,000ms → 6-8ms
- Model load: N/A → 30-115ms
- Total init: 139,000ms → 136-240ms

New modelLoader.ts handles all environments:
- Node.js: fs.readFile()
- Bun: Bun.file()
- Bun --compile: auto-embedded assets
- Browser: fetch()

Zero config - same API, npm package includes model files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 17:18:58 -08:00
5d9ec5bb16 fix: resolve WASM loading for Bun --compile single-binary executables
Both roaring-wasm and candle-wasm now work correctly in all environments:
- Node.js (fs.readFileSync)
- Bun runtime (Bun.file)
- Bun --compile (embedded assets via import { type: 'file' })
- Browser (fetch)

roaring-wasm:
- Created src/utils/roaring/index.ts wrapper
- Uses browser bundle which has WASM embedded as base64
- Top-level await ensures initialization before use
- Zero environment detection needed (works everywhere)

candle-wasm:
- Created src/embeddings/wasm/wasmLoader.ts universal loader
- Uses Bun's import { type: 'file' } to embed 93MB WASM in compiled binary
- Fixed browser detection (Bun defines 'self', check for 'document' instead)
- Simplified CandleEmbeddingEngine.ts to use wasmLoader

Binary size verification:
- Minimal Bun binary: 100MB (runtime only)
- Brainy binary: 199MB (100MB runtime + 93MB WASM + 6MB JS)
- No duplication: WASM embedded exactly once

Test results:
- Node.js: 1190/1190 tests pass
- Bun runtime: 8/8 tests pass
- Bun --compile: 8/8 tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 14:09:02 -08:00
da7d2ed29d feat: migrate embeddings to Candle WASM + remove semantic type inference
Major architectural changes:

1. EMBEDDINGS ENGINE (ONNX → Candle WASM):
   - Replace ONNX Runtime with Rust Candle compiled to WASM
   - Embedded model in WASM binary (no external downloads)
   - Quantized Q8 precision with <50MB memory footprint
   - Zero-download, offline-first operation
   - Same embedding quality (all-MiniLM-L6-v2)

2. REMOVE SEMANTIC TYPE INFERENCE:
   - Delete embeddedKeywordEmbeddings.ts (14MB of pre-computed embeddings)
   - Remove typeAwareQueryPlanner.ts and semanticTypeInference.ts
   - Remove VerbExactMatchSignal (uses keyword embeddings)
   - Update SmartRelationshipExtractor to 3 signals (55%/30%/15% weights)

API CHANGES (requires v7.0.0):
- Removed: inferTypes(), inferNouns(), inferVerbs(), inferIntent()
- Removed: getSemanticTypeInference(), SemanticTypeInference class
- Removed: TypeInference, SemanticTypeInferenceOptions types

Users can still use natural language queries in find() - they just
need to specify type explicitly for type-optimized searches.

PACKAGE SIZE IMPACT:
- Compressed: 90.1 MB → 86.2 MB (-4.3%)
- Uncompressed: 114.4 MB → 100.3 MB (-12%)
- ~448K lines of code removed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 12:52:34 -08:00
1f59aa2013 feat: replace transformers.js with direct ONNX WASM for Bun compatibility
- 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
2025-12-17 17:42:37 -08:00