2025-09-11 16:23:32 -07:00
|
|
|
|
/**
|
|
|
|
|
|
* 🧠 Brainy 3.0 Type Definitions
|
|
|
|
|
|
*
|
|
|
|
|
|
* Beautiful, consistent, type-safe interfaces for the future of neural databases
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import { Vector } from '../coreTypes.js'
|
|
|
|
|
|
import { NounType, VerbType } from './graphTypes.js'
|
|
|
|
|
|
|
|
|
|
|
|
// ============= Core Types =============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
* Entity (Noun) — the fundamental data unit in Brainy
|
|
|
|
|
|
*
|
|
|
|
|
|
* **Data vs Metadata:**
|
|
|
|
|
|
* - `data`: Content used for vector embeddings. Searchable via **semantic similarity**
|
|
|
|
|
|
* (HNSW index) and hybrid text+semantic search. NOT queryable via `where` filters.
|
|
|
|
|
|
* - `metadata`: Structured fields indexed by MetadataIndex. Queryable via `where`
|
|
|
|
|
|
* filters in `find()`. Standard system fields (noun, createdAt, etc.) are stored
|
|
|
|
|
|
* alongside user metadata but extracted to top-level Entity fields on read.
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface Entity<T = any> {
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Unique identifier (UUID v4) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
id: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Embedding vector (384-dim by default). Empty array when loaded without includeVectors. */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
vector: Vector
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Entity type classification (NounType enum) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
type: NounType
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Opaque content — used for embeddings and semantic search. Not indexed by MetadataIndex. */
|
2025-09-12 12:36:11 -07:00
|
|
|
|
data?: any
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** User-defined structured fields — indexed and queryable via `where` filters. */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
metadata?: T
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Multi-tenancy service identifier */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
service?: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Creation timestamp (ms since epoch) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
createdAt: number
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Last update timestamp (ms since epoch) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
updatedAt?: number
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Source that created this entity (e.g., augmentation info) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
createdBy?: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Type classification confidence (0-1) */
|
|
|
|
|
|
confidence?: number
|
|
|
|
|
|
/** Entity importance/salience (0-1) */
|
|
|
|
|
|
weight?: number
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
* Relation (Verb) — a typed edge connecting two entities
|
|
|
|
|
|
*
|
|
|
|
|
|
* **Data vs Metadata (on relationships):**
|
|
|
|
|
|
* - `data`: Opaque content stored on the relationship. If provided during relate(),
|
|
|
|
|
|
* overrides the auto-computed vector (default: average of source+target vectors).
|
|
|
|
|
|
* - `metadata`: Structured queryable fields on the edge (e.g., role, startDate).
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface Relation<T = any> {
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Unique identifier (UUID v4) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
id: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Source entity ID */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
from: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Target entity ID */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
to: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Relationship type classification (VerbType enum) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
type: VerbType
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Connection strength (0-1, default: 1.0) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
weight?: number
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Opaque content for the relationship (overrides auto-computed vector if provided) */
|
|
|
|
|
|
data?: any
|
|
|
|
|
|
/** User-defined structured fields on the edge */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
metadata?: T
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Multi-tenancy service identifier */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
service?: string
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Creation timestamp (ms since epoch) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
createdAt: number
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Last update timestamp (ms since epoch) */
|
2025-09-11 16:23:32 -07:00
|
|
|
|
updatedAt?: number
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Relationship certainty (0-1) */
|
|
|
|
|
|
confidence?: number
|
|
|
|
|
|
/** Evidence for why this relationship was detected */
|
2025-10-01 15:12:54 -07:00
|
|
|
|
evidence?: RelationEvidence
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Evidence for why a relationship was detected
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface RelationEvidence {
|
|
|
|
|
|
sourceText?: string // Text that indicated this relationship
|
|
|
|
|
|
position?: { // Position in source text
|
|
|
|
|
|
start: number
|
|
|
|
|
|
end: number
|
|
|
|
|
|
}
|
|
|
|
|
|
method: 'neural' | 'pattern' | 'structural' | 'explicit' // How it was detected
|
|
|
|
|
|
reasoning?: string // Human-readable explanation
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Search result with similarity score
|
feat: add confidence/weight to Entity and flatten Result fields for convenient access
Add confidence and weight properties to Entity interface and flatten Result fields to top level for improved developer experience and API consistency.
Breaking Changes: None (all changes are backward compatible)
Phase 2 - Entity Confidence & Weight:
- Add confidence (type classification certainty) and weight (entity importance) to Entity interface
- Add confidence/weight parameters to AddParams and UpdateParams
- Update convertNounToEntity() to extract confidence/weight from storage
- Update add() and update() methods to preserve confidence/weight in metadata
- Enable developers to specify and access entity confidence/weight scores
Phase 3 - Result Field Flattening:
- Flatten commonly-used entity fields (type, metadata, data, confidence, weight) to Result top level
- Add createResult() helper for consistent Result construction
- Update all find() code paths to use createResult()
- Enable direct access: result.metadata instead of result.entity.metadata
- Preserve full entity in result.entity for backward compatibility
VFS Fix (from previous work):
- Fix VFSStructureGenerator to use brain.vfs() cached instance instead of creating separate instance
- Improve VFS error messages with step-by-step guidance
- Update examples to show correct vfs.init() usage
- Add comprehensive VFS import verification tests
Documentation Updates:
- Update API_REFERENCE.md with confidence/weight examples and flattened Result documentation
- Enhance JSDoc for add(), get(), find(), similar() with v4.3.0 examples
- Document Result structure changes and backward compatibility
- Add migration examples showing both old and new access patterns
Tests:
- Add 16 comprehensive tests for Entity confidence/weight exposure
- Add tests for Result field flattening
- Add tests for backward compatibility
- All tests passing (16/16)
API Consistency:
- Entity: direct access to confidence/weight
- Result: flattened fields + nested entity (both work)
- Relation: already had confidence/weight (consistent)
- VFS: inherits from Entity (automatic)
Files Changed:
- src/types/brainy.types.ts - Updated Entity, AddParams, UpdateParams, Result interfaces
- src/brainy.ts - Updated implementation and JSDoc for all affected methods
- tests/integration/entity-confidence-weight.test.ts - 16 comprehensive tests
- docs/API_REFERENCE.md - Updated with v4.3.0 examples
- src/importers/VFSStructureGenerator.ts - VFS fix
- src/vfs/VirtualFileSystem.ts - Improved error messages
- examples/unified-import-example.ts - Added vfs.init() example
- tests/integration/vfs-*-verification.test.ts - VFS verification tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:19:50 -07:00
|
|
|
|
*
|
|
|
|
|
|
* Flattens commonly-used entity fields to top level for convenience,
|
|
|
|
|
|
* while preserving full entity in 'entity' field for backward compatibility.
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface Result<T = any> {
|
feat: add confidence/weight to Entity and flatten Result fields for convenient access
Add confidence and weight properties to Entity interface and flatten Result fields to top level for improved developer experience and API consistency.
Breaking Changes: None (all changes are backward compatible)
Phase 2 - Entity Confidence & Weight:
- Add confidence (type classification certainty) and weight (entity importance) to Entity interface
- Add confidence/weight parameters to AddParams and UpdateParams
- Update convertNounToEntity() to extract confidence/weight from storage
- Update add() and update() methods to preserve confidence/weight in metadata
- Enable developers to specify and access entity confidence/weight scores
Phase 3 - Result Field Flattening:
- Flatten commonly-used entity fields (type, metadata, data, confidence, weight) to Result top level
- Add createResult() helper for consistent Result construction
- Update all find() code paths to use createResult()
- Enable direct access: result.metadata instead of result.entity.metadata
- Preserve full entity in result.entity for backward compatibility
VFS Fix (from previous work):
- Fix VFSStructureGenerator to use brain.vfs() cached instance instead of creating separate instance
- Improve VFS error messages with step-by-step guidance
- Update examples to show correct vfs.init() usage
- Add comprehensive VFS import verification tests
Documentation Updates:
- Update API_REFERENCE.md with confidence/weight examples and flattened Result documentation
- Enhance JSDoc for add(), get(), find(), similar() with v4.3.0 examples
- Document Result structure changes and backward compatibility
- Add migration examples showing both old and new access patterns
Tests:
- Add 16 comprehensive tests for Entity confidence/weight exposure
- Add tests for Result field flattening
- Add tests for backward compatibility
- All tests passing (16/16)
API Consistency:
- Entity: direct access to confidence/weight
- Result: flattened fields + nested entity (both work)
- Relation: already had confidence/weight (consistent)
- VFS: inherits from Entity (automatic)
Files Changed:
- src/types/brainy.types.ts - Updated Entity, AddParams, UpdateParams, Result interfaces
- src/brainy.ts - Updated implementation and JSDoc for all affected methods
- tests/integration/entity-confidence-weight.test.ts - 16 comprehensive tests
- docs/API_REFERENCE.md - Updated with v4.3.0 examples
- src/importers/VFSStructureGenerator.ts - VFS fix
- src/vfs/VirtualFileSystem.ts - Improved error messages
- examples/unified-import-example.ts - Added vfs.init() example
- tests/integration/vfs-*-verification.test.ts - VFS verification tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:19:50 -07:00
|
|
|
|
// Search metadata
|
2025-09-11 16:23:32 -07:00
|
|
|
|
id: string
|
|
|
|
|
|
score: number
|
feat: add confidence/weight to Entity and flatten Result fields for convenient access
Add confidence and weight properties to Entity interface and flatten Result fields to top level for improved developer experience and API consistency.
Breaking Changes: None (all changes are backward compatible)
Phase 2 - Entity Confidence & Weight:
- Add confidence (type classification certainty) and weight (entity importance) to Entity interface
- Add confidence/weight parameters to AddParams and UpdateParams
- Update convertNounToEntity() to extract confidence/weight from storage
- Update add() and update() methods to preserve confidence/weight in metadata
- Enable developers to specify and access entity confidence/weight scores
Phase 3 - Result Field Flattening:
- Flatten commonly-used entity fields (type, metadata, data, confidence, weight) to Result top level
- Add createResult() helper for consistent Result construction
- Update all find() code paths to use createResult()
- Enable direct access: result.metadata instead of result.entity.metadata
- Preserve full entity in result.entity for backward compatibility
VFS Fix (from previous work):
- Fix VFSStructureGenerator to use brain.vfs() cached instance instead of creating separate instance
- Improve VFS error messages with step-by-step guidance
- Update examples to show correct vfs.init() usage
- Add comprehensive VFS import verification tests
Documentation Updates:
- Update API_REFERENCE.md with confidence/weight examples and flattened Result documentation
- Enhance JSDoc for add(), get(), find(), similar() with v4.3.0 examples
- Document Result structure changes and backward compatibility
- Add migration examples showing both old and new access patterns
Tests:
- Add 16 comprehensive tests for Entity confidence/weight exposure
- Add tests for Result field flattening
- Add tests for backward compatibility
- All tests passing (16/16)
API Consistency:
- Entity: direct access to confidence/weight
- Result: flattened fields + nested entity (both work)
- Relation: already had confidence/weight (consistent)
- VFS: inherits from Entity (automatic)
Files Changed:
- src/types/brainy.types.ts - Updated Entity, AddParams, UpdateParams, Result interfaces
- src/brainy.ts - Updated implementation and JSDoc for all affected methods
- tests/integration/entity-confidence-weight.test.ts - 16 comprehensive tests
- docs/API_REFERENCE.md - Updated with v4.3.0 examples
- src/importers/VFSStructureGenerator.ts - VFS fix
- src/vfs/VirtualFileSystem.ts - Improved error messages
- examples/unified-import-example.ts - Added vfs.init() example
- tests/integration/vfs-*-verification.test.ts - VFS verification tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:19:50 -07:00
|
|
|
|
|
|
|
|
|
|
// Convenience: Common entity fields flattened to top level
|
|
|
|
|
|
type?: NounType // Entity type (from entity.type)
|
|
|
|
|
|
metadata?: T // Entity metadata (from entity.metadata)
|
|
|
|
|
|
data?: any // Entity data (from entity.data)
|
|
|
|
|
|
confidence?: number // Type classification confidence (from entity.confidence)
|
|
|
|
|
|
weight?: number // Entity importance (from entity.weight)
|
|
|
|
|
|
|
|
|
|
|
|
// Full entity (preserved for backward compatibility)
|
2025-09-11 16:23:32 -07:00
|
|
|
|
entity: Entity<T>
|
feat: add confidence/weight to Entity and flatten Result fields for convenient access
Add confidence and weight properties to Entity interface and flatten Result fields to top level for improved developer experience and API consistency.
Breaking Changes: None (all changes are backward compatible)
Phase 2 - Entity Confidence & Weight:
- Add confidence (type classification certainty) and weight (entity importance) to Entity interface
- Add confidence/weight parameters to AddParams and UpdateParams
- Update convertNounToEntity() to extract confidence/weight from storage
- Update add() and update() methods to preserve confidence/weight in metadata
- Enable developers to specify and access entity confidence/weight scores
Phase 3 - Result Field Flattening:
- Flatten commonly-used entity fields (type, metadata, data, confidence, weight) to Result top level
- Add createResult() helper for consistent Result construction
- Update all find() code paths to use createResult()
- Enable direct access: result.metadata instead of result.entity.metadata
- Preserve full entity in result.entity for backward compatibility
VFS Fix (from previous work):
- Fix VFSStructureGenerator to use brain.vfs() cached instance instead of creating separate instance
- Improve VFS error messages with step-by-step guidance
- Update examples to show correct vfs.init() usage
- Add comprehensive VFS import verification tests
Documentation Updates:
- Update API_REFERENCE.md with confidence/weight examples and flattened Result documentation
- Enhance JSDoc for add(), get(), find(), similar() with v4.3.0 examples
- Document Result structure changes and backward compatibility
- Add migration examples showing both old and new access patterns
Tests:
- Add 16 comprehensive tests for Entity confidence/weight exposure
- Add tests for Result field flattening
- Add tests for backward compatibility
- All tests passing (16/16)
API Consistency:
- Entity: direct access to confidence/weight
- Result: flattened fields + nested entity (both work)
- Relation: already had confidence/weight (consistent)
- VFS: inherits from Entity (automatic)
Files Changed:
- src/types/brainy.types.ts - Updated Entity, AddParams, UpdateParams, Result interfaces
- src/brainy.ts - Updated implementation and JSDoc for all affected methods
- tests/integration/entity-confidence-weight.test.ts - 16 comprehensive tests
- docs/API_REFERENCE.md - Updated with v4.3.0 examples
- src/importers/VFSStructureGenerator.ts - VFS fix
- src/vfs/VirtualFileSystem.ts - Improved error messages
- examples/unified-import-example.ts - Added vfs.init() example
- tests/integration/vfs-*-verification.test.ts - VFS verification tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:19:50 -07:00
|
|
|
|
|
|
|
|
|
|
// Score transparency
|
2025-09-11 16:23:32 -07:00
|
|
|
|
explanation?: ScoreExplanation
|
2026-01-26 17:16:18 -08:00
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// Match visibility - shows what matched in hybrid search
|
2026-01-26 17:16:18 -08:00
|
|
|
|
textMatches?: string[] // Query words found in entity (e.g., ["david", "warrior"])
|
|
|
|
|
|
textScore?: number // Normalized text match score (0-1)
|
|
|
|
|
|
semanticScore?: number // Semantic similarity score (0-1)
|
|
|
|
|
|
matchSource?: 'text' | 'semantic' | 'both' // Where this result came from
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
rrfScore?: number // Raw RRF fusion score (for advanced ranking analysis)
|
2026-05-26 11:32:46 -07:00
|
|
|
|
|
|
|
|
|
|
// Aggregation: present only on rows returned by find({ aggregate }). These mirror the
|
|
|
|
|
|
// documented AggregateResult shape so callers can read group/metric data at the top level
|
|
|
|
|
|
// instead of digging into `metadata`. (The same values are also flattened into `metadata`
|
|
|
|
|
|
// for backward compatibility.)
|
|
|
|
|
|
groupKey?: Record<string, string | number> // Group-by key values for this aggregate row
|
|
|
|
|
|
metrics?: Record<string, number> // Computed metric values (sum/avg/min/max/count)
|
|
|
|
|
|
count?: number // Total entity count in this group
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Score explanation for transparency
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ScoreExplanation {
|
|
|
|
|
|
vectorScore?: number
|
|
|
|
|
|
metadataScore?: number
|
|
|
|
|
|
graphScore?: number
|
|
|
|
|
|
boosts?: Record<string, number>
|
|
|
|
|
|
penalties?: Record<string, number>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============= Operation Parameters =============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameters for adding entities
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
*
|
|
|
|
|
|
* **Data vs Metadata:**
|
|
|
|
|
|
* - `data` is embedded into a vector and searchable via semantic similarity (HNSW).
|
|
|
|
|
|
* It is NOT indexed by MetadataIndex and NOT queryable via `where` filters.
|
|
|
|
|
|
* - `metadata` is indexed by MetadataIndex and queryable via `where` filters in `find()`.
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface AddParams<T = any> {
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Content to embed and store. Strings are auto-embedded; objects are JSON-stringified for embedding. */
|
|
|
|
|
|
data: any | Vector
|
|
|
|
|
|
/** Entity type classification (required) */
|
|
|
|
|
|
type: NounType
|
|
|
|
|
|
/** Structured queryable fields — indexed by MetadataIndex, used in `where` filters */
|
|
|
|
|
|
metadata?: T
|
|
|
|
|
|
/** Custom entity ID (auto-generated UUID v4 if not provided) */
|
|
|
|
|
|
id?: string
|
|
|
|
|
|
/** Pre-computed embedding vector (skips auto-embedding when provided) */
|
|
|
|
|
|
vector?: Vector
|
|
|
|
|
|
/** Multi-tenancy service identifier */
|
|
|
|
|
|
service?: string
|
|
|
|
|
|
/** Type classification confidence (0-1) */
|
|
|
|
|
|
confidence?: number
|
|
|
|
|
|
/** Entity importance/salience (0-1) */
|
|
|
|
|
|
weight?: number
|
|
|
|
|
|
/** Track which augmentation created this entity */
|
|
|
|
|
|
createdBy?: { augmentation: string; version: string }
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameters for updating entities
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface UpdateParams<T = any> {
|
|
|
|
|
|
id: string // Entity to update
|
|
|
|
|
|
data?: any // New content to re-embed
|
|
|
|
|
|
type?: NounType // Change type
|
|
|
|
|
|
metadata?: Partial<T> // Metadata to update
|
|
|
|
|
|
merge?: boolean // Merge or replace metadata (default: true)
|
|
|
|
|
|
vector?: Vector // New pre-computed vector
|
feat: add confidence/weight to Entity and flatten Result fields for convenient access
Add confidence and weight properties to Entity interface and flatten Result fields to top level for improved developer experience and API consistency.
Breaking Changes: None (all changes are backward compatible)
Phase 2 - Entity Confidence & Weight:
- Add confidence (type classification certainty) and weight (entity importance) to Entity interface
- Add confidence/weight parameters to AddParams and UpdateParams
- Update convertNounToEntity() to extract confidence/weight from storage
- Update add() and update() methods to preserve confidence/weight in metadata
- Enable developers to specify and access entity confidence/weight scores
Phase 3 - Result Field Flattening:
- Flatten commonly-used entity fields (type, metadata, data, confidence, weight) to Result top level
- Add createResult() helper for consistent Result construction
- Update all find() code paths to use createResult()
- Enable direct access: result.metadata instead of result.entity.metadata
- Preserve full entity in result.entity for backward compatibility
VFS Fix (from previous work):
- Fix VFSStructureGenerator to use brain.vfs() cached instance instead of creating separate instance
- Improve VFS error messages with step-by-step guidance
- Update examples to show correct vfs.init() usage
- Add comprehensive VFS import verification tests
Documentation Updates:
- Update API_REFERENCE.md with confidence/weight examples and flattened Result documentation
- Enhance JSDoc for add(), get(), find(), similar() with v4.3.0 examples
- Document Result structure changes and backward compatibility
- Add migration examples showing both old and new access patterns
Tests:
- Add 16 comprehensive tests for Entity confidence/weight exposure
- Add tests for Result field flattening
- Add tests for backward compatibility
- All tests passing (16/16)
API Consistency:
- Entity: direct access to confidence/weight
- Result: flattened fields + nested entity (both work)
- Relation: already had confidence/weight (consistent)
- VFS: inherits from Entity (automatic)
Files Changed:
- src/types/brainy.types.ts - Updated Entity, AddParams, UpdateParams, Result interfaces
- src/brainy.ts - Updated implementation and JSDoc for all affected methods
- tests/integration/entity-confidence-weight.test.ts - 16 comprehensive tests
- docs/API_REFERENCE.md - Updated with v4.3.0 examples
- src/importers/VFSStructureGenerator.ts - VFS fix
- src/vfs/VirtualFileSystem.ts - Improved error messages
- examples/unified-import-example.ts - Added vfs.init() example
- tests/integration/vfs-*-verification.test.ts - VFS verification tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:19:50 -07:00
|
|
|
|
confidence?: number // Update type classification confidence
|
|
|
|
|
|
weight?: number // Update entity importance/salience
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameters for creating relationships
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
*
|
|
|
|
|
|
* **Data vs Metadata (on relationships):**
|
|
|
|
|
|
* - `data`: Opaque content for the edge. If provided, overrides the auto-computed
|
|
|
|
|
|
* vector (default: average of source+target entity vectors).
|
|
|
|
|
|
* - `metadata`: Structured queryable fields on the edge.
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface RelateParams<T = any> {
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Source entity ID (required — must exist) */
|
|
|
|
|
|
from: string
|
|
|
|
|
|
/** Target entity ID (required — must exist) */
|
|
|
|
|
|
to: string
|
|
|
|
|
|
/** Relationship type classification (required) */
|
|
|
|
|
|
type: VerbType
|
|
|
|
|
|
/** Connection strength (0-1, default: 1.0) */
|
|
|
|
|
|
weight?: number
|
|
|
|
|
|
/** Content for the relationship (optional — overrides auto-computed vector) */
|
|
|
|
|
|
data?: any
|
|
|
|
|
|
/** Structured queryable fields on the edge */
|
|
|
|
|
|
metadata?: T
|
|
|
|
|
|
/** Create reverse edge too (default: false) */
|
|
|
|
|
|
bidirectional?: boolean
|
|
|
|
|
|
/** Multi-tenancy service identifier */
|
|
|
|
|
|
service?: string
|
|
|
|
|
|
/** Relationship certainty (0-1) */
|
|
|
|
|
|
confidence?: number
|
|
|
|
|
|
/** Evidence for why this relationship exists */
|
|
|
|
|
|
evidence?: RelationEvidence
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameters for updating relationships
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface UpdateRelationParams<T = any> {
|
|
|
|
|
|
id: string // Relation to update
|
|
|
|
|
|
weight?: number // New weight
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
data?: any // New content
|
2025-09-11 16:23:32 -07:00
|
|
|
|
metadata?: Partial<T> // Metadata to update
|
|
|
|
|
|
merge?: boolean // Merge or replace metadata
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============= Query Parameters =============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
* Unified find parameters — Triple Intelligence search
|
|
|
|
|
|
*
|
|
|
|
|
|
* Combines three search dimensions in one query:
|
|
|
|
|
|
* - **Vector:** `query` or `vector` for semantic/hybrid similarity search (searches `data`)
|
|
|
|
|
|
* - **Metadata:** `where` for structured field filters (queries `metadata` via MetadataIndex)
|
|
|
|
|
|
* - **Graph:** `connected` for relationship traversal (via GraphAdjacencyIndex)
|
|
|
|
|
|
*
|
|
|
|
|
|
* See also: [Query Operators](../../docs/QUERY_OPERATORS.md) for all `where` operators.
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface FindParams<T = any> {
|
|
|
|
|
|
// Vector Intelligence
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Natural language or semantic search query (embedded and matched via HNSW + text index) */
|
|
|
|
|
|
query?: string
|
|
|
|
|
|
/** Direct vector search (pre-computed embedding) */
|
|
|
|
|
|
vector?: Vector
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
// Metadata Intelligence
|
feat: enforce data/metadata separation, numeric range queries, improved docs
- Store data opaquely in add() and update() instead of spreading object
properties into top-level metadata. data is for semantic search (HNSW),
metadata is for structured where-filter queries (MetadataIndex).
- Fix numeric range queries in MetadataIndex — use numeric-aware comparison
instead of lexicographic string comparison for normalized values.
- Add data field to RelateParams and Relation types for relationship content.
- Add where.type → where.noun alias in metadata-only find() path.
- Rewrite README: focused ~350 lines from 791, quick start first, feature
showcase with mini-snippets, organized doc links, no version callouts.
- Add DATA_MODEL.md and QUERY_OPERATORS.md reference docs.
- Remove 10 outdated/redundant doc files consolidated into API reference.
- Improve JSDoc on Entity, Relation, AddParams, FindParams, and core methods.
- Fix tests asserting data properties appear in metadata (data model violation).
- Deprecate verb.source/target in favor of from/to (public) and sourceId/targetId (storage).
2026-02-09 12:06:59 -08:00
|
|
|
|
/** Filter by entity type(s). Alias for `where.noun`. */
|
|
|
|
|
|
type?: NounType | NounType[]
|
|
|
|
|
|
/** Metadata filters using BFO operators (e.g., `{ year: { greaterThan: 2020 } }`) */
|
|
|
|
|
|
where?: Partial<T>
|
2025-09-11 16:23:32 -07:00
|
|
|
|
|
|
|
|
|
|
// Graph Intelligence
|
|
|
|
|
|
connected?: GraphConstraints
|
|
|
|
|
|
|
|
|
|
|
|
// Proximity search
|
|
|
|
|
|
near?: {
|
|
|
|
|
|
id: string // Find near this entity
|
|
|
|
|
|
threshold?: number // Min similarity (0-1)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Control options
|
|
|
|
|
|
limit?: number // Max results (default: 10)
|
|
|
|
|
|
offset?: number // Skip N results
|
|
|
|
|
|
cursor?: string // Cursor-based pagination
|
feat: add orderBy sorting and fix timestamp queries
Add production-scale sorting support with orderBy/order parameters:
- Sort by any field including createdAt, updatedAt, timestamps
- Works in both metadata-only and vector+metadata query paths
- O(k) memory complexity where k = filtered results
Fix timestamp sorting precision issue:
- Load actual timestamp values from entity metadata for sorting
- Avoids 1-minute bucketing precision loss
- Maintains bucketing for efficient range queries
Fix range query operators:
- Normalize min/max bounds before comparison with bucketed index
- Ensures gte, lte, gt, lt work correctly with timestamps
Standardize operator syntax:
- Canonical: eq, ne, gt, gte, lt, lte, in, between, contains, exists
- Deprecate: is, isNot, greaterEqual, lessEqual (remove in v5.0.0)
- Maintain backward compatibility with aliases
Test results: All sorting and range query tests pass, no regressions
2025-10-27 09:14:10 -07:00
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// Sorting
|
feat: add orderBy sorting and fix timestamp queries
Add production-scale sorting support with orderBy/order parameters:
- Sort by any field including createdAt, updatedAt, timestamps
- Works in both metadata-only and vector+metadata query paths
- O(k) memory complexity where k = filtered results
Fix timestamp sorting precision issue:
- Load actual timestamp values from entity metadata for sorting
- Avoids 1-minute bucketing precision loss
- Maintains bucketing for efficient range queries
Fix range query operators:
- Normalize min/max bounds before comparison with bucketed index
- Ensures gte, lte, gt, lt work correctly with timestamps
Standardize operator syntax:
- Canonical: eq, ne, gt, gte, lt, lte, in, between, contains, exists
- Deprecate: is, isNot, greaterEqual, lessEqual (remove in v5.0.0)
- Maintain backward compatibility with aliases
Test results: All sorting and range query tests pass, no regressions
2025-10-27 09:14:10 -07:00
|
|
|
|
orderBy?: string // Field to sort by (e.g., 'createdAt', 'title', 'metadata.priority')
|
|
|
|
|
|
order?: 'asc' | 'desc' // Sort direction: 'asc' (default) or 'desc'
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
// Advanced options
|
|
|
|
|
|
mode?: SearchMode // Search strategy
|
|
|
|
|
|
explain?: boolean // Return scoring explanation
|
|
|
|
|
|
includeRelations?: boolean // Include entity relationships
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
excludeVFS?: boolean // Exclude VFS entities from results (default: false - VFS included)
|
2025-09-11 16:23:32 -07:00
|
|
|
|
service?: string // Multi-tenancy filter
|
2026-01-26 17:16:18 -08:00
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// Hybrid search options
|
2026-01-26 17:16:18 -08:00
|
|
|
|
searchMode?: 'auto' | 'text' | 'semantic' | 'vector' | 'hybrid' // Search strategy: auto (default), text-only, semantic/vector-only, or explicit hybrid
|
|
|
|
|
|
hybridAlpha?: number // Weight between text (0.0) and semantic (1.0) search, default: auto-detected by query length
|
2025-09-11 16:23:32 -07:00
|
|
|
|
|
|
|
|
|
|
// Triple Intelligence Fusion
|
|
|
|
|
|
fusion?: {
|
|
|
|
|
|
strategy?: 'adaptive' | 'weighted' | 'progressive'
|
|
|
|
|
|
weights?: {
|
|
|
|
|
|
vector?: number
|
|
|
|
|
|
graph?: number
|
|
|
|
|
|
field?: number
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Performance options
|
|
|
|
|
|
writeOnly?: boolean // Skip validation for high-speed ingestion
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
|
|
|
|
|
|
// Aggregation
|
|
|
|
|
|
/** Query a named aggregate definition. String shorthand or full query params. */
|
|
|
|
|
|
aggregate?: string | AggregateQueryParams
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Graph constraints for search
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface GraphConstraints {
|
|
|
|
|
|
to?: string // Connected to this entity
|
|
|
|
|
|
from?: string // Connected from this entity
|
|
|
|
|
|
via?: VerbType | VerbType[] // Via these relationship types
|
2025-09-12 12:36:11 -07:00
|
|
|
|
type?: VerbType | VerbType[] // Alias for via
|
2025-09-11 16:23:32 -07:00
|
|
|
|
depth?: number // Max traversal depth (default: 1)
|
2025-09-12 12:36:11 -07:00
|
|
|
|
direction?: 'in' | 'out' | 'both' // Direction of traversal (default: 'both')
|
2025-09-11 16:23:32 -07:00
|
|
|
|
bidirectional?: boolean // Consider both directions
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Search modes
|
|
|
|
|
|
*/
|
2026-01-26 17:16:18 -08:00
|
|
|
|
export type SearchMode =
|
|
|
|
|
|
| 'auto' // Automatically choose best mode (default - enables hybrid text+semantic)
|
|
|
|
|
|
| 'vector' // Pure vector search (semantic only)
|
|
|
|
|
|
| 'semantic' // Alias for vector search
|
|
|
|
|
|
| 'text' // Pure text/keyword search
|
2025-09-11 16:23:32 -07:00
|
|
|
|
| 'metadata' // Pure metadata filtering
|
|
|
|
|
|
| 'graph' // Pure graph traversal
|
2026-01-26 17:16:18 -08:00
|
|
|
|
| 'hybrid' // Combine all intelligences (explicit hybrid mode)
|
2025-09-11 16:23:32 -07:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameters for similarity search
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface SimilarParams<T = any> {
|
|
|
|
|
|
to: string | Entity<T> | Vector // Find similar to this
|
|
|
|
|
|
limit?: number // Max results (default: 10)
|
|
|
|
|
|
threshold?: number // Min similarity score
|
|
|
|
|
|
type?: NounType | NounType[] // Restrict to types
|
|
|
|
|
|
where?: Partial<T> // Additional filters
|
|
|
|
|
|
service?: string // Multi-tenancy
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
excludeVFS?: boolean // Exclude VFS entities (default: false - VFS included)
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameters for getting relationships
|
2025-10-21 13:10:34 -07:00
|
|
|
|
*
|
|
|
|
|
|
* All parameters are optional. When called without parameters, returns all relationships
|
|
|
|
|
|
* with pagination (default limit: 100).
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* // Get all relationships (default limit: 100)
|
|
|
|
|
|
* const all = await brain.getRelations()
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Get relationships from a specific entity (string shorthand)
|
|
|
|
|
|
* const fromEntity = await brain.getRelations(entityId)
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Equivalent to:
|
|
|
|
|
|
* const fromEntity2 = await brain.getRelations({ from: entityId })
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Get relationships to a specific entity
|
|
|
|
|
|
* const toEntity = await brain.getRelations({ to: entityId })
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Filter by relationship type
|
|
|
|
|
|
* const friends = await brain.getRelations({ type: VerbType.FriendOf })
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Pagination
|
|
|
|
|
|
* const page2 = await brain.getRelations({ offset: 100, limit: 50 })
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Combined filters
|
|
|
|
|
|
* const filtered = await brain.getRelations({
|
|
|
|
|
|
* from: entityId,
|
|
|
|
|
|
* type: VerbType.WorksWith,
|
|
|
|
|
|
* limit: 20
|
|
|
|
|
|
* })
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Fixed bug where calling without parameters returned empty array
|
|
|
|
|
|
* Added string ID shorthand syntax
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
|
|
|
|
|
export interface GetRelationsParams {
|
2025-10-21 13:10:34 -07:00
|
|
|
|
/**
|
|
|
|
|
|
* Filter by source entity ID
|
|
|
|
|
|
*
|
|
|
|
|
|
* Returns all relationships originating from this entity.
|
|
|
|
|
|
*/
|
|
|
|
|
|
from?: string
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Filter by target entity ID
|
|
|
|
|
|
*
|
|
|
|
|
|
* Returns all relationships pointing to this entity.
|
|
|
|
|
|
*/
|
|
|
|
|
|
to?: string
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Filter by relationship type(s)
|
|
|
|
|
|
*
|
|
|
|
|
|
* Can be a single VerbType or array of VerbTypes.
|
|
|
|
|
|
*/
|
|
|
|
|
|
type?: VerbType | VerbType[]
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Maximum number of results to return
|
|
|
|
|
|
*
|
|
|
|
|
|
* @default 100
|
|
|
|
|
|
*/
|
|
|
|
|
|
limit?: number
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Number of results to skip (offset-based pagination)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @default 0
|
|
|
|
|
|
*/
|
|
|
|
|
|
offset?: number
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Cursor for cursor-based pagination
|
|
|
|
|
|
*
|
|
|
|
|
|
* More efficient than offset for large result sets.
|
|
|
|
|
|
*/
|
|
|
|
|
|
cursor?: string
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Filter by service (multi-tenancy)
|
|
|
|
|
|
*
|
|
|
|
|
|
* Only return relationships belonging to this service.
|
|
|
|
|
|
*/
|
|
|
|
|
|
service?: string
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============= Batch Operations =============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Batch add parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface AddManyParams<T = any> {
|
|
|
|
|
|
items: AddParams<T>[] // Items to add
|
|
|
|
|
|
parallel?: boolean // Process in parallel (default: true)
|
|
|
|
|
|
chunkSize?: number // Batch size (default: 100)
|
|
|
|
|
|
onProgress?: (done: number, total: number) => void
|
|
|
|
|
|
continueOnError?: boolean // Continue if some fail
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Batch update parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface UpdateManyParams<T = any> {
|
|
|
|
|
|
items: UpdateParams<T>[] // Items to update
|
|
|
|
|
|
parallel?: boolean
|
|
|
|
|
|
chunkSize?: number
|
|
|
|
|
|
onProgress?: (done: number, total: number) => void
|
|
|
|
|
|
continueOnError?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Batch delete parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface DeleteManyParams {
|
|
|
|
|
|
ids?: string[] // Specific IDs to delete
|
|
|
|
|
|
type?: NounType // Delete all of type
|
|
|
|
|
|
where?: any // Delete by metadata
|
|
|
|
|
|
limit?: number // Max to delete (safety)
|
|
|
|
|
|
onProgress?: (done: number, total: number) => void
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
continueOnError?: boolean // Continue processing if a delete fails
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Batch relate parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface RelateManyParams<T = any> {
|
|
|
|
|
|
items: RelateParams<T>[] // Relations to create
|
|
|
|
|
|
parallel?: boolean
|
|
|
|
|
|
chunkSize?: number
|
|
|
|
|
|
onProgress?: (done: number, total: number) => void
|
|
|
|
|
|
continueOnError?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Batch result
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface BatchResult<T = any> {
|
|
|
|
|
|
successful: T[] // Successfully processed items
|
|
|
|
|
|
failed: Array<{ // Failed items with errors
|
|
|
|
|
|
item: any
|
|
|
|
|
|
error: string
|
|
|
|
|
|
}>
|
|
|
|
|
|
total: number // Total attempted
|
|
|
|
|
|
duration: number // Time taken in ms
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// ============= Import Progress =============
|
feat: comprehensive import progress tracking for all 7 formats
Add real-time progress reporting throughout the entire import pipeline
with a standardized API that works across all supported formats.
Workshop Team Feature Request:
- Eliminates "0% complete" hangs during AI extraction
- Shows continuous progress with entities/sec, throughput, ETA
- Reports contextual messages ("Processing page 5 of 23")
- Standardized progress API for CSV, PDF, Excel, JSON, Markdown, YAML, DOCX
Core Changes:
- Add FormatHandlerProgressHooks interface for extensible progress
- Wire up all 3 binary format handlers (CSV, PDF, Excel) with 7+ progress points
- Wire up all 4 text format importers (JSON, Markdown, YAML, DOCX)
- Add ImportProgress interface with stage, message, counts, throughput, ETA
- ImportCoordinator normalizes all format progress to standard interface
CLI Improvements:
- Import command now uses brain.import() directly with full progress
- Add --include-vfs flag to find command (v4.4.0 compatibility)
- Add --confidence and --weight options to add command
Documentation:
- docs/guides/standard-import-progress.md - Universal API guide
- docs/guides/import-progress-implementation.md - Developer guide
- docs/guides/import-progress-examples.md - Practical examples
- JSDoc on brain.import() with universal handler examples
Result: ONE progress handler works for ALL 7 formats with zero format-specific code!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 14:45:46 -07:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Import stage enumeration
|
|
|
|
|
|
*/
|
|
|
|
|
|
export type ImportStage =
|
|
|
|
|
|
| 'detecting' // Detecting file format
|
|
|
|
|
|
| 'reading' // Reading file from disk/network
|
|
|
|
|
|
| 'parsing' // Parsing file structure (CSV rows, PDF pages, Excel sheets)
|
|
|
|
|
|
| 'extracting' // Extracting entities using AI
|
|
|
|
|
|
| 'indexing' // Creating graph nodes and relationships
|
|
|
|
|
|
| 'completing' // Final cleanup and stats
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Overall import status
|
|
|
|
|
|
*/
|
|
|
|
|
|
export type ImportStatus =
|
|
|
|
|
|
| 'starting' // Initializing import
|
|
|
|
|
|
| 'processing' // Actively importing
|
|
|
|
|
|
| 'completing' // Finalizing
|
|
|
|
|
|
| 'done' // Complete
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Comprehensive import progress information
|
|
|
|
|
|
*
|
|
|
|
|
|
* Provides multi-dimensional progress tracking:
|
|
|
|
|
|
* - Bytes processed (always deterministic)
|
|
|
|
|
|
* - Entities extracted and indexed
|
|
|
|
|
|
* - Stage-specific progress
|
|
|
|
|
|
* - Time estimates
|
|
|
|
|
|
* - Performance metrics
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ImportProgress {
|
|
|
|
|
|
// Overall Progress
|
|
|
|
|
|
overall_progress: number // 0-100 weighted estimate across all stages
|
|
|
|
|
|
overall_status: ImportStatus // High-level status
|
|
|
|
|
|
|
|
|
|
|
|
// Current Stage
|
|
|
|
|
|
stage: ImportStage // What's happening now
|
|
|
|
|
|
stage_progress: number // 0-100 within current stage (0 if unknown)
|
|
|
|
|
|
stage_message: string // Human-readable: "Extracting entities from PDF..."
|
|
|
|
|
|
|
|
|
|
|
|
// Bytes (Always Available - most deterministic metric)
|
|
|
|
|
|
bytes_processed: number // Bytes read/processed so far
|
|
|
|
|
|
total_bytes: number // Total file size (0 if streaming/unknown)
|
|
|
|
|
|
bytes_percentage: number // Convenience: bytes_processed / total_bytes * 100
|
|
|
|
|
|
bytes_per_second?: number // Processing rate (relevant during parsing)
|
|
|
|
|
|
|
|
|
|
|
|
// Entities (Available when extraction starts)
|
|
|
|
|
|
entities_extracted: number // Entities found during AI extraction
|
|
|
|
|
|
entities_indexed: number // Entities added to Brainy graph
|
|
|
|
|
|
entities_per_second?: number // Entities/sec (relevant during extraction/indexing)
|
|
|
|
|
|
estimated_total_entities?: number // Estimated final count
|
|
|
|
|
|
estimation_confidence?: number // 0-1 confidence in estimation
|
|
|
|
|
|
|
|
|
|
|
|
// Timing
|
|
|
|
|
|
elapsed_ms: number // Time since import started
|
|
|
|
|
|
estimated_remaining_ms?: number // Estimated time remaining
|
|
|
|
|
|
estimated_total_ms?: number // Estimated total time
|
|
|
|
|
|
|
|
|
|
|
|
// Context (helps users understand what's happening)
|
|
|
|
|
|
current_item?: string // "Processing page 5 of 23"
|
|
|
|
|
|
current_file?: string // "Sheet: Q2 Sales Data"
|
|
|
|
|
|
file_number?: number // 3 (when importing multiple files)
|
|
|
|
|
|
total_files?: number // 10
|
|
|
|
|
|
|
|
|
|
|
|
// Performance Metrics (for debugging/optimization)
|
|
|
|
|
|
metrics?: {
|
|
|
|
|
|
parsing_rate_mbps?: number // MB/s during parsing
|
|
|
|
|
|
extraction_rate_entities_per_sec?: number // Entities/s during extraction
|
|
|
|
|
|
indexing_rate_entities_per_sec?: number // Entities/s during indexing
|
|
|
|
|
|
memory_usage_mb?: number // Current memory usage
|
|
|
|
|
|
peak_memory_mb?: number // Peak memory usage
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Backwards Compatibility (for legacy code)
|
|
|
|
|
|
current: number // Alias for entities_indexed
|
|
|
|
|
|
total: number // Alias for estimated_total_entities or 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Import progress callback - backwards compatible
|
|
|
|
|
|
*
|
|
|
|
|
|
* Supports both legacy (current, total) and new (ImportProgress object) signatures
|
|
|
|
|
|
*/
|
|
|
|
|
|
export type ImportProgressCallback =
|
|
|
|
|
|
| ((progress: ImportProgress) => void)
|
|
|
|
|
|
| ((current: number, total: number) => void)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Stage weight configuration for overall progress calculation
|
|
|
|
|
|
*
|
|
|
|
|
|
* These weights reflect the typical time distribution across stages.
|
|
|
|
|
|
* Extraction is typically the slowest stage (60% of time).
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface StageWeights {
|
|
|
|
|
|
detecting: number // Default: 0.01 (1%)
|
|
|
|
|
|
reading: number // Default: 0.05 (5%)
|
|
|
|
|
|
parsing: number // Default: 0.10 (10%)
|
|
|
|
|
|
extracting: number // Default: 0.60 (60% - slowest!)
|
|
|
|
|
|
indexing: number // Default: 0.20 (20%)
|
|
|
|
|
|
completing: number // Default: 0.04 (4%)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Import result statistics
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ImportStats {
|
|
|
|
|
|
graphNodesCreated: number // Entities added to graph
|
|
|
|
|
|
graphEdgesCreated: number // Relationships created
|
|
|
|
|
|
vfsFilesCreated: number // VFS files created
|
|
|
|
|
|
duration: number // Total time in ms
|
|
|
|
|
|
bytesProcessed: number // Total bytes read
|
|
|
|
|
|
averageRate: number // Average entities/sec
|
|
|
|
|
|
peakMemoryMB?: number // Peak memory usage
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Import operation result
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ImportResult {
|
|
|
|
|
|
success: boolean
|
|
|
|
|
|
stats: ImportStats
|
|
|
|
|
|
errors?: Array<{
|
|
|
|
|
|
stage: ImportStage
|
|
|
|
|
|
message: string
|
|
|
|
|
|
error?: any
|
|
|
|
|
|
}>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
// ============= Advanced Operations =============
|
|
|
|
|
|
|
2025-11-18 15:31:29 -08:00
|
|
|
|
/**
|
|
|
|
|
|
* Options for brain.get() entity retrieval
|
|
|
|
|
|
*
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* **Performance Optimization**:
|
2025-11-18 15:31:29 -08:00
|
|
|
|
* By default, brain.get() loads ONLY metadata (not vectors), resulting in:
|
|
|
|
|
|
* - **76-81% faster** reads (10ms vs 43ms for metadata-only)
|
|
|
|
|
|
* - **95% less bandwidth** (300 bytes vs 6KB per entity)
|
|
|
|
|
|
* - **87% less memory** (optimal for VFS and large-scale operations)
|
|
|
|
|
|
*
|
|
|
|
|
|
* **When to use includeVectors**:
|
|
|
|
|
|
* - Computing similarity on a specific entity (not search): `brain.similar({ to: entity.vector })`
|
|
|
|
|
|
* - Manual vector operations: `cosineSimilarity(entity.vector, otherVector)`
|
|
|
|
|
|
* - Inspecting embeddings for debugging
|
|
|
|
|
|
*
|
|
|
|
|
|
* **When NOT to use includeVectors** (metadata-only is sufficient):
|
|
|
|
|
|
* - VFS operations (readFile, stat, readdir) - 100% of cases
|
|
|
|
|
|
* - Existence checks: `if (await brain.get(id))`
|
|
|
|
|
|
* - Metadata inspection: `entity.metadata`, `entity.data`, `entity.type`
|
|
|
|
|
|
* - Relationship traversal: `brain.getRelations({ from: id })`
|
|
|
|
|
|
* - Search operations: `brain.find()` generates embeddings automatically
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* // ✅ FAST (default): Metadata-only - 10ms, 300 bytes
|
|
|
|
|
|
* const entity = await brain.get(id)
|
|
|
|
|
|
* console.log(entity.data, entity.metadata) // ✅ Available
|
|
|
|
|
|
* console.log(entity.vector) // Empty Float32Array (stub)
|
|
|
|
|
|
*
|
|
|
|
|
|
* // ✅ FULL: Load vectors when needed - 43ms, 6KB
|
|
|
|
|
|
* const fullEntity = await brain.get(id, { includeVectors: true })
|
|
|
|
|
|
* const similarity = cosineSimilarity(fullEntity.vector, otherVector)
|
|
|
|
|
|
*
|
|
|
|
|
|
* // ✅ VFS automatically uses fast path (no change needed)
|
|
|
|
|
|
* await vfs.readFile('/file.txt') // 53ms → 10ms (81% faster)
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface GetOptions {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Include 384-dimensional vector embeddings in the response
|
|
|
|
|
|
*
|
|
|
|
|
|
* **Default: false** (metadata-only for 76-81% speedup)
|
|
|
|
|
|
*
|
|
|
|
|
|
* Set to `true` when you need to:
|
|
|
|
|
|
* - Compute similarity on this specific entity's vector
|
|
|
|
|
|
* - Perform manual vector operations
|
|
|
|
|
|
* - Inspect embeddings for debugging
|
|
|
|
|
|
*
|
|
|
|
|
|
* **Note**: Search operations (`brain.find()`) generate vectors automatically,
|
|
|
|
|
|
* so you don't need this flag for search. Only for direct vector operations
|
|
|
|
|
|
* on a retrieved entity.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @default false
|
|
|
|
|
|
*/
|
|
|
|
|
|
includeVectors?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
/**
|
|
|
|
|
|
* Graph traversal parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface TraverseParams {
|
|
|
|
|
|
from: string | string[] // Starting node(s)
|
|
|
|
|
|
direction?: 'out' | 'in' | 'both' // Traversal direction
|
|
|
|
|
|
types?: VerbType[] // Edge types to follow
|
|
|
|
|
|
depth?: number // Max depth (default: 2)
|
|
|
|
|
|
strategy?: 'bfs' | 'dfs' // Breadth or depth first
|
|
|
|
|
|
filter?: (entity: Entity, depth: number, path: string[]) => boolean
|
|
|
|
|
|
limit?: number // Max nodes to visit
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
// ============= Aggregation Engine Types =============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Supported aggregation operations
|
|
|
|
|
|
*/
|
2026-02-17 17:04:11 -08:00
|
|
|
|
export type AggregationOp = 'sum' | 'count' | 'avg' | 'min' | 'max' | 'stddev' | 'variance'
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Time window granularity for GROUP BY time dimensions
|
|
|
|
|
|
*/
|
|
|
|
|
|
export type TimeWindowGranularity =
|
|
|
|
|
|
| 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
|
|
|
|
|
|
| { seconds: number }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-05-26 14:20:40 -07:00
|
|
|
|
* A GROUP BY dimension — one of:
|
|
|
|
|
|
* - a plain metadata field name (string),
|
|
|
|
|
|
* - a time-windowed field (`{ field, window }`), or
|
|
|
|
|
|
* - an **unnest** field (`{ field, unnest: true }`): the field holds an array, and the entity
|
|
|
|
|
|
* contributes once to a group per distinct element (e.g. `tags: string[]` → tag frequency).
|
|
|
|
|
|
* An entity whose unnest field is missing or an empty array contributes to no group.
|
|
|
|
|
|
*/
|
|
|
|
|
|
export type GroupByDimension =
|
|
|
|
|
|
| string
|
|
|
|
|
|
| { field: string; window: TimeWindowGranularity }
|
|
|
|
|
|
| { field: string; unnest: true }
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Source filter for which entities feed into an aggregate
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface AggregateSource {
|
|
|
|
|
|
/** Filter by entity type(s) */
|
|
|
|
|
|
type?: NounType | NounType[]
|
|
|
|
|
|
/** Metadata filter (same syntax as find({ where })) */
|
|
|
|
|
|
where?: Record<string, unknown>
|
|
|
|
|
|
/** Multi-tenancy service filter */
|
|
|
|
|
|
service?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Full aggregate definition — registered via brain.defineAggregate()
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface AggregateDefinition {
|
|
|
|
|
|
/** Unique name for this aggregate (used in queries) */
|
|
|
|
|
|
name: string
|
|
|
|
|
|
/** Which entities contribute to this aggregate */
|
|
|
|
|
|
source: AggregateSource
|
|
|
|
|
|
/** Dimensions to group by */
|
|
|
|
|
|
groupBy: GroupByDimension[]
|
|
|
|
|
|
/** Named metrics to compute */
|
|
|
|
|
|
metrics: Record<string, AggregateMetricDef>
|
|
|
|
|
|
/** Control materialization of results as NounType.Measurement entities */
|
|
|
|
|
|
materialize?: boolean | { debounceMs?: number; trackSources?: boolean }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Single metric definition within an aggregate
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface AggregateMetricDef {
|
|
|
|
|
|
/** Aggregation operation */
|
|
|
|
|
|
op: AggregationOp
|
|
|
|
|
|
/** Metadata field to aggregate (required for sum/avg/min/max; optional for count) */
|
|
|
|
|
|
field?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Internal running state for a single metric.
|
|
|
|
|
|
* Tracks enough to compute all operations incrementally.
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface MetricState {
|
|
|
|
|
|
sum: number
|
|
|
|
|
|
count: number
|
|
|
|
|
|
min: number
|
|
|
|
|
|
max: number
|
2026-02-17 17:04:11 -08:00
|
|
|
|
/** Running M2 for Welford's online variance (sum of squared differences from mean) */
|
|
|
|
|
|
m2?: number
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Internal state for one aggregate group (one combination of group key values)
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface AggregateGroupState {
|
|
|
|
|
|
/** The group key values (e.g., { category: 'food', period: '2024-01' }) */
|
|
|
|
|
|
groupKey: Record<string, string | number>
|
|
|
|
|
|
/** Running metric states keyed by metric name */
|
|
|
|
|
|
metrics: Record<string, MetricState>
|
|
|
|
|
|
/** Entity ID of the materialized Measurement entity (if materialized) */
|
|
|
|
|
|
materializedEntityId?: string
|
|
|
|
|
|
/** Timestamp of last update */
|
|
|
|
|
|
lastUpdated: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Query parameters for reading aggregate results
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface AggregateQueryParams {
|
|
|
|
|
|
/** Name of the aggregate to query */
|
|
|
|
|
|
name: string
|
|
|
|
|
|
/** Filter aggregate groups by their key values */
|
|
|
|
|
|
where?: Record<string, unknown>
|
feat: queryAggregate() + HAVING, plus aggregate backfill, traversal depth/via, extraction typing (BR-ADV-FEATURES-BUN)
New report APIs:
- brain.queryAggregate(name, params) returns the clean AggregateResult[] shape
({ groupKey, metrics, count }) directly, instead of the search-Result wrapper that
find({ aggregate }) returns.
- HAVING: find({ aggregate, having }) and queryAggregate filter groups by computed
metric values (e.g. revenue > 1000), complementing where (which filters group keys).
Evaluated per group: O(groups), independent of entity count.
Fixes (all reproducible on Node; surfaced under Cortex+Bun by Memory):
- Aggregate backfill-on-define: defining an aggregate over a store that already holds
matching entities returned []. It now backfills from existing entities on first query
(storage-agnostic via getNouns), so it works under durable backends that reopen
pre-populated. groupBy:['noun'] resolves to the entity type; find({ aggregate }) rows
expose groupKey/metrics/count at the top level.
- Multi-hop find({ connected: { depth, via } }) honors depth and via at every hop
(was 1-hop only, with verb filtering applied to hop 1 only); BFS bounded by limit.
- extractEntities no longer bleeds a neighbour's type indicator across candidates; each
candidate is typed by its own span. Also fixes the "Dr." title pattern.
Adds real-embedding regression tests; full unit suite green.
2026-05-26 13:55:43 -07:00
|
|
|
|
/**
|
|
|
|
|
|
* Filter groups by their computed METRIC values (SQL HAVING). Same BFO operators as
|
|
|
|
|
|
* `where`, but applied to the derived metric results plus `count`, e.g.
|
|
|
|
|
|
* `{ revenue: { greaterThan: 1000 } }`. Evaluated per group (O(groups), independent of
|
|
|
|
|
|
* entity count), before sort/pagination.
|
|
|
|
|
|
*/
|
|
|
|
|
|
having?: Record<string, unknown>
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
/** Sort by metric name or group key field */
|
|
|
|
|
|
orderBy?: string
|
|
|
|
|
|
/** Sort direction */
|
|
|
|
|
|
order?: 'asc' | 'desc'
|
|
|
|
|
|
/** Max results */
|
|
|
|
|
|
limit?: number
|
|
|
|
|
|
/** Skip N results */
|
|
|
|
|
|
offset?: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
/**
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
* A single aggregate result row
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
export interface AggregateResult {
|
|
|
|
|
|
/** Group key values for this row */
|
|
|
|
|
|
groupKey: Record<string, string | number>
|
|
|
|
|
|
/** Computed metric values (derived from MetricState based on op) */
|
|
|
|
|
|
metrics: Record<string, number>
|
|
|
|
|
|
/** Total entity count in this group */
|
|
|
|
|
|
count: number
|
|
|
|
|
|
/** Entity ID of materialized Measurement (if materialized) */
|
|
|
|
|
|
entityId?: string
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
* Provider interface for Cortex-accelerated aggregation.
|
|
|
|
|
|
* When registered as 'aggregation' provider, Brainy delegates to this.
|
2025-09-11 16:23:32 -07:00
|
|
|
|
*/
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
export interface AggregationProvider {
|
2026-02-17 17:04:11 -08:00
|
|
|
|
/** Register an aggregate definition (caches compiled definition for hot path) */
|
|
|
|
|
|
defineAggregate?(def: AggregateDefinition): void
|
|
|
|
|
|
|
|
|
|
|
|
/** Remove a registered aggregate definition */
|
|
|
|
|
|
removeAggregate?(name: string): void
|
|
|
|
|
|
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
/** Incrementally update aggregation state when an entity changes */
|
|
|
|
|
|
incrementalUpdate(
|
|
|
|
|
|
name: string,
|
|
|
|
|
|
def: AggregateDefinition,
|
|
|
|
|
|
entity: Record<string, unknown>,
|
|
|
|
|
|
op: 'add' | 'update' | 'delete',
|
|
|
|
|
|
prev?: Record<string, unknown>
|
|
|
|
|
|
): AggregateGroupState[]
|
|
|
|
|
|
|
|
|
|
|
|
/** Compute the group key for a given entity */
|
|
|
|
|
|
computeGroupKey(
|
|
|
|
|
|
entity: Record<string, unknown>,
|
|
|
|
|
|
groupBy: GroupByDimension[]
|
|
|
|
|
|
): Record<string, string | number>
|
|
|
|
|
|
|
|
|
|
|
|
/** Rebuild an entire aggregate from scratch */
|
|
|
|
|
|
rebuildAggregate(
|
|
|
|
|
|
def: AggregateDefinition,
|
|
|
|
|
|
entities: Array<Record<string, unknown>>
|
|
|
|
|
|
): Map<string, AggregateGroupState>
|
|
|
|
|
|
|
|
|
|
|
|
/** Query aggregate state with filtering/sorting/pagination */
|
|
|
|
|
|
queryAggregate(
|
|
|
|
|
|
state: Map<string, AggregateGroupState>,
|
|
|
|
|
|
params: AggregateQueryParams
|
|
|
|
|
|
): AggregateResult[]
|
2026-02-17 17:04:11 -08:00
|
|
|
|
|
|
|
|
|
|
/** Restore previously serialized state (called during init) */
|
|
|
|
|
|
restoreState?(data: string): void
|
|
|
|
|
|
|
|
|
|
|
|
/** Serialize internal state for persistence (called during flush) */
|
|
|
|
|
|
serializeState?(): string
|
feat: add aggregation engine with incremental SUM/COUNT/AVG/MIN/MAX, GROUP BY, and time windows
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>
2026-02-16 16:57:53 -08:00
|
|
|
|
}
|
2025-09-11 16:23:32 -07:00
|
|
|
|
|
|
|
|
|
|
// ============= Configuration =============
|
|
|
|
|
|
|
2026-01-20 16:21:11 -08:00
|
|
|
|
/**
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Integration Hub configuration
|
2026-01-20 16:21:11 -08:00
|
|
|
|
*
|
|
|
|
|
|
* Enables external tool integrations: Excel, Power BI, Google Sheets, etc.
|
|
|
|
|
|
* Works in all environments with zero external dependencies.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* // Enable all integrations with defaults
|
|
|
|
|
|
* new Brainy({ integrations: true })
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Custom configuration
|
|
|
|
|
|
* new Brainy({
|
|
|
|
|
|
* integrations: {
|
|
|
|
|
|
* basePath: '/api/v1',
|
|
|
|
|
|
* enable: ['odata', 'sheets']
|
|
|
|
|
|
* }
|
|
|
|
|
|
* })
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface IntegrationsConfig {
|
|
|
|
|
|
/** Base path for all integration endpoints (default: '') */
|
|
|
|
|
|
basePath?: string
|
|
|
|
|
|
|
|
|
|
|
|
/** Which integrations to enable (default: all) */
|
|
|
|
|
|
enable?: ('odata' | 'sheets' | 'sse' | 'webhooks')[] | 'all'
|
|
|
|
|
|
|
|
|
|
|
|
/** Per-integration config overrides */
|
|
|
|
|
|
config?: {
|
|
|
|
|
|
odata?: { basePath?: string }
|
|
|
|
|
|
sheets?: { basePath?: string }
|
|
|
|
|
|
sse?: { basePath?: string; heartbeatInterval?: number }
|
|
|
|
|
|
webhooks?: { maxRetries?: number }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: multi-process safety + read-only inspector mode
Filesystem storage now enforces single-writer, many-reader semantics.
A second writer on the same data directory throws at init time with the
holder's PID, hostname, and heartbeat — replacing the previous silent
stale-reads failure mode.
- New: `Brainy.openReadOnly()` — coexists with a live writer, every
mutation throws clearly.
- New: writer lock at `<rootDir>/locks/_writer.lock` with 10s heartbeat
and stale-detection (PID liveness + heartbeat freshness).
- New: cross-process flush-request RPC (filesystem-based, no signals)
so inspectors can force fresh state on demand.
- New: `brain.stats()`, `brain.explain(findParams)`, `brain.health()`
for operator-facing introspection.
- New: `brainy inspect` CLI with 13 subcommands (stats, find, get,
relations, explain, health, sample, fields, dump, watch, backup,
repair, diff), all read-only by default.
- Same-PID re-opens allowed with a warning (preserves test "simulate
restart" patterns).
- Storage instances passed directly via `storage: new MemoryStorage()`
are now honoured instead of silently falling through to the
filesystem auto-detect path.
Brainy + Cortex compose under this model — the lock covers both because
they share `rootDir`, Cortex segments are immutable mmap files, and
MANIFEST updates use atomic-rename.
2026-05-15 11:25:05 -07:00
|
|
|
|
/**
|
|
|
|
|
|
* Operator-facing summary returned by `brain.stats()`. Designed to fit in a
|
|
|
|
|
|
* terminal screen so an incident responder can read it at a glance: counts,
|
|
|
|
|
|
* mode, lock owner, indexed fields, and index health flags.
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface BrainyStats {
|
|
|
|
|
|
/** Whether this instance can mutate. `reader` is set by `openReadOnly()` and `asOf()`. */
|
|
|
|
|
|
mode: 'writer' | 'reader'
|
|
|
|
|
|
/** Total entity (noun) count across all types. */
|
|
|
|
|
|
entityCount: number
|
|
|
|
|
|
/** Breakdown by NounType name (`person`, `event`, ...). Zero-count types omitted. */
|
|
|
|
|
|
entitiesByType: Record<string, number>
|
|
|
|
|
|
/** Total relationship (verb) count across all types. */
|
|
|
|
|
|
relationCount: number
|
|
|
|
|
|
/** Breakdown by VerbType name. Zero-count types omitted. */
|
|
|
|
|
|
relationsByType: Record<string, number>
|
|
|
|
|
|
/** Indexed metadata field names known to the metadata index. */
|
|
|
|
|
|
fieldRegistry: string[]
|
|
|
|
|
|
/** Per-index health flags. `true` = index has entries OR no entities exist yet. */
|
|
|
|
|
|
indexHealth: {
|
|
|
|
|
|
hnsw: boolean
|
|
|
|
|
|
metadata: boolean
|
|
|
|
|
|
graph: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
/** Storage backend info — `backend` is the adapter class name. */
|
|
|
|
|
|
storage: {
|
|
|
|
|
|
backend: string
|
|
|
|
|
|
rootDir?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Writer lock metadata if one is currently held on this directory. Present
|
|
|
|
|
|
* for both writer instances (their own lock) and readers inspecting a
|
|
|
|
|
|
* directory with a live writer.
|
|
|
|
|
|
*/
|
|
|
|
|
|
writerLock?: {
|
|
|
|
|
|
pid: number
|
|
|
|
|
|
hostname: string
|
|
|
|
|
|
startedAt: string
|
|
|
|
|
|
lastHeartbeat: string
|
|
|
|
|
|
version: string
|
|
|
|
|
|
rootDir?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
/** The Brainy library version this instance was built against. */
|
|
|
|
|
|
version: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
/**
|
|
|
|
|
|
* Brainy configuration
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface BrainyConfig {
|
|
|
|
|
|
// Storage configuration
|
|
|
|
|
|
storage?: {
|
2025-09-17 16:48:57 -07:00
|
|
|
|
type: 'auto' | 'memory' | 'filesystem' | 's3' | 'r2' | 'opfs' | 'gcs'
|
2026-03-19 09:46:11 -07:00
|
|
|
|
/** Root directory for filesystem storage. Passed through to storage factories
|
|
|
|
|
|
* including plugin-provided factories (e.g. Cortex mmap). */
|
|
|
|
|
|
rootDirectory?: string
|
2025-09-11 16:23:32 -07:00
|
|
|
|
options?: any
|
2025-11-01 11:56:11 -07:00
|
|
|
|
branch?: string // COW branch name (default: 'main')
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
2025-12-18 10:31:02 -08:00
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
// Index configuration
|
|
|
|
|
|
index?: {
|
|
|
|
|
|
m?: number // HNSW M parameter
|
|
|
|
|
|
efConstruction?: number // HNSW construction parameter
|
|
|
|
|
|
efSearch?: number // HNSW search parameter
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Performance options
|
|
|
|
|
|
cache?: boolean | { // Enable caching
|
|
|
|
|
|
maxSize?: number
|
|
|
|
|
|
ttl?: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-22 15:45:35 -07:00
|
|
|
|
// Distributed configuration
|
|
|
|
|
|
distributed?: {
|
|
|
|
|
|
enabled: boolean
|
|
|
|
|
|
nodeId?: string
|
|
|
|
|
|
nodes?: string[] // Other nodes in cluster
|
|
|
|
|
|
coordinatorUrl?: string // Coordinator endpoint
|
|
|
|
|
|
shardCount?: number // Number of shards (default: 64)
|
|
|
|
|
|
replicationFactor?: number // Number of replicas (default: 3)
|
|
|
|
|
|
consensus?: 'raft' | 'none' // Consensus mechanism
|
|
|
|
|
|
transport?: 'tcp' | 'http' | 'udp'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
// Advanced options
|
|
|
|
|
|
warmup?: boolean // Warm up on init
|
|
|
|
|
|
realtime?: boolean // Enable real-time updates
|
|
|
|
|
|
multiTenancy?: boolean // Enable service isolation
|
|
|
|
|
|
telemetry?: boolean // Send anonymous usage stats
|
2025-09-16 10:35:07 -07:00
|
|
|
|
|
2025-09-22 15:45:35 -07:00
|
|
|
|
// Performance tuning options for production
|
|
|
|
|
|
disableAutoRebuild?: boolean // Disable automatic index rebuilding on init
|
|
|
|
|
|
disableMetrics?: boolean // Completely disable metrics collection
|
|
|
|
|
|
disableAutoOptimize?: boolean // Disable automatic index optimization
|
|
|
|
|
|
batchWrites?: boolean // Enable write batching for better performance
|
|
|
|
|
|
maxConcurrentOperations?: number // Limit concurrent file operations
|
|
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// HNSW persistence mode
|
2025-12-02 14:20:04 -08:00
|
|
|
|
// Controls when HNSW graph connections are persisted to storage
|
|
|
|
|
|
// - 'immediate': Persist on every add (slow but durable, default for filesystem)
|
|
|
|
|
|
// - 'deferred': Persist only on flush/close (fast, default for cloud storage)
|
|
|
|
|
|
// Cloud storage (GCS/S3/R2/Azure) should use 'deferred' for 30-50× faster adds
|
|
|
|
|
|
hnswPersistMode?: 'immediate' | 'deferred'
|
|
|
|
|
|
|
2026-01-31 12:41:53 -08:00
|
|
|
|
// HNSW optimization options (v7.11.0)
|
|
|
|
|
|
hnsw?: {
|
|
|
|
|
|
quantization?: {
|
|
|
|
|
|
enabled?: boolean // default: false — current behavior exactly
|
2026-02-01 08:22:07 -08:00
|
|
|
|
bits?: 8 | 4 // default: 8 (SQ8). SQ4 requires cortex native.
|
2026-01-31 12:41:53 -08:00
|
|
|
|
rerankMultiplier?: number // default: 3 — over-retrieve 3x, rerank with float32
|
|
|
|
|
|
}
|
|
|
|
|
|
vectorStorage?: 'memory' | 'lazy' // default: 'memory' — 'lazy' evicts vectors after insert
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// Memory management options
|
feat: COW always-on architecture + cloud storage clear() fix (v5.11.0)
Major architectural improvements and critical bug fixes:
## COW Always-On Architecture
- Removed cowEnabled flag from BaseStorage (COW cannot be disabled)
- Eliminated marker file system (checkClearMarker, createClearMarker)
- Simplified all code paths to assume COW is always enabled
- COW automatically re-initializes after clear() operations
## Critical Bug Fix: Cloud Storage clear()
- Fixed GCS clear() using correct paths (branches/ instead of entities/nouns/)
- Fixed S3Compatible clear() path structure
- Fixed R2 clear() implementation
- Fixed Azure, FileSystem, OPFS, Memory clear() COW flag handling
- clear() now deletes: branches/, _cow/, _system/
- Result: Cloud buckets can now be fully cleared (previously impossible)
## Container Memory Detection
- Auto-detect Docker/K8s/Cloud Run memory limits (cgroup v1/v2)
- Smart memory allocation (75% graph data, 25% query operations)
- Environment variable support (CLOUD_RUN_MEMORY, MEMORY_LIMIT)
- Production-grade containerized deployment support
## CommitLog streamHistory Feature
- Added streamable commit history with pagination
- Efficient memory usage for large commit histories
- Support for branch filtering and time ranges
## Comprehensive Storage Documentation
- Complete v5.11.0 file structure reference
- Detailed path construction algorithms
- 8 common storage scenarios with examples
- Type-first storage, sharding, COW architecture explained
- Public docs: docs/architecture/data-storage-architecture.md (1063 lines)
## Files Modified (14 files)
- All 8 storage adapters (GCS, S3, R2, Azure, FS, OPFS, Memory, Historical)
- BaseStorage core architecture
- CommitLog with streaming
- Brainy memory configuration
- Parameter validation with container detection
- Storage architecture documentation
## Breaking Changes
NONE - COW was already enabled by default. This removes the ability to disable it.
## Migration
No action required. Upgrade and clear() will work correctly on cloud storage.
## Impact
- Users can now clear cloud storage buckets completely
- No more corrupted buckets after clear() operations
- Container deployments automatically optimize memory allocation
- COW is mandatory and always enabled (safer, simpler)
v5.11.0 - Production ready
2025-11-18 13:44:02 -08:00
|
|
|
|
maxQueryLimit?: number // Override auto-detected query result limit (max: 100000)
|
|
|
|
|
|
reservedQueryMemory?: number // Memory reserved for queries in bytes (e.g., 1073741824 = 1GB)
|
|
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// Embedding initialization
|
2026-01-06 17:18:58 -08:00
|
|
|
|
// Controls when the WASM embedding engine is initialized
|
|
|
|
|
|
// - false (default): Lazy initialization on first embed() call
|
|
|
|
|
|
// - true: Eager initialization during brain.init()
|
|
|
|
|
|
// Set to true for cloud deployments (Cloud Run, Lambda) where you want
|
|
|
|
|
|
// WASM compilation to happen during container startup, not on first request
|
|
|
|
|
|
eagerEmbeddings?: boolean
|
|
|
|
|
|
|
2026-02-02 08:52:18 -08:00
|
|
|
|
// Plugin configuration
|
|
|
|
|
|
// Controls which plugins are loaded during init()
|
|
|
|
|
|
// - undefined (default): Auto-detect installed plugins (@soulcraft/cortex, etc.)
|
|
|
|
|
|
// - false: No plugins — skip auto-detection entirely
|
|
|
|
|
|
// - []: No plugins — skip auto-detection entirely
|
|
|
|
|
|
// - ['@soulcraft/cortex']: Load only specified plugins, no auto-detection
|
|
|
|
|
|
plugins?: string[] | false
|
|
|
|
|
|
|
2025-09-16 10:35:07 -07:00
|
|
|
|
// Logging configuration
|
|
|
|
|
|
verbose?: boolean // Enable verbose logging
|
|
|
|
|
|
silent?: boolean // Suppress all logging output
|
2026-01-20 16:21:11 -08:00
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// Integration Hub
|
2026-01-20 16:21:11 -08:00
|
|
|
|
// Enable external tool integrations: Excel, Power BI, Google Sheets, etc.
|
|
|
|
|
|
// - true: Enable all integrations with default paths
|
|
|
|
|
|
// - false/undefined: Disable integrations (default)
|
|
|
|
|
|
// - IntegrationsConfig: Custom configuration
|
|
|
|
|
|
integrations?: boolean | IntegrationsConfig
|
feat: add migration system with error handling, validation, and enterprise hardening
- MigrationRunner: per-entity error tracking (non-fatal), maxErrors bail-out,
static validateMigrations() called in constructor, branch error propagation
- RefManager: updateRefMetadata() method for clean metadata updates
- brainy.ts: eliminate as-any casts in migration methods, use updateRefMetadata,
forward maxErrors through full chain including branch migrations
- Types: MigrationError interface, errors field on MigrationResult, maxErrors on MigrateOptions
- Package exports: MigrationError type, migrate() on BrainyInterface, autoMigrate config
- 31 integration tests covering error handling, validation, branch error propagation
- Documentation: docs/guides/schema-migrations.md
2026-02-09 16:13:14 -08:00
|
|
|
|
|
|
|
|
|
|
// Migration configuration
|
|
|
|
|
|
// - false/undefined (default): Log warning if pending migrations exist, but don't auto-run
|
|
|
|
|
|
// - true: Automatically run pending migrations during init() for small datasets (<10K entities)
|
|
|
|
|
|
autoMigrate?: boolean
|
feat: multi-process safety + read-only inspector mode
Filesystem storage now enforces single-writer, many-reader semantics.
A second writer on the same data directory throws at init time with the
holder's PID, hostname, and heartbeat — replacing the previous silent
stale-reads failure mode.
- New: `Brainy.openReadOnly()` — coexists with a live writer, every
mutation throws clearly.
- New: writer lock at `<rootDir>/locks/_writer.lock` with 10s heartbeat
and stale-detection (PID liveness + heartbeat freshness).
- New: cross-process flush-request RPC (filesystem-based, no signals)
so inspectors can force fresh state on demand.
- New: `brain.stats()`, `brain.explain(findParams)`, `brain.health()`
for operator-facing introspection.
- New: `brainy inspect` CLI with 13 subcommands (stats, find, get,
relations, explain, health, sample, fields, dump, watch, backup,
repair, diff), all read-only by default.
- Same-PID re-opens allowed with a warning (preserves test "simulate
restart" patterns).
- Storage instances passed directly via `storage: new MemoryStorage()`
are now honoured instead of silently falling through to the
filesystem auto-detect path.
Brainy + Cortex compose under this model — the lock covers both because
they share `rootDir`, Cortex segments are immutable mmap files, and
MANIFEST updates use atomic-rename.
2026-05-15 11:25:05 -07:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Process role for multi-process safety on filesystem storage.
|
|
|
|
|
|
*
|
|
|
|
|
|
* - `'writer'` (default): acquires an exclusive lock on the storage directory at
|
|
|
|
|
|
* `init()` and refuses to open if another live writer holds the lock. Required
|
|
|
|
|
|
* for any instance that calls `add`/`update`/`delete`/`relate` or any other
|
|
|
|
|
|
* mutation. Released on `close()` and on process exit/SIGINT/SIGTERM.
|
|
|
|
|
|
* - `'reader'`: opens without acquiring the writer lock. Coexists with a live
|
|
|
|
|
|
* writer and with other readers. All mutation methods throw
|
|
|
|
|
|
* `Cannot mutate a read-only Brainy instance`. Use `Brainy.openReadOnly()`
|
|
|
|
|
|
* as a convenience factory.
|
|
|
|
|
|
*
|
|
|
|
|
|
* For cloud storage backends (s3/r2/gcs/azure) the lock is a best-effort
|
|
|
|
|
|
* advisory marker — multi-process safety against concurrent writers on
|
|
|
|
|
|
* cloud-backed stores is not yet enforced. See `docs/concepts/multi-process.md`.
|
|
|
|
|
|
*/
|
|
|
|
|
|
mode?: 'writer' | 'reader'
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Bypass the writer-lock check at init even when another writer holds the lock.
|
|
|
|
|
|
* Use only when you know the existing lock is stale and stale-detection
|
|
|
|
|
|
* (PID liveness + heartbeat) cannot prove it. Logs a warning regardless.
|
|
|
|
|
|
*/
|
|
|
|
|
|
force?: boolean
|
2025-09-11 16:23:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============= Neural API Types =============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Neural similarity parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface NeuralSimilarityParams {
|
|
|
|
|
|
between?: [any, any] // Compare two items
|
|
|
|
|
|
items?: any[] // Compare multiple items
|
|
|
|
|
|
explain?: boolean // Return detailed breakdown
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Neural clustering parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface NeuralClusterParams {
|
|
|
|
|
|
items?: string[] | Entity[] // Items to cluster (or all)
|
|
|
|
|
|
algorithm?: 'hierarchical' | 'kmeans' | 'dbscan' | 'spectral'
|
|
|
|
|
|
params?: {
|
|
|
|
|
|
k?: number // Number of clusters (kmeans)
|
|
|
|
|
|
threshold?: number // Distance threshold (hierarchical)
|
|
|
|
|
|
epsilon?: number // DBSCAN epsilon
|
|
|
|
|
|
minPoints?: number // DBSCAN min points
|
|
|
|
|
|
}
|
|
|
|
|
|
visualize?: boolean // Return visualization data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Neural anomaly detection parameters
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface NeuralAnomalyParams {
|
|
|
|
|
|
threshold?: number // Standard deviations (default: 2.5)
|
|
|
|
|
|
type?: NounType // Check specific type
|
|
|
|
|
|
method?: 'isolation' | 'lof' | 'statistical' | 'autoencoder'
|
|
|
|
|
|
returnScores?: boolean // Return anomaly scores
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// ============= Content Extraction Types =============
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Detected content type for smart text extraction
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
export type ContentType = 'plaintext' | 'richtext-json' | 'html' | 'markdown'
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Content category for extracted segments
|
|
|
|
|
|
*
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Universal categories that work across documents, code, and UI:
|
|
|
|
|
|
* - 'title': Names the subject — headings, identifiers, labels, JSON keys
|
|
|
|
|
|
* - 'annotation': Human explanation — comments, docstrings, captions, alt text
|
|
|
|
|
|
* - 'content': Body substance — paragraphs, list items, flowing text
|
|
|
|
|
|
* - 'value': Data literals — strings, numbers, form values, error messages
|
|
|
|
|
|
* - 'code': Unparsed code blocks (custom parsers decompose into above)
|
|
|
|
|
|
* - 'structural': Boilerplate — keywords, operators, punctuation, formatting
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
*
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Built-in extractors produce: 'title', 'content', 'code'.
|
|
|
|
|
|
* All 6 categories are available for custom parsers.
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
*/
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
export type ContentCategory = 'title' | 'annotation' | 'content' | 'value' | 'code' | 'structural'
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* A segment of extracted text with its content category
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ExtractedSegment {
|
|
|
|
|
|
/** The extracted text content */
|
|
|
|
|
|
text: string
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
/** What role this text plays: 'title' | 'annotation' | 'content' | 'value' | 'code' | 'structural' */
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
contentCategory: ContentCategory
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
// ============= Semantic Highlighting Types =============
|
2026-01-26 17:16:18 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Parameters for hybrid highlighting
|
2026-01-26 17:16:18 -08:00
|
|
|
|
*
|
|
|
|
|
|
* Zero-config highlighting that returns both text (exact) and semantic (concept) matches.
|
|
|
|
|
|
* Perfect for UI highlighting at different levels.
|
|
|
|
|
|
*
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Added contentType hint and contentExtractor callback for structured text
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
* (rich-text JSON, HTML, Markdown). Auto-detects format when not specified.
|
|
|
|
|
|
*
|
2026-01-26 17:16:18 -08:00
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* // Plain text
|
2026-01-26 17:16:18 -08:00
|
|
|
|
* const highlights = await brain.highlight({
|
|
|
|
|
|
* query: "david the warrior",
|
|
|
|
|
|
* text: "David Smith is a brave fighter who battles dragons"
|
|
|
|
|
|
* })
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
*
|
|
|
|
|
|
* // Rich-text JSON (auto-detected)
|
|
|
|
|
|
* const highlights = await brain.highlight({
|
|
|
|
|
|
* query: "david the warrior",
|
|
|
|
|
|
* text: JSON.stringify(tiptapDocument)
|
|
|
|
|
|
* })
|
|
|
|
|
|
*
|
|
|
|
|
|
* // Custom extractor (for proprietary formats)
|
|
|
|
|
|
* const highlights = await brain.highlight({
|
|
|
|
|
|
* query: "function",
|
|
|
|
|
|
* text: sourceCode,
|
|
|
|
|
|
* contentExtractor: (text) => treeSitterParse(text)
|
|
|
|
|
|
* })
|
2026-01-26 17:16:18 -08:00
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface HighlightParams {
|
|
|
|
|
|
/** The search query to match against */
|
|
|
|
|
|
query: string
|
|
|
|
|
|
|
|
|
|
|
|
/** The text to highlight (e.g., entity.data) */
|
|
|
|
|
|
text: string
|
|
|
|
|
|
|
|
|
|
|
|
/** Granularity of highlighting: 'word' (default), 'phrase', or 'sentence' */
|
|
|
|
|
|
granularity?: 'word' | 'phrase' | 'sentence'
|
|
|
|
|
|
|
|
|
|
|
|
/** Minimum semantic similarity score for semantic matches (default: 0.5) */
|
|
|
|
|
|
threshold?: number
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Optional content type hint to skip auto-detection.
|
|
|
|
|
|
* When omitted, the content type is detected from the text content.
|
|
|
|
|
|
*/
|
|
|
|
|
|
contentType?: ContentType
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Optional custom content extractor function.
|
|
|
|
|
|
* When provided, bypasses built-in detection and extraction entirely.
|
|
|
|
|
|
* Use this to plug in custom parsers (tree-sitter, Monaco, proprietary formats).
|
|
|
|
|
|
*/
|
|
|
|
|
|
contentExtractor?: (text: string) => ExtractedSegment[]
|
2026-01-26 17:16:18 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* A highlight showing which text matched the query
|
|
|
|
|
|
*
|
|
|
|
|
|
* matchType tells the UI how to style the highlight:
|
|
|
|
|
|
* - 'text': Exact word match (strongest signal, highest confidence)
|
|
|
|
|
|
* - 'semantic': Conceptually similar match (may need softer highlight)
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface Highlight {
|
|
|
|
|
|
/** The text that matched */
|
|
|
|
|
|
text: string
|
|
|
|
|
|
|
|
|
|
|
|
/** Match score (0-1). For text matches, always 1.0. For semantic, varies by similarity. */
|
|
|
|
|
|
score: number
|
|
|
|
|
|
|
|
|
|
|
|
/** Position in original text [start, end] */
|
|
|
|
|
|
position: [number, number]
|
|
|
|
|
|
|
|
|
|
|
|
/** Match type: 'text' (exact word match) or 'semantic' (concept match) */
|
|
|
|
|
|
matchType: 'text' | 'semantic'
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
|
|
|
|
|
|
/**
|
feat: expand ContentCategory to universal 6-category set for highlight()
Replace document-centric categories (prose/heading/code/label) with a
universal set that works across documents, code, and UI:
- title: headings, identifiers, labels, JSON keys
- annotation: comments, docstrings, captions, alt text
- content: paragraphs, list items, flowing text
- value: string literals, numbers, form values
- code: unparsed code blocks
- structural: keywords, operators, punctuation
Built-in extractors now produce title/content/code. All 6 categories
are available for custom parsers (e.g. tree-sitter).
Also adds inline code detection in Markdown: backtick spans within
prose lines are split into separate code/content segments.
2026-01-27 13:44:58 -08:00
|
|
|
|
* Content category of the source segment: 'title' | 'annotation' | 'content' | 'value' | 'code' | 'structural'.
|
feat: add structured content extraction and batch embedding optimization to highlight()
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
2026-01-27 10:27:22 -08:00
|
|
|
|
* Present when the input text was structured (JSON, HTML, Markdown).
|
|
|
|
|
|
*/
|
|
|
|
|
|
contentCategory?: ContentCategory
|
2026-01-26 17:16:18 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:23:32 -07:00
|
|
|
|
// ============= Export all types =============
|
|
|
|
|
|
|
|
|
|
|
|
export * from './graphTypes.js' // Re-export NounType, VerbType, etc.
|