/** * Universal Display Augmentation - Intelligent Computation Engine * * Leverages existing Brainy AI infrastructure for intelligent field computation: * - BrainyTypes for semantic type detection * - Neural Import patterns for field analysis * - JSON processing utilities for field extraction * - Existing NounType/VerbType taxonomy (31+40 types) */ import type { ComputedDisplayFields, FieldComputationContext, TypeMatchResult, DisplayConfig } from './types.js' import type { VectorDocument, GraphVerb } from '../../coreTypes.js' import { BrainyTypes, getBrainyTypes } from '../typeMatching/brainyTypes.js' import { getNounIcon, getVerbIcon } from './iconMappings.js' import { getFieldPatterns, getPriorityFields, extractFieldValue, calculateFieldConfidence } from './fieldPatterns.js' import { prepareJsonForVectorization, extractFieldFromJson } from '../../utils/jsonProcessing.js' import { NounType, VerbType } from '../../types/graphTypes.js' /** * Intelligent field computation engine * Coordinates AI-powered analysis with fallback heuristics */ export class IntelligentComputationEngine { private typeMatcher: BrainyTypes | null = null protected config: DisplayConfig private initialized = false constructor(config: DisplayConfig) { this.config = config } /** * Initialize the computation engine with AI components */ async initialize(): Promise { if (this.initialized) return try { // 🧠 LEVERAGE YOUR EXISTING AI INFRASTRUCTURE this.typeMatcher = await getBrainyTypes() if (this.typeMatcher) { console.log('🎨 Display computation engine initialized with AI intelligence') } else { console.warn('🎨 Display computation engine running in basic mode (AI unavailable)') } } catch (error) { console.warn('🎨 AI initialization failed, using heuristic fallback:', error) } this.initialized = true } /** * Compute display fields for a noun using AI-first approach * @param data The noun data/metadata * @param id Optional noun ID * @returns Computed display fields */ async computeNounDisplay(data: any, id?: string): Promise { const startTime = Date.now() try { // 🟢 PRIMARY PATH: Use your existing AI intelligence if (this.typeMatcher) { return await this.computeWithAI(data, 'noun', { id }) } // 🟡 FALLBACK PATH: Use heuristic patterns return await this.computeWithHeuristics(data, 'noun', { id }) } catch (error) { console.warn('Display computation failed, using minimal fallback:', error) return this.createMinimalDisplay(data, 'noun') } finally { const computationTime = Date.now() - startTime if (this.config.debugMode) { console.log(`Display computation took ${computationTime}ms`) } } } /** * Compute display fields for a verb using AI-first approach * @param verb The verb/relationship data * @returns Computed display fields */ async computeVerbDisplay(verb: GraphVerb): Promise { const startTime = Date.now() try { // 🟢 PRIMARY PATH: Use your existing AI for verb analysis if (this.typeMatcher) { return await this.computeVerbWithAI(verb) } // 🟡 FALLBACK PATH: Use heuristic patterns for verbs return await this.computeWithHeuristics(verb, 'verb') } catch (error) { console.warn('Verb display computation failed, using minimal fallback:', error) return this.createMinimalDisplay(verb, 'verb') } finally { const computationTime = Date.now() - startTime if (this.config.debugMode) { console.log(`Verb display computation took ${computationTime}ms`) } } } /** * AI-powered computation using your existing BrainyTypes * @param data Entity data/metadata * @param entityType Type of entity (noun/verb) * @param options Additional options * @returns AI-computed display fields */ private async computeWithAI( data: any, entityType: 'noun' | 'verb', options: { id?: string } = {} ): Promise { // 🧠 USE YOUR EXISTING TYPE DETECTION AI const typeResult = await this.typeMatcher!.matchNounType(data) // Create computation context const context: FieldComputationContext = { data, metadata: data, typeResult, config: this.config, entityType } // 🟢 INTELLIGENT FIELD EXTRACTION using your patterns + AI insights const displayFields = { title: await this.computeIntelligentTitle(context), description: await this.computeIntelligentDescription(context), type: typeResult.type, tags: await this.computeIntelligentTags(context), confidence: typeResult.confidence, reasoning: this.config.debugMode ? typeResult.reasoning : undefined, alternatives: this.config.debugMode ? typeResult.alternatives : undefined, computedAt: Date.now(), version: '1.0.0' } return displayFields } /** * AI-powered verb computation using relationship analysis * @param verb The verb/relationship * @returns AI-computed display fields */ private async computeVerbWithAI(verb: GraphVerb): Promise { // 🧠 USE YOUR EXISTING VERB TYPE DETECTION const typeResult = await this.typeMatcher!.matchVerbType(verb, 0.7) // Create verb computation context const context: FieldComputationContext = { data: verb, metadata: verb.metadata || {}, typeResult, config: this.config, entityType: 'verb', verbContext: { sourceId: verb.sourceId, targetId: verb.targetId, verbType: verb.type } } // 🟢 INTELLIGENT VERB DISPLAY COMPUTATION const displayFields = { title: await this.computeVerbTitle(context), description: await this.computeVerbDescription(context), type: typeResult.type, tags: await this.computeVerbTags(context), relationship: await this.computeHumanReadableRelationship(context), confidence: typeResult.confidence, reasoning: this.config.debugMode ? typeResult.reasoning : undefined, alternatives: this.config.debugMode ? typeResult.alternatives : undefined, computedAt: Date.now(), version: '1.0.0' } return displayFields } /** * Heuristic computation when AI is unavailable * @param data Entity data * @param entityType Type of entity * @param options Additional options * @returns Heuristically computed display fields */ private async computeWithHeuristics( data: any, entityType: 'noun' | 'verb', options: { id?: string } = {} ): Promise { // Use basic type detection const detectedType = this.detectTypeHeuristically(data, entityType) const typeResult: TypeMatchResult = { type: detectedType, confidence: 0.6, // Lower confidence for heuristics reasoning: 'Heuristic detection (AI unavailable)', alternatives: [] } const context: FieldComputationContext = { data, metadata: data, typeResult: typeResult, config: this.config, entityType } // Use pattern-based field extraction const patterns = getFieldPatterns(entityType, detectedType) return { title: this.extractFieldWithPatterns(data, patterns, 'title') || 'Untitled', description: this.extractFieldWithPatterns(data, patterns, 'description') || 'No description', type: detectedType, tags: this.extractFieldWithPatterns(data, patterns, 'tags') || [], confidence: typeResult.confidence, reasoning: this.config.debugMode ? typeResult.reasoning : undefined, computedAt: Date.now(), version: '1.0.0' } } /** * Compute intelligent title using AI insights and your field extraction * @param context Computation context with AI results * @returns Computed title */ private async computeIntelligentTitle(context: FieldComputationContext): Promise { const { data, typeResult } = context // 🟢 USE TYPE-SPECIFIC LOGIC based on your NounType taxonomy switch (typeResult?.type) { case NounType.Person: return this.computePersonTitle(data) case NounType.Organization: return this.computeOrganizationTitle(data) case NounType.Project: return this.computeProjectTitle(data) case NounType.Document: return this.computeDocumentTitle(data) default: // 🟢 LEVERAGE YOUR JSON PROCESSING for unknown types return this.extractBestTitle(data, typeResult?.type) } } /** * Compute intelligent description using AI insights and context * @param context Computation context * @returns Enhanced description */ private async computeIntelligentDescription(context: FieldComputationContext): Promise { const { data, typeResult } = context // 🟢 USE YOUR EXISTING JSON PROCESSING for vectorization-quality text const priorityFields = getPriorityFields('noun', typeResult?.type) const enhancedText = prepareJsonForVectorization(data, { priorityFields, includeFieldNames: false, maxDepth: 2 }) // Create context-aware description based on type return this.createContextAwareDescription(data, typeResult, enhancedText) } /** * Compute intelligent tags using type analysis * @param context Computation context * @returns Generated tags array */ private async computeIntelligentTags(context: FieldComputationContext): Promise { const { data, typeResult } = context const tags: string[] = [] // Add type-based tag if (typeResult?.type) { tags.push(typeResult.type.toLowerCase()) } // Extract explicit tags from data const explicitTags = this.extractExplicitTags(data) tags.push(...explicitTags) // Add semantic tags based on AI analysis if (typeResult && this.typeMatcher) { const semanticTags = this.generateSemanticTags(data, typeResult) tags.push(...semanticTags) } // Remove duplicates and return return [...new Set(tags.filter(Boolean))] } /** * Compute verb title (relationship summary) * @param context Verb computation context * @returns Verb title */ private async computeVerbTitle(context: FieldComputationContext): Promise { const { verbContext, typeResult } = context if (!verbContext) return 'Relationship' const { sourceId, targetId } = verbContext const relationshipType = typeResult?.type || 'RelatedTo' // Try to get readable names for source and target // This could be enhanced to actually resolve the entities return `${sourceId} ${this.getReadableVerbPhrase(relationshipType)} ${targetId}` } /** * Create minimal display for error cases * @param data Entity data * @param entityType Entity type * @returns Minimal display fields */ private createMinimalDisplay(data: any, entityType: 'noun' | 'verb'): ComputedDisplayFields { return { title: data.name || data.title || data.id || 'Untitled', description: data.description || data.summary || 'No description available', type: entityType === 'noun' ? 'Item' : 'RelatedTo', tags: [], confidence: 0.1, // Very low confidence for fallback computedAt: Date.now(), version: '1.0.0' } } // Helper methods for specific noun types private computePersonTitle(data: any): string { if (data.firstName && data.lastName) { return `${data.firstName} ${data.lastName}`.trim() } return data.name || data.fullName || data.displayName || data.firstName || data.lastName || 'Person' } private computeOrganizationTitle(data: any): string { return data.name || data.companyName || data.organizationName || data.title || 'Organization' } private computeProjectTitle(data: any): string { return data.name || data.projectName || data.title || data.projectTitle || 'Project' } private computeDocumentTitle(data: any): string { return data.title || data.filename || data.name || data.subject || 'Document' } private extractBestTitle(data: any, type?: string): string { const titleFields = ['name', 'title', 'displayName', 'label', 'subject', 'heading'] for (const field of titleFields) { if (data[field]) return String(data[field]) } return data.id || Object.keys(data)[0] || 'Untitled' } private createContextAwareDescription(data: any, typeResult?: TypeMatchResult, enhancedText?: string): string { // Start with basic description fields const basicDesc = data.description || data.summary || data.about || data.details if (basicDesc) return String(basicDesc) // Use enhanced text from JSON processing if (enhancedText && enhancedText.length > 10) { return enhancedText.substring(0, 200) + (enhancedText.length > 200 ? '...' : '') } // Generate from available fields const parts = [] if (data.role) parts.push(data.role) if (data.company) parts.push(`at ${data.company}`) if (data.location) parts.push(`in ${data.location}`) return parts.length > 0 ? parts.join(' ') : 'No description available' } private extractExplicitTags(data: any): string[] { const tagFields = ['tags', 'keywords', 'labels', 'categories', 'topics'] for (const field of tagFields) { if (data[field]) { if (Array.isArray(data[field])) { return data[field].map(String).filter(Boolean) } if (typeof data[field] === 'string') { return data[field].split(/[,;]\s*|\s+/).filter(Boolean) } } } return [] } private generateSemanticTags(data: any, typeResult: TypeMatchResult): string[] { const tags: string[] = [] // Add confidence-based tags if (typeResult.confidence > 0.9) tags.push('verified') else if (typeResult.confidence < 0.7) tags.push('uncertain') // Add type-specific semantic tags if (data.status) tags.push(String(data.status).toLowerCase()) if (data.priority) tags.push(String(data.priority).toLowerCase()) if (data.category) tags.push(String(data.category).toLowerCase()) return tags } private getReadableVerbPhrase(verbType: string): string { const verbPhrases: Record = { [VerbType.WorksWith]: 'works with', [VerbType.MemberOf]: 'is member of', [VerbType.ReportsTo]: 'reports to', [VerbType.CreatedBy]: 'created by', [VerbType.Owns]: 'owns', [VerbType.LocatedAt]: 'located at', [VerbType.Likes]: 'likes', [VerbType.Follows]: 'follows', [VerbType.Supervises]: 'supervises' } return verbPhrases[verbType] || 'related to' } private async computeVerbDescription(context: FieldComputationContext): Promise { const { data, verbContext, typeResult } = context if (data.description) return String(data.description) // Generate contextual description for relationship if (verbContext && typeResult) { const parts = [] const relationshipPhrase = this.getReadableVerbPhrase(typeResult.type) if (data.role) parts.push(`Role: ${data.role}`) if (data.startDate) parts.push(`Since: ${new Date(data.startDate).toLocaleDateString()}`) if (data.department) parts.push(`Department: ${data.department}`) return parts.length > 0 ? `${relationshipPhrase} - ${parts.join(', ')}` : `${relationshipPhrase} relationship` } return 'Relationship' } private async computeVerbTags(context: FieldComputationContext): Promise { const { data, typeResult } = context const tags = ['relationship'] if (typeResult?.type) { tags.push(typeResult.type.toLowerCase()) } // Add relationship-specific tags if (data.status) tags.push(String(data.status).toLowerCase()) if (data.type) tags.push(String(data.type).toLowerCase()) return [...new Set(tags)] } private async computeHumanReadableRelationship(context: FieldComputationContext): Promise { const { verbContext, typeResult } = context if (!verbContext || !typeResult) return 'Related' const { sourceId, targetId } = verbContext const phrase = this.getReadableVerbPhrase(typeResult.type) return `${sourceId} ${phrase} ${targetId}` } private detectTypeHeuristically(data: any, entityType: 'noun' | 'verb'): string { if (entityType === 'verb') return VerbType.RelatedTo // Basic heuristics for noun types if (data.firstName || data.lastName || data.email) return NounType.Person if (data.companyName || data.organization) return NounType.Organization if (data.filename || data.fileType) return NounType.Document if (data.projectName || data.initiative) return NounType.Project if (data.taskName || data.todo) return NounType.Task if (data.startDate || data.endDate) return NounType.Event return 'Item' // Generic fallback } private extractFieldWithPatterns(data: any, patterns: any[], fieldType: string): any { const relevantPatterns = patterns.filter(p => p.displayField === fieldType) for (const pattern of relevantPatterns) { for (const field of pattern.fields) { if (data[field]) { return pattern.transform ? pattern.transform(data[field], { data, config: this.config } as any) : data[field] } } } return null } /** * Shutdown the computation engine */ async shutdown(): Promise { // Cleanup if needed this.typeMatcher = null this.initialized = false } }