feat: modernize API architecture and deprecation handling

- Modernize BrainyInterface to only contain current API methods (add, relate, find, get)
- Update all interface consumers to use modern API patterns
- Make Brainy class implement clean modernized interface
- Update CLI commands to use add() and relate() instead of deprecated methods
- Update all source code components to use modern API consistently
- Update examples and integration tests to modern patterns
- Improve architectural consistency across the entire codebase

BREAKING: BrainyInterface no longer contains deprecated methods
Migration: Use add() instead of addNoun(), relate() instead of addVerb()
This commit is contained in:
David Snelling 2025-09-17 11:54:20 -07:00
parent e311a149df
commit 5be5ea5201
11 changed files with 89 additions and 84 deletions

View file

@ -546,7 +546,7 @@ program
metadata.encrypted = true
}
const id = await brainyInstance.addNoun(processedData, metadata)
const id = await brainyInstance.add({ data: processedData, type: 'content', metadata })
console.log(colors.success(`✅ Added successfully! ID: ${id}`))
}))
@ -1337,9 +1337,8 @@ program
}
try {
// In 2.0 API, addNoun takes (data, metadata) - type goes in metadata
metadata.type = options.type
const id = await brainy.addNoun(name, metadata)
// Use modern 3.0 API with parameter object
const id = await brainy.add({ data: name, type: options.type, metadata })
console.log(colors.success('✅ Noun added successfully!'))
console.log(colors.info(`🆔 ID: ${id}`))
@ -1506,7 +1505,7 @@ program
// Use the provided type or fall back to RelatedTo
const verbType = VerbType[options.type] || options.type
const id = await brainy.addVerb(source, target, verbType, metadata)
const id = await brainy.relate({ from: source, to: target, type: verbType, metadata })
console.log(colors.success('✅ Relationship added successfully!'))
console.log(colors.info(`🆔 ID: ${id}`))

View file

@ -16,9 +16,9 @@ async function main() {
await brain.init()
// 2. Add some sample data
await brain.addNoun("The quick brown fox", 'Content', { type: "sentence", category: "animals" })
await brain.addNoun("Machine learning models", 'Content', { type: "tech", category: "AI" })
await brain.addNoun("Natural language processing", 'Content', { type: "tech", category: "NLP" })
await brain.add({ data: "The quick brown fox", type: 'content', metadata: { type: "sentence", category: "animals" } })
await brain.add({ data: "Machine learning models", type: 'content', metadata: { type: "tech", category: "AI" } })
await brain.add({ data: "Natural language processing", type: 'content', metadata: { type: "tech", category: "NLP" } })
// 3. Create and register the API Server augmentation
const apiServer = new APIServerAugmentation({

View file

@ -23,7 +23,7 @@ async function main() {
await brain.init()
// Use Brainy normally - augmentations work transparently
await brain.addNoun("Hello world", 'Content', { type: "greeting" })
await brain.add({ data: "Hello world", type: 'content', metadata: { type: "greeting" } })
// Batch operations automatically optimized
await brain.addBatch([

View file

@ -194,7 +194,7 @@ export class APIServerAugmentation extends BaseAugmentation {
app.post('/api/add', async (req: any, res: any) => {
try {
const { content, metadata } = req.body
const id = await this.context!.brain.addNoun(content, 'Content', metadata)
const id = await this.context!.brain.add({ data: content, type: 'content', metadata })
res.json({ success: true, id })
} catch (error: any) {
res.status(500).json({ success: false, error: error.message })
@ -368,7 +368,7 @@ export class APIServerAugmentation extends BaseAugmentation {
break
case 'add':
const id = await this.context!.brain.addNoun(msg.content, 'Content', msg.metadata)
const id = await this.context!.brain.add({ data: msg.content, type: 'content', metadata: msg.metadata })
socket.send(JSON.stringify({
type: 'addResult',
requestId: msg.requestId,

View file

@ -204,18 +204,18 @@ export class WebSocketConduitAugmentation extends BaseConduitAugmentation {
try {
switch (operation) {
case 'addNoun':
await this.context?.brain.addNoun(params.content, params.metadata)
await this.context?.brain.add({ data: params.content, type: 'content', metadata: params.metadata })
break
case 'deleteNoun':
await this.context?.brain.deleteNoun(params.id)
break
case 'addVerb':
await this.context?.brain.addVerb(
params.source,
params.target,
params.verb,
params.metadata
)
await this.context?.brain.relate({
from: params.source,
to: params.target,
type: params.verb,
metadata: params.metadata
})
break
}
} catch (error) {
@ -269,6 +269,6 @@ export class WebSocketConduitAugmentation extends BaseConduitAugmentation {
* await conduit.establishConnection('ws://localhost:3000/ws')
*
* // Now operations sync automatically!
* await clientBrain.addNoun('synced data', { source: 'client' })
* await clientBrain.add({ data: 'synced data', type: 'content', metadata: { source: 'client' } })
* // This will automatically sync to the server
*/

View file

@ -41,12 +41,15 @@ import {
BrainyConfig
} from './types/brainy.types.js'
import { NounType, VerbType } from './types/graphTypes.js'
import { BrainyInterface } from './types/brainyDataInterface.js'
/**
* The main Brainy class - Clean, Beautiful, Powerful
* REAL IMPLEMENTATION - No stubs, no mocks
*
* Implements BrainyInterface to ensure consistency across integrations
*/
export class Brainy<T = any> {
export class Brainy<T = any> implements BrainyInterface<T> {
// Core components
private index!: HNSWIndex | HNSWIndexOptimized
private storage!: StorageAdapter
@ -1707,7 +1710,7 @@ export class Brainy<T = any> {
/**
* Embed data into vector
*/
private async embed(data: any): Promise<Vector> {
async embed(data: any): Promise<Vector> {
return this.embedder(data)
}

View file

@ -194,8 +194,8 @@ export class ImportManager {
_confidence: item.confidence
}
// Add to brain using proper API signature: addNoun(vectorOrData, nounType, metadata)
const id = await this.brain.addNoun(dataToImport, nounType || 'content', metadata)
// Add to brain using modern API signature
const id = await this.brain.add({ data: dataToImport, type: nounType || 'content', metadata })
result.nouns.push(id)
result.stats.imported++
return id
@ -229,13 +229,13 @@ export class ImportManager {
verbType = match.type
}
const verbId = await this.brain.addVerb(
rel.sourceId,
rel.targetId,
verbType as VerbType,
rel.metadata,
rel.weight
)
const verbId = await this.brain.relate({
from: rel.sourceId,
to: rel.targetId,
type: verbType as VerbType,
metadata: rel.metadata,
weight: rel.weight
})
result.verbs.push(verbId)
result.stats.relationships++

View file

@ -8,9 +8,10 @@
import { v4 as uuidv4 } from '../universal/uuid.js'
import { BrainyInterface } from '../types/brainyDataInterface.js'
import {
MCPRequest,
MCPResponse,
import { NounType } from '../types/graphTypes.js'
import {
MCPRequest,
MCPResponse,
MCPDataAccessRequest,
MCPRequestType,
MCP_VERSION
@ -75,7 +76,7 @@ export class BrainyMCPAdapter {
)
}
const noun = await this.brainyData.getNoun(id)
const noun = await this.brainyData.get(id)
if (!noun) {
return this.createErrorResponse(
@ -104,7 +105,7 @@ export class BrainyMCPAdapter {
)
}
const results = await this.brainyData.searchText(query, k)
const results = await this.brainyData.find({ query, limit: k })
return this.createSuccessResponse(request.requestId, results)
}
@ -124,8 +125,8 @@ export class BrainyMCPAdapter {
)
}
// Add data directly using addNoun
const id = await this.brainyData.addNoun(text, 'document', metadata)
// Add data using modern API (interface only supports modern methods)
const id = await this.brainyData.add({ data: text, type: NounType.Document, metadata })
return this.createSuccessResponse(request.requestId, { id })
}

View file

@ -3285,7 +3285,7 @@ export class ImprovedNeuralAPI {
if (clusters.length === 0) break
try {
const noun = await this.brain.getNoun(itemId)
const noun = await this.brain.get(itemId)
const itemVector = noun?.vector || []
if (itemVector.length === 0) continue

View file

@ -1,11 +1,14 @@
/**
* BrainyInterface
*
* This interface defines the methods from Brainy that are used by serverSearchAugmentations.ts.
* It's used to break the circular dependency between brainyData.ts and serverSearchAugmentations.ts.
* BrainyInterface - Modern API Only
*
* This interface defines the MODERN methods from Brainy 3.0.
* Used to break circular dependencies while enforcing modern API usage.
*
* NO DEPRECATED METHODS - Only clean, modern API patterns.
*/
import { Vector } from '../coreTypes.js'
import { AddParams, RelateParams, Result, Entity, FindParams, SimilarParams } from './brainy.types.js'
export interface BrainyInterface<T = unknown> {
/**
@ -14,47 +17,39 @@ export interface BrainyInterface<T = unknown> {
init(): Promise<void>
/**
* Get a noun by ID
* @param id The ID of the noun to get
* Modern add method - unified entity creation
* @param params Parameters for adding entities
* @returns The ID of the created entity
*/
getNoun(id: string): Promise<unknown>
add(params: AddParams<T>): Promise<string>
/**
* @deprecated Use add() instead - it's smart by default now
* Add a noun (entity with vector and metadata) to the database
* @param data Text string or vector representation (will auto-embed strings)
* @param nounType Required noun type (one of 31 types)
* @param metadata Optional metadata to associate with the noun
* @returns The ID of the added noun
* Modern relate method - unified relationship creation
* @param params Parameters for creating relationships
* @returns The ID of the created relationship
*/
addNoun(data: string | Vector, nounType: string, metadata?: T): Promise<string>
relate(params: RelateParams<T>): Promise<string>
/**
* Search for text in the database
* @param text The text to search for
* @param limit Maximum number of results to return
* @returns Search results
* Modern find method - unified search and discovery
* @param query Search query or parameters object
* @returns Array of search results
*/
searchText(text: string, limit?: number): Promise<unknown[]>
find(query: string | FindParams<T>): Promise<Result<T>[]>
/**
* @deprecated Use relate() instead
* Create a relationship (verb) between two entities
* @param sourceId The ID of the source entity
* @param targetId The ID of the target entity
* @param verbType The type of relationship
* @param metadata Optional metadata about the relationship
* @returns The ID of the created verb
* Modern get method - retrieve entities by ID
* @param id The entity ID to retrieve
* @returns Entity or null if not found
*/
addVerb(sourceId: string, targetId: string, verbType: string, metadata?: unknown): Promise<string>
get(id: string): Promise<Entity<T> | null>
/**
* Find entities similar to a given entity ID
* @param id ID of the entity to find similar entities for
* @param options Additional options
* @returns Array of search results with similarity scores
* Modern similar method - find similar entities
* @param params Parameters for similarity search
* @returns Array of similar entities with scores
*/
findSimilar(id: string, options?: { limit?: number }): Promise<unknown[]>
similar(params: SimilarParams<T>): Promise<Result<T>[]>
/**
* Generate embedding vector from text
@ -62,4 +57,4 @@ export interface BrainyInterface<T = unknown> {
* @returns Vector representation of the text
*/
embed(text: string): Promise<Vector>
}
}

View file

@ -318,15 +318,18 @@ describe('Brainy 2.0 Complete Feature Test (Real AI)', () => {
it('should handle nested metadata queries', async () => {
// Add items with nested metadata
await brain.addNoun('Advanced framework test', {
framework: {
name: 'Next.js',
version: '13.0',
features: ['SSR', 'API', 'Routing']
},
tech: {
language: 'JavaScript',
runtime: 'Node.js'
await brain.add({
data: 'Advanced framework test',
type: 'content',
metadata: {
framework: {
name: 'Next.js',
version: '13.0',
features: ['SSR', 'API', 'Routing']
},
tech: {
language: 'JavaScript',
runtime: 'Node.js'
}
})
@ -426,10 +429,14 @@ describe('Brainy 2.0 Complete Feature Test (Real AI)', () => {
const ids = []
for (const item of performanceData) {
const id = await brain.addNoun(item.content, {
category: item.category,
priority: item.priority,
timestamp: item.timestamp
const id = await brain.add({
data: item.content,
type: 'content',
metadata: {
category: item.category,
priority: item.priority,
timestamp: item.timestamp
}
})
ids.push(id)
}