brainy/README.md
David Snelling 606445cd61 feat(8.0): API simplification — remove neural()/Db.search, one storage path key, integration→0
8.0 RC cleanup toward "one place per thing, zero-config, no deprecation":

- Remove the `brain.neural()` clustering namespace (ImprovedNeuralAPI + the dead
  legacy NeuralAPI + the neural CLI + neural-only types). Similarity is `find({vector})`
  / `similar({to})`; attribute grouping is the aggregation `GROUP BY` engine. The separate
  entity-extraction / smart-import feature (NeuralImport, NeuralEntityExtractor, SmartExtractor,
  NaturalLanguageProcessor, `brain.extract()`/`brain.nlp()`) is kept.
- Remove `Db.search()`; `find()` is the one query verb (accepts a bare string or FindParams).
  Fix the bundled MCP client, which called a non-existent `brain.search(query, limit)` →
  now `find({ query, limit })`.
- Storage config: collapse to one canonical top-level `path` key. The pre-8.0 aliases
  (`rootDirectory`, `options.*`, `fileSystemStorage.*`) are removed and now THROW with the
  exact rename instead of silently defaulting to `./brainy-data` on upgrade. A single resolver
  feeds createStorage, the 7.x→8.0 migration probe, and the plugin-factory handoff, so a native
  storage provider resolves the identical root (no split-brain).
- Fix `similar({ threshold })`: the min-similarity filter was silently dropped; it is now
  applied as a post-filter on `result.score` (the documented way to bound semantic results).
- Fix `vfs.rename()` on a directory: child path updates spread the entity vector into `update()`
  and failed dimension validation; they are metadata-only updates now.
- Fix `vfs.move()`: copy+delete orphaned the content-addressed content blob (the destination
  shared the source hash, then unlink removed it). `move()` now delegates to `rename()` — an
  in-place path change that preserves the blob and the entity id, for files and directories.
- Fix streaming import: the bulk fast path never flushed mid-import nor signalled queryability.
  Entity writes are now chunked by a progressive flush interval (100 → 1000 → 5000); each chunk
  flushes and emits `progress.queryable`, so imported data is queryable during the import.
- Sweep all docs, comments, and JSDoc for the removed/changed APIs.

Integration suite: 49 files / 588 passed / 0 failed. Unit: 80 files / 1456 passed, no type errors.
2026-06-20 13:31:11 -07:00

16 KiB
Raw Permalink Blame History

Brainy

Brainy Logo

npm version npm downloads Documentation MIT License TypeScript

Three database paradigms. One API. Zero configuration.

Built because we were tired of stitching together Pinecone + Neo4j + MongoDB and spending weeks on configuration before writing a single line of business logic. Brainy unifies vector search, graph traversal, and metadata filtering so you don't have to choose.

New here?What is Brainy? — plain-language overview, no jargon


Install

npm install @soulcraft/brainy

Quick Start

import { Brainy, NounType, VerbType } from '@soulcraft/brainy'

const brain = new Brainy()
await brain.init()

// Add knowledge — text auto-embeds, metadata auto-indexes
const reactId = await brain.add({
  data: 'React is a JavaScript library for building user interfaces',
  type: NounType.Concept,
  metadata: { category: 'frontend', year: 2013 }
})

const nextId = await brain.add({
  data: 'Next.js framework for React with server-side rendering',
  type: NounType.Concept,
  metadata: { category: 'framework', year: 2016 }
})

// Create a relationship
await brain.relate({ from: nextId, to: reactId, type: VerbType.BuiltOn })

// Query all three paradigms at once
const results = await brain.find({
  query: 'modern frontend frameworks',            // Vector similarity
  where: { year: { greaterThan: 2015 } },         // Metadata filtering
  connected: { to: reactId, depth: 2 }            // Graph traversal
})

Full API Reference | soulcraft.com/docs


Three Indexes, One Query

Every piece of knowledge lives in three indexes simultaneously:

  • dataVector index — Content for semantic search. Strings auto-embed into 384-dim vectors. Queried with find({ query: '...' }).
  • metadataMetadata index — Structured fields for filtering. O(1) lookups. Queried with find({ where: { ... } }).
  • relate()Graph index — Typed, directed relationships between entities. Traversed with find({ connected: { ... } }).
// Data → vector index (semantic search)
const articleId = await brain.add({
  data: 'A deep dive into transformer architectures',
  type: NounType.Document,
  metadata: { author: 'Dr. Chen', year: 2024, tags: ['AI'] }  // → metadata index
})

// Relationships → graph index
await brain.relate({ from: authorId, to: articleId, type: VerbType.Authored })

// Query all three at once
brain.find({
  query: 'attention mechanisms',                  // Vector similarity
  where: { year: { greaterThan: 2023 } },         // Metadata filter
  connected: { from: authorId, depth: 1 }         // Graph traversal
})

