/** * SONA Integration for V3 Neural Module * * Wraps @ruvector/sona package for V3 usage with: * - Trajectory tracking and verdict judgment * - Pattern extraction and memory distillation * - Sub-0.05ms learning performance target * - Clean TypeScript API with proper types * * @module sona-integration */ import { SonaEngine, type JsSonaConfig, type JsLearnedPattern } from '@ruvector/sona'; import type { Trajectory, TrajectoryStep, TrajectoryVerdict, DistilledMemory, SONAMode, SONAModeConfig, } from './types.js'; // ============================================================================= // Types // ============================================================================= /** * Context for SONA learning adaptation */ export interface Context { /** Task domain */ domain: 'code' | 'creative' | 'reasoning' | 'chat' | 'math' | 'general'; /** Current query embedding */ queryEmbedding: Float32Array; /** Additional context metadata */ metadata?: Record; } /** * Adapted behavior result from SONA */ export interface AdaptedBehavior { /** Transformed query embedding after micro-LoRA */ transformedQuery: Float32Array; /** Similar learned patterns */ patterns: JsLearnedPattern[]; /** Suggested route/model */ suggestedRoute?: string; /** Confidence score */ confidence: number; } /** * SONA engine statistics */ export interface SONAStats { /** Total trajectories recorded */ totalTrajectories: number; /** Patterns learned */ patternsLearned: number; /** Average quality */ avgQuality: number; /** Last learning time (ms) */ lastLearningMs: number; /** Engine enabled state */ enabled: boolean; } // ============================================================================= // Mode Configuration Mapping // ============================================================================= /** * Convert V3 SONA mode to @ruvector/sona config */ function modeToConfig(mode: SONAMode, modeConfig: SONAModeConfig): JsSonaConfig { const baseConfig: JsSonaConfig = { hiddenDim: 768, // Standard transformer dimension embeddingDim: 768, microLoraRank: modeConfig.loraRank <= 2 ? modeConfig.loraRank : 1, baseLoraRank: modeConfig.loraRank, microLoraLr: modeConfig.learningRate, baseLoraLr: modeConfig.learningRate * 0.1, ewcLambda: modeConfig.ewcLambda, patternClusters: modeConfig.patternClusters, trajectoryCapacity: modeConfig.trajectoryCapacity, qualityThreshold: modeConfig.qualityThreshold, enableSimd: true, }; // Mode-specific adjustments switch (mode) { case 'real-time': return { ...baseConfig, microLoraRank: 1, backgroundIntervalMs: 60000, // 1 minute }; case 'edge': return { ...baseConfig, hiddenDim: 384, // Smaller for edge devices embeddingDim: 384, microLoraRank: 1, patternClusters: 25, backgroundIntervalMs: 300000, // 5 minutes }; case 'research': return { ...baseConfig, baseLoraRank: 16, backgroundIntervalMs: 3600000, // 1 hour }; case 'batch': return { ...baseConfig, backgroundIntervalMs: 7200000, // 2 hours }; case 'balanced': default: return { ...baseConfig, backgroundIntervalMs: 1800000, // 30 minutes }; } } // ============================================================================= // SONA Learning Engine // ============================================================================= /** * SONA Learning Engine - wraps @ruvector/sona for V3 usage * * Performance targets: * - learn(): <0.05ms * - adapt(): <0.1ms * - Full learning cycle: <10ms */ export class SONALearningEngine { private engine: SonaEngine; private trajectoryMap: Map = new Map(); private adaptationTimeMs: number = 0; private learningTimeMs: number = 0; private mode: SONAMode; private modeConfig: SONAModeConfig; constructor(mode: SONAMode, modeConfig: SONAModeConfig) { this.mode = mode; this.modeConfig = modeConfig; const config = modeToConfig(mode, modeConfig); this.engine = SonaEngine.withConfig(config); } /** * Learn from a trajectory * * Performance target: <0.05ms * * @param trajectory - Trajectory to learn from */ async learn(trajectory: Trajectory): Promise { const startTime = performance.now(); try { // Begin trajectory recording const queryEmbedding = this.trajectoryToQueryEmbedding(trajectory); const trajectoryId = this.engine.beginTrajectory( Array.from(queryEmbedding) ); // Add trajectory steps for (const step of trajectory.steps) { const activations = this.stateToActivations(step.stateBefore); const attentionWeights = this.stateToAttentionWeights(step.stateAfter); this.engine.addTrajectoryStep( trajectoryId, Array.from(activations), Array.from(attentionWeights), step.reward ); } // Set context if available if (trajectory.domain) { this.engine.addTrajectoryContext(trajectoryId, trajectory.domain); } // Complete trajectory with quality score const quality = this.calculateQuality(trajectory); this.engine.endTrajectory(trajectoryId, quality); // Flush instant updates this.engine.flush(); this.learningTimeMs = performance.now() - startTime; } catch (error) { throw new Error(`SONA learning failed: ${error}`); } } /** * Adapt behavior based on context * * @param context - Current context for adaptation * @returns Adapted behavior with transformed embeddings */ async adapt(context: Context): Promise { const startTime = performance.now(); try { // Apply micro-LoRA transformation const transformedQuery = this.engine.applyMicroLora( Array.from(context.queryEmbedding) ); // Find similar patterns const patterns = this.engine.findPatterns( Array.from(context.queryEmbedding), 5 ); // Determine suggested route from patterns const suggestedRoute = this.inferRoute(patterns, context); const confidence = patterns.length > 0 ? patterns[0].avgQuality : 0.5; this.adaptationTimeMs = performance.now() - startTime; return { transformedQuery: new Float32Array(transformedQuery), patterns, suggestedRoute, confidence, }; } catch (error) { throw new Error(`SONA adaptation failed: ${error}`); } } /** * Get last adaptation time * * @returns Adaptation time in milliseconds */ getAdaptationTime(): number { return this.adaptationTimeMs; } /** * Get last learning time * * @returns Learning time in milliseconds */ getLearningTime(): number { return this.learningTimeMs; } /** * Reset learning state */ resetLearning(): void { // Create a new engine with the same config const config = modeToConfig(this.mode, this.modeConfig); this.engine = SonaEngine.withConfig(config); this.trajectoryMap.clear(); this.adaptationTimeMs = 0; this.learningTimeMs = 0; } /** * Force immediate learning cycle * * @returns Status message */ forceLearning(): string { return this.engine.forceLearn(); } /** * Tick background learning (call periodically) * * @returns Status message if learning occurred */ tick(): string | null { return this.engine.tick(); } /** * Get engine statistics * * @returns SONA engine statistics */ getStats(): SONAStats { const statsJson = this.engine.getStats(); const stats = JSON.parse(statsJson); return { totalTrajectories: stats.total_trajectories || 0, patternsLearned: stats.patterns_learned || 0, avgQuality: stats.avg_quality || 0, lastLearningMs: this.learningTimeMs, enabled: this.engine.isEnabled(), }; } /** * Enable or disable the engine * * @param enabled - Whether to enable the engine */ setEnabled(enabled: boolean): void { this.engine.setEnabled(enabled); } /** * Check if engine is enabled * * @returns Whether the engine is enabled */ isEnabled(): boolean { return this.engine.isEnabled(); } /** * Find learned patterns similar to query * * @param queryEmbedding - Query embedding * @param k - Number of patterns to return * @returns Learned patterns */ findPatterns(queryEmbedding: Float32Array, k: number = 5): JsLearnedPattern[] { return this.engine.findPatterns(Array.from(queryEmbedding), k); } // ============================================================================= // Private Helpers // ============================================================================= /** * Convert trajectory to query embedding */ private trajectoryToQueryEmbedding(trajectory: Trajectory): Float32Array { // Use the first step's state as query if (trajectory.steps.length > 0) { return trajectory.steps[0].stateBefore; } // Fallback to zero embedding return new Float32Array(768); } /** * Convert state embedding to activations */ private stateToActivations(state: Float32Array): Float32Array { // For now, use state directly as activations // In a real implementation, this would extract layer activations return state; } /** * Convert state embedding to attention weights */ private stateToAttentionWeights(state: Float32Array): Float32Array { // For now, use normalized state as attention weights // In a real implementation, this would extract attention patterns const sum = state.reduce((acc, val) => acc + Math.abs(val), 0); if (sum === 0) return state; const weights = new Float32Array(state.length); for (let i = 0; i < state.length; i++) { weights[i] = Math.abs(state[i]) / sum; } return weights; } /** * Calculate quality score for trajectory */ private calculateQuality(trajectory: Trajectory): number { if (trajectory.qualityScore !== undefined) { return trajectory.qualityScore; } // Calculate from steps if (trajectory.steps.length === 0) return 0.5; const avgReward = trajectory.steps.reduce((sum, step) => sum + step.reward, 0) / trajectory.steps.length; // Normalize to [0, 1] return Math.max(0, Math.min(1, (avgReward + 1) / 2)); } /** * Infer suggested route from patterns and context */ private inferRoute(patterns: JsLearnedPattern[], context: Context): string | undefined { if (patterns.length === 0) return undefined; // Use the highest quality pattern's type as route const bestPattern = patterns.reduce((best, pattern) => pattern.avgQuality > best.avgQuality ? pattern : best ); return bestPattern.patternType || `${context.domain}-default`; } } // ============================================================================= // Factory Functions // ============================================================================= /** * Create a SONA learning engine * * @param mode - SONA learning mode * @param modeConfig - Mode configuration * @returns SONA learning engine instance */ export function createSONALearningEngine( mode: SONAMode, modeConfig: SONAModeConfig ): SONALearningEngine { return new SONALearningEngine(mode, modeConfig); } // ============================================================================= // Exports // ============================================================================= export type { JsLearnedPattern, JsSonaConfig };