2025-06-05 11:18:20 -07:00
# ! / u s r / b i n / e n v n o d e
/ * *
* Brainy CLI
* A command - line interface for interacting with the Brainy vector database
* /
2025-06-05 11:44:18 -07:00
import { BrainyData , NounType , VerbType , FileSystemStorage } from './index.js'
import { fileURLToPath } from 'url'
import { dirname , join } from 'path'
import fs from 'fs'
import { Command } from 'commander'
import omelette from 'omelette'
2025-06-05 14:04:29 -07:00
import { VERSION } from './utils/version.js'
import { sequentialPipeline } from './sequentialPipeline.js'
import { augmentationPipeline , ExecutionMode } from './augmentationPipeline.js'
import { AugmentationType } from './types/augmentations.js'
2025-06-10 11:15:22 -07:00
import { createLLMAugmentations } from './augmentations/llmAugmentations.js'
2025-06-05 11:18:20 -07:00
// Get the directory of the current module
2025-06-05 11:44:18 -07:00
const __filename = fileURLToPath ( import . meta . url )
const __dirname = dirname ( __filename )
2025-06-05 11:18:20 -07:00
// Helper function to parse JSON safely
function parseJSON ( str : string ) : any {
try {
2025-06-05 11:44:18 -07:00
return JSON . parse ( str )
2025-06-05 11:18:20 -07:00
} catch ( e ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error parsing JSON:' , ( e as Error ) . message )
return { }
2025-06-05 11:18:20 -07:00
}
}
// Helper function to resolve noun type
function resolveNounType ( type : string | number | undefined ) : NounType {
2025-06-05 11:44:18 -07:00
if ( ! type ) return NounType . Thing
2025-06-05 11:18:20 -07:00
// If it's a string, try to match it to a NounType
if ( typeof type === 'string' ) {
const nounTypeKey = Object . keys ( NounType ) . find (
key = > key . toLowerCase ( ) === type . toLowerCase ( )
2025-06-05 11:44:18 -07:00
)
return nounTypeKey ? NounType [ nounTypeKey as keyof typeof NounType ] : NounType . Thing
2025-06-05 11:18:20 -07:00
}
// Convert number to string type for safety
2025-06-05 11:44:18 -07:00
return Object . values ( NounType ) [ type as number ] || NounType . Thing
2025-06-05 11:18:20 -07:00
}
// Helper function to resolve verb type
function resolveVerbType ( type : string | number | undefined ) : VerbType {
2025-06-05 11:44:18 -07:00
if ( ! type ) return VerbType . RelatedTo
2025-06-05 11:18:20 -07:00
// If it's a string, try to match it to a VerbType
if ( typeof type === 'string' ) {
const verbTypeKey = Object . keys ( VerbType ) . find (
key = > key . toLowerCase ( ) === type . toLowerCase ( )
2025-06-05 11:44:18 -07:00
)
return verbTypeKey ? VerbType [ verbTypeKey as keyof typeof VerbType ] : VerbType . RelatedTo
2025-06-05 11:18:20 -07:00
}
// Convert number to string type for safety
2025-06-05 11:44:18 -07:00
return Object . values ( VerbType ) [ type as number ] || VerbType . RelatedTo
2025-06-05 11:18:20 -07:00
}
// Create a new Command instance
2025-06-05 11:44:18 -07:00
const program = new Command ( )
2025-06-05 11:18:20 -07:00
// Configure the program
program
2025-06-05 14:04:29 -07:00
. name ( '@soulcraft/brainy' )
. description ( 'A vector database using HNSW indexing with Origin Private File System storage' )
. version ( VERSION , '-V, --version' , 'Output the current version' )
2025-06-05 11:18:20 -07:00
// Create data directory if it doesn't exist
2025-06-05 11:44:18 -07:00
const dataDir = join ( __dirname , '..' , 'data' )
2025-06-05 11:18:20 -07:00
if ( ! fs . existsSync ( dataDir ) ) {
2025-06-05 11:44:18 -07:00
fs . mkdirSync ( dataDir , { recursive : true } )
2025-06-05 11:18:20 -07:00
}
// Create a database instance with file system storage
const createDb = ( ) = > {
return new BrainyData ( {
storageAdapter : new FileSystemStorage ( dataDir )
2025-06-05 11:44:18 -07:00
} )
}
2025-06-05 11:18:20 -07:00
// Define commands
program
. command ( 'init' )
. description ( 'Initialize a new database' )
. action ( async ( ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
console . log ( 'Database initialized successfully' )
2025-06-05 11:18:20 -07:00
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'add' )
. description ( 'Add a new noun with the given text and optional metadata' )
. argument ( '<text>' , 'Text to add as a noun' )
. argument ( '[metadata]' , 'Optional metadata as JSON string' )
. action ( async ( text , metadataStr ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const metadata = metadataStr ? parseJSON ( metadataStr ) : { }
2025-06-05 11:18:20 -07:00
// Process metadata to handle noun type
if ( metadata . noun ) {
2025-06-05 11:44:18 -07:00
metadata . noun = resolveNounType ( metadata . noun )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
const id = await db . add ( text , metadata )
console . log ( ` Added noun with ID: ${ id } ` )
2025-06-05 11:18:20 -07:00
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'search' )
. description ( 'Search for nouns similar to the query' )
. argument ( '<query>' , 'Search query text' )
. option ( '-l, --limit <number>' , 'Maximum number of results to return' , '5' )
. action ( async ( query , options ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const limit = parseInt ( options . limit , 10 )
const results = await db . searchText ( query , limit )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
console . log ( ` Search results for " ${ query } ": ` )
2025-06-05 11:18:20 -07:00
results . forEach ( ( result , index ) = > {
2025-06-05 11:44:18 -07:00
console . log ( ` ${ index + 1 } . ID: ${ result . id } ` )
console . log ( ` Score: ${ result . score . toFixed ( 4 ) } ` )
console . log ( ` Metadata: ${ JSON . stringify ( result . metadata ) } ` )
console . log ( ` Vector: [ ${ result . vector . slice ( 0 , 3 ) . map ( v = > v . toFixed ( 2 ) ) . join ( ', ' ) } ...] ` )
console . log ( )
} )
2025-06-05 11:18:20 -07:00
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'get' )
. description ( 'Get a noun by ID' )
. argument ( '<id>' , 'ID of the noun to get' )
. action ( async ( id ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const noun = await db . get ( id )
2025-06-05 11:18:20 -07:00
if ( noun ) {
2025-06-05 11:44:18 -07:00
console . log ( ` Noun ID: ${ noun . id } ` )
console . log ( ` Metadata: ${ JSON . stringify ( noun . metadata ) } ` )
console . log ( ` Vector: [ ${ noun . vector . slice ( 0 , 5 ) . map ( v = > v . toFixed ( 2 ) ) . join ( ', ' ) } ...] ` )
2025-06-05 11:18:20 -07:00
} else {
2025-06-05 11:44:18 -07:00
console . log ( ` No noun found with ID: ${ id } ` )
2025-06-05 11:18:20 -07:00
}
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'delete' )
. description ( 'Delete a noun by ID' )
. argument ( '<id>' , 'ID of the noun to delete' )
. action ( async ( id ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
await db . delete ( id )
console . log ( ` Deleted noun with ID: ${ id } ` )
2025-06-05 11:18:20 -07:00
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'addVerb' )
. description ( 'Add a relationship between nouns' )
. argument ( '<sourceId>' , 'ID of the source noun' )
. argument ( '<targetId>' , 'ID of the target noun' )
. argument ( '<verbType>' , 'Type of relationship' )
. argument ( '[metadata]' , 'Optional metadata as JSON string' )
. action ( async ( sourceId , targetId , verbTypeStr , metadataStr ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const verbType = resolveVerbType ( verbTypeStr )
const verbMetadata = metadataStr ? parseJSON ( metadataStr ) : { }
2025-06-05 11:18:20 -07:00
// Add verb type to metadata
2025-06-05 11:44:18 -07:00
verbMetadata . verb = verbType
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const verbId = await db . addVerb ( sourceId , targetId , undefined , {
type : verbType ,
metadata : verbMetadata
} )
console . log ( ` Added verb with ID: ${ verbId } ` )
2025-06-05 11:18:20 -07:00
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'getVerbs' )
. description ( 'Get all relationships for a noun' )
. argument ( '<id>' , 'ID of the noun to get relationships for' )
. action ( async ( id ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const verbs = await db . getVerbsBySource ( id )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
console . log ( ` Relationships for noun ${ id } : ` )
2025-06-05 11:18:20 -07:00
if ( verbs . length === 0 ) {
2025-06-05 11:44:18 -07:00
console . log ( 'No relationships found' )
2025-06-05 11:18:20 -07:00
} else {
verbs . forEach ( ( verb , index ) = > {
2025-06-05 11:44:18 -07:00
console . log ( ` ${ index + 1 } . ID: ${ verb . id } ` )
console . log ( ` Type: ${ Object . keys ( VerbType ) . find ( key = > VerbType [ key as keyof typeof VerbType ] === verb . metadata . verb ) || verb . metadata . verb } ` )
console . log ( ` Target: ${ verb . targetId } ` )
console . log ( ` Metadata: ${ JSON . stringify ( verb . metadata ) } ` )
console . log ( )
} )
2025-06-05 11:18:20 -07:00
}
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
program
. command ( 'status' )
. description ( 'Show database status' )
. action ( async ( ) = > {
try {
2025-06-05 11:44:18 -07:00
const db = createDb ( )
await db . init ( )
2025-06-05 11:18:20 -07:00
2025-06-05 11:44:18 -07:00
const status = await db . status ( )
console . log ( 'Database Status:' )
console . log ( ` Storage type: ${ status . type } ` )
console . log ( ` Storage used: ${ status . used } bytes ` )
console . log ( ` Storage quota: ${ status . quota !== null ? ` ${ status . quota } bytes ` : 'unlimited' } ` )
2025-06-05 11:18:20 -07:00
// Display additional details if available
if ( status . details ) {
2025-06-05 11:44:18 -07:00
console . log ( 'Additional details:' )
2025-06-05 11:18:20 -07:00
Object . entries ( status . details ) . forEach ( ( [ key , value ] ) = > {
2025-06-05 11:44:18 -07:00
console . log ( ` ${ key } : ${ JSON . stringify ( value ) } ` )
} )
2025-06-05 11:18:20 -07:00
}
} catch ( error ) {
2025-06-05 11:44:18 -07:00
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
2025-06-05 11:18:20 -07:00
}
2025-06-05 11:44:18 -07:00
} )
2025-06-05 11:18:20 -07:00
2025-06-05 14:04:29 -07:00
program
. command ( 'clear' )
. description ( 'Clear all data from the database' )
. option ( '-f, --force' , 'Skip confirmation prompt' , false )
. action ( async ( options ) = > {
try {
// Confirm unless --force is used
if ( ! options . force ) {
console . log ( 'WARNING: This will permanently delete ALL data in the database.' )
console . log ( 'To proceed without confirmation, use the --force option.' )
// Exit without doing anything
console . log ( 'Operation cancelled. No data was deleted.' )
console . log ( 'To clear all data, use: brainy clear --force' )
return
}
const db = createDb ( )
await db . init ( )
await db . clear ( )
console . log ( 'Database cleared successfully. All data has been removed.' )
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
program
. command ( 'visualize' )
. description ( 'Visualize the graph structure in ASCII format' )
. option ( '-r, --root <id>' , 'ID of the root noun to start visualization from' )
. option ( '-d, --depth <number>' , 'Maximum depth of the graph to visualize' , '2' )
. option ( '-t, --type <type>' , 'Filter by noun type' )
. option ( '-l, --limit <number>' , 'Maximum number of nodes to display per level' , '10' )
. action ( async ( options ) = > {
try {
const db = createDb ( )
await db . init ( )
// Parse options
const depth = parseInt ( options . depth , 10 )
const limit = parseInt ( options . limit , 10 )
const rootId = options . root
const nounType = options . type ? resolveNounType ( options . type ) : undefined
// Get all nouns if no root is specified
if ( ! rootId && ! nounType ) {
// Get all nouns (limited by the limit option)
const allNouns = [ ]
let count = 0
// Since there's no direct method to get all nouns, we'll use search with a high limit
const searchResults = await db . search ( "" , 1000 , {
forceEmbed : true
} )
for ( const result of searchResults ) {
if ( count >= limit ) break
allNouns . push ( result )
count ++
}
if ( allNouns . length === 0 ) {
console . log ( 'No nouns found in the database.' )
return
}
console . log ( ` Graph Overview (showing ${ allNouns . length } nouns): \ n ` )
for ( const noun of allNouns ) {
// Get outgoing verbs
const outgoingVerbs = await db . getVerbsBySource ( noun . id )
// Get incoming verbs
const incomingVerbs = await db . getVerbsByTarget ( noun . id )
const nounType = noun . metadata ? . noun || 'Unknown'
const label = noun . metadata ? . label || noun . id . substring ( 0 , 8 )
console . log ( ` [ ${ nounType } ] ${ label } ( ${ noun . id } ) ` )
if ( outgoingVerbs . length > 0 ) {
console . log ( ' Outgoing:' )
for ( const verb of outgoingVerbs . slice ( 0 , limit ) ) {
const targetNoun = await db . get ( verb . targetId )
const targetLabel = targetNoun ? . metadata ? . label || verb . targetId . substring ( 0 , 8 )
console . log ( ` --( ${ verb . metadata ? . verb || 'relates to' } )--→ [ ${ targetNoun ? . metadata ? . noun || 'Unknown' } ] ${ targetLabel } ` )
}
if ( outgoingVerbs . length > limit ) {
console . log ( ` ... and ${ outgoingVerbs . length - limit } more ` )
}
}
if ( incomingVerbs . length > 0 ) {
console . log ( ' Incoming:' )
for ( const verb of incomingVerbs . slice ( 0 , limit ) ) {
const sourceNoun = await db . get ( verb . sourceId )
const sourceLabel = sourceNoun ? . metadata ? . label || verb . sourceId . substring ( 0 , 8 )
console . log ( ` ←--( ${ verb . metadata ? . verb || 'relates to' } )-- [ ${ sourceNoun ? . metadata ? . noun || 'Unknown' } ] ${ sourceLabel } ` )
}
if ( incomingVerbs . length > limit ) {
console . log ( ` ... and ${ incomingVerbs . length - limit } more ` )
}
}
console . log ( '' )
}
return
}
// If noun type is specified but no root, show all nouns of that type
if ( ! rootId && nounType ) {
console . log ( ` Visualizing nouns of type: ${ nounType } \ n ` )
// Search for nouns of the specified type
const searchResults = await db . search ( "" , 1000 , {
nounTypes : [ nounType ] ,
forceEmbed : true
} )
const filteredNouns = searchResults . slice ( 0 , limit )
if ( filteredNouns . length === 0 ) {
console . log ( ` No nouns found with type: ${ nounType } ` )
return
}
for ( const noun of filteredNouns ) {
const label = noun . metadata ? . label || noun . id . substring ( 0 , 8 )
console . log ( ` [ ${ nounType } ] ${ label } ( ${ noun . id } ) ` )
// Get outgoing verbs
const outgoingVerbs = await db . getVerbsBySource ( noun . id )
if ( outgoingVerbs . length > 0 ) {
console . log ( ' Outgoing:' )
for ( const verb of outgoingVerbs . slice ( 0 , limit ) ) {
const targetNoun = await db . get ( verb . targetId )
const targetLabel = targetNoun ? . metadata ? . label || verb . targetId . substring ( 0 , 8 )
console . log ( ` --( ${ verb . metadata ? . verb || 'relates to' } )--→ [ ${ targetNoun ? . metadata ? . noun || 'Unknown' } ] ${ targetLabel } ` )
}
if ( outgoingVerbs . length > limit ) {
console . log ( ` ... and ${ outgoingVerbs . length - limit } more ` )
}
}
console . log ( '' )
}
return
}
// If root is specified, visualize the graph starting from that root
if ( rootId ) {
const rootNoun = await db . get ( rootId )
if ( ! rootNoun ) {
console . error ( ` Root noun with ID ${ rootId } not found ` )
return
}
console . log ( ` Visualizing graph from root: ${ rootNoun . metadata ? . label || rootId } \ n ` )
// Use a breadth-first search to visualize the graph
const visited = new Set < string > ( )
const queue : Array < { id : string ; level : number ; path : string } > = [
{ id : rootId , level : 0 , path : '' }
]
while ( queue . length > 0 ) {
const { id , level , path } = queue . shift ( ) !
if ( visited . has ( id ) || level > depth ) {
continue
}
visited . add ( id )
const noun = await db . get ( id )
if ( ! noun ) {
console . warn ( ` Noun with ID ${ id } not found ` )
continue
}
const nounType = noun . metadata ? . noun || 'Unknown'
const label = noun . metadata ? . label || id . substring ( 0 , 8 )
// Print the current noun with proper indentation
console . log ( ` ${ ' ' . repeat ( level * 2 ) } ${ path } [ ${ nounType } ] ${ label } ( ${ id } ) ` )
// Get outgoing verbs
const outgoingVerbs = await db . getVerbsBySource ( id )
// Add target nouns to the queue for the next level
let verbCount = 0
for ( const verb of outgoingVerbs ) {
if ( verbCount >= limit ) {
console . log ( ` ${ ' ' . repeat ( ( level + 1 ) * 2 ) } ... and ${ outgoingVerbs . length - limit } more ` )
break
}
const verbType = verb . metadata ? . verb || 'relates to'
queue . push ( {
id : verb.targetId ,
level : level + 1 ,
path : ` --( ${ verbType } )--→ `
} )
verbCount ++
}
}
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
program
. command ( 'generate-random-graph' )
. description ( 'Generate a random graph of data with typed nouns and verbs for testing' )
. option ( '-n, --noun-count <number>' , 'Number of nouns to generate' , '10' )
. option ( '-v, --verb-count <number>' , 'Number of verbs to generate' , '20' )
. option ( '-c, --clear' , 'Clear existing data before generating' , false )
. option ( '-t, --noun-types <types>' , 'Comma-separated list of noun types to use' )
. option ( '-r, --verb-types <types>' , 'Comma-separated list of verb types to use' )
. action ( async ( options ) = > {
try {
const db = createDb ( )
await db . init ( )
// Parse options
const nounCount = parseInt ( options . nounCount , 10 )
const verbCount = parseInt ( options . verbCount , 10 )
const clearExisting = options . clear
// Parse noun types if provided
let nounTypes : NounType [ ] | undefined
if ( options . nounTypes ) {
const typeNames = options . nounTypes . split ( ',' ) . map ( ( t : string ) = > t . trim ( ) )
nounTypes = typeNames . map ( ( name : string ) = > {
// Try to match by key name (case insensitive)
const key = Object . keys ( NounType ) . find (
k = > k . toLowerCase ( ) === name . toLowerCase ( )
)
if ( key ) return NounType [ key as keyof typeof NounType ]
// If not found by key, check if it's a valid value
if ( Object . values ( NounType ) . includes ( name as NounType ) ) {
return name as NounType
}
console . warn ( ` Warning: Unknown noun type " ${ name } ", ignoring ` )
return null
} ) . filter ( Boolean ) as NounType [ ]
}
// Parse verb types if provided
let verbTypes : VerbType [ ] | undefined
if ( options . verbTypes ) {
const typeNames = options . verbTypes . split ( ',' ) . map ( ( t : string ) = > t . trim ( ) )
verbTypes = typeNames . map ( ( name : string ) = > {
// Try to match by key name (case insensitive)
const key = Object . keys ( VerbType ) . find (
k = > k . toLowerCase ( ) === name . toLowerCase ( )
)
if ( key ) return VerbType [ key as keyof typeof VerbType ]
// If not found by key, check if it's a valid value
if ( Object . values ( VerbType ) . includes ( name as VerbType ) ) {
return name as VerbType
}
console . warn ( ` Warning: Unknown verb type " ${ name } ", ignoring ` )
return null
} ) . filter ( Boolean ) as VerbType [ ]
}
console . log ( ` Generating random graph with ${ nounCount } nouns and ${ verbCount } verbs... ` )
if ( clearExisting ) {
console . log ( 'Clearing existing data first...' )
}
const result = await db . generateRandomGraph ( {
nounCount ,
verbCount ,
nounTypes ,
verbTypes ,
clearExisting
} )
console . log ( 'Random graph generated successfully!' )
console . log ( ` Created ${ result . nounIds . length } nouns and ${ result . verbIds . length } verbs ` )
// Print some sample IDs
if ( result . nounIds . length > 0 ) {
console . log ( '\nSample noun IDs:' )
result . nounIds . slice ( 0 , 3 ) . forEach ( id = > console . log ( ` - ${ id } ` ) )
if ( result . nounIds . length > 3 ) {
console . log ( ` ... and ${ result . nounIds . length - 3 } more ` )
}
}
if ( result . verbIds . length > 0 ) {
console . log ( '\nSample verb IDs:' )
result . verbIds . slice ( 0 , 3 ) . forEach ( id = > console . log ( ` - ${ id } ` ) )
if ( result . verbIds . length > 3 ) {
console . log ( ` ... and ${ result . verbIds . length - 3 } more ` )
}
}
console . log ( '\nUse the search, get, or visualize commands to explore the generated graph' )
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-05 11:18:20 -07:00
// Add examples to help text
program . addHelpText ( 'after' , `
Examples :
$ brainy init
$ brainy add "Cats are independent pets" '{"noun":"Thing","category":"animal"}'
$ brainy search "feline pets" -- limit 5
$ brainy addVerb id1 id2 RelatedTo '{"description":"Both are pets"}'
2025-06-05 14:04:29 -07:00
$ brainy clear -- force
$ brainy generate - random - graph -- noun - count 20 -- verb - count 30 -- clear
$ brainy generate - random - graph -- noun - types Person , Thing -- verb - types RelatedTo , Owns
$ brainy visualize -- type Thing -- limit 10
$ brainy visualize -- root id1 -- depth 3
2025-06-10 11:15:22 -07:00
# Augmentation commands
$ brainy augment list
$ brainy augment info cognition
$ brainy augment test - pipeline "Test data" -- data - type text -- mode sequential
$ brainy augment stream - test -- count 3 -- interval 500
# LLM commands
$ brainy llm create -- name my - model -- type simple
$ brainy llm train model - id -- epochs 20 -- batch - size 64
$ brainy llm test model - id -- generate - samples
$ brainy llm export model - id -- format json -- include - metadata
$ brainy llm deploy model - id -- target browser
$ brainy llm generate model - id "Once upon a time" -- temperature 0.8
2025-06-05 11:44:18 -07:00
` )
// Setup autocomplete
const completion = omelette ( 'brainy' )
// Helper function to get all noun types
const getNounTypes = ( ) = > Object . keys ( NounType )
// Helper function to get all verb types
const getVerbTypes = ( ) = > Object . keys ( VerbType )
// Define autocomplete handlers
completion . tree ( {
// First level commands - suggest all available commands
_ : ( ) = > [
'add' ,
'addVerb' ,
'search' ,
'get' ,
'delete' ,
'getVerbs' ,
'status' ,
2025-06-05 14:04:29 -07:00
'clear' ,
'visualize' ,
'generate-random-graph' ,
2025-06-05 11:44:18 -07:00
'completion-setup' ,
'init' ,
2025-06-05 14:04:29 -07:00
'help' ,
2025-06-10 11:15:22 -07:00
'augment' ,
'llm'
2025-06-05 11:44:18 -07:00
] ,
// Command-specific completions
add : {
// For the second argument of 'add' command (metadata)
_ : ( ) = > {
// Generate templates for each noun type
2025-06-05 14:04:29 -07:00
return getNounTypes ( ) . map ( type = >
2025-06-05 11:44:18 -07:00
` {"noun":" ${ type } ","category":"example"} `
)
}
} ,
addVerb : {
// First two arguments are IDs, third is verb type
'<sourceId>' : {
'<targetId>' : {
_ : ( ) = > {
// Suggest all available verb types
return getVerbTypes ( )
}
}
}
} ,
// Add autocomplete for other commands
search : { } ,
get : { } ,
delete : { } ,
getVerbs : { } ,
status : { } ,
2025-06-05 14:04:29 -07:00
clear : {
_ : ( ) = > [
'--force'
]
} ,
'generate-random-graph' : {
_ : ( ) = > [
'--noun-count 10' ,
'--verb-count 20' ,
'--clear' ,
` --noun-types ${ getNounTypes ( ) . join ( ',' ) } ` ,
` --verb-types ${ getVerbTypes ( ) . join ( ',' ) } `
]
} ,
2025-06-10 11:15:22 -07:00
augment : {
2025-06-05 14:04:29 -07:00
_ : ( ) = > [
2025-06-10 11:15:22 -07:00
'list' ,
'info' ,
'test-pipeline' ,
'stream-test'
] ,
info : {
_ : ( ) = > [
'sense' ,
'memory' ,
'cognition' ,
'conduit' ,
'activation' ,
'perception' ,
'dialog' ,
'websocket'
]
} ,
'test-pipeline' : {
_ : ( ) = > [
'--data-type text' ,
'--mode sequential' ,
'--mode parallel' ,
'--mode threaded' ,
'--stop-on-error' ,
'--verbose'
]
} ,
'stream-test' : {
_ : ( ) = > [
'--count 5' ,
'--interval 1000' ,
'--data-type text' ,
'--verbose'
]
}
2025-06-05 14:04:29 -07:00
} ,
2025-06-05 11:44:18 -07:00
'completion-setup' : { } ,
init : { } ,
2025-06-10 11:15:22 -07:00
help : { } ,
llm : {
_ : ( ) = > [
'create' ,
'train' ,
'test' ,
'export' ,
'deploy' ,
'generate'
] ,
create : {
_ : ( ) = > [
'--name my-model' ,
'--description "My custom LLM model"' ,
'--type simple' ,
'--type transformer' ,
'--vocab-size 5000' ,
'--embedding-dim 64' ,
'--hidden-dim 128' ,
'--layers 2' ,
'--heads 4' ,
'--dropout 0.1' ,
'--max-seq-length 100'
]
} ,
train : {
_ : ( ) = > [
'--max-samples 1000' ,
'--validation-split 0.2' ,
'--epochs 10' ,
'--batch-size 32' ,
'--patience 3'
]
} ,
test : {
_ : ( ) = > [
'--test-size 100' ,
'--generate-samples' ,
'--sample-count 5'
]
} ,
export : {
_ : ( ) = > [
'--format json' ,
'--format tfjs' ,
'--output ./models' ,
'--include-metadata' ,
'--include-vocab'
]
} ,
deploy : {
_ : ( ) = > [
'--target browser' ,
'--target node' ,
'--target cloud' ,
'--provider aws' ,
'--provider gcp' ,
'--provider azure' ,
'--endpoint https://example.com/api' ,
'--region us-east-1'
]
} ,
generate : {
_ : ( ) = > [
'--temperature 0.7' ,
'--top-k 5' ,
'--max-length 100'
]
}
}
2025-06-05 11:44:18 -07:00
} )
// Initialize autocomplete
completion . init ( )
// If this script is run with --completion-setup flag, set up the autocomplete
if ( process . argv . includes ( '--completion-setup' ) ) {
completion . setupShellInitFile ( )
console . log ( 'Autocomplete setup complete. Please restart your shell.' )
process . exit ( 0 )
}
2025-06-05 14:04:29 -07:00
// Pipeline and Augmentation Commands
2025-06-10 11:15:22 -07:00
const augmentCommand = new Command ( 'augment' )
. description ( 'Augmentation pipeline operations' )
augmentCommand
. command ( 'list' )
2025-06-05 14:04:29 -07:00
. description ( 'List all available augmentation types and registered augmentations' )
. action ( async ( ) = > {
try {
// Initialize the pipeline
await augmentationPipeline . initialize ( )
// Get available augmentation types
const availableTypes = augmentationPipeline . getAvailableAugmentationTypes ( )
console . log ( 'Available Augmentation Types:' )
if ( availableTypes . length === 0 ) {
console . log ( ' No augmentation types available' )
} else {
availableTypes . forEach ( type = > {
const augmentations = augmentationPipeline . getAugmentationsByType ( type )
console . log ( ` \ n ${ type . toUpperCase ( ) } ( ${ augmentations . length } registered): ` )
if ( augmentations . length === 0 ) {
console . log ( ' No augmentations registered for this type' )
} else {
augmentations . forEach ( aug = > {
console . log ( ` - ${ aug . name } : ${ aug . description } ` )
console . log ( ` Status: ${ aug . enabled ? 'Enabled' : 'Disabled' } ` )
} )
}
} )
}
// Show WebSocket augmentations separately
const webSocketAugs = augmentationPipeline . getWebSocketAugmentations ( )
console . log ( '\nWebSocket-Enabled Augmentations:' )
if ( webSocketAugs . length === 0 ) {
console . log ( ' No WebSocket-enabled augmentations available' )
} else {
webSocketAugs . forEach ( aug = > {
console . log ( ` - ${ aug . name } : ${ aug . description } ` )
console . log ( ` Status: ${ aug . enabled ? 'Enabled' : 'Disabled' } ` )
} )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
augmentCommand
2025-06-05 14:04:29 -07:00
. command ( 'test-pipeline' )
. description ( 'Test the sequential pipeline with sample data' )
. argument ( '[text]' , 'Sample text to process through the pipeline' , 'This is a test of the Brainy pipeline' )
. option ( '-t, --data-type <type>' , 'Type of data to process' , 'text' )
. option ( '-m, --mode <mode>' , 'Execution mode (sequential, parallel, threaded)' , 'sequential' )
. option ( '-s, --stop-on-error' , 'Stop execution if an error occurs' , false )
. option ( '-v, --verbose' , 'Show detailed output' , false )
. action ( async ( text , options ) = > {
try {
// Initialize the pipeline
await sequentialPipeline . initialize ( )
console . log ( ` Processing data: " ${ text } " ` )
console . log ( ` Data type: ${ options . dataType } ` )
console . log ( ` Execution mode: ${ options . mode } ` )
console . log ( ` Stop on error: ${ options . stopOnError } ` )
console . log ( )
// Set execution mode
let executionMode = ExecutionMode . SEQUENTIAL
switch ( options . mode . toLowerCase ( ) ) {
case 'parallel' :
executionMode = ExecutionMode . PARALLEL
break
case 'threaded' :
executionMode = ExecutionMode . THREADED
break
default :
executionMode = ExecutionMode . SEQUENTIAL
}
// Process the data
const result = await sequentialPipeline . processData (
text ,
options . dataType ,
{
stopOnError : options.stopOnError ,
timeout : 30000
}
)
console . log ( 'Pipeline Execution Result:' )
console . log ( ` Success: ${ result . success } ` )
if ( result . error ) {
console . log ( ` Error: ${ result . error } ` )
}
console . log ( '\nStage Results:' )
// Display stage results
Object . entries ( result . stageResults ) . forEach ( ( [ stage , stageResult ] ) = > {
console . log ( ` \ n ${ stage . toUpperCase ( ) } : ` )
console . log ( ` Success: ${ stageResult ? . success } ` )
if ( stageResult ? . error ) {
console . log ( ` Error: ${ stageResult . error } ` )
}
if ( stageResult ? . data && options . verbose ) {
console . log ( ' Data:' )
console . log ( JSON . stringify ( stageResult . data , null , 2 )
. split ( '\n' )
. map ( line = > ` ${ line } ` )
. join ( '\n' )
)
}
} )
console . log ( '\nFinal Result Data:' )
console . log ( JSON . stringify ( result . data , null , 2 )
. split ( '\n' )
. map ( line = > ` ${ line } ` )
. join ( '\n' )
)
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
augmentCommand
2025-06-05 14:04:29 -07:00
. command ( 'stream-test' )
. description ( 'Test streaming data through the pipeline (simulated)' )
. option ( '-c, --count <number>' , 'Number of data items to stream' , '5' )
. option ( '-i, --interval <ms>' , 'Interval between data items in milliseconds' , '1000' )
. option ( '-t, --data-type <type>' , 'Type of data to process' , 'text' )
. option ( '-v, --verbose' , 'Show detailed output' , false )
. action ( async ( options ) = > {
try {
// Initialize the pipeline
await sequentialPipeline . initialize ( )
const count = parseInt ( options . count , 10 )
const interval = parseInt ( options . interval , 10 )
console . log ( ` Simulating stream of ${ count } data items at ${ interval } ms intervals ` )
console . log ( ` Data type: ${ options . dataType } ` )
console . log ( )
// Create a handler function similar to what would be used with WebSockets
const handler = ( data : string ) = > {
// Process the data asynchronously without blocking
sequentialPipeline . processData (
data ,
options . dataType ,
{ stopOnError : false }
) . then ( result = > {
console . log ( ` \ nProcessed: " ${ data } " ` )
console . log ( ` Success: ${ result . success } ` )
if ( options . verbose ) {
console . log ( 'Stage Results:' )
Object . entries ( result . stageResults ) . forEach ( ( [ stage , stageResult ] ) = > {
if ( stageResult ? . success ) {
console . log ( ` ${ stage } : Success ` )
} else {
console . log ( ` ${ stage } : Failed - ${ stageResult ? . error || 'Unknown error' } ` )
}
} )
}
if ( result . data ) {
console . log ( 'Result Data:' )
console . log ( JSON . stringify ( result . data , null , 2 )
. split ( '\n' )
. map ( line = > ` ${ line } ` )
. join ( '\n' )
)
}
} ) . catch ( error = > {
console . error ( ` Error processing " ${ data } ": ` , error . message )
} )
}
// Generate sample data items
const sampleTexts = [
"The quick brown fox jumps over the lazy dog" ,
"Artificial intelligence is transforming how we interact with data" ,
"Vector databases enable semantic search capabilities" ,
"Graph relationships connect entities in meaningful ways" ,
"Streaming data requires efficient real-time processing" ,
"WebSockets provide bidirectional communication channels" ,
"Augmentations extend the functionality of the core system" ,
"Sequential pipelines process data in defined stages" ,
"Parallel execution improves throughput for large datasets" ,
"Threaded operations utilize multiple CPU cores efficiently"
]
// Simulate streaming data
console . log ( 'Starting simulated data stream...' )
for ( let i = 0 ; i < count ; i ++ ) {
// Use modulo to cycle through sample texts if count > samples
const text = sampleTexts [ i % sampleTexts . length ]
// Wait for the specified interval
if ( i > 0 ) {
await new Promise ( resolve = > setTimeout ( resolve , interval ) )
}
console . log ( ` \ nStreaming item ${ i + 1 } / ${ count } : " ${ text } " ` )
// Process the data
handler ( text )
}
console . log ( '\nSimulated stream complete. Some processing may still be ongoing.' )
console . log ( 'In a real WebSocket scenario, the connection would remain open for continuous data.' )
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
augmentCommand
. command ( 'info' )
2025-06-05 14:04:29 -07:00
. description ( 'Get detailed information about a specific augmentation type' )
. argument ( '<type>' , 'Augmentation type (sense, memory, cognition, conduit, activation, perception, dialog, websocket)' )
. action ( async ( typeArg ) = > {
try {
// Initialize the pipeline
await augmentationPipeline . initialize ( )
// Resolve the augmentation type
let augType : AugmentationType | undefined
// Convert input to proper enum value
const normalizedType = typeArg . toLowerCase ( )
switch ( normalizedType ) {
case 'sense' :
augType = AugmentationType . SENSE
break
case 'memory' :
augType = AugmentationType . MEMORY
break
case 'cognition' :
augType = AugmentationType . COGNITION
break
case 'conduit' :
augType = AugmentationType . CONDUIT
break
case 'activation' :
augType = AugmentationType . ACTIVATION
break
case 'perception' :
augType = AugmentationType . PERCEPTION
break
case 'dialog' :
augType = AugmentationType . DIALOG
break
case 'websocket' :
augType = AugmentationType . WEBSOCKET
break
default :
console . error ( ` Unknown augmentation type: ${ typeArg } ` )
console . log ( 'Available types: sense, memory, cognition, conduit, activation, perception, dialog, websocket' )
process . exit ( 1 )
}
// Get augmentations of the specified type
const augmentations = augmentationPipeline . getAugmentationsByType ( augType )
console . log ( ` \ n ${ augType . toUpperCase ( ) } Augmentation Details: ` )
if ( augmentations . length === 0 ) {
console . log ( ' No augmentations registered for this type' )
} else {
// Display information about each augmentation
augmentations . forEach ( ( aug , index ) = > {
console . log ( ` \ n ${ index + 1 } . ${ aug . name } ` )
console . log ( ` Description: ${ aug . description } ` )
console . log ( ` Status: ${ aug . enabled ? 'Enabled' : 'Disabled' } ` )
// List available methods
console . log ( ' Available Methods:' )
// Get all methods that aren't from Object.prototype
const methods = Object . getOwnPropertyNames ( Object . getPrototypeOf ( aug ) )
. filter ( method = >
method !== 'constructor' &&
typeof ( aug as any ) [ method ] === 'function' &&
! [ 'initialize' , 'shutDown' , 'getStatus' ] . includes ( method )
)
if ( methods . length === 0 ) {
console . log ( ' No custom methods available' )
} else {
methods . forEach ( method = > {
console . log ( ` - ${ method } ` )
} )
}
} )
}
// Show pipeline order information
console . log ( '\nPipeline Execution Order:' )
console . log ( ' 1. SENSE - Process raw data into structured nouns and verbs' )
console . log ( ' 2. MEMORY - Store and retrieve data' )
console . log ( ' 3. COGNITION - Analyze and reason about data' )
console . log ( ' 4. CONDUIT - Exchange data with external systems' )
console . log ( ' 5. ACTIVATION - Trigger actions based on data' )
console . log ( ' 6. PERCEPTION - Interpret and visualize data' )
console . log ( ' 7. DIALOG - Process natural language interactions' )
console . log ( ' * WEBSOCKET - Enable real-time communication (can be combined with other types)' )
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
// Add the augment command to the program
program . addCommand ( augmentCommand )
2025-06-05 11:44:18 -07:00
// Add a command for setting up autocomplete
program
. command ( 'completion-setup' )
. description ( 'Setup shell autocomplete for the Brainy CLI' )
. action ( ( ) = > {
completion . setupShellInitFile ( )
console . log ( 'Autocomplete setup complete. Please restart your shell.' )
} )
2025-06-05 11:18:20 -07:00
2025-06-10 11:47:05 -07:00
// Helper function to initialize LLM augmentations and database
async function initializeLLM() {
const db = createDb ( ) ;
await db . init ( ) ;
// Initialize LLM augmentations
const { cognition , activation } = await createLLMAugmentations ( ) ;
// Set the database for the cognition augmentation
cognition . setBrainyDb ( db ) ;
return { db , cognition , activation } ;
}
2025-06-05 11:18:20 -07:00
// Parse command line arguments
2025-06-10 11:15:22 -07:00
// LLM Commands
const llmCommand = new Command ( 'llm' )
. description ( 'LLM (Language Learning Model) operations' )
2025-06-10 11:47:05 -07:00
llmCommand
. command ( 'create-simple' )
. description ( 'Create a new LLM model using a preset (tiny, small, medium, large)' )
. argument ( '[preset]' , 'Model preset to use (tiny, small, medium, large)' , 'small' )
. option ( '-n, --name <name>' , 'Custom name for the model' )
. action ( async ( preset , options ) = > {
try {
console . log ( ` Creating LLM model using ' ${ preset } ' preset... ` )
// Initialize LLM
const { cognition } = await initializeLLM ( ) ;
// Create the model using preset
const result = await cognition . createModelFromPreset ( preset , options . name ) ;
if ( result . success ) {
console . log ( ` Model created successfully with ID: ${ result . data . modelId } ` )
console . log ( ` Model name: ${ result . data . metadata . name } ` )
console . log ( ` Model type: ${ result . data . metadata . modelType } ` )
console . log ( ` \ nUse this ID with other commands, for example: ` )
console . log ( ` brainy llm train-simple ${ result . data . modelId } standard ` )
} else {
console . error ( ` Failed to create model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
llmCommand
. command ( 'create' )
2025-06-10 11:47:05 -07:00
. description ( 'Create a new LLM model from Brainy data (advanced)' )
2025-06-10 11:15:22 -07:00
. option ( '-n, --name <name>' , 'Name of the model' )
. option ( '-d, --description <description>' , 'Description of the model' )
. option ( '-t, --type <type>' , 'Type of model (simple, transformer, custom)' , 'simple' )
. option ( '-v, --vocab-size <size>' , 'Vocabulary size' , '5000' )
. option ( '-e, --embedding-dim <dim>' , 'Embedding dimension' , '64' )
. option ( '-h, --hidden-dim <dim>' , 'Hidden dimension' , '128' )
. option ( '-l, --layers <count>' , 'Number of layers' , '2' )
. option ( '--heads <count>' , 'Number of attention heads (for transformer models)' , '4' )
. option ( '--dropout <rate>' , 'Dropout rate' , '0.1' )
. option ( '--max-seq-length <length>' , 'Maximum sequence length' , '100' )
. action ( async ( options ) = > {
try {
2025-06-10 11:47:05 -07:00
console . log ( 'Creating LLM model with advanced options...' )
2025-06-10 11:15:22 -07:00
2025-06-10 11:47:05 -07:00
// Initialize LLM
const { cognition } = await initializeLLM ( ) ;
2025-06-10 11:15:22 -07:00
// Parse options
const config = {
name : options.name || 'model-' + Date . now ( ) ,
description : options.description || 'Created via CLI' ,
modelType : options.type ,
vocabSize : parseInt ( options . vocabSize , 10 ) ,
embeddingDim : parseInt ( options . embeddingDim , 10 ) ,
hiddenDim : parseInt ( options . hiddenDim , 10 ) ,
layers : parseInt ( options . layers , 10 ) ,
heads : parseInt ( options . heads , 10 ) ,
dropout : parseFloat ( options . dropout ) ,
maxSeqLength : parseInt ( options . maxSeqLength , 10 )
}
// Create the model
const result = await cognition . createModel ( config )
if ( result . success ) {
console . log ( ` Model created successfully with ID: ${ result . data . modelId } ` )
console . log ( ` Model type: ${ config . modelType } ` )
console . log ( ` Vocabulary size: ${ config . vocabSize } ` )
} else {
console . error ( ` Failed to create model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:47:05 -07:00
llmCommand
. command ( 'train-simple' )
. description ( 'Train an LLM model with simplified options' )
. argument ( '<modelId>' , 'ID of the model to train' )
. argument ( '[level]' , 'Training level (quick, standard, thorough)' , 'standard' )
. action ( async ( modelId , level ) = > {
try {
console . log ( ` Training LLM model ${ modelId } with ' ${ level } ' training level... ` )
// Initialize LLM
const { cognition } = await initializeLLM ( ) ;
// Display training level details
switch ( level ) {
case 'quick' :
console . log ( 'Quick training: Faster but less accurate (100 samples, 5 epochs)' )
break ;
case 'standard' :
console . log ( 'Standard training: Balanced speed and accuracy (500 samples, 10 epochs)' )
break ;
case 'thorough' :
console . log ( 'Thorough training: Slower but more accurate (1000 samples, 20 epochs)' )
break ;
default :
console . log ( ` Unknown level ' ${ level } ', using 'standard' instead ` )
level = 'standard' ;
}
// Train the model
const result = await cognition . trainModelSimple ( modelId , level as any )
if ( result . success ) {
console . log ( ` \ nModel ${ modelId } trained successfully! ` )
console . log ( ` Training metrics: ` )
if ( result . data . metrics ) {
console . log ( ` Final loss: ${ result . data . metrics . loss . toFixed ( 4 ) } ` )
console . log ( ` Final accuracy: ${ result . data . metrics . accuracy . toFixed ( 4 ) } ` )
console . log ( ` Epochs completed: ${ result . data . metrics . epochs } ` )
}
console . log ( ` \ nYou can now generate text with: ` )
console . log ( ` brainy llm generate-simple ${ modelId } "Your prompt here" ` )
} else {
console . error ( ` \ nFailed to train model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
llmCommand
. command ( 'train' )
2025-06-10 11:47:05 -07:00
. description ( 'Train an LLM model on Brainy data (advanced)' )
2025-06-10 11:15:22 -07:00
. argument ( '<modelId>' , 'ID of the model to train' )
. option ( '-s, --max-samples <count>' , 'Maximum number of training samples' )
. option ( '-v, --validation-split <ratio>' , 'Validation split ratio' , '0.2' )
. option ( '-e, --epochs <count>' , 'Number of training epochs' , '10' )
. option ( '-b, --batch-size <size>' , 'Batch size' , '32' )
. option ( '-p, --patience <count>' , 'Early stopping patience' , '3' )
. action ( async ( modelId , options ) = > {
try {
2025-06-10 11:47:05 -07:00
console . log ( ` Training LLM model ${ modelId } with advanced options... ` )
2025-06-10 11:15:22 -07:00
2025-06-10 11:47:05 -07:00
// Initialize LLM
const { cognition } = await initializeLLM ( ) ;
2025-06-10 11:15:22 -07:00
// Parse options
const trainingOptions = {
maxSamples : options.maxSamples ? parseInt ( options . maxSamples , 10 ) : undefined ,
validationSplit : parseFloat ( options . validationSplit ) ,
epochs : parseInt ( options . epochs , 10 ) ,
batchSize : parseInt ( options . batchSize , 10 ) ,
patience : parseInt ( options . patience , 10 )
}
console . log ( 'Training with options:' )
console . log ( ` Max samples: ${ trainingOptions . maxSamples || 'All available' } ` )
console . log ( ` Validation split: ${ trainingOptions . validationSplit } ` )
console . log ( ` Epochs: ${ trainingOptions . epochs } ` )
console . log ( ` Batch size: ${ trainingOptions . batchSize } ` )
console . log ( ` Early stopping patience: ${ trainingOptions . patience } ` )
// Train the model
const result = await cognition . trainModel ( modelId , trainingOptions )
if ( result . success ) {
console . log ( ` \ nModel ${ modelId } trained successfully! ` )
console . log ( ` Training metrics: ` )
if ( result . data . metrics ) {
console . log ( ` Final loss: ${ result . data . metrics . loss . toFixed ( 4 ) } ` )
console . log ( ` Final accuracy: ${ result . data . metrics . accuracy . toFixed ( 4 ) } ` )
console . log ( ` Epochs completed: ${ result . data . metrics . epochs } ` )
}
} else {
console . error ( ` \ nFailed to train model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
llmCommand
. command ( 'test' )
. description ( 'Test an LLM model on Brainy data' )
. argument ( '<modelId>' , 'ID of the model to test' )
. option ( '-s, --test-size <count>' , 'Number of test samples' , '100' )
. option ( '-g, --generate-samples' , 'Generate sample predictions' )
. option ( '-c, --sample-count <count>' , 'Number of samples to generate' , '5' )
. action ( async ( modelId , options ) = > {
try {
const db = createDb ( )
await db . init ( )
console . log ( ` Testing LLM model ${ modelId } ... ` )
// Initialize LLM augmentations
const { cognition , activation } = await createLLMAugmentations ( )
// Set the database for the cognition augmentation
cognition . setBrainyDb ( db )
// Parse options
const testingOptions = {
testSize : parseInt ( options . testSize , 10 ) ,
generateSamples : options.generateSamples ,
sampleCount : parseInt ( options . sampleCount , 10 )
}
console . log ( 'Testing with options:' )
console . log ( ` Test size: ${ testingOptions . testSize } ` )
console . log ( ` Generate samples: ${ testingOptions . generateSamples ? 'Yes' : 'No' } ` )
if ( testingOptions . generateSamples ) {
console . log ( ` Sample count: ${ testingOptions . sampleCount } ` )
}
// Test the model
const result = await cognition . testModel ( modelId , testingOptions )
if ( result . success ) {
console . log ( ` \ nModel ${ modelId } tested successfully! ` )
console . log ( ` Test metrics: ` )
if ( result . data . metrics ) {
console . log ( ` Test loss: ${ result . data . metrics . loss . toFixed ( 4 ) } ` )
console . log ( ` Test accuracy: ${ result . data . metrics . accuracy . toFixed ( 4 ) } ` )
console . log ( ` Test samples: ${ result . data . metrics . samples } ` )
}
// Display generated samples if available
if ( result . data . samples && result . data . samples . length > 0 ) {
console . log ( ` \ nGenerated samples: ` )
result . data . samples . forEach ( ( sample : { input : string ; expected : string ; generated : string } , index : number ) = > {
console . log ( ` \ nSample ${ index + 1 } : ` )
console . log ( ` Input: ${ sample . input } ` )
console . log ( ` Predicted: ${ sample . generated } ` )
if ( sample . expected ) {
console . log ( ` Actual: ${ sample . expected } ` )
}
} )
}
} else {
console . error ( ` \ nFailed to test model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
llmCommand
. command ( 'export' )
. description ( 'Export an LLM model for deployment' )
. argument ( '<modelId>' , 'ID of the model to export' )
. option ( '-f, --format <format>' , 'Export format (tfjs, json)' , 'json' )
. option ( '-o, --output <path>' , 'Output path' )
. option ( '-m, --include-metadata' , 'Include metadata' )
. option ( '-v, --include-vocab' , 'Include vocabulary' )
. action ( async ( modelId , options ) = > {
try {
const db = createDb ( )
await db . init ( )
console . log ( ` Exporting LLM model ${ modelId } ... ` )
// Initialize LLM augmentations
const { cognition , activation } = await createLLMAugmentations ( )
// Set the database for the cognition augmentation
cognition . setBrainyDb ( db )
// Parse options
const exportOptions = {
format : options.format ,
outputPath : options.output ,
includeMetadata : options.includeMetadata ,
includeVocab : options.includeVocab
}
console . log ( 'Exporting with options:' )
console . log ( ` Format: ${ exportOptions . format } ` )
if ( exportOptions . outputPath ) {
console . log ( ` Output path: ${ exportOptions . outputPath } ` )
}
console . log ( ` Include metadata: ${ exportOptions . includeMetadata ? 'Yes' : 'No' } ` )
console . log ( ` Include vocabulary: ${ exportOptions . includeVocab ? 'Yes' : 'No' } ` )
// Export the model
const result = await cognition . exportModel ( modelId , exportOptions )
if ( result . success ) {
console . log ( ` \ nModel ${ modelId } exported successfully! ` )
if ( result . data . path ) {
console . log ( ` Exported to: ${ result . data . path } ` )
}
if ( result . data . size ) {
console . log ( ` Export size: ${ ( result . data . size / 1024 ) . toFixed ( 2 ) } KB ` )
}
} else {
console . error ( ` \ nFailed to export model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
llmCommand
. command ( 'deploy' )
. description ( 'Deploy an LLM model to the specified target' )
. argument ( '<modelId>' , 'ID of the model to deploy' )
. option ( '-t, --target <target>' , 'Deployment target (browser, node, cloud)' , 'browser' )
. option ( '-p, --provider <provider>' , 'Cloud provider (aws, gcp, azure)' )
. option ( '-e, --endpoint <url>' , 'Endpoint URL for cloud deployment' )
. option ( '-r, --region <region>' , 'Region for cloud deployment' )
. action ( async ( modelId , options ) = > {
try {
const db = createDb ( )
await db . init ( )
console . log ( ` Deploying LLM model ${ modelId } to ${ options . target } ... ` )
// Initialize LLM augmentations
const { cognition , activation } = await createLLMAugmentations ( )
// Set the database for the cognition augmentation
cognition . setBrainyDb ( db )
// Parse options
const deploymentOptions = {
target : options.target ,
provider : options.provider ,
endpoint : options.endpoint ,
region : options.region
}
console . log ( 'Deploying with options:' )
console . log ( ` Target: ${ deploymentOptions . target } ` )
if ( deploymentOptions . provider ) {
console . log ( ` Provider: ${ deploymentOptions . provider } ` )
}
if ( deploymentOptions . endpoint ) {
console . log ( ` Endpoint: ${ deploymentOptions . endpoint } ` )
}
if ( deploymentOptions . region ) {
console . log ( ` Region: ${ deploymentOptions . region } ` )
}
// Deploy the model
const result = await cognition . deployModel ( modelId , deploymentOptions )
if ( result . success ) {
console . log ( ` \ nModel ${ modelId } deployed successfully! ` )
if ( result . data . url ) {
console . log ( ` Deployment URL: ${ result . data . url } ` )
}
if ( result . data . deploymentId ) {
console . log ( ` Deployment ID: ${ result . data . deploymentId } ` )
}
} else {
console . error ( ` \ nFailed to deploy model: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:47:05 -07:00
llmCommand
. command ( 'generate-simple' )
. description ( 'Generate text using an LLM model with simplified creativity options' )
. argument ( '<modelId>' , 'ID of the model to use' )
. argument ( '<prompt>' , 'Input prompt for text generation' )
. argument ( '[creativity]' , 'Creativity level (conservative, balanced, creative)' , 'balanced' )
. action ( async ( modelId , prompt , creativity ) = > {
try {
console . log ( ` Generating text using LLM model ${ modelId } ... ` )
console . log ( ` Prompt: " ${ prompt } " ` )
// Initialize LLM
const { cognition } = await initializeLLM ( ) ;
// Display creativity level details
switch ( creativity ) {
case 'conservative' :
console . log ( 'Conservative creativity: More predictable, focused output' )
break ;
case 'balanced' :
console . log ( 'Balanced creativity: Mix of predictability and creativity' )
break ;
case 'creative' :
console . log ( 'High creativity: More varied, unexpected output' )
break ;
default :
console . log ( ` Unknown creativity level ' ${ creativity } ', using 'balanced' instead ` )
creativity = 'balanced' ;
}
// Generate text
const result = await cognition . generateTextSimple ( modelId , prompt , creativity as any )
if ( result . success ) {
console . log ( ` \ nGenerated text: ` )
console . log ( ` -------------- ` )
console . log ( result . data . text )
console . log ( ` -------------- ` )
if ( result . data . tokens ) {
console . log ( ` \ nTokens generated: ${ result . data . tokens } ` )
}
if ( result . data . timeMs ) {
console . log ( ` Generation time: ${ result . data . timeMs } ms ` )
}
} else {
console . error ( ` \ nFailed to generate text: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
2025-06-10 11:15:22 -07:00
llmCommand
. command ( 'generate' )
2025-06-10 11:47:05 -07:00
. description ( 'Generate text using an LLM model (advanced)' )
2025-06-10 11:15:22 -07:00
. argument ( '<modelId>' , 'ID of the model to use' )
. argument ( '<prompt>' , 'Input prompt for text generation' )
. option ( '-t, --temperature <temp>' , 'Temperature for sampling' , '0.7' )
. option ( '-k, --top-k <count>' , 'Number of top tokens to consider' , '5' )
. option ( '-l, --max-length <length>' , 'Maximum length of generated text' , '100' )
. action ( async ( modelId , prompt , options ) = > {
try {
2025-06-10 11:47:05 -07:00
console . log ( ` Generating text using LLM model ${ modelId } with advanced options... ` )
2025-06-10 11:15:22 -07:00
console . log ( ` Prompt: " ${ prompt } " ` )
2025-06-10 11:47:05 -07:00
// Initialize LLM
const { cognition } = await initializeLLM ( ) ;
2025-06-10 11:15:22 -07:00
// Parse options
const generateOptions = {
temperature : parseFloat ( options . temperature ) ,
topK : parseInt ( options . topK , 10 ) ,
maxLength : parseInt ( options . maxLength , 10 )
}
console . log ( 'Generation options:' )
console . log ( ` Temperature: ${ generateOptions . temperature } ` )
console . log ( ` Top-K: ${ generateOptions . topK } ` )
console . log ( ` Max length: ${ generateOptions . maxLength } ` )
// Generate text
const result = await cognition . generateText ( modelId , prompt , generateOptions )
if ( result . success ) {
console . log ( ` \ nGenerated text: ` )
console . log ( ` -------------- ` )
console . log ( result . data . text )
console . log ( ` -------------- ` )
if ( result . data . tokens ) {
console . log ( ` \ nTokens generated: ${ result . data . tokens } ` )
}
if ( result . data . timeMs ) {
console . log ( ` Generation time: ${ result . data . timeMs } ms ` )
}
} else {
console . error ( ` \ nFailed to generate text: ${ result . error } ` )
}
} catch ( error ) {
console . error ( 'Error:' , ( error as Error ) . message )
process . exit ( 1 )
}
} )
// Add the LLM command to the program
program . addCommand ( llmCommand )
2025-06-05 11:44:18 -07:00
program . parse ( )