Data Model Reference | Query Operators


Features

Triple Intelligence

Vector search + graph traversal + metadata filtering in every query. No stitching services together — one find() call combines all three.

const results = await brain.find({
  query: 'machine learning',
  where: { department: 'engineering', level: 'senior' },
  connected: { from: teamLeadId, via: VerbType.WorksWith, depth: 2 }
})

Automatically combines keyword (text) and semantic (vector) search. No configuration needed.

await brain.find({ query: 'David Smith' })             // Auto: text + semantic
await brain.find({ query: 'AI concepts', searchMode: 'semantic' })  // Semantic only
await brain.find({ query: 'exact id', searchMode: 'text' })         // Text only

Query Operators

Filter metadata with equality, comparison, array, existence, pattern, and logical operators:

await brain.find({
  where: {
    status: 'active',                          // Exact match
    score: { greaterThan: 90 },                // Comparison
    tags: { contains: 'ai' },                  // Array
    anyOf: [{ role: 'admin' }, { role: 'owner' }]  // Logical OR
  }
})

Query Operators Reference — all operators with indexed/in-memory matrix

Graph Relationships

Typed, directed edges between entities. Traverse connections at any depth.

await brain.relate({ from: personId, to: projectId, type: VerbType.WorksOn })

const results = await brain.find({
  connected: { from: personId, via: VerbType.WorksOn, depth: 3 }
})

Database as a Value

The whole database, pinned as an immutable value. Snapshot isolation, time travel, atomic transactions, instant hard-link snapshots.

const db = brain.now()                         // Pin current state — O(1)

// Atomic multi-write transaction (all-or-nothing, with CAS)
await brain.transact([
  { op: 'update', id: orderId, metadata: { status: 'paid' } },
  { op: 'relate', from: invoiceId, to: orderId, type: VerbType.References, subtype: 'billing' }
], { meta: { author: 'billing-service' }, ifAtGeneration: db.generation })

await db.get(orderId)                          // Still 'pending' — pinned, forever
await brain.get(orderId)                       // 'paid' — live

// Time travel: full query surface at any past state
const yesterday = await brain.asOf(new Date(Date.now() - 86_400_000))
const past = await yesterday.find({ query: 'unpaid orders' })

// What-if: speculative writes, nothing touches disk
const whatIf = await db.with([{ op: 'remove', id: orderId }])

// Instant backup: hard-link snapshot, opens read-only with Brainy.load()
await brain.now().persist('/backups/today')

Consistency Model | Snapshots & Time Travel

Virtual Filesystem

File operations with semantic search built in.

const vfs = brain.vfs

await vfs.writeFile('/docs/readme.md', 'Project documentation')
const content = await vfs.readFile('/docs/readme.md')
const tree = await vfs.getTreeStructure('/docs', { maxDepth: 3 })

// Semantic file search
const matches = await vfs.search('React components with hooks')

VFS Quick Start | Common Patterns

Import Anything

CSV, Excel, PDF, URLs — auto-detected format, auto-classified entities.

await brain.import('customers.csv')
await brain.import('sales-data.xlsx')                              // all sheets processed
await brain.import('research-paper.pdf')                           // tables extracted automatically
await brain.import('https://api.example.com/data.json')
await brain.import('./handbook.md', { vfsPath: '/imports/handbook' })  // preserve in VFS

Import Guide

Entity Extraction

AI-powered named entity recognition with 4-signal ensemble scoring.

const entities = await brain.extractEntities('John Smith founded Acme Corp in New York')
// [
//   { text: 'John Smith', type: NounType.Person, confidence: 0.95 },
//   { text: 'Acme Corp', type: NounType.Organization, confidence: 0.92 },
//   { text: 'New York', type: NounType.Location, confidence: 0.88 }
// ]

Neural Extraction Guide

Plugin System

Optional native acceleration via @soulcraft/cortex — SIMD distance calculations, CRoaring bitmaps, Candle ML embeddings.

const brain = new Brainy({ plugins: ['@soulcraft/cortex'] })
await brain.init()

Plugins are opt-in. Brainy never auto-imports packages unless listed in plugins.

Plugin Documentation


Type System

42 noun types and 127 verb types form a universal knowledge protocol:

42 Nouns × 127 Verbs = 5,334 base relationship combinations

Model any domain — healthcare (Patient → diagnoses → Condition), finance (Account → transfers → Transaction), education (Student → completes → Course), or your own.

Subtypes — sub-classification within a NounType or VerbType

Both noun types and verb types are intentionally coarse. Use the top-level subtype field to sub-classify entities AND relationships within a type — flat string, no hierarchy, your choice of vocabulary:

