feat: Complete the 9 Unified Methods with augment() and export()! 🎯
BREAKING CHANGE: Brainy 1.0 now has 9 unified methods (odd numbers FTW!) THE 9 UNIFIED METHODS: 1. add() - Smart data addition 2. search() - Unified search 3. import() - Bulk import 4. addNoun() - Typed entities 5. addVerb() - Relationships 6. update() - Smart updates 7. delete() - Soft delete 8. augment() - Complete augmentation management ⭐ 9. export() - Universal data export ⭐ Key improvements: - Renamed register() to augment() for consistency - Made augment() super flexible - handles ALL operations: - augment(new MyAugmentation()) - Register - augment('list') - List all with status - augment('enable', 'name') - Enable - augment('disable', 'name') - Disable - augment('unregister', 'name') - Remove - augment('enable-type', 'sense') - Bulk enable - Added export() as 9th method for data portability: - Export as JSON, CSV, Graph, or Embeddings - Filter, limit, include/exclude options - Perfect for backups, migrations, integrations Documentation: - Created AUGMENTATION-GUIDE.md - Super simple guide - Updated UNIFIED-API.md for all 9 methods - Fixed misleading community package references - Updated README with 9 methods everywhere CLI commands now perfectly mirror the API: - brainy augment <action> - Matches augment() method - brainy export - Matches export() method From 40+ methods → 9 unified methods (78% reduction!) 'Make the simple things simple, and the complex things possible'
This commit is contained in:
parent
c93df7ee8e
commit
98bf98a228
5 changed files with 795 additions and 57 deletions
|
|
@ -7269,15 +7269,237 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
|
|||
// ===== Augmentation Control Methods =====
|
||||
|
||||
/**
|
||||
* UNIFIED API METHOD #8: Register an augmentation
|
||||
* Add custom augmentations to extend Brainy's capabilities
|
||||
* UNIFIED API METHOD #8: Augment - Complete augmentation management
|
||||
* Register, enable, disable, list, and manage augmentations
|
||||
*
|
||||
* @param augmentation The augmentation to register
|
||||
* @returns The BrainyData instance for chaining
|
||||
* @param action The action to perform or augmentation to register
|
||||
* @param options Additional options for the action
|
||||
* @returns Various return types based on action
|
||||
*/
|
||||
register(augmentation: IAugmentation): this {
|
||||
augmentationPipeline.register(augmentation)
|
||||
return this
|
||||
augment(
|
||||
action: IAugmentation | 'list' | 'enable' | 'disable' | 'unregister' | 'enable-type' | 'disable-type',
|
||||
options?: string | { name?: string; type?: string }
|
||||
): this | any {
|
||||
// If it's an augmentation object, register it
|
||||
if (typeof action === 'object' && 'name' in action && 'type' in action) {
|
||||
augmentationPipeline.register(action as IAugmentation)
|
||||
return this
|
||||
}
|
||||
|
||||
// Handle string actions
|
||||
switch (action) {
|
||||
case 'list':
|
||||
// Return list of all augmentations with status
|
||||
return this.listAugmentations()
|
||||
|
||||
case 'enable':
|
||||
// Enable specific augmentation by name
|
||||
if (typeof options === 'string') {
|
||||
this.enableAugmentation(options)
|
||||
} else if (options?.name) {
|
||||
this.enableAugmentation(options.name)
|
||||
}
|
||||
return this
|
||||
|
||||
case 'disable':
|
||||
// Disable specific augmentation by name
|
||||
if (typeof options === 'string') {
|
||||
this.disableAugmentation(options)
|
||||
} else if (options?.name) {
|
||||
this.disableAugmentation(options.name)
|
||||
}
|
||||
return this
|
||||
|
||||
case 'unregister':
|
||||
// Remove augmentation from pipeline
|
||||
if (typeof options === 'string') {
|
||||
this.unregister(options)
|
||||
} else if (options?.name) {
|
||||
this.unregister(options.name)
|
||||
}
|
||||
return this
|
||||
|
||||
case 'enable-type':
|
||||
// Enable all augmentations of a type
|
||||
if (typeof options === 'string') {
|
||||
const validTypes = ['sense', 'conduit', 'cognition', 'memory', 'perception', 'dialog', 'activation', 'webSocket'] as const
|
||||
if (validTypes.includes(options as any)) {
|
||||
return this.enableAugmentationType(options as any)
|
||||
}
|
||||
} else if (options?.type) {
|
||||
const validTypes = ['sense', 'conduit', 'cognition', 'memory', 'perception', 'dialog', 'activation', 'webSocket'] as const
|
||||
if (validTypes.includes(options.type as any)) {
|
||||
return this.enableAugmentationType(options.type as any)
|
||||
}
|
||||
}
|
||||
throw new Error('Invalid augmentation type')
|
||||
|
||||
case 'disable-type':
|
||||
// Disable all augmentations of a type
|
||||
if (typeof options === 'string') {
|
||||
const validTypes = ['sense', 'conduit', 'cognition', 'memory', 'perception', 'dialog', 'activation', 'webSocket'] as const
|
||||
if (validTypes.includes(options as any)) {
|
||||
return this.disableAugmentationType(options as any)
|
||||
}
|
||||
} else if (options?.type) {
|
||||
const validTypes = ['sense', 'conduit', 'cognition', 'memory', 'perception', 'dialog', 'activation', 'webSocket'] as const
|
||||
if (validTypes.includes(options.type as any)) {
|
||||
return this.disableAugmentationType(options.type as any)
|
||||
}
|
||||
}
|
||||
throw new Error('Invalid augmentation type')
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown augment action: ${action}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UNIFIED API METHOD #9: Export - Extract your data in various formats
|
||||
* Export your brain's knowledge for backup, migration, or integration
|
||||
*
|
||||
* @param options Export configuration
|
||||
* @returns The exported data in the specified format
|
||||
*/
|
||||
async export(options: {
|
||||
format?: 'json' | 'csv' | 'graph' | 'embeddings'
|
||||
includeVectors?: boolean
|
||||
includeMetadata?: boolean
|
||||
includeRelationships?: boolean
|
||||
filter?: any
|
||||
limit?: number
|
||||
} = {}): Promise<any> {
|
||||
const {
|
||||
format = 'json',
|
||||
includeVectors = false,
|
||||
includeMetadata = true,
|
||||
includeRelationships = true,
|
||||
filter = {},
|
||||
limit
|
||||
} = options
|
||||
|
||||
// Get all data with optional filtering
|
||||
const nounsResult = await this.getNouns()
|
||||
const allNouns = nounsResult.items || []
|
||||
let exportData: any[] = []
|
||||
|
||||
// Apply filters and limits
|
||||
let nouns = allNouns
|
||||
if (Object.keys(filter).length > 0) {
|
||||
nouns = allNouns.filter((noun: any) => {
|
||||
return Object.entries(filter).every(([key, value]) => {
|
||||
return noun.metadata?.[key] === value
|
||||
})
|
||||
})
|
||||
}
|
||||
if (limit) {
|
||||
nouns = nouns.slice(0, limit)
|
||||
}
|
||||
|
||||
// Build export data
|
||||
for (const noun of nouns) {
|
||||
const exportItem: any = {
|
||||
id: noun.id,
|
||||
text: (noun as any).text || (noun.metadata as any)?.text || noun.id
|
||||
}
|
||||
|
||||
if (includeVectors && noun.vector) {
|
||||
exportItem.vector = noun.vector
|
||||
}
|
||||
|
||||
if (includeMetadata && noun.metadata) {
|
||||
exportItem.metadata = noun.metadata
|
||||
}
|
||||
|
||||
if (includeRelationships) {
|
||||
const relationships = await this.getNounWithVerbs(noun.id)
|
||||
const allVerbs = [
|
||||
...(relationships?.incomingVerbs || []),
|
||||
...(relationships?.outgoingVerbs || [])
|
||||
]
|
||||
if (allVerbs.length > 0) {
|
||||
exportItem.relationships = allVerbs
|
||||
}
|
||||
}
|
||||
|
||||
exportData.push(exportItem)
|
||||
}
|
||||
|
||||
// Format output based on requested format
|
||||
switch (format) {
|
||||
case 'csv':
|
||||
return this.convertToCSV(exportData)
|
||||
case 'graph':
|
||||
return this.convertToGraphFormat(exportData)
|
||||
case 'embeddings':
|
||||
return exportData.map(item => ({
|
||||
id: item.id,
|
||||
vector: item.vector || []
|
||||
}))
|
||||
case 'json':
|
||||
default:
|
||||
return exportData
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Convert data to CSV format
|
||||
* @private
|
||||
*/
|
||||
private convertToCSV(data: any[]): string {
|
||||
if (data.length === 0) return ''
|
||||
|
||||
// Get all unique keys
|
||||
const keys = new Set<string>()
|
||||
data.forEach(item => {
|
||||
Object.keys(item).forEach(key => keys.add(key))
|
||||
})
|
||||
|
||||
// Create header
|
||||
const headers = Array.from(keys)
|
||||
const csv = [headers.join(',')]
|
||||
|
||||
// Add data rows
|
||||
data.forEach(item => {
|
||||
const row = headers.map(header => {
|
||||
const value = item[header]
|
||||
if (typeof value === 'object') {
|
||||
return JSON.stringify(value)
|
||||
}
|
||||
return value || ''
|
||||
})
|
||||
csv.push(row.join(','))
|
||||
})
|
||||
|
||||
return csv.join('\n')
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Convert data to graph format
|
||||
* @private
|
||||
*/
|
||||
private convertToGraphFormat(data: any[]): any {
|
||||
const nodes = data.map(item => ({
|
||||
id: item.id,
|
||||
label: item.text || item.id,
|
||||
metadata: item.metadata
|
||||
}))
|
||||
|
||||
const edges: any[] = []
|
||||
data.forEach(item => {
|
||||
if (item.relationships) {
|
||||
item.relationships.forEach((rel: any) => {
|
||||
edges.push({
|
||||
source: item.id,
|
||||
target: rel.targetId,
|
||||
type: rel.verbType,
|
||||
metadata: rel.metadata
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return { nodes, edges }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue