@juspay/neurolink
Version:
Universal AI Development Platform with external MCP server integration, multi-provider support, and professional CLI. Connect to 65+ MCP servers for filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major pr
274 lines (273 loc) • 9.26 kB
JavaScript
/**
* NeuroLink MCP Context Management System
* Unified context creation and management for all tool executions
* Ensures rich context flows through tool chain with session tracking
*/
/**
* Context manager for creating and managing execution contexts
* Provides rich context for all tool executions with session tracking
*/
export class ContextManager {
sessionCounter = 0;
activeContexts = new Map();
/**
* Create a new execution context with rich information
*
* @param request Context creation request with optional fields
* @returns Complete execution context ready for tool chain
*/
createContext(request = {}) {
// Generate session ID if not provided
const sessionId = request.sessionId || this.generateSessionId();
// Create comprehensive context
const context = {
// Session Management
sessionId,
userId: request.userId,
// AI Provider Context (from existing NeuroLink)
aiProvider: request.aiProvider,
modelId: request.modelId,
temperature: request.temperature,
maxTokens: request.maxTokens,
// Business Context (new for MCP)
organizationId: request.organizationId,
projectId: request.projectId,
environmentType: request.environmentType || 'development',
// Framework Context (new for MCP)
frameworkType: request.frameworkType,
// Tool Execution Context (initialized empty)
toolChain: [],
parentToolId: undefined,
// Security & Permissions
permissions: request.permissions || [],
securityLevel: request.securityLevel || 'private',
// Copy any additional custom fields
...this.extractCustomFields(request)
};
// Store context for session management
this.activeContexts.set(sessionId, context);
return context;
}
/**
* Add a tool to the execution chain
*
* @param context Execution context to modify
* @param toolName Name of the tool being executed
*/
addToToolChain(context, toolName) {
if (!context.toolChain) {
context.toolChain = [];
}
context.toolChain.push(toolName);
// Update the active context
this.activeContexts.set(context.sessionId, context);
}
/**
* Get the current tool chain for a context
*
* @param context Execution context
* @returns Array of tool names in execution order
*/
getToolChain(context) {
return context.toolChain || [];
}
/**
* Set parent tool for nested tool execution
*
* @param context Execution context to modify
* @param parentToolId ID of the parent tool
*/
setParentTool(context, parentToolId) {
context.parentToolId = parentToolId;
this.activeContexts.set(context.sessionId, context);
}
/**
* Create child context for nested tool execution
*
* @param parentContext Parent execution context
* @param childToolName Name of the child tool
* @returns New child context with inherited properties
*/
createChildContext(parentContext, childToolName) {
const childContext = {
// Inherit all parent context
...parentContext,
// Create new session ID for child
sessionId: this.generateSessionId(),
// Set parent tool reference
parentToolId: parentContext.toolChain?.[parentContext.toolChain.length - 1],
// Reset tool chain for child (will be populated as child executes tools)
toolChain: []
};
// Store child context
this.activeContexts.set(childContext.sessionId, childContext);
return childContext;
}
/**
* Get context by session ID
*
* @param sessionId Session identifier
* @returns Execution context or undefined if not found
*/
getContext(sessionId) {
return this.activeContexts.get(sessionId);
}
/**
* Update context with new information
*
* @param sessionId Session identifier
* @param updates Partial context updates
*/
updateContext(sessionId, updates) {
const context = this.activeContexts.get(sessionId);
if (context) {
const updatedContext = { ...context, ...updates };
this.activeContexts.set(sessionId, updatedContext);
}
}
/**
* Remove context from active tracking
*
* @param sessionId Session identifier
*/
removeContext(sessionId) {
this.activeContexts.delete(sessionId);
}
/**
* Get all active contexts (for debugging/monitoring)
*
* @returns Array of all active contexts
*/
getActiveContexts() {
return Array.from(this.activeContexts.values());
}
/**
* Clear all active contexts
*/
clearAllContexts() {
this.activeContexts.clear();
this.sessionCounter = 0;
}
/**
* Get context statistics
*
* @returns Context usage statistics
*/
getStats() {
const contexts = Array.from(this.activeContexts.values());
const totalToolChainLength = contexts.reduce((sum, ctx) => sum + (ctx.toolChain?.length || 0), 0);
return {
activeContexts: contexts.length,
totalSessionsCreated: this.sessionCounter,
averageToolChainLength: contexts.length > 0
? totalToolChainLength / contexts.length
: 0
};
}
/**
* Generate unique session ID
*
* @returns Unique session identifier
*/
generateSessionId() {
this.sessionCounter++;
const timestamp = Date.now();
const random = Math.random().toString(36).substring(2, 8);
return `nlmcp-${timestamp}-${this.sessionCounter}-${random}`;
}
/**
* Extract custom fields from request (excluding known fields)
*
* @param request Context creation request
* @returns Custom fields object
*/
extractCustomFields(request) {
const knownFields = new Set([
'sessionId', 'userId', 'aiProvider', 'modelId', 'temperature', 'maxTokens',
'organizationId', 'projectId', 'environmentType', 'frameworkType',
'permissions', 'securityLevel'
]);
const customFields = {};
for (const [key, value] of Object.entries(request)) {
if (!knownFields.has(key)) {
customFields[key] = value;
}
}
return customFields;
}
}
/**
* Default context manager instance
* Can be used across the application for consistent context management
*/
export const defaultContextManager = new ContextManager();
/**
* Utility function to create context with defaults
*
* @param request Optional context request
* @returns Execution context with sensible defaults
*/
export function createExecutionContext(request = {}) {
return defaultContextManager.createContext(request);
}
/**
* Utility function to add tool to default context manager
*
* @param context Execution context
* @param toolName Tool name to add
*/
export function addToolToChain(context, toolName) {
defaultContextManager.addToToolChain(context, toolName);
}
/**
* Context validation utilities
*/
export class ContextValidator {
/**
* Validate context has required fields for tool execution
*
* @param context Execution context to validate
* @returns Validation result with details
*/
static validateContext(context) {
const errors = [];
const warnings = [];
// Required field validation
if (!context.sessionId) {
errors.push('sessionId is required');
}
// Optional field validation with warnings
if (!context.environmentType) {
warnings.push('environmentType not specified, defaulting to development');
}
if (!context.securityLevel) {
warnings.push('securityLevel not specified, defaulting to private');
}
// Tool chain validation
if (context.toolChain && context.toolChain.length > 10) {
warnings.push('Tool chain is getting long (>10 tools), consider breaking into smaller workflows');
}
return {
isValid: errors.length === 0,
errors,
warnings
};
}
/**
* Validate context permissions for tool execution
*
* @param context Execution context
* @param requiredPermissions Permissions required by tool
* @returns Whether context has required permissions
*/
static hasPermissions(context, requiredPermissions) {
if (!requiredPermissions || requiredPermissions.length === 0) {
return true;
}
const contextPermissions = context.permissions || [];
// Check if context has all required permissions
return requiredPermissions.every(permission => contextPermissions.includes(permission) ||
contextPermissions.includes('*') // Wildcard permission
);
}
}