// Nouns: sub-classify entities
await brain.add({
  data: 'Avery Brooks — runs the AI lab',
  type: NounType.Person,
  subtype: 'employee'                 // 'customer', 'vendor', 'contractor', …
})

// Verbs: sub-classify relationships
await brain.relate({
  from: ceoId,
  to: vpId,
  type: VerbType.ReportsTo,
  subtype: 'direct'                   // 'dotted-line', 'matrix', …
})

// Filter on the fast path — column-store hit, not metadata fallback:
const employees = await brain.find({ type: NounType.Person, subtype: 'employee' })
const directReports = await brain.related({ from: ceoId, subtype: 'direct' })

// O(1) counts via the persisted rollups:
brain.counts.bySubtype(NounType.Person)
// → { employee: 12, customer: 847, vendor: 34 }

brain.counts.byRelationshipSubtype(VerbType.ReportsTo)
// → { direct: 12, 'dotted-line': 3 }

Enforce the pairing. Register a vocabulary per type or turn on brain-wide strict mode to ensure every entity AND relationship has both type AND subtype:

// Per-type rule with a closed vocabulary
brain.requireSubtype(NounType.Person, { values: ['employee', 'customer'], required: true })

// 8.0 default: every write requires a subtype. Exempt genuine catch-all types…
const brain = new Brainy({ requireSubtype: { except: [NounType.Thing] } })

// …or opt out while migrating pre-8.0 data, then audit and back-fill:
const legacy = new Brainy({ requireSubtype: false })
await legacy.audit()                                      // gaps, grouped by type
await legacy.fillSubtypes({ [NounType.Person]: 'unspecified' })  // close them

For other facets you want counted (status, source, role), register them with brain.trackField(name). Renaming an existing convention to subtype? Use brain.migrateField({from, to, entityKind: 'both'}) to walk nouns AND verbs in one pass. Full guide: Subtypes & Facets.

Noun-Verb Taxonomy | Stage 3 Canonical Reference


Storage: Memory and Filesystem

The same API at every scale. Change one config line to go from prototype to production.

Development — Zero Config

const brain = new Brainy()

Production — Filesystem (gzip compression on by default)

const brain = new Brainy({
  storage: { type: 'filesystem', path: './data' }
})

Backups and Portability — Snapshots

const db = brain.now()
await db.persist('/backups/2026-06-11')   // instant hard-link snapshot
await db.release()

const snapshot = await Brainy.load('/backups/2026-06-11')  // read-only Db
const hits = await snapshot.find({ query: 'quarterly invoices' })
await snapshot.release()

A snapshot directory is self-contained — copy it to another machine, open it with Brainy.load(), or restore it wholesale with brain.restore(path, { confirm: true }).

Performance benchmarks and capacity planning in docs/PERFORMANCE.md.

Capacity Planning


Use Cases

  • AI agents — Persistent memory with semantic recall and relationship tracking
  • Knowledge bases — Auto-linking, semantic search, relationship-aware navigation
  • Semantic search — Find by meaning across codebases, documents, or media
  • Enterprise knowledge — CRM, product catalogs, institutional memory
  • Interactive experiences — Game worlds, NPCs, and characters that remember
  • Content platforms — Similarity-based discovery, intelligent tagging

Documentation

Start Here

Core

Architecture

Virtual Filesystem

Guides

Operations


Requirements

Bun 1.0+ (recommended) or Node.js 22 LTS

bun install @soulcraft/brainy    # Bun — best performance
npm install @soulcraft/brainy    # Node.js — fully supported

Brainy 8.0 is server-only. Browser support (OPFS storage, Web Workers, in-browser WASM embeddings) was removed in 8.0 — the 7.x line remains available on npm if you need it.

Single-Writer Model

Brainy is single-writer, many-reader on filesystem storage. One writer holds an exclusive lock on the data directory; any number of readers can inspect it concurrently. Opening a second writer throws with the PID of the existing one.

// Live application — writer mode is the default
const brain = new Brainy({ storage: { type: 'filesystem', path: '/data/brain' } })
await brain.init()

// Out-of-band diagnostics from a separate process — safe to run while the
// writer is live
const reader = await Brainy.openReadOnly({
  storage: { type: 'filesystem', path: '/data/brain' }
})
await reader.requestFlush({ timeoutMs: 5000 })
const stats = await reader.stats()

For incident debugging, use the brainy inspect CLI:

brainy inspect stats   /data/brain
brainy inspect find    /data/brain --where '{"entityType":"booking"}'
brainy inspect explain /data/brain --where '{"entityType":"booking"}'
brainy inspect health  /data/brain

See the multi-process model and the inspection guide for the full story, including stale-lock detection and the cross-process flush RPC.

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

License

MIT © Brainy Contributors