UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and

403 lines (402 loc) 14.2 kB
/** * Context Types for NeuroLink - Factory Pattern Implementation * Provides type-safe context integration for AI generation */ /** * Factory for context processing */ export class ContextFactory { /** * Default framework fields configuration */ static DEFAULT_FRAMEWORK_FIELDS = { defaultFields: [ "sessionId", "userId", "apiToken", "authToken", "apiEndpoint", "serviceUrl", "endpoint", "environment", "region", "enabledFeatures", "platformType", "platformUrl", "platformId", "enableDemoMode", ], additionalFields: [], includeFields: [], }; /** * Current framework fields configuration */ static frameworkFieldsConfig = ContextFactory.DEFAULT_FRAMEWORK_FIELDS; /** * Flag to track if framework fields have been initialized */ static isFrameworkFieldsInitialized = false; /** * Configure framework fields for exclusion from custom data */ static configureFrameworkFields(config) { ContextFactory.frameworkFieldsConfig = { ...ContextFactory.DEFAULT_FRAMEWORK_FIELDS, ...config, }; ContextFactory.isFrameworkFieldsInitialized = true; } /** * Get current framework fields configuration * Ensures lazy initialization if not already loaded */ static getFrameworkFieldsConfig() { // Lazy initialization - load from environment if not explicitly configured if (!ContextFactory.isFrameworkFieldsInitialized) { ContextFactory.loadFrameworkFieldsFromEnv(); ContextFactory.isFrameworkFieldsInitialized = true; } return { ...ContextFactory.frameworkFieldsConfig }; } /** * Reset framework fields configuration to default */ static resetFrameworkFieldsConfig() { ContextFactory.frameworkFieldsConfig = { ...ContextFactory.DEFAULT_FRAMEWORK_FIELDS, }; } /** * Load framework fields configuration from environment variables * Supports NEUROLINK_CONTEXT_EXCLUDE_FIELDS and NEUROLINK_CONTEXT_INCLUDE_FIELDS */ static loadFrameworkFieldsFromEnv() { const excludeFields = process.env.NEUROLINK_CONTEXT_EXCLUDE_FIELDS; const includeFields = process.env.NEUROLINK_CONTEXT_INCLUDE_FIELDS; const overrideFields = process.env.NEUROLINK_CONTEXT_OVERRIDE_FIELDS; const config = {}; if (excludeFields) { config.additionalFields = excludeFields .split(",") .map((f) => f.trim()) .filter(Boolean); } if (includeFields) { config.includeFields = includeFields .split(",") .map((f) => f.trim()) .filter(Boolean); } if (overrideFields) { config.overrideFields = overrideFields .split(",") .map((f) => f.trim()) .filter(Boolean); } // Optimized check: avoid creating array with Object.keys() for simple property existence check const hasConfigChanges = config.additionalFields || config.includeFields || config.overrideFields; if (hasConfigChanges) { ContextFactory.configureFrameworkFields(config); } ContextFactory.isFrameworkFieldsInitialized = true; } /** * Add additional fields to exclude */ static addFrameworkFieldsToExclude(fields) { const currentConfig = ContextFactory.frameworkFieldsConfig; ContextFactory.configureFrameworkFields({ additionalFields: [...(currentConfig.additionalFields || []), ...fields], }); } /** * Add fields to include (override exclusion) */ static addFrameworkFieldsToInclude(fields) { const currentConfig = ContextFactory.frameworkFieldsConfig; ContextFactory.configureFrameworkFields({ includeFields: [...(currentConfig.includeFields || []), ...fields], }); } /** * Default context configuration */ static DEFAULT_CONFIG = { mode: "metadata_only", includeInPrompt: false, includeInAnalytics: true, includeInEvaluation: true, maxLength: 1000, }; /** * Validate and normalize context data */ static validateContext(context) { if (!context || typeof context !== "object") { return null; } try { // Ensure it's JSON serializable const serialized = JSON.stringify(context); const parsed = JSON.parse(serialized); // Basic validation if (typeof parsed !== "object" || Array.isArray(parsed)) { return null; } return parsed; } catch { return null; } } /** * Process context for AI generation based on configuration */ static processContext(context, config = {}) { const startTime = Date.now(); const finalConfig = { ...this.DEFAULT_CONFIG, ...config }; let processedContext = null; const template = "default"; let truncated = false; if (finalConfig.includeInPrompt && finalConfig.mode !== "metadata_only") { processedContext = this.formatContextForPrompt(context, finalConfig); // Truncate if necessary if (finalConfig.maxLength && processedContext.length > finalConfig.maxLength) { processedContext = processedContext.substring(0, finalConfig.maxLength) + "..."; truncated = true; } } const processingTime = Date.now() - startTime; return { originalContext: context, processedContext, config: finalConfig, metadata: { truncated, processingTime, template, mode: finalConfig.mode, }, }; } /** * Format context for prompt integration */ static formatContextForPrompt(context, config) { switch (config.mode) { case "prompt_prefix": return this.formatAsPrefix(context); case "prompt_suffix": return this.formatAsSuffix(context); case "system_prompt": return this.formatForSystemPrompt(context); case "structured_prompt": return this.formatStructured(context); case "metadata_only": case "none": default: return ""; } } /** * Format context as prompt prefix */ static formatAsPrefix(context) { const parts = []; if (context.userId) { parts.push(`User: ${context.userId}`); } if (context.userRole) { parts.push(`Role: ${context.userRole}`); } if (context.sessionId) { parts.push(`Session: ${context.sessionId}`); } if (parts.length === 0) { return ""; } return `Context: ${parts.join(", ")}\n\n`; } /** * Format context as prompt suffix */ static formatAsSuffix(context) { const relevantKeys = Object.keys(context).filter((key) => !["userId", "sessionId", "requestId"].includes(key)); if (relevantKeys.length === 0) { return ""; } const contextData = relevantKeys.reduce((acc, key) => { acc[key] = context[key]; return acc; }, {}); return `\n\nAdditional Context: ${JSON.stringify(contextData, null, 2)}`; } /** * Format context for system prompt */ static formatForSystemPrompt(context) { const parts = []; if (context.userRole) { parts.push(`You are assisting a user with the role: ${context.userRole}`); } if (context.organizationId) { parts.push(`Organization context: ${context.organizationId}`); } if (context.userPreferences) { parts.push(`User preferences: ${JSON.stringify(context.userPreferences)}`); } return parts.join(". "); } /** * Format context in structured format */ static formatStructured(context) { return `[CONTEXT]\n${JSON.stringify(context, null, 2)}\n[/CONTEXT]\n\n`; } /** * Extract analytics data from context */ static extractAnalyticsContext(context) { return { hasUserId: !!context.userId, hasSessionId: !!context.sessionId, hasUserRole: !!context.userRole, hasOrgContext: !!context.organizationId, contextKeys: Object.keys(context), contextSize: JSON.stringify(context).length, }; } /** * Extract evaluation context */ static extractEvaluationContext(context) { return { userRole: context.userRole || "unknown", applicationContext: context.applicationContext?.name || "unknown", organizationContext: context.organizationId || "unknown", hasPreferences: !!context.userPreferences, }; } } /** * Type guard to check if value is valid context */ function isValidContext(value) { return ContextFactory.validateContext(value) !== null; } export class ContextConverter { /** * Convert legacy business context to generic domain context * Based on business context patterns */ static convertBusinessContext(legacyContext, domainType, options = {}) { const { preserveLegacyFields = false, validateDomainData = true, includeMetadata = true, } = options; return { sessionId: legacyContext.sessionId, userId: legacyContext.userId, config: { domainType, providerConfig: { token: legacyContext.apiToken || legacyContext.authToken || legacyContext.accessToken, endpoint: legacyContext.apiEndpoint || legacyContext.serviceUrl, provider: this.inferProvider(legacyContext), }, platformConfig: { type: legacyContext.platformType || "generic", url: legacyContext.platformUrl || legacyContext.serviceUrl, id: legacyContext.platformId || legacyContext.serviceId, integrations: legacyContext.platformIntegrations || [], }, operationalConfig: { demoMode: legacyContext.enableDemoMode || false, environment: legacyContext.environment || "production", region: legacyContext.region, features: legacyContext.enabledFeatures || [], }, customData: { // Preserve domain-specific fields if needed ...(preserveLegacyFields ? { entityId: legacyContext.entityId || legacyContext.organizationId, departmentId: legacyContext.departmentId, projectId: legacyContext.projectId, } : {}), // Include all additional custom data ...this.extractCustomData(legacyContext), }, }, metadata: includeMetadata ? { convertedFrom: "legacy-business-context", conversionTime: Date.now(), originalKeys: Object.keys(legacyContext), domainType, } : undefined, }; } /** * Create execution context for required domain */ static createDomainContext(domainType, domainData, sessionInfo = {}) { return { sessionId: sessionInfo.sessionId || `session_${Date.now()}`, userId: sessionInfo.userId, config: { domainType, customData: domainData, }, metadata: { source: "domain-context-factory", createdAt: Date.now(), domainType, }, }; } static inferProvider(context) { // Generic provider inference based on context structure if (context.apiToken || context.authToken) { return "api-provider"; } if (context.serviceUrl || context.endpoint) { return "service-provider"; } return "generic-provider"; } static extractCustomData(context) { // Get current framework fields configuration const config = ContextFactory.getFrameworkFieldsConfig(); // Build the set of fields to exclude let fieldsToExclude; if (config.overrideFields) { // Use override fields completely fieldsToExclude = new Set(config.overrideFields); } else { // Use default fields + additional fields fieldsToExclude = new Set([ ...config.defaultFields, ...(config.additionalFields || []), ]); } // Remove filtered fields that should be included despite being in the exclude list if (config.includeFields) { config.includeFields.forEach((field) => fieldsToExclude.delete(field)); } const customData = {}; Object.entries(context).forEach(([key, value]) => { if (!fieldsToExclude.has(key)) { customData[key] = value; } }); return customData; } } // Framework fields configuration loading moved to lazy initialization // Call ContextFactory.loadFrameworkFieldsFromEnv() explicitly in application entrypoint or test setup