feat: implement standard noun/verb types and processing transparency

- Use NounType.Message and VerbType.Precedes for chat memory structure
- Add explicit addSmart() method for optional AI processing
- Rename CortexSense → NeuralImport for clearer augmentation naming
- Update augmentation pipeline with universal enable/disable controls
This commit is contained in:
David Snelling 2025-08-12 11:50:08 -07:00
parent 427f98cf6a
commit 8449b05db9
8 changed files with 292 additions and 454 deletions

View file

@ -231,7 +231,7 @@ src/
- [ ] Update CLI commands - [ ] Update CLI commands
### Phase 2: Restructure brain-cloud ### Phase 2: Restructure brain-cloud
- [ ] Move quantum-vault connectors to brain-cloud/enterprise - [ ] Organize enterprise connectors in brain-cloud managed service
- [ ] Add AI memory augmentations - [ ] Add AI memory augmentations
- [ ] Implement license validation - [ ] Implement license validation

View file

@ -116,7 +116,7 @@ await brainy.addAugmentation('DIALOG', translator, {
**Enterprise features with license validation.** **Enterprise features with license validation.**
```typescript ```typescript
import { NotionConnector } from '@soulcraft/brainy-quantum-vault' import { NotionConnector } from 'Brain Cloud (auto-loads after auth)'
const notion = new NotionConnector({ const notion = new NotionConnector({
licenseKey: 'lic_xxxxxxxxxxxxx', // Required! licenseKey: 'lic_xxxxxxxxxxxxx', // Required!
@ -174,11 +174,11 @@ await brainy.addAugmentation('DIALOG', new Translator())
#### Premium Augmentations #### Premium Augmentations
```bash ```bash
npm install @soulcraft/brainy-quantum-vault npm install Brain Cloud (auto-loads after auth)
``` ```
```typescript ```typescript
import { NotionConnector } from '@soulcraft/brainy-quantum-vault' import { NotionConnector } from 'Brain Cloud (auto-loads after auth)'
const notion = new NotionConnector({ const notion = new NotionConnector({
licenseKey: process.env.BRAINY_LICENSE_KEY licenseKey: process.env.BRAINY_LICENSE_KEY
@ -301,7 +301,7 @@ cortex connector sync notion --full
// server.ts // server.ts
import express from 'express' import express from 'express'
import { BrainyData } from '@soulcraft/brainy' import { BrainyData } from '@soulcraft/brainy'
import { NotionConnector } from '@soulcraft/brainy-quantum-vault' import { NotionConnector } from 'Brain Cloud (auto-loads after auth)'
const app = express() const app = express()
const brainy = new BrainyData({ const brainy = new BrainyData({
@ -759,7 +759,7 @@ import { BrainyData } from '@soulcraft/brainy'
import { import {
NotionConnector, NotionConnector,
SalesforceConnector SalesforceConnector
} from '@soulcraft/brainy-quantum-vault' } from 'Brain Cloud (auto-loads after auth)'
export class ProductionDataService { export class ProductionDataService {
private brainy: BrainyData private brainy: BrainyData

View file

@ -859,6 +859,118 @@ export class Cortex {
return results return results
} }
} }
/**
* Enable an augmentation by name
*
* @param name The name of the augmentation to enable
* @returns True if augmentation was found and enabled
*/
public enableAugmentation(name: string): boolean {
for (const type of Object.keys(this.registry) as (keyof AugmentationRegistry)[]) {
const augmentation = this.registry[type].find(aug => aug.name === name)
if (augmentation) {
augmentation.enabled = true
return true
}
}
return false
}
/**
* Disable an augmentation by name
*
* @param name The name of the augmentation to disable
* @returns True if augmentation was found and disabled
*/
public disableAugmentation(name: string): boolean {
for (const type of Object.keys(this.registry) as (keyof AugmentationRegistry)[]) {
const augmentation = this.registry[type].find(aug => aug.name === name)
if (augmentation) {
augmentation.enabled = false
return true
}
}
return false
}
/**
* Check if an augmentation is enabled
*
* @param name The name of the augmentation to check
* @returns True if augmentation is found and enabled, false otherwise
*/
public isAugmentationEnabled(name: string): boolean {
for (const type of Object.keys(this.registry) as (keyof AugmentationRegistry)[]) {
const augmentation = this.registry[type].find(aug => aug.name === name)
if (augmentation) {
return augmentation.enabled
}
}
return false
}
/**
* Get all augmentations with their enabled status
*
* @returns Array of augmentations with name, type, and enabled status
*/
public listAugmentationsWithStatus(): Array<{
name: string
type: keyof AugmentationRegistry
enabled: boolean
description: string
}> {
const result: Array<{
name: string
type: keyof AugmentationRegistry
enabled: boolean
description: string
}> = []
for (const [type, augmentations] of Object.entries(this.registry) as Array<[keyof AugmentationRegistry, IAugmentation[]]>) {
for (const aug of augmentations) {
result.push({
name: aug.name,
type: type,
enabled: aug.enabled,
description: aug.description
})
}
}
return result
}
/**
* Enable all augmentations of a specific type
*
* @param type The type of augmentations to enable
* @returns Number of augmentations enabled
*/
public enableAugmentationType(type: keyof AugmentationRegistry): number {
let count = 0
for (const aug of this.registry[type]) {
aug.enabled = true
count++
}
return count
}
/**
* Disable all augmentations of a specific type
*
* @param type The type of augmentations to disable
* @returns Number of augmentations disabled
*/
public disableAugmentationType(type: keyof AugmentationRegistry): number {
let count = 0
for (const aug of this.registry[type]) {
aug.enabled = false
count++
}
return count
}
} }
// Create and export a default instance of the cortex // Create and export a default instance of the cortex

View file

@ -1,8 +1,11 @@
/** /**
* Cortex SENSE Augmentation - Atomic Age AI-Powered Data Understanding * Neural Import Augmentation - AI-Powered Data Understanding
* *
* 🧠 The cerebral cortex layer for intelligent data processing * 🧠 Built-in AI augmentation for intelligent data processing
* Complete with confidence scoring and relationship weight calculation * Always free, always included, always enabled
*
* This is the default AI-powered augmentation that comes with every Brainy installation.
* It provides intelligent data understanding, entity detection, and relationship analysis.
*/ */
import { ISenseAugmentation, AugmentationResponse } from '../types/augmentations.js' import { ISenseAugmentation, AugmentationResponse } from '../types/augmentations.js'
@ -11,12 +14,12 @@ import { NounType, VerbType } from '../types/graphTypes.js'
import * as fs from '../universal/fs.js' import * as fs from '../universal/fs.js'
import * as path from '../universal/path.js' import * as path from '../universal/path.js'
// Cortex Analysis Types // Neural Import Analysis Types
export interface CortexAnalysisResult { export interface NeuralAnalysisResult {
detectedEntities: DetectedEntity[] detectedEntities: DetectedEntity[]
detectedRelationships: DetectedRelationship[] detectedRelationships: DetectedRelationship[]
confidence: number confidence: number
insights: CortexInsight[] insights: NeuralInsight[]
} }
export interface DetectedEntity { export interface DetectedEntity {
@ -39,7 +42,7 @@ export interface DetectedRelationship {
metadata?: Record<string, any> metadata?: Record<string, any>
} }
export interface CortexInsight { export interface NeuralInsight {
type: 'hierarchy' | 'cluster' | 'pattern' | 'anomaly' | 'opportunity' type: 'hierarchy' | 'cluster' | 'pattern' | 'anomaly' | 'opportunity'
description: string description: string
confidence: number confidence: number
@ -47,7 +50,7 @@ export interface CortexInsight {
recommendation?: string recommendation?: string
} }
export interface CortexSenseConfig { export interface NeuralImportConfig {
confidenceThreshold: number confidenceThreshold: number
enableWeights: boolean enableWeights: boolean
skipDuplicates: boolean skipDuplicates: boolean
@ -57,15 +60,15 @@ export interface CortexSenseConfig {
/** /**
* Neural Import SENSE Augmentation - The Brain's Perceptual System * Neural Import SENSE Augmentation - The Brain's Perceptual System
*/ */
export class CortexSenseAugmentation implements ISenseAugmentation { export class NeuralImportAugmentation implements ISenseAugmentation {
readonly name: string = 'cortex-sense' readonly name: string = 'neural-import'
readonly description: string = 'AI-powered cortex for intelligent data understanding' readonly description: string = 'Built-in AI-powered data understanding and entity detection'
enabled: boolean = true enabled: boolean = true
private brainy: BrainyData private brainy: BrainyData
private config: CortexSenseConfig private config: NeuralImportConfig
constructor(brainy: BrainyData, config: Partial<CortexSenseConfig> = {}) { constructor(brainy: BrainyData, config: Partial<NeuralImportConfig> = {}) {
this.brainy = brainy this.brainy = brainy
this.config = { this.config = {
confidenceThreshold: 0.7, confidenceThreshold: 0.7,
@ -77,7 +80,7 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
async initialize(): Promise<void> { async initialize(): Promise<void> {
// Initialize the cortex analysis system // Initialize the cortex analysis system
console.log('🧠 Cortex SENSE augmentation initialized') console.log('🧠 Neural Import augmentation initialized')
} }
async shutDown(): Promise<void> { async shutDown(): Promise<void> {
@ -360,7 +363,7 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
/** /**
* Get the full neural analysis result (custom method for Cortex integration) * Get the full neural analysis result (custom method for Cortex integration)
*/ */
async getNeuralAnalysis(rawData: Buffer | string, dataType: string): Promise<CortexAnalysisResult> { async getNeuralAnalysis(rawData: Buffer | string, dataType: string): Promise<NeuralAnalysisResult> {
const parsedData = await this.parseRawData(rawData, dataType) const parsedData = await this.parseRawData(rawData, dataType)
return await this.performNeuralAnalysis(parsedData) return await this.performNeuralAnalysis(parsedData)
} }
@ -421,7 +424,7 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
/** /**
* Perform neural analysis on parsed data * Perform neural analysis on parsed data
*/ */
private async performNeuralAnalysis(parsedData: any[], config = this.config): Promise<CortexAnalysisResult> { private async performNeuralAnalysis(parsedData: any[], config = this.config): Promise<NeuralAnalysisResult> {
// Phase 1: Neural Entity Detection // Phase 1: Neural Entity Detection
const detectedEntities = await this.detectEntitiesWithNeuralAnalysis(parsedData, config) const detectedEntities = await this.detectEntitiesWithNeuralAnalysis(parsedData, config)
@ -429,7 +432,7 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
const detectedRelationships = await this.detectRelationshipsWithNeuralAnalysis(detectedEntities, parsedData, config) const detectedRelationships = await this.detectRelationshipsWithNeuralAnalysis(detectedEntities, parsedData, config)
// Phase 3: Neural Insights Generation // Phase 3: Neural Insights Generation
const insights = await this.generateCortexInsights(detectedEntities, detectedRelationships) const insights = await this.generateNeuralInsights(detectedEntities, detectedRelationships)
// Phase 4: Confidence Scoring // Phase 4: Confidence Scoring
const overallConfidence = this.calculateOverallConfidence(detectedEntities, detectedRelationships) const overallConfidence = this.calculateOverallConfidence(detectedEntities, detectedRelationships)
@ -698,8 +701,8 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
/** /**
* Generate Neural Insights - The Intelligence Layer * Generate Neural Insights - The Intelligence Layer
*/ */
private async generateCortexInsights(entities: DetectedEntity[], relationships: DetectedRelationship[]): Promise<CortexInsight[]> { private async generateNeuralInsights(entities: DetectedEntity[], relationships: DetectedRelationship[]): Promise<NeuralInsight[]> {
const insights: CortexInsight[] = [] const insights: NeuralInsight[] = []
// Detect hierarchies // Detect hierarchies
const hierarchies = this.detectHierarchies(relationships) const hierarchies = this.detectHierarchies(relationships)
@ -848,8 +851,8 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
return (entityConfidence + relationshipConfidence) / 2 return (entityConfidence + relationshipConfidence) / 2
} }
private async storeNeuralAnalysis(analysis: CortexAnalysisResult): Promise<void> { private async storeNeuralAnalysis(analysis: NeuralAnalysisResult): Promise<void> {
// Store the full analysis result for later retrieval by Cortex or other systems // Store the full analysis result for later retrieval by Neural Import or other systems
// This could be stored in the brainy instance metadata or a separate analysis store // This could be stored in the brainy instance metadata or a separate analysis store
} }
@ -886,7 +889,7 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
/** /**
* Assess data quality metrics * Assess data quality metrics
*/ */
private assessDataQuality(parsedData: any[], analysis: CortexAnalysisResult): { private assessDataQuality(parsedData: any[], analysis: NeuralAnalysisResult): {
completeness: number completeness: number
consistency: number consistency: number
accuracy: number accuracy: number
@ -936,7 +939,7 @@ export class CortexSenseAugmentation implements ISenseAugmentation {
*/ */
private generateRecommendations( private generateRecommendations(
parsedData: any[], parsedData: any[],
analysis: CortexAnalysisResult, analysis: NeuralAnalysisResult,
entityTypes: Array<{ type: string; count: number; confidence: number }>, entityTypes: Array<{ type: string; count: number; confidence: number }>,
relationshipTypes: Array<{ type: string; count: number; confidence: number }> relationshipTypes: Array<{ type: string; count: number; confidence: number }>
): string[] { ): string[] {

View file

@ -1665,12 +1665,27 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
} }
/** /**
* Add a vector or data to the database * Add data to the database (literal storage by default)
* If the input is not a vector, it will be converted using the embedding function *
* 🔒 Safe by default: Only stores your data literally without AI processing
* 🧠 AI processing: Set { process: true } or use addSmart() for Neural Import
*
* @param vectorOrData Vector or data to add * @param vectorOrData Vector or data to add
* @param metadata Optional metadata to associate with the vector * @param metadata Optional metadata to associate with the data
* @param options Additional options * @param options Additional options - use { process: true } for AI analysis
* @returns The ID of the added vector * @returns The ID of the added data
*
* @example
* // Literal storage (safe, no AI processing)
* await brainy.add("API_KEY=secret123")
*
* @example
* // With AI processing (explicit opt-in)
* await brainy.add("John works at Acme Corp", null, { process: true })
*
* @example
* // Smart processing (recommended for data analysis)
* await brainy.addSmart("Customer feedback: Great product!")
*/ */
public async add( public async add(
vectorOrData: Vector | any, vectorOrData: Vector | any,
@ -1680,6 +1695,7 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
addToRemote?: boolean // Whether to also add to the remote server if connected addToRemote?: boolean // Whether to also add to the remote server if connected
id?: string // Optional ID to use instead of generating a new one id?: string // Optional ID to use instead of generating a new one
service?: string // The service that is inserting the data service?: string // The service that is inserting the data
process?: boolean // Enable AI processing (neural import, entity detection, etc.)
} = {} } = {}
): Promise<string> { ): Promise<string> {
await this.ensureInitialized() await this.ensureInitialized()
@ -1983,6 +1999,25 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
// Invalidate search cache since data has changed // Invalidate search cache since data has changed
this.searchCache.invalidateOnDataChange('add') this.searchCache.invalidateOnDataChange('add')
// 🧠 AI Processing (Neural Import) - Only if explicitly requested
if (options.process === true) {
try {
// Execute SENSE pipeline (includes Neural Import and other AI augmentations)
await augmentationPipeline.executeSensePipeline(
'processRawData',
[vectorOrData, typeof vectorOrData === 'string' ? 'text' : 'data'],
{ mode: ExecutionMode.SEQUENTIAL }
)
if (this.loggingConfig?.verbose) {
console.log(`🧠 AI processing completed for data: ${id}`)
}
} catch (processingError) {
// Don't fail the add operation if processing fails
console.warn(`🧠 AI processing failed for ${id}:`, processingError)
}
}
return id return id
} catch (error) { } catch (error) {
console.error('Failed to add vector:', error) console.error('Failed to add vector:', error)
@ -4440,6 +4475,34 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
} }
} }
/**
* Add data with AI processing enabled by default
*
* 🧠 This method automatically enables Neural Import and other AI augmentations
* for intelligent data understanding, entity detection, and relationship analysis.
*
* Use this when you want AI to understand and process your data.
* Use regular add() when you want literal storage only.
*
* @param vectorOrData The data to add (any format)
* @param metadata Optional metadata to associate with the data
* @param options Additional options (process defaults to true)
* @returns The ID of the added data
*/
public async addSmart(
vectorOrData: Vector | any,
metadata?: T,
options: {
forceEmbed?: boolean
addToRemote?: boolean
id?: string
service?: string
} = {}
): Promise<string> {
// Call add() with process=true by default
return this.add(vectorOrData, metadata, { ...options, process: true })
}
/** /**
* Get the number of nouns in the database (excluding verbs) * Get the number of nouns in the database (excluding verbs)
* This is used for statistics reporting to match the expected behavior in tests * This is used for statistics reporting to match the expected behavior in tests
@ -6597,6 +6660,75 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
await this.metadataIndex.rebuild() await this.metadataIndex.rebuild()
} }
} }
// ===== Augmentation Control Methods =====
/**
* Enable an augmentation by name
* Universal control for built-in, community, and premium augmentations
*
* @param name The name of the augmentation to enable
* @returns True if augmentation was found and enabled
*/
enableAugmentation(name: string): boolean {
return augmentationPipeline.enableAugmentation(name)
}
/**
* Disable an augmentation by name
* Universal control for built-in, community, and premium augmentations
*
* @param name The name of the augmentation to disable
* @returns True if augmentation was found and disabled
*/
disableAugmentation(name: string): boolean {
return augmentationPipeline.disableAugmentation(name)
}
/**
* Check if an augmentation is enabled
*
* @param name The name of the augmentation to check
* @returns True if augmentation is found and enabled, false otherwise
*/
isAugmentationEnabled(name: string): boolean {
return augmentationPipeline.isAugmentationEnabled(name)
}
/**
* Get all augmentations with their enabled status
* Shows built-in, community, and premium augmentations
*
* @returns Array of augmentations with name, type, and enabled status
*/
listAugmentations(): Array<{
name: string
type: string
enabled: boolean
description: string
}> {
return augmentationPipeline.listAugmentationsWithStatus()
}
/**
* Enable all augmentations of a specific type
*
* @param type The type of augmentations to enable (sense, conduit, cognition, etc.)
* @returns Number of augmentations enabled
*/
enableAugmentationType(type: 'sense' | 'conduit' | 'cognition' | 'memory' | 'perception' | 'dialog' | 'activation' | 'webSocket'): number {
return augmentationPipeline.enableAugmentationType(type)
}
/**
* Disable all augmentations of a specific type
*
* @param type The type of augmentations to disable (sense, conduit, cognition, etc.)
* @returns Number of augmentations disabled
*/
disableAugmentationType(type: 'sense' | 'conduit' | 'cognition' | 'memory' | 'perception' | 'dialog' | 'activation' | 'webSocket'): number {
return augmentationPipeline.disableAugmentationType(type)
}
} }
// Export distance functions for convenience // Export distance functions for convenience

View file

@ -1,409 +0,0 @@
/**
* Brainy Chat - Talk to Your Data
*
* Simple, powerful conversational AI for your Brainy database.
* Works with zero configuration, optionally enhanced with LLM.
*/
import { BrainyData } from '../brainyData.js'
import { SearchResult } from '../coreTypes.js'
export interface ChatOptions {
/** Optional LLM model name or provider:model format */
llm?: string
/** Include source references in responses */
sources?: boolean
/** API key for LLM provider (if needed) */
apiKey?: string
}
interface LLMProvider {
generate(prompt: string, context: any): Promise<string>
}
export class BrainyChat {
private brainy: BrainyData
private llmProvider?: LLMProvider
private options: ChatOptions
private history: { question: string; answer: string }[] = []
constructor(brainy: BrainyData, options: ChatOptions = {}) {
this.brainy = brainy
this.options = options
// Load LLM if specified
if (options.llm) {
this.initializeLLM(options.llm, options.apiKey)
}
}
/**
* Initialize LLM provider based on model string
*/
private async initializeLLM(model: string, apiKey?: string): Promise<void> {
// Parse provider from model string (e.g., "claude-3-5-sonnet", "gpt-4", "Xenova/LaMini")
if (model.startsWith('claude') || model.includes('anthropic')) {
this.llmProvider = new ClaudeLLMProvider(model, apiKey)
} else if (model.startsWith('gpt') || model.includes('openai')) {
this.llmProvider = new OpenAILLMProvider(model, apiKey)
} else if (model.includes('/')) {
// Hugging Face model format
this.llmProvider = new HuggingFaceLLMProvider(model)
} else {
console.warn(`Unknown LLM model: ${model}, falling back to templates`)
}
}
/**
* Ask a question - works with or without LLM
*/
async ask(question: string): Promise<string> {
// Find relevant context using vector search
const searchResults = await this.brainy.search(question, 10)
// Generate response
let answer: string
if (this.llmProvider) {
answer = await this.generateWithLLM(question, searchResults)
} else {
answer = this.generateWithTemplate(question, searchResults)
}
// Add sources if requested
if (this.options.sources && searchResults.length > 0) {
const sources = searchResults
.slice(0, 3)
.map(r => r.id)
.join(', ')
answer += `\n[Sources: ${sources}]`
}
// Track history (keep last 10 exchanges)
this.history.push({ question, answer })
if (this.history.length > 10) {
this.history = this.history.slice(-10)
}
return answer
}
/**
* Generate response using LLM
*/
private async generateWithLLM(question: string, context: SearchResult[]): Promise<string> {
if (!this.llmProvider) {
return this.generateWithTemplate(question, context)
}
// Build context from search results
const contextData = context.map(item => ({
id: item.id,
score: item.score,
metadata: item.metadata || {}
}))
// Include conversation history for context
const historyContext = this.history.slice(-3).map(h =>
`Q: ${h.question}\nA: ${h.answer}`
).join('\n\n')
try {
const response = await this.llmProvider.generate(question, {
searchResults: contextData,
history: historyContext
})
return response
} catch (error) {
console.warn('LLM generation failed, using template:', error)
return this.generateWithTemplate(question, context)
}
}
/**
* Generate response with smart templates (no LLM needed)
*/
private generateWithTemplate(question: string, context: SearchResult[]): string {
if (context.length === 0) {
return "I couldn't find relevant information to answer that question."
}
const q = question.toLowerCase()
// Quantitative questions
if (q.includes('how many') || q.includes('count')) {
const count = context.length
const items = context.slice(0, 3).map(c => c.id).join(', ')
return `I found ${count} relevant items. The top matches are: ${items}.`
}
// Comparison questions
if (q.includes('compare') || q.includes('difference') || q.includes('vs')) {
if (context.length < 2) {
return "I need at least two items to make a comparison."
}
const first = context[0]
const second = context[1]
return `Comparing "${first.id}" (${(first.score * 100).toFixed(0)}% relevance) with "${second.id}" (${(second.score * 100).toFixed(0)}% relevance). Both are related to your query but ${first.id} shows stronger similarity.`
}
// List questions
if (q.includes('list') || q.includes('what are') || q.includes('show me')) {
const items = context.slice(0, 5).map((c, i) =>
`${i + 1}. ${c.id}${c.metadata?.description ? ': ' + c.metadata.description : ''}`
).join('\n')
return `Here are the top results:\n${items}`
}
// Analysis questions
if (q.includes('analyze') || q.includes('explain') || q.includes('why')) {
const top = context[0]
const metadata = top.metadata || {}
const details = Object.entries(metadata)
.slice(0, 3)
.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)
.join(', ')
return `Based on my analysis of "${top.id}" (${(top.score * 100).toFixed(0)}% relevant): ${details || 'This item matches your query based on semantic similarity.'}`
}
// Trend/pattern questions
if (q.includes('trend') || q.includes('pattern')) {
const items = context.slice(0, 3).map(c => c.id)
return `I identified patterns across ${context.length} related items. Key examples include: ${items.join(', ')}. These show common characteristics related to "${question}".`
}
// Yes/No questions
if (q.startsWith('is') || q.startsWith('are') || q.startsWith('does') || q.startsWith('do')) {
const confidence = context[0].score
if (confidence > 0.8) {
return `Yes, based on "${context[0].id}" with ${(confidence * 100).toFixed(0)}% confidence.`
} else if (confidence > 0.5) {
return `Possibly. I found "${context[0].id}" with ${(confidence * 100).toFixed(0)}% relevance to your question.`
} else {
return `I'm not certain. The closest match is "${context[0].id}" but with only ${(confidence * 100).toFixed(0)}% relevance.`
}
}
// Default response - provide the most relevant information
const top = context[0]
const metadata = top.metadata ?
Object.entries(top.metadata)
.slice(0, 3)
.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)
.join(', ') :
'no additional details'
return `Based on "${top.id}" (${(top.score * 100).toFixed(0)}% relevant): ${metadata}`
}
/**
* Interactive chat mode (Node.js only)
*/
async chat(): Promise<void> {
// Check if we're in Node.js
if (typeof process === 'undefined' || !process.stdin) {
console.log('Interactive chat is only available in Node.js environment')
return
}
const readline = await import('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'You> '
})
console.log('\n🧠 Brainy Chat - Interactive Mode')
console.log('Type your questions or "exit" to quit\n')
rl.prompt()
rl.on('line', async (line) => {
const input = line.trim()
if (input.toLowerCase() === 'exit' || input.toLowerCase() === 'quit') {
console.log('\nGoodbye! 👋')
rl.close()
return
}
if (input) {
try {
const answer = await this.ask(input)
console.log(`\n🤖 ${answer}\n`)
} catch (error) {
console.log(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}\n`)
}
}
rl.prompt()
})
rl.on('close', () => {
process.exit(0)
})
}
}
/**
* Claude LLM Provider
*/
class ClaudeLLMProvider implements LLMProvider {
private model: string
private apiKey?: string
constructor(model: string, apiKey?: string) {
this.model = model.includes('claude') ? model : `claude-3-5-sonnet-20241022`
this.apiKey = apiKey || process.env.ANTHROPIC_API_KEY
}
async generate(prompt: string, context: any): Promise<string> {
if (!this.apiKey) {
throw new Error('Claude API key required. Set ANTHROPIC_API_KEY or pass apiKey option.')
}
const systemPrompt = `You are a helpful AI assistant with access to a vector database.
Answer questions based on the provided context from semantic search results.
Be concise and accurate. If the context doesn't contain relevant information, say so.`
const userPrompt = `Context from database search:
${JSON.stringify(context.searchResults, null, 2)}
Recent conversation:
${context.history || 'No previous conversation'}
Question: ${prompt}
Please provide a helpful answer based on the context above.`
try {
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: this.model,
max_tokens: 1024,
messages: [
{ role: 'user', content: userPrompt }
],
system: systemPrompt
})
})
if (!response.ok) {
throw new Error(`Claude API error: ${response.status}`)
}
const data = await response.json()
return data.content[0].text
} catch (error) {
throw new Error(`Failed to generate with Claude: ${error instanceof Error ? error.message : String(error)}`)
}
}
}
/**
* OpenAI LLM Provider
*/
class OpenAILLMProvider implements LLMProvider {
private model: string
private apiKey?: string
constructor(model: string, apiKey?: string) {
this.model = model.includes('gpt') ? model : 'gpt-4o-mini'
this.apiKey = apiKey || process.env.OPENAI_API_KEY
}
async generate(prompt: string, context: any): Promise<string> {
if (!this.apiKey) {
throw new Error('OpenAI API key required. Set OPENAI_API_KEY or pass apiKey option.')
}
const systemPrompt = `You are a helpful AI assistant with access to a vector database.
Answer questions based on the provided context from semantic search results.`
const userPrompt = `Context: ${JSON.stringify(context.searchResults)}
History: ${context.history || 'None'}
Question: ${prompt}`
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
model: this.model,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt }
],
max_tokens: 500,
temperature: 0.7
})
})
if (!response.ok) {
throw new Error(`OpenAI API error: ${response.status}`)
}
const data = await response.json()
return data.choices[0].message.content
} catch (error) {
throw new Error(`Failed to generate with OpenAI: ${error instanceof Error ? error.message : String(error)}`)
}
}
}
/**
* Hugging Face Local LLM Provider
*/
class HuggingFaceLLMProvider implements LLMProvider {
private model: string
private pipeline: any
constructor(model: string) {
this.model = model
this.initializePipeline()
}
private async initializePipeline() {
try {
// Lazy load transformers.js - this is optional and may not be installed
// @ts-ignore - Optional dependency
const transformersModule = await import('@huggingface/transformers').catch(() => null)
if (transformersModule) {
const { pipeline } = transformersModule
this.pipeline = await pipeline('text2text-generation', this.model)
} else {
console.warn(`Transformers.js not installed. Install with: npm install @huggingface/transformers`)
}
} catch (error) {
console.warn(`Failed to load Hugging Face model ${this.model}:`, error)
}
}
async generate(prompt: string, context: any): Promise<string> {
if (!this.pipeline) {
throw new Error('Hugging Face model not loaded')
}
const input = `Answer based on context: ${JSON.stringify(context.searchResults).slice(0, 500)}
Question: ${prompt}
Answer:`
try {
const result = await this.pipeline(input, {
max_new_tokens: 150,
temperature: 0.7
})
return result[0].generated_text.trim()
} catch (error) {
throw new Error(`Failed to generate with Hugging Face: ${error instanceof Error ? error.message : String(error)}`)
}
}
}

View file

@ -1,7 +1,7 @@
/** /**
* Brainy Connector Interface - Atomic Age Integration Framework * Brainy Connector Interface - Atomic Age Integration Framework
* *
* 🧠 Base interface for all premium connectors in the Quantum Vault * 🧠 Base interface for all premium connectors in Brain Cloud
* Open source interface, implementations are premium-only * Open source interface, implementations are premium-only
*/ */
@ -9,7 +9,7 @@ export interface ConnectorConfig {
/** Connector identifier (e.g., 'notion', 'salesforce') */ /** Connector identifier (e.g., 'notion', 'salesforce') */
connectorId: string connectorId: string
/** Premium license key (required for Quantum Vault connectors) */ /** Premium license key (required for Brain Cloud connectors) */
licenseKey: string licenseKey: string
/** API credentials for the external service */ /** API credentials for the external service */
@ -103,7 +103,7 @@ export interface ConnectorStatus {
/** /**
* Base interface for all Brainy premium connectors * Base interface for all Brainy premium connectors
* *
* Implementations live in the Quantum Vault (brainy-quantum-vault) * Implementations auto-load with Brain Cloud subscription after auth
*/ */
export interface IConnector { export interface IConnector {
/** Unique connector identifier */ /** Unique connector identifier */

View file

@ -25,25 +25,25 @@ export class DefaultAugmentationRegistry {
async initializeDefaults(): Promise<void> { async initializeDefaults(): Promise<void> {
console.log('🧠⚛️ Initializing default augmentations...') console.log('🧠⚛️ Initializing default augmentations...')
// Register Cortex as default SENSE augmentation // Register Neural Import as default SENSE augmentation
await this.registerCortex() await this.registerNeuralImport()
console.log('🧠⚛️ Default augmentations initialized') console.log('🧠⚛️ Default augmentations initialized')
} }
/** /**
* Cortex - Default SENSE Augmentation * Neural Import - Default SENSE Augmentation
* AI-powered data understanding and entity extraction * AI-powered data understanding and entity extraction (always free)
*/ */
private async registerCortex(): Promise<void> { private async registerNeuralImport(): Promise<void> {
try { try {
// Import the Cortex augmentation // Import the Neural Import augmentation
const { CortexSenseAugmentation } = await import('../augmentations/cortexSense.js') const { NeuralImportAugmentation } = await import('../augmentations/neuralImport.js')
// Note: The actual registration is commented out since BrainyData doesn't have addAugmentation method yet // Note: The actual registration is commented out since BrainyData doesn't have addAugmentation method yet
// This would create instance with default configuration // This would create instance with default configuration
/* /*
const cortex = new CortexSenseAugmentation(this.brainy as any, { const neuralImport = new NeuralImportAugmentation(this.brainy as any, {
confidenceThreshold: 0.7, confidenceThreshold: 0.7,
enableWeights: true, enableWeights: true,
skipDuplicates: true skipDuplicates: true