/** * Universal Display Augmentation - Smart Field Patterns * * Intelligent field detection patterns for mapping user data to display fields * Uses semantic understanding and common naming conventions */ import { NounType } from '../../types/graphTypes.js'; /** * Universal field patterns that work across all data types * Ordered by confidence level (highest first) */ export const UNIVERSAL_FIELD_PATTERNS = [ // Title/Name Patterns (Highest Priority) { fields: ['name', 'title', 'displayName', 'label', 'heading'], displayField: 'title', confidence: 0.95 }, { fields: ['firstName', 'lastName', 'fullName', 'realName'], displayField: 'title', confidence: 0.9, applicableTypes: [NounType.Person, NounType.User], transform: (value, context) => { const { metadata } = context; if (metadata.firstName && metadata.lastName) { return `${metadata.firstName} ${metadata.lastName}`.trim(); } return String(value || ''); } }, { fields: ['companyName', 'organizationName', 'orgName', 'businessName'], displayField: 'title', confidence: 0.9, applicableTypes: [NounType.Organization] }, { fields: ['filename', 'fileName', 'documentTitle', 'docName'], displayField: 'title', confidence: 0.85, applicableTypes: [NounType.Document, NounType.File, NounType.Media] }, { fields: ['projectName', 'projectTitle', 'initiative'], displayField: 'title', confidence: 0.9, applicableTypes: [NounType.Project] }, { fields: ['taskName', 'taskTitle', 'action', 'todo'], displayField: 'title', confidence: 0.85, applicableTypes: [NounType.Task] }, { fields: ['subject', 'topic', 'headline', 'caption'], displayField: 'title', confidence: 0.8 }, // Description Patterns (High Priority) { fields: ['description', 'summary', 'overview', 'details'], displayField: 'description', confidence: 0.9 }, { fields: ['bio', 'biography', 'profile', 'about'], displayField: 'description', confidence: 0.85, applicableTypes: [NounType.Person, NounType.User] }, { fields: ['content', 'text', 'body', 'message'], displayField: 'description', confidence: 0.8 }, { fields: ['abstract', 'excerpt', 'snippet', 'preview'], displayField: 'description', confidence: 0.75 }, { fields: ['notes', 'comments', 'remarks', 'observations'], displayField: 'description', confidence: 0.7 }, // Type Patterns (Medium Priority) { fields: ['type', 'category', 'classification', 'kind'], displayField: 'type', confidence: 0.9 }, { fields: ['nounType', 'entityType', 'objectType'], displayField: 'type', confidence: 0.95 }, { fields: ['role', 'position', 'jobTitle', 'occupation'], displayField: 'type', confidence: 0.8, applicableTypes: [NounType.Person, NounType.User], transform: (value) => String(value || 'Person') }, { fields: ['industry', 'sector', 'domain', 'field'], displayField: 'type', confidence: 0.7, applicableTypes: [NounType.Organization] }, // Tag Patterns (Medium Priority) { fields: ['tags', 'keywords', 'labels', 'categories'], displayField: 'tags', confidence: 0.85 }, { fields: ['topics', 'subjects', 'themes'], displayField: 'tags', confidence: 0.8 } ]; /** * Type-specific field patterns for enhanced detection * Used when we know the specific type of the entity */ export const TYPE_SPECIFIC_PATTERNS = { [NounType.Person]: [ { fields: ['email', 'emailAddress', 'contactEmail'], displayField: 'description', confidence: 0.7, transform: (value, context) => { const { metadata } = context; const role = metadata.role || metadata.jobTitle || metadata.position; const company = metadata.company || metadata.organization || metadata.employer; const parts = []; if (role) parts.push(role); if (company) parts.push(`at ${company}`); if (parts.length === 0 && value) parts.push(`Contact: ${value}`); return parts.join(' ') || 'Person'; } }, { fields: ['phone', 'phoneNumber', 'mobile', 'cell'], displayField: 'tags', confidence: 0.6 } ], [NounType.Organization]: [ { fields: ['website', 'url', 'homepage', 'domain'], displayField: 'description', confidence: 0.7, transform: (value, context) => { const { metadata } = context; const industry = metadata.industry || metadata.sector; const location = metadata.location || metadata.city || metadata.country; const parts = []; if (industry) parts.push(industry); parts.push('organization'); if (location) parts.push(`in ${location}`); return parts.join(' '); } }, { fields: ['employees', 'size', 'headcount'], displayField: 'tags', confidence: 0.6 } ], [NounType.Project]: [ { fields: ['status', 'phase', 'stage', 'state'], displayField: 'description', confidence: 0.8, transform: (value, context) => { const { metadata } = context; const status = String(value || 'active').toLowerCase(); const budget = metadata.budget || metadata.cost; const lead = metadata.lead || metadata.manager || metadata.owner; const parts = []; parts.push(status.charAt(0).toUpperCase() + status.slice(1)); if (metadata.description) parts.push('project'); if (lead) parts.push(`led by ${lead}`); if (budget) parts.push(`($${parseInt(String(budget)).toLocaleString()} budget)`); return parts.join(' '); } } ], [NounType.Document]: [ { fields: ['author', 'creator', 'writer'], displayField: 'description', confidence: 0.7, transform: (value, context) => { const { metadata } = context; const docType = metadata.type || metadata.category || 'document'; const date = metadata.date || metadata.created || metadata.published; const parts = []; if (docType) parts.push(docType); if (value) parts.push(`by ${value}`); if (date) { const dateStr = new Date(date).toLocaleDateString(); parts.push(`(${dateStr})`); } return parts.join(' '); } } ], [NounType.Task]: [ { fields: ['priority', 'urgency', 'importance'], displayField: 'tags', confidence: 0.7 } ] }; /** * Get field patterns for a specific entity type * @param entityType The type of entity (noun or verb) * @param specificType Optional specific noun/verb type * @returns Array of applicable field patterns */ export function getFieldPatterns(entityType, specificType) { const patterns = [...UNIVERSAL_FIELD_PATTERNS]; if (entityType === 'noun' && specificType && TYPE_SPECIFIC_PATTERNS[specificType]) { patterns.unshift(...TYPE_SPECIFIC_PATTERNS[specificType]); } return patterns.sort((a, b) => b.confidence - a.confidence); } /** * Priority fields for different entity types (for AI analysis) * Used by the BrainyTypes and neural processing */ export const TYPE_PRIORITY_FIELDS = { [NounType.Person]: [ 'name', 'firstName', 'lastName', 'fullName', 'displayName', 'email', 'role', 'jobTitle', 'position', 'title', 'bio', 'description', 'about', 'profile', 'company', 'organization', 'employer' ], [NounType.Organization]: [ 'name', 'companyName', 'organizationName', 'title', 'industry', 'sector', 'domain', 'type', 'description', 'about', 'summary', 'location', 'city', 'country', 'headquarters', 'website', 'url' ], [NounType.Project]: [ 'name', 'projectName', 'title', 'projectTitle', 'description', 'summary', 'overview', 'goal', 'status', 'phase', 'stage', 'state', 'lead', 'manager', 'owner', 'team', 'budget', 'timeline', 'deadline' ], [NounType.Document]: [ 'title', 'filename', 'name', 'subject', 'content', 'text', 'body', 'summary', 'author', 'creator', 'writer', 'type', 'category', 'format', 'date', 'created', 'published' ], [NounType.Task]: [ 'title', 'name', 'taskName', 'action', 'description', 'details', 'notes', 'status', 'state', 'priority', 'assignee', 'owner', 'responsible', 'due', 'deadline', 'dueDate' ], [NounType.Event]: [ 'name', 'title', 'eventName', 'description', 'details', 'summary', 'startDate', 'endDate', 'date', 'time', 'location', 'venue', 'address', 'organizer', 'host', 'creator' ], [NounType.Product]: [ 'name', 'productName', 'title', 'description', 'summary', 'features', 'price', 'cost', 'value', 'category', 'type', 'brand', 'manufacturer', 'vendor' ] }; /** * Get priority fields for intelligent analysis * @param entityType The type of entity * @param specificType Optional specific type * @returns Array of priority field names */ export function getPriorityFields(entityType, specificType) { if (entityType === 'noun' && specificType && TYPE_PRIORITY_FIELDS[specificType]) { return TYPE_PRIORITY_FIELDS[specificType]; } // Default priority fields for any entity return [ 'name', 'title', 'label', 'displayName', 'description', 'summary', 'about', 'details', 'type', 'category', 'kind', 'classification', 'tags', 'keywords', 'labels' ]; } /** * Smart field value extraction with type-aware processing * @param data The data object to extract from * @param pattern The field pattern to apply * @param context The computation context * @returns The extracted and processed field value */ export function extractFieldValue(data, pattern, context) { // Find the first matching field let value = null; let matchedField = null; for (const field of pattern.fields) { if (data[field] !== undefined && data[field] !== null && data[field] !== '') { value = data[field]; matchedField = field; break; } } if (value === null) return null; // Apply transformation if provided if (pattern.transform) { try { return pattern.transform(value, context); } catch (error) { console.warn(`Field transformation error for ${matchedField}:`, error); return String(value); } } // Default processing based on display field type switch (pattern.displayField) { case 'title': case 'description': case 'type': return String(value); case 'tags': if (Array.isArray(value)) return value; if (typeof value === 'string') { return value.split(/[,;]\s*|\s+/).filter(Boolean); } return [String(value)]; default: return value; } } /** * Calculate confidence score for field detection * @param pattern The field pattern * @param context The computation context * @param value The extracted value * @returns Confidence score (0-1) */ export function calculateFieldConfidence(pattern, context, value) { let confidence = pattern.confidence; // Boost confidence if type matches if (pattern.applicableTypes && context.typeResult) { if (pattern.applicableTypes.includes(context.typeResult.type)) { confidence = Math.min(1.0, confidence + 0.1); } } // Reduce confidence for empty or very short values if (typeof value === 'string') { if (value.length < 2) { confidence *= 0.5; } else if (value.length < 5) { confidence *= 0.8; } } // Reduce confidence for generic values const genericValues = ['unknown', 'n/a', 'null', 'undefined', 'default']; if (typeof value === 'string' && genericValues.includes(value.toLowerCase())) { confidence *= 0.3; } return Math.max(0, Math.min(1, confidence)); } //# sourceMappingURL=fieldPatterns.js.map