diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..b55605d7
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,57 @@
+# Git
+.git
+.gitignore
+
+# Development
+.vscode
+.idea
+*.swp
+*.swo
+.DS_Store
+
+# Node
+node_modules
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Testing
+tests
+*.test.ts
+*.test.js
+coverage
+.nyc_output
+
+# Documentation (keep only essentials)
+docs
+*.md
+!README.md
+!LICENSE
+
+# Build artifacts (will be built in Docker)
+dist
+build
+*.tsbuildinfo
+
+# Environment
+.env
+.env.*
+
+# Strategy and private docs
+.strategy
+CLAUDE.md
+
+# Development files
+docker-compose.yml
+Dockerfile
+.dockerignore
+
+# Data (should be mounted, not baked in)
+data
+*.db
+*.sqlite
+
+# Models (should be downloaded at runtime or mounted)
+models
+*.onnx
+*.bin
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 625b492e..7378a5ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,3 +74,15 @@ CLAUDE.md
# Backup folders
backup-*
backup/
+
+# Internal documentation
+docs/internal/
+
+# Cache files
+*.cache
+
+# Log files (redundant but explicit)
+*.log
+
+# Temporary files (redundant but explicit)
+*.tmp
diff --git a/.opencode/agent/vitest-qa-engineer.md b/.opencode/agent/vitest-qa-engineer.md
new file mode 100644
index 00000000..82acaa03
--- /dev/null
+++ b/.opencode/agent/vitest-qa-engineer.md
@@ -0,0 +1,150 @@
+---
+description: >-
+ Use this agent when you need to create, review, or enhance Vitest test suites
+ for the brainy application, particularly focusing on public API validation,
+ embedding model testing, and performance/scale verification. This includes
+ writing new test cases, improving existing test coverage, debugging test
+ failures, and ensuring comprehensive validation of all features.
+
+
+ Examples:
+
+ -
+ Context: The user has just implemented a new public API endpoint and needs comprehensive testing.
+ user: "I've added a new /api/embeddings endpoint that processes text and returns vectors"
+ assistant: "I'll use the vitest-qa-engineer agent to create comprehensive tests for this new API endpoint"
+
+ Since a new API endpoint was created, use the vitest-qa-engineer agent to ensure proper test coverage including validation, error cases, and performance testing.
+
+
+ -
+ Context: The user wants to verify the embedding model's accuracy and performance.
+ user: "We need to validate that our embedding model maintains consistency across different input sizes"
+ assistant: "Let me invoke the vitest-qa-engineer agent to create performance and consistency tests for the embedding model"
+
+ The user needs specialized testing for the embedding model, which requires the vitest-qa-engineer agent's expertise in creating performance and validation tests.
+
+
+ -
+ Context: The user has made changes to the codebase and wants to ensure nothing is broken.
+ user: "I've refactored the authentication middleware, can you check if everything still works?"
+ assistant: "I'll use the vitest-qa-engineer agent to review and run the relevant test suites for the authentication system"
+
+ After refactoring, the vitest-qa-engineer agent should verify that existing tests pass and identify any gaps in test coverage.
+
+
+mode: all
+---
+You are an elite QA engineer specializing in Vitest testing frameworks with deep expertise in API validation, machine learning model testing, and performance engineering. Your mission is to ensure bulletproof quality assurance for the brainy application through comprehensive, maintainable, and efficient test suites.
+
+**Core Responsibilities:**
+
+You will design and implement rigorous test strategies using Vitest that cover:
+- Every public API endpoint with exhaustive validation of inputs, outputs, and edge cases
+- Embedding model accuracy, consistency, and performance characteristics
+- System scalability under various load conditions
+- Performance benchmarks and regression detection
+- Integration points and data flow validation
+
+**Testing Philosophy:**
+
+You approach testing with a security-first, performance-conscious mindset. Every test you write should:
+- Validate both happy paths and failure scenarios
+- Include boundary condition testing
+- Verify error handling and recovery mechanisms
+- Measure and assert on performance metrics where relevant
+- Ensure backward compatibility for public APIs
+
+**Vitest Implementation Standards:**
+
+When writing tests, you will:
+- Use descriptive test names that clearly state what is being tested and expected outcomes
+- Organize tests into logical describe blocks following the Arrange-Act-Assert pattern
+- Implement proper setup and teardown using beforeEach/afterEach hooks
+- Utilize Vitest's powerful mocking capabilities for isolating units under test
+- Leverage concurrent testing where appropriate for performance
+- Include snapshot testing for API response structures
+- Implement custom matchers for domain-specific assertions
+
+**Public API Testing Requirements:**
+
+For each public API endpoint, you will create tests that verify:
+- Request validation (required fields, data types, constraints)
+- Authentication and authorization mechanisms
+- Response structure and data integrity
+- HTTP status codes for various scenarios
+- Rate limiting and throttling behavior
+- CORS and security headers
+- Pagination, filtering, and sorting functionality
+- Concurrent request handling
+- API versioning compatibility
+
+**Embedding Model Testing Strategy:**
+
+You will validate the embedding model through:
+- Consistency tests ensuring identical inputs produce identical outputs
+- Similarity tests verifying semantic relationships are preserved
+- Performance benchmarks for various input sizes
+- Memory usage profiling under load
+- Edge case handling (empty inputs, maximum length inputs, special characters)
+- Cross-validation against expected embedding dimensions
+- Temporal stability tests to detect model drift
+
+**Performance and Scale Testing:**
+
+You will implement:
+- Load tests simulating realistic user patterns
+- Stress tests to identify breaking points
+- Spike tests for sudden traffic increases
+- Endurance tests for memory leaks and resource exhaustion
+- Benchmark suites with performance budgets
+- Database query performance validation
+- Caching effectiveness measurements
+- Response time percentile tracking (p50, p95, p99)
+
+**Test Data Management:**
+
+You will:
+- Create comprehensive fixtures for consistent test data
+- Implement factories for generating test objects
+- Use seed data for database-dependent tests
+- Ensure test isolation through proper cleanup
+- Manage test environment configurations
+
+**Code Coverage and Quality Metrics:**
+
+You will maintain:
+- Minimum 80% code coverage for critical paths
+- 100% coverage for public API handlers
+- Branch coverage for complex logic
+- Integration test coverage for user workflows
+- Performance regression detection thresholds
+
+**Error Handling and Debugging:**
+
+When tests fail, you will:
+- Provide clear, actionable error messages
+- Include relevant context and data in assertions
+- Implement custom error formatters for complex validations
+- Add debugging helpers for troubleshooting
+- Document known issues and workarounds
+
+**Continuous Integration Optimization:**
+
+You will ensure tests are:
+- Fast enough for rapid feedback cycles
+- Parallelizable for CI/CD efficiency
+- Deterministic and free from race conditions
+- Environment-agnostic where possible
+- Tagged for selective execution (unit, integration, e2e, performance)
+
+**Documentation and Maintenance:**
+
+You will:
+- Document test scenarios and their business rationale
+- Maintain a test plan for each major feature
+- Create testing guidelines for the development team
+- Regular test suite refactoring to prevent decay
+- Generate test reports with actionable insights
+
+When asked to create or review tests, you will always consider the broader testing strategy and ensure your contributions align with the overall quality goals of the brainy application. You prioritize tests that provide the highest value in terms of risk mitigation and confidence in system reliability.
diff --git a/.recovery-workspace/brainy.corrupted.ts b/.recovery-workspace/brainy.corrupted.ts
new file mode 100644
index 00000000..c5552de1
--- /dev/null
+++ b/.recovery-workspace/brainy.corrupted.ts
@@ -0,0 +1,740 @@
+/**
+ * 🧠 Brainy 3.0 - The Future of Neural Databases
+ *
+ * Beautiful, Professional, Planet-Scale, Fun to Use
+ * NO STUBS, NO MOCKS, REAL IMPLEMENTATION
+ */
+import { v4 as uuidv4 } from './universal/uuid.js';
+import { HNSWIndex } from './hnsw/hnswIndex.js';
+import { HNSWIndexOptimized } from './hnsw/hnswIndexOptimized.js';
+import { createStorage } from './storage/storageFactory.js';
+import { cosineDistance } from './utils/index.js';
+import { validateNounType, validateVerbType } from './utils/typeValidation.js';
+import { matchesMetadataFilter } from './utils/metadataFilter.js';
+import { AugmentationRegistry } from './augmentations/brainyAugmentation.js';
+import { createDefaultAugmentations } from './augmentations/defaultAugmentations.js';
+import { ImprovedNeuralAPI } from './neural/improvedNeuralAPI.js';
+import { NaturalLanguageProcessor } from './neural/naturalLanguageProcessor.js';
+import { NounType } from './types/graphTypes.js';
+/**
+ * The main Brainy class - Clean, Beautiful, Powerful
+ * REAL IMPLEMENTATION - No stubs, no mocks
+ */
+export class Brainy {
+ constructor(config) {
+ // State
+ this.initialized = false;
+ // Normalize configuration with defaults
+ this.config = this.normalizeConfig(config);
+ // Setup core components
+ this.distance = cosineDistance;
+ this.embedder = this.setupEmbedder();
+ this.augmentationRegistry = this.setupAugmentations();
+ // Index and storage are initialized in init() because they may need each other
+ }
+ /**
+ * Initialize Brainy - MUST be called before use
+ */
+ async init() {
+ if (this.initialized) {
+ return;
+ }
+ try {
+ // Setup and initialize storage
+ this.storage = await this.setupStorage();
+ await this.storage.init();
+ // Setup index now that we have storage
+ this.index = this.setupIndex();
+ // Initialize augmentations
+ await this.augmentationRegistry.initializeAll({
+ brain: this,
+ storage: this.storage,
+ config: this.config,
+ log: (message, level = 'info') => {
+ // Simple logging for now
+ if (level === 'error') {
+ console.error(message);
+ }
+ else if (level === 'warn') {
+ console.warn(message);
+ }
+ else {
+ console.log(message);
+ }
+ }
+ });
+ // Warm up if configured
+ if (this.config.warmup) {
+ await this.warmup();
+ }
+ this.initialized = true;
+ }
+ catch (error) {
+ throw new Error(`Failed to initialize Brainy: ${error}`);
+ }
+ }
+ /**
+ * Ensure Brainy is initialized
+ */
+ async ensureInitialized() {
+ if (!this.initialized) {
+ throw new Error('Brainy not initialized. Call init() first.');
+ }
+ }
+ // ============= CORE CRUD OPERATIONS =============
+ /**
+ * Add an entity to the database
+ */
+ async add(params) {
+ await this.ensureInitialized();
+ // Validate parameters
+ if (!params.data && !params.vector) {
+ throw new Error('Either data or vector is required');
+ }
+ validateNounType(params.type);
+ // Generate ID if not provided
+ const id = params.id || uuidv4();
+ // Get or compute vector
+ const vector = params.vector || (await this.embed(params.data));
+ // Ensure dimensions are set
+ if (!this.dimensions) {
+ this.dimensions = vector.length;
+ }
+ else if (vector.length !== this.dimensions) {
+ throw new Error(`Vector dimension mismatch: expected ${this.dimensions}, got ${vector.length}`);
+ }
+ // Execute through augmentation pipeline
+ return this.augmentationRegistry.execute('add', params, async () => {
+ // Add to index
+ await this.index.addItem({ id, vector });
+ // Save to storage
+ await this.storage.saveNoun({
+ id,
+ vector,
+ connections: new Map(),
+ level: 0,
+ metadata: {
+ ...params.metadata,
+ noun: params.type,
+ service: params.service,
+ createdAt: Date.now()
+ }
+ });
+ return id;
+ });
+ }
+ /**
+ * Get an entity by ID
+ */
+ async get(id) {
+ await this.ensureInitialized();
+ return this.augmentationRegistry.execute('get', { id }, async () => {
+ // Get from storage
+ const noun = await this.storage.getNoun(id);
+ if (!noun) {
+ return null;
+ }
+ // Extract metadata - separate user metadata from system metadata
+ const { noun: nounType, service, createdAt, updatedAt, ...userMetadata } = noun.metadata || {};
+ // Construct entity from noun
+ const entity = {
+ id: noun.id,
+ vector: noun.vector,
+ type: nounType || NounType.Thing,
+ metadata: userMetadata,
+ service: service,
+ createdAt: createdAt || Date.now(),
+ updatedAt: updatedAt
+ };
+ return entity;
+ });
+ }
+ /**
+ * Update an entity
+ */
+ async update(params) {
+ await this.ensureInitialized();
+ if (!params.id) {
+ throw new Error('ID is required for update');
+ }
+ return this.augmentationRegistry.execute('update', params, async () => {
+ // Get existing entity
+ const existing = await this.get(params.id);
+ if (!existing) {
+ throw new Error(`Entity ${params.id} not found`);
+ }
+ // Update vector if data changed
+ let vector = existing.vector;
+ if (params.data) {
+ vector = params.vector || (await this.embed(params.data));
+ // Update in index (remove and re-add since no update method)
+ await this.index.removeItem(params.id);
+ await this.index.addItem({ id: params.id, vector });
+ }
+ // Always update the noun with new metadata
+ const newMetadata = params.merge !== false
+ ? { ...existing.metadata, ...params.metadata }
+ : params.metadata || existing.metadata;
+ await this.storage.saveNoun({
+ id: params.id,
+ vector,
+ connections: new Map(),
+ level: 0,
+ metadata: {
+ ...newMetadata,
+ noun: params.type || existing.type,
+ service: existing.service,
+ createdAt: existing.createdAt,
+ updatedAt: Date.now()
+ }
+ });
+ });
+ }
+ /**
+ * Delete an entity
+ */
+ async delete(id) {
+ await this.ensureInitialized();
+ return this.augmentationRegistry.execute('delete', { id }, async () => {
+ // Remove from index
+ await this.index.removeItem(id);
+ // Delete from storage
+ await this.storage.deleteNoun(id);
+ // Delete metadata (if it exists as separate)
+ try {
+ await this.storage.saveMetadata(id, null); // Clear metadata
+ }
+ catch {
+ // Ignore if not supported
+ }
+ // Delete related verbs
+ const verbs = await this.storage.getVerbsBySource(id);
+ const targetVerbs = await this.storage.getVerbsByTarget(id);
+ const allVerbs = [...verbs, ...targetVerbs];
+ for (const verb of allVerbs) {
+ await this.storage.deleteVerb(verb.id);
+ }
+ });
+ }
+ // ============= RELATIONSHIP OPERATIONS =============
+ /**
+ * Create a relationship between entities
+ */
+ async relate(params) {
+ await this.ensureInitialized();
+ // Validate parameters
+ if (!params.from || !params.to) {
+ throw new Error('Both from and to are required');
+ }
+ validateVerbType(params.type);
+ // Verify entities exist
+ const fromEntity = await this.get(params.from);
+ const toEntity = await this.get(params.to);
+ if (!fromEntity) {
+ throw new Error(`Source entity ${params.from} not found`);
+ }
+ if (!toEntity) {
+ throw new Error(`Target entity ${params.to} not found`);
+ }
+ // Generate ID
+ const id = uuidv4();
+ // Compute relationship vector (average of entities)
+ const relationVector = fromEntity.vector.map((v, i) => (v + toEntity.vector[i]) / 2);
+ return this.augmentationRegistry.execute('relate', params, async () => {
+ // Save to storage
+ const verb = {
+ id,
+ vector: relationVector,
+ sourceId: params.from,
+ targetId: params.to,
+ source: fromEntity.type,
+ target: toEntity.type,
+ verb: params.type,
+ type: params.type,
+ weight: params.weight ?? 1.0,
+ metadata: params.metadata,
+ createdAt: Date.now()
+ };
+ await this.storage.saveVerb(verb);
+ // Create bidirectional if requested
+ if (params.bidirectional) {
+ const reverseId = uuidv4();
+ const reverseVerb = {
+ ...verb,
+ id: reverseId,
+ sourceId: params.to,
+ targetId: params.from,
+ source: toEntity.type,
+ target: fromEntity.type
+ };
+ await this.storage.saveVerb(reverseVerb);
+ }
+ return id;
+ });
+ }
+ /**
+ * Delete a relationship
+ */
+ async unrelate(id) {
+ await this.ensureInitialized();
+ return this.augmentationRegistry.execute('unrelate', { id }, async () => {
+ await this.storage.deleteVerb(id);
+ });
+ }
+ /**
+ * Get relationships
+ */
+ async getRelations(params = {}) {
+ await this.ensureInitialized();
+ const relations = [];
+ if (params.from) {
+ const verbs = await this.storage.getVerbsBySource(params.from);
+ relations.push(...this.verbsToRelations(verbs));
+ }
+ if (params.to) {
+ const verbs = await this.storage.getVerbsByTarget(params.to);
+ relations.push(...this.verbsToRelations(verbs));
+ }
+ // Filter by type
+ let filtered = relations;
+ if (params.type) {
+ const types = Array.isArray(params.type) ? params.type : [params.type];
+ filtered = relations.filter((r) => types.includes(r.type));
+ }
+ // Filter by service
+ if (params.service) {
+ filtered = filtered.filter((r) => r.service === params.service);
+ }
+ // Apply pagination
+ const limit = params.limit || 100;
+ const offset = params.offset || 0;
+ return filtered.slice(offset, offset + limit);
+ }
+ // ============= SEARCH & DISCOVERY =============
+ /**
+ * Unified find method - supports natural language and structured queries
+ */
+ async find(query) {
+ await this.ensureInitialized();
+ // Parse natural language queries
+ const params = typeof query === 'string' ? await this.parseNaturalQuery(query) : query;
+ return this.augmentationRegistry.execute('find', params, async () => {
+ let results = [];
+ // Vector search
+ if (params.query || params.vector) {
+ const vector = params.vector || (await this.embed(params.query));
+ const limit = params.limit || 10;
+ // Search index - returns array of [id, score] tuples
+ const searchResults = await this.index.search(vector, limit * 2); // Get extra for filtering
+ // Hydrate results
+ for (const [id, score] of searchResults) {
+ const entity = await this.get(id);
+ if (entity) {
+ results.push({
+ id,
+ score,
+ entity
+ });
+ }
+ }
+ }
+ // Proximity search
+ if (params.near) {
+ const nearEntity = await this.get(params.near.id);
+ if (nearEntity) {
+ const nearResults = await this.index.search(nearEntity.vector, params.limit || 10);
+ for (const [id, score] of nearResults) {
+ if (score >= (params.near.threshold || 0.7)) {
+ const entity = await this.get(id);
+ if (entity) {
+ results.push({
+ id,
+ score,
+ entity
+ });
+ }
+ }
+ }
+ }
+ }
+ // Apply filters
+ if (params.where) {
+ results = results.filter((r) => matchesMetadataFilter(r.entity.metadata, params.where));
+ }
+ if (params.type) {
+ const types = Array.isArray(params.type) ? params.type : [params.type];
+ results = results.filter((r) => types.includes(r.entity.type));
+ }
+ if (params.service) {
+ results = results.filter((r) => r.entity.service === params.service);
+ }
+ // Graph constraints
+ if (params.connected) {
+ results = await this.applyGraphConstraints(results, params.connected);
+ }
+ // Sort by score and limit
+ results.sort((a, b) => b.score - a.score);
+ const limit = params.limit || 10;
+ const offset = params.offset || 0;
+ return results.slice(offset, offset + limit);
+ });
+ }
+ /**
+ * Find similar entities
+ */
+ async similar(params) {
+ await this.ensureInitialized();
+ // Get target vector
+ let targetVector;
+ if (typeof params.to === 'string') {
+ const entity = await this.get(params.to);
+ if (!entity) {
+ throw new Error(`Entity ${params.to} not found`);
+ }
+ targetVector = entity.vector;
+ }
+ else if (Array.isArray(params.to)) {
+ targetVector = params.to;
+ }
+ else {
+ targetVector = params.to.vector;
+ }
+ // Use find with vector
+ return this.find({
+ vector: targetVector,
+ limit: params.limit,
+ type: params.type,
+ where: params.where,
+ service: params.service
+ });
+ }
+ // ============= BATCH OPERATIONS =============
+ /**
+ * Add multiple entities
+ */
+ async addMany(params) {
+ await this.ensureInitialized();
+ const result = {
+ successful: [],
+ failed: [],
+ total: params.items.length,
+ duration: 0
+ };
+ const startTime = Date.now();
+ const chunkSize = params.chunkSize || 100;
+ // Process in chunks
+ for (let i = 0; i < params.items.length; i += chunkSize) {
+ const chunk = params.items.slice(i, i + chunkSize);
+ const promises = chunk.map(async (item) => {
+ try {
+ const id = await this.add(item);
+ result.successful.push(id);
+ }
+ catch (error) {
+ result.failed.push({
+ item,
+ error: error.message
+ });
+ if (!params.continueOnError) {
+ throw error;
+ }
+ }
+ });
+ if (params.parallel !== false) {
+ await Promise.allSettled(promises);
+ }
+ else {
+ for (const promise of promises) {
+ await promise;
+ }
+ }
+ // Report progress
+ if (params.onProgress) {
+ params.onProgress(result.successful.length + result.failed.length, result.total);
+ }
+ }
+ result.duration = Date.now() - startTime;
+ return result;
+ }
+ /**
+ * Delete multiple entities
+ */
+ async deleteMany(params) {
+ await this.ensureInitialized();
+ // Determine what to delete
+ let idsToDelete = [];
+ if (params.ids) {
+ idsToDelete = params.ids;
+ }
+ else if (params.type || params.where) {
+ // Find entities to delete
+ const entities = await this.find({
+ type: params.type,
+ where: params.where,
+ limit: params.limit || 1000
+ });
+ idsToDelete = entities.map((e) => e.id);
+ }
+ const result = {
+ successful: [],
+ failed: [],
+ total: idsToDelete.length,
+ duration: 0
+ };
+ const startTime = Date.now();
+ for (const id of idsToDelete) {
+ try {
+ await this.delete(id);
+ result.successful.push(id);
+ }
+ catch (error) {
+ result.failed.push({
+ item: id,
+ error: error.message
+ });
+ }
+ if (params.onProgress) {
+ params.onProgress(result.successful.length + result.failed.length, result.total);
+ }
+ }
+ result.duration = Date.now() - startTime;
+ return result;
+ }
+ // ============= SUB-APIS =============
+ /**
+ * Neural API - Advanced AI operations
+ */
+ neural() {
+ if (!this._neural) {
+ this._neural = new ImprovedNeuralAPI(this);
+ }
+ return this._neural;
+ }
+}
+return this._neural;
+/**
+ * Neural API - Advanced AI operations
+ */
+neural();
+{
+ if (!this._neural) {
+ this._neural = new ImprovedNeuralAPI(this);
+ }
+ return this._neural;
+}
+/**
+ * Natural Language Processing API
+ */
+nlp();
+{
+ if (!this._nlp) {
+ this._nlp = new NaturalLanguageProcessor(this);
+ }
+ return this._nlp;
+}
+/**
+ * Create a streaming pipeline
+ */
+stream();
+{
+ const { Pipeline } = require('./streaming/pipeline.js');
+ return new Pipeline(this);
+}
+/**
+ * Get insights about the data
+ */
+async;
+insights();
+Promise < {
+ entities: number,
+ relationships: number,
+ types: (Record),
+ services: string[],
+ density: number
+} > {
+ await, this: .ensureInitialized()
+ // Get all entities count
+ ,
+ // Get all entities count
+ const: allEntities = await this.storage.getAllNouns(),
+ const: entities = allEntities.length
+ // Get relationships count
+ ,
+ // Get relationships count
+ const: allVerbs = await this.storage.getAllVerbs(),
+ const: relationships = allVerbs.length
+ // Count by type
+ ,
+ // Count by type
+ const: types
+};
+{ }
+for (const entity of allEntities) {
+ const type = entity.metadata?.noun || 'unknown';
+ types[type] = (types[type] || 0) + 1;
+}
+// Get unique services
+const services = [...new Set(allEntities.map(e => e.metadata?.service).filter(Boolean))];
+// Calculate density (relationships per entity)
+const density = entities > 0 ? relationships / entities : 0;
+return {
+ entities,
+ relationships,
+ types,
+ services,
+ density
+};
+/**
+ * Augmentations API - Clean and simple
+ */
+get;
+augmentations();
+{
+ return {
+ list: () => this.augmentationRegistry.getAll().map(a => a.name),
+ get: (name) => this.augmentationRegistry.getAll().find(a => a.name === name),
+ has: (name) => this.augmentationRegistry.getAll().some(a => a.name === name)
+ };
+}
+async;
+parseNaturalQuery(query, string);
+Promise < FindParams < T >> {
+ : ._nlp
+};
+{
+ this._nlp = new NaturalLanguageProcessor(this);
+}
+const parsed = await this._nlp.processNaturalQuery(query);
+return parsed;
+async;
+applyGraphConstraints(results, Result < T > [], constraints, any);
+Promise < Result < T > [] > {
+ // Filter by graph connections
+ if(constraints) { }, : .to || constraints.from
+};
+{
+ const filtered = [];
+ for (const result of results) {
+ if (constraints.to) {
+ const verbs = await this.storage.getVerbsBySource(result.id);
+ const hasConnection = verbs.some(v => v.targetId === constraints.to);
+ if (hasConnection) {
+ filtered.push(result);
+ }
+ }
+ if (constraints.from) {
+ const verbs = await this.storage.getVerbsByTarget(result.id);
+ const hasConnection = verbs.some(v => v.sourceId === constraints.from);
+ if (hasConnection) {
+ filtered.push(result);
+ }
+ }
+ }
+ return filtered;
+}
+return results;
+verbsToRelations(verbs, GraphVerb[]);
+Relation < T > [];
+{
+ return verbs.map((v) => ({
+ id: v.id,
+ from: v.sourceId,
+ to: v.targetId,
+ type: (v.verb || v.type),
+ weight: v.weight,
+ metadata: v.metadata,
+ service: v.metadata?.service,
+ createdAt: typeof v.createdAt === 'number' ? v.createdAt : Date.now()
+ }));
+}
+async;
+embed(data, any);
+Promise < Vector > {
+ return: this.embedder(data)
+};
+async;
+warmup();
+Promise < void > {
+ // Warm up embedder
+ await, this: .embed('warmup')
+};
+setupEmbedder();
+EmbeddingFunction;
+{
+ if (this.config.model?.type === 'custom' && this.config.model.name) {
+ // TODO: Load custom model
+ return defaultEmbeddingFunction;
+ }
+ return defaultEmbeddingFunction;
+}
+async;
+setupStorage();
+Promise < StorageAdapter > {
+ const: storage = await createStorage({
+ type: this.config.storage?.type || 'memory',
+ ...this.config.storage?.options
+ }),
+ return: storage
+};
+setupIndex();
+HNSWIndex | HNSWIndexOptimized;
+{
+ const indexConfig = {
+ ...this.config.index,
+ distanceFunction: this.distance
+ };
+ // Use optimized index for larger datasets
+ if (this.config.storage?.type !== 'memory') {
+ return new HNSWIndexOptimized(indexConfig, this.distance, this.storage);
+ }
+ return new HNSWIndex(indexConfig);
+}
+setupAugmentations();
+AugmentationRegistry;
+{
+ const registry = new AugmentationRegistry();
+ // Register default augmentations
+ const defaults = createDefaultAugmentations(this.config.augmentations);
+ for (const aug of defaults) {
+ registry.register(aug);
+ }
+ return registry;
+}
+normalizeConfig(config ? : BrainyConfig);
+Required < BrainyConfig > {
+ return: {
+ storage: config?.storage || { type: 'memory' },
+ model: config?.model || { type: 'fast' },
+ index: config?.index || {},
+ cache: config?.cache ?? true,
+ augmentations: config?.augmentations || {},
+ warmup: config?.warmup ?? false,
+ realtime: config?.realtime ?? false,
+ multiTenancy: config?.multiTenancy ?? false,
+ telemetry: config?.telemetry ?? false
+ }
+};
+/**
+ * Close and cleanup
+ */
+async;
+close();
+Promise < void > {
+ // Shutdown augmentations
+ const: augs = this.augmentationRegistry.getAll(),
+ for(, aug, of, augs) {
+ if ('shutdown' in aug && typeof aug.shutdown === 'function') {
+ await aug.shutdown();
+ }
+ }
+ // Storage doesn't have close in current interface
+ // We'll just mark as not initialized
+ ,
+ // Storage doesn't have close in current interface
+ // We'll just mark as not initialized
+ this: .initialized = false
+};
+// Re-export types for convenience
+export * from './types/brainy.types.js';
+export { NounType, VerbType } from './types/graphTypes.js';
+//# sourceMappingURL=brainy.js.map
\ No newline at end of file
diff --git a/.recovery-workspace/brainy.recovered-20250910-142457.ts b/.recovery-workspace/brainy.recovered-20250910-142457.ts
new file mode 100644
index 00000000..c8b7319e
--- /dev/null
+++ b/.recovery-workspace/brainy.recovered-20250910-142457.ts
@@ -0,0 +1,927 @@
+/**
+ * 🧠 Brainy 3.0 - The Future of Neural Databases
+ *
+ * Beautiful, Professional, Planet-Scale, Fun to Use
+ * NO STUBS, NO MOCKS, REAL IMPLEMENTATION
+ */
+
+import { v4 as uuidv4 } from './universal/uuid.js'
+import { HNSWIndex } from './hnsw/hnswIndex.js'
+import { HNSWIndexOptimized } from './hnsw/hnswIndexOptimized.js'
+import { createStorage } from './storage/storageFactory.js'
+import { StorageAdapter, Vector, DistanceFunction, EmbeddingFunction, GraphVerb } from './coreTypes.js'
+import {
+ defaultEmbeddingFunction,
+ cosineDistance
+} from './utils/index.js'
+import { validateNounType, validateVerbType } from './utils/typeValidation.js'
+import { matchesMetadataFilter } from './utils/metadataFilter.js'
+import { AugmentationRegistry, AugmentationContext } from './augmentations/brainyAugmentation.js'
+import { createDefaultAugmentations } from './augmentations/defaultAugmentations.js'
+import { ImprovedNeuralAPI } from './neural/improvedNeuralAPI.js'
+import { NaturalLanguageProcessor } from './neural/naturalLanguageProcessor.js'
+import { TripleIntelligenceSystem } from './triple/TripleIntelligenceSystem.js'
+import {
+ Entity,
+ Relation,
+ Result,
+ AddParams,
+ UpdateParams,
+ RelateParams,
+ FindParams,
+ SimilarParams,
+ GetRelationsParams,
+ AddManyParams,
+ DeleteManyParams,
+ BatchResult,
+ BrainyConfig
+} from './types/brainy.types.js'
+import { NounType, VerbType } from './types/graphTypes.js'
+
+/**
+ * The main Brainy class - Clean, Beautiful, Powerful
+ * REAL IMPLEMENTATION - No stubs, no mocks
+ */
+export class Brainy {
+ // Core components
+ private index!: HNSWIndex | HNSWIndexOptimized
+ private storage!: StorageAdapter
+ private embedder: EmbeddingFunction
+ private distance: DistanceFunction
+ private augmentationRegistry: AugmentationRegistry
+ private config: Required
+
+ // Sub-APIs (lazy-loaded)
+ private _neural?: ImprovedNeuralAPI
+ private _nlp?: NaturalLanguageProcessor
+ private _tripleIntelligence?: TripleIntelligenceSystem
+
+ // State
+ private initialized = false
+ private dimensions?: number
+
+ constructor(config?: BrainyConfig) {
+ // Normalize configuration with defaults
+ this.config = this.normalizeConfig(config)
+
+ // Setup core components
+ this.distance = cosineDistance
+ this.embedder = this.setupEmbedder()
+ this.augmentationRegistry = this.setupAugmentations()
+
+ // Index and storage are initialized in init() because they may need each other
+ }
+
+ /**
+ * Initialize Brainy - MUST be called before use
+ * @param overrides Optional configuration overrides for init
+ */
+ async init(overrides?: Partial): Promise {
+ if (this.initialized) {
+ return
+ }
+
+ // Apply any init-time configuration overrides
+ if (overrides) {
+ const { dimensions, ...configOverrides } = overrides
+ this.config = {
+ ...this.config,
+ ...configOverrides,
+ storage: { ...this.config.storage, ...configOverrides.storage },
+ model: { ...this.config.model, ...configOverrides.model },
+ index: { ...this.config.index, ...configOverrides.index },
+ augmentations: { ...this.config.augmentations, ...configOverrides.augmentations }
+ }
+
+ // Set dimensions if provided
+ if (dimensions) {
+ this.dimensions = dimensions
+ }
+ }
+
+ try {
+ // Setup and initialize storage
+ this.storage = await this.setupStorage()
+ await this.storage.init()
+
+ // Setup index now that we have storage
+ this.index = this.setupIndex()
+
+ // Initialize augmentations
+ await this.augmentationRegistry.initializeAll({
+ brain: this,
+ storage: this.storage,
+ config: this.config,
+ log: (message: string, level = 'info') => {
+ // Simple logging for now
+ if (level === 'error') {
+ console.error(message)
+ } else if (level === 'warn') {
+ console.warn(message)
+ } else {
+ console.log(message)
+ }
+ }
+ })
+
+ // Warm up if configured
+ if (this.config.warmup) {
+ await this.warmup()
+ }
+
+ this.initialized = true
+ } catch (error) {
+ throw new Error(`Failed to initialize Brainy: ${error}`)
+ }
+ }
+
+ /**
+ * Ensure Brainy is initialized
+ */
+ private async ensureInitialized(): Promise {
+ if (!this.initialized) {
+ throw new Error('Brainy not initialized. Call init() first.')
+ }
+ }
+
+ // ============= CORE CRUD OPERATIONS =============
+
+ /**
+ * Add an entity to the database
+ */
+ async add(params: AddParams): Promise {
+ await this.ensureInitialized()
+
+ // Validate parameters
+ if (!params.data && !params.vector) {
+ throw new Error('Either data or vector is required')
+ }
+ validateNounType(params.type)
+
+ // Generate ID if not provided
+ const id = params.id || uuidv4()
+
+ // Get or compute vector
+ const vector = params.vector || (await this.embed(params.data))
+
+ // Ensure dimensions are set
+ if (!this.dimensions) {
+ this.dimensions = vector.length
+ } else if (vector.length !== this.dimensions) {
+ throw new Error(
+ `Vector dimension mismatch: expected ${this.dimensions}, got ${vector.length}`
+ )
+ }
+
+ // Execute through augmentation pipeline
+ return this.augmentationRegistry.execute('add', params, async () => {
+ // Add to index
+ await this.index.addItem({ id, vector })
+
+ // Save to storage
+ await this.storage.saveNoun({
+ id,
+ vector,
+ connections: new Map(),
+ level: 0,
+ metadata: {
+ ...params.metadata,
+ noun: params.type,
+ service: params.service,
+ createdAt: Date.now()
+ }
+ })
+
+ return id
+ })
+ }
+
+ /**
+ * Get an entity by ID
+ */
+ async get(id: string): Promise | null> {
+ await this.ensureInitialized()
+
+ return this.augmentationRegistry.execute('get', { id }, async () => {
+ // Get from storage
+ const noun = await this.storage.getNoun(id)
+ if (!noun) {
+ return null
+ }
+
+ // Extract metadata - separate user metadata from system metadata
+ const { noun: nounType, service, createdAt, updatedAt, ...userMetadata } = noun.metadata || {}
+
+ // Construct entity from noun
+ const entity: Entity = {
+ id: noun.id,
+ vector: noun.vector,
+ type: (nounType as NounType) || NounType.Thing,
+ metadata: userMetadata as T,
+ service: service as string,
+ createdAt: (createdAt as number) || Date.now(),
+ updatedAt: updatedAt as number
+ }
+
+ return entity
+ })
+ }
+
+ /**
+ * Update an entity
+ */
+ async update(params: UpdateParams): Promise {
+ await this.ensureInitialized()
+
+ if (!params.id) {
+ throw new Error('ID is required for update')
+ }
+
+ return this.augmentationRegistry.execute('update', params, async () => {
+ // Get existing entity
+ const existing = await this.get(params.id)
+ if (!existing) {
+ throw new Error(`Entity ${params.id} not found`)
+ }
+
+ // Update vector if data changed
+ let vector = existing.vector
+ if (params.data) {
+ vector = params.vector || (await this.embed(params.data))
+ // Update in index (remove and re-add since no update method)
+ await this.index.removeItem(params.id)
+ await this.index.addItem({ id: params.id, vector })
+ }
+
+ // Always update the noun with new metadata
+ const newMetadata = params.merge !== false
+ ? { ...existing.metadata, ...params.metadata }
+ : params.metadata || existing.metadata
+
+ await this.storage.saveNoun({
+ id: params.id,
+ vector,
+ connections: new Map(),
+ level: 0,
+ metadata: {
+ ...newMetadata,
+ noun: params.type || existing.type,
+ service: existing.service,
+ createdAt: existing.createdAt,
+ updatedAt: Date.now()
+ }
+ })
+ })
+ }
+
+ /**
+ * Delete an entity
+ */
+ async delete(id: string): Promise {
+ await this.ensureInitialized()
+
+ return this.augmentationRegistry.execute('delete', { id }, async () => {
+ // Remove from index
+ await this.index.removeItem(id)
+
+ // Delete from storage
+ await this.storage.deleteNoun(id)
+
+ // Delete metadata (if it exists as separate)
+ try {
+ await this.storage.saveMetadata(id, null as any) // Clear metadata
+ } catch {
+ // Ignore if not supported
+ }
+
+ // Delete related verbs
+ const verbs = await this.storage.getVerbsBySource(id)
+ const targetVerbs = await this.storage.getVerbsByTarget(id)
+ const allVerbs = [...verbs, ...targetVerbs]
+
+ for (const verb of allVerbs) {
+ await this.storage.deleteVerb(verb.id)
+ }
+ })
+ }
+
+ // ============= RELATIONSHIP OPERATIONS =============
+
+ /**
+ * Create a relationship between entities
+ */
+ async relate(params: RelateParams): Promise {
+ await this.ensureInitialized()
+
+ // Validate parameters
+ if (!params.from || !params.to) {
+ throw new Error('Both from and to are required')
+ }
+ validateVerbType(params.type)
+
+ // Verify entities exist
+ const fromEntity = await this.get(params.from)
+ const toEntity = await this.get(params.to)
+
+ if (!fromEntity) {
+ throw new Error(`Source entity ${params.from} not found`)
+ }
+ if (!toEntity) {
+ throw new Error(`Target entity ${params.to} not found`)
+ }
+
+ // Generate ID
+ const id = uuidv4()
+
+ // Compute relationship vector (average of entities)
+ const relationVector = fromEntity.vector.map(
+ (v, i) => (v + toEntity.vector[i]) / 2
+ )
+
+ return this.augmentationRegistry.execute('relate', params, async () => {
+ // Save to storage
+ const verb: GraphVerb = {
+ id,
+ vector: relationVector,
+ sourceId: params.from,
+ targetId: params.to,
+ source: fromEntity.type,
+ target: toEntity.type,
+ verb: params.type,
+ type: params.type,
+ weight: params.weight ?? 1.0,
+ metadata: params.metadata as any,
+ createdAt: Date.now()
+ } as any
+
+ await this.storage.saveVerb(verb)
+
+ // Create bidirectional if requested
+ if (params.bidirectional) {
+ const reverseId = uuidv4()
+ const reverseVerb: GraphVerb = {
+ ...verb,
+ id: reverseId,
+ sourceId: params.to,
+ targetId: params.from,
+ source: toEntity.type,
+ target: fromEntity.type
+ } as any
+
+ await this.storage.saveVerb(reverseVerb)
+ }
+
+ return id
+ })
+ }
+
+ /**
+ * Delete a relationship
+ */
+ async unrelate(id: string): Promise {
+ await this.ensureInitialized()
+
+ return this.augmentationRegistry.execute('unrelate', { id }, async () => {
+ await this.storage.deleteVerb(id)
+ })
+ }
+
+ /**
+ * Get relationships
+ */
+ async getRelations(
+ params: GetRelationsParams = {}
+ ): Promise[]> {
+ await this.ensureInitialized()
+
+ const relations: Relation[] = []
+
+ if (params.from) {
+ const verbs = await this.storage.getVerbsBySource(params.from)
+ relations.push(...this.verbsToRelations(verbs))
+ }
+
+ if (params.to) {
+ const verbs = await this.storage.getVerbsByTarget(params.to)
+ relations.push(...this.verbsToRelations(verbs))
+ }
+
+ // Filter by type
+ let filtered = relations
+ if (params.type) {
+ const types = Array.isArray(params.type) ? params.type : [params.type]
+ filtered = relations.filter((r) => types.includes(r.type))
+ }
+
+ // Filter by service
+ if (params.service) {
+ filtered = filtered.filter((r) => r.service === params.service)
+ }
+
+ // Apply pagination
+ const limit = params.limit || 100
+ const offset = params.offset || 0
+ return filtered.slice(offset, offset + limit)
+ }
+
+ // ============= SEARCH & DISCOVERY =============
+
+ /**
+ * Unified find method - supports natural language and structured queries
+ */
+ async find(query: string | FindParams): Promise[]> {
+ await this.ensureInitialized()
+
+ // Parse natural language queries
+ const params: FindParams =
+ typeof query === 'string' ? await this.parseNaturalQuery(query) : query
+
+ return this.augmentationRegistry.execute('find', params, async () => {
+ let results: Result[] = []
+
+ // Vector search
+ if (params.query || params.vector) {
+ const vector = params.vector || (await this.embed(params.query!))
+ const limit = params.limit || 10
+
+ // Search index - returns array of [id, score] tuples
+ const searchResults = await this.index.search(vector, limit * 2) // Get extra for filtering
+
+ // Hydrate results
+ for (const [id, score] of searchResults) {
+ const entity = await this.get(id)
+ if (entity) {
+ results.push({
+ id,
+ score,
+ entity
+ })
+ }
+ }
+ }
+
+ // Proximity search
+ if (params.near) {
+ const nearEntity = await this.get(params.near.id)
+ if (nearEntity) {
+ const nearResults = await this.index.search(
+ nearEntity.vector,
+ params.limit || 10
+ )
+
+ for (const [id, score] of nearResults) {
+ if (score >= (params.near.threshold || 0.7)) {
+ const entity = await this.get(id)
+ if (entity) {
+ results.push({
+ id,
+ score,
+ entity
+ })
+ }
+ }
+ }
+ }
+ }
+
+ // Apply filters
+ if (params.where) {
+ results = results.filter((r) =>
+ matchesMetadataFilter(r.entity.metadata, params.where!)
+ )
+ }
+
+ if (params.type) {
+ const types = Array.isArray(params.type) ? params.type : [params.type]
+ results = results.filter((r) => types.includes(r.entity.type))
+ }
+
+ if (params.service) {
+ results = results.filter((r) => r.entity.service === params.service)
+ }
+
+ // Graph constraints
+ if (params.connected) {
+ results = await this.applyGraphConstraints(results, params.connected)
+ }
+
+ // Sort by score and limit
+ results.sort((a, b) => b.score - a.score)
+ const limit = params.limit || 10
+ const offset = params.offset || 0
+
+ return results.slice(offset, offset + limit)
+ })
+ }
+
+ /**
+ * Find similar entities
+ */
+ async similar(params: SimilarParams): Promise[]> {
+ await this.ensureInitialized()
+
+ // Get target vector
+ let targetVector: Vector
+
+ if (typeof params.to === 'string') {
+ const entity = await this.get(params.to)
+ if (!entity) {
+ throw new Error(`Entity ${params.to} not found`)
+ }
+ targetVector = entity.vector
+ } else if (Array.isArray(params.to)) {
+ targetVector = params.to as Vector
+ } else {
+ targetVector = (params.to as Entity).vector
+ }
+
+ // Use find with vector
+ return this.find({
+ vector: targetVector,
+ limit: params.limit,
+ type: params.type,
+ where: params.where,
+ service: params.service
+ })
+ }
+
+ // ============= BATCH OPERATIONS =============
+
+ /**
+ * Add multiple entities
+ */
+ async addMany(params: AddManyParams): Promise> {
+ await this.ensureInitialized()
+
+ const result: BatchResult = {
+ successful: [],
+ failed: [],
+ total: params.items.length,
+ duration: 0
+ }
+
+ const startTime = Date.now()
+ const chunkSize = params.chunkSize || 100
+
+ // Process in chunks
+ for (let i = 0; i < params.items.length; i += chunkSize) {
+ const chunk = params.items.slice(i, i + chunkSize)
+
+ const promises = chunk.map(async (item) => {
+ try {
+ const id = await this.add(item)
+ result.successful.push(id)
+ } catch (error) {
+ result.failed.push({
+ item,
+ error: (error as Error).message
+ })
+ if (!params.continueOnError) {
+ throw error
+ }
+ }
+ })
+
+ if (params.parallel !== false) {
+ await Promise.allSettled(promises)
+ } else {
+ for (const promise of promises) {
+ await promise
+ }
+ }
+
+ // Report progress
+ if (params.onProgress) {
+ params.onProgress(
+ result.successful.length + result.failed.length,
+ result.total
+ )
+ }
+ }
+
+ result.duration = Date.now() - startTime
+ return result
+ }
+
+ /**
+ * Delete multiple entities
+ */
+ async deleteMany(params: DeleteManyParams): Promise> {
+ await this.ensureInitialized()
+
+ // Determine what to delete
+ let idsToDelete: string[] = []
+
+ if (params.ids) {
+ idsToDelete = params.ids
+ } else if (params.type || params.where) {
+ // Find entities to delete
+ const entities = await this.find({
+ type: params.type,
+ where: params.where,
+ limit: params.limit || 1000
+ })
+ idsToDelete = entities.map((e) => e.id)
+ }
+
+ const result: BatchResult = {
+ successful: [],
+ failed: [],
+ total: idsToDelete.length,
+ duration: 0
+ }
+
+ const startTime = Date.now()
+
+ for (const id of idsToDelete) {
+ try {
+ await this.delete(id)
+ result.successful.push(id)
+ } catch (error) {
+ result.failed.push({
+ item: id,
+ error: (error as Error).message
+ })
+ }
+
+ if (params.onProgress) {
+ params.onProgress(
+ result.successful.length + result.failed.length,
+ result.total
+ )
+ }
+ }
+
+ result.duration = Date.now() - startTime
+ return result
+ }
+
+ // ============= SUB-APIS =============
+
+ /**
+ * Neural API - Advanced AI operations
+ */
+ neural(): ImprovedNeuralAPI {
+ if (!this._neural) {
+ this._neural = new ImprovedNeuralAPI(this as any)
+ }
+ return this._neural
+ }
+
+ /**
+ * Natural Language Processing API
+ */
+ nlp(): NaturalLanguageProcessor {
+ if (!this._nlp) {
+ this._nlp = new NaturalLanguageProcessor(this)
+ }
+ return this._nlp
+ }
+
+ /**
+ * Get Triple Intelligence System
+ * Advanced pattern recognition and relationship analysis
+ */
+ getTripleIntelligence(): TripleIntelligenceSystem {
+ if (!this._tripleIntelligence) {
+ this._tripleIntelligence = new TripleIntelligenceSystem(this as any)
+ }
+ return this._tripleIntelligence
+ }
+
+ /**
+ * Create a streaming pipeline
+ */
+ stream() {
+ const { Pipeline } = require('./streaming/pipeline.js')
+ return new Pipeline(this)
+ }
+
+ /**
+ * Get insights about the data
+ */
+ async insights(): Promise<{
+ entities: number
+ relationships: number
+ types: Record
+ services: string[]
+ density: number
+ }> {
+ await this.ensureInitialized()
+
+ // Get all entities count - use getNouns with high limit
+ const entitiesResult = await this.storage.getNouns({
+ pagination: { limit: 10000 }
+ })
+ const entities = entitiesResult.totalCount || entitiesResult.items.length
+
+ // Get relationships count - use getVerbs with high limit
+ const verbsResult = await this.storage.getVerbs({
+ pagination: { limit: 10000 }
+ })
+ const relationships = verbsResult.totalCount || verbsResult.items.length
+
+ // Count by type
+ const types: Record = {}
+ for (const entity of entitiesResult.items) {
+ const type = (entity.metadata?.noun as string) || 'unknown'
+ types[type] = (types[type] || 0) + 1
+ }
+
+ // Get unique services
+ const services = [...new Set(entitiesResult.items.map((e: any) => e.metadata?.service).filter(Boolean))] as string[]
+
+ // Calculate density (relationships per entity)
+ const density = entities > 0 ? relationships / entities : 0
+
+ return {
+ entities,
+ relationships,
+ types,
+ services,
+ density
+ }
+ }
+
+ /**
+ * Augmentations API - Clean and simple
+ */
+ get augmentations() {
+ return {
+ list: () => this.augmentationRegistry.getAll().map(a => a.name),
+ get: (name: string) => this.augmentationRegistry.getAll().find(a => a.name === name),
+ has: (name: string) => this.augmentationRegistry.getAll().some(a => a.name === name)
+ }
+ }
+
+ // ============= HELPER METHODS =============
+
+ /**
+ * Parse natural language query
+ */
+ private async parseNaturalQuery(query: string): Promise> {
+ if (!this._nlp) {
+ this._nlp = new NaturalLanguageProcessor(this as any)
+ }
+ const parsed = await this._nlp.processNaturalQuery(query)
+ return parsed as FindParams
+ }
+
+ /**
+ * Apply graph constraints to results
+ */
+ private async applyGraphConstraints(
+ results: Result[],
+ constraints: any
+ ): Promise[]> {
+ // Filter by graph connections
+ if (constraints.to || constraints.from) {
+ const filtered: Result[] = []
+
+ for (const result of results) {
+ if (constraints.to) {
+ const verbs = await this.storage.getVerbsBySource(result.id)
+ const hasConnection = verbs.some(v => v.targetId === constraints.to)
+ if (hasConnection) {
+ filtered.push(result)
+ }
+ }
+
+ if (constraints.from) {
+ const verbs = await this.storage.getVerbsByTarget(result.id)
+ const hasConnection = verbs.some(v => v.sourceId === constraints.from)
+ if (hasConnection) {
+ filtered.push(result)
+ }
+ }
+ }
+
+ return filtered
+ }
+
+ return results
+ }
+
+ /**
+ * Convert verbs to relations
+ */
+ private verbsToRelations(verbs: GraphVerb[]): Relation[] {
+ return verbs.map((v) => ({
+ id: v.id,
+ from: v.sourceId,
+ to: v.targetId,
+ type: (v.verb || v.type) as VerbType,
+ weight: v.weight,
+ metadata: v.metadata,
+ service: v.metadata?.service as string,
+ createdAt: typeof v.createdAt === 'number' ? v.createdAt : Date.now()
+ }))
+ }
+
+ /**
+ * Embed data into vector
+ */
+ private async embed(data: any): Promise {
+ return this.embedder(data)
+ }
+
+ /**
+ * Warm up the system
+ */
+ private async warmup(): Promise {
+ // Warm up embedder
+ await this.embed('warmup')
+ }
+
+ /**
+ * Setup embedder
+ */
+ private setupEmbedder(): EmbeddingFunction {
+ if (this.config.model?.type === 'custom' && this.config.model.name) {
+ // TODO: Load custom model
+ return defaultEmbeddingFunction
+ }
+ return defaultEmbeddingFunction
+ }
+
+ /**
+ * Setup storage
+ */
+ private async setupStorage(): Promise {
+ const storage = await createStorage({
+ type: this.config.storage?.type || 'memory',
+ ...this.config.storage?.options
+ })
+ return storage
+ }
+
+ /**
+ * Setup index
+ */
+ private setupIndex(): HNSWIndex | HNSWIndexOptimized {
+ const indexConfig = {
+ ...this.config.index,
+ distanceFunction: this.distance
+ }
+
+ // Use optimized index for larger datasets
+ if (this.config.storage?.type !== 'memory') {
+ return new HNSWIndexOptimized(indexConfig, this.distance, this.storage)
+ }
+
+ return new HNSWIndex(indexConfig as any)
+ }
+
+ /**
+ * Setup augmentations
+ */
+ private setupAugmentations(): AugmentationRegistry {
+ const registry = new AugmentationRegistry()
+
+ // Register default augmentations
+ const defaults = createDefaultAugmentations(this.config.augmentations)
+ for (const aug of defaults) {
+ registry.register(aug)
+ }
+
+ return registry
+ }
+
+ /**
+ * Normalize configuration
+ */
+ private normalizeConfig(config?: BrainyConfig): Required {
+ return {
+ storage: config?.storage || { type: 'memory' },
+ model: config?.model || { type: 'fast' },
+ index: config?.index || {},
+ cache: config?.cache ?? true,
+ augmentations: config?.augmentations || {},
+ warmup: config?.warmup ?? false,
+ realtime: config?.realtime ?? false,
+ multiTenancy: config?.multiTenancy ?? false,
+ telemetry: config?.telemetry ?? false
+ }
+ }
+
+ /**
+ * Close and cleanup
+ */
+ async close(): Promise {
+ // Shutdown augmentations
+ const augs = this.augmentationRegistry.getAll()
+ for (const aug of augs) {
+ if ('shutdown' in aug && typeof aug.shutdown === 'function') {
+ await aug.shutdown()
+ }
+ }
+
+ // Storage doesn't have close in current interface
+ // We'll just mark as not initialized
+ this.initialized = false
+ }
+}
+
+// Re-export types for convenience
+export * from './types/brainy.types.js'
+export { NounType, VerbType } from './types/graphTypes.js'
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.d.ts b/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.d.ts
new file mode 100644
index 00000000..a27928fe
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.d.ts
@@ -0,0 +1,67 @@
+/**
+ * Configuration API for Brainy 3.0
+ * Provides configuration storage with optional encryption
+ */
+import { StorageAdapter } from '../coreTypes.js';
+export interface ConfigOptions {
+ encrypt?: boolean;
+ decrypt?: boolean;
+}
+export interface ConfigEntry {
+ key: string;
+ value: any;
+ encrypted: boolean;
+ createdAt: number;
+ updatedAt: number;
+}
+export declare class ConfigAPI {
+ private storage;
+ private security;
+ private configCache;
+ private CONFIG_NOUN_PREFIX;
+ constructor(storage: StorageAdapter);
+ /**
+ * Set a configuration value with optional encryption
+ */
+ set(params: {
+ key: string;
+ value: any;
+ encrypt?: boolean;
+ }): Promise;
+ /**
+ * Get a configuration value with optional decryption
+ */
+ get(params: {
+ key: string;
+ decrypt?: boolean;
+ defaultValue?: any;
+ }): Promise;
+ /**
+ * Delete a configuration value
+ */
+ delete(key: string): Promise;
+ /**
+ * List all configuration keys
+ */
+ list(): Promise;
+ /**
+ * Check if a configuration key exists
+ */
+ has(key: string): Promise;
+ /**
+ * Clear all configuration
+ */
+ clear(): Promise;
+ /**
+ * Export all configuration
+ */
+ export(): Promise>;
+ /**
+ * Import configuration
+ */
+ import(config: Record): Promise;
+ /**
+ * Get raw config entry (without decryption)
+ */
+ private getEntry;
+}
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.js b/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.js
new file mode 100644
index 00000000..f3c2ff1e
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.js
@@ -0,0 +1,166 @@
+/**
+ * Configuration API for Brainy 3.0
+ * Provides configuration storage with optional encryption
+ */
+import { SecurityAPI } from './SecurityAPI.js';
+export class ConfigAPI {
+ constructor(storage) {
+ this.storage = storage;
+ this.configCache = new Map();
+ this.CONFIG_NOUN_PREFIX = '_config_';
+ this.security = new SecurityAPI();
+ }
+ /**
+ * Set a configuration value with optional encryption
+ */
+ async set(params) {
+ const { key, value, encrypt = false } = params;
+ // Serialize and optionally encrypt the value
+ let storedValue = value;
+ if (typeof value !== 'string') {
+ storedValue = JSON.stringify(value);
+ }
+ if (encrypt) {
+ storedValue = await this.security.encrypt(storedValue);
+ }
+ // Create config entry
+ const entry = {
+ key,
+ value: storedValue,
+ encrypted: encrypt,
+ createdAt: this.configCache.get(key)?.createdAt || Date.now(),
+ updatedAt: Date.now()
+ };
+ // Store in cache
+ this.configCache.set(key, entry);
+ // Persist to storage
+ const configId = this.CONFIG_NOUN_PREFIX + key;
+ await this.storage.saveMetadata(configId, entry);
+ }
+ /**
+ * Get a configuration value with optional decryption
+ */
+ async get(params) {
+ const { key, decrypt, defaultValue } = params;
+ // Check cache first
+ let entry = this.configCache.get(key);
+ // If not in cache, load from storage
+ if (!entry) {
+ const configId = this.CONFIG_NOUN_PREFIX + key;
+ const metadata = await this.storage.getMetadata(configId);
+ if (!metadata) {
+ return defaultValue;
+ }
+ entry = metadata;
+ this.configCache.set(key, entry);
+ }
+ let value = entry.value;
+ // Decrypt if needed
+ const shouldDecrypt = decrypt !== undefined ? decrypt : entry.encrypted;
+ if (shouldDecrypt && entry.encrypted && typeof value === 'string') {
+ value = await this.security.decrypt(value);
+ }
+ // Try to parse JSON if it looks like JSON
+ if (typeof value === 'string' && (value.startsWith('{') || value.startsWith('['))) {
+ try {
+ value = JSON.parse(value);
+ }
+ catch {
+ // Not JSON, return as string
+ }
+ }
+ return value;
+ }
+ /**
+ * Delete a configuration value
+ */
+ async delete(key) {
+ // Remove from cache
+ this.configCache.delete(key);
+ // Remove from storage
+ const configId = this.CONFIG_NOUN_PREFIX + key;
+ await this.storage.saveMetadata(configId, null);
+ }
+ /**
+ * List all configuration keys
+ */
+ async list() {
+ // Get all metadata keys from storage
+ const allMetadata = await this.storage.getMetadata('');
+ if (!allMetadata || typeof allMetadata !== 'object') {
+ return [];
+ }
+ // Filter for config keys
+ const configKeys = [];
+ for (const key of Object.keys(allMetadata)) {
+ if (key.startsWith(this.CONFIG_NOUN_PREFIX)) {
+ configKeys.push(key.substring(this.CONFIG_NOUN_PREFIX.length));
+ }
+ }
+ return configKeys;
+ }
+ /**
+ * Check if a configuration key exists
+ */
+ async has(key) {
+ if (this.configCache.has(key)) {
+ return true;
+ }
+ const configId = this.CONFIG_NOUN_PREFIX + key;
+ const metadata = await this.storage.getMetadata(configId);
+ return metadata !== null && metadata !== undefined;
+ }
+ /**
+ * Clear all configuration
+ */
+ async clear() {
+ // Clear cache
+ this.configCache.clear();
+ // Clear from storage
+ const keys = await this.list();
+ for (const key of keys) {
+ await this.delete(key);
+ }
+ }
+ /**
+ * Export all configuration
+ */
+ async export() {
+ const keys = await this.list();
+ const config = {};
+ for (const key of keys) {
+ const entry = await this.getEntry(key);
+ if (entry) {
+ config[key] = entry;
+ }
+ }
+ return config;
+ }
+ /**
+ * Import configuration
+ */
+ async import(config) {
+ for (const [key, entry] of Object.entries(config)) {
+ this.configCache.set(key, entry);
+ const configId = this.CONFIG_NOUN_PREFIX + key;
+ await this.storage.saveMetadata(configId, entry);
+ }
+ }
+ /**
+ * Get raw config entry (without decryption)
+ */
+ async getEntry(key) {
+ if (this.configCache.has(key)) {
+ return this.configCache.get(key);
+ }
+ const configId = this.CONFIG_NOUN_PREFIX + key;
+ const metadata = await this.storage.getMetadata(configId);
+ if (!metadata) {
+ return null;
+ }
+ const entry = metadata;
+ this.configCache.set(key, entry);
+ return entry;
+ }
+}
+//# sourceMappingURL=ConfigAPI.js.map
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.js.map b/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.js.map
new file mode 100644
index 00000000..9cf3a317
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/ConfigAPI.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"ConfigAPI.js","sourceRoot":"","sources":["../../src/api/ConfigAPI.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.d.ts b/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.d.ts
new file mode 100644
index 00000000..3fc22a5b
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.d.ts
@@ -0,0 +1,118 @@
+/**
+ * Data Management API for Brainy 3.0
+ * Provides backup, restore, import, export, and data management
+ */
+import { StorageAdapter } from '../coreTypes.js';
+import { Entity, Relation } from '../types/brainy.types.js';
+import { NounType } from '../types/graphTypes.js';
+export interface BackupOptions {
+ includeVectors?: boolean;
+ compress?: boolean;
+ format?: 'json' | 'binary';
+}
+export interface RestoreOptions {
+ merge?: boolean;
+ overwrite?: boolean;
+ validate?: boolean;
+}
+export interface ImportOptions {
+ format: 'json' | 'csv' | 'parquet';
+ mapping?: Record;
+ batchSize?: number;
+ validate?: boolean;
+}
+export interface ExportOptions {
+ format?: 'json' | 'csv' | 'parquet';
+ filter?: {
+ type?: NounType | NounType[];
+ where?: Record;
+ service?: string;
+ };
+ includeVectors?: boolean;
+}
+export interface BackupData {
+ version: string;
+ timestamp: number;
+ entities: Array<{
+ id: string;
+ vector?: number[];
+ type: string;
+ metadata: any;
+ service?: string;
+ }>;
+ relations: Array<{
+ id: string;
+ from: string;
+ to: string;
+ type: string;
+ weight: number;
+ metadata?: any;
+ }>;
+ config?: Record;
+ stats: {
+ entityCount: number;
+ relationCount: number;
+ vectorDimensions?: number;
+ };
+}
+export interface ImportResult {
+ successful: number;
+ failed: number;
+ errors: Array<{
+ item: any;
+ error: string;
+ }>;
+ duration: number;
+}
+export declare class DataAPI {
+ private storage;
+ private getEntity;
+ private getRelation?;
+ private brain;
+ constructor(storage: StorageAdapter, getEntity: (id: string) => Promise, getRelation?: ((id: string) => Promise) | undefined, brain?: any);
+ /**
+ * Create a backup of all data
+ */
+ backup(options?: BackupOptions): Promise;
+ /**
+ * Restore data from a backup
+ */
+ restore(params: {
+ backup: BackupData;
+ merge?: boolean;
+ overwrite?: boolean;
+ validate?: boolean;
+ }): Promise;
+ /**
+ * Clear data
+ */
+ clear(params?: {
+ entities?: boolean;
+ relations?: boolean;
+ config?: boolean;
+ }): Promise;
+ /**
+ * Import data from various formats
+ */
+ import(params: ImportOptions & {
+ data: any;
+ }): Promise;
+ /**
+ * Export data to various formats
+ */
+ export(params?: ExportOptions): Promise;
+ /**
+ * Get storage statistics
+ */
+ getStats(): Promise<{
+ entities: number;
+ relations: number;
+ storageSize?: number;
+ vectorDimensions?: number;
+ }>;
+ private applyMapping;
+ private validateImportItem;
+ private matchesFilter;
+ private convertToCSV;
+ private generateId;
+}
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.js b/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.js
new file mode 100644
index 00000000..cffb1ec7
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.js
@@ -0,0 +1,386 @@
+/**
+ * Data Management API for Brainy 3.0
+ * Provides backup, restore, import, export, and data management
+ */
+import { NounType } from '../types/graphTypes.js';
+export class DataAPI {
+ constructor(storage, getEntity, getRelation, brain) {
+ this.storage = storage;
+ this.getEntity = getEntity;
+ this.getRelation = getRelation;
+ this.brain = brain;
+ }
+ /**
+ * Create a backup of all data
+ */
+ async backup(options = {}) {
+ const { includeVectors = true, compress = false, format = 'json' } = options;
+ const startTime = Date.now();
+ // Get all entities
+ const nounsResult = await this.storage.getNouns({
+ pagination: { limit: 1000000 }
+ });
+ const entities = [];
+ for (const noun of nounsResult.items) {
+ const entity = {
+ id: noun.id,
+ vector: includeVectors ? noun.vector : undefined,
+ type: noun.metadata?.noun || NounType.Thing,
+ metadata: noun.metadata,
+ service: noun.metadata?.service
+ };
+ entities.push(entity);
+ }
+ // Get all relations
+ const verbsResult = await this.storage.getVerbs({
+ pagination: { limit: 1000000 }
+ });
+ const relations = [];
+ for (const verb of verbsResult.items) {
+ relations.push({
+ id: verb.id,
+ from: verb.sourceId,
+ to: verb.targetId,
+ type: (verb.verb || verb.type),
+ weight: verb.weight || 1.0,
+ metadata: verb.metadata
+ });
+ }
+ // Create backup data
+ const backupData = {
+ version: '3.0.0',
+ timestamp: Date.now(),
+ entities,
+ relations,
+ stats: {
+ entityCount: entities.length,
+ relationCount: relations.length,
+ vectorDimensions: entities[0]?.vector?.length
+ }
+ };
+ // Compress if requested (simplified - just stringify for now)
+ if (compress) {
+ // In production, use proper compression like gzip
+ // For now, just return the data
+ }
+ return backupData;
+ }
+ /**
+ * Restore data from a backup
+ */
+ async restore(params) {
+ const { backup, merge = false, overwrite = false, validate = true } = params;
+ // Validate backup format
+ if (validate) {
+ if (!backup.version || !backup.entities || !backup.relations) {
+ throw new Error('Invalid backup format');
+ }
+ }
+ // Clear existing data if not merging
+ if (!merge && overwrite) {
+ await this.clear({ entities: true, relations: true });
+ }
+ // Restore entities
+ for (const entity of backup.entities) {
+ try {
+ const noun = {
+ id: entity.id,
+ vector: entity.vector || new Array(384).fill(0), // Default vector if missing
+ connections: new Map(),
+ level: 0,
+ metadata: {
+ ...entity.metadata,
+ noun: entity.type,
+ service: entity.service
+ }
+ };
+ // Check if entity exists when merging
+ if (merge) {
+ const existing = await this.storage.getNoun(entity.id);
+ if (existing && !overwrite) {
+ continue; // Skip existing entities unless overwriting
+ }
+ }
+ await this.storage.saveNoun(noun);
+ }
+ catch (error) {
+ console.error(`Failed to restore entity ${entity.id}:`, error);
+ }
+ }
+ // Restore relations
+ for (const relation of backup.relations) {
+ try {
+ // Get source and target entities to compute relation vector
+ const sourceNoun = await this.storage.getNoun(relation.from);
+ const targetNoun = await this.storage.getNoun(relation.to);
+ if (!sourceNoun || !targetNoun) {
+ console.warn(`Skipping relation ${relation.id}: missing entities`);
+ continue;
+ }
+ // Compute relation vector as average of source and target
+ const relationVector = sourceNoun.vector.map((v, i) => (v + targetNoun.vector[i]) / 2);
+ const verb = {
+ id: relation.id,
+ vector: relationVector,
+ sourceId: relation.from,
+ targetId: relation.to,
+ source: sourceNoun.metadata?.noun || NounType.Thing,
+ target: targetNoun.metadata?.noun || NounType.Thing,
+ verb: relation.type,
+ type: relation.type,
+ weight: relation.weight,
+ metadata: relation.metadata,
+ createdAt: Date.now()
+ };
+ // Check if relation exists when merging
+ if (merge) {
+ const existing = await this.storage.getVerb(relation.id);
+ if (existing && !overwrite) {
+ continue;
+ }
+ }
+ await this.storage.saveVerb(verb);
+ }
+ catch (error) {
+ console.error(`Failed to restore relation ${relation.id}:`, error);
+ }
+ }
+ }
+ /**
+ * Clear data
+ */
+ async clear(params = {}) {
+ const { entities = true, relations = true, config = false } = params;
+ if (entities) {
+ // Clear all entities
+ const nounsResult = await this.storage.getNouns({
+ pagination: { limit: 1000000 }
+ });
+ for (const noun of nounsResult.items) {
+ await this.storage.deleteNoun(noun.id);
+ }
+ // Also clear the HNSW index if available
+ if (this.brain?.index?.clear) {
+ this.brain.index.clear();
+ }
+ // Clear metadata index if available
+ if (this.brain?.metadataIndex) {
+ await this.brain.metadataIndex.rebuild(); // Rebuild empty index
+ }
+ }
+ if (relations) {
+ // Clear all relations
+ const verbsResult = await this.storage.getVerbs({
+ pagination: { limit: 1000000 }
+ });
+ for (const verb of verbsResult.items) {
+ await this.storage.deleteVerb(verb.id);
+ }
+ }
+ if (config) {
+ // Clear configuration would be handled by ConfigAPI
+ // For now, skip this
+ }
+ }
+ /**
+ * Import data from various formats
+ */
+ async import(params) {
+ const { data, format, mapping = {}, batchSize = 100, validate = true } = params;
+ const result = {
+ successful: 0,
+ failed: 0,
+ errors: [],
+ duration: 0
+ };
+ const startTime = Date.now();
+ try {
+ // ALWAYS use neural import for proper type matching
+ const { UniversalImportAPI } = await import('./UniversalImportAPI.js');
+ const universalImport = new UniversalImportAPI(this.brain);
+ await universalImport.init();
+ // Convert to ImportSource format
+ const neuralResult = await universalImport.import({
+ type: 'object',
+ data,
+ format: format || 'json',
+ metadata: { mapping, batchSize, validate }
+ });
+ // Convert neural result to ImportResult format
+ result.successful = neuralResult.stats.entitiesCreated;
+ result.failed = 0; // Neural import always succeeds with best match
+ result.duration = neuralResult.stats.processingTimeMs;
+ // Log relationships created
+ if (neuralResult.stats.relationshipsCreated > 0) {
+ console.log(`Neural import also created ${neuralResult.stats.relationshipsCreated} relationships`);
+ }
+ return result;
+ }
+ catch (error) {
+ // Fallback to legacy import ONLY if neural import fails to load
+ console.warn('Neural import failed, using legacy import:', error);
+ let items = [];
+ // Parse data based on format
+ switch (format) {
+ case 'json':
+ items = Array.isArray(data) ? data : [data];
+ break;
+ case 'csv':
+ // CSV parsing would go here
+ // For now, assume data is already parsed
+ items = data;
+ break;
+ case 'parquet':
+ // Parquet parsing would go here
+ throw new Error('Parquet format not yet implemented');
+ default:
+ throw new Error(`Unsupported format: ${format}`);
+ }
+ // Process items in batches
+ for (let i = 0; i < items.length; i += batchSize) {
+ const batch = items.slice(i, i + batchSize);
+ for (const item of batch) {
+ try {
+ // Apply field mapping
+ const mapped = this.applyMapping(item, mapping);
+ // Validate if requested
+ if (validate) {
+ this.validateImportItem(mapped);
+ }
+ // Save as entity
+ const noun = {
+ id: mapped.id || this.generateId(),
+ vector: mapped.vector || new Array(384).fill(0),
+ connections: new Map(),
+ level: 0,
+ metadata: mapped
+ };
+ await this.storage.saveNoun(noun);
+ result.successful++;
+ }
+ catch (error) {
+ result.failed++;
+ result.errors.push({
+ item,
+ error: error.message
+ });
+ }
+ }
+ }
+ result.duration = Date.now() - startTime;
+ return result;
+ }
+ }
+ /**
+ * Export data to various formats
+ */
+ async export(params = {}) {
+ const { format = 'json', filter = {}, includeVectors = false } = params;
+ // Get filtered entities
+ const nounsResult = await this.storage.getNouns({
+ pagination: { limit: 1000000 }
+ });
+ let entities = nounsResult.items;
+ // Apply filters
+ if (filter.type) {
+ const types = Array.isArray(filter.type) ? filter.type : [filter.type];
+ entities = entities.filter(e => types.includes(e.metadata?.noun));
+ }
+ if (filter.service) {
+ entities = entities.filter(e => e.metadata?.service === filter.service);
+ }
+ if (filter.where) {
+ entities = entities.filter(e => this.matchesFilter(e.metadata, filter.where));
+ }
+ // Format data based on export format
+ switch (format) {
+ case 'json':
+ return entities.map(e => ({
+ id: e.id,
+ vector: includeVectors ? e.vector : undefined,
+ ...e.metadata
+ }));
+ case 'csv':
+ // Convert to CSV format
+ // For now, return simplified format
+ return this.convertToCSV(entities);
+ case 'parquet':
+ throw new Error('Parquet export not yet implemented');
+ default:
+ throw new Error(`Unsupported export format: ${format}`);
+ }
+ }
+ /**
+ * Get storage statistics
+ */
+ async getStats() {
+ const nounsResult = await this.storage.getNouns({
+ pagination: { limit: 1 }
+ });
+ const verbsResult = await this.storage.getVerbs({
+ pagination: { limit: 1 }
+ });
+ const firstNoun = nounsResult.items[0];
+ return {
+ entities: nounsResult.totalCount || nounsResult.items.length,
+ relations: verbsResult.totalCount || verbsResult.items.length,
+ vectorDimensions: firstNoun?.vector?.length
+ };
+ }
+ // Helper methods
+ applyMapping(item, mapping) {
+ const mapped = {};
+ for (const [key, value] of Object.entries(item)) {
+ const mappedKey = mapping[key] || key;
+ mapped[mappedKey] = value;
+ }
+ return mapped;
+ }
+ validateImportItem(item) {
+ // Basic validation
+ if (!item || typeof item !== 'object') {
+ throw new Error('Invalid item: must be an object');
+ }
+ // Could add more validation here
+ }
+ matchesFilter(metadata, filter) {
+ for (const [key, value] of Object.entries(filter)) {
+ if (metadata[key] !== value) {
+ return false;
+ }
+ }
+ return true;
+ }
+ convertToCSV(entities) {
+ if (entities.length === 0)
+ return '';
+ // Get all unique keys from metadata
+ const keys = new Set();
+ for (const entity of entities) {
+ if (entity.metadata) {
+ Object.keys(entity.metadata).forEach(k => keys.add(k));
+ }
+ }
+ // Create CSV header
+ const headers = ['id', ...Array.from(keys)];
+ const rows = [headers.join(',')];
+ // Add data rows
+ for (const entity of entities) {
+ const row = [entity.id];
+ for (const key of keys) {
+ const value = entity.metadata?.[key] || '';
+ // Escape values that contain commas
+ const escaped = String(value).includes(',')
+ ? `"${String(value).replace(/"/g, '""')}"`
+ : String(value);
+ row.push(escaped);
+ }
+ rows.push(row.join(','));
+ }
+ return rows.join('\n');
+ }
+ generateId() {
+ return `import_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+ }
+}
+//# sourceMappingURL=DataAPI.js.map
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.js.map b/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.js.map
new file mode 100644
index 00000000..0d702154
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/DataAPI.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"DataAPI.js","sourceRoot":"","sources":["../../src/api/DataAPI.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.d.ts b/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.d.ts
new file mode 100644
index 00000000..6cd0e2e2
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.d.ts
@@ -0,0 +1,50 @@
+/**
+ * Security API for Brainy 3.0
+ * Provides encryption, decryption, hashing, and secure storage
+ */
+export declare class SecurityAPI {
+ private config?;
+ private encryptionKey?;
+ constructor(config?: {
+ encryptionKey?: string;
+ } | undefined);
+ /**
+ * Encrypt data using AES-256-CBC
+ */
+ encrypt(data: string): Promise;
+ /**
+ * Decrypt data encrypted with encrypt()
+ */
+ decrypt(encryptedData: string): Promise;
+ /**
+ * Create a one-way hash of data (for passwords, etc)
+ */
+ hash(data: string, algorithm?: 'sha256' | 'sha512'): Promise;
+ /**
+ * Compare data with a hash (for password verification)
+ */
+ compare(data: string, hash: string, algorithm?: 'sha256' | 'sha512'): Promise;
+ /**
+ * Generate a secure random token
+ */
+ generateToken(bytes?: number): Promise;
+ /**
+ * Derive a key from a password using PBKDF2
+ * Note: Simplified version using hash instead of PBKDF2 which may not be available
+ */
+ deriveKey(password: string, salt?: string, iterations?: number): Promise<{
+ key: string;
+ salt: string;
+ }>;
+ /**
+ * Sign data with HMAC
+ */
+ sign(data: string, secret?: string): Promise;
+ /**
+ * Verify HMAC signature
+ */
+ verify(data: string, signature: string, secret: string): Promise;
+ private hexToBytes;
+ private bytesToHex;
+ private constantTimeCompare;
+}
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.js b/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.js
new file mode 100644
index 00000000..7de1a4cd
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.js
@@ -0,0 +1,139 @@
+/**
+ * Security API for Brainy 3.0
+ * Provides encryption, decryption, hashing, and secure storage
+ */
+export class SecurityAPI {
+ constructor(config) {
+ this.config = config;
+ if (config?.encryptionKey) {
+ // Use provided key (must be 32 bytes hex string)
+ this.encryptionKey = this.hexToBytes(config.encryptionKey);
+ }
+ }
+ /**
+ * Encrypt data using AES-256-CBC
+ */
+ async encrypt(data) {
+ const crypto = await import('../universal/crypto.js');
+ // Generate or use existing key
+ const key = this.encryptionKey || crypto.randomBytes(32);
+ const iv = crypto.randomBytes(16);
+ const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
+ let encrypted = cipher.update(data, 'utf8', 'hex');
+ encrypted += cipher.final('hex');
+ // Package encrypted data with metadata
+ // In production, store keys separately in a key management service
+ return JSON.stringify({
+ encrypted,
+ key: this.bytesToHex(key),
+ iv: this.bytesToHex(iv),
+ algorithm: 'aes-256-cbc',
+ timestamp: Date.now()
+ });
+ }
+ /**
+ * Decrypt data encrypted with encrypt()
+ */
+ async decrypt(encryptedData) {
+ const crypto = await import('../universal/crypto.js');
+ try {
+ const parsed = JSON.parse(encryptedData);
+ const { encrypted, key: keyHex, iv: ivHex, algorithm } = parsed;
+ if (algorithm && algorithm !== 'aes-256-cbc') {
+ throw new Error(`Unsupported encryption algorithm: ${algorithm}`);
+ }
+ const key = this.hexToBytes(keyHex);
+ const iv = this.hexToBytes(ivHex);
+ const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
+ decrypted += decipher.final('utf8');
+ return decrypted;
+ }
+ catch (error) {
+ throw new Error(`Decryption failed: ${error.message}`);
+ }
+ }
+ /**
+ * Create a one-way hash of data (for passwords, etc)
+ */
+ async hash(data, algorithm = 'sha256') {
+ const crypto = await import('../universal/crypto.js');
+ const hash = crypto.createHash(algorithm);
+ hash.update(data);
+ return hash.digest('hex');
+ }
+ /**
+ * Compare data with a hash (for password verification)
+ */
+ async compare(data, hash, algorithm = 'sha256') {
+ const dataHash = await this.hash(data, algorithm);
+ return this.constantTimeCompare(dataHash, hash);
+ }
+ /**
+ * Generate a secure random token
+ */
+ async generateToken(bytes = 32) {
+ const crypto = await import('../universal/crypto.js');
+ const buffer = crypto.randomBytes(bytes);
+ return this.bytesToHex(buffer);
+ }
+ /**
+ * Derive a key from a password using PBKDF2
+ * Note: Simplified version using hash instead of PBKDF2 which may not be available
+ */
+ async deriveKey(password, salt, iterations = 100000) {
+ const crypto = await import('../universal/crypto.js');
+ const actualSalt = salt || this.bytesToHex(crypto.randomBytes(32));
+ // Simplified key derivation using repeated hashing
+ // In production, use a proper PBKDF2 implementation
+ let derived = password + actualSalt;
+ for (let i = 0; i < Math.min(iterations, 1000); i++) {
+ const hash = crypto.createHash('sha256');
+ hash.update(derived);
+ derived = hash.digest('hex');
+ }
+ return {
+ key: derived,
+ salt: actualSalt
+ };
+ }
+ /**
+ * Sign data with HMAC
+ */
+ async sign(data, secret) {
+ const crypto = await import('../universal/crypto.js');
+ const actualSecret = secret || (await this.generateToken());
+ const hmac = crypto.createHmac('sha256', actualSecret);
+ hmac.update(data);
+ return hmac.digest('hex');
+ }
+ /**
+ * Verify HMAC signature
+ */
+ async verify(data, signature, secret) {
+ const expectedSignature = await this.sign(data, secret);
+ return this.constantTimeCompare(signature, expectedSignature);
+ }
+ // Helper methods
+ hexToBytes(hex) {
+ const matches = hex.match(/.{1,2}/g);
+ if (!matches)
+ throw new Error('Invalid hex string');
+ return new Uint8Array(matches.map(byte => parseInt(byte, 16)));
+ }
+ bytesToHex(bytes) {
+ return Array.from(bytes)
+ .map(b => b.toString(16).padStart(2, '0'))
+ .join('');
+ }
+ constantTimeCompare(a, b) {
+ if (a.length !== b.length)
+ return false;
+ let result = 0;
+ for (let i = 0; i < a.length; i++) {
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
+ }
+ return result === 0;
+ }
+}
+//# sourceMappingURL=SecurityAPI.js.map
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.js.map b/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.js.map
new file mode 100644
index 00000000..b44399a3
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/SecurityAPI.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"SecurityAPI.js","sourceRoot":"","sources":["../../src/api/SecurityAPI.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/UniversalImportAPI.d.ts b/.recovery-workspace/dist-backup-20250910-141917/api/UniversalImportAPI.d.ts
new file mode 100644
index 00000000..350e8cf6
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/UniversalImportAPI.d.ts
@@ -0,0 +1,134 @@
+/**
+ * Universal Neural Import API
+ *
+ * ALWAYS uses neural matching to map ANY data to our strict NounTypes and VerbTypes
+ * Never falls back to rules - neural matching is MANDATORY
+ *
+ * Handles:
+ * - Strings (text, JSON, CSV, YAML, Markdown)
+ * - Files (local paths, any format)
+ * - URLs (web pages, APIs, documents)
+ * - Objects (structured data)
+ * - Binary data (images, PDFs via extraction)
+ */
+import { NounType, VerbType } from '../types/graphTypes.js';
+import { Vector } from '../coreTypes.js';
+import type { Brainy } from '../brainy.js';
+export interface ImportSource {
+ type: 'string' | 'file' | 'url' | 'object' | 'binary';
+ data: any;
+ format?: string;
+ metadata?: any;
+}
+export interface NeuralImportResult {
+ entities: Array<{
+ id: string;
+ type: NounType;
+ data: any;
+ vector: Vector;
+ confidence: number;
+ metadata: any;
+ }>;
+ relationships: Array<{
+ id: string;
+ from: string;
+ to: string;
+ type: VerbType;
+ weight: number;
+ confidence: number;
+ metadata?: any;
+ }>;
+ stats: {
+ totalProcessed: number;
+ entitiesCreated: number;
+ relationshipsCreated: number;
+ averageConfidence: number;
+ processingTimeMs: number;
+ };
+}
+export declare class UniversalImportAPI {
+ private brain;
+ private typeMatcher;
+ private neuralImport;
+ private embedCache;
+ constructor(brain: Brainy);
+ /**
+ * Initialize the neural import system
+ */
+ init(): Promise;
+ /**
+ * Universal import - handles ANY data source
+ * ALWAYS uses neural matching, NEVER falls back
+ */
+ import(source: ImportSource | string | any): Promise;
+ /**
+ * Import from URL - fetches and processes
+ */
+ importFromURL(url: string): Promise;
+ /**
+ * Import from file - reads and processes
+ * Note: In browser environment, use File API instead
+ */
+ importFromFile(filePath: string): Promise;
+ /**
+ * Normalize any input to ImportSource
+ */
+ private normalizeSource;
+ /**
+ * Extract structured data from source
+ */
+ private extractData;
+ /**
+ * Extract data from URL
+ */
+ private extractFromURL;
+ /**
+ * Extract data from file
+ */
+ private extractFromFile;
+ /**
+ * Extract data from string based on format
+ */
+ private extractFromString;
+ /**
+ * Extract from binary data (images, PDFs, etc)
+ */
+ private extractFromBinary;
+ /**
+ * Extract entities from plain text
+ */
+ private extractFromText;
+ /**
+ * Neural processing - CORE of the system
+ * ALWAYS uses embeddings and neural matching
+ */
+ private neuralProcess;
+ /**
+ * Generate embedding for any data
+ */
+ private generateEmbedding;
+ /**
+ * Convert any data to text for embedding
+ */
+ private dataToText;
+ /**
+ * Detect relationships using neural matching
+ */
+ private detectNeuralRelationships;
+ /**
+ * Check if a field looks like a reference
+ */
+ private looksLikeReference;
+ /**
+ * Store processed data in brain
+ */
+ private storeInBrain;
+ private detectFormat;
+ private parseCSV;
+ private parseYAML;
+ private parseMarkdown;
+ private parseHTML;
+ private generateId;
+ private simpleHash;
+ private hashBinary;
+}
diff --git a/.recovery-workspace/dist-backup-20250910-141917/api/UniversalImportAPI.js b/.recovery-workspace/dist-backup-20250910-141917/api/UniversalImportAPI.js
new file mode 100644
index 00000000..9644d8f6
--- /dev/null
+++ b/.recovery-workspace/dist-backup-20250910-141917/api/UniversalImportAPI.js
@@ -0,0 +1,610 @@
+/**
+ * Universal Neural Import API
+ *
+ * ALWAYS uses neural matching to map ANY data to our strict NounTypes and VerbTypes
+ * Never falls back to rules - neural matching is MANDATORY
+ *
+ * Handles:
+ * - Strings (text, JSON, CSV, YAML, Markdown)
+ * - Files (local paths, any format)
+ * - URLs (web pages, APIs, documents)
+ * - Objects (structured data)
+ * - Binary data (images, PDFs via extraction)
+ */
+import { getBrainyTypes } from '../augmentations/typeMatching/brainyTypes.js';
+import { NeuralImportAugmentation } from '../augmentations/neuralImport.js';
+export class UniversalImportAPI {
+ constructor(brain) {
+ this.embedCache = new Map();
+ this.brain = brain;
+ this.neuralImport = new NeuralImportAugmentation({
+ confidenceThreshold: 0.0, // Accept ALL confidence levels - never reject
+ enableWeights: true,
+ skipDuplicates: false // Process everything
+ });
+ }
+ /**
+ * Initialize the neural import system
+ */
+ async init() {
+ this.typeMatcher = await getBrainyTypes();
+ // Neural import initializes itself
+ }
+ /**
+ * Universal import - handles ANY data source
+ * ALWAYS uses neural matching, NEVER falls back
+ */
+ async import(source) {
+ const startTime = Date.now();
+ // Normalize source
+ const normalizedSource = this.normalizeSource(source);
+ // Extract data based on source type
+ const extractedData = await this.extractData(normalizedSource);
+ // Neural processing - MANDATORY
+ const neuralResults = await this.neuralProcess(extractedData);
+ // Store in brain
+ const result = await this.storeInBrain(neuralResults);
+ result.stats.processingTimeMs = Date.now() - startTime;
+ return result;
+ }
+ /**
+ * Import from URL - fetches and processes
+ */
+ async importFromURL(url) {
+ const response = await fetch(url);
+ const contentType = response.headers.get('content-type') || 'text/plain';
+ let data;
+ if (contentType.includes('json')) {
+ data = await response.json();
+ }
+ else if (contentType.includes('text') || contentType.includes('html')) {
+ data = await response.text();
+ }
+ else {
+ // Binary data
+ const buffer = await response.arrayBuffer();
+ data = new Uint8Array(buffer);
+ }
+ return this.import({
+ type: 'url',
+ data,
+ format: contentType,
+ metadata: { url, fetchedAt: Date.now() }
+ });
+ }
+ /**
+ * Import from file - reads and processes
+ * Note: In browser environment, use File API instead
+ */
+ async importFromFile(filePath) {
+ // For file imports, the caller should read the file and pass content
+ // This is a placeholder that treats the path as a reference
+ const ext = filePath.split('.').pop()?.toLowerCase() || 'txt';
+ return this.import({
+ type: 'file',
+ data: filePath, // Path as reference
+ format: ext,
+ metadata: {
+ path: filePath,
+ importedAt: Date.now()
+ }
+ });
+ }
+ /**
+ * Normalize any input to ImportSource
+ */
+ normalizeSource(source) {
+ // Already normalized
+ if (source && typeof source === 'object' && 'type' in source && 'data' in source) {
+ return source;
+ }
+ // String input
+ if (typeof source === 'string') {
+ // Check if it's a URL
+ if (source.startsWith('http://') || source.startsWith('https://')) {
+ return { type: 'url', data: source };
+ }
+ // Check if it looks like a file path
+ if (source.includes('/') || source.includes('\\') || source.includes('.')) {
+ // Assume it's a file path reference
+ return { type: 'file', data: source };
+ }
+ // Treat as raw string data
+ return { type: 'string', data: source };
+ }
+ // Object/Array input
+ if (typeof source === 'object') {
+ return { type: 'object', data: source };
+ }
+ // Default to string
+ return { type: 'string', data: String(source) };
+ }
+ /**
+ * Extract structured data from source
+ */
+ async extractData(source) {
+ switch (source.type) {
+ case 'url':
+ // URL is in data field, need to fetch
+ return this.extractFromURL(source.data);
+ case 'file':
+ // File path is in data field, need to read
+ return this.extractFromFile(source.data);
+ case 'string':
+ return this.extractFromString(source.data, source.format);
+ case 'object':
+ return Array.isArray(source.data) ? source.data : [source.data];
+ case 'binary':
+ return this.extractFromBinary(source.data, source.format);
+ default:
+ // Unknown type, treat as object
+ return [source.data];
+ }
+ }
+ /**
+ * Extract data from URL
+ */
+ async extractFromURL(url) {
+ const result = await this.importFromURL(url);
+ return result.entities.map(e => e.data);
+ }
+ /**
+ * Extract data from file
+ */
+ async extractFromFile(filePath) {
+ const result = await this.importFromFile(filePath);
+ return result.entities.map(e => e.data);
+ }
+ /**
+ * Extract data from string based on format
+ */
+ extractFromString(data, format) {
+ // Try to detect format if not provided
+ const detectedFormat = format || this.detectFormat(data);
+ switch (detectedFormat) {
+ case 'json':
+ try {
+ const parsed = JSON.parse(data);
+ return Array.isArray(parsed) ? parsed : [parsed];
+ }
+ catch {
+ // Not valid JSON, treat as text
+ return this.extractFromText(data);
+ }
+ case 'csv':
+ return this.parseCSV(data);
+ case 'yaml':
+ case 'yml':
+ return this.parseYAML(data);
+ case 'markdown':
+ case 'md':
+ return this.parseMarkdown(data);
+ case 'xml':
+ case 'html':
+ return this.parseHTML(data);
+ default:
+ return this.extractFromText(data);
+ }
+ }
+ /**
+ * Extract from binary data (images, PDFs, etc)
+ */
+ async extractFromBinary(data, format) {
+ // For now, create a single entity representing the binary data
+ // In production, would use OCR, image recognition, PDF extraction, etc.
+ return [{
+ type: 'binary',
+ format: format || 'unknown',
+ size: data.length,
+ hash: await this.hashBinary(data),
+ extractedAt: Date.now()
+ }];
+ }
+ /**
+ * Extract entities from plain text
+ */
+ extractFromText(text) {
+ // Split into meaningful chunks
+ const chunks = [];
+ // Split by paragraphs
+ const paragraphs = text.split(/\n\n+/);
+ for (const para of paragraphs) {
+ if (para.trim()) {
+ chunks.push({
+ text: para.trim(),
+ type: 'paragraph',
+ length: para.length
+ });
+ }
+ }
+ // If no paragraphs, split by sentences
+ if (chunks.length === 0) {
+ const sentences = text.match(/[^.!?]+[.!?]+/g) || [text];
+ for (const sentence of sentences) {
+ if (sentence.trim()) {
+ chunks.push({
+ text: sentence.trim(),
+ type: 'sentence',
+ length: sentence.length
+ });
+ }
+ }
+ }
+ return chunks;
+ }
+ /**
+ * Neural processing - CORE of the system
+ * ALWAYS uses embeddings and neural matching
+ */
+ async neuralProcess(data) {
+ const entities = new Map();
+ const relationships = new Map();
+ for (const item of data) {
+ // Generate embedding for the item
+ const embedding = await this.generateEmbedding(item);
+ // Neural type matching - MANDATORY
+ const nounMatch = await this.typeMatcher.matchNounType(item);
+ // Never reject based on confidence - we ALWAYS accept the best match
+ const entityId = this.generateId(item);
+ entities.set(entityId, {
+ id: entityId,
+ type: nounMatch.type, // Always use the neural match
+ data: item,
+ vector: embedding,
+ confidence: nounMatch.confidence,
+ metadata: {
+ ...item,
+ _neuralMatch: nounMatch,
+ _importedAt: Date.now()
+ }
+ });
+ // Detect relationships using neural matching
+ await this.detectNeuralRelationships(item, entityId, entities, relationships);
+ }
+ return { entities, relationships };
+ }
+ /**
+ * Generate embedding for any data
+ */
+ async generateEmbedding(data) {
+ // Convert to string for embedding
+ const text = this.dataToText(data);
+ // Check cache
+ if (this.embedCache.has(text)) {
+ return this.embedCache.get(text);
+ }
+ // Generate new embedding
+ const embedding = await this.brain.embed(text);
+ // Cache it
+ this.embedCache.set(text, embedding);
+ return embedding;
+ }
+ /**
+ * Convert any data to text for embedding
+ */
+ dataToText(data) {
+ if (typeof data === 'string')
+ return data;
+ if (typeof data === 'object') {
+ // Extract meaningful text from object
+ const parts = [];
+ // Priority fields
+ const priorityFields = ['name', 'title', 'description', 'text', 'content', 'label', 'value'];
+ for (const field of priorityFields) {
+ if (data[field]) {
+ parts.push(String(data[field]));
+ }
+ }
+ // Add other fields
+ for (const [key, value] of Object.entries(data)) {
+ if (!priorityFields.includes(key) && value) {
+ if (typeof value === 'string' || typeof value === 'number') {
+ parts.push(`${key}: ${value}`);
+ }
+ }
+ }
+ return parts.join(' ');
+ }
+ return JSON.stringify(data);
+ }
+ /**
+ * Detect relationships using neural matching
+ */
+ async detectNeuralRelationships(item, sourceId, entities, relationships) {
+ if (typeof item !== 'object')
+ return;
+ // Look for references to other entities
+ for (const [key, value] of Object.entries(item)) {
+ // Check if this looks like a reference
+ if (this.looksLikeReference(key, value)) {
+ // Find or predict target entity
+ const targetId = String(value);
+ // Neural verb type matching
+ const verbMatch = await this.typeMatcher.matchVerbType(item, // source object
+ { id: targetId }, // target (we may not have full data)
+ key // field name as context
+ );
+ // Always create relationship with neural match
+ const relationId = `${sourceId}_${verbMatch.type}_${targetId}`;
+ relationships.set(relationId, {
+ id: relationId,
+ from: sourceId,
+ to: targetId,
+ type: verbMatch.type,
+ weight: verbMatch.confidence, // Use confidence as weight
+ confidence: verbMatch.confidence,
+ metadata: {
+ field: key,
+ _neuralMatch: verbMatch,
+ _importedAt: Date.now()
+ }
+ });
+ }
+ // Handle arrays of references
+ if (Array.isArray(value)) {
+ for (const item of value) {
+ if (this.looksLikeReference(key, item)) {
+ const targetId = String(item);
+ const verbMatch = await this.typeMatcher.matchVerbType(item, { id: targetId }, key);
+ const relationId = `${sourceId}_${verbMatch.type}_${targetId}`;
+ relationships.set(relationId, {
+ id: relationId,
+ from: sourceId,
+ to: targetId,
+ type: verbMatch.type,
+ weight: verbMatch.confidence,
+ confidence: verbMatch.confidence,
+ metadata: {
+ field: key,
+ array: true,
+ _neuralMatch: verbMatch,
+ _importedAt: Date.now()
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+ /**
+ * Check if a field looks like a reference
+ */
+ looksLikeReference(key, value) {
+ // Field name patterns that suggest references
+ const refPatterns = [
+ /[Ii]d$/, // ends with Id or id
+ /_id$/, // ends with _id
+ /^parent/i, // starts with parent
+ /^child/i, // starts with child
+ /^related/i, // starts with related
+ /^ref/i, // starts with ref
+ /^link/i, // starts with link
+ /^target/i, // starts with target
+ /^source/i, // starts with source
+ ];
+ // Check if field name matches patterns
+ const fieldLooksLikeRef = refPatterns.some(pattern => pattern.test(key));
+ // Check if value looks like an ID
+ const valueLooksLikeId = (typeof value === 'string' ||
+ typeof value === 'number') && String(value).length > 0;
+ return fieldLooksLikeRef && valueLooksLikeId;
+ }
+ /**
+ * Store processed data in brain
+ */
+ async storeInBrain(neuralResults) {
+ const result = {
+ entities: [],
+ relationships: [],
+ stats: {
+ totalProcessed: neuralResults.entities.size + neuralResults.relationships.size,
+ entitiesCreated: 0,
+ relationshipsCreated: 0,
+ averageConfidence: 0,
+ processingTimeMs: 0
+ }
+ };
+ let totalConfidence = 0;
+ // Store entities
+ for (const entity of neuralResults.entities.values()) {
+ const id = await this.brain.add({
+ data: entity.data,
+ type: entity.type,
+ metadata: entity.metadata,
+ vector: entity.vector,
+ writeOnly: true // Fast mode since we already have vectors
+ });
+ // Update entity ID for relationship mapping
+ entity.id = id;
+ result.entities.push({
+ ...entity,
+ id
+ });
+ result.stats.entitiesCreated++;
+ totalConfidence += entity.confidence;
+ }
+ // Store relationships
+ for (const relation of neuralResults.relationships.values()) {
+ // Map to actual entity IDs
+ const sourceEntity = Array.from(neuralResults.entities.values())
+ .find(e => e.id === relation.from);
+ const targetEntity = Array.from(neuralResults.entities.values())
+ .find(e => e.id === relation.to);
+ if (sourceEntity && targetEntity) {
+ const id = await this.brain.relate({
+ from: sourceEntity.id,
+ to: targetEntity.id,
+ type: relation.type,
+ weight: relation.weight,
+ metadata: relation.metadata,
+ writeOnly: true
+ });
+ result.relationships.push({
+ ...relation,
+ id,
+ from: sourceEntity.id,
+ to: targetEntity.id
+ });
+ result.stats.relationshipsCreated++;
+ totalConfidence += relation.confidence;
+ }
+ }
+ // Calculate average confidence
+ const totalItems = result.stats.entitiesCreated + result.stats.relationshipsCreated;
+ result.stats.averageConfidence = totalItems > 0 ? totalConfidence / totalItems : 0;
+ return result;
+ }
+ // Helper methods for parsing different formats
+ detectFormat(data) {
+ const trimmed = data.trim();
+ // JSON
+ if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
+ (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
+ return 'json';
+ }
+ // CSV (has commas and newlines)
+ if (trimmed.includes(',') && trimmed.includes('\n')) {
+ return 'csv';
+ }
+ // YAML (has colons and indentation)
+ if (trimmed.includes(':') && (trimmed.includes('\n ') || trimmed.includes('\n\t'))) {
+ return 'yaml';
+ }
+ // Markdown (has headers)
+ if (trimmed.includes('#') || trimmed.includes('```')) {
+ return 'markdown';
+ }
+ // HTML/XML
+ if (trimmed.includes('<') && trimmed.includes('>')) {
+ return trimmed.toLowerCase().includes(' l.trim());
+ if (lines.length === 0)
+ return [];
+ const headers = lines[0].split(',').map(h => h.trim());
+ const results = [];
+ for (let i = 1; i < lines.length; i++) {
+ const values = lines[i].split(',').map(v => v.trim());
+ const obj = {};
+ headers.forEach((header, index) => {
+ obj[header] = values[index] || '';
+ });
+ results.push(obj);
+ }
+ return results;
+ }
+ parseYAML(data) {
+ // Simple YAML parser
+ const results = [];
+ const lines = data.split('\n');
+ let current = null;
+ for (const line of lines) {
+ const trimmed = line.trim();
+ if (!trimmed || trimmed.startsWith('#'))
+ continue;
+ if (trimmed.startsWith('- ')) {
+ // Array item
+ const value = trimmed.substring(2);
+ if (!current) {
+ results.push(value);
+ }
+ else {
+ if (!current._items)
+ current._items = [];
+ current._items.push(value);
+ }
+ }
+ else if (trimmed.includes(':')) {
+ // Key-value
+ const [key, ...valueParts] = trimmed.split(':');
+ const value = valueParts.join(':').trim();
+ if (!current) {
+ current = {};
+ results.push(current);
+ }
+ current[key.trim()] = value;
+ }
+ }
+ return results.length > 0 ? results : [{ text: data }];
+ }
+ parseMarkdown(data) {
+ const results = [];
+ const lines = data.split('\n');
+ let current = null;
+ let inCodeBlock = false;
+ for (const line of lines) {
+ if (line.startsWith('```')) {
+ inCodeBlock = !inCodeBlock;
+ if (inCodeBlock && current) {
+ current.code = '';
+ }
+ continue;
+ }
+ if (inCodeBlock && current) {
+ current.code += line + '\n';
+ }
+ else if (line.startsWith('#')) {
+ // Header
+ const level = line.match(/^#+/)?.[0].length || 1;
+ const text = line.replace(/^#+\s*/, '');
+ current = {
+ type: 'heading',
+ level,
+ text
+ };
+ results.push(current);
+ }
+ else if (line.trim()) {
+ // Paragraph
+ if (!current || current.type !== 'paragraph') {
+ current = {
+ type: 'paragraph',
+ text: ''
+ };
+ results.push(current);
+ }
+ current.text += line + ' ';
+ }
+ }
+ return results;
+ }
+ parseHTML(data) {
+ // Simple HTML text extraction
+ const text = data
+ .replace(/