From d2ddbd2613f3f7c5f751938fd299a3b515b12646 Mon Sep 17 00:00:00 2001 From: David Snelling Date: Tue, 27 May 2025 10:08:01 -0700 Subject: [PATCH] Add augmentation pipeline and memory augmentation documentation Introduced an augmentation event pipeline supporting multiple execution modes (e.g., SEQUENTIAL, PARALLEL). Added new Memory Augmentation type for versatile data storage/retrieval (e.g., fileSystem, in-memory, Firestore). Updated `README.md` with pipeline usage, examples, and augmentations reorganization. Included new demo files for augmentation examples. --- README.md | 201 ++++++++-- src/augmentationPipeline.ts | 574 +++++++++++++++++++++++++++ src/examples/augmentationPipeline.ts | 266 +++++++++++++ src/index.ts | 38 ++ src/types/augmentations.ts | 349 +++++++++------- 5 files changed, 1243 insertions(+), 185 deletions(-) create mode 100644 src/augmentationPipeline.ts create mode 100644 src/examples/augmentationPipeline.ts diff --git a/README.md b/README.md index 38b086e5..9368107f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ A vector database that runs in a browser or Node.js and utilizes Origin Private - **TypeScript support**: Fully typed API with generics for metadata types - **Multiple distance functions**: Supports cosine, Euclidean, Manhattan, and dot product distance metrics - **Augmentation system**: Extensible architecture for adding specialized capabilities +- **Memory augmentation**: Store and retrieve data in different formats (fileSystem, in-memory, firestore) - **Graph data model**: Structured representation of entities and relationships ## Installation @@ -197,6 +198,45 @@ interface IWebSocketSupport { Brainy supports several specialized augmentation types: +#### Sense Augmentations + +For processing raw, unstructured data: + +```typescript +interface ISenseAugmentation extends IAugmentation { + processRawData(rawData: Buffer | string, dataType: string): AugmentationResponse<{ + nouns: string[]; + verbs: string[]; + }>; + listenToFeed( + feedUrl: string, + callback: DataCallback<{ nouns: string[]; verbs: string[] }> + ): Promise; +} +``` + +#### Conduit Augmentations + +For establishing data exchange channels: + +```typescript +interface IConduitAugmentation extends IAugmentation { + establishConnection( + targetSystemId: string, + config: Record + ): AugmentationResponse; + readData( + query: Record, + options?: Record + ): AugmentationResponse; + writeData( + data: Record, + options?: Record + ): AugmentationResponse; + monitorStream(streamId: string, callback: DataCallback): Promise; +} +``` + #### Cognition Augmentations For reasoning, inference, and logical operations: @@ -212,20 +252,34 @@ interface ICognitionAugmentation extends IAugmentation { } ``` -#### Sense Augmentations +#### Memory Augmentations -For processing raw, unstructured data: +For storing data in different formats (e.g., fileSystem, in-memory, or firestore): ```typescript -interface ISenseAugmentation extends IAugmentation { - processRawData(rawData: Buffer | string, dataType: string): AugmentationResponse<{ - nouns: string[]; - verbs: string[]; - }>; - listenToFeed( - feedUrl: string, - callback: DataCallback<{ nouns: string[]; verbs: string[] }> - ): Promise; +interface IMemoryAugmentation extends IAugmentation { + storeData( + key: string, + data: unknown, + options?: Record + ): AugmentationResponse; + retrieveData( + key: string, + options?: Record + ): AugmentationResponse; + updateData( + key: string, + data: unknown, + options?: Record + ): AugmentationResponse; + deleteData( + key: string, + options?: Record + ): AugmentationResponse; + listDataKeys( + pattern?: string, + options?: Record + ): AugmentationResponse; } ``` @@ -251,21 +305,6 @@ interface IPerceptionAugmentation extends IAugmentation { } ``` -#### Activation Augmentations - -For triggering actions and generating outputs: - -```typescript -interface IActivationAugmentation extends IAugmentation { - triggerAction( - actionName: string, - parameters?: Record - ): AugmentationResponse; - generateOutput(knowledgeId: string, format: string): AugmentationResponse>; - interactExternal(systemId: string, payload: Record): AugmentationResponse; -} -``` - #### Dialog Augmentations For natural language understanding and generation: @@ -287,28 +326,105 @@ interface IDialogAugmentation extends IAugmentation { } ``` -#### Conduit Augmentations +#### Activation Augmentations -For establishing data exchange channels: +For triggering actions and generating outputs: ```typescript -interface IConduitAugmentation extends IAugmentation { - establishConnection( - targetSystemId: string, - config: Record - ): AugmentationResponse; - readData( - query: Record, - options?: Record +interface IActivationAugmentation extends IAugmentation { + triggerAction( + actionName: string, + parameters?: Record ): AugmentationResponse; - writeData( - data: Record, - options?: Record - ): AugmentationResponse; - monitorStream(streamId: string, callback: DataCallback): Promise; + generateOutput(knowledgeId: string, format: string): AugmentationResponse>; + interactExternal(systemId: string, payload: Record): AugmentationResponse; } ``` +### Augmentation Event Pipeline + +Brainy provides an event pipeline that allows registering and executing multiple augmentations of each type. The pipeline supports different execution modes and provides a flexible way to manage augmentations. + +#### Using the Pipeline + +```typescript +import { augmentationPipeline, ExecutionMode } from '@soulcraft/brainy'; + +// Register augmentations +augmentationPipeline.register(mySenseAugmentation); +augmentationPipeline.register(myConduitAugmentation); +augmentationPipeline.register(myCognitionAugmentation); + +// Initialize all registered augmentations +await augmentationPipeline.initialize(); + +// Execute a sense pipeline +const processingResults = await augmentationPipeline.executeSensePipeline( + 'processRawData', + ['Some raw text data', 'text'], + { mode: ExecutionMode.SEQUENTIAL, stopOnError: true } +); + +// Execute a conduit pipeline +const connectionResults = await augmentationPipeline.executeConduitPipeline( + 'establishConnection', + ['external-system', { apiKey: 'your-api-key' }] +); + +// Execute a cognition pipeline +const reasoningResults = await augmentationPipeline.executeCognitionPipeline( + 'reason', + ['What is the capital of France?', { additionalContext: 'geography' }], + { mode: ExecutionMode.PARALLEL } +); + +// Execute a memory pipeline +const storeResults = await augmentationPipeline.executeMemoryPipeline( + 'storeData', + ['user123', { name: 'John Doe', email: 'john@example.com' }] +); + +const retrieveResults = await augmentationPipeline.executeMemoryPipeline( + 'retrieveData', + ['user123'] +); + +// Shut down all registered augmentations +await augmentationPipeline.shutDown(); +``` + +#### Execution Modes + +The pipeline supports several execution modes: + +- `ExecutionMode.SEQUENTIAL`: Execute augmentations one after another (default) +- `ExecutionMode.PARALLEL`: Execute all augmentations simultaneously +- `ExecutionMode.FIRST_SUCCESS`: Execute augmentations until one succeeds +- `ExecutionMode.FIRST_RESULT`: Execute augmentations until one returns a result + +#### Pipeline Options + +You can configure the pipeline execution with options: + +```typescript +interface PipelineOptions { + mode?: ExecutionMode; // Execution mode (default: SEQUENTIAL) + timeout?: number; // Timeout in milliseconds (default: 30000) + stopOnError?: boolean; // Whether to stop on error (default: false) +} +``` + +#### Creating a Custom Pipeline + +You can create a custom pipeline instance if needed: + +```typescript +import { AugmentationPipeline } from '@soulcraft/brainy'; + +const myPipeline = new AugmentationPipeline(); +myPipeline.register(myCustomAugmentation); +``` + ## Graph Data Model Brainy uses a graph-based data model to represent entities and relationships. This model consists of nouns (nodes) and verbs (edges). @@ -425,6 +541,9 @@ The repository also includes TypeScript examples for Node.js: - `src/examples/basicUsage.ts`: Demonstrates basic vector operations - `src/examples/customStorage.ts`: Shows how to use a custom storage adapter +- `src/examples/augmentationPipeline.ts`: Demonstrates the augmentation pipeline +- `src/examples/webSocketAugmentation.ts`: Shows how to create WebSocket-supporting augmentations +- `src/examples/memoryAugmentation.ts`: Demonstrates memory augmentations for different storage formats ## How It Works diff --git a/src/augmentationPipeline.ts b/src/augmentationPipeline.ts new file mode 100644 index 00000000..4a5a7bd0 --- /dev/null +++ b/src/augmentationPipeline.ts @@ -0,0 +1,574 @@ +/** + * Augmentation Event Pipeline + * + * This module provides a pipeline for managing and executing multiple augmentations + * of each type. It allows registering multiple augmentations and executing them + * in sequence or in parallel. + */ + +import { + BrainyAugmentations, + IAugmentation, + IWebSocketSupport, + AugmentationResponse +} from './types/augmentations.js' + +/** + * Type definitions for the augmentation registry + */ +type AugmentationRegistry = { + sense: BrainyAugmentations.ISenseAugmentation[]; + conduit: BrainyAugmentations.IConduitAugmentation[]; + cognition: BrainyAugmentations.ICognitionAugmentation[]; + memory: BrainyAugmentations.IMemoryAugmentation[]; + perception: BrainyAugmentations.IPerceptionAugmentation[]; + dialog: BrainyAugmentations.IDialogAugmentation[]; + activation: BrainyAugmentations.IActivationAugmentation[]; + webSocket: IWebSocketSupport[]; +} + +/** + * Execution mode for the pipeline + */ +export enum ExecutionMode { + SEQUENTIAL = 'sequential', + PARALLEL = 'parallel', + FIRST_SUCCESS = 'firstSuccess', + FIRST_RESULT = 'firstResult' +} + +/** + * Options for pipeline execution + */ +export interface PipelineOptions { + mode?: ExecutionMode; + timeout?: number; + stopOnError?: boolean; +} + +/** + * Default pipeline options + */ +const DEFAULT_PIPELINE_OPTIONS: PipelineOptions = { + mode: ExecutionMode.SEQUENTIAL, + timeout: 30000, + stopOnError: false +} + +/** + * AugmentationPipeline class + * + * Manages multiple augmentations of each type and provides methods to execute them. + */ +export class AugmentationPipeline { + private registry: AugmentationRegistry = { + sense: [], + conduit: [], + cognition: [], + memory: [], + perception: [], + dialog: [], + activation: [], + webSocket: [] + } + + /** + * Register an augmentation with the pipeline + * + * @param augmentation The augmentation to register + * @returns The pipeline instance for chaining + */ + public register(augmentation: T): AugmentationPipeline { + let registered = false + + // Check for specific augmentation types + if (this.isAugmentationType( + augmentation, + 'processRawData', + 'listenToFeed' + )) { + this.registry.sense.push(augmentation) + registered = true + } else if (this.isAugmentationType( + augmentation, + 'establishConnection', + 'readData', + 'writeData', + 'monitorStream' + )) { + this.registry.conduit.push(augmentation) + registered = true + } else if (this.isAugmentationType( + augmentation, + 'reason', + 'infer', + 'executeLogic' + )) { + this.registry.cognition.push(augmentation) + registered = true + } else if (this.isAugmentationType( + augmentation, + 'storeData', + 'retrieveData', + 'updateData', + 'deleteData', + 'listDataKeys' + )) { + this.registry.memory.push(augmentation) + registered = true + } else if (this.isAugmentationType( + augmentation, + 'interpret', + 'organize', + 'generateVisualization' + )) { + this.registry.perception.push(augmentation) + registered = true + } else if (this.isAugmentationType( + augmentation, + 'processUserInput', + 'generateResponse', + 'manageContext' + )) { + this.registry.dialog.push(augmentation) + registered = true + } else if (this.isAugmentationType( + augmentation, + 'triggerAction', + 'generateOutput', + 'interactExternal' + )) { + this.registry.activation.push(augmentation) + registered = true + } + + // Check if the augmentation supports WebSocket + if (this.isAugmentationType( + augmentation, + 'connectWebSocket', + 'sendWebSocketMessage', + 'onWebSocketMessage', + 'closeWebSocket' + )) { + this.registry.webSocket.push(augmentation as IWebSocketSupport) + registered = true + } + + // If the augmentation wasn't registered as any known type, throw an error + if (!registered) { + throw new Error(`Unknown augmentation type: ${augmentation.name}`) + } + + return this + } + + /** + * Unregister an augmentation from the pipeline + * + * @param augmentationName The name of the augmentation to unregister + * @returns The pipeline instance for chaining + */ + public unregister(augmentationName: string): AugmentationPipeline { + let found = false + + // Remove from all registries + for (const type in this.registry) { + const typedRegistry = this.registry[type as keyof AugmentationRegistry] + const index = typedRegistry.findIndex(aug => aug.name === augmentationName) + + if (index !== -1) { + typedRegistry.splice(index, 1) + found = true + } + } + + return this + } + + /** + * Initialize all registered augmentations + * + * @returns A promise that resolves when all augmentations are initialized + */ + public async initialize(): Promise { + const allAugmentations = this.getAllAugmentations() + + await Promise.all( + allAugmentations.map(augmentation => + augmentation.initialize().catch(error => { + console.error(`Failed to initialize augmentation ${augmentation.name}:`, error) + }) + ) + ) + } + + /** + * Shut down all registered augmentations + * + * @returns A promise that resolves when all augmentations are shut down + */ + public async shutDown(): Promise { + const allAugmentations = this.getAllAugmentations() + + await Promise.all( + allAugmentations.map(augmentation => + augmentation.shutDown().catch(error => { + console.error(`Failed to shut down augmentation ${augmentation.name}:`, error) + }) + ) + ) + } + + /** + * Execute a sense pipeline + * + * @param method The method to execute on each sense augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executeSensePipeline< + M extends keyof BrainyAugmentations.ISenseAugmentation & string, + R extends BrainyAugmentations.ISenseAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.ISenseAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.sense, + method, + args, + opts + ) + } + + /** + * Execute a conduit pipeline + * + * @param method The method to execute on each conduit augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executeConduitPipeline< + M extends keyof BrainyAugmentations.IConduitAugmentation & string, + R extends BrainyAugmentations.IConduitAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.IConduitAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.conduit, + method, + args, + opts + ) + } + + /** + * Execute a cognition pipeline + * + * @param method The method to execute on each cognition augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executeCognitionPipeline< + M extends keyof BrainyAugmentations.ICognitionAugmentation & string, + R extends BrainyAugmentations.ICognitionAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.ICognitionAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.cognition, + method, + args, + opts + ) + } + + /** + * Execute a memory pipeline + * + * @param method The method to execute on each memory augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executeMemoryPipeline< + M extends keyof BrainyAugmentations.IMemoryAugmentation & string, + R extends BrainyAugmentations.IMemoryAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.IMemoryAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.memory, + method, + args, + opts + ) + } + + /** + * Execute a perception pipeline + * + * @param method The method to execute on each perception augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executePerceptionPipeline< + M extends keyof BrainyAugmentations.IPerceptionAugmentation & string, + R extends BrainyAugmentations.IPerceptionAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.IPerceptionAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.perception, + method, + args, + opts + ) + } + + /** + * Execute a dialog pipeline + * + * @param method The method to execute on each dialog augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executeDialogPipeline< + M extends keyof BrainyAugmentations.IDialogAugmentation & string, + R extends BrainyAugmentations.IDialogAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.IDialogAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.dialog, + method, + args, + opts + ) + } + + /** + * Execute an activation pipeline + * + * @param method The method to execute on each activation augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + public async executeActivationPipeline< + M extends keyof BrainyAugmentations.IActivationAugmentation & string, + R extends BrainyAugmentations.IActivationAugmentation[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + method: M & (BrainyAugmentations.IActivationAugmentation[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions = {} + ): Promise[]> { + const opts = { ...DEFAULT_PIPELINE_OPTIONS, ...options } + return this.executeTypedPipeline( + this.registry.activation, + method, + args, + opts + ) + } + + /** + * Get all registered augmentations + * + * @returns An array of all registered augmentations + */ + private getAllAugmentations(): IAugmentation[] { + // Create a Set to avoid duplicates (an augmentation might be in multiple registries) + const allAugmentations = new Set([ + ...this.registry.sense, + ...this.registry.conduit, + ...this.registry.cognition, + ...this.registry.memory, + ...this.registry.perception, + ...this.registry.dialog, + ...this.registry.activation, + ...this.registry.webSocket + ]) + + // Convert back to array + return Array.from(allAugmentations) + } + + /** + * Get all WebSocket-supporting augmentations + * + * @returns An array of all augmentations that support WebSocket connections + */ + public getWebSocketAugmentations(): IWebSocketSupport[] { + return [...this.registry.webSocket] + } + + /** + * Check if an augmentation is of a specific type + * + * @param augmentation The augmentation to check + * @param methods The methods that should be present on the augmentation + * @returns True if the augmentation is of the specified type + */ + private isAugmentationType( + augmentation: IAugmentation, + ...methods: (keyof T)[] + ): augmentation is T { + // First check that the augmentation has all the required base methods + const baseMethodsExist = [ + 'initialize', + 'shutDown', + 'getStatus' + ].every(method => typeof (augmentation as any)[method] === 'function') + + if (!baseMethodsExist) { + return false + } + + // Then check that it has all the specific methods for this type + return methods.every(method => typeof (augmentation as any)[method] === 'function') + } + + /** + * Execute a pipeline for a specific augmentation type + * + * @param augmentations The augmentations to execute + * @param method The method to execute on each augmentation + * @param args The arguments to pass to the method + * @param options The pipeline execution options + * @returns A promise that resolves with the results from all augmentations + */ + private async executeTypedPipeline< + T extends IAugmentation, + M extends keyof T & string, + R extends T[M] extends (...args: any[]) => AugmentationResponse ? U : never + >( + augmentations: T[], + method: M & (T[M] extends (...args: any[]) => any ? M : never), + args: Parameters any>>, + options: PipelineOptions + ): Promise[]> { + if (augmentations.length === 0) { + return [] + } + + // Create a function to execute the method on an augmentation + const executeMethod = async (augmentation: T): Promise<{ + success: boolean + data: R + error?: string + }> => { + try { + // Create a timeout promise if a timeout is specified + const timeoutPromise = options.timeout + ? new Promise<{ + success: boolean + data: R + error?: string + }>((_, reject) => { + setTimeout(() => { + reject(new Error(`Timeout executing ${String(method)} on ${augmentation.name}`)) + }, options.timeout) + }) + : null + + // Execute the method on the augmentation + const methodPromise = (augmentation[method] as Function)(...args) as AugmentationResponse + + // Race the method promise against the timeout promise if a timeout is specified + const result = timeoutPromise + ? await Promise.race([methodPromise, timeoutPromise]) + : await methodPromise + + return result + } catch (error) { + console.error(`Error executing ${String(method)} on ${augmentation.name}:`, error) + return { + success: false, + data: null as unknown as R, + error: error instanceof Error ? error.message : String(error) + } + } + } + + // Execute the pipeline based on the specified mode + switch (options.mode) { + case ExecutionMode.PARALLEL: + // Execute all augmentations in parallel + return augmentations.map(executeMethod) + + case ExecutionMode.FIRST_SUCCESS: + // Execute augmentations sequentially until one succeeds + for (const augmentation of augmentations) { + const resultPromise = executeMethod(augmentation) + const result = await resultPromise + if (result.success) { + return [resultPromise] + } + } + return [] + + case ExecutionMode.FIRST_RESULT: + // Execute augmentations sequentially until one returns a result + for (const augmentation of augmentations) { + const resultPromise = executeMethod(augmentation) + const result = await resultPromise + if (result.success && result.data) { + return [resultPromise] + } + } + return [] + + case ExecutionMode.SEQUENTIAL: + default: + // Execute augmentations sequentially + const results: Promise<{ + success: boolean + data: R + error?: string + }>[] = [] + for (const augmentation of augmentations) { + const resultPromise = executeMethod(augmentation) + results.push(resultPromise) + + // Check if we need to stop on error + if (options.stopOnError) { + const result = await resultPromise + if (!result.success) { + break + } + } + } + return results + } + } +} + +// Create and export a default instance of the pipeline +export const augmentationPipeline = new AugmentationPipeline() diff --git a/src/examples/augmentationPipeline.ts b/src/examples/augmentationPipeline.ts new file mode 100644 index 00000000..48a91024 --- /dev/null +++ b/src/examples/augmentationPipeline.ts @@ -0,0 +1,266 @@ +/** + * Augmentation Pipeline Example + * + * This example demonstrates how to use the augmentation pipeline to register + * and execute multiple augmentations of each type. + */ + +import { + augmentationPipeline, + ExecutionMode, + PipelineOptions, + IAugmentation, + AugmentationResponse, + BrainyAugmentations +} from '../index.js' + +/** + * Example Cognition Augmentation + */ +class SimpleCognitionAugmentation implements BrainyAugmentations.ICognitionAugmentation { + readonly name = 'simple-cognition' + readonly description = 'A simple cognition augmentation for demonstration' + + async initialize(): Promise { + console.log('Initializing SimpleCognitionAugmentation') + } + + async shutDown(): Promise { + console.log('Shutting down SimpleCognitionAugmentation') + } + + async getStatus(): Promise<'active' | 'inactive' | 'error'> { + return 'active' + } + + async reason( + query: string, + context?: Record + ): Promise> { + console.log(`SimpleCognitionAugmentation reasoning about: ${query}`) + console.log('Context:', context) + + return { + success: true, + data: { + inference: `Simple inference about: ${query}`, + confidence: 0.7 + } + } + } + + async infer( + dataSubset: Record + ): Promise>> { + return { + success: true, + data: { + result: `Inferred from data: ${JSON.stringify(dataSubset)}` + } + } + } + + async executeLogic( + ruleId: string, + input: Record + ): Promise> { + return { + success: true, + data: true + } + } +} + +/** + * Another Example Cognition Augmentation + */ +class AdvancedCognitionAugmentation implements BrainyAugmentations.ICognitionAugmentation { + readonly name = 'advanced-cognition' + readonly description = 'A more advanced cognition augmentation for demonstration' + + async initialize(): Promise { + console.log('Initializing AdvancedCognitionAugmentation') + } + + async shutDown(): Promise { + console.log('Shutting down AdvancedCognitionAugmentation') + } + + async getStatus(): Promise<'active' | 'inactive' | 'error'> { + return 'active' + } + + async reason( + query: string, + context?: Record + ): Promise> { + console.log(`AdvancedCognitionAugmentation reasoning about: ${query}`) + console.log('Context:', context) + + return { + success: true, + data: { + inference: `Advanced inference about: ${query} with detailed analysis`, + confidence: 0.9 + } + } + } + + async infer( + dataSubset: Record + ): Promise>> { + return { + success: true, + data: { + result: `Advanced inference from data: ${JSON.stringify(dataSubset)}`, + additionalInsights: ['insight1', 'insight2'] + } + } + } + + async executeLogic( + ruleId: string, + input: Record + ): Promise> { + return { + success: true, + data: true + } + } +} + +/** + * Example Sense Augmentation + */ +class SimpleSenseAugmentation implements BrainyAugmentations.ISenseAugmentation { + readonly name = 'simple-sense' + readonly description = 'A simple sense augmentation for demonstration' + + async initialize(): Promise { + console.log('Initializing SimpleSenseAugmentation') + } + + async shutDown(): Promise { + console.log('Shutting down SimpleSenseAugmentation') + } + + async getStatus(): Promise<'active' | 'inactive' | 'error'> { + return 'active' + } + + async processRawData( + rawData: Buffer | string, + dataType: string + ): Promise> { + console.log(`SimpleSenseAugmentation processing ${dataType} data:`, + typeof rawData === 'string' ? rawData : 'Buffer data') + + return { + success: true, + data: { + nouns: ['example', 'data', 'processing'], + verbs: ['process', 'analyze', 'extract'] + } + } + } + + async listenToFeed( + feedUrl: string, + callback: (data: { nouns: string[]; verbs: string[] }) => void + ): Promise { + console.log(`SimpleSenseAugmentation listening to feed: ${feedUrl}`) + // In a real implementation, this would set up a listener + } +} + +/** + * Main function to demonstrate the augmentation pipeline + */ +async function main() { + try { + console.log('=== Augmentation Pipeline Example ===') + + // Create augmentation instances + const simpleCognition = new SimpleCognitionAugmentation() + const advancedCognition = new AdvancedCognitionAugmentation() + const simpleSense = new SimpleSenseAugmentation() + + // Register augmentations with the pipeline + augmentationPipeline + .register(simpleCognition) + .register(advancedCognition) + .register(simpleSense) + + // Initialize all registered augmentations + console.log('\n=== Initializing Augmentations ===') + await augmentationPipeline.initialize() + + // Execute a cognition pipeline in sequential mode (default) + console.log('\n=== Executing Cognition Pipeline (Sequential) ===') + const reasoningResults = await augmentationPipeline.executeCognitionPipeline( + 'reason', + ['What is the capital of France?', { additionalContext: 'geography' }] + ) + + console.log('\nReasoning Results:') + reasoningResults.forEach((result, index) => { + console.log(`Result ${index + 1}:`) + console.log(` Success: ${result.success}`) + if (result.success) { + console.log(` Inference: ${result.data.inference}`) + console.log(` Confidence: ${result.data.confidence}`) + } else { + console.log(` Error: ${result.error}`) + } + }) + + // Execute a cognition pipeline in parallel mode + console.log('\n=== Executing Cognition Pipeline (Parallel) ===') + const inferResults = await augmentationPipeline.executeCognitionPipeline( + 'infer', + [{ topic: 'climate change', data: [1, 2, 3] }], + { mode: ExecutionMode.PARALLEL } + ) + + console.log('\nInference Results:') + inferResults.forEach((result, index) => { + console.log(`Result ${index + 1}:`) + console.log(` Success: ${result.success}`) + if (result.success) { + console.log(` Data: ${JSON.stringify(result.data)}`) + } else { + console.log(` Error: ${result.error}`) + } + }) + + // Execute a sense pipeline + console.log('\n=== Executing Sense Pipeline ===') + const processingResults = await augmentationPipeline.executeSensePipeline( + 'processRawData', + ['This is some example text to process', 'text'] + ) + + console.log('\nProcessing Results:') + processingResults.forEach((result, index) => { + console.log(`Result ${index + 1}:`) + console.log(` Success: ${result.success}`) + if (result.success) { + console.log(` Nouns: ${result.data.nouns.join(', ')}`) + console.log(` Verbs: ${result.data.verbs.join(', ')}`) + } else { + console.log(` Error: ${result.error}`) + } + }) + + // Shut down all registered augmentations + console.log('\n=== Shutting Down Augmentations ===') + await augmentationPipeline.shutDown() + + console.log('\n=== Example Complete ===') + } catch (error) { + console.error('Error in augmentation pipeline example:', error) + } +} + +// Run the example +main() diff --git a/src/index.ts b/src/index.ts index 7b99b2bc..f3236276 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,6 +34,20 @@ export { createStorage } +// Export augmentation pipeline +import { + AugmentationPipeline, + augmentationPipeline, + ExecutionMode, + PipelineOptions +} from './augmentationPipeline.js' +export { + AugmentationPipeline, + augmentationPipeline, + ExecutionMode +} +export type { PipelineOptions } + // Export types import type { Vector, @@ -59,3 +73,27 @@ export type { HNSWConfig, StorageAdapter } + +// Export augmentation types +import type { + IAugmentation, + AugmentationResponse, + IWebSocketSupport +} from './types/augmentations.js' +export type { + IAugmentation, + AugmentationResponse, + IWebSocketSupport +} +export { BrainyAugmentations } from './types/augmentations.js' + +// Export combined WebSocket augmentation interfaces +export type { + IWebSocketCognitionAugmentation, + IWebSocketSenseAugmentation, + IWebSocketPerceptionAugmentation, + IWebSocketActivationAugmentation, + IWebSocketDialogAugmentation, + IWebSocketConduitAugmentation, + IWebSocketMemoryAugmentation +} from './types/augmentations.js' diff --git a/src/types/augmentations.ts b/src/types/augmentations.ts index 4a3f5fe2..22632652 100644 --- a/src/types/augmentations.ts +++ b/src/types/augmentations.ts @@ -6,7 +6,7 @@ type WebSocketConnection = { } type DataCallback = (data: T) => void -type AugmentationResponse = Promise<{ +export type AugmentationResponse = Promise<{ success: boolean data: T error?: string @@ -16,7 +16,7 @@ type AugmentationResponse = Promise<{ * Base interface for all Brainy augmentations. * All augmentations must implement these core properties. */ -interface IAugmentation { +export interface IAugmentation { /** A unique identifier for the augmentation (e.g., "my-reasoner-v1") */ readonly name: string /** A human-readable description of the augmentation's purpose */ @@ -37,7 +37,7 @@ interface IAugmentation { * Interface for WebSocket support. * Augmentations that implement this interface can communicate via WebSockets. */ -interface IWebSocketSupport { +export interface IWebSocketSupport extends IAugmentation { /** * Establishes a WebSocket connection. * @param url The WebSocket server URL to connect to @@ -69,36 +69,7 @@ interface IWebSocketSupport { closeWebSocket(connectionId: string, code?: number, reason?: string): Promise } -namespace BrainyAugmentations { - /** - * Interface for Cognitions augmentations. - * These augmentations enable advanced reasoning, inference, and logical operations. - */ - export interface ICognitionAugmentation extends IAugmentation { - /** - * Performs a reasoning operation based on current knowledge. - * @param query The specific reasoning task or question - * @param context Optional additional context for the reasoning - */ - reason(query: string, context?: Record): AugmentationResponse<{ - inference: string - confidence: number - }> - - /** - * Infers relationships or new facts from existing data. - * @param dataSubset A subset of data to infer from - */ - infer(dataSubset: Record): AugmentationResponse> - - /** - * Executes a logical operation or rule set. - * @param ruleId The identifier of the rule or logic to apply - * @param input Data to apply the logic to - */ - executeLogic(ruleId: string, input: Record): AugmentationResponse - } - +export namespace BrainyAugmentations { /** * Interface for Senses augmentations. * These augmentations ingest and process raw, unstructured data into nouns and verbs. @@ -125,111 +96,6 @@ namespace BrainyAugmentations { ): Promise } - /** - * Interface for Perceptions augmentations. - * These augmentations interpret, contextualize, and visualize identified nouns and verbs. - */ - export interface IPerceptionAugmentation extends IAugmentation { - /** - * Interprets and contextualizes processed nouns and verbs. - * @param nouns The list of identified nouns - * @param verbs The list of identified verbs - * @param context Optional additional context for interpretation - */ - interpret( - nouns: string[], - verbs: string[], - context?: Record - ): AugmentationResponse> - - /** - * Organizes and filters information. - * @param data The data to organize (e.g., interpreted perceptions) - * @param criteria Optional criteria for filtering/prioritization - */ - organize( - data: Record, - criteria?: Record - ): AugmentationResponse> - - /** - * Generates a visualization based on the provided data. - * @param data The data to visualize (e.g., interpreted patterns) - * @param visualizationType The desired type of visualization (e.g., 'graph', 'chart') - */ - generateVisualization( - data: Record, - visualizationType: string - ): AugmentationResponse> - } - - /** - * Interface for Activations augmentations. - * These augmentations dictate how Brainy initiates actions, responses, or data manipulations. - */ - export interface IActivationAugmentation extends IAugmentation { - /** - * Triggers an action based on a processed command or internal state. - * @param actionName The name of the action to trigger - * @param parameters Optional parameters for the action - */ - triggerAction( - actionName: string, - parameters?: Record - ): AugmentationResponse - - /** - * Generates an expressive output or response from Brainy. - * @param knowledgeId The identifier of the knowledge to express - * @param format The desired output format (e.g., 'text', 'json') - */ - generateOutput(knowledgeId: string, format: string): AugmentationResponse> - - /** - * Interacts with an external system or API. - * @param systemId The identifier of the external system - * @param payload The data to send to the external system - */ - interactExternal(systemId: string, payload: Record): AugmentationResponse - } - - /** - * Interface for Dialogs augmentations. - * These augmentations facilitate natural language understanding and generation for conversational interaction. - */ - export interface IDialogAugmentation extends IAugmentation { - /** - * Processes a user's natural language input (query). - * @param naturalLanguageQuery The raw text query from the user - * @param sessionId An optional session ID for conversational context - */ - processUserInput(naturalLanguageQuery: string, sessionId?: string): AugmentationResponse<{ - intent: string - nouns: string[] - verbs: string[] - context: Record - }> - - /** - * Generates a natural language response based on Brainy's knowledge and interpreted input. - * @param interpretedInput The output from `processUserInput` or similar - * @param knowledgeContext Relevant knowledge retrieved from Brainy - * @param sessionId An optional session ID for conversational context - */ - generateResponse( - interpretedInput: Record, - knowledgeContext: Record, - sessionId?: string - ): AugmentationResponse - - /** - * Manages and updates conversational context. - * @param sessionId The session ID - * @param contextUpdate The data to update the context with - */ - manageContext(sessionId: string, contextUpdate: Record): Promise - } - /** * Interface for Conduits augmentations. * These augmentations establish and manage high-bandwidth, dedicated channels for structured, programmatic two-way data exchange. @@ -272,12 +138,207 @@ namespace BrainyAugmentations { */ monitorStream(streamId: string, callback: DataCallback): Promise } + + /** + * Interface for Cognitions augmentations. + * These augmentations enable advanced reasoning, inference, and logical operations. + */ + export interface ICognitionAugmentation extends IAugmentation { + /** + * Performs a reasoning operation based on current knowledge. + * @param query The specific reasoning task or question + * @param context Optional additional context for the reasoning + */ + reason(query: string, context?: Record): AugmentationResponse<{ + inference: string + confidence: number + }> + + /** + * Infers relationships or new facts from existing data. + * @param dataSubset A subset of data to infer from + */ + infer(dataSubset: Record): AugmentationResponse> + + /** + * Executes a logical operation or rule set. + * @param ruleId The identifier of the rule or logic to apply + * @param input Data to apply the logic to + */ + executeLogic(ruleId: string, input: Record): AugmentationResponse + } + + /** + * Interface for Memory augmentations. + * These augmentations provide storage capabilities for data in different formats (e.g., fileSystem, in-memory, or firestore). + */ + export interface IMemoryAugmentation extends IAugmentation { + /** + * Stores data in the memory system. + * @param key The unique identifier for the data + * @param data The data to store + * @param options Optional storage options (e.g., expiration, format) + */ + storeData( + key: string, + data: unknown, + options?: Record + ): AugmentationResponse + + /** + * Retrieves data from the memory system. + * @param key The unique identifier for the data + * @param options Optional retrieval options (e.g., format, version) + */ + retrieveData( + key: string, + options?: Record + ): AugmentationResponse + + /** + * Updates existing data in the memory system. + * @param key The unique identifier for the data + * @param data The updated data + * @param options Optional update options (e.g., merge, overwrite) + */ + updateData( + key: string, + data: unknown, + options?: Record + ): AugmentationResponse + + /** + * Deletes data from the memory system. + * @param key The unique identifier for the data + * @param options Optional deletion options + */ + deleteData( + key: string, + options?: Record + ): AugmentationResponse + + /** + * Lists available data keys in the memory system. + * @param pattern Optional pattern to filter keys (e.g., prefix, regex) + * @param options Optional listing options (e.g., limit, offset) + */ + listDataKeys( + pattern?: string, + options?: Record + ): AugmentationResponse + } + + /** + * Interface for Perceptions augmentations. + * These augmentations interpret, contextualize, and visualize identified nouns and verbs. + */ + export interface IPerceptionAugmentation extends IAugmentation { + /** + * Interprets and contextualizes processed nouns and verbs. + * @param nouns The list of identified nouns + * @param verbs The list of identified verbs + * @param context Optional additional context for interpretation + */ + interpret( + nouns: string[], + verbs: string[], + context?: Record + ): AugmentationResponse> + + /** + * Organizes and filters information. + * @param data The data to organize (e.g., interpreted perceptions) + * @param criteria Optional criteria for filtering/prioritization + */ + organize( + data: Record, + criteria?: Record + ): AugmentationResponse> + + /** + * Generates a visualization based on the provided data. + * @param data The data to visualize (e.g., interpreted patterns) + * @param visualizationType The desired type of visualization (e.g., 'graph', 'chart') + */ + generateVisualization( + data: Record, + visualizationType: string + ): AugmentationResponse> + } + + /** + * Interface for Dialogs augmentations. + * These augmentations facilitate natural language understanding and generation for conversational interaction. + */ + export interface IDialogAugmentation extends IAugmentation { + /** + * Processes a user's natural language input (query). + * @param naturalLanguageQuery The raw text query from the user + * @param sessionId An optional session ID for conversational context + */ + processUserInput(naturalLanguageQuery: string, sessionId?: string): AugmentationResponse<{ + intent: string + nouns: string[] + verbs: string[] + context: Record + }> + + /** + * Generates a natural language response based on Brainy's knowledge and interpreted input. + * @param interpretedInput The output from `processUserInput` or similar + * @param knowledgeContext Relevant knowledge retrieved from Brainy + * @param sessionId An optional session ID for conversational context + */ + generateResponse( + interpretedInput: Record, + knowledgeContext: Record, + sessionId?: string + ): AugmentationResponse + + /** + * Manages and updates conversational context. + * @param sessionId The session ID + * @param contextUpdate The data to update the context with + */ + manageContext(sessionId: string, contextUpdate: Record): Promise + } + + /** + * Interface for Activations augmentations. + * These augmentations dictate how Brainy initiates actions, responses, or data manipulations. + */ + export interface IActivationAugmentation extends IAugmentation { + /** + * Triggers an action based on a processed command or internal state. + * @param actionName The name of the action to trigger + * @param parameters Optional parameters for the action + */ + triggerAction( + actionName: string, + parameters?: Record + ): AugmentationResponse + + /** + * Generates an expressive output or response from Brainy. + * @param knowledgeId The identifier of the knowledge to express + * @param format The desired output format (e.g., 'text', 'json') + */ + generateOutput(knowledgeId: string, format: string): AugmentationResponse> + + /** + * Interacts with an external system or API. + * @param systemId The identifier of the external system + * @param payload The data to send to the external system + */ + interactExternal(systemId: string, payload: Record): AugmentationResponse + } } /** WebSocket-enabled augmentation interfaces */ -type IWebSocketCognitionAugmentation = BrainyAugmentations.ICognitionAugmentation & IWebSocketSupport -type IWebSocketSenseAugmentation = BrainyAugmentations.ISenseAugmentation & IWebSocketSupport -type IWebSocketPerceptionAugmentation = BrainyAugmentations.IPerceptionAugmentation & IWebSocketSupport -type IWebSocketActivationAugmentation = BrainyAugmentations.IActivationAugmentation & IWebSocketSupport -type IWebSocketDialogAugmentation = BrainyAugmentations.IDialogAugmentation & IWebSocketSupport -type IWebSocketConduitAugmentation = BrainyAugmentations.IConduitAugmentation & IWebSocketSupport +export type IWebSocketSenseAugmentation = BrainyAugmentations.ISenseAugmentation & IWebSocketSupport +export type IWebSocketConduitAugmentation = BrainyAugmentations.IConduitAugmentation & IWebSocketSupport +export type IWebSocketCognitionAugmentation = BrainyAugmentations.ICognitionAugmentation & IWebSocketSupport +export type IWebSocketMemoryAugmentation = BrainyAugmentations.IMemoryAugmentation & IWebSocketSupport +export type IWebSocketPerceptionAugmentation = BrainyAugmentations.IPerceptionAugmentation & IWebSocketSupport +export type IWebSocketDialogAugmentation = BrainyAugmentations.IDialogAugmentation & IWebSocketSupport +export type IWebSocketActivationAugmentation = BrainyAugmentations.IActivationAugmentation & IWebSocketSupport